changeset 1498:0ef6603d986e

[gaim-migrate @ 1508] updating icqlib committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Thu, 22 Feb 2001 23:07:34 +0000
parents c3a40af2b0c4
children de0b946e86a4
files plugins/icq/.cvsignore plugins/icq/CHANGES_SINCE_1.0 plugins/icq/ChangeLog plugins/icq/Makefile.am plugins/icq/filesession.c plugins/icq/gaim_icq.c plugins/icq/icq.h plugins/icq/icqlib.c plugins/icq/list.c plugins/icq/list.h plugins/icq/queue.c plugins/icq/queue.h plugins/icq/socketmanager.c plugins/icq/tcp.c plugins/icq/tcplink.c plugins/icq/tcplink.h plugins/icq/timeout.c plugins/icq/timeout.h plugins/icq/udp.c plugins/icq/udphandle.c
diffstat 20 files changed, 317 insertions(+), 217 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/icq/.cvsignore	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/.cvsignore	Thu Feb 22 23:07:34 2001 +0000
@@ -21,6 +21,7 @@
 tcpfilehandle.lo
 tcphandle.lo
 tcplink.lo
+timeout.lo
 udp.lo
 udphandle.lo
 util.lo
--- a/plugins/icq/CHANGES_SINCE_1.0	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/CHANGES_SINCE_1.0	Thu Feb 22 23:07:34 2001 +0000
@@ -73,4 +73,6 @@
 call icq_Main every 1/10 of a second or so.  This has the disadvantage of 
 wasting CPU cycles and poor TCP file transfer performance, though.
 
- 
+2001-02-20: The icq_SetTimeout callback has been moved outside of the 
+ICQLINK structure, and icq_HandleTimeout no longer requires an ICQLINK 
+parameter.
--- a/plugins/icq/ChangeLog	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/ChangeLog	Thu Feb 22 23:07:34 2001 +0000
@@ -1,3 +1,35 @@
+2001-02-22  Bill Soudan  <soudan@kde.org>
+
+	Note the icq_SetTimeout callback has been moved outside of
+	the ICQLINK structure, and icq_HandleTimeout no longer 
+	requires an ICQLINK parameter.  TCP connect timeouts should
+	work once again.
+
+	* icqlib/filesession.c: fixed initialization bug that may
+	cause a crash on file session deletion
+
+	* icqlib/Makefile.am, icqlib/timeout.c, icqlib/timeout.h,
+	icqlib/icq.h.in, icqlib/icqlib.c: new timeout manager code,
+	correct compilation warnings
+
+	* icqlib/list.c, icqlib/list.h: added sorted list capability -
+	see list_insert_sorted and new compare_function list struct
+	member
+
+	* icqlib/queue.c, icqlib/queue.h, icqlib/tcp.c, icqlib/tcplink.c,
+	icqlib/tcplink.h, icqlib/udp.c, icqlib/udphandle.c:
+	port tcp connect timeout code and UDP queue to new timeout
+	manager
+
+	* icqlib/socketmanager.c: move icq_SocketHandler declaration
+	here, instead of declaring it in icqlib.c.  fix bug with
+	icq_SocketPoll/icq_SocketMain, as reported by Michael Hudson.
+
+	* bindings/python/icqlibmodule.c: ported to new timeout
+	interface - remove SetTimeout callback and HandleTimeout 
+	methods from PyICQLink class, add icqlib.InstallTimeoutHandler 
+	and icqlib.HandleTimeout methods.
+	
 2001-01-27  Bill Soudan  <soudan@kde.org>
 
 	* icqlib/socketmanager.c, icqlib/socketmanager.h, 
--- a/plugins/icq/Makefile.am	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/Makefile.am	Thu Feb 22 23:07:34 2001 +0000
@@ -46,6 +46,8 @@
 			tcphandle.c \
 			tcplink.c \
 			tcplink.h \
+			timeout.c \
+			timeout.h \
 			udp.c \
 			udp.h \
 			udphandle.c \
--- a/plugins/icq/filesession.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/filesession.c	Thu Feb 22 23:07:34 2001 +0000
@@ -27,6 +27,7 @@
     p->status=0;
     p->id=0L;
     p->icqlink=icqlink;
+    p->tcplink=NULL;
     p->current_fd=-1;
     p->current_file_num=0;
     p->current_file_progress=0;
--- a/plugins/icq/gaim_icq.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/gaim_icq.c	Thu Feb 22 23:07:34 2001 +0000
@@ -18,9 +18,10 @@
 struct icq_data {
 	ICQLINK *link;
 	int cur_status;
-	int ack_timer;
 };
 
+static guint ack_timer = 0;
+
 static struct gaim_connection *find_gaim_conn_by_icq_link(ICQLINK *link) {
 	GSList *c = connections;
 	struct gaim_connection *gc = NULL;
@@ -152,22 +153,19 @@
 	serv_got_update(gc, buf, 1, 0, 0, 0, status, 0);
 }
 
