comparison plugins/icq/udp.c @ 1152:201ec77f3a60

[gaim-migrate @ 1162] icq. whoop de doo committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Tue, 28 Nov 2000 02:22:42 +0000
parents
children 0a766047b4fd
comparison
equal deleted inserted replaced
1151:428372cc1e39 1152:201ec77f3a60
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3 $Id: udp.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.23 2000/07/09 22:19:35 bills
9 added new *Close functions, use *Close functions instead of *Delete
10 where correct, and misc cleanup
11
12 Revision 1.22 2000/07/09 18:25:44 denis
13 icq_UpdateNewUserInfo() now returns seq1 instead of seq2 since it
14 isn't META function.
15
16 Revision 1.21 2000/06/25 16:43:19 denis
17 icq_SendMetaInfoReq() was added.
18 All icq_*Meta*() functions now returns sequence number 2 because their
19 replies from the server are synced with it.
20
21 Revision 1.20 2000/06/15 01:50:39 bills
22 removed *Seq functions
23
24 Revision 1.19 2000/05/10 19:06:59 denis
25 UDP outgoing packet queue was implemented.
26
27 Revision 1.18 2000/05/03 18:34:43 denis
28 icq_UpdateNewUserInfo() was added.
29 All icq_UpdateMetaInfo*() now return their sequence number.
30
31 Revision 1.17 2000/04/10 16:36:04 denis
32 Some more Win32 compatibility from Guillaume Rosanis <grs@mail.com>
33
34 Revision 1.16 2000/04/06 19:03:07 denis
35 return sequence number
36
37 Revision 1.15 2000/04/06 16:36:18 denis
38 So called "Online List problem" bug with Long Contact List was fixed.
39 icq_*Send*Seq() functions with specified sequence number were added.
40
41 Revision 1.14 2000/04/05 14:37:02 denis
42 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
43 compatibility.
44
45 Revision 1.13 1999/12/27 11:12:35 denis
46 icq_UpdateMetaInfoSecurity() added for setting "My authorization is
47 required", "Web Aware" and "IP Publishing".
48
49 Revision 1.12 1999/10/14 11:43:28 denis
50 icq_UpdateMetaInfo* functions added.
51
52 Revision 1.11 1999/10/07 18:36:27 denis
53 proxy.h file removed.
54
55 Revision 1.10 1999/10/04 13:36:17 denis
56 Cleanups.
57
58 Revision 1.9 1999/09/29 20:15:30 bills
59 tcp port wasn't being sent properly in login packet
60
61 Revision 1.8 1999/09/29 17:13:45 denis
62 Webaware functions enabled without success even with UDP v5 - need more
63 investigations.
64
65 Revision 1.7 1999/07/18 20:22:16 bills
66 changed to use new byte-order functions & contact list functions
67
68 Revision 1.6 1999/07/16 15:46:00 denis
69 Cleaned up.
70
71 Revision 1.5 1999/07/16 12:40:53 denis
72 ICQ UDP v5 implemented.
73 Encription for ICQ UDP v5 implemented.
74 icq_Packet* unified interface for UDP packets implemented.
75 Multipacket support of ICQ UDP v5 support added.
76
77 Revision 1.4 1999/07/12 15:13:43 cproch
78 - added definition of ICQLINK to hold session-specific global variabled
79 applications which have more than one connection are now possible
80 - changed nearly every function defintion to support ICQLINK parameter
81
82 Revision 1.3 1999/04/29 09:40:52 denis
83 Unsuccessful attempt to implement web presence (webaware) feature
84
85 Revision 1.2 1999/04/14 15:04:13 denis
86 Cleanups for "strict" compiling (-ansi -pedantic)
87 Switched from icq_Log callback to icq_Fmt function.
88
89 Revision 1.1 1999/03/24 11:37:38 denis
90 Underscored files with TCP stuff renamed.
91 TCP stuff cleaned up
92 Function names changed to corresponding names.
93 icqlib.c splitted to many small files by subject.
94 C++ comments changed to ANSI C comments.
95
96 */
97
98 #ifndef _WIN32
99 #include <unistd.h>
100 #endif
101
102 #ifdef _WIN32
103 #include <winsock.h>
104 #endif
105
106 #include <stdlib.h>
107
108 #include "icqtypes.h"
109 #include "icqlib.h"
110 #include "udp.h"
111 #include "queue.h"
112
113 #include "stdpackets.h"
114 #include "icqbyteorder.h"
115
116 static const BYTE icq_UDPTable[] = {
117 0x59, 0x60, 0x37, 0x6B, 0x65, 0x62, 0x46, 0x48, 0x53, 0x61, 0x4C, 0x59, 0x60, 0x57, 0x5B, 0x3D,
118 0x5E, 0x34, 0x6D, 0x36, 0x50, 0x3F, 0x6F, 0x67, 0x53, 0x61, 0x4C, 0x59, 0x40, 0x47, 0x63, 0x39,
119 0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x43, 0x69, 0x48, 0x33, 0x31, 0x64, 0x35, 0x5A, 0x4A, 0x42,
120 0x56, 0x40, 0x67, 0x53, 0x41, 0x07, 0x6C, 0x49, 0x58, 0x3B, 0x4D, 0x46, 0x68, 0x43, 0x69, 0x48,
121 0x33, 0x31, 0x44, 0x65, 0x62, 0x46, 0x48, 0x53, 0x41, 0x07, 0x6C, 0x69, 0x48, 0x33, 0x51, 0x54,
122 0x5D, 0x4E, 0x6C, 0x49, 0x38, 0x4B, 0x55, 0x4A, 0x62, 0x46, 0x48, 0x33, 0x51, 0x34, 0x6D, 0x36,
123 0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x63, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64, 0x35, 0x5A,
124 0x6A, 0x52, 0x6E, 0x3C, 0x51, 0x34, 0x6D, 0x36, 0x50, 0x5F, 0x5F, 0x3F, 0x4F, 0x37, 0x4B, 0x35,
125 0x5A, 0x4A, 0x62, 0x66, 0x58, 0x3B, 0x4D, 0x66, 0x58, 0x5B, 0x5D, 0x4E, 0x6C, 0x49, 0x58, 0x3B,
126 0x4D, 0x66, 0x58, 0x3B, 0x4D, 0x46, 0x48, 0x53, 0x61, 0x4C, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64,
127 0x55, 0x6A, 0x32, 0x3E, 0x44, 0x45, 0x52, 0x6E, 0x3C, 0x31, 0x64, 0x55, 0x6A, 0x52, 0x4E, 0x6C,
128 0x69, 0x48, 0x53, 0x61, 0x4C, 0x39, 0x30, 0x6F, 0x47, 0x63, 0x59, 0x60, 0x57, 0x5B, 0x3D, 0x3E,
129 0x64, 0x35, 0x3A, 0x3A, 0x5A, 0x6A, 0x52, 0x4E, 0x6C, 0x69, 0x48, 0x53, 0x61, 0x6C, 0x49, 0x58,
130 0x3B, 0x4D, 0x46, 0x68, 0x63, 0x39, 0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x67, 0x53, 0x41, 0x25, 0x41,
131 0x3C, 0x51, 0x54, 0x3D, 0x5E, 0x54, 0x5D, 0x4E, 0x4C, 0x39, 0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F,
132 0x47, 0x43, 0x69, 0x48, 0x33, 0x51, 0x54, 0x5D, 0x6E, 0x3C, 0x31, 0x64, 0x35, 0x5A, 0x00, 0x00,
133 };
134
135 void icq_UDPCheckCode(icq_Packet *p)
136 {
137 DWORD num1, num2;
138 DWORD r1,r2;
139
140 num1 = p->data[8];
141 num1 <<= 8;
142 num1 += p->data[4];
143 num1 <<= 8;
144 num1 += p->data[2];
145 num1 <<= 8;
146 num1 += p->data[6];
147
148 r1 = 0x18 + (rand() % (p->length - 0x18));
149 r2 = rand() & 0xff;
150
151 num2 = r1;
152 num2 <<= 8;
153 num2 += p->data[r1];
154 num2 <<= 8;
155 num2 += r2;
156 num2 <<= 8;
157 num2 += icq_UDPTable[r2];
158 num2 ^= 0xFF00FF;
159
160 icq_PacketGoto(p, 0x14);
161 icq_PacketAppend32(p, num1 ^ num2);
162 }
163
164 DWORD icq_UDPScramble(DWORD cc)
165 {
166 DWORD a[5];
167
168 a[0] = cc & 0x0000001F;
169 a[1] = cc & 0x03E003E0;
170 a[2] = cc & 0xF8000400;
171 a[3] = cc & 0x0000F800;
172 a[4] = cc & 0x041F0000;
173
174 a[0] <<= 0x0C;
175 a[1] <<= 0x01;
176 a[2] >>= 0x0A;
177 a[3] <<= 0x10;
178 a[4] >>= 0x0F;
179
180 return a[0] + a[1] + a[2] + a[3] + a[4];
181 }
182
183 void icq_UDPEncode(icq_Packet *p)
184 {
185 DWORD checkcode;
186 DWORD code1, code2, code3;
187 DWORD pos;
188 DWORD data;
189
190 icq_UDPCheckCode(p);
191 icq_PacketGoto(p, 20);
192 checkcode = icq_PacketRead32(p);
193 code1 = p->length * 0x68656c6cL;
194 code2 = code1 + checkcode;
195 pos = 0x0A;
196
197 for(; pos < p->length; pos+=4)
198 {
199 code3 = code2 + icq_UDPTable[pos & 0xFF];
200 data = icqtohl(*(DWORD *)((p->data)+pos));
201 data ^= code3;
202 *(DWORD*)((p->data)+pos)=htoicql(data);
203 }
204 checkcode = icq_UDPScramble(checkcode);
205 *(DWORD *)((p->data)+0x14)=htoicql(checkcode);
206 }
207
208 /*********************************************************
209 icq_UDPSockWrite and icq_UDPSockRead are for _UDP_ packets
210 proxy support for TCP sockets is different!
211 *********************************************************/
212 int icq_UDPSockWriteDirect(ICQLINK *link, icq_Packet *p)
213 {
214 char tmpbuf[ICQ_PACKET_DATA_SIZE];
215
216 if(link->icq_UDPSok <= 3)
217 {
218 icq_FmtLog(link, ICQ_LOG_ERROR, "Bad socket!\n");
219 return -1;
220 }
221
222 icq_UDPEncode(p);
223 if(!link->icq_UseProxy)
224 {
225 #ifdef _WIN32
226 return send(link->icq_UDPSok, p->data, p->length, 0);
227 #else
228 return write(link->icq_UDPSok, p->data, p->length);
229 #endif
230 }
231 else
232 {
233 tmpbuf[0] = 0; /* reserved */
234 tmpbuf[1] = 0; /* reserved */
235 tmpbuf[2] = 0; /* standalone packet */
236 tmpbuf[3] = 1; /* address type IP v4 */
237 *(unsigned long*)&tmpbuf[4] = htonl(link->icq_ProxyDestIP);
238 *(unsigned short*)&tmpbuf[8] = htons(link->icq_ProxyDestPort);
239 memcpy(&tmpbuf[10], p->data, p->length);
240 #ifdef _WIN32
241 return send(link->icq_UDPSok, tmpbuf, p->length+10, 0)-10;
242 #else
243 return write(link->icq_UDPSok, tmpbuf, p->length+10)-10;
244 #endif
245 }
246 }
247
248 int icq_UDPSockWrite(ICQLINK *link, icq_Packet *p)
249 {
250 icq_Packet *qp;
251 WORD cmd = icq_PacketReadUDPOutCmd(p);
252 if(cmd != UDP_CMD_ACK && cmd != UDP_CMD_SEND_TEXT_CODE)
253 {
254 qp = (icq_Packet*)malloc(sizeof(icq_Packet));
255 memcpy(qp, p, sizeof(icq_Packet));
256 icq_UDPQueuePut(link, qp, 1);
257 if(link->icq_SetTimeout)
258 link->icq_SetTimeout(link, icq_UDPQueueInterval(link));
259 }
260 return icq_UDPSockWriteDirect(link, p);
261 }
262
263 int icq_UDPSockRead(ICQLINK *link, icq_Packet *p)
264 {
265 int res;
266 char tmpbuf[ICQ_PACKET_DATA_SIZE];
267
268 if(!link->icq_UseProxy)
269 {
270 #ifdef _WIN32
271 res = recv(link->icq_UDPSok, p->data, ICQ_PACKET_DATA_SIZE, 0);
272 #else
273 res = read(link->icq_UDPSok, p->data, ICQ_PACKET_DATA_SIZE);
274 #endif
275 p->length = res;
276 return res;
277 }
278 else
279 {
280 #ifdef _WIN32
281 res = recv(link->icq_UDPSok, tmpbuf, ICQ_PACKET_DATA_SIZE, 0);
282 #else
283 res = read(link->icq_UDPSok, tmpbuf, ICQ_PACKET_DATA_SIZE);
284 #endif
285 if(res<0)
286 return res;
287 memcpy(p->data, &tmpbuf[10], res-10);
288 p->length = res-10;
289 return res-10;
290 }
291 }
292
293 void icq_HandleTimeout(ICQLINK *link)
294 {
295 icq_UDPQueueItem *ptr = 0;
296 icq_Packet *sp = 0, *pack = 0;
297 int attempt;
298 while(icq_UDPQueueInterval(link) == 0)
299 {
300 ptr = (icq_UDPQueueItem*)list_first(link->icq_UDPQueue);
301 attempt = ptr->attempts + 1;
302 if(attempt > 6)
303 {
304 icq_Disconnect(link);
305 if(link->icq_Disconnected)
306 link->icq_Disconnected(link);
307 return;
308 }
309 pack = icq_UDPQueueGet(link);
310 sp = (icq_Packet*)malloc(sizeof(icq_Packet));
311 memcpy(sp, pack, sizeof(icq_Packet));
312 icq_UDPQueuePut(link, pack, attempt);
313 if(link->icq_SetTimeout)
314 link->icq_SetTimeout(link, icq_UDPQueueInterval(link));
315 icq_UDPSockWriteDirect(link, sp);
316 icq_PacketDelete(sp);
317 }
318 }
319
320 /****************************************
321 This must be called every 2 min.
322 so the server knows we're still alive.
323 JAVA client sends two different commands
324 so we do also :)
325 *****************************************/
326 WORD icq_KeepAlive(ICQLINK *link) /* V5 */
327 {
328 icq_Packet *p = icq_UDPCreateStdSeqPacket(link, UDP_CMD_KEEP_ALIVE, link->icq_UDPSeqNum1++);
329 icq_PacketAppend32(p, rand());
330 icq_UDPSockWrite(link, p);
331 icq_PacketDelete(p);
332
333 /* icq_Packet *p = icq_UDPCreateStdPacket(UDP_CMD_KEEP_ALIVE);
334 icq_UDPSockWrite(icq_UDPSok, p);
335 icq_PacketDelete(p);*/
336 /* p = icq_UDPCreateStdPacket(UDP_CMD_KEEP_ALIVE2);
337 icq_UDPSockWrite(icq_Sok, p);
338 icq_PacketDelete(p);*/
339
340 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Send Keep Alive packet to the server\n");
341
342 return link->icq_UDPSeqNum1-1;
343 }
344
345 /**********************************
346 This must be called to remove
347 messages from the server
348 ***********************************/
349 void icq_SendGotMessages(ICQLINK *link) /* V5 */
350 {
351 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_ACK_MESSAGES);
352 icq_PacketAppend32(p, rand());
353 icq_UDPSockWrite(link, p);
354 icq_PacketDelete(p);
355 }
356
357 /*************************************
358 this sends over the contact list
359 *************************************/
360 void icq_SendContactList(ICQLINK *link) /* V5 */
361 {
362 char num_used;
363 icq_ContactItem *ptr = icq_ContactGetFirst(link);
364
365 while(ptr)
366 {
367 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_CONT_LIST);
368
369 num_used = 0;
370 icq_PacketAdvance(p,1);
371 while(ptr && num_used<64)
372 {
373 icq_PacketAppend32(p, ptr->uin);
374 num_used++;
375 ptr = icq_ContactGetNext(ptr);
376 }
377 icq_PacketGotoUDPOutData(p, 0);
378 icq_PacketAppend8(p, num_used);
379 icq_UDPSockWrite(link, p);
380 icq_PacketDelete(p);
381 }
382 }
383
384 void icq_SendNewUser(ICQLINK *link, unsigned long uin) /* V5 */
385 {
386 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_ADD_TO_LIST);
387 icq_PacketAppend32(p, uin);
388 icq_UDPSockWrite(link, p);
389 icq_PacketDelete(p);
390 }
391
392 /*************************************
393 this sends over the visible list
394 that allows certain users to see you
395 if you're invisible.
396 *************************************/
397 void icq_SendVisibleList(ICQLINK *link) /* V5 */
398 {
399 char num_used;
400 icq_ContactItem *ptr = icq_ContactGetFirst(link);
401 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_VIS_LIST);
402
403 num_used = 0;
404 icq_PacketAdvance(p,1);
405 while(ptr)
406 {
407 if(ptr->vis_list)
408 {
409 icq_PacketAppend32(p, ptr->uin);
410 num_used++;
411 }
412 ptr = icq_ContactGetNext(ptr);
413 }
414 if(num_used != 0)
415 {
416 icq_PacketGotoUDPOutData(p, 0);
417 icq_PacketAppend8(p, num_used);
418 icq_UDPSockWrite(link, p);
419 }
420 icq_PacketDelete(p);
421 }
422
423 void icq_SendInvisibleList(ICQLINK *link) /* V5 */
424 {
425 char num_used;
426 icq_ContactItem *ptr = icq_ContactGetFirst(link);
427 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_INVIS_LIST);
428
429 num_used = 0;
430 icq_PacketAdvance(p,1);
431 while(ptr)
432 {
433 if(ptr->vis_list)
434 {
435 icq_PacketAppend32(p, ptr->uin);
436 num_used++;
437 }
438 ptr = icq_ContactGetNext(ptr);
439 }
440 if(num_used != 0)
441 {
442 icq_PacketGotoUDPOutData(p, 0);
443 icq_PacketAppend8(p, num_used);
444 icq_UDPSockWrite(link, p);
445 }
446 icq_PacketDelete(p);
447 }
448
449 /**************************************
450 This sends the second login command
451 this is necessary to finish logging in.
452 ***************************************/
453 void icq_SendLogin1(ICQLINK *link) /* V5 */
454 {
455 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_LOGIN_1);
456 icq_PacketAppend32(p, rand());
457 icq_UDPSockWrite(link, p);
458 icq_PacketDelete(p);
459 }
460
461 /************************************
462 This procedure logins into the server with icq_Uin and pass
463 on the socket icq_Sok and gives our ip and port.
464 It does NOT wait for any kind of a response.
465 *************************************/
466 void icq_Login(ICQLINK *link, DWORD status) /* V5 */
467 {
468 icq_Packet *p;
469
470 memset(link->icq_UDPServMess, FALSE, sizeof(link->icq_UDPServMess));
471 link->icq_UDPSession = rand() & 0x3FFFFFFF;
472 link->icq_UDPSeqNum1 = rand() & 0x7FFF;
473 link->icq_UDPSeqNum2 = 1;
474
475 p = icq_UDPCreateStdPacket(link, UDP_CMD_LOGIN);
476 icq_PacketAppend32(p, time(0L));
477 icq_PacketAppend32n(p, link->icq_TCPSrvPort);
478 /*icq_PacketAppend16(p, 0);
479 icq_PacketAppend16n(p, htons(link->icq_OurPort));*/
480 icq_PacketAppendString(p, link->icq_Password);
481 icq_PacketAppend32(p, LOGIN_X1_DEF);
482 icq_PacketAppend32n(p, htonl(link->icq_OurIP));
483 if(link->icq_UseProxy)
484 icq_PacketAppend8(p, LOGIN_SNDONLY_TCP);
485 else
486 icq_PacketAppend8(p, LOGIN_SNDRCV_TCP);
487 icq_PacketAppend32(p, status);
488 icq_PacketAppend32(p, LOGIN_X3_DEF);
489 icq_PacketAppend32(p, LOGIN_X4_DEF);
490 icq_PacketAppend32(p, LOGIN_X5_DEF);
491
492 icq_UDPSockWrite(link, p);
493 icq_PacketDelete(p);
494 }
495
496 /**********************
497 Logs off ICQ
498 ***********************/
499 void icq_Logout(ICQLINK *link) /* V5 */
500 {
501 icq_Packet *p = icq_UDPCreateStdSeqPacket(link, UDP_CMD_SEND_TEXT_CODE, link->icq_UDPSeqNum1++);
502 icq_PacketAppendString(p, "B_USER_DISCONNECTED");
503 icq_PacketAppend8(p, 5);
504 icq_PacketAppend8(p, 0);
505 icq_UDPSockWrite(link, p);
506 icq_PacketDelete(p);
507 }
508
509 /*******************************
510 This routine sends the aknowlegement cmd to the
511 server it appears that this must be done after
512 everything the server sends us
513 *******************************/
514 void icq_UDPAck(ICQLINK *link, int seq) /* V5 */
515 {
516 icq_Packet *p = icq_UDPCreateStdSeqPacket(link, UDP_CMD_ACK, seq);
517 icq_PacketAppend32(p, rand());
518
519 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Acking\n");
520 icq_UDPSockWrite(link, p);
521 icq_PacketDelete(p);
522 }
523
524 /***************************************************
525 Sends a message thru the server to uin. Text is the
526 message to send.
527 ***************************************************/
528 WORD icq_UDPSendMessage(ICQLINK *link, DWORD uin, const char *text) /* V5 */
529 {
530 char buf[512]; /* message may be only 450 bytes long */
531 icq_Packet *p;
532
533 strncpy(buf, text, 512);
534 icq_RusConv("kw", buf);
535
536 p = icq_UDPCreateStdPacket(link, UDP_CMD_SEND_THRU_SRV);
537 icq_PacketAppend32(p, uin);
538 icq_PacketAppend16(p, TYPE_MSG);
539 icq_PacketAppendString(p, buf);
540
541 icq_UDPSockWrite(link, p);
542 icq_PacketDelete(p);
543 return link->icq_UDPSeqNum1-1;
544 }
545
546 WORD icq_UDPSendURL(ICQLINK *link, DWORD uin, const char *url, const char *descr) /* V5 */
547 {
548 char buf1[512], buf2[512];
549 icq_Packet *p;
550
551 strncpy(buf1, descr, 512);
552 icq_RusConv("kw", buf1);
553 strncpy(buf2, url, 512);
554
555 p = icq_UDPCreateStdPacket(link, UDP_CMD_SEND_THRU_SRV);
556 icq_PacketAppend32(p, uin);
557 icq_PacketAppend16(p, TYPE_URL);
558 icq_PacketAppend16(p, strlen(buf1)+strlen(buf2)+2); /* length + the NULL + 0xFE delimiter */
559 icq_PacketAppendStringFE(p, buf1);
560 icq_PacketAppendString0(p, buf2);
561
562 icq_UDPSockWrite(link, p);
563 icq_PacketDelete(p);
564 return link->icq_UDPSeqNum1-1;
565 }
566
567 /**************************************************
568 Sends a authorization to the server so the Mirabilis
569 client can add the user.
570 ***************************************************/
571 WORD icq_SendAuthMsg(ICQLINK *link, DWORD uin) /* V5 */
572 {
573 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_SEND_THRU_SRV);
574 icq_PacketAppend32(p, uin);
575 icq_PacketAppend32(p, TYPE_AUTH);
576 icq_PacketAppend16(p, 0);
577 icq_UDPSockWrite(link, p);
578 icq_PacketDelete(p);
579
580 return link->icq_UDPSeqNum1-1;
581 }
582
583 /**************************************************
584 Changes the users status on the server
585 ***************************************************/
586 void icq_ChangeStatus(ICQLINK *link, DWORD status) /* V5 */
587 {
588 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_STATUS_CHANGE);
589 icq_PacketAppend32(p, status);
590 link->icq_Status = status;
591 icq_UDPSockWrite(link, p);
592 icq_PacketDelete(p);
593 }
594
595 /********************************************************
596 Sends a request to the server for info on a specific user
597 *********************************************************/
598 WORD icq_SendInfoReq(ICQLINK *link, DWORD uin) /* V5 */
599 {
600 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_INFO_REQ);
601 icq_PacketAppend32(p, uin);
602 icq_UDPSockWrite(link, p);
603 icq_PacketDelete(p);
604 return link->icq_UDPSeqNum1-1;
605 }
606
607 /********************************************************
608 Sends a request to the server for info on a specific user
609 *********************************************************/
610 WORD icq_SendExtInfoReq(ICQLINK *link, DWORD uin) /* V5 */
611 {
612 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_EXT_INFO_REQ);
613 icq_PacketAppend32(p, uin);
614 icq_UDPSockWrite(link, p);
615 icq_PacketDelete(p);
616 return link->icq_UDPSeqNum1-1;
617 }
618
619 /**************************************************************
620 Initializes a server search for the information specified
621 ***************************************************************/
622 void icq_SendSearchReq(ICQLINK *link, const char *email, const char *nick, const char *first,
623 const char *last) /* V5 */
624 {
625 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_SEARCH_USER);
626 icq_PacketAppendString(p, nick);
627 icq_PacketAppendString(p, first);
628 icq_PacketAppendString(p, last);
629 icq_PacketAppendString(p, email);
630 icq_UDPSockWrite(link, p);
631 icq_PacketDelete(p);
632 }
633
634 /**************************************************************
635 Initializes a server search for the information specified
636 ***************************************************************/
637 void icq_SendSearchUINReq(ICQLINK *link, DWORD uin) /* V5 */
638 {
639 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_SEARCH_UIN);
640 icq_PacketAppend32(p, uin);
641 icq_UDPSockWrite(link, p);
642 icq_PacketDelete(p);
643 }
644
645 /**************************************************
646 Registers a new uin in the ICQ network
647 ***************************************************/
648 void icq_RegNewUser(ICQLINK *link, const char *pass) /* V5 */
649 {
650 char pass8[9];
651 icq_Packet *p = icq_UDPCreateStdSeqPacket(link, UDP_CMD_REG_NEW_USER, link->icq_UDPSeqNum1++);
652 strncpy(pass8, pass, 8);
653 icq_PacketAppendString(p, pass8);
654 icq_PacketAppend32(p, 0xA0);
655 icq_PacketAppend32(p, 0x2461);
656 icq_PacketAppend32(p, 0xA00000);
657 icq_PacketAppend32(p, 0x00);
658 icq_PacketGoto(p, 6);
659 icq_PacketAppend32(p, 0);
660 icq_PacketAppend32(p, rand());
661 icq_UDPSockWrite(link, p);
662 icq_FmtLog(link, ICQ_LOG_MESSAGE, "Send RegNewUser packet to the server\n");
663 icq_PacketDelete(p);
664 }
665
666 WORD icq_UpdateUserInfo(ICQLINK *link, const char *nick, const char *first, const char *last,
667 const char *email) /* V5 */
668 {
669 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_UPDATE_INFO);
670 icq_PacketAppendString(p, nick);
671 icq_PacketAppendString(p, first);
672 icq_PacketAppendString(p, last);
673 icq_PacketAppendString(p, email);
674 /* auth (byte)? */
675 icq_UDPSockWrite(link, p);
676 icq_PacketDelete(p);
677 return link->icq_UDPSeqNum1-1;
678 }
679
680 WORD icq_UpdateAuthInfo(ICQLINK *link, DWORD auth) /* V5 */
681 {
682 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_UPDATE_AUTH);
683 icq_PacketAppend32(p, auth); /* NOT auth? */
684 icq_UDPSockWrite(link, p);
685 icq_PacketDelete(p);
686 return link->icq_UDPSeqNum1-1;
687 }
688
689 WORD icq_UpdateMetaInfoSet(ICQLINK *link, const char *nick, const char *first, const char *last,
690 const char *email, const char *email2, const char *email3,
691 const char *city, const char *state, const char *phone, const char *fax,
692 const char *street, const char *cellular, unsigned long zip,
693 unsigned short cnt_code, unsigned char cnt_stat, unsigned char emailhide)
694 {
695 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_META_USER);
696 icq_PacketAppend16(p, META_CMD_SET_INFO);
697 icq_PacketAppendString(p, nick);
698 icq_PacketAppendString(p, first);
699 icq_PacketAppendString(p, last);
700 icq_PacketAppendString(p, email);
701 icq_PacketAppendString(p, email2);
702 icq_PacketAppendString(p, email3);
703 icq_PacketAppendString(p, city);
704 icq_PacketAppendString(p, state);
705 icq_PacketAppendString(p, phone);
706 icq_PacketAppendString(p, fax);
707 icq_PacketAppendString(p, street);
708 icq_PacketAppendString(p, cellular);
709 icq_PacketAppend32(p, zip);
710 icq_PacketAppend16(p, cnt_code);
711 icq_PacketAppend8(p, cnt_stat);
712 icq_PacketAppend8(p, emailhide);
713 icq_UDPSockWrite(link, p);
714 icq_PacketDelete(p);
715 return link->icq_UDPSeqNum2-1;
716 }
717
718 WORD icq_UpdateMetaInfoHomepage(ICQLINK *link, unsigned char age, const char *homepage,
719 unsigned char year, unsigned char month, unsigned char day,
720 unsigned char lang1, unsigned char lang2, unsigned char lang3)
721 {
722 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_META_USER);
723 icq_PacketAppend16(p, META_CMD_SET_HOMEPAGE);
724 icq_PacketAppend8(p, age);
725 icq_PacketAppend16(p, 0x0200);
726 icq_PacketAppendString(p, homepage);
727 icq_PacketAppend8(p, year);
728 icq_PacketAppend8(p, month);
729 icq_PacketAppend8(p, day);
730 icq_PacketAppend8(p, 0xFF /* lang1 */);
731 icq_PacketAppend8(p, 0xFF /* lang2 */);
732 icq_PacketAppend8(p, 0xFF /* lang3 */);
733 icq_UDPSockWrite(link, p);
734 icq_PacketDelete(p);
735 return link->icq_UDPSeqNum2-1;
736 }
737
738 WORD icq_UpdateMetaInfoAbout(ICQLINK *link, const char *about)
739 {
740 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_META_USER);
741 icq_PacketAppend16(p, META_CMD_SET_ABOUT);
742 icq_PacketAppendString(p, about);
743 icq_UDPSockWrite(link, p);
744 icq_PacketDelete(p);
745 return link->icq_UDPSeqNum2-1;
746 }
747
748 WORD icq_UpdateMetaInfoSecurity(ICQLINK *link, unsigned char reqauth, unsigned char webpresence,
749 unsigned char pubip)
750 {
751 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_META_USER);
752 icq_PacketAppend16(p, META_CMD_SET_SECURE);
753 icq_PacketAppend8(p, !reqauth);
754 icq_PacketAppend8(p, webpresence);
755 icq_PacketAppend8(p, pubip);
756 icq_UDPSockWrite(link, p);
757 icq_PacketDelete(p);
758 return link->icq_UDPSeqNum2-1;
759 }
760
761 WORD icq_UpdateNewUserInfo(ICQLINK *link, const char *nick, const char *first, const char *last,
762 const char *email) /* V5 */
763 {
764 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_NEW_USER_INFO);
765 icq_PacketAppendString(p, nick);
766 icq_PacketAppendString(p, first);
767 icq_PacketAppendString(p, last);
768 icq_PacketAppendString(p, email);
769 icq_PacketAppend8(p, 1);
770 icq_PacketAppend8(p, 1);
771 icq_PacketAppend8(p, 1);
772 icq_UDPSockWrite(link, p);
773 icq_PacketDelete(p);
774 return link->icq_UDPSeqNum1-1;
775 }
776
777 WORD icq_SendMetaInfoReq(ICQLINK *link, unsigned long uin)
778 {
779 icq_Packet *p = icq_UDPCreateStdPacket(link, UDP_CMD_META_USER);
780 icq_PacketAppend16(p, META_CMD_REQ_INFO);
781 icq_PacketAppend32(p, uin);
782 icq_UDPSockWrite(link, p);
783 icq_PacketDelete(p);
784 return link->icq_UDPSeqNum2-1;
785 }