plugins/icq/icqlib.c

changeset 1432
ab10a52f94a7
parent 1309
dccfec27ffd4
child 1467
6dd0f7f6e93d
--- a/plugins/icq/icqlib.c	Sat Jan 27 11:18:17 2001 +0000
+++ b/plugins/icq/icqlib.c	Sun Jan 28 01:52:27 2001 +0000
@@ -1,9 +1,18 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
-$Id: icqlib.c 1319 2000-12-19 10:08:29Z warmenhoven $
+$Id: icqlib.c 1442 2001-01-28 01:52:27Z warmenhoven $
 $Log$
-Revision 1.2  2000/12/19 10:08:29  warmenhoven
-Yay, new icqlib
+Revision 1.3  2001/01/28 01:52:27  warmenhoven
+icqlib 1.1.5
+
+Revision 1.49  2001/01/17 01:29:17  bills
+Rework chat and file session interfaces; implement socket notifications.
+
+Revision 1.48  2001/01/15 06:20:24  denis
+Cleanup.
+
+Revision 1.47  2000/12/19 21:29:51  bills
+actually return the link in icq_ICQLINKNew
 
 Revision 1.46  2000/12/19 06:00:07  bills
 moved members from ICQLINK to ICQLINK_private struct
@@ -17,121 +26,7 @@
 
 Revision 1.43  2000/07/09 22:05:11  bills
 removed unnecessary functions
-
-Revision 1.42  2000/07/09 18:28:07  denis
-Initial memset() in icq_Init() replaced by callback's clearance.
-
-Revision 1.41  2000/06/15 01:50:39  bills
-removed *Seq functions
-
-Revision 1.40  2000/05/10 19:06:59  denis
-UDP outgoing packet queue was implemented.
-
-Revision 1.39  2000/05/03 18:12:36  denis
-Unfinished UDP queue was commented out.
-
-Revision 1.38  2000/04/10 16:36:04  denis
-Some more Win32 compatibility from Guillaume Rosanis <grs@mail.com>
-
-Revision 1.37  2000/04/06 16:38:04  denis
-icq_*Send*Seq() functions with specified sequence number were added.
-
-Revision 1.36  2000/04/05 14:37:02  denis
-Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
-compatibility.
-
-Revision 1.35  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.34  1999/12/27 16:06:32  bills
-cleanups
-
-Revision 1.33  1999/10/03 21:35:55  tim
-Fixed "url" and "descr" parameters order when sending a URL via TCP.
-
-Revision 1.32  1999/09/29 16:49:43  denis
-Host/network/icq byteorder systemized.
-icq_Init() cleaned up.
-
-Revision 1.31  1999/07/18 20:15:55  bills
-changed to use new byte-order functions & contact list functions
-
-Revision 1.30  1999/07/16 12:27:06  denis
-Other global variables moved to ICQLINK structure.
-Initialization of random number generator added in icq_Init()
-Cleaned up.
-
-Revision 1.29  1999/07/12 15:13:31  cproch
-- added definition of ICQLINK to hold session-specific global variabled
-  applications which have more than one connection are now possible
-- changed nearly every function defintion to support ICQLINK parameter
-
-Revision 1.28  1999/07/03 02:26:02  bills
-added new code to support thruSrv arg to SendMessage and SendURL
-
-Revision 1.27  1999/04/17 19:21:37  bills
-modified Send* Functions to return DWORD instead of WORD
-
-Revision 1.26  1999/04/14 14:48:18  denis
-Switched from icq_Log callback to icq_Fmt function.
-Cleanups for "strict" compiling (-ansi -pedantic)
-
-Revision 1.25  1999/04/05 13:14:57  denis
-Send messages and URLs to 'not in list' users fixed.
-
-Revision 1.24  1999/03/31 01:43:40  bills
-added TCP support to SendURL
-
-Revision 1.23  1999/03/30 22:47:44  lord
-list of countries now sorted.
-
-Revision 1.22  1999/03/28 03:18:22  bills
-enable tcp messaging in icq_SendMessage, uncommented icq_OurPort and
-icq_OurIp and fixed function names so icqlib compiles
-
-Revision 1.21  1999/03/25 22:16:43  bills
-added #include "util.h"
-
-Revision 1.20  1999/03/24 11:37:36  denis
-Underscored files with TCP stuff renamed.
-TCP stuff cleaned up
-Function names changed to corresponding names.
-icqlib.c splitted to many small files by subject.
-C++ comments changed to ANSI C comments.
-
-Revision 1.19  1999/03/22 20:51:28  bills
-added code in icq_HandleUserOnline to set/clear new struct entries in
-icq_ContactItem; added cleanup code in icq_HandleUserOffline for same
-
-Revision 1.18  1999/03/09 13:14:05  denis
-Cyrillic recoding removed from URLs
-
-Revision 1.17  1999/03/05 13:57:54  denis
-Some cosmetic changes...
-
-Revision 1.16  1998/12/08 16:00:59  denis
-Cleaned up a little before releasing
-
-Revision 1.15  1998/11/25 19:18:16  denis
-Added close icq_ProxySok in icq_Disconnect
-
-Revision 1.14  1998/11/25 09:48:49  denis
-icq_GetProxySok and icq_HandleProxyResponse methods added
-Connection terminated support added
-
-Revision 1.13  1998/11/19 12:22:48  denis
-SOCKS support cleaned a little
-icq_RecvUrl renamed to icq_RecvURL
-icq_ProxyAuth added for Username/Password Authentication
-URL/Description order inverted
-icq_Quit splitted to icq_Logout and icq_Disconnect
-icq_ProxyName and icq_ProxyPass range checking added
-
-Revision 1.12  1998/11/18 16:21:29  denis
-Fixed SOCKS5 proxy support
-
- */
+*/
 
 #include "icqlib.h"
 