-static gint icq_set_timeout_cb(struct icq_data *id) {
-	icq_HandleTimeout(id->link);
-	id->ack_timer = -1;
+static gint icq_set_timeout_cb() {
+	icq_HandleTimeout();
+	ack_timer = 0;
 	return FALSE;
 }
 
-static void icq_set_timeout(ICQLINK *link, long interval) {
-	struct gaim_connection *gc = find_gaim_conn_by_icq_link(link);
-	struct icq_data *id = (struct icq_data *)gc->proto_data;
-
+static void icq_set_timeout(long interval) {
 	debug_printf("icq_SetTimeout: %ld\n", interval);
-	if (interval > 0 && id->ack_timer < 1)
-		id->ack_timer = gtk_timeout_add(interval * 1000, (GtkFunction)icq_set_timeout_cb, id);
-	else if (id->ack_timer > 0) {
-		gtk_timeout_remove(id->ack_timer);
-		id->ack_timer = -1;
+	if (interval > 0 && ack_timer == 0)
+		ack_timer = gtk_timeout_add(interval * 1000, (GtkFunction)icq_set_timeout_cb, NULL);
+	else if (ack_timer > 0) {
+		gtk_timeout_remove(ack_timer);
+		ack_timer = 0;
 	}
 }
 
@@ -258,7 +256,6 @@
 	link->icq_WrongPassword = icq_wrong_passwd;
 	link->icq_InvalidUIN = icq_invalid_uin;
 	link->icq_Log = icq_do_log;
-	link->icq_SetTimeout = icq_set_timeout;
 
 	icq_ContactClear(id->link);
 	if (bud_list_cache_exists(gc))
@@ -479,6 +476,7 @@
 
 char *gaim_plugin_init(GModule *handle) {
 	icq_SocketNotify = icq_sock_notify;
+	icq_SetTimeout = icq_set_timeout;
 	load_protocol(icq_init, sizeof(struct prpl));
 	return NULL;
 }
--- a/plugins/icq/icq.h	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/icq.h	Thu Feb 22 23:07:34 2001 +0000
@@ -220,7 +220,6 @@
   void (*icq_ChatNotify)(icq_ChatSession *session, int type, int arg,
        void *data);
   void (*icq_NewUIN)(struct icq_link *link, unsigned long uin);
-  void (*icq_SetTimeout)(struct icq_link *link, long interval);
   void (*icq_MetaUserFound)(struct icq_link *link, unsigned short seq2,
        unsigned long uin, const char *nick, const char *first,
        const char *last, const char *email, char auth);
@@ -283,7 +282,6 @@
 int icq_GetProxySok(ICQLINK *link);
 void icq_HandleServerResponse(ICQLINK *link);
 void icq_HandleProxyResponse(ICQLINK *link);
-void icq_HandleTimeout(ICQLINK *link);
 void icq_Main(ICQLINK *link);
 unsigned short icq_KeepAlive(ICQLINK *link);
 void icq_Login(ICQLINK *link, unsigned long status);
@@ -600,6 +598,12 @@
 
 void icq_HandleReadySocket(int socket, int type);
 
+/* Timeout Manager */
+
+extern void (*icq_SetTimeout)(long interval);
+
+void icq_HandleTimeout();
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
--- a/plugins/icq/icqlib.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/icqlib.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,9 +1,12 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
-$Id: icqlib.c 1477 2001-02-04 07:34:46Z warmenhoven $
+$Id: icqlib.c 1508 2001-02-22 23:07:34Z warmenhoven $
 $Log$
-Revision 1.4  2001/02/04 07:34:46  warmenhoven
-updates to icqlib and gtkspell. also added catch case for when BYTE_ORDER wasn't defined.
+Revision 1.5  2001/02/22 23:07:34  warmenhoven
+updating icqlib
+
+Revision 1.51  2001/02/22 05:37:39  bills
+new timeout manager code, correct compilation warnings
 
 Revision 1.50  2001/02/03 17:04:16  mwh
 Add an icq_UserData field to the ICQLINK struct.
@@ -66,8 +69,6 @@
 int icq_Russian = FALSE;
 BYTE icq_LogLevel = 0;
 
-void (*icq_SocketNotify)(int socket, int type, int status);
-
 DWORD icq_SendMessage(ICQLINK *link, DWORD uin, const char *text, BYTE thruSrv)
 {
   if(thruSrv==ICQ_SEND_THRUSERVER)
@@ -123,10 +124,18 @@
   link->d = (ICQLINK_private*)malloc(sizeof(ICQLINK_private));
 
   srand(time(0L));
-  /* initialize icq_SocketList on first call */
+
+  /* initialize internal lists, if necessary */
   if (!icq_SocketList)
     icq_SocketList = list_new();
 
+  if (!icq_TimeoutList)
+  {
+    icq_TimeoutList = list_new();
+    icq_TimeoutList->compare_function =
+      (icq_ListCompareFunc)icq_TimeoutCompare;
+  }
+
   /* Initialize all callbacks */
   link->icq_Logged = 0L;
   link->icq_Disconnected = 0L;
@@ -151,7 +160,6 @@
   link->icq_SrvAck = 0L;
   link->icq_RequestNotify = 0L;
   link->icq_NewUIN = 0L;
-  link->icq_SetTimeout = 0L;
   link->icq_MetaUserFound = 0L;
   link->icq_MetaUserInfo = 0L;
   link->icq_MetaUserWork = 0L;
@@ -439,10 +447,10 @@
 
   /* sockets are ready to receive data - install handlers */
   icq_SocketSetHandler(link->icq_UDPSok, ICQ_SOCKET_READ,
-    icq_HandleServerResponse, link);
+    (icq_SocketHandler)icq_HandleServerResponse, link);
   if (link->icq_UseProxy)
     icq_SocketSetHandler(link->icq_ProxySok, ICQ_SOCKET_READ,
-      icq_HandleProxyResponse, link);
+      (icq_SocketHandler)icq_HandleProxyResponse, link);
   return link->icq_UDPSok;
 }
 
--- a/plugins/icq/list.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/list.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,9 +1,13 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
-$Id: list.c 1442 2001-01-28 01:52:27Z warmenhoven $
+$Id: list.c 1508 2001-02-22 23:07:34Z warmenhoven $
 $Log$
-Revision 1.3  2001/01/28 01:52:27  warmenhoven
-icqlib 1.1.5
+Revision 1.4  2001/02/22 23:07:34  warmenhoven
+updating icqlib
+
+Revision 1.15  2001/02/22 05:38:45  bills
+added sorted list capability - see list_insert_sorted and new
+compare_function list struct member
 
 Revision 1.14  2000/07/10 01:44:20  bills
 i really don't learn - removed LIST_TRACE define
@@ -14,37 +18,8 @@
 Revision 1.12  2000/07/10 01:31:17  bills
 oops - removed #define LIST_TRACE and #define QUEUE_DEBUG
 
-Revision 1.11  2000/07/10 01:26:30  bills
-added more trace messages, added list_remove_node call in list_free...
-fixes list corruption bug introduced during last commit
-
-Revision 1.10  2000/07/09 22:04:45  bills
-recoded list_free function - this was working very incorrectly!  it was
-only freeing the first node of the list, and then ending.  fixes a memory
-leak.
-
-Revision 1.9  2000/05/10 18:48:56  denis
-list_free() was added to free but do not dispose the list.
-Memory leak with destroying the list was fixed.
-
-Revision 1.8  2000/05/03 18:19:15  denis
-Bug with empty contact list was fixed.
+*/
 
-Revision 1.7  2000/01/16 21:26:54  bills
-fixed serious bug in list_remove
-
-Revision 1.6  2000/01/16 03:59:10  bills
-reworked list code so list_nodes don't need to be inside item structures,
-removed strlist code and replaced with generic list calls
-
-Revision 1.5  1999/09/29 19:59:30  bills
-cleanups
-
-Revision 1.4  1999/07/16 11:59:46  denis
-list_first(), list_last(), list_at() added.
-Cleaned up.
-
-*/
 /*
  * linked list functions
  */
@@ -92,6 +67,22 @@
   }
 }
 
