1152
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2 /*
|
|
3 $Id: udphandle.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.28 2000/06/25 17:25:52 denis
|
|
9 icq_HandleMetaUserInfo() handles all (!) available in original icq2k
|
|
10 Meta User Info packets along with other useful Meta* packets. (WOW! ;)
|
|
11
|
|
12 Revision 1.27 2000/05/10 18:54:43 denis
|
|
13 icq_Disconnect() now called before icq_Disconnected callback to
|
|
14 prevent high CPU usage in kicq's "reconnect on disconnect" code.
|
|
15
|
|
16 Revision 1.26 2000/05/03 18:29:15 denis
|
|
17 Callbacks have been moved to the ICQLINK structure.
|
|
18
|
|
19 Revision 1.25 2000/02/07 02:48:15 bills
|
|
20 changed log message in HandleUserOnline
|
|
21
|
|
22 Revision 1.24 2000/01/16 03:59:10 bills
|
|
23 reworked list code so list_nodes don't need to be inside item structures,
|
|
24 removed strlist code and replaced with generic list calls
|
|
25
|
|
26 Revision 1.23 1999/12/27 11:12:37 denis
|
|
27 icq_UpdateMetaInfoSecurity() added for setting "My authorization is
|
|
28 required", "Web Aware" and "IP Publishing".
|
|
29
|
|
30 Revision 1.22 1999/12/14 03:37:06 bills
|
|
31 removed old real_ip->ip masq hack, added store to remote_real_ip in
|
|
32 icq_ContactItem
|
|
33
|
|
34 Revision 1.21 1999/12/12 18:03:58 denis
|
|
35 Authorization Request packet handling fixed.
|
|
36
|
|
37 Revision 1.20 1999/11/29 17:18:31 denis
|
|
38 icq_DoMsg() redone using string lists.
|
|
39
|
|
40 Revision 1.18 1999/11/11 15:10:32 guruz
|
|
41 - Added Base for Webpager Messages. Please type "make fixme"
|
|
42 - Removed Segfault when kicq is started the first time
|
|
43
|
|
44 Revision 1.17 1999/10/14 11:44:04 denis
|
|
45 Cleanups.
|
|
46
|
|
47 Revision 1.16 1999/09/29 17:16:08 denis
|
|
48 MailExpress message handler started.
|
|
49
|
|
50 Revision 1.15 1999/07/18 20:23:54 bills
|
|
51 fixed tcp port bug in icq_HandleUserOnline, changed to use new byte-order
|
|
52 & contact list functions
|
|
53
|
|
54 Revision 1.14 1999/07/16 15:46:02 denis
|
|
55 Cleaned up.
|
|
56
|
|
57 Revision 1.13 1999/07/16 12:40:55 denis
|
|
58 ICQ UDP v5 implemented.
|
|
59 Encription for ICQ UDP v5 implemented.
|
|
60 icq_Packet* unified interface for UDP packets implemented.
|
|
61 Multipacket support of ICQ UDP v5 support added.
|
|
62
|
|
63 Revision 1.12 1999/07/12 15:13:45 cproch
|
|
64 - added definition of ICQLINK to hold session-specific global variabled
|
|
65 applications which have more than one connection are now possible
|
|
66 - changed nearly every function defintion to support ICQLINK parameter
|
|
67
|
|
68 Revision 1.11 1999/07/03 06:46:54 lord
|
|
69 converting icq_userOnline callback parameters to correct
|
|
70 byte order.
|
|
71
|
|
72 Revision 1.10 1999/07/03 02:29:46 bills
|
|
73 added code to HandleUserOnline to update tcp_flag
|
|
74
|
|
75 Revision 1.9 1999/04/29 09:40:54 denis
|
|
76 Unsuccessful attempt to implement web presence (webaware) feature
|
|
77
|
|
78 Revision 1.8 1999/04/18 01:58:37 bills
|
|
79 changed icq_SrvAck call to icq_RequestNotify
|
|
80
|
|
81 Revision 1.7 1999/04/17 19:26:49 bills
|
|
82 removed *_link entries from icq_ContactItem, including cleaup/init code
|
|
83
|
|
84 Revision 1.6 1999/04/14 15:05:39 denis
|
|
85 Cleanups for "strict" compiling (-ansi -pedantic)
|
|
86 Switched from icq_Log callback to icq_Fmt function.
|
|
87
|
|
88 Revision 1.5 1999/04/05 18:47:23 bills
|
|
89 initial chat support implemented
|
|
90
|
|
91 Revision 1.4 1999/03/31 01:39:50 bills
|
|
92 added handling of tcp_flag in HandleLogin
|
|
93
|
|
94 Revision 1.3 1999/03/28 03:35:17 bills
|
|
95 fixed function names so icqlib compiles, fixed bug in HandleUserOnline
|
|
96 (remote_ip and remote_real_ip were not evaluating correctly), added
|
|
97 hack so I can test using local network
|
|
98
|
|
99 Revision 1.2 1999/03/25 22:25:02 bills
|
|
100 modified icq_HandleUserOnline & Offline for new message_link
|
|
101
|
|
102 Revision 1.1 1999/03/24 11:37:38 denis
|
|
103 Underscored files with TCP stuff renamed.
|
|
104 TCP stuff cleaned up
|
|
105 Function names changed to corresponding names.
|
|
106 icqlib.c splitted to many small files by subject.
|
|
107 C++ comments changed to ANSI C comments.
|
|
108
|
|
109 */
|
|
110
|
|
111 #include <stdlib.h>
|
|
112
|
|
113 #include "icqtypes.h"
|
|
114 #include "icq.h"
|
|
115 #include "icqlib.h"
|
|
116 #include "udp.h"
|
|
117 #include "icqpacket.h"
|
|
118 #include "queue.h"
|
|
119 #include "icqbyteorder.h"
|
|
120 #include "list.h"
|
|
121
|
|
122 int icq_SplitFields(list *strList, const char *str)
|
|
123 {
|
|
124 char *tmpBuf, *tmp, *ptr;
|
|
125 int count = 0;
|
|
126
|
|
127 tmpBuf = (char*)malloc(strlen(str)+1);
|
|
128 strcpy(tmpBuf, str);
|
|
129 ptr = tmpBuf;
|
|
130
|
|
131 while(ptr)
|
|
132 {
|
|
133 char *p;
|
|
134 tmp = strchr(ptr, 0xFE);
|
|
135 if(tmp != 0L)
|
|
136 {
|
|
137 *tmp = 0;
|
|
138 tmp++;
|
|
139 }
|
|
140 count++;
|
|
141 p = (char *)malloc(strlen(ptr)+1);
|
|
142 strcpy(p, ptr);
|
|
143 list_enqueue(strList, p);
|
|
144 ptr = tmp;
|
|
145 }
|
|
146
|
|
147 free(tmpBuf);
|
|
148 return count;
|
|
149 }
|
|
150
|
|
151 void icq_DoMsg(ICQLINK *link, DWORD type, WORD len, char *data, DWORD uin, BYTE hour,
|
|
152 BYTE minute, BYTE day, BYTE month, WORD year)
|
|
153 {
|
|
154 list *strList;
|
|
155
|
|
156 strList = list_new();
|
|
157 switch(type)
|
|
158 {
|
|
159 case TYPE_ADDED:
|
|
160 /* Format: Nick, 0xFE, FName, 0xFE, LName, 0xFE, EMail */
|
|
161 if(icq_SplitFields(strList, data)!=4)
|
|
162 {
|
|
163 icq_FmtLog(link, ICQ_LOG_ERROR, "Bad packet!\n");
|
|
164 return;
|
|
165 }
|
|
166 icq_RusConv("wk", list_at(strList, 0)); /* Nick */
|
|
167 icq_RusConv("wk", list_at(strList, 1)); /* FName */
|
|
168 icq_RusConv("wk", list_at(strList, 2)); /* LName */
|
|
169 icq_RusConv("wk", list_at(strList, 3)); /* EMail */
|
|
170 icq_FmtLog(link, ICQ_LOG_MESSAGE, "%lu has added you to their contact list, "
|
|
171 "Nick: %s, First Name: %s, Last Name: %s, EMail: %s\n",
|
|
172 uin, list_at(strList, 0), list_at(strList, 1),
|
|
173 list_at(strList, 2), list_at(strList, 3));
|
|
174 if(link->icq_RecvAdded)
|
|
175 (*link->icq_RecvAdded)(link, uin, hour, minute, day, month, year,
|
|
176 list_at(strList, 0), list_at(strList, 1),
|
|
177 list_at(strList, 2), list_at(strList, 3));
|
|
178 break;
|
|
179 case TYPE_AUTH_REQ:
|
|
180 /* Format: Nick, 0xFE, FName, 0xFE, LName, 0xFE, EMail, 0xFE, 0, 0xFE, Reason */
|
|
181 if(icq_SplitFields(strList, data)!=6)
|
|
182 {
|
|
183 icq_FmtLog(link, ICQ_LOG_ERROR, "Bad packet!\n");
|
|
184 return;
|
|
185 }
|
|
186 icq_RusConv("wk", list_at(strList, 0)); /* Nick */
|
|
187 icq_RusConv("wk", list_at(strList, 1)); /* FName */
|
|
188 icq_RusConv("wk", list_at(strList, 2)); /* LName */
|
|
189 icq_RusConv("wk", list_at(strList, 3)); /* EMail */
|
|
190 icq_RusConv("wk", list_at(strList, 5)); /* Reason */
|
|
191 icq_FmtLog(link, ICQ_LOG_MESSAGE, "%lu has requested your authorization to be added to "
|
|
192 "their contact list, Nick: %s, First Name: %s, Last Name: %s, "
|
|
193 "EMail: %s, Reason: %s\n", uin, list_at(strList, 0), list_at(strList, 1),
|
|
194 list_at(strList, 2), list_at(strList, 3), list_at(strList, 4));
|
|
195 if(link->icq_RecvAuthReq)
|
|
196 (*link->icq_RecvAuthReq)(link, uin, hour, minute, day, month, year, list_at(strList, 0),
|
|
197 list_at(strList, 1), list_at(strList, 2),
|
|
198 list_at(strList, 3), list_at(strList, 5));
|
|
199 break;
|
|
200 case TYPE_URL:
|
|
201 /* Format: Description, 0xFE, URL */
|
|
202 if(icq_SplitFields(strList, data)!=2)
|
|
203 {
|
|
204 icq_FmtLog(link, ICQ_LOG_ERROR, "Bad packet!\n");
|
|
205 return;
|
|
206 }
|
|
207 icq_RusConv("wk", list_at(strList, 0)); /* Description */
|
|
208 icq_FmtLog(link, ICQ_LOG_MESSAGE, "URL received from %lu, URL: %s, Description: %s\n",
|
|
209 uin, list_at(strList, 1), list_at(strList, 0));
|
|
210 if(link->icq_RecvURL)
|
|
211 (*link->icq_RecvURL)(link, uin, hour, minute, day, month, year, list_at(strList, 1),
|
|
212 list_at(strList, 0));
|
|
213 break;
|
|
214 case TYPE_WEBPAGER:
|
|
215 /* Format: Nick, 0xFE, Empty-FName, 0xFE, Empty-LName, 0xFE, EMail, 0xFE,
|
|
216 * Reason(3), 0xFE, Message with IP & Subject */
|
|
217 if(icq_SplitFields(strList, data)!=6)
|
|
218 {
|
|
219 icq_FmtLog(link, ICQ_LOG_ERROR, "Bad packet!\n");
|
|
220 return;
|
|
221 }
|
|
222 icq_RusConv("wk", list_at(strList, 0)); /* Nick */
|
|
223 icq_RusConv("wk", list_at(strList, 5)); /* Message */
|
|
224 icq_FmtLog(link, ICQ_LOG_MESSAGE, "WebPager message received, Nick: %s, EMail: %s, "
|
|
225 "Message:\n%s\n", list_at(strList, 0), list_at(strList, 3),
|
|
226 list_at(strList, 5));
|
|
227 if(link->icq_RecvWebPager)
|
|
228 (*link->icq_RecvWebPager)(link, hour, minute, day, month, year, list_at(strList, 0),
|
|
229 list_at(strList, 3), list_at(strList, 5));
|
|
230 break;
|
|
231 case TYPE_EXPRESS:
|
|
232 /* Format: Nick, 0xFE, Empty-FName, 0xFE, Empty-LName, 0xFE, EMail, 0xFE,
|
|
233 * Reason(3), 0xFE, Message Subject */
|
|
234 if(icq_SplitFields(strList, data)!=6)
|
|
235 {
|
|
236 icq_FmtLog(link, ICQ_LOG_ERROR, "Bad packet!\n");
|
|
237 return;
|
|
238 }
|
|
239 icq_RusConv("wk", list_at(strList, 0)); /* Nick */
|
|
240 icq_RusConv("wk", list_at(strList, 5)); /* Message */
|
|
241 icq_FmtLog(link, ICQ_LOG_MESSAGE, "MailExpress message received, Nick: %s, EMail: %s, "
|
|
242 "Message:\n%s\n", list_at(strList, 0), list_at(strList, 3),
|
|
243 list_at(strList, 5));
|
|
244 if(link->icq_RecvMailExpress)
|
|
245 (*link->icq_RecvMailExpress)(link, hour, minute, day, month, year, list_at(strList, 0),
|
|
246 list_at(strList, 3), list_at(strList, 5));
|
|
247 break;
|
|
248 default:
|
|
249 icq_RusConv("wk", data); /* Entire message */
|
|
250 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Instant message type %i from %lu:\n%s\n", type, uin, data);
|
|
251 if(link->icq_RecvMessage)
|
|
252 (*link->icq_RecvMessage)(link, uin, hour, minute, day, month, year, data);
|
|
253 }
|
|
254 list_delete(strList, free);
|
|
255 }
|
|
256
|
|
257 void icq_HandleInfoReply(ICQLINK *link, icq_Packet *p)
|
|
258 {
|
|
259 char *ptr1, *ptr2, *ptr3, *ptr4;
|
|
260 DWORD uin;
|
|
261 icq_PacketGotoUDPInData(p, 0);
|
|
262 uin = icq_PacketRead32(p);
|
|
263 ptr1 = icq_PacketReadStringNew(p);
|
|
264 ptr2 = icq_PacketReadStringNew(p);
|
|
265 ptr3 = icq_PacketReadStringNew(p);
|
|
266 ptr4 = icq_PacketReadStringNew(p);
|
|
267 icq_RusConv("wk", ptr1);
|
|
268 icq_RusConv("wk", ptr2);
|
|
269 icq_RusConv("wk", ptr3);
|
|
270 icq_RusConv("wk", ptr4);
|
|
271 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Info reply for %lu\n", uin);
|
|
272 if(link->icq_InfoReply)
|
|
273 (*link->icq_InfoReply)(link, uin, ptr1, ptr2, ptr3, ptr4, icq_PacketRead8(p));
|
|
274 icq_UDPAck(link, icq_PacketReadUDPInSeq1(p));
|
|
275 free(ptr1);
|
|
276 free(ptr2);
|
|
277 free(ptr3);
|
|
278 free(ptr4);
|
|
279 }
|
|
280
|
|
281 void icq_HandleExtInfoReply(ICQLINK *link, icq_Packet *p)
|
|
282 {
|
|
283 char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
|
|
284 DWORD uin;
|
|
285 WORD cnt_code, age;
|
|
286 char cnt_stat, gender;
|
|
287
|
|
288 icq_PacketGotoUDPInData(p, 0);
|
|
289 uin = icq_PacketRead32(p);
|
|
290 ptr1 = icq_PacketReadStringNew(p);
|
|
291 cnt_code = icq_PacketRead16(p);
|
|
292 cnt_stat = icq_PacketRead8(p);
|
|
293 ptr2 = icq_PacketReadStringNew(p);
|
|
294 age = icq_PacketRead16(p);
|
|
295 gender = icq_PacketRead8(p);
|
|
296 ptr3 = icq_PacketReadStringNew(p);
|
|
297 ptr4 = icq_PacketReadStringNew(p);
|
|
298 ptr5 = icq_PacketReadStringNew(p);
|
|
299 icq_RusConv("wk", ptr1);
|
|
300 icq_RusConv("wk", ptr2);
|
|
301 icq_RusConv("wk", ptr3);
|
|
302 icq_RusConv("wk", ptr4);
|
|
303 icq_RusConv("wk", ptr5);
|
|
304 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Extended info reply for %lu\n", uin);
|
|
305 if(link->icq_ExtInfoReply)
|
|
306 (*link->icq_ExtInfoReply)(link, uin, (char*)ptr1, cnt_code, cnt_stat, (char*)ptr2, age,
|
|
307 gender, (char*)ptr3, (char*)ptr4, (char*)ptr5);
|
|
308 icq_UDPAck(link, icq_PacketReadUDPInSeq1(p));
|
|
309 free(ptr1);
|
|
310 free(ptr2);
|
|
311 free(ptr3);
|
|
312 free(ptr4);
|
|
313 free(ptr5);
|
|
314 }
|
|
315
|
|
316 void icq_HandleSearchReply(ICQLINK *link, icq_Packet *p)
|
|
317 {
|
|
318 char *ptr1, *ptr2, *ptr3, *ptr4, auth;
|
|
319 DWORD uin;
|
|
320 icq_PacketGotoUDPInData(p, 0);
|
|
321 uin = icq_PacketRead32(p);
|
|
322 ptr1 = icq_PacketReadStringNew(p);
|
|
323 ptr2 = icq_PacketReadStringNew(p);
|
|
324 ptr3 = icq_PacketReadStringNew(p);
|
|
325 ptr4 = icq_PacketReadStringNew(p);
|
|
326 icq_RusConv("wk", ptr1);
|
|
327 icq_RusConv("wk", ptr2);
|
|
328 icq_RusConv("wk", ptr3);
|
|
329 icq_RusConv("wk", ptr4);
|
|
330 auth = icq_PacketRead8(p);
|
|
331 icq_FmtLog(link, ICQ_LOG_MESSAGE, "User found %lu, Nick: %s, First Name: %s, Last Name: %s, "
|
|
332 "EMail: %s, Auth: %s\n", uin, ptr1, ptr2, ptr3, ptr4, auth==1?"no":"yes");
|
|
333 if(link->icq_UserFound)
|
|
334 (*link->icq_UserFound)(link, uin, (char*)ptr1, (char*)ptr2, (char*)ptr3, (char*)ptr4, auth);
|
|
335 icq_UDPAck(link, icq_PacketReadUDPInSeq1(p));
|
|
336 free(ptr1);
|
|
337 free(ptr2);
|
|
338 free(ptr3);
|
|
339 free(ptr4);
|
|
340 }
|
|
341
|
|
342 /************************************************
|
|
343 This is called when a user goes offline
|
|
344 *************************************************/
|
|
345 void icq_HandleUserOffline(ICQLINK *link, icq_Packet *p)
|
|
346 {
|
|
347 DWORD remote_uin;
|
|
348 icq_ContactItem *ptr;
|
|
349
|
|
350 icq_PacketGotoUDPInData(p, 0);
|
|
351 remote_uin = icq_PacketRead32(p);
|
|
352 icq_FmtLog(link, ICQ_LOG_MESSAGE, "User %lu logged off\n", remote_uin);
|
|
353 if(link->icq_UserOffline)
|
|
354 (*link->icq_UserOffline)(link, remote_uin);
|
|
355
|
|
356 ptr=icq_ContactFind(link, remote_uin);
|
|
357 if(ptr)
|
|
358 {
|
|
359 ptr->remote_ip = 0;
|
|
360 ptr->remote_port = 0;
|
|
361 }
|
|
362 icq_UDPAck(link, icq_PacketReadUDPInSeq1(p));
|
|
363 }
|
|
364
|
|
365 void icq_HandleUserOnline(ICQLINK *link, icq_Packet *p)
|
|
366 {
|
|
367 DWORD remote_uin, new_status, remote_ip, remote_real_ip;
|
|
368 DWORD remote_port; /* Why Mirabilis used 4 bytes for port? */
|
|
369 BYTE tcp_flag;
|
|
370 icq_ContactItem *ptr;
|
|
371
|
|
372 icq_PacketGotoUDPInData(p, 0);
|
|
373 remote_uin = icq_PacketRead32(p);
|
|
374 remote_ip = ntohl(icq_PacketRead32n(p)); /* icqtohl() */
|
|
375 remote_port = icqtohl(icq_PacketRead32n(p));
|
|
376 remote_real_ip = ntohl(icq_PacketRead32n(p)); /* icqtohl() */
|
|
377 tcp_flag = icq_PacketRead8(p);
|
|
378 new_status = icq_PacketRead32(p);
|
|
379
|
|
380 icq_FmtLog(link, ICQ_LOG_MESSAGE,
|
|
381 "User %lu (%s = 0x%X) logged on. tcp_flag=0x%X IP=%08X, real IP=%08X, port=%d\n",
|
|
382 remote_uin, icq_ConvertStatus2Str(new_status), new_status, tcp_flag, remote_ip,
|
|
383 remote_real_ip, remote_port);
|
|
384 if(link->icq_UserOnline)
|
|
385 (*link->icq_UserOnline)(link, remote_uin, new_status, remote_ip, remote_port, remote_real_ip, tcp_flag);
|
|
386
|
|
387 ptr=icq_ContactFind(link, remote_uin);
|
|
388 if(ptr)
|
|
389 {
|
|
390 ptr->remote_ip=remote_ip;
|
|
391 ptr->remote_real_ip=remote_real_ip;
|
|
392 ptr->remote_port = remote_port;
|
|
393 ptr->tcp_flag = tcp_flag;
|
|
394 }
|
|
395 icq_UDPAck(link, icq_PacketReadUDPInSeq1(p));
|
|
396 }
|
|
397
|
|
398 void icq_HandleStatusChange(ICQLINK *link, icq_Packet *p)
|
|
399 {
|
|
400 unsigned long remote_uin, new_status;
|
|
401
|
|
402 icq_PacketGotoUDPInData(p, 0);
|
|
403 remote_uin = icq_PacketRead32(p);
|
|
404 new_status = icq_PacketRead32(p);
|
|
405 icq_FmtLog(link, ICQ_LOG_MESSAGE, "%lu changed status to %s (0x%X)\n", remote_uin,
|
|
406 icq_ConvertStatus2Str(new_status), new_status);
|
|
407 if(link->icq_UserStatusUpdate)
|
|
408 (*link->icq_UserStatusUpdate)(link, remote_uin, new_status);
|
|
409 icq_UDPAck(link, icq_PacketReadUDPInSeq1(p));
|
|
410 }
|
|
411
|
|
412 void icq_HandleMetaUserInfo(ICQLINK *link, icq_Packet *p)
|
|
413 {
|
|
414 unsigned short subcmd, country, seq2, age, occupation, wcountry;
|
|
415 unsigned char res, auth, timezone, webaware, hideip, gender;
|
|
416 unsigned char *nick, *first, *last, *email, *about, *city;
|
|
417 unsigned char *pri_eml, *sec_eml, *old_eml;
|
|
418 unsigned char *phone, *fax, *street, *cellular, *state;
|
|
419 unsigned char *wcity, *wstate, *wphone, *wfax, *waddress;
|
|
420 unsigned char *company, *department, *job, *whomepage;
|
|
421 unsigned char *homepage;
|
|
422 unsigned char byear, bmonth, bday, lang1, lang2, lang3, inum, i;
|
|
423 unsigned char anum, bnum, hnum;
|
|
424 unsigned long uin, zip, wzip;
|
|
425 unsigned char *empty = "";
|
|
426 unsigned char *interests[4] = {0, 0, 0, 0};
|
|
427 unsigned short icategory[4] = {0, 0, 0, 0};
|
|
428 unsigned char *affiliations[4] = {0, 0, 0, 0};
|
|
429 unsigned short acategory[4] = {0, 0, 0, 0};
|
|
430 unsigned char *backgrounds[4] = {0, 0, 0, 0};
|
|
431 unsigned short bcategory[4] = {0, 0, 0, 0};
|
|
432 unsigned char *hpcat[4] = {0, 0, 0, 0};
|
|
433 unsigned short hcategory[4] = {0, 0, 0, 0};
|
|
434
|
|
435 seq2 = icq_PacketReadUDPInSeq2(p);
|
|
436 icq_PacketGotoUDPInData(p, 0);
|
|
437 subcmd = icq_PacketRead16(p);
|
|
438 res = icq_PacketRead8(p);
|
|
439 if(res == META_SRV_FAILURE)
|
|
440 {
|
|
441 icq_FmtLog(link, ICQ_LOG_WARNING, "META failure\n");
|
|
442 if(link->icq_RequestNotify)
|
|
443 (*link->icq_RequestNotify)(link, seq2, ICQ_NOTIFY_FAILED, sizeof(subcmd), &subcmd);
|
|
444 }
|
|
445 else
|
|
446 switch(subcmd)
|
|
447 {
|
|
448 case META_SRV_USER_FOUND:
|
|
449 uin = icq_PacketRead32(p);
|
|
450 nick = icq_PacketReadStringNew(p);
|
|
451 first = icq_PacketReadStringNew(p);
|
|
452 last = icq_PacketReadStringNew(p);
|
|
453 email = icq_PacketReadStringNew(p);
|
|
454 auth = icq_PacketRead8(p);
|
|
455 icq_PacketRead16(p); // ???
|
|
456 icq_PacketRead32(p); // ???
|
|
457 icq_RusConv("wk", nick);
|
|
458 icq_RusConv("wk", first);
|
|
459 icq_RusConv("wk", last);
|
|
460 icq_RusConv("wk", email);
|
|
461 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User Found %lu, Nick: %s, First Name: %s, "\
|
|
462 "Last Name: %s, EMail: %s, Auth: %s\n", seq2, uin, nick, first, last,
|
|
463 email, auth==1?"no":"yes");
|
|
464 if(link->icq_MetaUserFound)
|
|
465 (*link->icq_MetaUserFound)(link, seq2, uin, nick, first, last, email, auth);
|
|
466 free(nick);
|
|
467 free(first);
|
|
468 free(last);
|
|
469 free(email);
|
|
470 break;
|
|
471 case META_SRV_USER_INFO: // finished!
|
|
472 nick = icq_PacketReadStringNew(p);
|
|
473 first = icq_PacketReadStringNew(p);
|
|
474 last = icq_PacketReadStringNew(p);
|
|
475 pri_eml = icq_PacketReadStringNew(p);
|
|
476 sec_eml = icq_PacketReadStringNew(p);
|
|
477 old_eml = icq_PacketReadStringNew(p);
|
|
478 city = icq_PacketReadStringNew(p);
|
|
479 state = icq_PacketReadStringNew(p);
|
|
480 phone = icq_PacketReadStringNew(p);
|
|
481 fax = icq_PacketReadStringNew(p);
|
|
482 street = icq_PacketReadStringNew(p);
|
|
483 cellular = icq_PacketReadStringNew(p);
|
|
484 zip = icq_PacketRead32(p);
|
|
485 country = icq_PacketRead16(p);
|
|
486 timezone = icq_PacketRead8(p); // +1 = -30min, -1 = +30min (-4 = GMT+0200)
|
|
487 auth = icq_PacketRead8(p); // 1 - no auth required, 0 - required
|
|
488 webaware = icq_PacketRead8(p); // 1 - yes, 0 - no
|
|
489 hideip = icq_PacketRead8(p); // 1 - yes, 0 - no
|
|
490 icq_RusConv("wk", nick);
|
|
491 icq_RusConv("wk", first);
|
|
492 icq_RusConv("wk", last);
|
|
493 icq_RusConv("wk", pri_eml);
|
|
494 icq_RusConv("wk", sec_eml);
|
|
495 icq_RusConv("wk", old_eml);
|
|
496 icq_RusConv("wk", city);
|
|
497 icq_RusConv("wk", state);
|
|
498 icq_RusConv("wk", phone);
|
|
499 icq_RusConv("wk", fax);
|
|
500 icq_RusConv("wk", street);
|
|
501 icq_RusConv("wk", cellular);
|
|
502 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User Info: %s, %s, %s, "\
|
|
503 "%s, %s, %s, %s, %s, %s, %s, %s, %s, %lu, %s, %i, %s, %s, %s\n",
|
|
504 nick, first, last, pri_eml, sec_eml, old_eml, city, state, phone,
|
|
505 fax, street, cellular, zip, icq_GetCountryName(country), timezone,
|
|
506 auth?"false":"true", webaware?"true":"false", hideip?"true":"false");
|
|
507 if(link->icq_MetaUserInfo)
|
|
508 (*link->icq_MetaUserInfo)(link, seq2, nick, first, last, pri_eml, sec_eml,
|
|
509 old_eml, city, state, phone, fax, street, cellular,
|
|
510 zip, country, timezone, auth, webaware, hideip);
|
|
511 free(nick);
|
|
512 free(first);
|
|
513 free(last);
|
|
514 free(pri_eml);
|
|
515 free(sec_eml);
|
|
516 free(old_eml);
|
|
517 free(city);
|
|
518 free(state);
|
|
519 free(phone);
|
|
520 free(fax);
|
|
521 free(street);
|
|
522 free(cellular);
|
|
523 break;
|
|
524 case META_SRV_USER_WORK: // finished!
|
|
525 wcity = icq_PacketReadStringNew(p);
|
|
526 wstate = icq_PacketReadStringNew(p);
|
|
527 wphone = icq_PacketReadStringNew(p);
|
|
528 wfax = icq_PacketReadStringNew(p);
|
|
529 waddress = icq_PacketReadStringNew(p);
|
|
530 wzip = icq_PacketRead32(p);
|
|
531 wcountry = icq_PacketRead16(p); // icq_GetCountryName()
|
|
532 company = icq_PacketReadStringNew(p);
|
|
533 department = icq_PacketReadStringNew(p);
|
|
534 job = icq_PacketReadStringNew(p);
|
|
535 occupation = icq_PacketRead16(p); // icq_GetMetaOccupationName()
|
|
536 whomepage = icq_PacketReadStringNew(p);
|
|
537 icq_RusConv("wk", wcity);
|
|
538 icq_RusConv("wk", wstate);
|
|
539 icq_RusConv("wk", wphone);
|
|
540 icq_RusConv("wk", wfax);
|
|
541 icq_RusConv("wk", waddress);
|
|
542 icq_RusConv("wk", company);
|
|
543 icq_RusConv("wk", department);
|
|
544 icq_RusConv("wk", job);
|
|
545 icq_RusConv("wk", whomepage);
|
|
546 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User Work: %s, %s, %s, "\
|
|
547 "%s, %s, %lu, %s, %s, %s, %s, %s, %s\n", wcity, wstate,
|
|
548 wphone, wfax, waddress, wzip, icq_GetCountryName(wcountry),
|
|
549 company, department, job, icq_GetMetaOccupationName(occupation),
|
|
550 whomepage);
|
|
551 if(link->icq_MetaUserWork)
|
|
552 (*link->icq_MetaUserWork)(link, seq2, wcity, wstate, wphone, wfax,
|
|
553 waddress, wzip, wcountry, company, department,
|
|
554 job, occupation, whomepage);
|
|
555 free(wcity);
|
|
556 free(wstate);
|
|
557 free(wphone);
|
|
558 free(wfax);
|
|
559 free(waddress);
|
|
560 free(company);
|
|
561 free(department);
|
|
562 free(job);
|
|
563 free(whomepage);
|
|
564 break;
|
|
565 case META_SRV_USER_MORE: // finished!
|
|
566 age = icq_PacketRead16(p); // 0xFFFF - not entered
|
|
567 gender = icq_PacketRead8(p); // 1 - female, 2 - male
|
|
568 homepage = icq_PacketReadStringNew(p);
|
|
569 byear = icq_PacketRead8(p); // starting from 1900
|
|
570 bmonth = icq_PacketRead8(p);
|
|
571 bday = icq_PacketRead8(p);
|
|
572 lang1 = icq_PacketRead8(p); // icq_GetMetaLanguageName()
|
|
573 lang2 = icq_PacketRead8(p); // icq_GetMetaLanguageName()
|
|
574 lang3 = icq_PacketRead8(p); // icq_GetMetaLanguageName()
|
|
575 icq_RusConv("wk", homepage);
|
|
576 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User More: %i, %s, %s, "\
|
|
577 "%02i/%02i/%04i, %s, %s, %s\n", age,
|
|
578 gender==1?"female":gender==2?"male":"not entered",
|
|
579 homepage, bday, bmonth, byear+1900, icq_GetMetaLanguageName(lang1),
|
|
580 icq_GetMetaLanguageName(lang2), icq_GetMetaLanguageName(lang3));
|
|
581 if(link->icq_MetaUserMore)
|
|
582 (*link->icq_MetaUserMore)(link, seq2, age, gender, homepage, byear,
|
|
583 bmonth, bday, lang1, lang2, lang3);
|
|
584 free(homepage);
|
|
585 break;
|
|
586 case META_SRV_USER_ABOUT: // finished!
|
|
587 about = icq_PacketReadStringNew(p);
|
|
588 icq_RusConv("wk", about);
|
|
589 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User About: %s\n", about);
|
|
590 if(link->icq_MetaUserAbout)
|
|
591 (*link->icq_MetaUserAbout)(link, seq2, about);
|
|
592 free(about);
|
|
593 break;
|
|
594 case META_SRV_USER_INTERESTS: // finished!
|
|
595 inum = icq_PacketRead8(p);
|
|
596 for(i=0; i<inum && i<4; i++)
|
|
597 {
|
|
598 icategory[i] = icq_PacketRead16(p);
|
|
599 interests[i] = icq_PacketReadStringNew(p);
|
|
600 icq_RusConv("wk", interests[i]);
|
|
601 }
|
|
602 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User Interests: %i, %i - %s, "\
|
|
603 "%i - %s, %i - %s, %i - %s\n", inum, icategory[0],
|
|
604 interests[0]?interests[0]:empty, icategory[1], interests[1]?interests[1]:empty,
|
|
605 icategory[2], interests[2]?interests[2]:empty, icategory[3],
|
|
606 interests[3]?interests[3]:empty);
|
|
607 if(link->icq_MetaUserInterests)
|
|
608 (*link->icq_MetaUserInterests)(link, seq2, inum, icategory[0], interests[0],
|
|
609 icategory[1], interests[1], icategory[2],
|
|
610 interests[2], icategory[3], interests[3]);
|
|
611 for(i=0; i<inum && i<4; i++)
|
|
612 free(interests[i]);
|
|
613 break;
|
|
614 case META_SRV_USER_AFFILIATIONS: // finished!
|
|
615 bnum = icq_PacketRead8(p);
|
|
616 for(i=0; i<bnum && i<4; i++)
|
|
617 {
|
|
618 bcategory[i] = icq_PacketRead16(p); // icq_GetMetaBackgroundName()
|
|
619 backgrounds[i] = icq_PacketReadStringNew(p);
|
|
620 icq_RusConv("wk", backgrounds[i]);
|
|
621 }
|
|
622 anum = icq_PacketRead8(p);
|
|
623 for(i=0; i<anum && i<4; i++)
|
|
624 {
|
|
625 acategory[i] = icq_PacketRead16(p); // icq_GetMetaAffiliationName()
|
|
626 affiliations[i] = icq_PacketReadStringNew(p);
|
|
627 icq_RusConv("wk", affiliations[i]);
|
|
628 }
|
|
629 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User Affiliations: %i, %s - %s, "\
|
|
630 "%s - %s, %s - %s, %s - %s; Backgrounds: %i, %s - %s, %s - %s, "\
|
|
631 "%s - %s, %s - %s\n", anum,
|
|
632 icq_GetMetaAffiliationName(acategory[0]), affiliations[0]?affiliations[0]:empty,
|
|
633 icq_GetMetaAffiliationName(acategory[1]), affiliations[1]?affiliations[1]:empty,
|
|
634 icq_GetMetaAffiliationName(acategory[2]), affiliations[2]?affiliations[2]:empty,
|
|
635 icq_GetMetaAffiliationName(acategory[3]), affiliations[3]?affiliations[3]:empty,
|
|
636 bnum, icq_GetMetaBackgroundName(bcategory[0]), backgrounds[0]?backgrounds[0]:empty,
|
|
637 icq_GetMetaBackgroundName(bcategory[1]), backgrounds[1]?backgrounds[1]:empty,
|
|
638 icq_GetMetaBackgroundName(bcategory[2]), backgrounds[2]?backgrounds[2]:empty,
|
|
639 icq_GetMetaBackgroundName(bcategory[3]), backgrounds[3]?backgrounds[3]:empty);
|
|
640 if(link->icq_MetaUserAffiliations)
|
|
641 (*link->icq_MetaUserAffiliations)(link, seq2, anum, acategory[0],
|
|
642 affiliations[0], acategory[1], affiliations[1], acategory[2],
|
|
643 affiliations[2], acategory[3], affiliations[3], bnum,
|
|
644 bcategory[0], backgrounds[0], bcategory[1], backgrounds[1],
|
|
645 bcategory[2], backgrounds[2], bcategory[3], backgrounds[3]);
|
|
646 for(i=0; i<bnum && i<4; i++)
|
|
647 free(backgrounds[i]);
|
|
648 for(i=0; i<anum && i<4; i++)
|
|
649 free(affiliations[i]);
|
|
650 break;
|
|
651 case META_SRV_USER_HPCATEGORY: // finished!
|
|
652 hnum = icq_PacketRead8(p);
|
|
653 for(i=0; i<hnum && i<1; i++)
|
|
654 {
|
|
655 hcategory[i] = icq_PacketRead16(p);
|
|
656 hpcat[i] = icq_PacketReadStringNew(p);
|
|
657 icq_RusConv("wk", hpcat[i]);
|
|
658 }
|
|
659 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User Homepage Category: %i, %i - %s\n",
|
|
660 hnum, hcategory[0], hpcat[0]);
|
|
661 if(link->icq_MetaUserHomePageCategory)
|
|
662 (*link->icq_MetaUserHomePageCategory)(link, seq2, hnum, hcategory[0], hpcat[0]?hpcat[0]:empty);
|
|
663 for(i=0; i<hnum && i<1; i++)
|
|
664 free(hpcat[i]);
|
|
665 break;
|
|
666 case META_SRV_RES_INFO:
|
|
667 case META_SRV_RES_HOMEPAGE:
|
|
668 case META_SRV_RES_ABOUT:
|
|
669 case META_SRV_RES_SECURE:
|
|
670 case META_SRV_RES_PASS:
|
|
671 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META success\n");
|
|
672 if(link->icq_RequestNotify)
|
|
673 (*link->icq_RequestNotify)(link, seq2, ICQ_NOTIFY_SUCCESS, sizeof(subcmd), &subcmd);
|
|
674 break;
|
|
675 default:
|
|
676 icq_FmtLog(link, ICQ_LOG_MESSAGE, "META User - 0x%04X\n", subcmd);
|
|
677 icq_PacketUDPDump(p);
|
|
678 break;
|
|
679 }
|
|
680 icq_UDPAck(link, icq_PacketReadUDPInSeq1(p));
|
|
681 }
|
|
682
|
|
683 void icq_HandleMultiPacket(ICQLINK *link, icq_Packet *p)
|
|
684 {
|
|
685 icq_Packet *tmp;
|
|
686 int num, i;
|
|
687 icq_PacketGotoUDPInData(p, 0);
|
|
688 num = icq_PacketRead8(p);
|
|
689
|
|
690 icq_FmtLog(link, ICQ_LOG_MESSAGE, "MultiPacket: %i packets\n", num);
|
|
691
|
|
692 for(i = 0; i < num; i++)
|
|
693 {
|
|
694 tmp = icq_PacketNew();
|
|
695 tmp->length = icq_PacketRead16(p);
|
|
696 memcpy(tmp->data, &(p->data[p->cursor]), tmp->length);
|
|
697 icq_PacketAdvance(p, tmp->length);
|
|
698 icq_ServerResponse(link, tmp);
|
|
699 icq_PacketDelete(tmp);
|
|
700 }
|
|
701 }
|
|
702
|
|
703 void icq_ServerResponse(ICQLINK *link, icq_Packet *p)
|
|
704 {
|
|
705 time_t cur_time;
|
|
706 struct tm *tm_str;
|
|
707 int len;
|
|
708 struct in_addr in_a;
|
|
709 DWORD uin;
|
|
710 WORD year, type, seq, cmd;
|
|
711 BYTE month, day, hour, minute;
|
|
712
|
|
713 seq = icq_PacketReadUDPInSeq1(p);
|
|
714 cmd = icq_PacketReadUDPInCmd(p);
|
|
715
|
|
716 if(icq_PacketReadUDPInVer(p) == 5) /* We understand only V5 packets! */
|
|
717 {
|
|
718 switch(cmd)
|
|
719 {
|
|
720 case UDP_SRV_ACK:
|
|
721 icq_FmtLog(link, ICQ_LOG_MESSAGE, "The server acknowledged the command\n");
|
|
722 if(link->icq_RequestNotify)
|
|
723 {
|
|
724 (*link->icq_RequestNotify)(link, seq, ICQ_NOTIFY_ACK, 0, 0);
|
|
725 (*link->icq_RequestNotify)(link, seq, ICQ_NOTIFY_SUCCESS, 0, 0);
|
|
726 }
|
|
727 icq_UDPQueueDelSeq(link, seq);
|
|
728 if(link->icq_SetTimeout)
|
|
729 link->icq_SetTimeout(link, icq_UDPQueueInterval(link));
|
|
730 break;
|
|
731 case UDP_SRV_MULTI_PACKET:
|
|
732 icq_HandleMultiPacket(link, p);
|
|
733 break;
|
|
734 case UDP_SRV_NEW_UIN:
|
|
735 uin = icq_PacketReadUDPInUIN(p);
|
|
736 icq_FmtLog(link, ICQ_LOG_MESSAGE, "The new uin is %lu\n", uin);
|
|
737 icq_UDPAck(link, seq);
|
|
738 if(link->icq_NewUIN)
|
|
739 (*link->icq_NewUIN)(link, uin);
|
|
740 break;
|
|
741 case UDP_SRV_LOGIN_REPLY:
|
|
742 icq_PacketGotoUDPInData(p, 0);
|
|
743 link->icq_OurIP = ntohl(icq_PacketRead32n(p));
|
|
744 /* icq_OurIp = icq_PacketRead32(p); */
|
|
745 in_a.s_addr = htonl(link->icq_OurIP);
|
|
746 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Login successful, UIN: %lu, IP: %s\n",
|
|
747 link->icq_Uin, inet_ntoa(in_a));
|
|
748 icq_UDPAck(link, seq);
|
|
749 icq_SendLogin1(link);
|
|
750 icq_SendContactList(link);
|
|
751 icq_SendVisibleList(link);
|
|
752 if(link->icq_Logged)
|
|
753 (*link->icq_Logged)(link);
|
|
754 break;
|
|
755 case UDP_SRV_OFFLINE_MESSAGE: /* Offline message through the server */
|
|
756 icq_PacketGotoUDPInData(p, 0);
|
|
757 uin = icq_PacketRead32(p);
|
|
758 year = icq_PacketRead16(p);
|
|
759 month = icq_PacketRead8(p);
|
|
760 day = icq_PacketRead8(p);
|
|
761 hour = icq_PacketRead8(p);
|
|
762 minute = icq_PacketRead8(p);
|
|
763 type = icq_PacketRead16(p);
|
|
764 len = icq_PacketRead16(p);
|
|
765 icq_DoMsg(link, type, len, (char*)&p->data[p->cursor], uin, hour, minute, day, month, year);
|
|
766 icq_UDPAck(link, seq);
|
|
767 break;
|
|
768 case UDP_SRV_X1: /* unknown message sent after login*/
|
|
769 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Acknowleged UDP_SRV_X1 (Begin messages)\n");
|
|
770 icq_UDPAck(link, seq);
|
|
771 break;
|
|
772 case UDP_SRV_X2: /* unknown message sent after login*/
|
|
773 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Acknowleged UDP_SRV_X2 (Done old messages)\n");
|
|
774 icq_UDPAck(link, seq);
|
|
775 icq_SendGotMessages(link);
|
|
776 break;
|
|
777 case UDP_SRV_INFO_REPLY:
|
|
778 icq_HandleInfoReply(link, p);
|
|
779 break;
|
|
780 case UDP_SRV_EXT_INFO_REPLY:
|
|
781 icq_HandleExtInfoReply(link, p);
|
|
782 break;
|
|
783 case UDP_SRV_USER_ONLINE:
|
|
784 icq_HandleUserOnline(link, p);
|
|
785 break;
|
|
786 case UDP_SRV_USER_OFFLINE:
|
|
787 icq_HandleUserOffline(link, p);
|
|
788 break;
|
|
789 case UDP_SRV_TRY_AGAIN:
|
|
790 icq_FmtLog(link, ICQ_LOG_WARNING, "Server is busy, please try again\n");
|
|
791 icq_Login(link, link->icq_Status);
|
|
792 break;
|
|
793 case UDP_SRV_STATUS_UPDATE:
|
|
794 icq_HandleStatusChange(link, p);
|
|
795 break;
|
|
796 case UDP_SRV_GO_AWAY:
|
|
797 icq_FmtLog(link, ICQ_LOG_ERROR, "Server has forced us to disconnect\n");
|
|
798 if(link->icq_Disconnected)
|
|
799 (*link->icq_Disconnected)(link);
|
|
800 break;
|
|
801 case UDP_SRV_END_OF_SEARCH:
|
|
802 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Search done\n");
|
|
803 if(link->icq_SearchDone)
|
|
804 (*link->icq_SearchDone)(link);
|
|
805 icq_UDPAck(link, seq);
|
|
806 break;
|
|
807 case UDP_SRV_USER_FOUND:
|
|
808 icq_HandleSearchReply(link, p);
|
|
809 break;
|
|
810 case UDP_SRV_ONLINE_MESSAGE: /* Online message through the server */
|
|
811 cur_time = time(0L);
|
|
812 tm_str = localtime(&cur_time);
|
|
813 icq_PacketGotoUDPInData(p, 0);
|
|
814 uin = icq_PacketRead32(p);
|
|
815 type = icq_PacketRead16(p);
|
|
816 len = icq_PacketRead16(p);
|
|
817 icq_DoMsg(link, type, len, (char*)&p->data[p->cursor], uin, tm_str->tm_hour,
|
|
818 tm_str->tm_min, tm_str->tm_mday, tm_str->tm_mon+1, tm_str->tm_year+1900);
|
|
819 icq_UDPAck(link, seq);
|
|
820 break;
|
|
821 case UDP_SRV_WRONG_PASSWORD:
|
|
822 icq_FmtLog(link, ICQ_LOG_ERROR, "Wrong password\n");
|
|
823 if(link->icq_WrongPassword)
|
|
824 (*link->icq_WrongPassword)(link);
|
|
825 icq_UDPAck(link, seq);
|
|
826 break;
|
|
827 case UDP_SRV_INVALID_UIN:
|
|
828 icq_FmtLog(link, ICQ_LOG_WARNING, "Invalid UIN\n");
|
|
829 if(link->icq_InvalidUIN)
|
|
830 (*link->icq_InvalidUIN)(link);
|
|
831 icq_UDPAck(link, seq);
|
|
832 break;
|
|
833 case UDP_SRV_META_USER:
|
|
834 icq_HandleMetaUserInfo(link, p);
|
|
835 break;
|
|
836 default: /* commands we dont handle yet */
|
|
837 icq_FmtLog(link, ICQ_LOG_WARNING, "Unhandled message %04x, Version: %x, "
|
|
838 "Sequence: %04x, Size: %d\n", cmd, icq_PacketReadUDPInVer(p),
|
|
839 seq, p->length);
|
|
840 icq_UDPAck(link, seq); /* fake like we know what we're doing */
|
|
841 break;
|
|
842 }
|
|
843 }
|
|
844 else
|
|
845 {
|
|
846 icq_FmtLog(link, ICQ_LOG_WARNING, "Unhandled message %04x, Version: %x, "
|
|
847 "Sequence: %04x, Size: %d\n", cmd, icq_PacketReadUDPInVer(p),
|
|
848 seq, p->length);
|
|
849 icq_UDPAck(link, seq); /* fake like we know what we're doing */
|
|
850 }
|
|
851 }
|
|
852
|
|
853 /******************************************
|
|
854 Handles packets that the server sends to us.
|
|
855 *******************************************/
|
|
856 void icq_HandleServerResponse(ICQLINK *link)
|
|
857 {
|
|
858 WORD seq, cmd;
|
|
859 int s;
|
|
860 icq_Packet *p;
|
|
861
|
|
862 p = icq_PacketNew();
|
|
863 s = icq_UDPSockRead(link, p);
|
|
864 p->length = s;
|
|
865 if(s<=0)
|
|
866 {
|
|
867 icq_FmtLog(link, ICQ_LOG_FATAL, "Connection terminated\n");
|
|
868 icq_Disconnect(link);
|
|
869 if(link->icq_Disconnected)
|
|
870 (*link->icq_Disconnected)(link);
|
|
871 }
|
|
872 seq = icq_PacketReadUDPInSeq1(p);
|
|
873 cmd = icq_PacketReadUDPInCmd(p);
|
|
874 if(icq_GetServMess(link, seq) && cmd != UDP_SRV_NEW_UIN && cmd != UDP_SRV_GO_AWAY && cmd != UDP_SRV_ACK)
|
|
875 {
|
|
876 icq_FmtLog(link, ICQ_LOG_WARNING, "Ignored a message cmd %04x, seq %04x\n", cmd, seq);
|
|
877 icq_UDPAck(link, seq); /* LAGGGGG!! */
|
|
878 icq_PacketDelete(p);
|
|
879 return;
|
|
880 }
|
|
881 if(cmd != UDP_SRV_ACK)
|
|
882 icq_SetServMess(link, seq);
|
|
883
|
|
884 icq_ServerResponse(link, p);
|
|
885
|
|
886 icq_PacketDelete(p);
|
|
887 }
|