1152
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2 /*
|
|
3 $Id: tcp.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.36 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.35 2000/06/15 01:52:16 bills
|
|
13 added Cancel and Refuse functions for chat and file reqs, changed packet
|
|
14 sending code to use new icq_TCPLinkSendSeq function to elimitane duplicate
|
|
15 code, removed *Seq functions, renamed chat req functions
|
|
16
|
|
17 Revision 1.34 2000/05/04 15:57:20 bills
|
|
18 Reworked file transfer notification, small bugfixes, and cleanups.
|
|
19
|
|
20 Revision 1.33 2000/04/10 18:11:45 denis
|
|
21 ANSI cleanups.
|
|
22
|
|
23 Revision 1.32 2000/04/10 16:36:04 denis
|
|
24 Some more Win32 compatibility from Guillaume Rosanis <grs@mail.com>
|
|
25
|
|
26 Revision 1.31 2000/04/06 16:38:04 denis
|
|
27 icq_*Send*Seq() functions with specified sequence number were added.
|
|
28
|
|
29 Revision 1.30 2000/04/05 14:37:02 denis
|
|
30 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
|
|
31 compatibility.
|
|
32
|
|
33 Revision 1.29 2000/02/15 04:02:41 bills
|
|
34 warning cleanup
|
|
35
|
|
36 Revision 1.28 2000/02/15 03:58:20 bills
|
|
37 use new icq_ChatRusConv_n function in icq_TCPSendChatData,
|
|
38 new icq_TCPSendChatData_n function
|
|
39
|
|
40 Revision 1.27 2000/02/07 02:40:23 bills
|
|
41 new code for SOCKS connections, more cyrillic translations
|
|
42
|
|
43 Revision 1.26 2000/01/20 19:59:15 bills
|
|
44 first implementation of sending file requests
|
|
45
|
|
46 Revision 1.25 2000/01/16 21:28:24 bills
|
|
47 renamed icq_TCPAcceptFileReq to icq_AcceptFileRequest, moved file request
|
|
48 functions to new file session code
|
|
49
|
|
50 Revision 1.24 2000/01/16 03:59:10 bills
|
|
51 reworked list code so list_nodes don't need to be inside item structures,
|
|
52 removed strlist code and replaced with generic list calls
|
|
53
|
|
54 Revision 1.23 1999/12/27 16:10:04 bills
|
|
55 fixed buy in icq_TCPAcceptFileReq, added icq_TCPFileSetSpeed
|
|
56
|
|
57 Revision 1.22 1999/12/21 00:29:59 bills
|
|
58 moved _process_packet logic into tcplink::icq_TCPLinkProcessReceived,
|
|
59 removed unnecessary icq_TCPSendFile??Packet functions
|
|
60
|
|
61 Revision 1.21 1999/12/14 03:31:48 bills
|
|
62 fixed double delete bug in _handle_ready_sockets, added code to implement
|
|
63 connect timeout
|
|
64
|
|
65 Revision 1.20 1999/11/30 09:44:31 bills
|
|
66 added file session logic
|
|
67
|
|
68 Revision 1.19 1999/09/29 20:07:12 bills
|
|
69 cleanups, moved connect logic from _handle_ready_sockets to
|
|
70 icq_TCPLinkOnConnect, tcp_link->icq_TCPLink
|
|
71
|
|
72 Revision 1.18 1999/09/29 17:08:48 denis
|
|
73 Cleanups.
|
|
74
|
|
75 Revision 1.17 1999/07/18 20:19:56 bills
|
|
76 added better log messages
|
|
77
|
|
78 Revision 1.16 1999/07/16 15:45:56 denis
|
|
79 Cleaned up.
|
|
80
|
|
81 Revision 1.15 1999/07/16 12:14:13 denis
|
|
82 tcp_packet* functions renamed to icq_Packet*
|
|
83 Cleaned up.
|
|
84
|
|
85 Revision 1.14 1999/07/12 15:13:34 cproch
|
|
86 - added definition of ICQLINK to hold session-specific global variabled
|
|
87 applications which have more than one connection are now possible
|
|
88 - changed nearly every function defintion to support ICQLINK parameter
|
|
89
|
|
90 Revision 1.13 1999/07/03 06:33:49 lord
|
|
91 . byte order conversion macros added
|
|
92 . some compilation warnings removed
|
|
93
|
|
94 Revision 1.12 1999/06/30 13:52:22 bills
|
|
95 implemented non-blocking connects
|
|
96
|
|
97 Revision 1.11 1999/05/03 21:41:26 bills
|
|
98 initial file xfer support added- untested
|
|
99
|
|
100 Revision 1.10 1999/04/29 09:35:41 denis
|
|
101 Cleanups, warning removed
|
|
102
|
|
103 Revision 1.9 1999/04/17 19:30:50 bills
|
|
104 _major_ restructuring. all tcp sockets (including listening sockets) are
|
|
105 kept in global linked list, icq_TCPLinks. accept and listen functions
|
|
106 moved to tcplink.c. changed return values of Send* functions to DWORD.
|
|
107
|
|
108 Revision 1.8 1999/04/14 14:57:05 denis
|
|
109 Cleanups for "strict" compiling (-ansi -pedantic)
|
|
110 Parameter port added to function icq_TCPCreateListeningSocket()
|
|
111
|
|
112 */
|
|
113
|
|
114 /*
|
|
115 Peer-to-peer ICQ protocol implementation
|
|
116
|
|
117 Uses version 2 of the ICQ protocol
|
|
118
|
|
119 Thanks to Douglas F. McLaughlin and many others for
|
|
120 packet details (see tcp02.txt)
|
|
121
|
|
122 */
|
|
123
|
|
124 #include <stdlib.h>
|
|
125
|
|
126 #ifndef _WIN32
|
|
127 #include <unistd.h>
|
|
128 #endif
|
|
129
|
|
130 #include <fcntl.h>
|
|
131 #include <stdarg.h>
|
|
132 #include <errno.h>
|
|
133
|
|
134 #include <sys/types.h>
|
|
135
|
|
136 #ifdef _WIN32
|
|
137 #include <winsock.h>
|
|
138 #else
|
|
139 #include <sys/socket.h>
|
|
140 #endif
|
|
141
|
|
142 #include <sys/stat.h>
|
|
143
|
|
144 #ifndef _WIN32
|
|
145 #include <sys/time.h>
|
|
146 #endif
|
|
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 */
|
|
170 link->icq_TCPLinks=list_new();
|
|
171 link->icq_ChatSessions=list_new();
|
|
172 link->icq_FileSessions=list_new();
|
|
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 */
|
|
181 link->icq_TCPSequence=0xfffffffe;
|
|
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 */
|
|
190 list_delete(link->icq_TCPLinks, icq_TCPLinkDelete);
|
|
191 list_delete(link->icq_ChatSessions, icq_ChatSessionDelete);
|
|
192 list_delete(link->icq_FileSessions, icq_FileSessionDelete);
|
|
193 }
|
|
194
|
|
195 /* helper function for icq_TCPMain */
|
|
196 int _generate_fds(void *p, va_list data)
|
|
197 {
|
|
198 icq_TCPLink *plink=(icq_TCPLink *)p;
|
|
199 ICQLINK *icqlink = plink->icqlink;
|
|
200
|
|
201 (void)data;
|
|
202
|
|
203 if(plink->socket>-1)
|
|
204 {
|
|
205 int socket=plink->socket;
|
|
206
|
|
207 FD_SET(socket, &icqlink->TCP_readfds);
|
|
208
|
|
209 /* we only care about writing if socket is trying to connect */
|
|
210 if(plink->mode & TCP_LINK_MODE_CONNECTING)
|
|
211 {
|
|
212 if(plink->mode & (TCP_LINK_SOCKS_AUTHORIZATION | TCP_LINK_SOCKS_NOAUTHSTATUS | TCP_LINK_SOCKS_AUTHSTATUS | TCP_LINK_SOCKS_CONNSTATUS))
|
|
213 FD_SET(socket, &icqlink->TCP_readfds);
|
|
214 else
|
|
215 FD_SET(socket, &icqlink->TCP_writefds);
|
|
216 }
|
|
217
|
|
218 if(socket+1>icqlink->TCP_maxfd)
|
|
219 icqlink->TCP_maxfd=socket+1;
|
|
220 }
|
|
221
|
|
222 return 0; /* traverse the entire list */
|
|
223 }
|
|
224
|
|
225 /* helper function for icq_TCPMain */
|
|
226 int _handle_ready_sockets(void *p, va_list data)
|
|
227 {
|
|
228 icq_TCPLink *plink=(icq_TCPLink *)p;
|
|
229 ICQLINK *icqlink = plink->icqlink;
|
|
230 int socket=plink->socket;
|
|
231
|
|
232 (void)data;
|
|
233
|
|
234 /* handle connecting sockets */
|
|
235 if (plink->mode & TCP_LINK_MODE_CONNECTING)
|
|
236 {
|
|
237 if(socket>-1 && (FD_ISSET(socket, &icqlink->TCP_writefds) || FD_ISSET(socket, &icqlink->TCP_readfds)))
|
|
238 {
|
|
239 icq_TCPLinkOnConnect(plink);
|
|
240 return 0;
|
|
241 }
|
|
242
|
|
243 if((time(0L) - plink->connect_time) > TCP_LINK_CONNECT_TIMEOUT)
|
|
244 {
|
|
245 icq_TCPLinkClose(plink);
|
|
246 return 0;
|
|
247 }
|
|
248 }
|
|
249
|
|
250 /* handle ready for read sockets- either a connection is waiting on *
|
|
251 * the listen sockets or data is ready to be read */
|
|
252 if(socket>-1 && FD_ISSET(socket, &icqlink->TCP_readfds))
|
|
253 {
|
|
254 if(plink->mode & TCP_LINK_MODE_LISTEN)
|
|
255 (void)icq_TCPLinkAccept(plink);
|
|
256 else {
|
|
257
|
|
258 int result=icq_TCPLinkOnDataReceived(plink);
|
|
259
|
|
260 /* close the link if there was a receive error or if *
|
|
261 * the remote end has closed the connection */
|
|
262 if (result < 1)
|
|
263 icq_TCPLinkClose(plink);
|
|
264
|
|
265 }
|
|
266 }
|
|
267
|
|
268 return 0; /* traverse the entire list */
|
|
269 }
|
|
270
|
|
271 /* helper function for icq_TCPMain */
|
|
272 int _process_links(void *p, va_list data)
|
|
273 {
|
|
274 icq_TCPLink *plink=(icq_TCPLink *)p;
|
|
275
|
|
276 (void)data;
|
|
277
|
|
278 /* receive any packets watiting on the link */
|
|
279 icq_TCPLinkProcessReceived(plink);
|
|
280
|
|
281 /* if this a currently sending file link, send data! */
|
|
282 if(plink->type==TCP_LINK_FILE) {
|
|
283 icq_FileSession *psession=plink->session;
|
|
284 if(psession && psession->status==FILE_STATUS_SENDING)
|
|
285 icq_FileSessionSendData(psession);
|
|
286 }
|
|
287
|
|
288 return 0; /* traverse entire list */
|
|
289 }
|
|
290
|
|
291 void icq_TCPMain(ICQLINK *link)
|
|
292 {
|
|
293 struct timeval tv;
|
|
294
|
|
295 tv.tv_sec = 0;
|
|
296 tv.tv_usec = 0;
|
|
297
|
|
298 link->TCP_maxfd = 0;
|
|
299 FD_ZERO(&link->TCP_readfds);
|
|
300 FD_ZERO(&link->TCP_writefds);
|
|
301
|
|
302 /* generate the fd sets for all open tcp links */
|
|
303 (void)list_traverse(link->icq_TCPLinks, _generate_fds);
|
|
304
|
|
305 /* determine which sockets require maintenance */
|
|
306 select(link->TCP_maxfd, &link->TCP_readfds, &link->TCP_writefds, 0, &tv);
|
|
307
|
|
308 /* call icq_TCPLinkOnDataReceived for any sockets with ready data,
|
|
309 * send all packets on send queue if socket has connected, and
|
|
310 * accept() from any listening sockets with pending connections */
|
|
311 (void)list_traverse(link->icq_TCPLinks, _handle_ready_sockets, 0, 0);
|
|
312
|
|
313 /* process all packets waiting for each TCPLink */
|
|
314 (void)list_traverse(link->icq_TCPLinks, _process_links, 0, 0);
|
|
315 }
|
|
316
|
|
317 icq_TCPLink *icq_TCPCheckLink(ICQLINK *link, DWORD uin, int type)
|
|
318 {
|
|
319 icq_TCPLink *plink=icq_FindTCPLink(link, uin, type);
|
|
320
|
|
321 if(!plink)
|
|
322 {
|
|
323 plink=icq_TCPLinkNew( link );
|
|
324 if(type==TCP_LINK_MESSAGE)
|
|
325 icq_TCPLinkConnect(plink, uin, 0);
|
|
326 }
|
|
327
|
|
328 return plink;
|
|
329
|
|
330 }
|
|
331
|
|
332 DWORD icq_TCPSendMessage(ICQLINK *link, DWORD uin, const char *message)
|
|
333 {
|
|
334 icq_TCPLink *plink;
|
|
335 icq_Packet *p;
|
|
336 DWORD sequence;
|
|
337 char data[512] ;
|
|
338
|
|
339 strncpy(data,message,512) ;
|
|
340 icq_RusConv("kw", data) ;
|
|
341
|
|
342 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
343
|
|
344 /* create and send the message packet */
|
|
345 p=icq_TCPCreateMessagePacket(plink, (unsigned char *)data);
|
|
346 sequence=icq_TCPLinkSendSeq(plink, p, 0);
|
|
347
|
|
348 #ifdef TCP_PACKET_TRACE
|
|
349 printf("message packet sent to uin %lu { sequence=%lx }\n", uin, p->id);
|
|
350 #endif
|
|
351
|
|
352 return sequence;
|
|
353 }
|
|
354
|
|
355 DWORD icq_TCPSendURL(ICQLINK *link, DWORD uin, const char *message, const char *url)
|
|
356 {
|
|
357 icq_TCPLink *plink;
|
|
358 icq_Packet *p;
|
|
359 DWORD sequence;
|
|
360 char data[512];
|
|
361
|
|
362 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
363
|
|
364 strncpy(data, message, 512);
|
|
365 data[511] = '\0';
|
|
366 icq_RusConv("kw", data);
|
|
367
|
|
368 /* create and send the url packet */
|
|
369 p=icq_TCPCreateURLPacket(plink, data, url);
|
|
370 sequence=icq_TCPLinkSendSeq(plink, p, 0);
|
|
371
|
|
372 #ifdef TCP_PACKET_TRACE
|
|
373 printf("url packet queued for uin %lu { sequence=%lx }\n", uin, p->id);
|
|
374 #endif
|
|
375
|
|
376 return sequence;
|
|
377 }
|
|
378
|
|
379 DWORD icq_SendChatRequest(ICQLINK *link, DWORD uin, const char *message)
|
|
380 {
|
|
381 icq_TCPLink *plink;
|
|
382 icq_Packet *p;
|
|
383 DWORD sequence;
|
|
384 char data[512];
|
|
385
|
|
386 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
387
|
|
388 strncpy(data, message, 512);
|
|
389 data[511] = '\0';
|
|
390 icq_RusConv("kw", data);
|
|
391
|
|
392 /* create and send the url packet */
|
|
393 p=icq_TCPCreateChatReqPacket(plink, (unsigned char *)data);
|
|
394 sequence=icq_TCPLinkSendSeq(plink, p, 0);
|
|
395
|
|
396 #ifdef TCP_PACKET_TRACE
|
|
397 printf("chat req packet sent to uin %lu { sequence=%lx }\n", uin, p->id);
|
|
398 #endif
|
|
399
|
|
400 return sequence;
|
|
401 }
|
|
402
|
|
403 unsigned long icq_SendFileRequest(ICQLINK *link, unsigned long uin,
|
|
404 const char *message, char **files)
|
|
405 {
|
|
406 icq_TCPLink *plink;
|
|
407 icq_FileSession *pfile;
|
|
408 icq_Packet *p;
|
|
409 unsigned long sequence;
|
|
410 char filename[64];
|
|
411 char data[512];
|
|
412
|
|
413 plink=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
414
|
|
415 /* create the file session, this will be linked to the incoming icq_TCPLink
|
|
416 * in icq_HandleFileAck */
|
|
417 pfile=icq_FileSessionNew(link);
|
|
418 pfile->remote_uin=uin;
|
|
419 pfile->files=files;
|
|
420 pfile->direction=FILE_STATUS_SENDING;
|
|
421
|
|
422 /* count the number and size of the files */
|
|
423 pfile->total_files=0;
|
|
424 while(*files) {
|
|
425 struct stat file_status;
|
|
426
|
|
427 if(stat(*files, &file_status)==0) {
|
|
428 pfile->total_files++;
|
|
429 pfile->total_bytes+=file_status.st_size;
|
|
430 }
|
|
431 files++;
|
|
432 }
|
|
433
|
|
434 strncpy(filename, *(pfile->files), 64);
|
|
435
|
|
436 strncpy(data, message, 512);
|
|
437 data[511] = '\0';
|
|
438 icq_RusConv("kw", data);
|
|
439
|
|
440 /* create and send the file req packet */
|
|
441 p=icq_TCPCreateFileReqPacket(plink, (char *)data, filename,
|
|
442 pfile->total_bytes);
|
|
443 sequence=icq_TCPLinkSendSeq(plink, p, 0);
|
|
444 pfile->id=sequence;
|
|
445
|
|
446 #ifdef TCP_PACKET_TRACE
|
|
447 printf("file req packet sent to uin %lu { sequence=%lx }\n", uin, p->id);
|
|
448 #endif
|
|
449
|
|
450 return sequence;
|
|
451 }
|
|
452
|
|
453 void icq_AcceptChatRequest(ICQLINK *link, DWORD uin, unsigned long sequence)
|
|
454 {
|
|
455 icq_TCPLink *pmessage, *plisten;
|
|
456 icq_ChatSession *pchat;
|
|
457 icq_Packet *p;
|
|
458
|
|
459 pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
460
|
|
461 /* create the chat listening socket if necessary */
|
|
462 if(!(plisten=icq_FindTCPLink(link, 0, TCP_LINK_CHAT)))
|
|
463 {
|
|
464 plisten=icq_TCPLinkNew( link );
|
|
465 plisten->type=TCP_LINK_CHAT;
|
|
466 icq_TCPLinkListen(plisten);
|
|
467 }
|
|
468
|
|
469 /* create the chat session, this will be linked to the incoming icq_TCPLink
|
|
470 * in TCPProcessHello */
|
|
471 pchat=icq_ChatSessionNew(link);
|
|
472 pchat->id=sequence;
|
|
473 pchat->remote_uin=uin;
|
|
474
|
|
475 /* create and send the ack packet */
|
|
476 p=icq_TCPCreateChatReqAck(pmessage,
|
|
477 ntohs(plisten->socket_address.sin_port));
|
|
478 (void)icq_TCPLinkSendSeq(pmessage, p, sequence);
|
|
479
|
|
480 #ifdef TCP_PACKET_TRACE
|
|
481 printf("chat req ack sent to uin %lu { sequence=%lx }\n", uin, sequence);
|
|
482 #endif
|
|
483 }
|
|
484
|
|
485 void icq_TCPSendChatData(ICQLINK *link, DWORD uin, const char *data)
|
|
486 {
|
|
487 icq_TCPLink *plink=icq_FindTCPLink(link, uin, TCP_LINK_CHAT);
|
|
488 char data1[512];
|
|
489 int data1_len;
|
|
490
|
|
491 if(!plink)
|
|
492 return;
|
|
493
|
|
494 strncpy(data1,data,512) ;
|
|
495 data1[511] = '\0';
|
|
496 data1_len = strlen(data);
|
|
497 icq_ChatRusConv_n("kw", data1, data1_len);
|
|
498
|
|
499 send(plink->socket, data1, data1_len, 0);
|
|
500
|
|
501 }
|
|
502
|
|
503 void icq_TCPSendChatData_n(ICQLINK *link, DWORD uin, const char *data, int len)
|
|
504 {
|
|
505 icq_TCPLink *plink=icq_FindTCPLink(link, uin, TCP_LINK_CHAT);
|
|
506 char *data1;
|
|
507
|
|
508 if(!plink)
|
|
509 return;
|
|
510
|
|
511 data1 = (char *)malloc(len);
|
|
512 memcpy(data1, data, len);
|
|
513 icq_ChatRusConv_n("kw", data1, len);
|
|
514
|
|
515 send(plink->socket, data1, len, 0);
|
|
516
|
|
517 }
|
|
518
|
|
519 void icq_TCPCloseChat(ICQLINK *link, unsigned long uin)
|
|
520 {
|
|
521 icq_TCPLink *plink=icq_FindTCPLink(link, uin, TCP_LINK_CHAT);
|
|
522
|
|
523 if(plink)
|
|
524 icq_TCPLinkClose(plink);
|
|
525
|
|
526 }
|
|
527
|
|
528 icq_FileSession *icq_AcceptFileRequest(ICQLINK *link, DWORD uin,
|
|
529 unsigned long sequence)
|
|
530 {
|
|
531 icq_TCPLink *pmessage, *plisten;
|
|
532 icq_FileSession *pfile;
|
|
533 icq_Packet *p;
|
|
534
|
|
535 pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
536
|
|
537 /* create the file listening socket if necessary */
|
|
538 if(!(plisten=icq_FindTCPLink(link, 0, TCP_LINK_FILE)))
|
|
539 {
|
|
540 plisten=icq_TCPLinkNew( link );
|
|
541 plisten->type=TCP_LINK_FILE;
|
|
542 icq_TCPLinkListen(plisten);
|
|
543 }
|
|
544
|
|
545 /* create the file session, this will be linked to the incoming icq_TCPLink
|
|
546 * in TCPProcessHello */
|
|
547 pfile=icq_FileSessionNew(link);
|
|
548 pfile->id=sequence;
|
|
549 pfile->remote_uin=uin;
|
|
550 pfile->direction=FILE_STATUS_RECEIVING;
|
|
551 icq_FileSessionSetStatus(pfile, FILE_STATUS_LISTENING);
|
|
552
|
|
553 /* create and send the ack packet */
|
|
554 p=icq_TCPCreateFileReqAck(pmessage,
|
|
555 ntohs(plisten->socket_address.sin_port));
|
|
556 (void)icq_TCPLinkSendSeq(pmessage, p, sequence);
|
|
557
|
|
558 #ifdef TCP_PACKET_TRACE
|
|
559 printf("file req ack sent to uin %lu { sequence=%lx }\n", uin, sequence);
|
|
560 #endif
|
|
561
|
|
562 return pfile;
|
|
563
|
|
564 }
|
|
565
|
|
566 void icq_RefuseFileRequest(ICQLINK *link, DWORD uin,
|
|
567 unsigned long sequence, const char *reason)
|
|
568 {
|
|
569 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
570 icq_Packet *p;
|
|
571
|
|
572 /* create and send the refuse packet */
|
|
573 p=icq_TCPCreateFileReqRefuse(pmessage,
|
|
574 ntohs(pmessage->socket_address.sin_port), reason);
|
|
575 (void)icq_TCPLinkSendSeq(pmessage, p, sequence);
|
|
576
|
|
577 #ifdef TCP_PACKET_TRACE
|
|
578 printf("file req refuse sent to uin %lu { sequence=%lx, reason=\"%s\" }\n",
|
|
579 uin, sequence, reason);
|
|
580 #endif
|
|
581
|
|
582 }
|
|
583
|
|
584 void icq_CancelFileRequest(ICQLINK *link, DWORD uin, unsigned long sequence)
|
|
585 {
|
|
586 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
587 icq_FileSession *psession=icq_FindFileSession(link, uin, sequence);
|
|
588 icq_Packet *p;
|
|
589
|
|
590 if (psession)
|
|
591 icq_FileSessionClose(psession);
|
|
592
|
|
593 /* create and send the cancel packet */
|
|
594 p=icq_TCPCreateFileReqCancel(pmessage,
|
|
595 ntohs(pmessage->socket_address.sin_port));
|
|
596 (void)icq_TCPLinkSendSeq(pmessage, p, sequence);
|
|
597 #ifdef TCP_PACKET_TRACE
|
|
598 printf("file req cancel sent to uin %lu { sequence=%lx }\n", uin, sequence);
|
|
599 #endif
|
|
600
|
|
601 }
|
|
602
|
|
603 void icq_RefuseChatRequest(ICQLINK *link, DWORD uin,
|
|
604 unsigned long sequence, const char *reason)
|
|
605 {
|
|
606 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
607 icq_Packet *p;
|
|
608
|
|
609 /* create and send the refuse packet */
|
|
610 p=icq_TCPCreateChatReqRefuse(pmessage,
|
|
611 ntohs(pmessage->socket_address.sin_port), reason);
|
|
612 (void)icq_TCPLinkSendSeq(pmessage, p, sequence);
|
|
613
|
|
614 #ifdef TCP_PACKET_TRACE
|
|
615 printf("chat req refuse sent to uin %lu { sequence=%lx, reason=\"%s\" }\n",
|
|
616 uin, sequence, reason);
|
|
617 #endif
|
|
618
|
|
619 }
|
|
620
|
|
621 void icq_CancelChatRequest(ICQLINK *link, DWORD uin, unsigned long sequence)
|
|
622 {
|
|
623 icq_TCPLink *pmessage=icq_TCPCheckLink(link, uin, TCP_LINK_MESSAGE);
|
|
624 icq_FileSession *psession=icq_FindFileSession(link, uin, sequence);
|
|
625 icq_Packet *p;
|
|
626
|
|
627 if (psession)
|
|
628 icq_FileSessionClose(psession);
|
|
629
|
|
630 /* create and send the cancel packet */
|
|
631 p=icq_TCPCreateChatReqCancel(pmessage,
|
|
632 ntohs(pmessage->socket_address.sin_port));
|
|
633 (void)icq_TCPLinkSendSeq(pmessage, p, sequence);
|
|
634
|
|
635 #ifdef TCP_PACKET_TRACE
|
|
636 printf("chat req cancel sent to uin %lu { sequence=%lx }\n", uin, sequence);
|
|
637 #endif
|
|
638
|
|
639 }
|