+void list_insert_sorted(list *plist, void *pitem)
+{
+  list_node *i=plist->head;
+  int done;
+
+  while (i && !done)
+  {
+    if ((*plist->compare_function)(pitem, i->item)<0)
+      done = 1;
+    else
+      i=i->next;
+  }
+
+  list_insert(plist, i, pitem);
+}
+
 void list_insert(list *plist, list_node *pnode, void *pitem)
 {
   list_node *pnew=(list_node *)malloc(sizeof(list_node));
@@ -195,7 +186,9 @@
     if(!(f=(*item_f)(i->item, ap)))
       i=pnext;
   }
+
   va_end(ap);
+
   if (i)
     return i->item;
   else
--- a/plugins/icq/list.h	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/list.h	Thu Feb 22 23:07:34 2001 +0000
@@ -16,6 +16,7 @@
 
 typedef struct list_node_s list_node;
 typedef struct list_s list;
+typedef int (*icq_ListCompareFunc)(void *o1, void *o2);
 
 struct list_node_s
 {
@@ -29,11 +30,13 @@
   list_node *head;
   list_node *tail;
   int count;
+  icq_ListCompareFunc compare_function;
 };
 
 list *list_new(void);
 void list_delete(list *plist, void (*item_free_f)(void *));
 void list_free(list *plist, void (*item_free_f)(void *));
+void list_insert_sorted(list *plist, void *pitem);
 void list_insert(list *plist, list_node *pnode, void *pitem);
 void *list_remove(list *plist, void *pitem);
 void *list_traverse(list *plist, int (*item_f)(void *, va_list), ...);
--- a/plugins/icq/queue.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/queue.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,9 +1,12 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
-$Id: queue.c 1442 2001-01-28 01:52:27Z warmenhoven $
+$Id: queue.c 1508 2001-02-22 23:07:34Z warmenhoven $
 $Log$
-Revision 1.4  2001/01/28 01:52:27  warmenhoven
-icqlib 1.1.5
+Revision 1.5  2001/02/22 23:07:34  warmenhoven
+updating icqlib
+
+Revision 1.13  2001/02/22 05:40:04  bills
+port tcp connect timeout code and UDP queue to new timeout manager
 
 Revision 1.12  2000/12/19 06:00:07  bills
 moved members from ICQLINK to ICQLINK_private struct
@@ -61,47 +64,25 @@
   link->icq_UDPExpireInterval = 15; /* expire interval = 15 sec */
 }
 
