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