2086
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2
|
|
3 /*
|
|
4 * $Id: tcpchathandle.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 <stdlib.h>
|
|
26
|
|
27 #include "icqlib.h"
|
|
28
|
|
29 #include "stdpackets.h"
|
|
30 #include "chatsession.h"
|
|
31
|
|
32 void icq_HandleChatAck(icq_TCPLink *plink, icq_Packet *p, int port)
|
|
33 {
|
|
34 icq_TCPLink *pchatlink;
|
|
35 icq_ChatSession *pchat;
|
|
36 icq_Packet *p2;
|
|
37
|
|
38 pchatlink=icq_TCPLinkNew(plink->icqlink);
|
|
39 pchatlink->type=TCP_LINK_CHAT;
|
|
40 pchatlink->id=p->id;
|
|
41
|
|
42 /* once the ack packet has been processed, create a new chat session */
|
|
43 pchat=icq_ChatSessionNew(plink->icqlink);
|
|
44
|
|
45 pchat->id=p->id;
|
|
46 pchat->remote_uin=plink->remote_uin;
|
|
47 pchat->tcplink=pchatlink;
|
|
48
|
|
49 invoke_callback(plink->icqlink, icq_RequestNotify)(plink->icqlink, p->id,
|
|
50 ICQ_NOTIFY_CHATSESSION, sizeof(icq_ChatSession), pchat);
|
|
51
|
|
52 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_CONNECTING);
|
|
53 icq_TCPLinkConnect(pchatlink, plink->remote_uin, port);
|
|
54
|
|
55 pchatlink->session=pchat;
|
|
56
|
|
57 p2=icq_TCPCreateChatInfoPacket(pchatlink, plink->icqlink->icq_Nick,
|
|
58 0x00ffffff, 0x00000000);
|
|
59 icq_TCPLinkSend(pchatlink, p2);
|
|
60
|
|
61 }
|
|
62
|
|
63 void icq_HandleChatHello(icq_TCPLink *plink)
|
|
64 {
|
|
65
|
|
66 /* once the hello packet has been processed and we know which uin this
|
|
67 * link is for, we can link up with a chat session */
|
|
68 icq_ChatSession *pchat=icq_FindChatSession(plink->icqlink,
|
|
69 plink->remote_uin);
|
|
70
|
|
71 if(pchat)
|
|
72 {
|
|
73 plink->id=pchat->id;
|
|
74 plink->session=pchat;
|
|
75 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_WAIT_NAME);
|
|
76
|
|
77 } else {
|
|
78
|
|
79 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING,
|
|
80 "unexpected chat hello received from %d, closing link\n",
|
|
81 plink->remote_uin);
|
|
82 icq_TCPLinkClose(plink);
|
|
83 }
|
|
84
|
|
85 }
|
|
86
|
|
87 void icq_TCPOnChatReqReceived(icq_Link *icqlink, DWORD uin,
|
|
88 const char *message, DWORD id)
|
|
89 {
|
|
90 /* use the current system time for time received */
|
|
91 time_t t=time(0);
|
|
92 struct tm *ptime=localtime(&t);
|
|
93
|
|
94 #ifdef TCP_PACKET_TRACE
|
|
95 printf("chat request packet received from %lu { sequence=%lx, message=%s }\n",
|
|
96 uin, id, message);
|
|
97 #endif /* TCP_PACKET_TRACE */
|
|
98
|
|
99 invoke_callback(icqlink,icq_RecvChatReq)(icqlink, uin, ptime->tm_hour,
|
|
100 ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900,
|
|
101 message, id);
|
|
102
|
|
103 /* don't send an acknowledgement to the remote client!
|
|
104 * GUI is responsible for sending acknowledgement once user accepts
|
|
105 * or denies using icq_TCPSendChatAck */
|
|
106 }
|
|
107
|
|
108 void icq_TCPChatUpdateFont(icq_ChatSession *psession, const char *font,
|
|
109 WORD encoding, DWORD style, DWORD size)
|
|
110 {
|
|
111 icq_Link *icqlink = psession->icqlink;
|
|
112 int packet_len, fontlen;
|
|
113 char *buffer;
|
|
114
|
|
115 buffer = malloc(packet_len = (2 + (fontlen = strlen(font) + 1)) +
|
|
116 2 + 1 + (4+1)*2);
|
|
117 buffer[0] = '\x11';
|
|
118 *((DWORD *)&buffer[1]) = style;
|
|
119 buffer[5] = '\x12';
|
|
120 *((DWORD *)&buffer[6]) = size;
|
|
121 buffer[10] = '\x10';
|
|
122 *((WORD *)&buffer[11]) = fontlen;
|
|
123 strcpy(&buffer[13], font);
|
|
124
|
|
125 icq_RusConv("wk", &buffer[13]);
|
|
126
|
|
127 *((WORD *)&buffer[13 + fontlen]) = encoding;
|
|
128
|
|
129 invoke_callback(icqlink, icq_ChatNotify)(psession, CHAT_NOTIFY_DATA,
|
|
130 packet_len, buffer);
|
|
131
|
|
132 free(buffer);
|
|
133 }
|
|
134
|
|
135 void icq_TCPChatUpdateColors(icq_ChatSession *psession, DWORD foreground,
|
|
136 DWORD background)
|
|
137 {
|
|
138 icq_Link *icqlink = psession->icqlink;
|
|
139 char buffer[10];
|
|
140
|
|
141 buffer[0] = '\x00';
|
|
142 *((DWORD *)&buffer[1]) = foreground;
|
|
143 buffer[5] = '\x01';
|
|
144 *((DWORD *)&buffer[6]) = background;
|
|
145
|
|
146 invoke_callback(icqlink, icq_ChatNotify)(psession,
|
|
147 CHAT_NOTIFY_DATA, sizeof(buffer), buffer);
|
|
148 }
|
|
149
|
|
150 void icq_TCPProcessChatPacket(icq_Packet *p, icq_TCPLink *plink)
|
|
151 {
|
|
152 DWORD code;
|
|
153 DWORD remote_uin;
|
|
154 DWORD ip1, ip2;
|
|
155 DWORD fg, bg, fontstyle, fontsize;
|
|
156 WORD port1, encoding;
|
|
157 icq_Packet *presponse;
|
|
158 icq_ChatSession *pchat=(icq_ChatSession *)plink->session;
|
|
159 const char *font, *user;
|
|
160
|
|
161 icq_PacketBegin(p);
|
|
162
|
|
163 code=icq_PacketRead32(p);
|
|
164 remote_uin=icq_PacketRead32(p);
|
|
165
|
|
166 if(code==0x00000006 || code==0x00070004)
|
|
167 {
|
|
168 font = (char *)NULL;
|
|
169 encoding = 0;
|
|
170 fontstyle = 0;
|
|
171 fontsize = 0;
|
|
172 if(code == 0x00070004)
|
|
173 {
|
|
174 ip1 = icq_PacketRead32(p);
|
|
175 ip2 = icq_PacketRead32(p);
|
|
176 icq_PacketRead8(p);
|
|
177 port1 = icq_PacketRead16(p);
|
|
178 fontsize = icq_PacketRead32(p);
|
|
179 fontstyle = icq_PacketRead32(p);
|
|
180 font = icq_PacketReadString(p);
|
|
181 encoding = icq_PacketRead16(p);
|
|
182 }
|
|
183 else
|
|
184 {
|
|
185 ip1 = icq_PacketRead32(p);
|
|
186 ip2 = icq_PacketRead32(p);
|
|
187 port1 = icq_PacketRead16(p);
|
|
188 icq_PacketRead8(p);
|
|
189 fontsize = icq_PacketRead32(p);
|
|
190 fontstyle = icq_PacketRead32(p);
|
|
191 font = icq_PacketReadString(p);
|
|
192 encoding = icq_PacketRead16(p);
|
|
193 }
|
|
194 if(font)
|
|
195 icq_TCPChatUpdateFont(pchat, font, encoding, fontstyle, fontsize);
|
|
196 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_READY);
|
|
197 plink->mode|=TCP_LINK_MODE_RAW;
|
|
198 }
|
|
199 else
|
|
200 if(remote_uin>0xffffff00)
|
|
201 {
|
|
202 remote_uin=icq_PacketRead32(p);
|
|
203 user = icq_PacketReadString(p);
|
|
204 icq_PacketRead16(p); /* Unknown */;
|
|
205 fg = icq_PacketRead32(p);
|
|
206 bg = icq_PacketRead32(p);
|
|
207 icq_TCPChatUpdateColors(pchat, fg, bg);
|
|
208
|
|
209 presponse=icq_TCPCreateChatInfo2Packet(plink, plink->icqlink->icq_Nick,
|
|
210 0x00ffffff, 0x00000000);
|
|
211 icq_PacketSend(presponse, plink->socket);
|
|
212 icq_PacketDelete(presponse);
|
|
213 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_WAIT_FONT);
|
|
214 }
|
|
215 else
|
|
216 {
|
|
217 user = icq_PacketReadString(p);
|
|
218 fg = icq_PacketRead32(p);
|
|
219 bg = icq_PacketRead32(p);
|
|
220 icq_TCPChatUpdateColors(pchat, fg, bg);
|
|
221 font = (char *)NULL;
|
|
222 encoding = 0;
|
|
223 fontstyle = 0;
|
|
224 fontsize = 0;
|
|
225 if((code = icq_PacketRead32(p)) == 0x00070004)
|
|
226 {
|
|
227 icq_PacketRead32(p);
|
|
228 ip1 = icq_PacketRead32(p);
|
|
229 ip2 = icq_PacketRead32(p);
|
|
230 icq_PacketRead8(p);
|
|
231 port1 = icq_PacketRead16(p);
|
|
232 fontsize = icq_PacketRead32(p);
|
|
233 fontstyle = icq_PacketRead32(p);
|
|
234 font = icq_PacketReadString(p);
|
|
235 encoding = icq_PacketRead16(p);
|
|
236 }
|
|
237 else if(code == 0x00000006)
|
|
238 {
|
|
239 icq_PacketRead32(p);
|
|
240 ip1 = icq_PacketRead32(p);
|
|
241 ip2 = icq_PacketRead32(p);
|
|
242 port1 = icq_PacketRead16(p);
|
|
243 icq_PacketRead8(p);
|
|
244 fontsize = icq_PacketRead32(p);
|
|
245 fontstyle = icq_PacketRead32(p);
|
|
246 font = icq_PacketReadString(p);
|
|
247 encoding = icq_PacketRead16(p);
|
|
248 }
|
|
249 if(font)
|
|
250 icq_TCPChatUpdateFont(pchat, font, encoding, fontstyle, fontsize);
|
|
251 presponse=icq_TCPCreateChatFontInfoPacket(plink);
|
|
252 icq_PacketSend(presponse, plink->socket);
|
|
253 icq_PacketDelete(presponse);
|
|
254 /* notify app that chat connection has been established */
|
|
255 icq_ChatSessionSetStatus(pchat, CHAT_STATUS_READY);
|
|
256 plink->mode|=TCP_LINK_MODE_RAW;
|
|
257 }
|
|
258 }
|
|
259
|