-void icq_UDPQueuePut(ICQLINK *link, icq_Packet *p, int attempt)
+void icq_UDPQueuePut(ICQLINK *link, icq_Packet *p)
 {
   icq_UDPQueueItem *ptr = (icq_UDPQueueItem*)malloc(sizeof(icq_UDPQueueItem));
 #ifdef QUEUE_DEBUG
   printf("icq_UDPQueuePut(seq=0x%04X, cmd=0x%04X)\n", icq_PacketReadUDPOutSeq1(p),
          icq_PacketReadUDPOutCmd(p));
 #endif
-  ptr->attempts = attempt;
-  ptr->expire = time(0L)+link->icq_UDPExpireInterval;
+  ptr->attempts = 1;
+  ptr->timeout = icq_TimeoutNew(link->icq_UDPExpireInterval, 
+    (icq_TimeoutHandler)icq_UDPQueueItemResend, ptr);
+  ptr->timeout->single_shot = 0;
   ptr->pack = p;
+  ptr->icqlink = link;
 #ifdef QUEUE_DEBUG
   printf("enqueuing queueitem %p\n", ptr);
 #endif
   list_enqueue(link->d->icq_UDPQueue, ptr);
 }
 
-icq_Packet *icq_UDPQueueGet(ICQLINK *link)
-{
-  icq_UDPQueueItem *ptr = (icq_UDPQueueItem*)list_first(link->d->icq_UDPQueue);
-  icq_Packet *pack = 0L;
-  if(ptr)
-  {
-    pack = ptr->pack;
-    list_remove(link->d->icq_UDPQueue, (list_node*)ptr);
-  }
-#ifdef QUEUE_DEBUG
-  if(pack)
-    printf("icq_UDPQueueGet(cmd=0x%04X)\n", icq_PacketReadUDPOutCmd(pack));
-#endif
-  return pack;
-}
-
-icq_Packet *icq_UDPQueuePeek(ICQLINK *link)
-{
-  icq_UDPQueueItem *ptr = (icq_UDPQueueItem*)list_first(link->d->icq_UDPQueue);
-  if(ptr)
-    return ptr->pack;
-  else
-    return 0L;
-}
-
 void _icq_UDPQueueItemFree(void *p)
 {
   icq_UDPQueueItem *pitem=(icq_UDPQueueItem *)p;
@@ -113,6 +94,9 @@
   if (pitem->pack)
     icq_PacketDelete(pitem->pack);
 
+  if (pitem->timeout)
+    icq_TimeoutDelete(pitem->timeout);
+
   free(p);
 }
 
@@ -165,14 +149,16 @@
 #endif
 }
 
-long icq_UDPQueueInterval(ICQLINK *link)
+void icq_UDPQueueItemResend(icq_UDPQueueItem *p)
 {
-  long interval;
-  icq_UDPQueueItem *ptr = (icq_UDPQueueItem*)list_first(link->d->icq_UDPQueue);
-  if(ptr)
+  p->attempts++;
+  if (p->attempts > 6)
   {
-    interval = ptr->expire - time(0L);
-    return interval>=0?interval:0;
+    icq_Disconnect(p->icqlink);
+    invoke_callback(p->icqlink, icq_Disconnected)(p->icqlink);
+    return;
   }
-  return -1;
+
+  icq_UDPSockWriteDirect(p->icqlink, p->pack);
 }
+
--- a/plugins/icq/queue.h	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/queue.h	Thu Feb 22 23:07:34 2001 +0000
@@ -8,22 +8,22 @@
 
 #include "icq.h"
 #include "icqpacket.h"
+#include "timeout.h"
 
 typedef struct udp_item
 {
   unsigned char attempts;
-  unsigned long expire;
+  icq_Timeout *timeout;
   icq_Packet *pack;
+  ICQLINK *icqlink;
 } icq_UDPQueueItem;
 
 void icq_UDPQueueNew(ICQLINK*);
 void icq_UDPQueueFree(ICQLINK*);
-void icq_UDPQueuePut(ICQLINK*, icq_Packet*, int);
-icq_Packet *icq_UDPQueueGet(ICQLINK*);
-icq_Packet *icq_UDPQueuePeek(ICQLINK*);
+void icq_UDPQueuePut(ICQLINK*, icq_Packet*);
 void icq_UDPQueueDelete(ICQLINK*);
 void icq_UDPQueueFree(ICQLINK*);
 void icq_UDPQueueDelSeq(ICQLINK*, WORD);
-long icq_UDPQueueInterval(ICQLINK *);
+void icq_UDPQueueItemResend(icq_UDPQueueItem *pitem);
 
 #endif
--- a/plugins/icq/socketmanager.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/socketmanager.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,7 +1,7 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
 /*
-  $Id: socketmanager.c 1442 2001-01-28 01:52:27Z warmenhoven $
+  $Id: socketmanager.c 1508 2001-02-22 23:07:34Z warmenhoven $
 */
 
 #include "socketmanager.h"
@@ -47,6 +47,8 @@
 fd_set icq_FdSets[ICQ_SOCKET_MAX];
 int icq_MaxSocket;
 
