1152
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2 /*
|
|
3 $Id: icqlib.c 1162 2000-11-28 02:22:42Z warmenhoven $
|
|
4 $Log$
|
|
5 Revision 1.1 2000/11/28 02:22:42 warmenhoven
|
|
6 icq. whoop de doo
|
|
7
|
|
8 Revision 1.44 2000/07/24 03:10:08 bills
|
|
9 added support for real nickname during TCP transactions like file and
|
|
10 chat, instead of using Bill all the time (hmm, where'd I get that from? :)
|
|
11
|
|
12 Revision 1.43 2000/07/09 22:05:11 bills
|
|
13 removed unnecessary functions
|
|
14
|
|
15 Revision 1.42 2000/07/09 18:28:07 denis
|
|
16 Initial memset() in icq_Init() replaced by callback's clearance.
|
|
17
|
|
18 Revision 1.41 2000/06/15 01:50:39 bills
|
|
19 removed *Seq functions
|
|
20
|
|
21 Revision 1.40 2000/05/10 19:06:59 denis
|
|
22 UDP outgoing packet queue was implemented.
|
|
23
|
|
24 Revision 1.39 2000/05/03 18:12:36 denis
|
|
25 Unfinished UDP queue was commented out.
|
|
26
|
|
27 Revision 1.38 2000/04/10 16:36:04 denis
|
|
28 Some more Win32 compatibility from Guillaume Rosanis <grs@mail.com>
|
|
29
|
|
30 Revision 1.37 2000/04/06 16:38:04 denis
|
|
31 icq_*Send*Seq() functions with specified sequence number were added.
|
|
32
|
|
33 Revision 1.36 2000/04/05 14:37:02 denis
|
|
34 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
|
|
35 compatibility.
|
|
36
|
|
37 Revision 1.35 2000/01/16 03:59:10 bills
|
|
38 reworked list code so list_nodes don't need to be inside item structures,
|
|
39 removed strlist code and replaced with generic list calls
|
|
40
|
|
41 Revision 1.34 1999/12/27 16:06:32 bills
|
|
42 cleanups
|
|
43
|
|
44 Revision 1.33 1999/10/03 21:35:55 tim
|
|
45 Fixed "url" and "descr" parameters order when sending a URL via TCP.
|
|
46
|
|
47 Revision 1.32 1999/09/29 16:49:43 denis
|
|
48 Host/network/icq byteorder systemized.
|
|
49 icq_Init() cleaned up.
|
|
50
|
|
51 Revision 1.31 1999/07/18 20:15:55 bills
|
|
52 changed to use new byte-order functions & contact list functions
|
|
53
|
|
54 Revision 1.30 1999/07/16 12:27:06 denis
|
|
55 Other global variables moved to ICQLINK structure.
|
|
56 Initialization of random number generator added in icq_Init()
|
|
57 Cleaned up.
|
|
58
|
|
59 Revision 1.29 1999/07/12 15:13:31 cproch
|
|
60 - added definition of ICQLINK to hold session-specific global variabled
|
|
61 applications which have more than one connection are now possible
|
|
62 - changed nearly every function defintion to support ICQLINK parameter
|
|
63
|
|
64 Revision 1.28 1999/07/03 02:26:02 bills
|
|
65 added new code to support thruSrv arg to SendMessage and SendURL
|
|
66
|
|
67 Revision 1.27 1999/04/17 19:21:37 bills
|
|
68 modified Send* Functions to return DWORD instead of WORD
|
|
69
|
|
70 Revision 1.26 1999/04/14 14:48:18 denis
|
|
71 Switched from icq_Log callback to icq_Fmt function.
|
|
72 Cleanups for "strict" compiling (-ansi -pedantic)
|
|
73
|
|
74 Revision 1.25 1999/04/05 13:14:57 denis
|
|
75 Send messages and URLs to 'not in list' users fixed.
|
|
76
|
|
77 Revision 1.24 1999/03/31 01:43:40 bills
|
|
78 added TCP support to SendURL
|
|
79
|
|
80 Revision 1.23 1999/03/30 22:47:44 lord
|
|
81 list of countries now sorted.
|
|
82
|
|
83 Revision 1.22 1999/03/28 03:18:22 bills
|
|
84 enable tcp messaging in icq_SendMessage, uncommented icq_OurPort and
|
|
85 icq_OurIp and fixed function names so icqlib compiles
|
|
86
|
|
87 Revision 1.21 1999/03/25 22:16:43 bills
|
|
88 added #include "util.h"
|
|
89
|
|
90 Revision 1.20 1999/03/24 11:37:36 denis
|
|
91 Underscored files with TCP stuff renamed.
|
|
92 TCP stuff cleaned up
|
|
93 Function names changed to corresponding names.
|
|
94 icqlib.c splitted to many small files by subject.
|
|
95 C++ comments changed to ANSI C comments.
|
|
96
|
|
97 Revision 1.19 1999/03/22 20:51:28 bills
|
|
98 added code in icq_HandleUserOnline to set/clear new struct entries in
|
|
99 icq_ContactItem; added cleanup code in icq_HandleUserOffline for same
|
|
100
|
|
101 Revision 1.18 1999/03/09 13:14:05 denis
|
|
102 Cyrillic recoding removed from URLs
|
|
103
|
|
104 Revision 1.17 1999/03/05 13:57:54 denis
|
|
105 Some cosmetic changes...
|
|
106
|
|
107 Revision 1.16 1998/12/08 16:00:59 denis
|
|
108 Cleaned up a little before releasing
|
|
109
|
|
110 Revision 1.15 1998/11/25 19:18:16 denis
|
|
111 Added close icq_ProxySok in icq_Disconnect
|
|
112
|
|
113 Revision 1.14 1998/11/25 09:48:49 denis
|
|
114 icq_GetProxySok and icq_HandleProxyResponse methods added
|
|
115 Connection terminated support added
|
|
116
|
|
117 Revision 1.13 1998/11/19 12:22:48 denis
|
|
118 SOCKS support cleaned a little
|
|
119 icq_RecvUrl renamed to icq_RecvURL
|
|
120 icq_ProxyAuth added for Username/Password Authentication
|
|
121 URL/Description order inverted
|
|
122 icq_Quit splitted to icq_Logout and icq_Disconnect
|
|
123 icq_ProxyName and icq_ProxyPass range checking added
|
|
124
|
|
125 Revision 1.12 1998/11/18 16:21:29 denis
|
|
126 Fixed SOCKS5 proxy support
|
|
127
|
|
128 */
|
|
129
|
|
130 #include "icqlib.h"
|
|
131
|
|
132 #include <stdlib.h>
|
|
133
|
|
134 #ifndef _WIN32
|
|
135 #include <unistd.h>
|
|
136 #endif
|
|
137
|
|
138 #include <time.h>
|
|
139
|
|
140 #ifdef _WIN32
|
|
141 #include <winsock.h>
|
|
142 #else
|
|
143 #include <netdb.h>
|
|
144 #include <sys/socket.h>
|
|
145 #endif
|
|
146
|
|
147 #include <sys/stat.h>
|
|
148
|
|
149 #ifndef _WIN32
|
|
150 #include <sys/time.h>
|
|
151 #include <netinet/in.h>
|
|
152 #endif
|
|
153
|
|
154 #include "util.h"
|
|
155 #include "icqtypes.h"
|
|
156 #include "icq.h"
|
|
157 #include "udp.h"
|
|
158 #include "tcp.h"
|
|
159 #include "queue.h"
|
|
160
|
|
161 int icq_Russian = FALSE;
|
|
162 BYTE icq_LogLevel = 0;
|
|
163
|
|
164 DWORD icq_SendMessage(ICQLINK *link, DWORD uin, const char *text, BYTE thruSrv)
|
|
165 {
|
|
166 if(thruSrv==ICQ_SEND_THRUSERVER)
|
|
167 return icq_UDPSendMessage(link, uin, text);
|
|
168 else if(thruSrv==ICQ_SEND_DIRECT)
|
|
169 return icq_TCPSendMessage(link, uin, text);
|
|
170 else if(thruSrv==ICQ_SEND_BESTWAY)
|
|
171 {
|
|
172 icq_ContactItem *pcontact=icq_ContactFind(link, uin);
|
|
173 if(pcontact)
|
|
174 {
|
|
175 if(pcontact->tcp_flag == 0x04)
|
|
176 return icq_TCPSendMessage(link, uin, text);
|
|
177 else
|
|
178 return icq_UDPSendMessage(link, uin, text);
|
|
179 }
|
|
180 else
|
|
181 {
|
|
182 return icq_UDPSendMessage(link, uin, text);
|
|
183 }
|
|
184 }
|
|
185 return 0;
|
|
186 }
|
|
187
|
|
188 DWORD icq_SendURL(ICQLINK *link, DWORD uin, const char *url, const char *descr, BYTE thruSrv)
|
|
189 {
|
|
190 if(thruSrv==ICQ_SEND_THRUSERVER)
|
|
191 return icq_UDPSendURL(link, uin, url, descr);
|
|
192 else if(thruSrv==ICQ_SEND_DIRECT)
|
|
193 return icq_TCPSendURL(link, uin, descr, url);
|
|
194 else if(thruSrv==ICQ_SEND_BESTWAY)
|
|
195 {
|
|
196 icq_ContactItem *pcontact=icq_ContactFind(link, uin);
|
|
197 if(pcontact)
|
|
198 {
|
|
199 if(pcontact->tcp_flag == 0x04)
|
|
200 return icq_TCPSendURL(link, uin, descr, url);
|
|
201 else
|
|
202 return icq_UDPSendURL(link, uin, url, descr);
|
|
203 }
|
|
204 else
|
|
205 {
|
|
206 return icq_UDPSendURL(link, uin, url, descr);
|
|
207 }
|
|
208 }
|
|
209 return 0;
|
|
210 }
|
|
211
|
|
212 void icq_Init(ICQLINK *link, DWORD uin, const char *password,
|
|
213 const char *nick)
|
|
214 {
|
|
215 srand(time(0L));
|
|
216 /* memset(link, 0, sizeof(ICQLINK)); */
|
|
217
|
|
218 /* Initialize all callbacks */
|
|
219 link->icq_Logged = 0L;
|
|
220 link->icq_Disconnected = 0L;
|
|
221 link->icq_RecvMessage = 0L;
|
|
222 link->icq_RecvURL = 0L;
|
|
223 link->icq_RecvWebPager = 0L;
|
|
224 link->icq_RecvMailExpress = 0L;
|
|
225 link->icq_RecvChatReq = 0L;
|
|
226 link->icq_RecvFileReq = 0L;
|
|
227 link->icq_RecvAdded = 0L;
|
|
228 link->icq_RecvAuthReq = 0L;
|
|
229 link->icq_UserFound = 0L;
|
|
230 link->icq_SearchDone = 0L;
|
|
231 link->icq_UserOnline = 0L;
|
|
232 link->icq_UserOffline = 0L;
|
|
233 link->icq_UserStatusUpdate = 0L;
|
|
234 link->icq_InfoReply = 0L;
|
|
235 link->icq_ExtInfoReply = 0L;
|
|
236 link->icq_WrongPassword = 0L;
|
|
237 link->icq_InvalidUIN = 0L;
|
|
238 link->icq_Log = 0L;
|
|
239 link->icq_SrvAck = 0L;
|
|
240 link->icq_RequestNotify = 0L;
|
|
241 link->icq_NewUIN = 0L;
|
|
242 link->icq_SetTimeout = 0L;
|
|
243 link->icq_MetaUserFound = 0L;
|
|
244 link->icq_MetaUserInfo = 0L;
|
|
245 link->icq_MetaUserWork = 0L;
|
|
246 link->icq_MetaUserMore = 0L;
|
|
247 link->icq_MetaUserAbout = 0L;
|
|
248 link->icq_MetaUserInterests = 0L;
|
|
249 link->icq_MetaUserAffiliations = 0L;
|
|
250 link->icq_MetaUserHomePageCategory = 0L;
|
|
251
|
|
252 /* General stuff */
|
|
253 link->icq_Uin = uin;
|
|
254 link->icq_Password = strdup(password);
|
|
255 link->icq_Nick = strdup(nick);
|
|
256 link->icq_OurIP = -1;
|
|
257 link->icq_OurPort = 0;
|
|
258 link->icq_ContactList = list_new();
|
|
259 link->icq_Status = -1;
|
|
260
|
|
261 /* UDP stuff */
|
|
262 link->icq_UDPSok = -1;
|
|
263 memset(link->icq_UDPServMess, FALSE, sizeof(link->icq_UDPServMess));
|
|
264 link->icq_UDPSeqNum1 = 0;
|
|
265 link->icq_UDPSeqNum2 = 0;
|
|
266 link->icq_UDPSession = 0;
|
|
267 icq_UDPQueueNew(link);
|
|
268
|
|
269 icq_TCPInit(link);
|
|
270
|
|
271 /* Proxy stuff */
|
|
272 link->icq_UseProxy = 0;
|
|
273 link->icq_ProxyHost = 0L;
|
|
274 link->icq_ProxyIP = -1;
|
|
275 link->icq_ProxyPort = 0;
|
|
276 link->icq_ProxyAuth = 0;
|
|
277 link->icq_ProxyName = 0L;
|
|
278 link->icq_ProxyPass = 0L;
|
|
279 link->icq_ProxySok = -1;
|
|
280 link->icq_ProxyOurPort = 0;
|
|
281 link->icq_ProxyDestIP = -1;
|
|
282 link->icq_ProxyDestPort = 0;
|
|
283 }
|
|
284
|
|
285 void icq_Done(ICQLINK *link)
|
|
286 {
|
|
287 icq_TCPDone(link);
|
|
288 if(link->icq_Password)
|
|
289 free(link->icq_Password);
|
|
290 if(link->icq_Nick)
|
|
291 free(link->icq_Nick);
|
|
292 if(link->icq_ContactList)
|
|
293 list_delete(link->icq_ContactList, icq_ContactDelete);
|
|
294 icq_UDPQueueDelete(link);
|
|
295 }
|
|
296
|
|
297 /******************************
|
|
298 Main function connects gets icq_Uin
|
|
299 and icq_Password and logins in and sits
|
|
300 in a loop waiting for server responses.
|
|
301 *******************************/
|
|
302 void icq_Main(ICQLINK *link)
|
|
303 {
|
|
304 struct timeval tv;
|
|
305 fd_set readfds;
|
|
306
|
|
307 tv.tv_sec = 0;
|
|
308 tv.tv_usec = 0;
|
|
309 FD_ZERO(&readfds);
|
|
310 FD_SET(link->icq_UDPSok, &readfds);
|
|
311 select(link->icq_UDPSok+1, &readfds, 0L, 0L, &tv);
|
|
312 if(FD_ISSET(link->icq_UDPSok, &readfds))
|
|
313 icq_HandleServerResponse(link);
|
|
314 icq_TCPMain(link);
|
|
315 }
|
|
316
|
|
317 /**********************************
|
|
318 Connects to hostname on port port
|
|
319 hostname can be DNS or nnn.nnn.nnn.nnn
|
|
320 write out messages to the FD aux
|
|
321 ***********************************/
|
|
322 int icq_Connect(ICQLINK *link, const char *hostname, int port)
|
|
323 {
|
|
324 char buf[1024]; /*, un = 1;*/
|
|
325 /* char tmpbuf[256], our_host[256]*/
|
|
326 int conct, res;
|
|
327 unsigned int length;
|
|
328 struct sockaddr_in sin, prsin; /* used to store inet addr stuff */
|
|
329 struct hostent *host_struct; /* used in DNS llokup */
|
|
330
|
|
331 link->icq_UDPSok = socket(AF_INET, SOCK_DGRAM, 0);/* create the unconnected socket*/
|
|
332 if(link->icq_UDPSok == -1)
|
|
333 {
|
|
334 icq_FmtLog(link, ICQ_LOG_FATAL, "Socket creation failed\n");
|
|
335 return -1;
|
|
336 }
|
|
337 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Socket created attempting to connect\n");
|
|
338 sin.sin_addr.s_addr = INADDR_ANY;
|
|
339 sin.sin_family = AF_INET; /* we're using the inet not appletalk*/
|
|
340 sin.sin_port = 0;
|
|
341 if(bind(link->icq_UDPSok, (struct sockaddr*)&sin, sizeof(struct sockaddr))<0)
|
|
342 {
|
|
343 icq_FmtLog(link, ICQ_LOG_FATAL, "Can't bind socket to free port\n");
|
|
344 return -1;
|
|
345 }
|
|
346 length = sizeof(sin);
|
|
347 getsockname(link->icq_UDPSok, (struct sockaddr*)&sin, &length);
|
|
348 link->icq_ProxyOurPort = ntohs(sin.sin_port);
|
|
349 if(link->icq_UseProxy)
|
|
350 {
|
|
351 icq_FmtLog(link, ICQ_LOG_MESSAGE, "[SOCKS] Trying to use SOCKS5 proxy\n");
|
|
352 prsin.sin_addr.s_addr = inet_addr(link->icq_ProxyHost);
|
|
353 if(prsin.sin_addr.s_addr == (unsigned long)-1) /* name isn't n.n.n.n so must be DNS */
|
|
354 {
|
|
355 host_struct = gethostbyname(link->icq_ProxyHost);
|
|
356 if(host_struct == 0L)
|
|
357 {
|
|
358 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Can't find hostname: %s\n", link->icq_ProxyHost);
|
|
359 return -1;
|
|
360 }
|
|
361 prsin.sin_addr = *((struct in_addr*)host_struct->h_addr);
|
|
362 }
|
|
363 link->icq_ProxyIP = ntohl(prsin.sin_addr.s_addr);
|
|
364 prsin.sin_family = AF_INET; /* we're using the inet not appletalk*/
|
|
365 prsin.sin_port = htons(link->icq_ProxyPort); /* port */
|
|
366 link->icq_ProxySok = socket(AF_INET, SOCK_STREAM, 0);/* create the unconnected socket*/
|
|
367 if(link->icq_ProxySok == -1)
|
|
368 {
|
|
369 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Socket creation failed\n");
|
|
370 return -1;
|
|
371 }
|
|
372 icq_FmtLog(link, ICQ_LOG_MESSAGE, "[SOCKS] Socket created attempting to connect\n");
|
|
373 conct = connect(link->icq_ProxySok, (struct sockaddr *) &prsin, sizeof(prsin));
|
|
374 if(conct == -1) /* did we connect ?*/
|
|
375 {
|
|
376 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Connection refused\n");
|
|
377 return -1;
|
|
378 }
|
|
379 buf[0] = 5; /* protocol version */
|
|
380 buf[1] = 1; /* number of methods */
|
|
381 if(!strlen(link->icq_ProxyName) || !strlen(link->icq_ProxyPass) || !link->icq_ProxyAuth)
|
|
382 buf[2] = 0; /* no authorization required */
|
|
383 else
|
|
384 buf[2] = 2; /* method username/password */
|
|
385 #ifdef _WIN32
|
|
386 send(link->icq_ProxySok, buf, 3, 0);
|
|
387 res = recv(link->icq_ProxySok, buf, 2, 0);
|
|
388 #else
|
|
389 write(link->icq_ProxySok, buf, 3);
|
|
390 res = read(link->icq_ProxySok, buf, 2);
|
|
391 #endif
|
|
392 if(strlen(link->icq_ProxyName) && strlen(link->icq_ProxyPass) && link->icq_ProxyAuth)
|
|
393 {
|
|
394 if(res != 2 || buf[0] != 5 || buf[1] != 2) /* username/password authentication*/
|
|
395 {
|
|
396 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Authentication method incorrect\n");
|
|
397 #ifdef _WIN32
|
|
398 closesocket(link->icq_ProxySok);
|
|
399 #else
|
|
400 close(link->icq_ProxySok);
|
|
401 #endif
|
|
402 return -1;
|
|
403 }
|
|
404 buf[0] = 1; /* version of subnegotiation */
|
|
405 buf[1] = strlen(link->icq_ProxyName);
|
|
406 memcpy(&buf[2], link->icq_ProxyName, buf[1]);
|
|
407 buf[2+buf[1]] = strlen(link->icq_ProxyPass);
|
|
408 memcpy(&buf[3+buf[1]], link->icq_ProxyPass, buf[2+buf[1]]);
|
|
409 #ifdef _WIN32
|
|
410 send(link->icq_ProxySok, buf, buf[1]+buf[2+buf[1]]+3, 0);
|
|
411 res = recv(link->icq_ProxySok, buf, 2, 0);
|
|
412 #else
|
|
413 write(link->icq_ProxySok, buf, buf[1]+buf[2+buf[1]]+3);
|
|
414 res = read(link->icq_ProxySok, buf, 2);
|
|
415 #endif
|
|
416 if(res != 2 || buf[0] != 1 || buf[1] != 0)
|
|
417 {
|
|
418 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Authorization failure\n");
|
|
419 #ifdef _WIN32
|
|
420 closesocket(link->icq_ProxySok);
|
|
421 #else
|
|
422 close(link->icq_ProxySok);
|
|
423 #endif
|
|
424 return -1;
|
|
425 }
|
|
426 }
|
|
427 else
|
|
428 {
|
|
429 if(res != 2 || buf[0] != 5 || buf[1] != 0) /* no authentication required */
|
|
430 {
|
|
431 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Authentication method incorrect\n");
|
|
432 #ifdef _WIN32
|
|
433 closesocket(link->icq_ProxySok);
|
|
434 #else
|
|
435 close(link->icq_ProxySok);
|
|
436 #endif
|
|
437 return -1;
|
|
438 }
|
|
439 }
|
|
440 buf[0] = 5; /* protocol version */
|
|
441 buf[1] = 3; /* command UDP associate */
|
|
442 buf[2] = 0; /* reserved */
|
|
443 buf[3] = 1; /* address type IP v4 */
|
|
444 buf[4] = (char)0;
|
|
445 buf[5] = (char)0;
|
|
446 buf[6] = (char)0;
|
|
447 buf[7] = (char)0;
|
|
448 *(unsigned short*)&buf[8] = htons(link->icq_ProxyOurPort);
|
|
449 /* memcpy(&buf[8], &link->icq_ProxyOurPort, 2); */
|
|
450 #ifdef _WIN32
|
|
451 send(link->icq_ProxySok, buf, 10, 0);
|
|
452 res = recv(link->icq_ProxySok, buf, 10, 0);
|
|
453 #else
|
|
454 write(link->icq_ProxySok, buf, 10);
|
|
455 res = read(link->icq_ProxySok, buf, 10);
|
|
456 #endif
|
|
457 if(res != 10 || buf[0] != 5 || buf[1] != 0)
|
|
458 {
|
|
459 switch(buf[1])
|
|
460 {
|
|
461 case 1:
|
|
462 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] General SOCKS server failure\n");
|
|
463 break;
|
|
464 case 2:
|
|
465 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Connection not allowed by ruleset\n");
|
|
466 break;
|
|
467 case 3:
|
|
468 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Network unreachable\n");
|
|
469 break;
|
|
470 case 4:
|
|
471 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Host unreachable\n");
|
|
472 break;
|
|
473 case 5:
|
|
474 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Connection refused\n");
|
|
475 break;
|
|
476 case 6:
|
|
477 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] TTL expired\n");
|
|
478 break;
|
|
479 case 7:
|
|
480 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Command not supported\n");
|
|
481 break;
|
|
482 case 8:
|
|
483 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Address type not supported\n");
|
|
484 break;
|
|
485 default:
|
|
486 icq_FmtLog(link, ICQ_LOG_FATAL, "[SOCKS] Unknown SOCKS server failure\n");
|
|
487 break;
|
|
488 }
|
|
489 #ifdef _WIN32
|
|
490 closesocket(link->icq_ProxySok);
|
|
491 #else
|
|
492 close(link->icq_ProxySok);
|
|
493 #endif
|
|
494 return -1;
|
|
495 }
|
|
496 }
|
|
497 sin.sin_addr.s_addr = inet_addr(hostname); /* checks for n.n.n.n notation */
|
|
498 if(sin.sin_addr.s_addr == (unsigned long)-1) /* name isn't n.n.n.n so must be DNS */
|
|
499 {
|
|
500 host_struct = gethostbyname(hostname);
|
|
501 if(host_struct == 0L)
|
|
502 {
|
|
503 icq_FmtLog(link, ICQ_LOG_FATAL, "Can't find hostname: %s\n", hostname);
|
|
504 if(link->icq_UseProxy)
|
|
505 {
|
|
506 #ifdef _WIN32
|
|
507 closesocket(link->icq_ProxySok);
|
|
508 #else
|
|
509 close(link->icq_ProxySok);
|
|
510 #endif
|
|
511 }
|
|
512 return -1;
|
|
513 }
|
|
514 sin.sin_addr = *((struct in_addr *)host_struct->h_addr);
|
|
515 }
|
|
516 if(link->icq_UseProxy)
|
|
517 {
|
|
518 link->icq_ProxyDestIP = ntohl(sin.sin_addr.s_addr);
|
|
519 memcpy(&sin.sin_addr.s_addr, &buf[4], 4);
|
|
520 }
|
|
521 sin.sin_family = AF_INET; /* we're using the inet not appletalk*/
|
|
522 sin.sin_port = htons(port); /* port */
|
|
523 if(link->icq_UseProxy)
|
|
524 {
|
|
525 link->icq_ProxyDestPort = port;
|
|
526 memcpy(&sin.sin_port, &buf[8], 2);
|
|
527 }
|
|
528 conct = connect(link->icq_UDPSok, (struct sockaddr*)&sin, sizeof(sin));
|
|
529 if(conct == -1) /* did we connect ?*/
|
|
530 {
|
|
531 icq_FmtLog(link, ICQ_LOG_FATAL, "Connection refused\n");
|
|
532 if(link->icq_UseProxy)
|
|
533 {
|
|
534 #ifdef _WIN32
|
|
535 closesocket(link->icq_ProxySok);
|
|
536 #else
|
|
537 close(link->icq_ProxySok);
|
|
538 #endif
|
|
539 }
|
|
540 return -1;
|
|
541 }
|
|
542 length = sizeof(sin) ;
|
|
543 getsockname(link->icq_UDPSok, (struct sockaddr*)&sin, &length);
|
|
544 link->icq_OurIP = ntohl(sin.sin_addr.s_addr);
|
|
545 link->icq_OurPort = ntohs(sin.sin_port);
|
|
546 return link->icq_UDPSok;
|
|
547 }
|
|
548
|
|
549 void icq_Disconnect(ICQLINK *link)
|
|
550 {
|
|
551 #ifdef _WIN32
|
|
552 closesocket(link->icq_UDPSok);
|
|
553 #else
|
|
554 close(link->icq_UDPSok);
|
|
555 #endif
|
|
556 if(link->icq_UseProxy)
|
|
557 {
|
|
558 #ifdef _WIN32
|
|
559 closesocket(link->icq_ProxySok);
|
|
560 #else
|
|
561 close(link->icq_ProxySok);
|
|
562 #endif
|
|
563 }
|
|
564 icq_UDPQueueFree(link);
|
|
565 }
|
|
566
|
|
567 /*
|
|
568 void icq_InitNewUser(const char *hostname, DWORD port)
|
|
569 {
|
|
570 srv_net_icq_pak pak;
|
|
571 int s;
|
|
572 struct timeval tv;
|
|
573 fd_set readfds;
|
|
574
|
|
575 icq_Connect(hostname, port);
|
|
576 if((icq_UDPSok == -1) || (icq_UDPSok == 0))
|
|
577 {
|
|
578 printf("Couldn't establish connection\n");
|
|
579 exit(1);
|
|
580 }
|
|
581 icq_RegNewUser(icq_Password);
|
|
582 for(;;)
|
|
583 {
|
|
584 tv.tv_sec = 2;
|
|
585 tv.tv_usec = 500000;
|
|
586
|
|
587 FD_ZERO(&readfds);
|
|
588 FD_SET(icq_UDPSok, &readfds);
|
|
589
|
|
590 select(icq_UDPSok+1, &readfds, 0L, 0L, &tv);
|
|
591
|
|
592 if(FD_ISSET(icq_UDPSok, &readfds))
|
|
593 {
|
|
594 s = icq_UDPSockRead(icq_UDPSok, &pak.head, sizeof(pak));
|
|
595 if(icqtohs(pak.head.cmd) == SRV_NEW_UIN)
|
|
596 {
|
|
597 icq_Uin = icqtohl(&pak.data[2]);
|
|
598 return;
|
|
599 }
|
|
600 }
|
|
601 }
|
|
602 }
|
|
603 */
|
|
604
|
|
605 /************************
|
|
606 icq_UDPServMess functions
|
|
607 *************************/
|
|
608 BOOL icq_GetServMess(ICQLINK *link, WORD num)
|
|
609 {
|
|
610 return ((link->icq_UDPServMess[num/8] & (1 << (num%8))) >> (num%8));
|
|
611 }
|
|
612
|
|
613 void icq_SetServMess(ICQLINK *link, WORD num)
|
|
614 {
|
|
615 link->icq_UDPServMess[num/8] |= (1 << (num%8));
|
|
616 }
|
|
617
|
|
618 int icq_GetSok(ICQLINK *link)
|
|
619 {
|
|
620 return link->icq_UDPSok;
|
|
621 }
|