1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
4 * $Id: udphandle.c 2096 2001-07-31 01:00:39Z warmenhoven $
6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and
7 * Bill Soudan <soudan@kde.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 #include "icqbyteorder.h"
33 void icq_DoMsg(icq_Link
*icqlink
, DWORD type
, WORD len
, char *data
, DWORD uin
, BYTE hour
,
34 BYTE minute
, BYTE day
, BYTE month
, WORD year
)
39 const char **contact_uin
;
40 const char **contact_nick
;
43 strList
= icq_ListNew();
47 /* Format: Nick, 0xFE, FName, 0xFE, LName, 0xFE, EMail */
48 fieldCount
= icq_SplitFields(strList
, data
);
49 if(fieldCount
!= 4 && fieldCount
!= 5)
51 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Bad TYPE_ADDED packet (expected 4/5 args, received %i)!\n",
55 icq_RusConv("wk", icq_ListAt(strList
, 0)); /* Nick */
56 icq_RusConv("wk", icq_ListAt(strList
, 1)); /* FName */
57 icq_RusConv("wk", icq_ListAt(strList
, 2)); /* LName */
58 icq_RusConv("wk", icq_ListAt(strList
, 3)); /* EMail */
59 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "%lu has added you to their contact list, "
60 "Nick: %s, First Name: %s, Last Name: %s, EMail: %s\n",
61 uin
, icq_ListAt(strList
, 0), icq_ListAt(strList
, 1),
62 icq_ListAt(strList
, 2), icq_ListAt(strList
, 3));
63 invoke_callback(icqlink
,icq_RecvAdded
)(icqlink
, uin
, hour
, minute
, day
, month
, year
,
64 icq_ListAt(strList
, 0), icq_ListAt(strList
, 1),
65 icq_ListAt(strList
, 2), icq_ListAt(strList
, 3));
68 /* Format: Nick, 0xFE, FName, 0xFE, LName, 0xFE, EMail, 0xFE, 0, 0xFE, Reason */
69 fieldCount
= icq_SplitFields(strList
, data
);
72 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Bad TYPE_AUTH_REQ packet (expected 6 args, received %i)!\n",
76 icq_RusConv("wk", icq_ListAt(strList
, 0)); /* Nick */
77 icq_RusConv("wk", icq_ListAt(strList
, 1)); /* FName */
78 icq_RusConv("wk", icq_ListAt(strList
, 2)); /* LName */
79 icq_RusConv("wk", icq_ListAt(strList
, 3)); /* EMail */
80 icq_RusConv("wk", icq_ListAt(strList
, 5)); /* Reason */
81 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "%lu has requested your authorization to be added to "
82 "their contact list, Nick: %s, First Name: %s, Last Name: %s, "
83 "EMail: %s, Reason: %s\n", uin
, icq_ListAt(strList
, 0), icq_ListAt(strList
, 1),
84 icq_ListAt(strList
, 2), icq_ListAt(strList
, 3), icq_ListAt(strList
, 4));
85 invoke_callback(icqlink
,icq_RecvAuthReq
)(icqlink
, uin
, hour
, minute
, day
, month
, year
,
86 icq_ListAt(strList
, 0), icq_ListAt(strList
, 1),
87 icq_ListAt(strList
, 2), icq_ListAt(strList
, 3),
88 icq_ListAt(strList
, 5));
91 /* Format: Description, 0xFE, URL */
92 fieldCount
= icq_SplitFields(strList
, data
);
95 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Bad TYPE_URL packet (expected 2 args, recived %i)!\n",
99 icq_RusConv("wk", icq_ListAt(strList
, 0)); /* Description */
100 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "URL received from %lu, URL: %s, Description: %s\n",
101 uin
, icq_ListAt(strList
, 1), icq_ListAt(strList
, 0));
102 invoke_callback(icqlink
,icq_RecvURL
)(icqlink
, uin
, hour
, minute
, day
, month
, year
,
103 icq_ListAt(strList
, 1), icq_ListAt(strList
, 0));
106 /* Format: Nick, 0xFE, Empty-FName, 0xFE, Empty-LName, 0xFE, EMail, 0xFE,
107 * Reason(3), 0xFE, Message with IP & Subject */
108 fieldCount
= icq_SplitFields(strList
, data
);
111 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Bad TYPE_WEBPAGER packet (expected 6 args, received %i)!\n",
115 icq_RusConv("wk", icq_ListAt(strList
, 0)); /* Nick */
116 icq_RusConv("wk", icq_ListAt(strList
, 5)); /* Message */
117 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "WebPager message received, Nick: %s, EMail: %s, "
118 "Message:\n%s\n", icq_ListAt(strList
, 0), icq_ListAt(strList
, 3),
119 icq_ListAt(strList
, 5));
120 invoke_callback(icqlink
,icq_RecvWebPager
)(icqlink
, hour
, minute
, day
, month
, year
,
121 icq_ListAt(strList
, 0), icq_ListAt(strList
, 3),
122 icq_ListAt(strList
, 5));
125 /* Format: Nick, 0xFE, Empty-FName, 0xFE, Empty-LName, 0xFE, EMail, 0xFE,
126 * Reason(3), 0xFE, Message Subject */
127 fieldCount
= icq_SplitFields(strList
, data
);
130 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Bad TYPE_EXPRESS packet (expected 6 args, received %i)!\n",
134 icq_RusConv("wk", icq_ListAt(strList
, 0)); /* Nick */
135 icq_RusConv("wk", icq_ListAt(strList
, 5)); /* Message */
136 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "MailExpress message received, Nick: %s, EMail: %s, "
137 "Message:\n%s\n", icq_ListAt(strList
, 0), icq_ListAt(strList
, 3),
138 icq_ListAt(strList
, 5));
139 invoke_callback(icqlink
, icq_RecvMailExpress
)(icqlink
, hour
, minute
, day
, month
, year
,
140 icq_ListAt(strList
, 0), icq_ListAt(strList
, 3),
141 icq_ListAt(strList
, 5));
144 /* Format: Number of contacts, 0xFE, UIN, 0xFE, Nick, 0xFE, ... */
145 nr
= icq_SplitFields(strList
, data
);
146 contact_uin
= (const char**)malloc((nr
- 1) / 2);
147 contact_nick
= (const char**)malloc((nr
- 1) / 2);
149 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Contact List received from %lu (%i):\n", uin
,
150 atoi(icq_ListAt(strList
, 0)));
152 for(i
= 1, k
= 0; i
< (nr
- 1); k
++)
154 contact_uin
[k
] = icq_ListAt(strList
, i
);
155 contact_nick
[k
] = icq_ListAt(strList
, i
+ 1);
157 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "\t%s - %s\n", contact_uin
[k
], contact_nick
[k
]);
159 invoke_callback(icqlink
, icq_RecvContactList
)(icqlink
, uin
, hour
, minute
, day
, month
, year
,
160 k
, contact_uin
, contact_nick
);
165 icq_RusConv("wk", data
); /* Entire message */
166 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Instant message type %i from %lu:\n%s\n", type
, uin
, data
);
167 invoke_callback(icqlink
, icq_RecvMessage
)(icqlink
, uin
, hour
, minute
, day
, month
, year
, data
);
169 icq_ListDelete(strList
, free
);
172 void icq_HandleInfoReply(icq_Link
*icqlink
, icq_Packet
*p
)
174 char *ptr1
, *ptr2
, *ptr3
, *ptr4
;
176 icq_PacketGotoUDPInData(p
, 0);
177 uin
= icq_PacketRead32(p
);
178 ptr1
= icq_PacketReadStringNew(p
);
179 ptr2
= icq_PacketReadStringNew(p
);
180 ptr3
= icq_PacketReadStringNew(p
);
181 ptr4
= icq_PacketReadStringNew(p
);
182 icq_RusConv("wk", ptr1
);
183 icq_RusConv("wk", ptr2
);
184 icq_RusConv("wk", ptr3
);
185 icq_RusConv("wk", ptr4
);
186 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Info reply for %lu\n", uin
);
187 icq_UDPAck(icqlink
, icq_PacketReadUDPInSeq1(p
));
188 invoke_callback(icqlink
,icq_InfoReply
)(icqlink
, uin
, ptr1
, ptr2
, ptr3
, ptr4
, icq_PacketRead8(p
));
195 void icq_HandleExtInfoReply(icq_Link
*icqlink
, icq_Packet
*p
)
197 char *ptr1
, *ptr2
, *ptr3
, *ptr4
, *ptr5
;
200 char cnt_stat
, gender
;
202 icq_PacketGotoUDPInData(p
, 0);
203 uin
= icq_PacketRead32(p
);
204 ptr1
= icq_PacketReadStringNew(p
);
205 cnt_code
= icq_PacketRead16(p
);
206 cnt_stat
= icq_PacketRead8(p
);
207 ptr2
= icq_PacketReadStringNew(p
);
208 age
= icq_PacketRead16(p
);
209 gender
= icq_PacketRead8(p
);
210 ptr3
= icq_PacketReadStringNew(p
);
211 ptr4
= icq_PacketReadStringNew(p
);
212 ptr5
= icq_PacketReadStringNew(p
);
213 icq_RusConv("wk", ptr1
);
214 icq_RusConv("wk", ptr2
);
215 icq_RusConv("wk", ptr3
);
216 icq_RusConv("wk", ptr4
);
217 icq_RusConv("wk", ptr5
);
218 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Extended info reply for %lu\n", uin
);
219 icq_UDPAck(icqlink
, icq_PacketReadUDPInSeq1(p
));
220 invoke_callback(icqlink
,icq_ExtInfoReply
)(icqlink
, uin
, (char*)ptr1
, cnt_code
, cnt_stat
, (char*)ptr2
,
221 age
, gender
, (char*)ptr3
, (char*)ptr4
, (char*)ptr5
);
229 void icq_HandleSearchReply(icq_Link
*icqlink
, icq_Packet
*p
)
231 char *ptr1
, *ptr2
, *ptr3
, *ptr4
, auth
;
233 icq_PacketGotoUDPInData(p
, 0);
234 uin
= icq_PacketRead32(p
);
235 ptr1
= icq_PacketReadStringNew(p
);
236 ptr2
= icq_PacketReadStringNew(p
);
237 ptr3
= icq_PacketReadStringNew(p
);
238 ptr4
= icq_PacketReadStringNew(p
);
239 icq_RusConv("wk", ptr1
);
240 icq_RusConv("wk", ptr2
);
241 icq_RusConv("wk", ptr3
);
242 icq_RusConv("wk", ptr4
);
243 auth
= icq_PacketRead8(p
);
244 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "User found %lu, Nick: %s, First Name: %s, Last Name: %s, "
245 "EMail: %s, Auth: %s\n", uin
, ptr1
, ptr2
, ptr3
, ptr4
, auth
==1?"no":"yes");
246 icq_UDPAck(icqlink
, icq_PacketReadUDPInSeq1(p
));
247 invoke_callback(icqlink
,icq_UserFound
)(icqlink
, uin
, (char*)ptr1
, (char*)ptr2
,
248 (char*)ptr3
, (char*)ptr4
, auth
);
255 /************************************************
256 This is called when a user goes offline
257 *************************************************/
258 void icq_HandleUserOffline(icq_Link
*icqlink
, icq_Packet
*p
)
261 icq_ContactItem
*ptr
;
263 icq_PacketGotoUDPInData(p
, 0);
264 remote_uin
= icq_PacketRead32(p
);
265 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "User %lu logged off\n", remote_uin
);
267 ptr
=icq_ContactFind(icqlink
, remote_uin
);
271 ptr
->remote_port
= 0;
273 icq_UDPAck(icqlink
, icq_PacketReadUDPInSeq1(p
));
274 invoke_callback(icqlink
,icq_UserOffline
)(icqlink
, remote_uin
);
277 void icq_HandleUserOnline(icq_Link
*icqlink
, icq_Packet
*p
)
279 DWORD remote_uin
, new_status
, remote_ip
, remote_real_ip
;
280 DWORD remote_port
; /* Why Mirabilis used 4 bytes for port? */
282 icq_ContactItem
*ptr
;
284 icq_PacketGotoUDPInData(p
, 0);
285 remote_uin
= icq_PacketRead32(p
);
286 remote_ip
= ntohl(icq_PacketRead32n(p
)); /* icqtohl() */
287 remote_port
= icqtohl(icq_PacketRead32n(p
));
288 remote_real_ip
= ntohl(icq_PacketRead32n(p
)); /* icqtohl() */
289 tcp_flag
= icq_PacketRead8(p
);
290 new_status
= icq_PacketRead32(p
);
292 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
,
293 "User %lu (%s = 0x%X) logged on. tcp_flag=0x%X IP=%08X, real IP=%08X, port=%d\n",
294 remote_uin
, icq_ConvertStatus2Str(new_status
), new_status
, tcp_flag
, remote_ip
,
295 remote_real_ip
, remote_port
);
297 ptr
=icq_ContactFind(icqlink
, remote_uin
);
300 ptr
->remote_ip
=remote_ip
;
301 ptr
->remote_real_ip
=remote_real_ip
;
302 ptr
->remote_port
= remote_port
;
303 ptr
->tcp_flag
= tcp_flag
;
305 icq_UDPAck(icqlink
, icq_PacketReadUDPInSeq1(p
));
306 invoke_callback(icqlink
,icq_UserOnline
)(icqlink
, remote_uin
, new_status
, remote_ip
,
307 remote_port
, remote_real_ip
, tcp_flag
);
310 void icq_HandleStatusChange(icq_Link
*icqlink
, icq_Packet
*p
)
312 unsigned long remote_uin
, new_status
;
314 icq_PacketGotoUDPInData(p
, 0);
315 remote_uin
= icq_PacketRead32(p
);
316 new_status
= icq_PacketRead32(p
);
317 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "%lu changed status to %s (0x%X)\n", remote_uin
,
318 icq_ConvertStatus2Str(new_status
), new_status
);
319 icq_UDPAck(icqlink
, icq_PacketReadUDPInSeq1(p
));
320 invoke_callback(icqlink
,icq_UserStatusUpdate
)(icqlink
, remote_uin
, new_status
);
323 void icq_HandleMetaUserInfo(icq_Link
*icqlink
, icq_Packet
*p
)
325 unsigned short subcmd
, country
, seq2
, age
, occupation
, wcountry
;
326 char res
, auth
, timezone
, webaware
, hideip
, gender
;
327 char *nick
, *first
, *last
, *email
, *about
, *city
;
328 char *pri_eml
, *sec_eml
, *old_eml
;
329 char *phone
, *fax
, *street
, *cellular
, *state
;
330 char *wcity
, *wstate
, *wphone
, *wfax
, *waddress
;
331 char *company
, *department
, *job
, *whomepage
;
333 char byear
, bmonth
, bday
, lang1
, lang2
, lang3
, inum
;
335 char anum
, bnum
, hnum
;
336 unsigned long uin
, zip
, wzip
;
338 char *interests
[4] = {0, 0, 0, 0};
339 unsigned short icategory
[4] = {0, 0, 0, 0};
340 char *affiliations
[4] = {0, 0, 0, 0};
341 unsigned short acategory
[4] = {0, 0, 0, 0};
342 char *backgrounds
[4] = {0, 0, 0, 0};
343 unsigned short bcategory
[4] = {0, 0, 0, 0};
344 char *hpcat
[4] = {0, 0, 0, 0};
345 unsigned short hcategory
[4] = {0, 0, 0, 0};
347 seq2
= icq_PacketReadUDPInSeq2(p
);
348 icq_PacketGotoUDPInData(p
, 0);
349 subcmd
= icq_PacketRead16(p
);
350 res
= icq_PacketRead8(p
);
351 icq_UDPAck(icqlink
, icq_PacketReadUDPInSeq1(p
));
352 if(res
== META_SRV_FAILURE
)
354 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "META failure\n");
355 invoke_callback(icqlink
,icq_RequestNotify
)(icqlink
, seq2
, ICQ_NOTIFY_FAILED
,
356 sizeof(subcmd
), &subcmd
);
361 case META_SRV_USER_FOUND
:
362 uin
= icq_PacketRead32(p
);
363 nick
= icq_PacketReadStringNew(p
);
364 first
= icq_PacketReadStringNew(p
);
365 last
= icq_PacketReadStringNew(p
);
366 email
= icq_PacketReadStringNew(p
);
367 auth
= icq_PacketRead8(p
);
368 icq_PacketRead16(p
); /* ??? */
369 icq_PacketRead32(p
); /* ??? */
370 icq_RusConv("wk", nick
);
371 icq_RusConv("wk", first
);
372 icq_RusConv("wk", last
);
373 icq_RusConv("wk", email
);
374 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User Found %lu, Nick: %s, First Name: %s, "\
375 "Last Name: %s, EMail: %s, Auth: %s\n", seq2
, uin
, nick
, first
, last
,
376 email
, auth
==1?"no":"yes");
377 invoke_callback(icqlink
,icq_MetaUserFound
)(icqlink
, seq2
, uin
, nick
, first
, last
, email
, auth
);
383 case META_SRV_USER_INFO
: /* finished! */
384 nick
= icq_PacketReadStringNew(p
);
385 first
= icq_PacketReadStringNew(p
);
386 last
= icq_PacketReadStringNew(p
);
387 pri_eml
= icq_PacketReadStringNew(p
);
388 sec_eml
= icq_PacketReadStringNew(p
);
389 old_eml
= icq_PacketReadStringNew(p
);
390 city
= icq_PacketReadStringNew(p
);
391 state
= icq_PacketReadStringNew(p
);
392 phone
= icq_PacketReadStringNew(p
);
393 fax
= icq_PacketReadStringNew(p
);
394 street
= icq_PacketReadStringNew(p
);
395 cellular
= icq_PacketReadStringNew(p
);
396 zip
= icq_PacketRead32(p
);
397 country
= icq_PacketRead16(p
);
398 timezone
= icq_PacketRead8(p
); /* +1 = -30min, -1 = +30min (-4 = GMT+0200) */
399 auth
= icq_PacketRead8(p
); /* 1 - no auth required, 0 - required */
400 webaware
= icq_PacketRead8(p
); /* 1 - yes, 0 - no */
401 hideip
= icq_PacketRead8(p
); /* 1 - yes, 0 - no */
402 icq_RusConv("wk", nick
);
403 icq_RusConv("wk", first
);
404 icq_RusConv("wk", last
);
405 icq_RusConv("wk", pri_eml
);
406 icq_RusConv("wk", sec_eml
);
407 icq_RusConv("wk", old_eml
);
408 icq_RusConv("wk", city
);
409 icq_RusConv("wk", state
);
410 icq_RusConv("wk", phone
);
411 icq_RusConv("wk", fax
);
412 icq_RusConv("wk", street
);
413 icq_RusConv("wk", cellular
);
414 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User Info: %s, %s, %s, "\
415 "%s, %s, %s, %s, %s, %s, %s, %s, %s, %lu, %s, %i, %s, %s, %s\n",
416 nick
, first
, last
, pri_eml
, sec_eml
, old_eml
, city
, state
, phone
,
417 fax
, street
, cellular
, zip
, icq_GetCountryName(country
), timezone
,
418 auth
?"false":"true", webaware
?"true":"false", hideip
?"true":"false");
419 invoke_callback(icqlink
,icq_MetaUserInfo
)(icqlink
, seq2
, nick
, first
, last
, pri_eml
,
420 sec_eml
, old_eml
, city
, state
, phone
, fax
,
421 street
, cellular
, zip
, country
, timezone
,
422 auth
, webaware
, hideip
);
436 case META_SRV_USER_WORK
: /* finished! */
437 wcity
= icq_PacketReadStringNew(p
);
438 wstate
= icq_PacketReadStringNew(p
);
439 wphone
= icq_PacketReadStringNew(p
);
440 wfax
= icq_PacketReadStringNew(p
);
441 waddress
= icq_PacketReadStringNew(p
);
442 wzip
= icq_PacketRead32(p
);
443 wcountry
= icq_PacketRead16(p
); /* icq_GetCountryName() */
444 company
= icq_PacketReadStringNew(p
);
445 department
= icq_PacketReadStringNew(p
);
446 job
= icq_PacketReadStringNew(p
);
447 occupation
= icq_PacketRead16(p
); /* icq_GetMetaOccupationName() */
448 whomepage
= icq_PacketReadStringNew(p
);
449 icq_RusConv("wk", wcity
);
450 icq_RusConv("wk", wstate
);
451 icq_RusConv("wk", wphone
);
452 icq_RusConv("wk", wfax
);
453 icq_RusConv("wk", waddress
);
454 icq_RusConv("wk", company
);
455 icq_RusConv("wk", department
);
456 icq_RusConv("wk", job
);
457 icq_RusConv("wk", whomepage
);
458 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User Work: %s, %s, %s, "\
459 "%s, %s, %lu, %s, %s, %s, %s, %s, %s\n", wcity
, wstate
,
460 wphone
, wfax
, waddress
, wzip
, icq_GetCountryName(wcountry
),
461 company
, department
, job
, icq_GetMetaOccupationName(occupation
),
463 invoke_callback(icqlink
, icq_MetaUserWork
)(icqlink
, seq2
, wcity
, wstate
, wphone
,
464 wfax
, waddress
, wzip
, wcountry
, company
,
465 department
, job
, occupation
, whomepage
);
476 case META_SRV_USER_MORE
: /* finished! */
477 age
= icq_PacketRead16(p
); /* 0xFFFF - not entered */
478 gender
= icq_PacketRead8(p
); /* 1 - female, 2 - male */
479 homepage
= icq_PacketReadStringNew(p
);
480 byear
= icq_PacketRead8(p
); /* starting from 1900 */
481 bmonth
= icq_PacketRead8(p
);
482 bday
= icq_PacketRead8(p
);
483 lang1
= icq_PacketRead8(p
); /* icq_GetMetaLanguageName() */
484 lang2
= icq_PacketRead8(p
); /* icq_GetMetaLanguageName() */
485 lang3
= icq_PacketRead8(p
); /* icq_GetMetaLanguageName() */
486 icq_RusConv("wk", homepage
);
487 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User More: %i, %s, %s, "\
488 "%02i/%02i/%04i, %s, %s, %s\n", age
,
489 gender
==1?"female":gender
==2?"male":"not entered",
490 homepage
, bday
, bmonth
, byear
+1900, icq_GetMetaLanguageName(lang1
),
491 icq_GetMetaLanguageName(lang2
), icq_GetMetaLanguageName(lang3
));
492 if(icqlink
->icq_MetaUserMore
)
493 (*icqlink
->icq_MetaUserMore
)(icqlink
, seq2
, age
, gender
, homepage
, byear
,
494 bmonth
, bday
, lang1
, lang2
, lang3
);
497 case META_SRV_USER_ABOUT
: /* finished! */
498 about
= icq_PacketReadStringNew(p
);
499 icq_RusConv("wk", about
);
500 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User About: %s\n", about
);
501 invoke_callback(icqlink
,icq_MetaUserAbout
)(icqlink
, seq2
, about
);
504 case META_SRV_USER_INTERESTS
: /* finished! */
505 inum
= icq_PacketRead8(p
);
506 for(i
=0; i
<inum
&& i
<4; i
++)
508 icategory
[i
] = icq_PacketRead16(p
);
509 interests
[i
] = icq_PacketReadStringNew(p
);
510 icq_RusConv("wk", interests
[i
]);
512 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User Interests: %i, %i - %s, "\
513 "%i - %s, %i - %s, %i - %s\n", inum
, icategory
[0],
514 interests
[0]?interests
[0]:empty
, icategory
[1], interests
[1]?interests
[1]:empty
,
515 icategory
[2], interests
[2]?interests
[2]:empty
, icategory
[3],
516 interests
[3]?interests
[3]:empty
);
517 invoke_callback(icqlink
, icq_MetaUserInterests
)(icqlink
, seq2
, inum
,
518 icategory
[0], interests
[0], icategory
[1],
519 interests
[1], icategory
[2], interests
[2],
520 icategory
[3], interests
[3]);
521 for(i
=0; i
<inum
&& i
<4; i
++)
524 case META_SRV_USER_AFFILIATIONS
: /* finished! */
525 bnum
= icq_PacketRead8(p
);
526 for(i
=0; i
<bnum
&& i
<4; i
++)
528 bcategory
[i
] = icq_PacketRead16(p
); /* icq_GetMetaBackgroundName() */
529 backgrounds
[i
] = icq_PacketReadStringNew(p
);
530 icq_RusConv("wk", backgrounds
[i
]);
532 anum
= icq_PacketRead8(p
);
533 for(i
=0; i
<anum
&& i
<4; i
++)
535 acategory
[i
] = icq_PacketRead16(p
); /* icq_GetMetaAffiliationName() */
536 affiliations
[i
] = icq_PacketReadStringNew(p
);
537 icq_RusConv("wk", affiliations
[i
]);
539 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User Affiliations: %i, %s - %s, "\
540 "%s - %s, %s - %s, %s - %s; Backgrounds: %i, %s - %s, %s - %s, "\
541 "%s - %s, %s - %s\n", anum
,
542 icq_GetMetaAffiliationName(acategory
[0]), affiliations
[0]?affiliations
[0]:empty
,
543 icq_GetMetaAffiliationName(acategory
[1]), affiliations
[1]?affiliations
[1]:empty
,
544 icq_GetMetaAffiliationName(acategory
[2]), affiliations
[2]?affiliations
[2]:empty
,
545 icq_GetMetaAffiliationName(acategory
[3]), affiliations
[3]?affiliations
[3]:empty
,
546 bnum
, icq_GetMetaBackgroundName(bcategory
[0]), backgrounds
[0]?backgrounds
[0]:empty
,
547 icq_GetMetaBackgroundName(bcategory
[1]), backgrounds
[1]?backgrounds
[1]:empty
,
548 icq_GetMetaBackgroundName(bcategory
[2]), backgrounds
[2]?backgrounds
[2]:empty
,
549 icq_GetMetaBackgroundName(bcategory
[3]), backgrounds
[3]?backgrounds
[3]:empty
);
550 invoke_callback(icqlink
, icq_MetaUserAffiliations
)(icqlink
, seq2
, anum
, acategory
[0],
551 affiliations
[0], acategory
[1], affiliations
[1],
552 acategory
[2], affiliations
[2], acategory
[3],
553 affiliations
[3], bnum
, bcategory
[0],
554 backgrounds
[0], bcategory
[1], backgrounds
[1],
555 bcategory
[2], backgrounds
[2], bcategory
[3],
557 for(i
=0; i
<bnum
&& i
<4; i
++)
558 free(backgrounds
[i
]);
559 for(i
=0; i
<anum
&& i
<4; i
++)
560 free(affiliations
[i
]);
562 case META_SRV_USER_HPCATEGORY
: /* finished! */
563 hnum
= icq_PacketRead8(p
);
564 for(i
=0; i
<hnum
&& i
<1; i
++)
566 hcategory
[i
] = icq_PacketRead16(p
);
567 hpcat
[i
] = icq_PacketReadStringNew(p
);
568 icq_RusConv("wk", hpcat
[i
]);
570 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User Homepage Category: %i, %i - %s\n",
571 hnum
, hcategory
[0], hpcat
[0]);
572 invoke_callback(icqlink
,icq_MetaUserHomePageCategory
)(icqlink
, seq2
,
573 hnum
, hcategory
[0], hpcat
[0]?hpcat
[0]:empty
);
574 for(i
=0; i
<hnum
&& i
<1; i
++)
577 case META_SRV_RES_INFO
:
578 case META_SRV_RES_HOMEPAGE
:
579 case META_SRV_RES_ABOUT
:
580 case META_SRV_RES_SECURE
:
581 case META_SRV_RES_PASS
:
582 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META success\n");
583 invoke_callback(icqlink
,icq_RequestNotify
)(icqlink
, seq2
, ICQ_NOTIFY_SUCCESS
,
584 sizeof(subcmd
), &subcmd
);
587 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "META User - 0x%04X\n", subcmd
);
588 icq_PacketUDPDump(p
);
593 void icq_HandleMultiPacket(icq_Link
*icqlink
, icq_Packet
*p
)
597 icq_PacketGotoUDPInData(p
, 0);
598 num
= icq_PacketRead8(p
);
600 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "MultiPacket: %i packets\n", num
);
602 for(i
= 0; i
< num
; i
++)
604 tmp
= icq_PacketNew();
605 tmp
->length
= icq_PacketRead16(p
);
606 memcpy(tmp
->data
, &(p
->data
[p
->cursor
]), tmp
->length
);
607 icq_PacketAdvance(p
, tmp
->length
);
608 icq_ServerResponse(icqlink
, tmp
);
609 icq_PacketDelete(tmp
);
613 void icq_ServerResponse(icq_Link
*icqlink
, icq_Packet
*p
)
620 WORD year
, type
, seq
, cmd
, ver
;
621 BYTE month
, day
, hour
, minute
;
623 seq
= icq_PacketReadUDPInSeq1(p
);
624 cmd
= icq_PacketReadUDPInCmd(p
);
625 ver
= icq_PacketReadUDPInVer(p
);
627 if(ver
== 5) /* We understand only V5 packets! */
632 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "The server acknowledged the command\n");
633 invoke_callback(icqlink
,icq_RequestNotify
)(icqlink
, seq
, ICQ_NOTIFY_ACK
, 0, 0);
634 invoke_callback(icqlink
,icq_RequestNotify
)(icqlink
, seq
, ICQ_NOTIFY_SUCCESS
, 0, 0);
635 icq_UDPQueueDelSeq(icqlink
, seq
);
637 case UDP_SRV_MULTI_PACKET
:
638 icq_HandleMultiPacket(icqlink
, p
);
640 case UDP_SRV_NEW_UIN
:
641 uin
= icq_PacketReadUDPInUIN(p
);
642 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "The new uin is %lu\n", uin
);
643 icq_UDPAck(icqlink
, seq
);
644 invoke_callback(icqlink
,icq_NewUIN
)(icqlink
, uin
);
646 case UDP_SRV_LOGIN_REPLY
:
647 icq_PacketGotoUDPInData(p
, 0);
648 icqlink
->icq_OurIP
= ntohl(icq_PacketRead32n(p
));
649 /* icq_OurIp = icq_PacketRead32(p); */
650 in_a
.s_addr
= htonl(icqlink
->icq_OurIP
);
651 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Login successful, UIN: %lu, IP: %s\n",
652 icqlink
->icq_Uin
, inet_ntoa(in_a
));
653 icq_UDPAck(icqlink
, seq
);
654 icq_SendLogin1(icqlink
);
655 icq_SendContactList(icqlink
);
656 icq_SendVisibleList(icqlink
);
657 icq_SendInvisibleList(icqlink
);
658 invoke_callback(icqlink
,icq_Logged
)(icqlink
);
660 case UDP_SRV_OFFLINE_MESSAGE
: /* Offline message through the server */
661 icq_PacketGotoUDPInData(p
, 0);
662 uin
= icq_PacketRead32(p
);
663 year
= icq_PacketRead16(p
);
664 month
= icq_PacketRead8(p
);
665 day
= icq_PacketRead8(p
);
666 hour
= icq_PacketRead8(p
);
667 minute
= icq_PacketRead8(p
);
668 type
= icq_PacketRead16(p
);
669 len
= icq_PacketRead16(p
);
670 icq_UDPAck(icqlink
, seq
);
671 icq_DoMsg(icqlink
, type
, len
, (char*)&p
->data
[p
->cursor
], uin
, hour
, minute
, day
, month
, year
);
673 case UDP_SRV_X1
: /* unknown message sent after login*/
674 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Acknowleged UDP_SRV_X1 (Begin messages)\n");
675 icq_UDPAck(icqlink
, seq
);
677 case UDP_SRV_X2
: /* unknown message sent after login*/
678 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Acknowleged UDP_SRV_X2 (Done old messages)\n");
679 icq_UDPAck(icqlink
, seq
);
680 icq_SendGotMessages(icqlink
);
682 case UDP_SRV_INFO_REPLY
:
683 icq_HandleInfoReply(icqlink
, p
);
685 case UDP_SRV_EXT_INFO_REPLY
:
686 icq_HandleExtInfoReply(icqlink
, p
);
688 case UDP_SRV_USER_ONLINE
:
689 icq_HandleUserOnline(icqlink
, p
);
691 case UDP_SRV_USER_OFFLINE
:
692 icq_HandleUserOffline(icqlink
, p
);
694 case UDP_SRV_TRY_AGAIN
:
695 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "Server is busy, please try again\n");
696 icq_Login(icqlink
, icqlink
->icq_Status
);
698 case UDP_SRV_STATUS_UPDATE
:
699 icq_HandleStatusChange(icqlink
, p
);
701 case UDP_SRV_GO_AWAY
:
702 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Server has forced us to disconnect\n");
703 icq_UDPAck(icqlink
, seq
);
704 invoke_callback(icqlink
, icq_Disconnected
)(icqlink
);
706 case UDP_SRV_END_OF_SEARCH
:
707 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "Search done\n");
708 icq_UDPAck(icqlink
, seq
);
709 invoke_callback(icqlink
, icq_SearchDone
)(icqlink
);
711 case UDP_SRV_UPDATE_OK
:
712 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "User info successfully updated\n");
713 icq_UDPAck(icqlink
, seq
);
714 invoke_callback(icqlink
, icq_UpdateSuccess
)(icqlink
);
716 case UDP_SRV_UPDATE_FAIL
:
717 icq_FmtLog(icqlink
, ICQ_LOG_MESSAGE
, "User info update failed\n");
718 icq_UDPAck(icqlink
, seq
);
719 invoke_callback(icqlink
, icq_UpdateFailure
)(icqlink
);
721 case UDP_SRV_USER_FOUND
:
722 icq_HandleSearchReply(icqlink
, p
);
724 case UDP_SRV_ONLINE_MESSAGE
: /* Online message through the server */
726 tm_str
= localtime(&cur_time
);
727 icq_PacketGotoUDPInData(p
, 0);
728 uin
= icq_PacketRead32(p
);
729 type
= icq_PacketRead16(p
);
730 len
= icq_PacketRead16(p
);
731 icq_UDPAck(icqlink
, seq
);
732 icq_DoMsg(icqlink
, type
, len
, (char*)&p
->data
[p
->cursor
], uin
, tm_str
->tm_hour
,
733 tm_str
->tm_min
, tm_str
->tm_mday
, tm_str
->tm_mon
+1, tm_str
->tm_year
+1900);
735 case UDP_SRV_WRONG_PASSWORD
:
736 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Wrong password\n");
737 icq_UDPAck(icqlink
, seq
);
738 invoke_callback(icqlink
,icq_WrongPassword
)(icqlink
);
740 case UDP_SRV_INVALID_UIN
:
741 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "Invalid UIN\n");
742 icq_UDPAck(icqlink
, seq
);
743 invoke_callback(icqlink
,icq_InvalidUIN
)(icqlink
);
745 case UDP_SRV_META_USER
:
746 icq_HandleMetaUserInfo(icqlink
, p
);
748 default: /* commands we dont handle yet */
749 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "Unhandled message %04x, Version: %x, "
750 "Sequence: %04x, Size: %d\n", cmd
, ver
, seq
, p
->length
);
751 icq_UDPAck(icqlink
, seq
); /* fake like we know what we're doing */
755 else if(ver
== 3) /* And some of V3... */
757 cmd
= icq_PacketReadUDPInCmdV3(p
);
760 case UDP_SRV_WRONG_PASSWORD
:
761 icq_FmtLog(icqlink
, ICQ_LOG_ERROR
, "Wrong password\n");
762 icq_UDPAck(icqlink
, seq
);
763 invoke_callback(icqlink
,icq_WrongPassword
)(icqlink
);
765 default: /* commands we dont handle yet */
766 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "Unhandled message %04x, Version: %x, "
767 "Sequence: %04x, Size: %d\n", cmd
, ver
, seq
, p
->length
);
768 icq_UDPAck(icqlink
, seq
); /* fake like we know what we're doing */
774 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "Unhandled protocol version! Message %04x, Version: %x, "
775 "Sequence: %04x, Size: %d\n", cmd
, ver
, seq
, p
->length
);
776 /* icq_UDPAck(icqlink, seq); DO NOT ACK unhandled protocol version! */
780 /******************************************
781 Handles packets that the server sends to us.
782 *******************************************/
783 void icq_HandleServerResponse(icq_Link
*icqlink
)
790 s
= icq_UDPSockRead(icqlink
, p
);
794 icq_FmtLog(icqlink
, ICQ_LOG_FATAL
, "Connection terminated\n");
795 icq_Disconnect(icqlink
);
796 invoke_callback(icqlink
,icq_Disconnected
)(icqlink
);
799 seq
= icq_PacketReadUDPInSeq1(p
);
800 cmd
= icq_PacketReadUDPInCmd(p
);
801 if(icq_GetServMess(icqlink
, seq
) && cmd
!= UDP_SRV_NEW_UIN
&& cmd
!= UDP_SRV_GO_AWAY
&& cmd
!= UDP_SRV_ACK
)
803 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "Ignored a message cmd %04x, seq %04x\n", cmd
, seq
);
804 icq_UDPAck(icqlink
, seq
); /* LAGGGGG!! */
808 if(cmd
!= UDP_SRV_ACK
)
809 icq_SetServMess(icqlink
, seq
);
811 icq_ServerResponse(icqlink
, p
);