+void (*icq_SocketNotify)(int socket, int type, int status);
+
 /**
  * Creates a new socket using the operating system's socket creation
  * facitily.
@@ -143,7 +145,6 @@
     s->handlers[type] = handler;
     if (icq_SocketNotify)
       (*icq_SocketNotify)(socket, type, handler ? 1 : 0);
-    icq_SocketBuildFdSets();
   }
 }
 
@@ -170,11 +171,11 @@
   int i;
 
   for (i=0; i<ICQ_SOCKET_MAX; i++)
-    if (s->handlers[i])
-      FD_SET(s->socket, &icq_FdSets[i]);
-
-  if (s->socket > icq_MaxSocket)
-    icq_MaxSocket = s->socket;
+    if (s->handlers[i]) {
+      FD_SET(s->socket, &(icq_FdSets[i]));
+      if (s->socket > icq_MaxSocket)
+        icq_MaxSocket = s->socket;
+    }
 
   return 0; /* traverse entire list */
 }
@@ -182,10 +183,10 @@
 void icq_SocketBuildFdSets()
 {
   int i;
-  
+
   /* clear fdsets */
   for (i=0; i<ICQ_SOCKET_MAX; i++)
-    FD_ZERO(&icq_FdSets[i]);
+    FD_ZERO(&(icq_FdSets[i]));
 
   icq_MaxSocket = 0;
   
@@ -199,8 +200,9 @@
   int i;
 
   for (i=0; i<ICQ_SOCKET_MAX; i++)
-    if (FD_ISSET(s->socket, &icq_FdSets[i]))
+    if (FD_ISSET(s->socket, &(icq_FdSets[i]))) {
       icq_SocketReady(s, i);
+    }
 
   return 0; /* traverse entire list */
 }
@@ -211,10 +213,13 @@
   int max_socket = 0;
   int i;
 
-  tv.tv_sec = 0; tv.tv_usec = 0;
+  icq_SocketBuildFdSets();
   
+  tv.tv_sec = 0; tv.tv_usec = 0;
+    
   /* determine which sockets require maintenance */
-  select(icq_MaxSocket+1, &icq_FdSets[0], &icq_FdSets[1], NULL, &tv);
+  select(icq_MaxSocket+1, &(icq_FdSets[ICQ_SOCKET_READ]),
+    &(icq_FdSets[ICQ_SOCKET_WRITE]), NULL, &tv);
 
   /* handle ready sockets */
   (void)list_traverse(icq_SocketList, _icq_SocketHandleReady);
--- a/plugins/icq/tcp.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/tcp.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,9 +1,12 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
-$Id: tcp.c 1442 2001-01-28 01:52:27Z warmenhoven $
+$Id: tcp.c 1508 2001-02-22 23:07:34Z warmenhoven $
 $Log$
-Revision 1.3  2001/01/28 01:52:27  warmenhoven
-icqlib 1.1.5
+Revision 1.4  2001/02/22 23:07:34  warmenhoven
+updating icqlib
+
+Revision 1.39  2001/02/22 05:40:04  bills
+port tcp connect timeout code and UDP queue to new timeout manager
 
 Revision 1.38  2001/01/17 01:29:17  bills
 Rework chat and file session interfaces; implement socket notifications.
@@ -192,16 +195,6 @@
   list_delete(link->d->icq_FileSessions, icq_FileSessionDelete);
 }
 
-/* need to do this somehow...
-
-    if((time(0L) - plink->connect_time) > TCP_LINK_CONNECT_TIMEOUT)
-    {
-      icq_TCPLinkClose(plink);
-      return 0;
-    }
-  }
-*/
-
 icq_TCPLink *icq_TCPCheckLink(ICQLINK *link, DWORD uin, int type)
 {
   icq_TCPLink *plink=icq_FindTCPLink(link, uin, type);
--- a/plugins/icq/tcplink.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/tcplink.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,9 +1,12 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
-$Id: tcplink.c 1442 2001-01-28 01:52:27Z warmenhoven $
+$Id: tcplink.c 1508 2001-02-22 23:07:34Z warmenhoven $
 $Log$
-Revision 1.3  2001/01/28 01:52:27  warmenhoven
-icqlib 1.1.5
+Revision 1.4  2001/02/22 23:07:34  warmenhoven
+updating icqlib
+
+Revision 1.44  2001/02/22 05:40:04  bills
+port tcp connect timeout code and UDP queue to new timeout manager
 
 Revision 1.43  2001/01/27 22:48:01  bills
 fix bugs related to TCP and new socket manager: implemented accepting TCP
@@ -211,6 +214,7 @@
   p->remote_version=0;
   p->flags=0;
   p->proxy_status = 0;
+  p->connect_timeout = NULL;
 
   if(p)
     list_enqueue(link->d->icq_TCPLinks, p);
@@ -269,6 +273,11 @@
     icq_SocketDelete(p->socket);
   }
 
+  if (p->connect_timeout)
+  {
+    icq_TimeoutDelete(p->connect_timeout);
+  }
+
   free(p);
 }
 
@@ -583,8 +592,6 @@
 
   plink->remote_uin=uin;
 
-  plink->connect_time=time(0L);
-
   /* Send the hello packet */
   p=icq_TCPCreateInitPacket(plink);
   icq_TCPLinkSend(plink, p);
