2086
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2
|
|
3 /*
|
|
4 * $Id: eventhandle.c 2096 2001-07-31 01:00:39Z warmenhoven $
|
|
5 *
|
|
6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and
|
|
7 * Bill Soudan <soudan@kde.org>
|
|
8 *
|
|
9 * This program is free software; you can redistribute it and/or modify
|
|
10 * it under the terms of the GNU General Public License as published by
|
|
11 * the Free Software Foundation; either version 2 of the License, or
|
|
12 * (at your option) any later version.
|
|
13 *
|
|
14 * This program is distributed in the hope that it will be useful,
|
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 * GNU General Public License for more details.
|
|
18 *
|
|
19 * You should have received a copy of the GNU General Public License
|
|
20 * along with this program; if not, write to the Free Software
|
|
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 #include <time.h>
|
|
26
|
|
27 #ifndef _WIN32
|
|
28 #include <unistd.h>
|
|
29 #endif
|
|
30
|
|
31 #include "icqevent.h"
|
|
32 #include "icqpacket.h"
|
|
33 #include "tcplink.h"
|
|
34 #include "chatsession.h"
|
|
35 #include "filesession.h"
|
|
36
|
|
37 #include "eventhandle.h"
|
|
38
|
|
39 void icq_TCPProcessPacket2(icq_Packet *p, icq_TCPLink *tcplink)
|
|
40 {
|
|
41 icq_MessageEvent *pevent=(icq_MessageEvent *)icq_ParsePacket(p);
|
|
42 icq_Event *pbase=(icq_Event *)pevent;
|
|
43
|
|
44 icq_Link *icqlink=tcplink->icqlink;
|
|
45
|
|
46 if (pbase->uin != tcplink->remote_uin)
|
|
47 {
|
|
48 /* TODO: spoofed packet! */
|
|
49 }
|
|
50
|
|
51 pbase->handleEvent(pbase, icqlink);
|
|
52
|
|
53 /* notify library client than the ack was received from remote client */
|
|
54 if (pbase->subtype==ICQ_EVENT_ACK)
|
|
55 {
|
|
56 icq_FmtLog(tcplink->icqlink, ICQ_LOG_MESSAGE, "received ack %d\n", p->id);
|
|
57 if(icqlink->icq_RequestNotify)
|
|
58 {
|
|
59 (*icqlink->icq_RequestNotify)(icqlink, pbase->id,
|
|
60 ICQ_NOTIFY_ACK, pevent->status, (void *)pevent->message);
|
|
61 (*icqlink->icq_RequestNotify)(icqlink, pbase->id,
|
|
62 ICQ_NOTIFY_SUCCESS, 0, 0);
|
|
63 }
|
|
64 }
|
|
65 }
|
|
66
|
|
67 void icq_HandleMessageEvent(icq_Event *pbase, icq_Link *icqlink)
|
|
68 {
|
|
69 icq_MessageEvent *pevent=(icq_MessageEvent *)pbase;
|
|
70 struct tm *ptime=localtime(&(pbase->time));
|
|
71
|
|
72 if (pbase->subtype==ICQ_EVENT_MESSAGE && icqlink->icq_RecvMessage)
|
|
73 {
|
|
74 (*icqlink->icq_RecvMessage)(icqlink, pbase->uin, ptime->tm_hour,
|
|
75 ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
|
|
76 ptime->tm_year+1900, pevent->message);
|
|
77 /* TODO: send ack */
|
|
78 }
|
|
79
|
|
80 }
|
|
81
|
|
82 void icq_HandleURLEvent(icq_Event *pbase, icq_Link *icqlink)
|
|
83 {
|
|
84 icq_URLEvent *pevent=(icq_URLEvent *)pbase;
|
|
85 struct tm *ptime=localtime(&(pbase->time));
|
|
86
|
|
87 if (pbase->subtype==ICQ_EVENT_MESSAGE && icqlink->icq_RecvURL)
|
|
88 {
|
|
89 (*icqlink->icq_RecvURL)(icqlink, pbase->uin, ptime->tm_hour,
|
|
90 ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
|
|
91 ptime->tm_year+1900, pevent->url, pevent->message);
|
|
92 /* TODO: send ack */
|
|
93 }
|
|
94 }
|
|
95
|
|
96 void icq_HandleChatRequestEvent(icq_Event *pbase, icq_Link *icqlink)
|
|
97 {
|
|
98 icq_ChatRequestEvent *pevent=(icq_ChatRequestEvent *)pbase;
|
|
99 icq_MessageEvent *pmsgevent=(icq_MessageEvent *)pmsgevent;
|
|
100
|
|
101 struct tm *ptime=localtime(&(pbase->time));
|
|
102
|
|
103 switch(pbase->subtype)
|
|
104 {
|
|
105 case ICQ_EVENT_MESSAGE:
|
|
106 if (icqlink->icq_RecvChatReq)
|
|
107 (*icqlink->icq_RecvChatReq)(icqlink, pbase->uin,
|
|
108 ptime->tm_hour, ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
|
|
109 ptime->tm_year+1900, pmsgevent->message, pbase->id);
|
|
110 /* don't send an ack to the remote client! library client is
|
|
111 * responsible for sending the ack once the user accepts
|
|
112 * or denies the request */
|
|
113 break;
|
|
114 case ICQ_EVENT_ACK:
|
|
115 icq_HandleChatRequestAck(pbase, icqlink);
|
|
116 break;
|
|
117 case ICQ_EVENT_CANCEL:
|
|
118 /* TODO */
|
|
119 break;
|
|
120 default:
|
|
121 /* TODO */
|
|
122 break;
|
|
123 }
|
|
124 }
|
|
125
|
|
126 void icq_HandleChatRequestAck(icq_Event *pbase, icq_Link *icqlink)
|
|
127 {
|
|
128 icq_ChatRequestEvent *pevent=(icq_ChatRequestEvent *)pbase;
|
|
129 icq_TCPLink *pchatlink;
|
|
130 icq_ChatSession *pchat;
|
|
131 icq_Packet *p2;
|
|
132
|
|
133 /* once a chat request acknowledgement has been received, the remote
|
|
134 * client opens up a listening port for us. we need to connect to
|
|
135 * this port and all chat session communication takes place over
|
|
136 * this new tcp link */
|
|
137 pchatlink=icq_TCPLinkNew(icqlink);
|
|
138 pchatlink->type=TCP_LINK_CHAT;
|
|
139 pchatlink->id=pbase->id;
|
|
140
|
|
141 /* create a new chat session to manage the communication, and link
|
|
142 * it to the tcp link */
|
|
143 pchat=icq_ChatSessionNew(icqlink);
|
|
144 pchat->id=pbase->id;
|
|
145 pchat->remote_uin=pbase->uin;
|
|
146 pchatlink->session=pchat;
|
|
147
|
|
148 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_CONNECTING);
|
|
149
|
|
150 /* initiate the connection to the remote client's chat session
|
|
151 * port, which was specified in the ack event they sent */
|
|
152 icq_TCPLinkConnect(pchatlink, pbase->uin, pevent->port);
|
|
153
|
|
154 /* send off chat init event */
|
|
155 p2=icq_TCPCreateChatInfoPacket(pchatlink, icqlink->icq_Nick, 0x00ffffff,
|
|
156 0x00000000);
|
|
157 icq_TCPLinkSend(pchatlink, p2);
|
|
158 }
|
|
159
|
|
160
|
|
161 void icq_HandleFileRequestEvent(icq_Event *pbase, icq_Link *icqlink)
|
|
162 {
|
|
163 icq_FileRequestEvent *pevent=(icq_FileRequestEvent *)pbase;
|
|
164 icq_MessageEvent *pmsgevent=(icq_MessageEvent *)pmsgevent;
|
|
165 struct tm *ptime=localtime(&(pbase->time));
|
|
166
|
|
167 switch(pbase->subtype)
|
|
168 {
|
|
169 case ICQ_EVENT_MESSAGE:
|
|
170 if (icqlink->icq_RecvFileReq)
|
|
171 (*icqlink->icq_RecvFileReq)(icqlink, pbase->uin,
|
|
172 ptime->tm_hour, ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1,
|
|
173 ptime->tm_year+1900, pmsgevent->message, pevent->filename,
|
|
174 pevent->filesize, pbase->id);
|
|
175 /* don't send an ack to the remote client! library client is
|
|
176 * responsible for sending the ack once the user accepts
|
|
177 * or denies the request */
|
|
178 break;
|
|
179 case ICQ_EVENT_ACK:
|
|
180 icq_HandleFileRequestAck(pbase, icqlink);
|
|
181 break;
|
|
182 case ICQ_EVENT_CANCEL:
|
|
183 break;
|
|
184 default:
|
|
185 /* TODO */
|
|
186 break;
|
|
187 }
|
|
188 }
|
|
189
|
|
190 void icq_HandleFileRequestAck(icq_Event *pbase, icq_Link *icqlink)
|
|
191 {
|
|
192 icq_FileRequestEvent *pevent=(icq_FileRequestEvent *)pbase;
|
|
193 icq_TCPLink *pfilelink;
|
|
194 icq_FileSession *pfile;
|
|
195 icq_Packet *p2;
|
|
196
|
|
197 /* once a file request acknowledgement has been received, the remote
|
|
198 * client opens up a listening port for us. we need to connect to
|
|
199 * this port and all file transfer communication takes place over
|
|
200 * this new tcp link */
|
|
201 pfilelink=icq_TCPLinkNew(icqlink);
|
|
202 pfilelink->type=TCP_LINK_FILE;
|
|
203
|
|
204 /* a file session was created when the request was initially sent,
|
|
205 * but it wasn't attached to a tcp link because one did not exist.
|
|
206 * find the file sesion now and link it to the new tcp link */
|
|
207 pfile=icq_FindFileSession(icqlink, pbase->uin,
|
|
208 pbase->id); /* TODO: make sure find session succeeded */
|
|
209 pfile->tcplink=pfilelink;
|
|
210 pfilelink->id=pfile->id;
|
|
211 pfilelink->session=pfile;
|
|
212
|
|
213 /* notify the library client of the created file session */
|
|
214 if (icqlink->icq_RequestNotify)
|
|
215 (*icqlink->icq_RequestNotify)(icqlink, pfile->id,
|
|
216 ICQ_NOTIFY_FILESESSION, sizeof(icq_FileSession), pfile);
|
|
217 icq_FileSessionSetStatus(pfile, FILE_STATUS_CONNECTING);
|
|
218
|
|
219 /* initiate the connection to the remote client's file session
|
|
220 * port, which was specified in the ack event they sent */
|
|
221 icq_TCPLinkConnect(pfilelink, pbase->uin, pevent->port);
|
|
222
|
|
223 /* send off the file transfer init event */
|
|
224 /* TODO: convert file packets to events */
|
|
225 p2=icq_TCPCreateFile00Packet( pfile->total_files,
|
|
226 pfile->total_bytes, pfile->current_speed, icqlink->icq_Nick);
|
|
227 icq_TCPLinkSend(pfilelink, p2);
|
|
228 }
|
|
229
|
|
230
|
|
231 /*
|
|
232 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message type %d!\n", type);
|
|
233 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown packet command %d!\n",
|
|
234 command);
|
|
235
|
|
236 TODO: conversion
|
|
237 strncpy(data,message,512) ;
|
|
238 icq_RusConv("wk",data) ;
|
|
239
|
|
240
|
|
241 TODO: ack code
|
|
242
|
|
243 if(plink)
|
|
244 {
|
|
245 pack=icq_TCPCreateMessageAck(plink,0);
|
|
246 icq_PacketAppend32(pack, id);
|
|
247 icq_PacketSend(pack, plink->socket);
|
|
248 icq_PacketDelete(pack);
|
|
249 }
|
|
250 */
|