Mercurial > pidgin.yaz
annotate plugins/icq/tcp.c @ 1474:4e891576c226
[gaim-migrate @ 1484]
bah
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Tue, 06 Feb 2001 13:49:32 +0000 |
parents | 4c510ca3563f |
children | 0ef6603d986e |
rev | line source |
---|---|
1152 | 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 /* | |
1432
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
3 $Id: tcp.c 1442 2001-01-28 01:52:27Z warmenhoven $ |
1152 | 4 $Log$ |
1432
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
5 Revision 1.3 2001/01/28 01:52:27 warmenhoven |
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
6 icqlib 1.1.5 |
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
7 |
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
8 Revision 1.38 2001/01/17 01:29:17 bills |
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
9 Rework chat and file session interfaces; implement socket notifications. |
1309
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
10 |
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
11 Revision 1.37 2000/12/19 06:00:07 bills |
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
12 moved members from ICQLINK to ICQLINK_private struct |
1152 | 13 |
14 Revision 1.36 2000/07/09 22:19:35 bills | |
15 added new *Close functions, use *Close functions instead of *Delete | |
16 where correct, and misc cleanup | |
17 | |
18 Revision 1.35 2000/06/15 01:52:16 bills | |
19 added Cancel and Refuse functions for chat and file reqs, changed packet | |
20 sending code to use new icq_TCPLinkSendSeq function to elimitane duplicate | |
21 code, removed *Seq functions, renamed chat req functions | |
22 | |
23 Revision 1.34 2000/05/04 15:57:20 bills | |
24 Reworked file transfer notification, small bugfixes, and cleanups. | |
25 | |
26 Revision 1.33 2000/04/10 18:11:45 denis | |
27 ANSI cleanups. | |
28 | |
29 Revision 1.32 2000/04/10 16:36:04 denis | |
30 Some more Win32 compatibility from Guillaume Rosanis <grs@mail.com> | |
31 | |
32 Revision 1.31 2000/04/06 16:38:04 denis | |
33 icq_*Send*Seq() functions with specified sequence number were added. | |
34 | |
35 Revision 1.30 2000/04/05 14:37:02 denis | |
36 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32 | |
37 compatibility. | |
38 | |
39 Revision 1.29 2000/02/15 04:02:41 bills | |
40 warning cleanup | |
41 | |
42 Revision 1.28 2000/02/15 03:58:20 bills | |
43 use new icq_ChatRusConv_n function in icq_TCPSendChatData, | |
44 new icq_TCPSendChatData_n function | |
45 | |
46 Revision 1.27 2000/02/07 02:40:23 bills | |
47 new code for SOCKS connections, more cyrillic translations | |
48 | |
49 Revision 1.26 2000/01/20 19:59:15 bills | |
50 first implementation of sending file requests | |
51 | |
52 Revision 1.25 2000/01/16 21:28:24 bills | |
53 renamed icq_TCPAcceptFileReq to icq_AcceptFileRequest, moved file request | |
54 functions to new file session code | |
55 | |
56 Revision 1.24 2000/01/16 03:59:10 bills | |
57 reworked list code so list_nodes don't need to be inside item structures, | |
58 removed strlist code and replaced with generic list calls | |
59 | |
60 Revision 1.23 1999/12/27 16:10:04 bills | |
61 fixed buy in icq_TCPAcceptFileReq, added icq_TCPFileSetSpeed | |
62 | |
63 Revision 1.22 1999/12/21 00:29:59 bills | |
64 moved _process_packet logic into tcplink::icq_TCPLinkProcessReceived, | |
65 removed unnecessary icq_TCPSendFile??Packet functions | |
66 | |
67 Revision 1.21 1999/12/14 03:31:48 bills | |
68 fixed double delete bug in _handle_ready_sockets, added code to implement | |
69 connect timeout | |
70 | |
71 Revision 1.20 1999/11/30 09:44:31 bills | |
72 added file session logic | |
73 | |
74 Revision 1.19 1999/09/29 20:07:12 bills | |
75 cleanups, moved connect logic from _handle_ready_sockets to | |
76 icq_TCPLinkOnConnect, tcp_link->icq_TCPLink | |
77 | |
78 Revision 1.18 1999/09/29 17:08:48 denis | |
79 Cleanups. | |
80 | |
81 Revision 1.17 1999/07/18 20:19:56 bills | |
82 added better log messages | |
83 | |
84 Revision 1.16 1999/07/16 15:45:56 denis | |
85 Cleaned up. | |
86 | |
87 Revision 1.15 1999/07/16 12:14:13 denis | |
88 tcp_packet* functions renamed to icq_Packet* | |
89 Cleaned up. | |
90 | |
91 Revision 1.14 1999/07/12 15:13:34 cproch | |
92 - added definition of ICQLINK to hold session-specific global variabled | |
93 applications which have more than one connection are now possible | |
94 - changed nearly every function defintion to support ICQLINK parameter | |
95 | |
96 Revision 1.13 1999/07/03 06:33:49 lord | |
97 . byte order conversion macros added | |
98 . some compilation warnings removed | |
99 | |
100 Revision 1.12 1999/06/30 13:52:22 bills | |
101 implemented non-blocking connects | |
102 | |
103 Revision 1.11 1999/05/03 21:41:26 bills | |
104 initial file xfer support added- untested | |
105 | |
106 Revision 1.10 1999/04/29 09:35:41 denis | |
107 Cleanups, warning removed | |
108 | |
109 Revision 1.9 1999/04/17 19:30:50 bills | |
110 _major_ restructuring. all tcp sockets (including listening sockets) are | |
111 kept in global linked list, icq_TCPLinks. accept and listen functions | |
112 moved to tcplink.c. changed return values of Send* functions to DWORD. | |
113 | |
114 Revision 1.8 1999/04/14 14:57:05 denis | |
115 Cleanups for "strict" compiling (-ansi -pedantic) | |
116 Parameter port added to function icq_TCPCreateListeningSocket() | |
117 | |
118 */ | |
119 | |
120 /* | |
121 Peer-to-peer ICQ protocol implementation | |
122 | |
123 Uses version 2 of the ICQ protocol | |
124 | |
125 Thanks to Douglas F. McLaughlin and many others for | |
126 packet details (see tcp02.txt) | |
127 | |
128 */ | |
129 | |
130 #include <stdlib.h> | |
131 | |
132 #include <fcntl.h> | |
133 #include <stdarg.h> | |
134 #include <errno.h> | |
135 | |
136 #include <sys/types.h> | |
137 | |
138 #ifdef _WIN32 | |
139 #include <winsock.h> | |
140 #else | |
141 #include <sys/socket.h> | |
1432
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
142 #include <sys/time.h> |
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
143 #include <unistd.h> |
1152 | 144 #endif |
145 | |
146 #include <sys/stat.h> | |
147 | |
148 #include "icqtypes.h" | |
149 #include "icqlib.h" | |
150 | |
151 #include "tcp.h" | |
152 #include "stdpackets.h" | |
153 #include "list.h" | |
154 #include "tcplink.h" | |
155 #include "chatsession.h" | |
156 #include "filesession.h" | |
157 | |
158 /** | |
159 Initializes structures necessary for TCP use. Not required by user | |
160 programs. | |
161 | |
162 \return true on error | |
163 */ | |
164 | |
165 int icq_TCPInit(ICQLINK *link) | |
166 { | |
167 icq_TCPLink *plink; | |
168 | |
169 /* allocate lists */ | |
1309
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
170 link->d->icq_TCPLinks=list_new(); |
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
171 link->d->icq_ChatSessions=list_new(); |
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
172 link->d->icq_FileSessions=list_new(); |
1152 | 173 |
174 /* only the main listening socket gets created upon initialization - | |
175 * the other two are created when necessary */ | |
176 plink=icq_TCPLinkNew( link ); | |
177 icq_TCPLinkListen(plink); | |
178 link->icq_TCPSrvPort=ntohs(plink->socket_address.sin_port); | |
179 | |
180 /* reset tcp sequence number */ | |
1309
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
181 link->d->icq_TCPSequence=0xfffffffe; |
1152 | 182 |
183 return 0; | |
184 } | |
185 | |
186 void icq_TCPDone(ICQLINK *link) | |
187 { | |
188 /* close and deallocate all tcp links, this will also close any attached | |
189 * file or chat sessions */ | |
1309
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
190 list_delete(link->d->icq_TCPLinks, icq_TCPLinkDelete); |
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
191 list_delete(link->d->icq_ChatSessions, icq_ChatSessionDelete); |
0a766047b4fd
[gaim-migrate @ 1319]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1152
diff
changeset
|
192 list_delete(link->d->icq_FileSessions, icq_FileSessionDelete); |
1152 | 193 } |
194 | |
1432
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
195 /* need to do this somehow... |
1152 | 196 |
197 if((time(0L) - plink->connect_time) > TCP_LINK_CONNECT_TIMEOUT) | |
198 { | |
199 icq_TCPLinkClose(plink); | |
200 return 0; | |
201 } | |
202 } | |
1432
4c510ca3563f
[gaim-migrate @ 1442]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1309
diff
changeset
|
203 */ |
1152 | 204 |
205 icq_TCPLink *icq_TCPCheckLink(ICQLINK *link, DWORD uin, int type) | |
206 { | |
207 icq_TCPLink *plink=icq_FindTCPLink(link, uin, type); | |
208 | |
209 if(!plink) | |
210 { | |
211 plink=icq_TCPLinkNew( link ); | |
212 if(type==TCP_LINK_MESSAGE) | |
213 icq_TCPLinkConnect(plink, uin, 0); | |
214 } | |
215 | |
216 return plink; | |
217 | |
218 } | |
219 | |
220 DWORD icq_TCPSendMessage(ICQLINK *link, DWORD uin, const char *message) | |
221 { | |
222 icq_TCPLink *plink; | |
223 icq_Packet *p; | |
224 DWORD sequence; | |
225 char data[512] ; | |
226 | |
227 strncpy(data,message,512) ; | |
228 icq_RusConv("kw", data) ; | |
229 | |
230 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
231 | |
232 /* create and send the message packet */ | |
233 p=icq_TCPCreateMessagePacket(plink, (unsigned char *)data); | |
234 sequence=icq_TCPLinkSendSeq(plink, p, 0); | |
235 | |
236 #ifdef TCP_PACKET_TRACE | |
237 printf("message packet sent to uin %lu { sequence=%lx }\n", uin, p->id); | |
238 #endif | |
239 | |
240 return sequence; | |
241 } | |
242 | |
243 DWORD icq_TCPSendURL(ICQLINK *link, DWORD uin, const char *message, const char *url) | |
244 { | |
245 icq_TCPLink *plink; | |
246 icq_Packet *p; | |
247 DWORD sequence; | |
248 char data[512]; | |
249 | |
250 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
251 | |
252 strncpy(data, message, 512); | |
253 data[511] = '\0'; | |
254 icq_RusConv("kw", data); | |
255 | |
256 /* create and send the url packet */ | |
257 p=icq_TCPCreateURLPacket(plink, data, url); | |
258 sequence=icq_TCPLinkSendSeq(plink, p, 0); | |
259 | |
260 #ifdef TCP_PACKET_TRACE | |
261 printf("url packet queued for uin %lu { sequence=%lx }\n", uin, p->id); | |
262 #endif | |
263 | |
264 return sequence; | |
265 } | |
266 | |
267 DWORD icq_SendChatRequest(ICQLINK *link, DWORD uin, const char *message) | |
268 { | |
269 icq_TCPLink *plink; | |
270 icq_Packet *p; | |
271 DWORD sequence; | |
272 char data[512]; | |
273 | |
274 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
275 | |
276 strncpy(data, message, 512); | |
277 data[511] = '\0'; | |
278 icq_RusConv("kw", data); | |
279 | |
280 /* create and send the url packet */ | |
281 p=icq_TCPCreateChatReqPacket(plink, (unsigned char *)data); | |
282 sequence=icq_TCPLinkSendSeq(plink, p, 0); | |
283 | |
284 #ifdef TCP_PACKET_TRACE | |
285 printf("chat req packet sent to uin %lu { sequence=%lx }\n", uin, p->id); | |
286 #endif | |
287 | |
288 return sequence; | |
289 } | |
290 | |
291 unsigned long icq_SendFileRequest(ICQLINK *link, unsigned long uin, | |
292 const char *message, char **files) | |
293 { | |
294 icq_TCPLink *plink; | |
295 icq_FileSession *pfile; | |
296 icq_Packet *p; | |
297 unsigned long sequence; | |
298 char filename[64]; | |
299 char data[512]; | |
300 | |
301 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
302 | |
303 /* create the file session, this will be linked to the incoming icq_TCPLink | |
304 * in icq_HandleFileAck */ | |
305 pfile=icq_FileSessionNew(link); | |
306 pfile->remote_uin=uin; | |
307 pfile->files=files; | |
308 pfile->direction=FILE_STATUS_SENDING; | |
309 | |
310 /* count the number and size of the files */ | |
311 pfile->total_files=0; | |
312 while(*files) { | |
313 struct stat file_status; | |
314 | |
315 if(stat(*files, &file_status)==0) { | |
316 pfile->total_files++; | |
317 pfile->total_bytes+=file_status.st_size; | |
318 } | |
319 files++; | |
320 } | |
321 | |
322 strncpy(filename, *(pfile->files), 64); | |
323 | |
324 strncpy(data, message, 512); | |
325 data[511] = '\0'; | |
326 icq_RusConv("kw", data); | |
327 | |
328 /* create and send the file req packet */ | |
329 p=icq_TCPCreateFileReqPacket(plink, (char *)data, filename, | |
330 pfile->total_bytes); | |
331 sequence=icq_TCPLinkSendSeq(plink, p, 0); | |
332 pfile->id=sequence; | |
333 | |
334 #ifdef TCP_PACKET_TRACE | |
335 printf("file req packet sent to uin %lu { sequence=%lx }\n", uin, p->id); | |
336 #endif | |
337 | |
338 return sequence; | |
339 } | |
340 | |
341 void icq_AcceptChatRequest(ICQLINK *link, DWORD uin, unsigned long sequence) | |
342 { | |
343 icq_TCPLink *pmessage, *plisten; | |
344 icq_ChatSession *pchat; | |
345 icq_Packet *p; | |
346 | |
347 pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
348 | |
349 /* create the chat listening socket if necessary */ | |
350 if(!(plisten=icq_FindTCPLink(link, 0, TCP_LINK_CHAT))) | |
351 { | |
352 plisten=icq_TCPLinkNew( link ); | |
353 plisten->type=TCP_LINK_CHAT; | |
354 icq_TCPLinkListen(plisten); | |
355 } | |
356 | |
357 /* create the chat session, this will be linked to the incoming icq_TCPLink | |
358 * in TCPProcessHello */ | |
359 pchat=icq_ChatSessionNew(link); | |
360 pchat->id=sequence; | |
361 pchat->remote_uin=uin; | |
362 | |
363 /* create and send the ack packet */ | |
364 p=icq_TCPCreateChatReqAck(pmessage, | |
365 ntohs(plisten->socket_address.sin_port)); | |
366 (void)icq_TCPLinkSendSeq(pmessage, p, sequence); | |
367 | |
368 #ifdef TCP_PACKET_TRACE | |
369 printf("chat req ack sent to uin %lu { sequence=%lx }\n", uin, sequence); | |
370 #endif | |
371 } | |
372 | |
373 void icq_TCPSendChatData(ICQLINK *link, DWORD uin, const char *data) | |
374 { | |
375 icq_TCPLink *plink=icq_FindTCPLink(link, uin, TCP_LINK_CHAT); | |
376 char data1[512]; | |
377 int data1_len; | |
378 | |
379 if(!plink) | |
380 return; | |
381 | |
382 strncpy(data1,data,512) ; | |
383 data1[511] = '\0'; | |
384 data1_len = strlen(data); | |
385 icq_ChatRusConv_n("kw", data1, data1_len); | |
386 | |
387 send(plink->socket, data1, data1_len, 0); | |
388 | |
389 } | |
390 | |
391 void icq_TCPSendChatData_n(ICQLINK *link, DWORD uin, const char *data, int len) | |
392 { | |
393 icq_TCPLink *plink=icq_FindTCPLink(link, uin, TCP_LINK_CHAT); | |
394 char *data1; | |
395 | |
396 if(!plink) | |
397 return; | |
398 | |
399 data1 = (char *)malloc(len); | |
400 memcpy(data1, data, len); | |
401 icq_ChatRusConv_n("kw", data1, len); | |
402 | |
403 send(plink->socket, data1, len, 0); | |
404 | |
405 } | |
406 | |
407 icq_FileSession *icq_AcceptFileRequest(ICQLINK *link, DWORD uin, | |
408 unsigned long sequence) | |
409 { | |
410 icq_TCPLink *pmessage, *plisten; | |
411 icq_FileSession *pfile; | |
412 icq_Packet *p; | |
413 | |
414 pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
415 | |
416 /* create the file listening socket if necessary */ | |
417 if(!(plisten=icq_FindTCPLink(link, 0, TCP_LINK_FILE))) | |
418 { | |
419 plisten=icq_TCPLinkNew( link ); | |
420 plisten->type=TCP_LINK_FILE; | |
421 icq_TCPLinkListen(plisten); | |
422 } | |
423 | |
424 /* create the file session, this will be linked to the incoming icq_TCPLink | |
425 * in TCPProcessHello */ | |
426 pfile=icq_FileSessionNew(link); | |
427 pfile->id=sequence; | |
428 pfile->remote_uin=uin; | |
429 pfile->direction=FILE_STATUS_RECEIVING; | |
430 icq_FileSessionSetStatus(pfile, FILE_STATUS_LISTENING); | |
431 | |
432 /* create and send the ack packet */ | |
433 p=icq_TCPCreateFileReqAck(pmessage, | |
434 ntohs(plisten->socket_address.sin_port)); | |
435 (void)icq_TCPLinkSendSeq(pmessage, p, sequence); | |
436 | |
437 #ifdef TCP_PACKET_TRACE | |
438 printf("file req ack sent to uin %lu { sequence=%lx }\n", uin, sequence); | |
439 #endif | |
440 | |
441 return pfile; | |
442 | |
443 } | |
444 | |
445 void icq_RefuseFileRequest(ICQLINK *link, DWORD uin, | |
446 unsigned long sequence, const char *reason) | |
447 { | |
448 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
449 icq_Packet *p; | |
450 | |
451 /* create and send the refuse packet */ | |
452 p=icq_TCPCreateFileReqRefuse(pmessage, | |
453 ntohs(pmessage->socket_address.sin_port), reason); | |
454 (void)icq_TCPLinkSendSeq(pmessage, p, sequence); | |
455 | |
456 #ifdef TCP_PACKET_TRACE | |
457 printf("file req refuse sent to uin %lu { sequence=%lx, reason=\"%s\" }\n", | |
458 uin, sequence, reason); | |
459 #endif | |
460 | |
461 } | |
462 | |
463 void icq_CancelFileRequest(ICQLINK *link, DWORD uin, unsigned long sequence) | |
464 { | |
465 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
466 icq_FileSession *psession=icq_FindFileSession(link, uin, sequence); | |
467 icq_Packet *p; | |
468 | |
469 if (psession) | |
470 icq_FileSessionClose(psession); | |
471 | |
472 /* create and send the cancel packet */ | |
473 p=icq_TCPCreateFileReqCancel(pmessage, | |
474 ntohs(pmessage->socket_address.sin_port)); | |
475 (void)icq_TCPLinkSendSeq(pmessage, p, sequence); | |
476 #ifdef TCP_PACKET_TRACE | |
477 printf("file req cancel sent to uin %lu { sequence=%lx }\n", uin, sequence); | |
478 #endif | |
479 | |
480 } | |
481 | |
482 void icq_RefuseChatRequest(ICQLINK *link, DWORD uin, | |
483 unsigned long sequence, const char *reason) | |
484 { | |
485 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
486 icq_Packet *p; | |
487 | |
488 /* create and send the refuse packet */ | |
489 p=icq_TCPCreateChatReqRefuse(pmessage, | |
490 ntohs(pmessage->socket_address.sin_port), reason); | |
491 (void)icq_TCPLinkSendSeq(pmessage, p, sequence); | |
492 | |
493 #ifdef TCP_PACKET_TRACE | |
494 printf("chat req refuse sent to uin %lu { sequence=%lx, reason=\"%s\" }\n", | |
495 uin, sequence, reason); | |
496 #endif | |
497 | |
498 } | |
499 | |
500 void icq_CancelChatRequest(ICQLINK *link, DWORD uin, unsigned long sequence) | |
501 { | |
502 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE); | |
503 icq_FileSession *psession=icq_FindFileSession(link, uin, sequence); | |
504 icq_Packet *p; | |
505 | |
506 if (psession) | |
507 icq_FileSessionClose(psession); | |
508 | |
509 /* create and send the cancel packet */ | |
510 p=icq_TCPCreateChatReqCancel(pmessage, | |
511 ntohs(pmessage->socket_address.sin_port)); | |
512 (void)icq_TCPLinkSendSeq(pmessage, p, sequence); | |
513 | |
514 #ifdef TCP_PACKET_TRACE | |
515 printf("chat req cancel sent to uin %lu { sequence=%lx }\n", uin, sequence); | |
516 #endif | |
517 | |
518 } |