Mercurial > pidgin.yaz
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 } |