1152
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2 /*
|
|
3 $Id: tcpchathandle.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.8 2000/07/24 03:10:08 bills
|
|
9 added support for real nickname during TCP transactions like file and
|
|
10 chat, instead of using Bill all the time (hmm, where'd I get that from? :)
|
|
11
|
|
12 Revision 1.7 2000/07/09 22:19:35 bills
|
|
13 added new *Close functions, use *Close functions instead of *Delete
|
|
14 where correct, and misc cleanup
|
|
15
|
|
16 Revision 1.6 2000/05/04 15:57:20 bills
|
|
17 Reworked file transfer notification, small bugfixes, and cleanups.
|
|
18
|
|
19 Revision 1.5 2000/05/03 18:29:15 denis
|
|
20 Callbacks have been moved to the ICQLINK structure.
|
|
21
|
|
22 Revision 1.4 2000/04/05 14:37:02 denis
|
|
23 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
|
|
24 compatibility.
|
|
25
|
|
26 Revision 1.3 2000/02/07 02:54:45 bills
|
|
27 warning cleanups.
|
|
28
|
|
29 Revision 1.2 2000/02/07 02:43:37 bills
|
|
30 new code for special chat functions (background, fonts, etc)
|
|
31
|
|
32 Revision 1.1 1999/09/29 19:47:21 bills
|
|
33 reworked chat/file handling. fixed chat. (it's been broke since I put
|
|
34 non-blocking connects in)
|
|
35
|
|
36 */
|
|
37
|
|
38 #include <time.h>
|
|
39
|
|
40 #ifndef _WIN32
|
|
41 #include <unistd.h>
|
|
42 #endif
|
|
43
|
|
44 #include <stdlib.h>
|
|
45
|
|
46 #include "icqtypes.h"
|
|
47 #include "icq.h"
|
|
48 #include "icqlib.h"
|
|
49
|
|
50 #include "stdpackets.h"
|
|
51 #include "tcplink.h"
|
|
52 #include "chatsession.h"
|
|
53
|
|
54 void icq_HandleChatAck(icq_TCPLink *plink, icq_Packet *p, int port)
|
|
55 {
|
|
56 icq_TCPLink *pchatlink;
|
|
57 icq_ChatSession *pchat;
|
|
58 icq_Packet *p2;
|
|
59
|
|
60 if(plink->icqlink->icq_RequestNotify)
|
|
61 (*plink->icqlink->icq_RequestNotify)(plink->icqlink, p->id, ICQ_NOTIFY_ACK, 0, 0);
|
|
62 pchatlink=icq_TCPLinkNew(plink->icqlink);
|
|
63 pchatlink->type=TCP_LINK_CHAT;
|
|
64 pchatlink->id=p->id;
|
|
65
|
|
66 pchat=icq_ChatSessionNew(plink->icqlink);
|
|
67 pchat->id=p->id;
|
|
68 pchat->remote_uin=plink->remote_uin;
|
|
69 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_CONNECTING);
|
|
70 icq_TCPLinkConnect(pchatlink, plink->remote_uin, port);
|
|
71
|
|
72 pchatlink->session=pchat;
|
|
73
|
|
74 p2=icq_TCPCreateChatInfoPacket(pchatlink, plink->icqlink->icq_Nick,
|
|
75 0x00ffffff, 0x00000000);
|
|
76 icq_TCPLinkSend(pchatlink, p2);
|
|
77
|
|
78 }
|
|
79
|
|
80 void icq_HandleChatHello(icq_TCPLink *plink)
|
|
81 {
|
|
82
|
|
83 /* once the hello packet has been processed and we know which uin this
|
|
84 * link is for, we can link up with a chat session */
|
|
85 icq_ChatSession *pchat=icq_FindChatSession(plink->icqlink,
|
|
86 plink->remote_uin);
|
|
87
|
|
88 if(pchat)
|
|
89 {
|
|
90 plink->id=pchat->id;
|
|
91 plink->session=pchat;
|
|
92 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_WAIT_NAME);
|
|
93
|
|
94 } else {
|
|
95
|
|
96 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING,
|
|
97 "unexpected chat hello received from %d, closing link\n",
|
|
98 plink->remote_uin);
|
|
99 icq_TCPLinkClose(plink);
|
|
100 }
|
|
101
|
|
102 }
|
|
103
|
|
104 void icq_TCPOnChatReqReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id)
|
|
105 {
|
|
106 #ifdef TCP_PACKET_TRACE
|
|
107 printf("chat request packet received from %lu { sequence=%lx, message=%s }\n",
|
|
108 uin, id, message);
|
|
109 #endif /* TCP_PACKET_TRACE */
|
|
110
|
|
111 if(link->icq_RecvChatReq) {
|
|
112
|
|
113 /* use the current system time for time received */
|
|
114 time_t t=time(0);
|
|
115 struct tm *ptime=localtime(&t);
|
|
116
|
|
117 (*link->icq_RecvChatReq)(link, uin, ptime->tm_hour, ptime->tm_min,
|
|
118 ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, message, id);
|
|
119
|
|
120 /* don't send an acknowledgement to the remote client!
|
|
121 * GUI is responsible for sending acknowledgement once user accepts
|
|
122 * or denies using icq_TCPSendChatAck */
|
|
123 }
|
|
124 }
|
|
125
|
|
126 void icq_TCPChatUpdateFont(icq_TCPLink *plink, const char *font, WORD encoding, DWORD style, DWORD size)
|
|
127 {
|
|
128 int packet_len, fontlen;
|
|
129 char *buffer;
|
|
130 if(!plink->icqlink->icq_RequestNotify)
|
|
131 return;
|
|
132 buffer = malloc(packet_len = (2 + (fontlen = strlen(font) + 1)) + 2 + 1 + (4+1)*2);
|
|
133 buffer[0] = '\x11';
|
|
134 *((DWORD *)&buffer[1]) = style;
|
|
135 buffer[5] = '\x12';
|
|
136 *((DWORD *)&buffer[6]) = size;
|
|
137 buffer[10] = '\x10';
|
|
138 *((WORD *)&buffer[11]) = fontlen;
|
|
139 strcpy(&buffer[13], font);
|
|
140 icq_RusConv("wk", &buffer[13]);
|
|
141 *((WORD *)&buffer[13 + fontlen]) = encoding;
|
|
142 if(plink->icqlink->icq_RequestNotify)
|
|
143 (*plink->icqlink->icq_RequestNotify)(plink->icqlink, plink->id, ICQ_NOTIFY_CHATDATA, packet_len, buffer);
|
|
144 free(buffer);
|
|
145 }
|
|
146
|
|
147 void icq_TCPChatUpdateColors(icq_TCPLink *plink, DWORD foreground, DWORD background)
|
|
148 {
|
|
149 char buffer[10];
|
|
150
|
|
151 if(!plink->icqlink->icq_RequestNotify)
|
|
152 return;
|
|
153 buffer[0] = '\x00';
|
|
154 *((DWORD *)&buffer[1]) = foreground;
|
|
155 buffer[5] = '\x01';
|
|
156 *((DWORD *)&buffer[6]) = background;
|
|
157 if(plink->icqlink->icq_RequestNotify)
|
|
158 (*plink->icqlink->icq_RequestNotify)(plink->icqlink, plink->id, ICQ_NOTIFY_CHATDATA,
|
|
159 sizeof(buffer), buffer);
|
|
160 }
|
|
161
|
|
162 void icq_TCPProcessChatPacket(icq_Packet *p, icq_TCPLink *plink)
|
|
163 {
|
|
164 DWORD code;
|
|
165 DWORD remote_uin;
|
|
166 DWORD ip1, ip2;
|
|
167 DWORD fg, bg, fontstyle, fontsize;
|
|
168 WORD port1, encoding;
|
|
169 icq_Packet *presponse;
|
|
170 icq_ChatSession *pchat=(icq_ChatSession *)plink->session;
|
|
171 const char *font, *user;
|
|
172
|
|
173 icq_PacketBegin(p);
|
|
174
|
|
175 code=icq_PacketRead32(p);
|
|
176 remote_uin=icq_PacketRead32(p);
|
|
177
|
|
178 if(code==0x00000006 || code==0x00070004)
|
|
179 {
|
|
180 font = (char *)NULL;
|
|
181 encoding = 0;
|
|
182 fontstyle = 0;
|
|
183 fontsize = 0;
|
|
184 if(code == 0x00070004)
|
|
185 {
|
|
186 ip1 = icq_PacketRead32(p);
|
|
187 ip2 = icq_PacketRead32(p);
|
|
188 icq_PacketRead8(p);
|
|
189 port1 = icq_PacketRead16(p);
|
|
190 fontsize = icq_PacketRead32(p);
|
|
191 fontstyle = icq_PacketRead32(p);
|
|
192 font = icq_PacketReadString(p);
|
|
193 encoding = icq_PacketRead16(p);
|
|
194 }
|
|
195 else
|
|
196 {
|
|
197 ip1 = icq_PacketRead32(p);
|
|
198 ip2 = icq_PacketRead32(p);
|
|
199 port1 = icq_PacketRead16(p);
|
|
200 icq_PacketRead8(p);
|
|
201 fontsize = icq_PacketRead32(p);
|
|
202 fontstyle = icq_PacketRead32(p);
|
|
203 font = icq_PacketReadString(p);
|
|
204 encoding = icq_PacketRead16(p);
|
|
205 }
|
|
206 if(font)
|
|
207 icq_TCPChatUpdateFont(plink, font, encoding, fontstyle, fontsize);
|
|
208 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_READY);
|
|
209 plink->mode|=TCP_LINK_MODE_RAW;
|
|
210 }
|
|
211 else
|
|
212 if(remote_uin>0xffffff00)
|
|
213 {
|
|
214 remote_uin=icq_PacketRead32(p);
|
|
215 user = icq_PacketReadString(p);
|
|
216 icq_PacketRead16(p); /* Unknown */;
|
|
217 fg = icq_PacketRead32(p);
|
|
218 bg = icq_PacketRead32(p);
|
|
219 icq_TCPChatUpdateColors(plink, fg, bg);
|
|
220
|
|
221 presponse=icq_TCPCreateChatInfo2Packet(plink, plink->icqlink->icq_Nick,
|
|
222 0x00ffffff, 0x00000000);
|
|
223 icq_PacketSend(presponse, plink->socket);
|
|
224 icq_PacketDelete(presponse);
|
|
225 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_WAIT_FONT);
|
|
226 }
|
|
227 else
|
|
228 {
|
|
229 user = icq_PacketReadString(p);
|
|
230 fg = icq_PacketRead32(p);
|
|
231 bg = icq_PacketRead32(p);
|
|
232 icq_TCPChatUpdateColors(plink, fg, bg);
|
|
233 font = (char *)NULL;
|
|
234 encoding = 0;
|
|
235 fontstyle = 0;
|
|
236 fontsize = 0;
|
|
237 if((code = icq_PacketRead32(p)) == 0x00070004)
|
|
238 {
|
|
239 icq_PacketRead32(p);
|
|
240 ip1 = icq_PacketRead32(p);
|
|
241 ip2 = icq_PacketRead32(p);
|
|
242 icq_PacketRead8(p);
|
|
243 port1 = icq_PacketRead16(p);
|
|
244 fontsize = icq_PacketRead32(p);
|
|
245 fontstyle = icq_PacketRead32(p);
|
|
246 font = icq_PacketReadString(p);
|
|
247 encoding = icq_PacketRead16(p);
|
|
248 }
|
|
249 else if(code == 0x00000006)
|
|
250 {
|
|
251 icq_PacketRead32(p);
|
|
252 ip1 = icq_PacketRead32(p);
|
|
253 ip2 = icq_PacketRead32(p);
|
|
254 port1 = icq_PacketRead16(p);
|
|
255 icq_PacketRead8(p);
|
|
256 fontsize = icq_PacketRead32(p);
|
|
257 fontstyle = icq_PacketRead32(p);
|
|
258 font = icq_PacketReadString(p);
|
|
259 encoding = icq_PacketRead16(p);
|
|
260 }
|
|
261 if(font)
|
|
262 icq_TCPChatUpdateFont(plink, font, encoding, fontstyle, fontsize);
|
|
263 presponse=icq_TCPCreateChatFontInfoPacket(plink);
|
|
264 icq_PacketSend(presponse, plink->socket);
|
|
265 icq_PacketDelete(presponse);
|
|
266 /* notify app that chat connection has been established */
|
|
267 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_READY);
|
|
268 plink->mode|=TCP_LINK_MODE_RAW;
|
|
269 }
|
|
270 }
|
|
271
|