@@ -163,10 +58,13 @@
 #include "udp.h"
 #include "tcp.h"
 #include "queue.h"
+#include "socketmanager.h"
 
 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)
@@ -216,14 +114,15 @@
 }
 
 ICQLINK *icq_ICQLINKNew(DWORD uin, const char *password, const char *nick,
-  unsigned char useTCP)
+                        unsigned char useTCP)
 {
-  ICQLINK *link = (ICQLINK *)malloc(sizeof(ICQLINK));
-  link->d = (ICQLINK_private *)malloc(sizeof(ICQLINK_private));
+  ICQLINK *link = (ICQLINK*)malloc(sizeof(ICQLINK));
+  link->d = (ICQLINK_private*)malloc(sizeof(ICQLINK_private));
 
   srand(time(0L));
-
-/*   memset(link, 0, sizeof(ICQLINK)); */
+  /* initialize icq_SocketList on first call */
+  if (!icq_SocketList)
+    icq_SocketList = list_new();
 
   /* Initialize all callbacks */
   link->icq_Logged = 0L;
@@ -276,6 +175,7 @@
   link->d->icq_UDPSession = 0;
   icq_UDPQueueNew(link);
 
+  /* TCP stuff */
   icq_TCPInit(link);
   link->icq_UseTCP = useTCP;
 
@@ -316,17 +216,7 @@
 *******************************/
 void icq_Main(ICQLINK *link)
 {
-  struct timeval tv;
-  fd_set readfds;
-
-  tv.tv_sec = 0;
-  tv.tv_usec = 0;
-  FD_ZERO(&readfds);
-  FD_SET(link->icq_UDPSok, &readfds);
-  select(link->icq_UDPSok+1, &readfds, 0L, 0L, &tv);
-  if(FD_ISSET(link->icq_UDPSok, &readfds))
-    icq_HandleServerResponse(link);
-  icq_TCPMain(link);
+  icq_SocketPoll();
 }
 
 /**********************************
@@ -343,7 +233,9 @@
   struct sockaddr_in sin, prsin;  /* used to store inet addr stuff */
   struct hostent *host_struct; /* used in DNS llokup */
 
-  link->icq_UDPSok = socket(AF_INET, SOCK_DGRAM, 0);/* create the unconnected socket*/
+  /* create the unconnected socket*/
+  link->icq_UDPSok = icq_SocketNew(AF_INET, SOCK_DGRAM, 0);
+
   if(link->icq_UDPSok == -1)
   {
     icq_FmtLog(link, ICQ_LOG_FATAL, "Socket creation failed\n");
@@ -356,6 +248,8 @@
   if(bind(link->icq_UDPSok, (struct sockaddr*)&sin, sizeof(struct sockaddr))<0)
   {
     icq_FmtLog(link, ICQ_LOG_FATAL, "Can't bind socket to free port\n");
+    icq_SocketDelete(link->icq_UDPSok);
+    link->icq_UDPSok = -1;
     return -1;
   }
   length = sizeof(sin);
@@ -378,7 +272,10 @@
     link->icq_ProxyIP = ntohl(prsin.sin_addr.s_addr);
     prsin.sin_family = AF_INET; /* we're using the inet not appletalk*/
     prsin.sin_port = htons(link->icq_ProxyPort); /* port */
-    link->icq_ProxySok = socket(AF_INET, SOCK_STREAM, 0);/* create the unconnected socket*/
+
+    /* create the unconnected socket*/
+    link->icq_ProxySok = icq_SocketNew(AF_INET, SOCK_STREAM, 0);
+
     if(link->icq_ProxySok == -1)
     {
       icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Socket creation failed\n");
@@ -409,11 +306,7 @@
       if(res != 2 || buf[0] != 5 || buf[1] != 2) /* username/password authentication*/
       {
         icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Authentication method incorrect\n");
-#ifdef _WIN32
-        closesocket(link->icq_ProxySok);
-#else
-        close(link->icq_ProxySok);
-#endif
+        icq_SocketDelete(link->icq_ProxySok);
         return -1;
       }
       buf[0] = 1; /* version of subnegotiation */
@@ -431,11 +324,7 @@
       if(res != 2 || buf[0] != 1 || buf[1] != 0)
       {
         icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Authorization failure\n");
-#ifdef _WIN32
-        closesocket(link->icq_ProxySok);
-#else
-        close(link->icq_ProxySok);
-#endif
+        icq_SocketDelete(link->icq_ProxySok);
         return -1;
       }
     }
@@ -444,11 +333,7 @@
       if(res != 2 || buf[0] != 5 || buf[1] != 0) /* no authentication required */
       {
         icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Authentication method incorrect\n");
-#ifdef _WIN32
-        closesocket(link->icq_ProxySok);
-#else
-        close(link->icq_ProxySok);
-#endif
+        icq_SocketDelete(link->icq_ProxySok);
         return -1;
       }
     }
@@ -501,11 +386,8 @@
           icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Unknown SOCKS server failure\n");
           break;
       }