@@ -595,6 +602,8 @@
 
   icq_SocketSetHandler(plink->socket, ICQ_SOCKET_WRITE,
     icq_TCPLinkOnConnect, plink);
+  plink->connect_timeout=icq_TimeoutNew(TCP_LINK_CONNECT_TIMEOUT,
+    (icq_TimeoutHandler)icq_TCPLinkClose, plink);
   
   return 1;
 }
@@ -843,6 +852,9 @@
 #endif
   int error;
   
+  icq_TimeoutDelete(plink->connect_timeout);
+  plink->connect_timeout = NULL;
+
   /* check getsockopt */
   len=sizeof(error);
 
--- a/plugins/icq/tcplink.h	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/tcplink.h	Thu Feb 22 23:07:34 2001 +0000
@@ -18,7 +18,7 @@
 
 #include "icq.h"
 #include "icqpacket.h"
-#include "list.h"
+#include "timeout.h"
 
 /* link mode bitfield values */
 #define TCP_LINK_MODE_RAW             1
@@ -68,8 +68,8 @@
    unsigned long remote_uin;
    char flags;
 
-   /* connect timer */
-   time_t connect_time;
+   /* timeout for connect operation */
+   icq_Timeout *connect_timeout;
 
 };
 
@@ -85,6 +85,7 @@
 void icq_TCPLinkOnDataReceived(icq_TCPLink *plink);
 void icq_TCPLinkOnPacketReceived(icq_TCPLink *plink, icq_Packet *p);
 void icq_TCPLinkOnConnect(icq_TCPLink *plink);
+void icq_TCPLinkOnConnectTimeout(icq_TCPLink *plink);
 
 unsigned long icq_TCPLinkSendSeq(icq_TCPLink *plink, icq_Packet *p,
   unsigned long sequence);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/icq/timeout.c	Thu Feb 22 23:07:34 2001 +0000
