This is just a smalle testmessage to see how this interface handles a lot of spaces.
I want spaces because then it is much easier to read sourcecode pasted in to this.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok... Here is my code. So far I have not done much about sending messages, I have mostly tested callbacks and so on.
The code compiles on RH7.1 with ICQLIB 1.0.0.
I hope that this may help others to understand ICQLIB better.
/* Used while debugging the software
at the moment all the time ;-) */
#define DEBUG 1
/* These should be self explaining */
#define ICQ_UIN 10472501
#define ICQ_PASS "ThisIsNotMyRealPassword"
#define ICQ_NICK "Walther"
ICQLINK *icqlink;
unsigned int TimeoutCounter;
unsigned int TimeoutCount;
unsigned char TimeoutEnabled;
unsigned int KeepAliveCounter;
/* Define callback functions */
/* Called when user is logged in */
void CallBack_Logged (struct icq_link *link);
/* Called when user is logged out */
void CallBack_Disconnected (struct icq_link *link);
/* Called when a user on the contactlist is online */
void CallBack_UserOnline (struct icq_link *link,
unsigned long uin,
unsigned long status,
unsigned long ip,
unsigned short port,
unsigned long real_ip,
unsigned char tcp_flag);
/* Called when a user on the contactlist is offline */
void CallBack_UserOffline (struct icq_link *link,
unsigned long uin);
/* Called when a user on contactlist changes status */
void CallBack_UserStatusUpdate(struct icq_link *link,
unsigned long uin,
unsigned long status);
/* Called when a normal message is received */
void CallBack_RecvMessage (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *msg);
/* Called when an URL is received */
void CallBack_RecvURL (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *URL,
const char *descr);
/* Called when a WebPager message is received */
void CallBack_RecvWebPager (struct icq_link *link,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *email,
const char *msg);
/* Called when a MailExpress message is received */
void CallBack_RecvMailExpress (struct icq_link *link,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *email,
const char *msg);
/* Called when a Log event should be written */
void CallBack_Log (struct icq_link *link,
time_t time,
unsigned char level,
const char *str);
/* Called when we have been added by another user */
void CallBack_RecvAdded (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *first,
const char *last,
const char *email);
/* Called when the client must handle timeouts */
void CallBack_SetTimeout (struct icq_link *link,
long interval);
/* Called if you have tryied logging in with wrong
password. I have never received such a message.
If I use a wrong password, nothing happens, but
when I send a KeepAlive the reply is that I am
disconnected */
void CallBack_WrongPassword (struct icq_link *link);
/* Called if you have tryied logging in with wrong UIN
Same thing as with WrongPassword, I have never
received this */
void CallBack_InvalidUIN (struct icq_link *link);
/* This function is called when the program should exit. */
void sig_quit()
{
#ifdef DEBUG
fprintf(stderr, "sig_quit: Logging out\n");
#endif
icq_Logout(icqlink);
usleep(1000000); /* Sleep for 1 second */
#ifdef DEBUG
fprintf(stderr, "main: Setting up signal handler\n");
#endif
signal(SIGINT, &sig_quit); /* This is set up in order to stop the program */
signal(SIGQUIT, &sig_quit); /* by sending SIGINT or SIGQUIT to it */
#ifdef DEBUG
fprintf(stderr, "main: Setting up Contactlist\n");
#endif
/* The contactlist that you know you have must be populated before
logging on to mirabilis */
icq_ContactClear(icqlink);
icq_ContactAdd(icqlink, 12695672); /* My own account used when I am at work */
icq_ContactAdd(icqlink, 115483538); /* Another ICQ account that I have */
#ifdef DEBUG
fprintf(stderr, "main: Logging in to ICQ server\n");
#endif
icq_Login(icqlink, STATUS_ONLINE);
#ifdef DEBUG
fprintf(stderr, "main: Starting mainloop\n");
#endif
while (1)
{
usleep(50000); /* Sleep 0.05 seconds */
icq_Main(icqlink); /* Poll to received packets */
/* When we sleep 0.05 seconds then every 1800th loop
occurrs about every 90 seconds. Should be about
every 120 seconds, but since there is running
other code I would like to be on the safe side */
if (KeepAliveCounter++ == 1800)
{
#ifdef DEBUG
fprintf(stderr, "main: Sending KeepAlive package\n");
#endif
icq_KeepAlive(icqlink);
KeepAliveCounter =0;
}
if (TimeoutEnabled) /* If we are waiting for packet from server */
if (TimeoutCounter++ == TimeoutCount) /* If the packet has not been received within timeoutperiod */
{
#ifdef DEBUG
fprintf(stderr, "main: Timeout occurred\n");
#endif
icq_HandleTimeout(icqlink); /* Handle the timeout event */
}
}
}
/* Callback functions */
void CallBack_Logged (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_Logged: User is logged in\n");
#endif
TimeoutEnabled = 0;
}
void CallBack_Disconnected (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_Disconnected: User is disconnected\n");
#endif
TimeoutEnabled = 0;
sig_quit(); /* If we are disconnected, stop the program */
}
void CallBack_UserOnline (struct icq_link *link,
unsigned long uin,
unsigned long status,
unsigned long ip,
unsigned short port,
unsigned long real_ip,
unsigned char tcp_flag)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_UserOnline: %d is online\n", uin);
fprintf(stderr, "Status: %d\n", status); /* Strange, this is not at all the same as the defines */
fprintf(stderr, "Online %d, Away %d, DND %d, NA %d, Occupied %d, Free for chat %d, Invisible %d\n", STATUS_ONLINE, STATUS_AWAY, STATUS_DND, STATUS_NA, STATUS_OCCUPIED, STATUS_FREE_CHAT, STATUS_INVISIBLE);
fprintf(stderr, "IP: %d\n", ip);
fprintf(stderr, "Port: %d\n", port);
fprintf(stderr, "Real IP: %d\n", real_ip);
fprintf(stderr, "TCP flag: %d\n", tcp_flag);
icq_SendMessage(icqlink, uin, "Davs", ICQ_SEND_BESTWAY);
#endif
TimeoutEnabled = 0;
}
void CallBack_UserOffline (struct icq_link *link,
unsigned long uin)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_UserOffline: User %d is now offline\n", uin);
#endif
TimeoutEnabled = 0;
}
void CallBack_UserStatusUpdate(struct icq_link *link,
unsigned long uin,
unsigned long status)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_UserStatusUpdate: User %d changed status to %d\n", uin, status);
#endif
TimeoutEnabled = 0;
}
void CallBack_RecvMessage (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *msg)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_RecvMessage: Received message from %d\n", uin);
fprintf(stderr, "Message received at %d:%d %d/%d %d\n", hour, minute, day, month, year);
fprintf(stderr, "%s\n", msg);
#endif
TimeoutEnabled = 0;
}
void CallBack_RecvURL (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *URL,
const char *descr)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_RecvURL: Received URL from %d\n", uin);
fprintf(stderr, "URL received at %d:%d %d/%d %d\n", hour, minute, day, month, year);
fprintf(stderr, "URL: %s\n", URL);
fprintf(stderr, "Description: %s\n", descr);
#endif
void CallBack_SetTimeout (struct icq_link *link,
long interval)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_SetTimeout: Interval is %d\n", interval);
#endif
/* If the interval is 0 or -1 then we should disable timeout.
This must mean that the server is not going to send any
more before we have sent something to the server */
if ((interval == 0) || (interval == -1))
{
TimeoutEnabled = 0; /* Disable Timeout */
}
else
{
/* Calculate how many loops it takes before there has gone
approx [interval] seconds */
TimeoutCount = interval * 20;
TimeoutCounter = 0;
TimeoutEnabled = 1;
}
}
void CallBack_WrongPassword (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_WrongPassword: Password used for login was incorrect\n");
#endif
TimeoutEnabled = 0;
sig_quit();
}
void CallBack_InvalidUIN (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_InvalidUIN: UIN was not recognized\n");
#endif
TimeoutEnabled = 0;
sig_quit();
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
To see the code as I intended...
View source.
Search for #include
Mark alle the sourcecode and copy it to other editor.
Search and replace <br /> with a space
Change the html equivelants of < and > to < and >
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is just a smalle testmessage to see how this interface handles a lot of spaces.
I want spaces because then it is much easier to read sourcecode pasted in to this.
Ok... Here is my code. So far I have not done much about sending messages, I have mostly tested callbacks and so on.
The code compiles on RH7.1 with ICQLIB 1.0.0.
I hope that this may help others to understand ICQLIB better.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <icq.h>
#include <time.h>
#include <signal.h>
/* Used while debugging the software
at the moment all the time ;-) */
#define DEBUG 1
/* These should be self explaining */
#define ICQ_UIN 10472501
#define ICQ_PASS "ThisIsNotMyRealPassword"
#define ICQ_NICK "Walther"
ICQLINK *icqlink;
unsigned int TimeoutCounter;
unsigned int TimeoutCount;
unsigned char TimeoutEnabled;
unsigned int KeepAliveCounter;
/* Define callback functions */
/* Called when user is logged in */
void CallBack_Logged (struct icq_link *link);
/* Called when user is logged out */
void CallBack_Disconnected (struct icq_link *link);
/* Called when a user on the contactlist is online */
void CallBack_UserOnline (struct icq_link *link,
unsigned long uin,
unsigned long status,
unsigned long ip,
unsigned short port,
unsigned long real_ip,
unsigned char tcp_flag);
/* Called when a user on the contactlist is offline */
void CallBack_UserOffline (struct icq_link *link,
unsigned long uin);
/* Called when a user on contactlist changes status */
void CallBack_UserStatusUpdate(struct icq_link *link,
unsigned long uin,
unsigned long status);
/* Called when a normal message is received */
void CallBack_RecvMessage (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *msg);
/* Called when an URL is received */
void CallBack_RecvURL (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *URL,
const char *descr);
/* Called when a WebPager message is received */
void CallBack_RecvWebPager (struct icq_link *link,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *email,
const char *msg);
/* Called when a MailExpress message is received */
void CallBack_RecvMailExpress (struct icq_link *link,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *email,
const char *msg);
/* Called when a Log event should be written */
void CallBack_Log (struct icq_link *link,
time_t time,
unsigned char level,
const char *str);
/* Called when we have been added by another user */
void CallBack_RecvAdded (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *first,
const char *last,
const char *email);
/* Called when the client must handle timeouts */
void CallBack_SetTimeout (struct icq_link *link,
long interval);
/* Called if you have tryied logging in with wrong
password. I have never received such a message.
If I use a wrong password, nothing happens, but
when I send a KeepAlive the reply is that I am
disconnected */
void CallBack_WrongPassword (struct icq_link *link);
/* Called if you have tryied logging in with wrong UIN
Same thing as with WrongPassword, I have never
received this */
void CallBack_InvalidUIN (struct icq_link *link);
/* This function is called when the program should exit. */
void sig_quit()
{
#ifdef DEBUG
fprintf(stderr, "sig_quit: Logging out\n");
#endif
icq_Logout(icqlink);
usleep(1000000); /* Sleep for 1 second */
#ifdef DEBUG
fprintf(stderr, "sig_quit: Polling\n");
#endif
icq_Main(icqlink);
#ifdef DEBUG
fprintf(stderr, "sig_quit: Disconnecting\n");
#endif
icq_Disconnect(icqlink);
exit (0);
}
int main(int argc, char *argv[])
{
TimeoutEnabled = 0;
KeepAliveCounter = 0;
#ifdef DEBUG
fprintf(stderr, "main: Allocating memory for icqlink\n");
#endif
icqlink = malloc(sizeof(ICQLINK));
#ifdef DEBUG
fprintf(stderr, "main: Initializing ICQ link\n");
#endif
icq_Init(icqlink, ICQ_UIN, ICQ_PASS, ICQ_NICK);
#ifdef DEBUG
fprintf(stderr, "main: Setting callback functions\n");
#endif
icqlink->icq_Logged = &CallBack_Logged;
icqlink->icq_Disconnected = &CallBack_Disconnected;
icqlink->icq_UserOnline = &CallBack_UserOnline;
icqlink->icq_UserOffline = &CallBack_UserOffline;
icqlink->icq_UserStatusUpdate = &CallBack_UserStatusUpdate;
icqlink->icq_RecvMessage = &CallBack_RecvMessage;
icqlink->icq_RecvURL = &CallBack_RecvURL;
icqlink->icq_RecvWebPager = &CallBack_RecvWebPager;
icqlink->icq_RecvMailExpress = &CallBack_RecvMailExpress;
icqlink->icq_Log = &CallBack_Log;
icqlink->icq_RecvAdded = &CallBack_RecvAdded;
icqlink->icq_SetTimeout = &CallBack_SetTimeout;
#ifdef DEBUG
fprintf(stderr, "main: Setting up signal handler\n");
#endif
signal(SIGINT, &sig_quit); /* This is set up in order to stop the program */
signal(SIGQUIT, &sig_quit); /* by sending SIGINT or SIGQUIT to it */
#ifdef DEBUG
fprintf(stderr, "main: Setting up Contactlist\n");
#endif
/* The contactlist that you know you have must be populated before
logging on to mirabilis */
icq_ContactClear(icqlink);
icq_ContactAdd(icqlink, 12695672); /* My own account used when I am at work */
icq_ContactAdd(icqlink, 115483538); /* Another ICQ account that I have */
#ifdef DEBUG
fprintf(stderr, "main: Connecting to ICQ server\n");
#endif
icq_Connect(icqlink, "icq.mirabilis.com", 4000);
#ifdef DEBUG
fprintf(stderr, "main: Logging in to ICQ server\n");
#endif
icq_Login(icqlink, STATUS_ONLINE);
#ifdef DEBUG
fprintf(stderr, "main: Starting mainloop\n");
#endif
while (1)
{
usleep(50000); /* Sleep 0.05 seconds */
icq_Main(icqlink); /* Poll to received packets */
/* When we sleep 0.05 seconds then every 1800th loop
occurrs about every 90 seconds. Should be about
every 120 seconds, but since there is running
other code I would like to be on the safe side */
if (KeepAliveCounter++ == 1800)
{
#ifdef DEBUG
fprintf(stderr, "main: Sending KeepAlive package\n");
#endif
icq_KeepAlive(icqlink);
KeepAliveCounter =0;
}
if (TimeoutEnabled) /* If we are waiting for packet from server */
if (TimeoutCounter++ == TimeoutCount) /* If the packet has not been received within timeoutperiod */
{
#ifdef DEBUG
fprintf(stderr, "main: Timeout occurred\n");
#endif
icq_HandleTimeout(icqlink); /* Handle the timeout event */
}
}
}
/* Callback functions */
void CallBack_Logged (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_Logged: User is logged in\n");
#endif
TimeoutEnabled = 0;
}
void CallBack_Disconnected (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_Disconnected: User is disconnected\n");
#endif
TimeoutEnabled = 0;
sig_quit(); /* If we are disconnected, stop the program */
}
void CallBack_UserOnline (struct icq_link *link,
unsigned long uin,
unsigned long status,
unsigned long ip,
unsigned short port,
unsigned long real_ip,
unsigned char tcp_flag)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_UserOnline: %d is online\n", uin);
fprintf(stderr, "Status: %d\n", status); /* Strange, this is not at all the same as the defines */
fprintf(stderr, "Online %d, Away %d, DND %d, NA %d, Occupied %d, Free for chat %d, Invisible %d\n", STATUS_ONLINE, STATUS_AWAY, STATUS_DND, STATUS_NA, STATUS_OCCUPIED, STATUS_FREE_CHAT, STATUS_INVISIBLE);
fprintf(stderr, "IP: %d\n", ip);
fprintf(stderr, "Port: %d\n", port);
fprintf(stderr, "Real IP: %d\n", real_ip);
fprintf(stderr, "TCP flag: %d\n", tcp_flag);
icq_SendMessage(icqlink, uin, "Davs", ICQ_SEND_BESTWAY);
#endif
TimeoutEnabled = 0;
}
void CallBack_UserOffline (struct icq_link *link,
unsigned long uin)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_UserOffline: User %d is now offline\n", uin);
#endif
TimeoutEnabled = 0;
}
void CallBack_UserStatusUpdate(struct icq_link *link,
unsigned long uin,
unsigned long status)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_UserStatusUpdate: User %d changed status to %d\n", uin, status);
#endif
TimeoutEnabled = 0;
}
void CallBack_RecvMessage (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *msg)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_RecvMessage: Received message from %d\n", uin);
fprintf(stderr, "Message received at %d:%d %d/%d %d\n", hour, minute, day, month, year);
fprintf(stderr, "%s\n", msg);
#endif
TimeoutEnabled = 0;
}
void CallBack_RecvURL (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *URL,
const char *descr)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_RecvURL: Received URL from %d\n", uin);
fprintf(stderr, "URL received at %d:%d %d/%d %d\n", hour, minute, day, month, year);
fprintf(stderr, "URL: %s\n", URL);
fprintf(stderr, "Description: %s\n", descr);
#endif
TimeoutEnabled = 0;
}
void CallBack_RecvWebPager (struct icq_link *link,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *email,
const char *msg)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_RecvWebPager: Received message from %s\n", nick);
fprintf(stderr, "Message received at %d:%d %d/%d %d\n", hour, minute, day, month, year);
fprintf(stderr, "E-mail: %s\n", email);
fprintf(stderr, "%s\n", msg);
#endif
TimeoutEnabled = 0;
}
void CallBack_RecvMailExpress (struct icq_link *link,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *email,
const char *msg)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_RecvMailExpress: Received message from %s\n", nick);
fprintf(stderr, "Message received at %d:%d %d/%d %d\n", hour, minute, day, month, year);
fprintf(stderr, "E-mail: %s\n", email);
fprintf(stderr, "%s\n", msg);
#endif
TimeoutEnabled = 0;
}
void CallBack_Log (struct icq_link *link,
time_t time,
unsigned char level,
const char *str)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_Log: Level is %d\n", level);
fprintf(stderr, "String: %s\n", str);
#endif
TimeoutEnabled = 0;
}
void CallBack_RecvAdded (struct icq_link *link,
unsigned long uin,
unsigned char hour,
unsigned char minute,
unsigned char day,
unsigned char month,
unsigned short year,
const char *nick,
const char *first,
const char *last,
const char *email)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_RecvAdded: UIN=%d\n", uin);
fprintf(stderr, "%d:%d %d/%d %d\n", hour, minute, day, month, year);
fprintf(stderr, "Nickname: %s\n", nick);
fprintf(stderr, "Real name: %s %s\n", first, last);
fprintf(stderr, "E-mail: %s\n", email);
#endif
TimeoutEnabled = 0;
}
void CallBack_SetTimeout (struct icq_link *link,
long interval)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_SetTimeout: Interval is %d\n", interval);
#endif
/* If the interval is 0 or -1 then we should disable timeout.
This must mean that the server is not going to send any
more before we have sent something to the server */
if ((interval == 0) || (interval == -1))
{
TimeoutEnabled = 0; /* Disable Timeout */
}
else
{
/* Calculate how many loops it takes before there has gone
approx [interval] seconds */
TimeoutCount = interval * 20;
TimeoutCounter = 0;
TimeoutEnabled = 1;
}
}
void CallBack_WrongPassword (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_WrongPassword: Password used for login was incorrect\n");
#endif
TimeoutEnabled = 0;
sig_quit();
}
void CallBack_InvalidUIN (struct icq_link *link)
{
#ifdef DEBUG
fprintf(stderr, "CallBack_InvalidUIN: UIN was not recognized\n");
#endif
TimeoutEnabled = 0;
sig_quit();
}
To see the code as I intended...
View source.
Search for #include
Mark alle the sourcecode and copy it to other editor.
Search and replace <br /> with a space
Change the html equivelants of < and > to < and >
Hmm... I have just downloadet the newest version of ICQLIB via CVS so now I'm off writing my client from scratch once more :(