-#ifdef _WIN32
-      closesocket(link->icq_ProxySok);
-#else
-      close(link->icq_ProxySok);
-#endif
+      icq_SocketDelete(link->icq_ProxySok);
+      link->icq_ProxySok = -1;
       return -1;
     }
   }
@@ -518,11 +400,7 @@
       icq_FmtLog(link, ICQ_LOG_FATAL, "Can't find hostname: %s\n", hostname);
       if(link->icq_UseProxy)
       {
-#ifdef _WIN32
-        closesocket(link->icq_ProxySok);
-#else
-        close(link->icq_ProxySok);
-#endif
+        icq_SocketDelete(link->icq_ProxySok);
       }
       return -1;
     }
@@ -546,11 +424,7 @@
     icq_FmtLog(link, ICQ_LOG_FATAL, "Connection refused\n");
     if(link->icq_UseProxy)
     {
-#ifdef _WIN32
-      closesocket(link->icq_ProxySok);
-#else
-      close(link->icq_ProxySok);
-#endif
+      icq_SocketDelete(link->icq_ProxySok);
     }
     return -1;
   }
@@ -558,23 +432,22 @@
   getsockname(link->icq_UDPSok, (struct sockaddr*)&sin, &length);
   link->icq_OurIP = ntohl(sin.sin_addr.s_addr);
   link->icq_OurPort = ntohs(sin.sin_port);
+
+  /* sockets are ready to receive data - install handlers */
+  icq_SocketSetHandler(link->icq_UDPSok, ICQ_SOCKET_READ,
+    icq_HandleServerResponse, link);
+  if (link->icq_UseProxy)
+    icq_SocketSetHandler(link->icq_ProxySok, ICQ_SOCKET_READ,
+      icq_HandleProxyResponse, link);
   return link->icq_UDPSok;
 }
 
 void icq_Disconnect(ICQLINK *link)
 {
-#ifdef _WIN32
-  closesocket(link->icq_UDPSok);
-#else
-  close(link->icq_UDPSok);
-#endif
+  icq_SocketDelete(link->icq_UDPSok);
   if(link->icq_UseProxy)
   {
-#ifdef _WIN32
-    closesocket(link->icq_ProxySok);
-#else
-    close(link->icq_ProxySok);
-#endif
+    icq_SocketDelete(link->icq_ProxySok);
   }
   icq_UDPQueueFree(link);
 }

mercurial