@@ -0,0 +1,83 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+#include "timeout.h"
+
+list *icq_TimeoutList = NULL;
+
+void (*icq_SetTimeout)(long length);
+
+int icq_TimeoutCompare(icq_Timeout *t1, icq_Timeout *t2)
+{
+  return (t1->expire_time - t2->expire_time);
+}
+
+icq_Timeout *icq_TimeoutNew(int length, icq_TimeoutHandler handler, 
+  void *data)
+{
+  icq_Timeout *t = (icq_Timeout *)malloc(sizeof(icq_Timeout));
+
+  if (t)
+  {
+    int count = icq_TimeoutList->count;
+
+    t->length = length;
+    t->handler = handler;
+    t->data = data;
+    t->expire_time = time(NULL) + length;
+    t->single_shot = 1;
+
+    list_insert_sorted(icq_TimeoutList, t);
+
+    if (count == 0)
+      icq_TimeoutDoNotify();
+  }
+
+  return t;
+}
+
+void icq_TimeoutDelete(icq_Timeout *timeout)
+{
+  list_remove(icq_TimeoutList, timeout);
+  free(timeout);
+}
+
+int _icq_HandleTimeout(void *p, va_list data)
+{
+  icq_Timeout *t = p;
+  time_t current_time = va_arg(data, time_t);
+  int complete = 0;
+
+  if (t->expire_time <= current_time)
+    (*t->handler)(t->data);
+  else
+    /* traversal is complete when we reach an expire time in the future */
+    complete = 1;
+
+  if (t->single_shot)
+    icq_TimeoutDelete(t);
+  else
+    t->expire_time = current_time + t->length;
+
+  return complete;
+}
+
+void icq_HandleTimeout()
+{
+  time_t current_time = time(NULL);
+
+  /* call handler functions for all timeouts that have expired */
+  list_traverse(icq_TimeoutList, _icq_HandleTimeout, current_time);
+
+  if (icq_TimeoutList->count)
+    icq_TimeoutDoNotify();
+}  
+
+void icq_TimeoutDoNotify()
+{
+  time_t current_time = time(NULL);
+
+  icq_Timeout *t = (icq_Timeout *)list_first(icq_TimeoutList);
+  long length = t->expire_time - current_time;
+  if (icq_SetTimeout)
+    (*icq_SetTimeout)(length);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/icq/timeout.h	Thu Feb 22 23:07:34 2001 +0000
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+#ifndef _TIMEOUTMANAGER_H
+#define _TIMEOUTMANAGER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <time.h>
+
+#include "list.h"
+
+typedef struct icq_Timeout_s icq_Timeout;
+typedef void (*icq_TimeoutHandler)(void *data);
+
+struct icq_Timeout_s
+{
+  time_t expire_time;
+  int length;
+  int single_shot;
+
+  icq_TimeoutHandler handler;
+  void *data;
+};
+
+int icq_TimeoutCompare(icq_Timeout *t1, icq_Timeout *t2);
+icq_Timeout *icq_TimeoutNew(int length, icq_TimeoutHandler handler, 
+  void *data);
+void icq_TimeoutDelete(icq_Timeout *timeout);
+
+void icq_HandleTimeout();
+void icq_TimeoutDoNotify();
+
+extern list *icq_TimeoutList;
+
+#endif /* _TIMEOUTMANAGER_H */
--- a/plugins/icq/udp.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/udp.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,9 +1,12 @@
-/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2  -*- */
 /*
-$Id: udp.c 1442 2001-01-28 01:52:27Z warmenhoven $
+$Id: udp.c 1508 2001-02-22 23:07:34Z warmenhoven $
 $Log$
-Revision 1.3  2001/01/28 01:52:27  warmenhoven
-icqlib 1.1.5
+Revision 1.4  2001/02/22 23:07:34  warmenhoven
+updating icqlib
+
+Revision 1.28  2001/02/22 05:40:04  bills
+port tcp connect timeout code and UDP queue to new timeout manager
 
 Revision 1.27  2001/01/16 00:10:13  denis
 Invisible list has been finished.
@@ -259,16 +262,8 @@
 
 int icq_UDPSockWrite(ICQLINK *link, icq_Packet *p)
 {
-  icq_Packet *qp;
-  WORD cmd = icq_PacketReadUDPOutCmd(p);
-  if(cmd != UDP_CMD_ACK && cmd != UDP_CMD_SEND_TEXT_CODE)
-  {
-    qp = (icq_Packet*)malloc(sizeof(icq_Packet));
-    memcpy(qp, p, sizeof(icq_Packet));
-    icq_UDPQueuePut(link, qp, 1);
-    if(link->icq_SetTimeout)
-      link->icq_SetTimeout(link, icq_UDPQueueInterval(link));
-  }
+  icq_UDPQueuePut(link, p);
+
   return icq_UDPSockWriteDirect(link, p);
 }
 
@@ -302,33 +297,6 @@
   }
 }
 
-void icq_HandleTimeout(ICQLINK *link)
-{
-  icq_UDPQueueItem *ptr = 0;
-  icq_Packet *sp = 0, *pack = 0;
-  int attempt;
-  while(icq_UDPQueueInterval(link) == 0)
-  {
-    ptr = (icq_UDPQueueItem*)list_first(link->d->icq_UDPQueue);
-    attempt = ptr->attempts + 1;
-    if(attempt > 6)
-    {
-      icq_Disconnect(link);
-      if(link->icq_Disconnected)
-        link->icq_Disconnected(link);
-      return;
-    }
-    pack = icq_UDPQueueGet(link);
-    sp = (icq_Packet*)malloc(sizeof(icq_Packet));
-    memcpy(sp, pack, sizeof(icq_Packet));
-    icq_UDPQueuePut(link, pack, attempt);
-    if(link->icq_SetTimeout)
-      link->icq_SetTimeout(link, icq_UDPQueueInterval(link));
-    icq_UDPSockWriteDirect(link, sp);
-    icq_PacketDelete(sp);
-  }
-}
-
 /****************************************
 This must be called every 2 min.
 so the server knows we're still alive.
@@ -339,16 +307,9 @@
 {
   icq_Packet *p = icq_UDPCreateStdSeqPacket(link, UDP_CMD_KEEP_ALIVE, link->d->icq_UDPSeqNum1++);
   icq_PacketAppend32(p, rand());
-  icq_UDPSockWrite(link, p);
+  icq_UDPSockWriteDirect(link, p); /* don't queue keep alive packets! */
   icq_PacketDelete(p);
 
-/*  icq_Packet *p = icq_UDPCreateStdPacket(UDP_CMD_KEEP_ALIVE);
-  icq_UDPSockWrite(icq_UDPSok, p);
-  icq_PacketDelete(p);*/
-/*  p = icq_UDPCreateStdPacket(UDP_CMD_KEEP_ALIVE2);
-  icq_UDPSockWrite(icq_Sok, p);
-  icq_PacketDelete(p);*/
-
   icq_FmtLog(link, ICQ_LOG_MESSAGE, "Send Keep Alive packet to the server\n");
 
   return link->d->icq_UDPSeqNum1-1;
@@ -363,7 +324,6 @@
   icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_ACK_MESSAGES);
   icq_PacketAppend32(p, rand());
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /*************************************
@@ -389,7 +349,6 @@
     icq_PacketGotoUDPOutData(p, 0);
     icq_PacketAppend8(p, num_used);
     icq_UDPSockWrite(link, p);
-    icq_PacketDelete(p);
   }
 }
 
@@ -398,7 +357,6 @@
   icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_ADD_TO_LIST);
   icq_PacketAppend32(p, uin);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /*************************************
@@ -428,8 +386,8 @@
     icq_PacketGotoUDPOutData(p, 0);
     icq_PacketAppend8(p, num_used);
     icq_UDPSockWrite(link, p);
-  }
-  icq_PacketDelete(p);
+  } else
+    icq_PacketDelete(p);
 }
 
 void icq_SendInvisibleList(ICQLINK *link) /* V5 */
@@ -454,8 +412,8 @@
     icq_PacketGotoUDPOutData(p, 0);
     icq_PacketAppend8(p, num_used);
     icq_UDPSockWrite(link, p);
