comparison plugins/icq/tcphandle.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: tcphandle.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.12 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.11 2000/06/25 16:36:16 denis
13 '\n' was added at the end of log messages.
14
15 Revision 1.10 2000/05/04 15:57:20 bills
16 Reworked file transfer notification, small bugfixes, and cleanups.
17
18 Revision 1.9 2000/05/03 18:29:15 denis
19 Callbacks have been moved to the ICQLINK structure.
20
21 Revision 1.8 2000/04/05 14:37:02 denis
22 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
23 compatibility.
24
25 Revision 1.7 2000/01/20 20:06:00 bills
26 removed debugging printfs
27
28 Revision 1.6 2000/01/20 19:59:15 bills
29 first implementation of sending file requests
30
31 Revision 1.5 1999/11/30 09:51:42 bills
32 more file xfer logic added
33
34 Revision 1.4 1999/11/11 15:10:30 guruz
35 - Added Base for Webpager Messages. Please type "make fixme"
36 - Removed Segfault when kicq is started the first time
37
38 Revision 1.3 1999/10/01 02:28:51 bills
39 icq_TCPProcessHello returns something now :)
40
41 Revision 1.2 1999/10/01 00:49:20 lord
42 some compilation problems are fixed.
43
44 Revision 1.1 1999/09/29 19:47:21 bills
45 reworked chat/file handling. fixed chat. (it's been broke since I put
46 non-blocking connects in)
47
48 Revision 1.15 1999/07/16 15:45:59 denis
49 Cleaned up.
50
51 Revision 1.14 1999/07/16 12:10:10 denis
52 tcp_packet* functions renamed to icq_Packet*
53 Cleaned up.
54
55 Revision 1.13 1999/07/12 15:13:41 cproch
56 - added definition of ICQLINK to hold session-specific global variabled
57 applications which have more than one connection are now possible
58 - changed nearly every function defintion to support ICQLINK parameter
59
60 Revision 1.12 1999/06/30 13:51:25 bills
61 cleanups
62
63 Revision 1.11 1999/05/03 21:41:30 bills
64 initial file xfer support added- untested
65
66 Revision 1.10 1999/04/29 09:36:06 denis
67 Cleanups, warning removed
68
69 Revision 1.9 1999/04/17 19:40:33 bills
70 reworked code to use icq_TCPLinks instead of icq_ContactItem entries.
71 modified ProcessChatPacket to negotiate both sending and receiving chat
72 requests properly.
73
74 Revision 1.8 1999/04/14 15:12:02 denis
75 Cleanups for "strict" compiling (-ansi -pedantic)
76 icq_ContactItem parameter added to function icq_TCPOnMessageReceived()
77 Segfault fixed on spoofed messages.
78
79 */
80
81 #include <time.h>
82
83 #ifndef _WIN32
84 #include <unistd.h>
85 #endif
86
87 #include "icqtypes.h"
88 #include "icq.h"
89 #include "icqlib.h"
90
91 #include "tcp.h"
92 #include "stdpackets.h"
93 #include "tcplink.h"
94
95 void icq_TCPOnMessageReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id, icq_TCPLink *plink);
96 void icq_TCPOnURLReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id);
97 void icq_TCPOnChatReqReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id);
98 void icq_TCPOnFileReqReceived(ICQLINK *link, DWORD uin, const char *message,
99 const char *filename, unsigned long filesize, DWORD id);
100 void icq_TCPProcessAck(ICQLINK *link, icq_Packet *p);
101 void icq_HandleChatAck(icq_TCPLink *plink, icq_Packet *p, int port);
102 void icq_HandleChatHello(icq_TCPLink *plink);
103 void icq_HandleFileHello(icq_TCPLink *plink);
104 void icq_HandleFileAck(icq_TCPLink *plink, icq_Packet *p, int port);
105
106 void icq_TCPProcessPacket(icq_Packet *p, icq_TCPLink *plink)
107 {
108 DWORD uin;
109 WORD version;
110 WORD command;
111 WORD type;
112 WORD status;
113 DWORD command_type;
114 DWORD filesize = 0;
115 DWORD port = 0;
116
117 const char *message;
118 const char *filename = 0;
119
120 icq_PacketBegin(p);
121 (void)icq_PacketRead32(p);
122 version=icq_PacketRead16(p);
123 command=icq_PacketRead16(p);
124 (void)icq_PacketRead16(p);
125
126 uin=icq_PacketRead32(p);
127 type=icq_PacketRead16(p);
128 message=icq_PacketReadString(p);
129 (void)icq_PacketRead32(p);
130 (void)icq_PacketRead32(p);
131 (void)icq_PacketRead32(p);
132 (void)icq_PacketRead8(p);
133 status=icq_PacketRead16(p);
134 command_type=icq_PacketRead16(p);
135
136 switch(type)
137 {
138 case ICQ_TCP_MSG_MSG:
139 case ICQ_TCP_MSG_URL:
140 p->id=icq_PacketRead32(p);
141 break;
142
143 case ICQ_TCP_MSG_CHAT:
144 (void)icq_PacketReadString(p);
145 (void)icq_PacketRead16(p);
146 (void)icq_PacketRead16(p);
147 port=icq_PacketRead32(p);
148 p->id=icq_PacketRead32(p);
149 break;
150
151 case ICQ_TCP_MSG_FILE:
152 (void)icq_PacketRead16(p);
153 (void)icq_PacketRead16(p);
154 filename=icq_PacketReadString(p);
155 filesize=icq_PacketRead32(p);
156 port=icq_PacketRead32(p);
157 p->id=icq_PacketRead32(p);
158 break;
159
160 default:
161 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message packet, type %x\n", type);
162 }
163
164 #ifdef TCP_PROCESS_TRACE
165 printf("packet processed from uin: %lu:\n", uin);
166 printf(" command: %x\ttype: %x\n", command, type);
167 printf(" status: %x\tcommand_type: %x\n", status, (int)command_type);
168 printf(" message %s\n", message);
169 printf(" id: %x\n", (int)p->id);
170 #endif
171
172 switch(command)
173 {
174 case ICQ_TCP_MESSAGE:
175 switch(type)
176 {
177 case ICQ_TCP_MSG_MSG:
178 icq_TCPOnMessageReceived(plink->icqlink, uin, message, p->id, plink);
179 break;
180
181 case ICQ_TCP_MSG_URL:
182 icq_TCPOnURLReceived(plink->icqlink, uin, message, p->id);
183 break;
184
185 case ICQ_TCP_MSG_CHAT:
186 icq_TCPOnChatReqReceived(plink->icqlink, uin, message, p->id);
187 break;
188
189 case ICQ_TCP_MSG_FILE:
190 icq_TCPOnFileReqReceived(plink->icqlink, uin, message, filename, filesize, p->id);
191 break;
192
193 default:
194 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message type %d!\n", type);
195 break;
196 }
197 break;
198
199 case ICQ_TCP_ACK:
200 switch(type) {
201 case ICQ_TCP_MSG_CHAT:
202 icq_HandleChatAck(plink, p, port);
203 break;
204
205 case ICQ_TCP_MSG_FILE:
206 icq_HandleFileAck(plink, p, port);
207 break;
208
209 case ICQ_TCP_MSG_MSG:
210 case ICQ_TCP_MSG_URL:
211 if(plink->icqlink->icq_RequestNotify) {
212 icq_FmtLog(plink->icqlink, ICQ_LOG_MESSAGE, "received ack %d\n", p->id);
213 (*plink->icqlink->icq_RequestNotify)(plink->icqlink, p->id, ICQ_NOTIFY_ACK, status,
214 (void *)message);
215 (*plink->icqlink->icq_RequestNotify)(plink->icqlink, p->id, ICQ_NOTIFY_SUCCESS, 0, 0);
216 }
217 break;
218 }
219 break;
220
221 case ICQ_TCP_CANCEL:
222 /* icq_TCPProcessCancel(p); */
223 break;
224
225 default:
226 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING,
227 "unknown packet command %d!\n", command);
228 }
229 }
230
231 void icq_TCPProcessCancel(icq_Packet *p)
232 {
233 (void)p;
234
235 /*
236 find packet in queue
237 call notification function
238 remove packet from queue
239 */
240 }
241
242 int icq_TCPProcessHello(icq_Packet *p, icq_TCPLink *plink)
243 {
244 /* TCP Hello packet */
245 BYTE code; /* 0xFF - init packet code */
246 DWORD version; /* tcp version */
247 DWORD remote_port; /* remote message listen port */
248 DWORD remote_uin; /* remote uin */
249 DWORD remote_ip; /* remote IP as seen by ICQ server */
250 DWORD remote_real_ip; /* remote IP as seen by client */
251 BYTE flags; /* tcp flags */
252 DWORD remote_other_port; /* remote chat or file listen port */
253
254 icq_PacketBegin(p);
255
256 code=icq_PacketRead8(p);
257 version=icq_PacketRead32(p);
258
259 if (!(p->length>=26 && code==ICQ_TCP_HELLO))
260 {
261 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING,
262 "malformed hello packet received from %s:%d, closing link\n",
263 inet_ntoa(*((struct in_addr *)(&(plink->remote_address.sin_addr)))),
264 ntohs(plink->remote_address.sin_port));
265
266 icq_TCPLinkClose(plink);
267 return 0;
268 }
269 remote_port=icq_PacketRead32(p);
270 remote_uin=icq_PacketRead32(p);
271 remote_ip=icq_PacketRead32(p);
272 remote_real_ip=icq_PacketRead32(p);
273 flags=icq_PacketRead8(p);
274 remote_other_port=icq_PacketRead32(p);
275
276 icq_FmtLog(plink->icqlink, ICQ_LOG_MESSAGE,
277 "hello packet received from %lu { version=%d }\n", remote_uin, version);
278
279 plink->remote_version=version;
280 plink->remote_uin=remote_uin;
281 plink->flags=flags;
282 plink->mode&=~TCP_LINK_MODE_HELLOWAIT;
283
284 /* file and chat sessions require additional handling */
285 if(plink->type==TCP_LINK_CHAT) icq_HandleChatHello(plink);
286 if(plink->type==TCP_LINK_FILE) icq_HandleFileHello(plink);
287
288 return 1;
289 }
290
291 void icq_TCPOnMessageReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id, icq_TCPLink *plink)
292 {
293 char data[512] ;
294 #ifdef TCP_PACKET_TRACE
295 printf("tcp message packet received from %lu { sequence=%x }\n",
296 uin, (int)id);
297 #endif
298
299 if(link->icq_RecvMessage)
300 {
301 /* use the current system time for time received */
302 time_t t=time(0);
303 struct tm *ptime=localtime(&t);
304 icq_Packet *pack;
305 icq_TCPLink *preallink=icq_FindTCPLink(link, uin, TCP_LINK_MESSAGE);
306
307 strncpy(data,message,512) ;
308 icq_RusConv("wk",data) ;
309
310 (*link->icq_RecvMessage)(link, uin, ptime->tm_hour, ptime->tm_min,
311 ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, data);
312
313 if(plink != preallink)
314 {
315 /* if(icq_SpoofedMessage)
316 (*icq_SpoofedMessage(uin, ...));*/
317 }
318
319 if(plink)
320 {
321 /* send an acknowledgement to the remote client */
322 pack=icq_TCPCreateMessageAck(plink,0);
323 icq_PacketAppend32(pack, id);
324 icq_PacketSend(pack, plink->socket);
325 #ifdef TCP_PACKET_TRACE
326 printf("tcp message ack sent to uin %lu { sequence=%lx }\n", uin, id);
327 #endif
328 icq_PacketDelete(pack);
329 }
330 }
331 }
332
333 void icq_TCPOnURLReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id)
334 {
335 #ifdef TCP_PACKET_TRACE
336 printf("tcp url packet received from %lu { sequence=%lx }\n",
337 uin, id);
338 #endif /*TCP_PACKET_TRACE*/
339
340 if(link->icq_RecvURL) {
341
342 /* use the current system time for time received */
343 time_t t=time(0);
344 struct tm *ptime=localtime(&t);
345 icq_Packet *pack;
346 char *pfe;
347 icq_TCPLink *plink=icq_FindTCPLink(link, uin, TCP_LINK_MESSAGE);
348
349 /* the URL is split from the description by 0xFE */
350 pfe=strchr(message, '\xFE');
351 *pfe=0;
352 (*link->icq_RecvURL)(link, uin, ptime->tm_hour, ptime->tm_min,
353 ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, pfe+1, message);
354
355 /* send an acknowledgement to the remote client */
356 pack=icq_TCPCreateURLAck(plink,0);
357 icq_PacketAppend32(pack, id);
358 icq_PacketSend(pack, plink->socket);
359 #ifdef TCP_PACKET_TRACE
360 printf("tcp message ack sent to %lu { sequence=%lx }\n", uin, id);
361 #endif
362 icq_PacketDelete(pack);
363 }
364 }
365
366