Wed, 01 Oct 2003 07:15:53 +0000
[gaim-migrate @ 7673]
Put the rest of util.[ch] into namespaces and sectioned off the functions.
| 2086 | 1 | /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| 2 | ||
| 3 | /* | |
| 4 | * $Id: tcphandle.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 "tcp.h" | |
| 30 | #include "stdpackets.h" | |
| 31 | ||
| 32 | void icq_TCPOnMessageReceived(icq_Link *icqlink, DWORD uin, const char *message, DWORD id, icq_TCPLink *plink); | |
| 33 | void icq_TCPOnURLReceived(icq_Link *icqlink, DWORD uin, const char *message, DWORD id); | |
| 34 | void icq_TCPOnContactListReceived(icq_Link *icqlink, DWORD uin, const char *message, DWORD id); | |
| 35 | void icq_TCPOnChatReqReceived(icq_Link *icqlink, DWORD uin, const char *message, DWORD id); | |
| 36 | void icq_TCPOnFileReqReceived(icq_Link *icqlink, DWORD uin, const char *message, | |
| 37 | const char *filename, unsigned long filesize, DWORD id); | |
| 38 | void icq_TCPProcessAck(icq_Link *icqlink, icq_Packet *p); | |
| 39 | void icq_HandleChatAck(icq_TCPLink *plink, icq_Packet *p, int port); | |
| 40 | void icq_HandleChatHello(icq_TCPLink *plink); | |
| 41 | void icq_HandleFileHello(icq_TCPLink *plink); | |
| 42 | void icq_HandleFileAck(icq_TCPLink *plink, icq_Packet *p, int port); | |
| 43 | ||
| 44 | void icq_TCPProcessPacket(icq_Packet *p, icq_TCPLink *plink) | |
| 45 | { | |
| 46 | DWORD uin; | |
| 47 | WORD version; | |
| 48 | WORD command; | |
| 49 | WORD type; | |
| 50 | WORD status; | |
| 51 | DWORD command_type; | |
| 52 | DWORD filesize = 0; | |
| 53 | DWORD port = 0; | |
| 54 | ||
| 55 | const char *message; | |
| 56 | const char *filename = 0; | |
| 57 | ||
| 58 | icq_PacketBegin(p); | |
| 59 | (void)icq_PacketRead32(p); | |
| 60 | version=icq_PacketRead16(p); | |
| 61 | command=icq_PacketRead16(p); | |
| 62 | (void)icq_PacketRead16(p); | |
| 63 | ||
| 64 | uin=icq_PacketRead32(p); | |
| 65 | type=icq_PacketRead16(p); | |
| 66 | message=icq_PacketReadString(p); | |
| 67 | (void)icq_PacketRead32(p); | |
| 68 | (void)icq_PacketRead32(p); | |
| 69 | (void)icq_PacketRead32(p); | |
| 70 | (void)icq_PacketRead8(p); | |
| 71 | status=icq_PacketRead16(p); | |
| 72 | command_type=icq_PacketRead16(p); | |
| 73 | ||
| 74 | switch(type & ~ICQ_TCP_MASS_MASK) | |
| 75 | { | |
| 76 | case ICQ_TCP_MSG_MSG: | |
| 77 | case ICQ_TCP_MSG_URL: | |
| 78 | case ICQ_TCP_MSG_CONTACTLIST: | |
| 79 | case ICQ_TCP_MSG_READAWAY: | |
| 80 | case ICQ_TCP_MSG_READNA: | |
| 81 | case ICQ_TCP_MSG_READDND: | |
| 82 | case ICQ_TCP_MSG_READOCCUPIED: | |
| 83 | case ICQ_TCP_MSG_READFFC: | |
| 84 | p->id=icq_PacketRead32(p); | |
| 85 | break; | |
| 86 | ||
| 87 | case ICQ_TCP_MSG_CHAT: | |
| 88 | (void)icq_PacketReadString(p); | |
| 89 | (void)icq_PacketRead16(p); | |
| 90 | (void)icq_PacketRead16(p); | |
| 91 | port=icq_PacketRead32(p); | |
| 92 | p->id=icq_PacketRead32(p); | |
| 93 | break; | |
| 94 | ||
| 95 | case ICQ_TCP_MSG_FILE: | |
| 96 | (void)icq_PacketRead16(p); | |
| 97 | (void)icq_PacketRead16(p); | |
| 98 | filename=icq_PacketReadString(p); | |
| 99 | filesize=icq_PacketRead32(p); | |
| 100 | port=icq_PacketRead32(p); | |
| 101 | p->id=icq_PacketRead32(p); | |
| 102 | break; | |
| 103 | ||
| 104 | default: | |
| 105 | icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message packet, type %x\n", type); | |
| 106 | } | |
| 107 | ||
| 108 | #ifdef TCP_PROCESS_TRACE | |
| 109 | printf("packet processed from uin: %lu:\n", uin); | |
| 110 | printf(" command: %x\ttype: %x\n", command, type); | |
| 111 | printf(" status: %x\tcommand_type: %x\n", status, (int)command_type); | |
| 112 | printf(" message %s\n", message); | |
| 113 | printf(" id: %x\n", (int)p->id); | |
| 114 | #endif | |
| 115 | ||
| 116 | switch(command) | |
| 117 | { | |
| 118 | case ICQ_TCP_MESSAGE: | |
| 119 | switch(type & ~ICQ_TCP_MASS_MASK) | |
| 120 | { | |
| 121 | case ICQ_TCP_MSG_MSG: | |
| 122 | icq_TCPOnMessageReceived(plink->icqlink, uin, message, p->id, plink); | |
| 123 | break; | |
| 124 | ||
| 125 | case ICQ_TCP_MSG_URL: | |
| 126 | icq_TCPOnURLReceived(plink->icqlink, uin, message, p->id); | |
| 127 | break; | |
| 128 | ||
| 129 | case ICQ_TCP_MSG_CHAT: | |
| 130 | icq_TCPOnChatReqReceived(plink->icqlink, uin, message, p->id); | |
| 131 | break; | |
| 132 | ||
| 133 | case ICQ_TCP_MSG_FILE: | |
| 134 | icq_TCPOnFileReqReceived(plink->icqlink, uin, message, filename, filesize, p->id); | |
| 135 | break; | |
| 136 | ||
| 137 | case ICQ_TCP_MSG_CONTACTLIST: | |
| 138 | icq_TCPOnContactListReceived(plink->icqlink, uin, message, p->id); | |
| 139 | break; | |
| 140 | ||
| 141 | default: | |
| 142 | icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message type %d!\n", type); | |
| 143 | break; | |
| 144 | } | |
| 145 | break; | |
| 146 | ||
| 147 | case ICQ_TCP_ACK: | |
| 148 | invoke_callback(plink->icqlink, icq_RequestNotify) | |
| 149 | (plink->icqlink, p->id, ICQ_NOTIFY_ACK, status, (void *)message); | |
| 150 | switch(type) | |
| 151 | { | |
| 152 | case ICQ_TCP_MSG_CHAT: | |
| 153 | icq_HandleChatAck(plink, p, port); | |
| 154 | break; | |
| 155 | ||
| 156 | case ICQ_TCP_MSG_FILE: | |
| 157 | icq_HandleFileAck(plink, p, port); | |
| 158 | break; | |
| 159 | ||
| 160 | case ICQ_TCP_MSG_MSG: | |
| 161 | case ICQ_TCP_MSG_URL: | |
| 162 | icq_FmtLog(plink->icqlink, ICQ_LOG_MESSAGE, "received ack %d\n", | |
| 163 | p->id); | |
| 164 | break; | |
| 165 | ||
| 166 | case ICQ_TCP_MSG_READAWAY: | |
| 167 | case ICQ_TCP_MSG_READNA: | |
| 168 | case ICQ_TCP_MSG_READDND: | |
| 169 | case ICQ_TCP_MSG_READOCCUPIED: | |
| 170 | case ICQ_TCP_MSG_READFFC: | |
| 171 | icq_FmtLog(plink->icqlink, ICQ_LOG_MESSAGE, | |
| 172 | "received away msg, seq %d\n", p->id); | |
| 173 | invoke_callback(plink->icqlink, icq_RecvAwayMsg) | |
| 174 | (plink->icqlink, p->id, message); | |
| 175 | break; | |
| 176 | } | |
| 177 | invoke_callback(plink->icqlink, icq_RequestNotify) | |
| 178 | (plink->icqlink, p->id, ICQ_NOTIFY_SUCCESS, 0, NULL); | |
| 179 | break; | |
| 180 | ||
| 181 | case ICQ_TCP_CANCEL: | |
| 182 | /* icq_TCPProcessCancel(p); */ | |
| 183 | break; | |
| 184 | ||
| 185 | default: | |
| 186 | icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, | |
| 187 | "unknown packet command %d!\n", command); | |
| 188 | } | |
| 189 | } | |
| 190 | ||
| 191 | void icq_TCPProcessCancel(icq_Packet *p) | |
| 192 | { | |
| 193 | (void)p; | |
| 194 | ||
| 195 | /* | |
| 196 | find packet in queue | |
| 197 | call notification function | |
| 198 | remove packet from queue | |
| 199 | */ | |
| 200 | } | |
| 201 | ||
| 202 | int icq_TCPProcessHello(icq_Packet *p, icq_TCPLink *plink) | |
| 203 | { | |
| 204 | /* TCP Hello packet */ | |
| 205 | BYTE code; /* 0xFF - init packet code */ | |
| 206 | DWORD version; /* tcp version */ | |
| 207 | DWORD remote_port; /* remote message listen port */ | |
| 208 | DWORD remote_uin; /* remote uin */ | |
| 209 | DWORD remote_ip; /* remote IP as seen by ICQ server */ | |
| 210 | DWORD remote_real_ip; /* remote IP as seen by client */ | |
| 211 | BYTE flags; /* tcp flags */ | |
| 212 | DWORD remote_other_port; /* remote chat or file listen port */ | |
| 213 | ||
| 214 | icq_PacketBegin(p); | |
| 215 | ||
| 216 | code=icq_PacketRead8(p); | |
| 217 | version=icq_PacketRead32(p); | |
| 218 | ||
| 219 | if (!(p->length>=26 && code==ICQ_TCP_HELLO)) | |
| 220 | { | |
| 221 | icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, | |
| 222 | "malformed hello packet received from %s:%d, closing link\n", | |
| 223 | inet_ntoa(*((struct in_addr *)(&(plink->remote_address.sin_addr)))), | |
| 224 | ntohs(plink->remote_address.sin_port)); | |
| 225 | ||
| 226 | icq_TCPLinkClose(plink); | |
| 227 | return 0; | |
| 228 | } | |
| 229 | remote_port=icq_PacketRead32(p); | |
| 230 | remote_uin=icq_PacketRead32(p); | |
| 231 | remote_ip=icq_PacketRead32(p); | |
| 232 | remote_real_ip=icq_PacketRead32(p); | |
| 233 | flags=icq_PacketRead8(p); | |
| 234 | remote_other_port=icq_PacketRead32(p); | |
| 235 | ||
| 236 | icq_FmtLog(plink->icqlink, ICQ_LOG_MESSAGE, | |
| 237 | "hello packet received from %lu { version=%d }\n", remote_uin, version); | |
| 238 | ||
| 239 | plink->remote_version=version; | |
| 240 | plink->remote_uin=remote_uin; | |
| 241 | plink->flags=flags; | |
| 242 | plink->mode&=~TCP_LINK_MODE_HELLOWAIT; | |
| 243 | ||
| 244 | /* file and chat sessions require additional handling */ | |
| 245 | if(plink->type==TCP_LINK_CHAT) icq_HandleChatHello(plink); | |
| 246 | if(plink->type==TCP_LINK_FILE) icq_HandleFileHello(plink); | |
| 247 | ||
| 248 | return 1; | |
| 249 | } | |
| 250 | ||
| 251 | void icq_TCPOnMessageReceived(icq_Link *icqlink, DWORD uin, const char *message, DWORD id, icq_TCPLink *plink) | |
| 252 | { | |
| 253 | char data[ICQ_MAX_MESSAGE_SIZE]; | |
| 254 | ||
| 255 | /* use the current system time for time received */ | |
| 256 | time_t t=time(0); | |
| 257 | struct tm *ptime=localtime(&t); | |
| 258 | icq_Packet *pack; | |
| 259 | ||
| 260 | #ifdef TCP_PACKET_TRACE | |
| 261 | printf("tcp message packet received from %lu { sequence=%x }\n", | |
| 262 | uin, (int)id); | |
| 263 | #endif | |
| 264 | ||
| 265 | strncpy(data,message,sizeof(data)); | |
| 266 | data[sizeof(data)-1]='\0'; | |
| 267 | icq_RusConv("wk",data); | |
| 268 | ||
| 269 | invoke_callback(icqlink,icq_RecvMessage)(icqlink, uin, ptime->tm_hour, | |
| 270 | ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, data); | |
| 271 | ||
| 272 | /* | |
| 273 | icq_TCPLink *preallink=icq_FindTCPLink(icqlink, uin, TCP_LINK_MESSAGE); | |
| 274 | if(plink != preallink) | |
| 275 | invoke_callback(icqlink,icq_SpoofedMessage)(uin, ...) | |
| 276 | */ | |
| 277 | ||
| 278 | /* send an acknowledgement to the remote client */ | |
| 279 | pack=icq_TCPCreateMessageAck(plink,0); | |
| 280 | icq_PacketAppend32(pack, id); | |
| 281 | icq_PacketSend(pack, plink->socket); | |
| 282 | #ifdef TCP_PACKET_TRACE | |
| 283 | printf("tcp message ack sent to uin %lu { sequence=%lx }\n", uin, id); | |
| 284 | #endif | |
| 285 | icq_PacketDelete(pack); | |
| 286 | } | |
| 287 | ||
| 288 | void icq_TCPOnURLReceived(icq_Link *icqlink, DWORD uin, const char *message, DWORD id) | |
| 289 | { | |
| 290 | /* use the current system time for time received */ | |
| 291 | time_t t=time(0); | |
| 292 | struct tm *ptime=localtime(&t); | |
| 293 | icq_Packet *pack; | |
| 294 | char *pfe; | |
| 295 | icq_TCPLink *plink=icq_FindTCPLink(icqlink, uin, TCP_LINK_MESSAGE); | |
| 296 | ||
| 297 | #ifdef TCP_PACKET_TRACE | |
| 298 | printf("tcp url packet received from %lu { sequence=%lx }\n", | |
| 299 | uin, id); | |
| 300 | #endif /*TCP_PACKET_TRACE*/ | |
| 301 | ||
| 302 | /* the URL is split from the description by 0xFE */ | |
| 303 | pfe=strchr(message, '\xFE'); | |
| 304 | *pfe=0; | |
| 305 | icq_RusConv("wk", (char*)message); | |
| 306 | ||
| 307 | invoke_callback(icqlink,icq_RecvURL)(icqlink, uin, ptime->tm_hour, | |
| 308 | ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, | |
| 309 | pfe+1, message); | |
| 310 | ||
| 311 | /* send an acknowledgement to the remote client */ | |
| 312 | pack=icq_TCPCreateURLAck(plink,0); | |
| 313 | icq_PacketAppend32(pack, id); | |
| 314 | icq_PacketSend(pack, plink->socket); | |
| 315 | #ifdef TCP_PACKET_TRACE | |
| 316 | printf("tcp message ack sent to %lu { sequence=%lx }\n", uin, id); | |
| 317 | #endif | |
| 318 | icq_PacketDelete(pack); | |
| 319 | } | |
| 320 | ||
| 321 | void icq_TCPOnContactListReceived(icq_Link *icqlink, DWORD uin, const char *message, DWORD id) | |
| 322 | { | |
| 323 | /* use the current system time for time received */ | |
| 324 | time_t t=time(0); | |
| 325 | struct tm *ptime=localtime(&t); | |
| 326 | icq_Packet *pack; | |
| 327 | icq_List *strList = icq_ListNew(); | |
| 328 | int i, k, nr = icq_SplitFields(strList, message); | |
| 329 | const char **contact_uin = (const char **)malloc((nr - 2) /2); | |
| 330 | const char **contact_nick = (const char **)malloc((nr - 2) /2); | |
| 331 | icq_TCPLink *plink=icq_FindTCPLink(icqlink, uin, TCP_LINK_MESSAGE); | |
| 332 | ||
| 333 | #ifdef TCP_PACKET_TRACE | |
| 334 | printf("tcp contactlist packet received from %lu { sequence=%lx }\n", uin, id); | |
| 335 | #endif /* TCP_PACKET_TRACE */ | |
| 336 | ||
| 337 | /* split message */ | |
| 338 | for (i = 1, k = 0; i < (nr - 1); k++) | |
| 339 | { | |
| 340 | contact_uin[k] = icq_ListAt(strList, i); | |
| 341 | contact_nick[k] = icq_ListAt(strList, i + 1); | |
| 342 | i += 2; | |
| 343 | } | |
| 344 | ||
| 345 | invoke_callback(icqlink,icq_RecvContactList)(icqlink, uin, | |
| 346 | ptime->tm_hour, ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1, | |
| 347 | ptime->tm_year+1900, k, contact_uin, contact_nick); | |
| 348 | ||
| 349 | /* send an acknowledement to the remote client */ | |
| 350 | pack=icq_TCPCreateContactListAck(plink, 0); | |
| 351 | icq_PacketAppend32(pack, id); | |
| 352 | icq_PacketSend(pack, plink->socket); | |
| 353 | #ifdef TCP_PACKET_TRACE | |
| 354 | printf("tcp message ack sent to %lu { sequence=%lx }\n", uin, id); | |
| 355 | #endif /* TCP_PACKE_TRACE */ | |
| 356 | icq_PacketDelete(pack); | |
| 357 | ||
| 358 | free(contact_nick); | |
| 359 | free(contact_uin); | |
| 360 | icq_ListDelete(strList, free); | |
| 361 | } |