-  }
-  icq_PacketDelete(p);
+  } else
+    icq_PacketDelete(p);
 }
 
 /**************************************
@@ -467,7 +425,6 @@
   icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_LOGIN_1);
   icq_PacketAppend32(p, rand());
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /************************************
@@ -515,7 +472,6 @@
   icq_PacketAppend32(p, LOGIN_X5_DEF);
 
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /**********************
@@ -527,7 +483,7 @@
   icq_PacketAppendString(p, "B_USER_DISCONNECTED");
   icq_PacketAppend8(p, 5);
   icq_PacketAppend8(p, 0);
-  icq_UDPSockWrite(link, p);
+  icq_UDPSockWriteDirect(link, p); /* don't queue */
   icq_PacketDelete(p);
 }
 
@@ -543,7 +499,6 @@
 
   icq_FmtLog(link, ICQ_LOG_MESSAGE, "Acking\n");
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /***************************************************
@@ -564,7 +519,6 @@
   icq_PacketAppendString(p, buf);
 
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum1-1;
 }
 
@@ -585,7 +539,6 @@
   icq_PacketAppendString0(p, buf2);
 
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum1-1;
 }
 
@@ -600,7 +553,6 @@
   icq_PacketAppend32(p, TYPE_AUTH);
   icq_PacketAppend16(p, 0);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 
   return link->d->icq_UDPSeqNum1-1;
 }
@@ -614,7 +566,6 @@
   icq_PacketAppend32(p, status);
   link->icq_Status = status;
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /********************************************************
@@ -625,7 +576,6 @@
   icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_INFO_REQ);
   icq_PacketAppend32(p, uin);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum1-1;
 }
 
@@ -637,7 +587,6 @@
   icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_EXT_INFO_REQ);
   icq_PacketAppend32(p, uin);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum1-1;
 }
 
@@ -653,7 +602,6 @@
   icq_PacketAppendString(p, last);
   icq_PacketAppendString(p, email);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /**************************************************************
@@ -664,7 +612,6 @@
   icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_SEARCH_UIN);
   icq_PacketAppend32(p, uin);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
 }
 
 /**************************************************
@@ -685,7 +632,6 @@
   icq_PacketAppend32(p, rand());
   icq_UDPSockWrite(link, p);
   icq_FmtLog(link, ICQ_LOG_MESSAGE, "Send RegNewUser packet to the server\n");
-  icq_PacketDelete(p);
 }
 
 WORD icq_UpdateUserInfo(ICQLINK *link, const char *nick, const char *first, const char *last,
@@ -698,7 +644,6 @@
   icq_PacketAppendString(p, email);
 /* auth (byte)? */
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum1-1;
 }
 
@@ -707,7 +652,6 @@
   icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_UPDATE_AUTH);
   icq_PacketAppend32(p, auth); /* NOT auth? */
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum1-1;
 }
 
@@ -736,7 +680,6 @@
   icq_PacketAppend8(p, cnt_stat);
   icq_PacketAppend8(p, emailhide);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum2-1;
 }
 
@@ -756,7 +699,6 @@
   icq_PacketAppend8(p, 0xFF /* lang2 */);
   icq_PacketAppend8(p, 0xFF /* lang3 */);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum2-1;
 }
 
@@ -766,7 +708,6 @@
   icq_PacketAppend16(p, META_CMD_SET_ABOUT);
   icq_PacketAppendString(p, about);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum2-1;
 }
 
@@ -779,7 +720,6 @@
   icq_PacketAppend8(p, webpresence);
   icq_PacketAppend8(p, pubip);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum2-1;
 }
 
@@ -795,7 +735,6 @@
   icq_PacketAppend8(p, 1);
   icq_PacketAppend8(p, 1);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum1-1;
 }
 
@@ -805,6 +744,5 @@
   icq_PacketAppend16(p, META_CMD_REQ_INFO);
   icq_PacketAppend32(p, uin);
   icq_UDPSockWrite(link, p);
-  icq_PacketDelete(p);
   return link->d->icq_UDPSeqNum2-1;
 }
--- a/plugins/icq/udphandle.c	Thu Feb 22 22:50:03 2001 +0000
+++ b/plugins/icq/udphandle.c	Thu Feb 22 23:07:34 2001 +0000
@@ -1,9 +1,12 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
-$Id: udphandle.c 1442 2001-01-28 01:52:27Z warmenhoven $
+$Id: udphandle.c 1508 2001-02-22 23:07:34Z warmenhoven $
 $Log$
-Revision 1.3  2001/01/28 01:52:27  warmenhoven
-icqlib 1.1.5
+Revision 1.4  2001/02/22 23:07:34  warmenhoven
+updating icqlib
+
+Revision 1.31  2001/02/22 05:40:04  bills
+port tcp connect timeout code and UDP queue to new timeout manager
 
 Revision 1.30  2001/01/15 06:17:35  denis
 Applied patch from Andrey Chernomyrdin <andrey@excom.spb.su> to
@@ -742,8 +745,6 @@
           (*link->icq_RequestNotify)(link, seq, ICQ_NOTIFY_SUCCESS, 0, 0);
         }
         icq_UDPQueueDelSeq(link, seq);
-        if(link->icq_SetTimeout)
-          link->icq_SetTimeout(link, icq_UDPQueueInterval(link));
         break;
       case UDP_SRV_MULTI_PACKET:
         icq_HandleMultiPacket(link, p);