Mercurial > pidgin
annotate src/protocols/toc/toc.c @ 2138:cfa83a1b3d49
[gaim-migrate @ 2148]
hopefully fixes any problems we might have with icq. also makes it so we can receive messages from people whose names are longer than 64 characters. this should be arbitrary.
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Wed, 08 Aug 2001 20:09:57 +0000 |
| parents | 18722ae5b882 |
| children | 42e8e44f5c40 |
| rev | line source |
|---|---|
| 2086 | 1 /* |
| 2 * gaim | |
| 3 * | |
| 4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
| 5 * | |
| 6 * This program is free software; you can redistribute it and/or modify | |
| 7 * it under the terms of the GNU General Public License as published by | |
| 8 * the Free Software Foundation; either version 2 of the License, or | |
| 9 * (at your option) any later version. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License | |
| 17 * along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 * | |
| 20 */ | |
| 21 | |
| 22 | |
| 23 | |
| 24 #ifdef HAVE_CONFIG_H | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
25 #include <config.h> |
| 2086 | 26 #endif |
| 27 #include <netdb.h> | |
| 28 #include <gtk/gtk.h> | |
| 29 #include <unistd.h> | |
| 30 #include <errno.h> | |
| 31 #include <netinet/in.h> | |
| 32 #include <arpa/inet.h> | |
| 33 #include <string.h> | |
| 34 #include <stdlib.h> | |
| 35 #include <stdio.h> | |
| 36 #include <time.h> | |
| 37 #include <sys/socket.h> | |
| 38 #include <sys/types.h> | |
| 39 #include <sys/stat.h> | |
| 40 #include "prpl.h" | |
| 41 #include "multi.h" | |
| 42 #include "gaim.h" | |
| 43 #include "proxy.h" | |
| 44 | |
| 45 #include "pixmaps/admin_icon.xpm" | |
| 46 #include "pixmaps/aol_icon.xpm" | |
| 47 #include "pixmaps/away_icon.xpm" | |
| 48 #include "pixmaps/dt_icon.xpm" | |
| 49 #include "pixmaps/free_icon.xpm" | |
| 50 | |
| 51 #define REVISION "penguin" | |
| 52 | |
| 53 #define TYPE_SIGNON 1 | |
| 54 #define TYPE_DATA 2 | |
| 55 #define TYPE_ERROR 3 | |
| 56 #define TYPE_SIGNOFF 4 | |
| 57 #define TYPE_KEEPALIVE 5 | |
| 58 | |
| 59 #define FLAPON "FLAPON\r\n\r\n" | |
| 60 #define ROAST "Tic/Toc" | |
| 61 | |
| 62 #define TOC_HOST "toc.oscar.aol.com" | |
| 63 #define TOC_PORT 9898 | |
| 64 #define AUTH_HOST "login.oscar.aol.com" | |
| 65 #define AUTH_PORT 5190 | |
| 66 #define LANGUAGE "english" | |
| 67 | |
| 68 #define STATE_OFFLINE 0 | |
| 69 #define STATE_FLAPON 1 | |
| 70 #define STATE_SIGNON_REQUEST 2 | |
| 71 #define STATE_ONLINE 3 | |
| 72 #define STATE_PAUSE 4 | |
| 73 | |
| 74 #define VOICE_UID "09461341-4C7F-11D1-8222-444553540000" | |
| 75 #define FILE_SEND_UID "09461343-4C7F-11D1-8222-444553540000" | |
| 76 #define IMAGE_UID "09461345-4C7F-11D1-8222-444553540000" | |
| 77 #define B_ICON_UID "09461346-4C7F-11D1-8222-444553540000" | |
| 78 #define STOCKS_UID "09461347-4C7F-11D1-8222-444553540000" | |
| 79 #define FILE_GET_UID "09461348-4C7F-11D1-8222-444553540000" | |
| 80 #define GAMES_UID "0946134a-4C7F-11D1-8222-444553540000" | |
| 81 | |
| 82 struct ft_request { | |
| 83 struct gaim_connection *gc; | |
| 84 char *user; | |
| 85 char UID[2048]; | |
| 86 char *cookie; | |
| 87 char *ip; | |
| 88 int port; | |
| 89 char *message; | |
| 90 char *filename; | |
| 91 int files; | |
| 92 int size; | |
| 93 }; | |
| 94 | |
| 95 struct buddy_icon { | |
| 96 guint32 hash; | |
| 97 guint32 len; | |
| 98 time_t time; | |
| 99 void *data; | |
| 100 }; | |
| 101 | |
| 102 struct toc_data { | |
| 103 int toc_fd; | |
| 104 int seqno; | |
| 105 int state; | |
| 106 }; | |
| 107 | |
| 108 struct sflap_hdr { | |
| 109 unsigned char ast; | |
| 110 unsigned char type; | |
| 111 unsigned short seqno; | |
| 112 unsigned short len; | |
| 113 }; | |
| 114 | |
| 115 struct signon { | |
| 116 unsigned int ver; | |
| 117 unsigned short tag; | |
| 118 unsigned short namelen; | |
| 119 char username[80]; | |
| 120 }; | |
| 121 | |
| 122 /* constants to identify proto_opts */ | |
| 123 #define USEROPT_AUTH 0 | |
| 124 #define USEROPT_AUTHPORT 1 | |
| 125 | |
| 126 static GtkWidget *join_chat_spin = NULL; | |
| 127 static GtkWidget *join_chat_entry = NULL; | |
| 128 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
129 static void toc_login_callback(gpointer, gint, GaimInputCondition); |
|
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
130 static void toc_callback(gpointer, gint, GaimInputCondition); |
| 2086 | 131 static unsigned char *roast_password(char *); |
| 132 static void accept_file_dialog(struct ft_request *); | |
| 133 | |
| 134 /* ok. this function used to take username/password, and return 0 on success. | |
| 135 * now, it takes username/password, and returns NULL on error or a new gaim_connection | |
| 136 * on success. */ | |
| 137 static void toc_login(struct aim_user *user) | |
| 138 { | |
| 139 struct gaim_connection *gc; | |
| 140 struct toc_data *tdt; | |
| 141 char buf[80]; | |
| 142 | |
| 143 gc = new_gaim_conn(user); | |
| 144 gc->proto_data = tdt = g_new0(struct toc_data, 1); | |
| 145 | |
| 146 g_snprintf(buf, sizeof buf, "Looking up %s", | |
| 147 user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : TOC_HOST); | |
| 148 set_login_progress(gc, 1, buf); | |
| 149 | |
| 150 debug_printf("* Client connects to TOC\n"); | |
| 151 tdt->toc_fd = | |
| 152 proxy_connect(user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : TOC_HOST, | |
| 153 user->proto_opt[USEROPT_AUTHPORT][0] ? | |
| 154 atoi(user->proto_opt[USEROPT_AUTHPORT]) : TOC_PORT, | |
| 155 toc_login_callback, gc); | |
| 156 | |
| 157 if (!user->gc || (tdt->toc_fd < 0)) { | |
| 158 g_snprintf(buf, sizeof(buf), "Connect to %s failed", user->proto_opt[USEROPT_AUTH]); | |
| 159 hide_login_progress(gc, buf); | |
| 160 signoff(gc); | |
| 161 return; | |
| 162 } | |
| 163 } | |
| 164 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
165 static void toc_login_callback(gpointer data, gint source, GaimInputCondition cond) |
| 2086 | 166 { |
| 167 struct gaim_connection *gc = data; | |
| 168 struct toc_data *tdt; | |
| 169 char buf[80]; | |
| 170 | |
| 171 if (!g_slist_find(connections, data)) { | |
| 172 close(source); | |
| 173 return; | |
| 174 } | |
| 175 | |
| 176 tdt = gc->proto_data; | |
| 177 | |
| 178 if (source == -1) { | |
| 179 /* we didn't successfully connect. tdt->toc_fd is valid here */ | |
| 180 hide_login_progress(gc, "Unable to connect."); | |
| 181 signoff(gc); | |
| 182 return; | |
| 183 } | |
| 184 | |
| 185 if (tdt->toc_fd == 0) | |
| 186 tdt->toc_fd = source; | |
| 187 | |
| 188 debug_printf("* Client sends \"FLAPON\\r\\n\\r\\n\"\n"); | |
| 189 if (write(tdt->toc_fd, FLAPON, strlen(FLAPON)) < 0) { | |
| 190 hide_login_progress(gc, "Disconnected."); | |
| 191 signoff(gc); | |
| 192 return; | |
| 193 } | |
| 194 tdt->state = STATE_FLAPON; | |
| 195 | |
| 196 /* i know a lot of people like to look at gaim to see how TOC works. so i'll comment | |
| 197 * on what this does. it's really simple. when there's data ready to be read from the | |
| 198 * toc_fd file descriptor, toc_callback is called, with gc passed as its data arg. */ | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
199 gc->inpa = gaim_input_add(tdt->toc_fd, GAIM_INPUT_READ, toc_callback, gc); |
| 2086 | 200 |
| 201 g_snprintf(buf, sizeof(buf), "Signon: %s", gc->username); | |
| 202 set_login_progress(gc, 2, buf); | |
| 203 } | |
| 204 | |
| 205 static void toc_close(struct gaim_connection *gc) | |
| 206 { | |
| 207 if (gc->inpa > 0) | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
208 gaim_input_remove(gc->inpa); |
| 2086 | 209 gc->inpa = 0; |
| 210 close(((struct toc_data *)gc->proto_data)->toc_fd); | |
| 211 g_free(gc->proto_data); | |
| 212 } | |
| 213 | |
| 214 static int sflap_send(struct gaim_connection *gc, char *buf, int olen, int type) | |
| 215 { | |
| 216 int len; | |
| 217 int slen = 0; | |
| 218 struct sflap_hdr hdr; | |
| 219 char obuf[MSG_LEN]; | |
| 220 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
| 221 | |
| 222 if (tdt->state == STATE_PAUSE) | |
| 223 /* TOC has given us the PAUSE message; sending could cause a disconnect | |
| 224 * so we just return here like everything went through fine */ | |
| 225 return 0; | |
| 226 | |
| 227 /* One _last_ 2048 check here! This shouldn't ever | |
| 228 * get hit though, hopefully. If it gets hit on an IM | |
| 229 * It'll lose the last " and the message won't go through, | |
| 230 * but this'll stop a segfault. */ | |
| 231 if (strlen(buf) > (MSG_LEN - sizeof(hdr))) { | |
| 232 debug_printf("message too long, truncating\n"); | |
| 233 buf[MSG_LEN - sizeof(hdr) - 3] = '"'; | |
| 234 buf[MSG_LEN - sizeof(hdr) - 2] = '\0'; | |
| 235 } | |
| 236 | |
| 237 if (olen < 0) | |
| 238 len = escape_message(buf); | |
| 239 else | |
| 240 len = olen; | |
| 241 hdr.ast = '*'; | |
| 242 hdr.type = type; | |
| 243 hdr.seqno = htons(tdt->seqno++ & 0xffff); | |
| 244 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); | |
| 245 | |
| 246 memcpy(obuf, &hdr, sizeof(hdr)); | |
| 247 slen += sizeof(hdr); | |
| 248 memcpy(&obuf[slen], buf, len); | |
| 249 slen += len; | |
| 250 if (type != TYPE_SIGNON) { | |
| 251 obuf[slen] = '\0'; | |
| 252 slen += 1; | |
| 253 } | |
| 254 | |
| 255 return write(tdt->toc_fd, obuf, slen); | |
| 256 } | |
| 257 | |
| 258 static int wait_reply(struct gaim_connection *gc, char *buffer, size_t buflen) | |
| 259 { | |
| 260 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
| 261 struct sflap_hdr *hdr; | |
| 262 int ret; | |
| 263 | |
| 264 if (read(tdt->toc_fd, buffer, sizeof(struct sflap_hdr)) < 0) { | |
| 265 debug_printf("error, couldn't read flap header\n"); | |
| 266 return -1; | |
| 267 } | |
| 268 | |
| 269 hdr = (struct sflap_hdr *)buffer; | |
| 270 | |
| 271 if (buflen < ntohs(hdr->len)) { | |
| 272 /* fake like there's a read error */ | |
| 273 debug_printf("buffer too small (have %d, need %d)\n", buflen, ntohs(hdr->len)); | |
| 274 return -1; | |
| 275 } | |
| 276 | |
| 277 if (ntohs(hdr->len) > 0) { | |
| 278 int count = 0; | |
| 279 ret = 0; | |
| 280 do { | |
| 281 count += ret; | |
| 282 ret = read(tdt->toc_fd, | |
| 283 buffer + sizeof(struct sflap_hdr) + count, ntohs(hdr->len) - count); | |
| 284 } while (count + ret < ntohs(hdr->len) && ret > 0); | |
| 285 buffer[sizeof(struct sflap_hdr) + count + ret] = '\0'; | |
| 286 return ret; | |
| 287 } else | |
| 288 return 0; | |
| 289 } | |
| 290 | |
| 291 static unsigned char *roast_password(char *pass) | |
| 292 { | |
| 293 /* Trivial "encryption" */ | |
| 294 static unsigned char rp[256]; | |
| 295 static char *roast = ROAST; | |
| 296 int pos = 2; | |
| 297 int x; | |
| 298 strcpy(rp, "0x"); | |
| 299 for (x = 0; (x < 150) && pass[x]; x++) | |
| 300 pos += sprintf(&rp[pos], "%02x", pass[x] ^ roast[x % strlen(roast)]); | |
| 301 rp[pos] = '\0'; | |
| 302 return rp; | |
| 303 } | |
| 304 | |
| 305 static void toc_got_info(gpointer data, char *url_text) | |
| 306 { | |
| 307 if (!url_text) | |
| 308 return; | |
| 309 | |
|
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2136
diff
changeset
|
310 g_show_info_text(url_text, NULL); |
| 2086 | 311 } |
| 312 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
313 static void toc_callback(gpointer data, gint source, GaimInputCondition condition) |
| 2086 | 314 { |
| 315 struct gaim_connection *gc = (struct gaim_connection *)data; | |
| 316 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
| 317 struct sflap_hdr *hdr; | |
| 318 struct signon so; | |
| 319 char buf[8 * 1024], *c; | |
| 320 char snd[BUF_LEN * 2]; | |
| 321 | |
| 322 /* there's data waiting to be read, so read it. */ | |
| 323 if (wait_reply(gc, buf, 8 * 1024) <= 0) { | |
| 324 hide_login_progress(gc, _("Connection Closed")); | |
| 325 signoff(gc); | |
| 326 return; | |
| 327 } | |
| 328 | |
| 329 if (tdt->state == STATE_FLAPON) { | |
| 330 hdr = (struct sflap_hdr *)buf; | |
| 331 if (hdr->type != TYPE_SIGNON) | |
| 332 debug_printf("problem, hdr->type != TYPE_SIGNON\n"); | |
| 333 else | |
| 334 debug_printf("* TOC sends Client FLAP SIGNON\n"); | |
| 335 tdt->seqno = ntohs(hdr->seqno); | |
| 336 tdt->state = STATE_SIGNON_REQUEST; | |
| 337 | |
| 338 debug_printf("* Client sends TOC FLAP SIGNON\n"); | |
| 339 g_snprintf(so.username, sizeof(so.username), "%s", gc->username); | |
| 340 so.ver = htonl(1); | |
| 341 so.tag = htons(1); | |
| 342 so.namelen = htons(strlen(so.username)); | |
| 343 if (sflap_send(gc, (char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON) < 0) { | |
| 344 hide_login_progress(gc, _("Disconnected.")); | |
| 345 signoff(gc); | |
| 346 return; | |
| 347 } | |
| 348 | |
| 349 debug_printf("* Client sends TOC \"toc_signon\" message\n"); | |
| 350 g_snprintf(snd, sizeof snd, "toc_signon %s %d %s %s %s \"%s\"", | |
| 351 AUTH_HOST, AUTH_PORT, normalize(gc->username), | |
| 352 roast_password(gc->password), LANGUAGE, REVISION); | |
| 353 if (sflap_send(gc, snd, -1, TYPE_DATA) < 0) { | |
| 354 hide_login_progress(gc, _("Disconnected.")); | |
| 355 signoff(gc); | |
| 356 return; | |
| 357 } | |
| 358 | |
| 359 set_login_progress(gc, 3, _("Waiting for reply...")); | |
| 360 return; | |
| 361 } | |
| 362 | |
| 363 if (tdt->state == STATE_SIGNON_REQUEST) { | |
| 364 debug_printf("* TOC sends client SIGN_ON reply\n"); | |
| 365 if (g_strncasecmp(buf + sizeof(struct sflap_hdr), "SIGN_ON", strlen("SIGN_ON"))) { | |
| 366 debug_printf("Didn't get SIGN_ON! buf was: %s\n", | |
| 367 buf + sizeof(struct sflap_hdr)); | |
| 368 hide_login_progress(gc, _("Authentication Failed")); | |
| 369 signoff(gc); | |
| 370 return; | |
| 371 } | |
| 372 /* we're supposed to check that it's really TOC v1 here but we know it is ;) */ | |
|
2128
bc79be34eb73
[gaim-migrate @ 2138]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
373 debug_printf("TOC version: %s\n", buf + sizeof(struct sflap_hdr) + 8); |
| 2086 | 374 |
| 375 /* we used to check for the CONFIG here, but we'll wait until we've sent our | |
| 376 * version of the config and then the toc_init_done message. we'll come back to | |
| 377 * the callback in a better state if we get CONFIG anyway */ | |
| 378 | |
| 379 tdt->state = STATE_ONLINE; | |
| 380 | |
| 381 account_online(gc); | |
| 382 serv_finish_login(gc); | |
| 383 | |
| 384 do_import(0, gc); | |
| 385 | |
| 386 /* Client sends TOC toc_init_done message */ | |
| 387 debug_printf("* Client sends TOC toc_init_done message\n"); | |
| 388 g_snprintf(snd, sizeof snd, "toc_init_done"); | |
| 389 sflap_send(gc, snd, -1, TYPE_DATA); | |
| 390 | |
| 391 /* | |
| 392 g_snprintf(snd, sizeof snd, "toc_set_caps %s %s %s", | |
| 393 FILE_SEND_UID, FILE_GET_UID, B_ICON_UID); | |
| 394 */ | |
| 395 g_snprintf(snd, sizeof snd, "toc_set_caps %s %s", FILE_SEND_UID, FILE_GET_UID); | |
| 396 sflap_send(gc, snd, -1, TYPE_DATA); | |
| 397 | |
| 398 return; | |
| 399 } | |
| 400 | |
| 401 debug_printf("From TOC server: %s\n", buf + sizeof(struct sflap_hdr)); | |
| 402 | |
| 403 c = strtok(buf + sizeof(struct sflap_hdr), ":"); /* Ditch the first part */ | |
| 404 | |
| 405 if (!g_strcasecmp(c, "SIGN_ON")) { | |
| 406 /* we should only get here after a PAUSE */ | |
| 407 if (tdt->state != STATE_PAUSE) | |
| 408 debug_printf("got SIGN_ON but not PAUSE!\n"); | |
| 409 else { | |
| 410 tdt->state = STATE_ONLINE; | |
| 411 g_snprintf(snd, sizeof snd, "toc_signon %s %d %s %s %s \"%s\"", | |
| 412 AUTH_HOST, AUTH_PORT, normalize(gc->username), | |
| 413 roast_password(gc->password), LANGUAGE, REVISION); | |
| 414 if (sflap_send(gc, snd, -1, TYPE_DATA) < 0) { | |
| 415 hide_login_progress(gc, _("Disconnected.")); | |
| 416 signoff(gc); | |
| 417 return; | |
| 418 } | |
| 419 do_import(0, gc); | |
| 420 g_snprintf(snd, sizeof snd, "toc_init_done"); | |
| 421 sflap_send(gc, snd, -1, TYPE_DATA); | |
| 422 do_error_dialog(_("TOC has come back from its pause. You may now send" | |
| 423 " messages again."), _("TOC Resume")); | |
| 424 } | |
| 425 } else if (!strcasecmp(c, "CONFIG")) { | |
| 426 c = strtok(NULL, ":"); | |
| 427 parse_toc_buddy_list(gc, c, 0); | |
| 428 } else if (!strcasecmp(c, "NICK")) { | |
| 429 /* ignore NICK so that things get imported/exported properly | |
| 430 c = strtok(NULL, ":"); | |
| 431 g_snprintf(gc->username, sizeof(gc->username), "%s", c); | |
| 432 */ | |
| 433 } else if (!strcasecmp(c, "IM_IN")) { | |
| 434 char *away, *message; | |
| 435 int a = 0; | |
| 436 | |
| 437 c = strtok(NULL, ":"); | |
| 438 away = strtok(NULL, ":"); | |
| 439 | |
| 440 message = away; | |
| 441 while (*message && (*message != ':')) | |
| 442 message++; | |
| 443 message++; | |
| 444 | |
| 445 a = (away && (*away == 'T')) ? 1 : 0; | |
| 446 | |
| 447 serv_got_im(gc, c, message, a, time((time_t)NULL)); | |
| 448 } else if (!strcasecmp(c, "UPDATE_BUDDY")) { | |
| 449 char *l, *uc; | |
| 450 int logged, evil, idle, type = 0; | |
| 451 time_t signon, time_idle; | |
| 452 | |
| 453 c = strtok(NULL, ":"); /* name */ | |
| 454 l = strtok(NULL, ":"); /* online */ | |
| 455 sscanf(strtok(NULL, ":"), "%d", &evil); | |
| 456 sscanf(strtok(NULL, ":"), "%ld", &signon); | |
| 457 sscanf(strtok(NULL, ":"), "%d", &idle); | |
| 458 uc = strtok(NULL, ":"); | |
| 459 | |
| 460 logged = (l && (*l == 'T')) ? 1 : 0; | |
| 461 | |
| 462 if (uc[0] == 'A') | |
| 463 type |= UC_AOL; | |
| 464 switch (uc[1]) { | |
| 465 case 'A': | |
| 466 type |= UC_ADMIN; | |
| 467 break; | |
| 468 case 'U': | |
| 469 type |= UC_UNCONFIRMED; | |
| 470 break; | |
| 471 case 'O': | |
| 472 type |= UC_NORMAL; | |
| 473 break; | |
| 474 default: | |
| 475 break; | |
| 476 } | |
| 477 if (uc[2] == 'U') | |
| 478 type |= UC_UNAVAILABLE; | |
| 479 | |
| 480 if (idle) { | |
| 481 time(&time_idle); | |
| 482 time_idle -= idle * 60; | |
| 483 } else | |
| 484 time_idle = 0; | |
| 485 | |
| 486 serv_got_update(gc, c, logged, evil, signon, time_idle, type, 0); | |
| 487 } else if (!strcasecmp(c, "ERROR")) { | |
| 488 c = strtok(NULL, ":"); | |
| 489 show_error_dialog(c); | |
| 490 } else if (!strcasecmp(c, "EVILED")) { | |
| 491 int lev; | |
| 492 char *name; | |
| 493 | |
| 494 sscanf(strtok(NULL, ":"), "%d", &lev); | |
| 495 name = strtok(NULL, ":"); | |
| 496 | |
| 497 serv_got_eviled(gc, name, lev); | |
| 498 } else if (!strcasecmp(c, "CHAT_JOIN")) { | |
| 499 char *name; | |
| 500 int id; | |
| 501 | |
| 502 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 503 name = strtok(NULL, ":"); | |
| 504 | |
| 505 serv_got_joined_chat(gc, id, name); | |
| 506 } else if (!strcasecmp(c, "CHAT_IN")) { | |
| 507 int id, w; | |
| 508 char *m, *who, *whisper; | |
| 509 | |
| 510 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 511 who = strtok(NULL, ":"); | |
| 512 whisper = strtok(NULL, ":"); | |
| 513 m = whisper; | |
| 514 while (*m && (*m != ':')) | |
| 515 m++; | |
| 516 m++; | |
| 517 | |
| 518 w = (whisper && (*whisper == 'T')) ? 1 : 0; | |
| 519 | |
| 520 serv_got_chat_in(gc, id, who, w, m, time((time_t)NULL)); | |
| 521 } else if (!strcasecmp(c, "CHAT_UPDATE_BUDDY")) { | |
| 522 int id; | |
| 523 char *in, *buddy; | |
| 524 GSList *bcs = gc->buddy_chats; | |
| 525 struct conversation *b = NULL; | |
| 526 | |
| 527 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 528 in = strtok(NULL, ":"); | |
| 529 | |
| 530 while (bcs) { | |
| 531 b = (struct conversation *)bcs->data; | |
| 532 if (id == b->id) | |
| 533 break; | |
| 534 bcs = bcs->next; | |
| 535 b = NULL; | |
| 536 } | |
| 537 | |
| 538 if (!b) | |
| 539 return; | |
| 540 | |
| 541 if (in && (*in == 'T')) | |
| 542 while ((buddy = strtok(NULL, ":")) != NULL) | |
| 543 add_chat_buddy(b, buddy); | |
| 544 else | |
| 545 while ((buddy = strtok(NULL, ":")) != NULL) | |
| 546 remove_chat_buddy(b, buddy); | |
| 547 } else if (!strcasecmp(c, "CHAT_INVITE")) { | |
| 548 char *name, *who, *message; | |
| 549 int id; | |
| 550 | |
| 551 name = strtok(NULL, ":"); | |
| 552 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 553 who = strtok(NULL, ":"); | |
| 554 message = strtok(NULL, ":"); | |
| 555 | |
| 556 serv_got_chat_invite(gc, name, id, who, message); | |
| 557 } else if (!strcasecmp(c, "CHAT_LEFT")) { | |
| 558 GSList *bcs = gc->buddy_chats; | |
| 559 struct conversation *b = NULL; | |
| 560 int id; | |
| 561 | |
| 562 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 563 | |
| 564 while (bcs) { | |
| 565 b = (struct conversation *)bcs->data; | |
| 566 if (id == b->id) | |
| 567 break; | |
| 568 b = NULL; | |
| 569 bcs = bcs->next; | |
| 570 } | |
| 571 | |
| 572 if (!b) | |
| 573 return; | |
| 574 | |
| 575 if (b->window) { | |
| 576 char error_buf[BUF_LONG]; | |
| 577 b->gc = NULL; | |
| 578 g_snprintf(error_buf, sizeof error_buf, _("You have been disconnected" | |
| 579 " from chat room %s."), b->name); | |
| 580 do_error_dialog(error_buf, _("Chat Error")); | |
| 581 } else | |
| 582 serv_got_chat_left(gc, id); | |
| 583 } else if (!strcasecmp(c, "GOTO_URL")) { | |
| 584 char *name, *url, tmp[256]; | |
| 585 | |
| 586 name = strtok(NULL, ":"); | |
| 587 url = strtok(NULL, ":"); | |
| 588 | |
| 589 g_snprintf(tmp, sizeof(tmp), "http://%s:%d/%s", | |
| 590 gc->user->proto_opt[USEROPT_AUTH][0] ? | |
| 591 gc->user->proto_opt[USEROPT_AUTH] : TOC_HOST, | |
| 592 gc->user->proto_opt[USEROPT_AUTHPORT][0] ? | |
| 593 atoi(gc->user->proto_opt[USEROPT_AUTHPORT]) : TOC_PORT, | |
| 594 url); | |
| 595 grab_url(tmp, toc_got_info, NULL); | |
| 596 } else if (!strcasecmp(c, "DIR_STATUS")) { | |
| 597 } else if (!strcasecmp(c, "ADMIN_NICK_STATUS")) { | |
| 598 } else if (!strcasecmp(c, "ADMIN_PASSWD_STATUS")) { | |
| 599 do_error_dialog(_("Password Change Successeful"), _("Gaim - Password Change")); | |
| 600 } else if (!strcasecmp(c, "PAUSE")) { | |
| 601 tdt->state = STATE_PAUSE; | |
| 602 do_error_dialog(_("TOC has sent a PAUSE command. When this happens, TOC ignores" | |
| 603 " any messages sent to it, and may kick you off if you send a" | |
| 604 " message. Gaim will prevent anything from going through. This" | |
| 605 " is only temporary, please be patient."), _("TOC Pause")); | |
| 606 } else if (!strcasecmp(c, "RVOUS_PROPOSE")) { | |
| 607 char *user, *uuid, *cookie; | |
| 608 int seq; | |
| 609 char *rip, *pip, *vip; | |
| 610 int port; | |
| 611 | |
| 612 user = strtok(NULL, ":"); | |
| 613 uuid = strtok(NULL, ":"); | |
| 614 cookie = strtok(NULL, ":"); | |
| 615 sscanf(strtok(NULL, ":"), "%d", &seq); | |
| 616 rip = strtok(NULL, ":"); | |
| 617 pip = strtok(NULL, ":"); | |
| 618 vip = strtok(NULL, ":"); | |
| 619 sscanf(strtok(NULL, ":"), "%d", &port); | |
| 620 | |
| 621 if (!strcmp(uuid, FILE_SEND_UID)) { | |
| 622 /* they want us to get a file */ | |
| 623 int unk[4], i; | |
| 624 char *messages[4], *tmp, *name; | |
| 625 int subtype, files, totalsize = 0; | |
| 626 struct ft_request *ft; | |
| 627 | |
| 628 for (i = 0; i < 4; i++) { | |
| 629 sscanf(strtok(NULL, ":"), "%d", &unk[i]); | |
| 630 if (unk[i] == 10001) | |
| 631 break; | |
| 632 frombase64(strtok(NULL, ":"), &messages[i], NULL); | |
| 633 } | |
| 634 frombase64(strtok(NULL, ":"), &tmp, NULL); | |
| 635 | |
| 636 subtype = tmp[1]; | |
| 637 files = tmp[3]; | |
| 638 | |
| 639 totalsize |= (tmp[4] << 24) & 0xff000000; | |
| 640 totalsize |= (tmp[5] << 16) & 0x00ff0000; | |
| 641 totalsize |= (tmp[6] << 8) & 0x0000ff00; | |
| 642 totalsize |= (tmp[7] << 0) & 0x000000ff; | |
| 643 | |
| 644 if (!totalsize) { | |
| 645 g_free(tmp); | |
| 646 for (i--; i >= 0; i--) | |
| 647 g_free(messages[i]); | |
| 648 return; | |
| 649 } | |
| 650 | |
| 651 name = tmp + 8; | |
| 652 | |
| 653 ft = g_new0(struct ft_request, 1); | |
| 654 ft->cookie = g_strdup(cookie); | |
| 655 ft->ip = g_strdup(pip); | |
| 656 ft->port = port; | |
| 657 if (i) | |
| 658 ft->message = g_strdup(messages[0]); | |
| 659 else | |
| 660 ft->message = NULL; | |
| 661 ft->filename = g_strdup(name); | |
| 662 ft->user = g_strdup(user); | |
| 663 ft->size = totalsize; | |
| 664 ft->files = files; | |
| 665 g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_SEND_UID); | |
| 666 ft->gc = gc; | |
| 667 | |
| 668 g_free(tmp); | |
| 669 for (i--; i >= 0; i--) | |
| 670 g_free(messages[i]); | |
| 671 | |
| 672 debug_printf("English translation of RVOUS_PROPOSE: %s requests Send File (i.e." | |
| 673 " send a file to you); %s:%d (verified_ip:port), %d files at" | |
| 674 " total size of %ld bytes.\n", user, vip, port, files, totalsize); | |
| 675 accept_file_dialog(ft); | |
| 676 } else if (!strcmp(uuid, FILE_GET_UID)) { | |
| 677 /* they want us to send a file */ | |
| 678 int unk[4], i; | |
| 679 char *messages[4], *tmp; | |
| 680 struct ft_request *ft; | |
| 681 | |
| 682 for (i = 0; i < 4; i++) { | |
| 683 sscanf(strtok(NULL, ":"), "%d", unk + i); | |
| 684 if (unk[i] == 10001) | |
| 685 break; | |
| 686 frombase64(strtok(NULL, ":"), &messages[i], NULL); | |
| 687 } | |
| 688 frombase64(strtok(NULL, ":"), &tmp, NULL); | |
| 689 | |
| 690 ft = g_new0(struct ft_request, 1); | |
| 691 ft->cookie = g_strdup(cookie); | |
| 692 ft->ip = g_strdup(pip); | |
| 693 ft->port = port; | |
| 694 if (i) | |
| 695 ft->message = g_strdup(messages[0]); | |
| 696 else | |
| 697 ft->message = NULL; | |
| 698 ft->user = g_strdup(user); | |
| 699 g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_GET_UID); | |
| 700 ft->gc = gc; | |
| 701 | |
| 702 g_free(tmp); | |
| 703 for (i--; i >= 0; i--) | |
| 704 g_free(messages[i]); | |
| 705 | |
| 706 accept_file_dialog(ft); | |
| 707 } else if (!strcmp(uuid, VOICE_UID)) { | |
| 708 /* oh goody. voice over ip. fun stuff. */ | |
| 709 } else if (!strcmp(uuid, B_ICON_UID)) { | |
| 710 /* | |
| 711 int unk[4], i; | |
| 712 char *messages[4]; | |
| 713 struct buddy_icon *icon; | |
| 714 | |
| 715 for (i = 0; i < 4; i++) { | |
| 716 sscanf(strtok(NULL, ":"), "%d", unk + i); | |
| 717 if (unk[i] == 10001) | |
| 718 break; | |
| 719 frombase64(strtok(NULL, ":"), &messages[i], NULL); | |
| 720 } | |
| 721 frombase64(strtok(NULL, ":"), (char **)&icon, NULL); | |
| 722 | |
| 723 debug_printf("received icon of length %d\n", icon->len); | |
| 724 g_free(icon); | |
| 725 for (i--; i >= 0; i--) | |
| 726 g_free(messages[i]); | |
| 727 */ | |
| 728 } else if (!strcmp(uuid, IMAGE_UID)) { | |
| 729 /* aka Direct IM */ | |
| 730 } else { | |
| 731 debug_printf("Don't know what to do with RVOUS UUID %s\n", uuid); | |
| 732 /* do we have to do anything here? i think it just times out */ | |
| 733 } | |
| 734 } else { | |
| 735 debug_printf("don't know what to do with %s\n", c); | |
| 736 } | |
| 737 } | |
| 738 | |
| 739 static char *toc_name() | |
| 740 { | |
| 741 return "TOC"; | |
| 742 } | |
| 743 | |
|
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
744 static int toc_send_im(struct gaim_connection *gc, char *name, char *message, int away) |
| 2086 | 745 { |
| 746 char buf[BUF_LEN * 2]; | |
|
2136
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
747 char *tmp = g_malloc(strlen(message) * 2); |
| 2086 | 748 |
|
2136
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
749 strcpy(tmp, message); |
|
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
750 escape_text(tmp); |
|
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
751 if (strlen(tmp) + 52 > MSG_LEN) { |
|
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
752 g_free(tmp); |
|
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
753 return -E2BIG; |
|
2136
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
754 } |
| 2086 | 755 g_snprintf(buf, MSG_LEN - 8, "toc_send_im %s \"%s\"%s", normalize(name), |
|
2136
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
756 tmp, ((away) ? " auto" : "")); |
| 2086 | 757 sflap_send(gc, buf, -1, TYPE_DATA); |
|
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
758 |
|
2136
73253b36c3cb
[gaim-migrate @ 2146]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
759 g_free(tmp); |
|
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
760 return 0; |
| 2086 | 761 } |
| 762 | |
| 763 static void toc_set_config(struct gaim_connection *gc) | |
| 764 { | |
| 765 char buf[MSG_LEN], snd[BUF_LEN * 2]; | |
| 766 toc_build_config(gc, buf, MSG_LEN, FALSE); | |
| 767 g_snprintf(snd, MSG_LEN, "toc_set_config {%s}", buf); | |
| 768 sflap_send(gc, snd, -1, TYPE_DATA); | |
| 769 } | |
| 770 | |
| 771 static void toc_get_info(struct gaim_connection *g, char *name) | |
| 772 { | |
| 773 char buf[BUF_LEN * 2]; | |
| 774 g_snprintf(buf, MSG_LEN, "toc_get_info %s", normalize(name)); | |
| 775 sflap_send(g, buf, -1, TYPE_DATA); | |
| 776 } | |
| 777 | |
| 778 static void toc_get_dir(struct gaim_connection *g, char *name) | |
| 779 { | |
| 780 char buf[BUF_LEN * 2]; | |
| 781 g_snprintf(buf, MSG_LEN, "toc_get_dir %s", normalize(name)); | |
| 782 sflap_send(g, buf, -1, TYPE_DATA); | |
| 783 } | |
| 784 | |
| 785 static void toc_set_dir(struct gaim_connection *g, char *first, char *middle, char *last, | |
| 786 char *maiden, char *city, char *state, char *country, int web) | |
| 787 { | |
| 788 char buf2[BUF_LEN * 4], buf[BUF_LEN]; | |
| 789 g_snprintf(buf2, sizeof(buf2), "%s:%s:%s:%s:%s:%s:%s:%s", first, | |
| 790 middle, last, maiden, city, state, country, (web == 1) ? "Y" : ""); | |
| 791 escape_text(buf2); | |
| 792 g_snprintf(buf, sizeof(buf), "toc_set_dir %s", buf2); | |
| 793 sflap_send(g, buf, -1, TYPE_DATA); | |
| 794 } | |
| 795 | |
| 796 static void toc_dir_search(struct gaim_connection *g, char *first, char *middle, char *last, | |
| 797 char *maiden, char *city, char *state, char *country, char *email) | |
| 798 { | |
| 799 char buf[BUF_LONG]; | |
| 800 g_snprintf(buf, sizeof(buf) / 2, "toc_dir_search %s:%s:%s:%s:%s:%s:%s:%s", first, middle, | |
| 801 last, maiden, city, state, country, email); | |
| 802 debug_printf("Searching for: %s,%s,%s,%s,%s,%s,%s\n", first, middle, last, maiden, | |
| 803 city, state, country); | |
| 804 sflap_send(g, buf, -1, TYPE_DATA); | |
| 805 } | |
| 806 | |
| 807 static void toc_set_away(struct gaim_connection *g, char *state, char *message) | |
| 808 { | |
| 809 char buf[BUF_LEN * 2]; | |
| 810 if (g->away) | |
| 811 g_free (g->away); | |
| 812 g->away = NULL; | |
| 813 if (message) { | |
| 814 g->away = g_strdup (message); | |
| 815 escape_text(message); | |
| 816 g_snprintf(buf, MSG_LEN, "toc_set_away \"%s\"", message); | |
| 817 } else | |
| 818 g_snprintf(buf, MSG_LEN, "toc_set_away \"\""); | |
| 819 sflap_send(g, buf, -1, TYPE_DATA); | |
| 820 } | |
| 821 | |
| 822 static void toc_set_info(struct gaim_connection *g, char *info) | |
| 823 { | |
| 824 char buf[BUF_LEN * 2], buf2[BUF_LEN * 2]; | |
| 825 g_snprintf(buf2, sizeof buf2, "%s", info); | |
| 826 escape_text(buf2); | |
| 827 g_snprintf(buf, sizeof(buf), "toc_set_info \"%s\n\"", buf2); | |
| 828 sflap_send(g, buf, -1, TYPE_DATA); | |
| 829 } | |
| 830 | |
| 831 static void toc_change_passwd(struct gaim_connection *g, char *orig, char *new) | |
| 832 { | |
| 833 char buf[BUF_LEN * 2]; | |
| 834 g_snprintf(buf, BUF_LONG, "toc_change_passwd %s %s", orig, new); | |
| 835 sflap_send(g, buf, strlen(buf), TYPE_DATA); | |
| 836 } | |
| 837 | |
| 838 static void toc_add_buddy(struct gaim_connection *g, char *name) | |
| 839 { | |
| 840 char buf[BUF_LEN * 2]; | |
| 841 g_snprintf(buf, sizeof(buf), "toc_add_buddy %s", normalize(name)); | |
| 842 sflap_send(g, buf, -1, TYPE_DATA); | |
| 843 toc_set_config(g); | |
| 844 } | |
| 845 | |
| 846 static void toc_add_buddies(struct gaim_connection *g, GList * buddies) | |
| 847 { | |
| 848 char buf[BUF_LEN * 2]; | |
| 849 int n; | |
| 850 | |
| 851 n = g_snprintf(buf, sizeof(buf), "toc_add_buddy"); | |
| 852 while (buddies) { | |
|
2130
50c7a704ee56
[gaim-migrate @ 2140]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2128
diff
changeset
|
853 if (strlen(normalize(buddies->data)) + n + 32 > MSG_LEN) { |
| 2086 | 854 sflap_send(g, buf, -1, TYPE_DATA); |
| 855 n = g_snprintf(buf, sizeof(buf), "toc_add_buddy"); | |
| 856 } | |
| 857 n += g_snprintf(buf + n, sizeof(buf) - n, " %s", normalize(buddies->data)); | |
| 858 buddies = buddies->next; | |
| 859 } | |
| 860 sflap_send(g, buf, -1, TYPE_DATA); | |
| 861 } | |
| 862 | |
| 863 static void toc_remove_buddy(struct gaim_connection *g, char *name) | |
| 864 { | |
| 865 char buf[BUF_LEN * 2]; | |
| 866 g_snprintf(buf, sizeof(buf), "toc_remove_buddy %s", normalize(name)); | |
| 867 sflap_send(g, buf, -1, TYPE_DATA); | |
| 868 toc_set_config(g); | |
| 869 } | |
| 870 | |
| 871 static void toc_set_idle(struct gaim_connection *g, int time) | |
| 872 { | |
| 873 char buf[BUF_LEN * 2]; | |
| 874 g_snprintf(buf, sizeof(buf), "toc_set_idle %d", time); | |
| 875 sflap_send(g, buf, -1, TYPE_DATA); | |
| 876 } | |
| 877 | |
| 878 static void toc_warn(struct gaim_connection *g, char *name, int anon) | |
| 879 { | |
| 880 char send[BUF_LEN * 2]; | |
| 881 g_snprintf(send, 255, "toc_evil %s %s", name, ((anon) ? "anon" : "norm")); | |
| 882 sflap_send(g, send, -1, TYPE_DATA); | |
| 883 } | |
| 884 | |
| 885 static void toc_accept_chat(struct gaim_connection *g, int i) | |
| 886 { | |
| 887 char buf[BUF_LEN * 2]; | |
| 888 g_snprintf(buf, 255, "toc_chat_accept %d", i); | |
| 889 sflap_send(g, buf, -1, TYPE_DATA); | |
| 890 } | |
| 891 | |
| 892 static void toc_join_chat(struct gaim_connection *g, int exchange, char *name) | |
| 893 { | |
| 894 char buf[BUF_LONG]; | |
| 895 if (!name) { | |
| 896 const char *nm; | |
| 897 if (!join_chat_entry || !join_chat_spin) | |
| 898 return; | |
| 899 nm = gtk_entry_get_text(GTK_ENTRY(join_chat_entry)); | |
| 900 exchange = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(join_chat_spin)); | |
| 901 if (!name || !strlen(name)) | |
| 902 return; | |
| 903 g_snprintf(buf, sizeof(buf) / 2, "toc_chat_join %d \"%s\"", exchange, nm); | |
| 904 } else | |
| 905 g_snprintf(buf, sizeof(buf) / 2, "toc_chat_join %d \"%s\"", exchange, name); | |
| 906 sflap_send(g, buf, -1, TYPE_DATA); | |
| 907 } | |
| 908 | |
| 909 static void toc_chat_invite(struct gaim_connection *g, int id, char *message, char *name) | |
| 910 { | |
| 911 char buf[BUF_LONG]; | |
| 912 g_snprintf(buf, sizeof(buf) / 2, "toc_chat_invite %d \"%s\" %s", id, message, normalize(name)); | |
| 913 sflap_send(g, buf, -1, TYPE_DATA); | |
| 914 } | |
| 915 | |
| 916 static void toc_chat_leave(struct gaim_connection *g, int id) | |
| 917 { | |
| 918 GSList *bcs = g->buddy_chats; | |
| 919 struct conversation *b = NULL; | |
| 920 char buf[BUF_LEN * 2]; | |
| 921 | |
| 922 while (bcs) { | |
| 923 b = (struct conversation *)bcs->data; | |
| 924 if (id == b->id) | |
| 925 break; | |
| 926 b = NULL; | |
| 927 bcs = bcs->next; | |
| 928 } | |
| 929 | |
| 930 if (!b) | |
| 931 return; /* can this happen? */ | |
| 932 | |
| 933 if (!b->gc) /* TOC already kicked us out of this room */ | |
| 934 serv_got_chat_left(g, id); | |
| 935 else { | |
| 936 g_snprintf(buf, 255, "toc_chat_leave %d", id); | |
| 937 sflap_send(g, buf, -1, TYPE_DATA); | |
| 938 } | |
| 939 } | |
| 940 | |
| 941 static void toc_chat_whisper(struct gaim_connection *g, int id, char *who, char *message) | |
| 942 { | |
| 943 char buf2[BUF_LEN * 2]; | |
| 944 g_snprintf(buf2, sizeof(buf2), "toc_chat_whisper %d %s \"%s\"", id, who, message); | |
| 945 sflap_send(g, buf2, -1, TYPE_DATA); | |
| 946 } | |
| 947 | |
| 948 static void toc_chat_send(struct gaim_connection *g, int id, char *message) | |
| 949 { | |
| 950 char buf[BUF_LEN * 2]; | |
| 951 escape_text(message); | |
| 952 g_snprintf(buf, sizeof(buf), "toc_chat_send %d \"%s\"", id, message); | |
| 953 sflap_send(g, buf, -1, TYPE_DATA); | |
| 954 } | |
| 955 | |
| 956 static void toc_keepalive(struct gaim_connection *gc) | |
| 957 { | |
| 958 sflap_send(gc, "", 0, TYPE_KEEPALIVE); | |
| 959 } | |
| 960 | |
| 961 static char **toc_list_icon(int uc) | |
| 962 { | |
| 963 if (uc & UC_UNAVAILABLE) | |
| 964 return (char **)away_icon_xpm; | |
| 965 if (uc & UC_AOL) | |
| 966 return (char **)aol_icon_xpm; | |
| 967 if (uc & UC_NORMAL) | |
| 968 return (char **)free_icon_xpm; | |
| 969 if (uc & UC_ADMIN) | |
| 970 return (char **)admin_icon_xpm; | |
| 971 if (uc & UC_UNCONFIRMED) | |
| 972 return (char **)dt_icon_xpm; | |
| 973 return NULL; | |
| 974 } | |
| 975 | |
| 976 static void toc_info(GtkObject * obj, char *who) | |
| 977 { | |
| 978 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(obj); | |
| 979 serv_get_info(gc, who); | |
| 980 } | |
| 981 | |
| 982 static void toc_dir_info(GtkObject * obj, char *who) | |
| 983 { | |
| 984 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(obj); | |
| 985 serv_get_dir(gc, who); | |
| 986 } | |
| 987 | |
| 988 static void des_jc() | |
| 989 { | |
| 990 join_chat_entry = NULL; | |
| 991 join_chat_spin = NULL; | |
| 992 } | |
| 993 | |
| 994 static void toc_draw_join_chat(struct gaim_connection *gc, GtkWidget *fbox) { | |
| 995 GtkWidget *label; | |
| 996 GtkWidget *rowbox; | |
| 997 GtkObject *adjust; | |
| 998 | |
| 999 rowbox = gtk_hbox_new(FALSE, 5); | |
| 1000 gtk_box_pack_start(GTK_BOX(fbox), rowbox, TRUE, TRUE, 0); | |
| 1001 gtk_widget_show(rowbox); | |
| 1002 | |
| 1003 label = gtk_label_new(_("Join what group:")); | |
| 1004 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
| 1005 gtk_signal_connect(GTK_OBJECT(label), "destroy", GTK_SIGNAL_FUNC(des_jc), NULL); | |
| 1006 gtk_widget_show(label); | |
| 1007 | |
| 1008 join_chat_entry = gtk_entry_new(); | |
| 1009 gtk_box_pack_start(GTK_BOX(rowbox), join_chat_entry, TRUE, TRUE, 0); | |
| 1010 gtk_widget_grab_focus(join_chat_entry); | |
| 1011 gtk_signal_connect(GTK_OBJECT(join_chat_entry), "activate", GTK_SIGNAL_FUNC(do_join_chat), NULL); | |
| 1012 gtk_widget_show(join_chat_entry); | |
| 1013 | |
| 1014 rowbox = gtk_hbox_new(FALSE, 5); | |
| 1015 gtk_box_pack_start(GTK_BOX(fbox), rowbox, TRUE, TRUE, 0); | |
| 1016 gtk_widget_show(rowbox); | |
| 1017 | |
| 1018 label = gtk_label_new(_("Community:")); | |
| 1019 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
| 1020 gtk_widget_show(label); | |
| 1021 | |
| 1022 adjust = gtk_adjustment_new(4, 4, 20, 1, 10, 10); | |
| 1023 join_chat_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); | |
| 1024 gtk_widget_set_usize(join_chat_spin, 50, -1); | |
| 1025 gtk_box_pack_start(GTK_BOX(rowbox), join_chat_spin, FALSE, FALSE, 0); | |
| 1026 gtk_widget_show(join_chat_spin); | |
| 1027 } | |
| 1028 | |
| 1029 static void toc_buddy_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) | |
| 1030 { | |
| 1031 GtkWidget *button; | |
| 1032 | |
| 1033 button = gtk_menu_item_new_with_label(_("Get Info")); | |
| 1034 gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(toc_info), who); | |
| 1035 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
| 1036 gtk_menu_append(GTK_MENU(menu), button); | |
| 1037 gtk_widget_show(button); | |
| 1038 | |
| 1039 button = gtk_menu_item_new_with_label(_("Get Dir Info")); | |
| 1040 gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(toc_dir_info), who); | |
| 1041 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
| 1042 gtk_menu_append(GTK_MENU(menu), button); | |
| 1043 gtk_widget_show(button); | |
| 1044 } | |
| 1045 | |
| 1046 static void toc_print_option(GtkEntry *entry, struct aim_user *user) | |
| 1047 { | |
| 1048 int entrynum; | |
| 1049 | |
| 1050 entrynum = (int)gtk_object_get_user_data(GTK_OBJECT(entry)); | |
| 1051 | |
| 1052 if (entrynum == USEROPT_AUTH) { | |
| 1053 g_snprintf(user->proto_opt[USEROPT_AUTH], | |
| 1054 sizeof(user->proto_opt[USEROPT_AUTH]), "%s", gtk_entry_get_text(entry)); | |
| 1055 } else if (entrynum == USEROPT_AUTHPORT) { | |
| 1056 g_snprintf(user->proto_opt[USEROPT_AUTHPORT], | |
| 1057 sizeof(user->proto_opt[USEROPT_AUTHPORT]), "%s", gtk_entry_get_text(entry)); | |
| 1058 } | |
| 1059 } | |
| 1060 | |
| 1061 static void toc_user_opts(GtkWidget *book, struct aim_user *user) | |
| 1062 { | |
| 1063 /* so here, we create the new notebook page */ | |
| 1064 GtkWidget *vbox; | |
| 1065 GtkWidget *hbox; | |
| 1066 GtkWidget *label; | |
| 1067 GtkWidget *entry; | |
| 1068 | |
| 1069 vbox = gtk_vbox_new(FALSE, 5); | |
| 1070 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); | |
| 1071 gtk_notebook_append_page(GTK_NOTEBOOK(book), vbox, gtk_label_new("TOC Options")); | |
| 1072 gtk_widget_show(vbox); | |
| 1073 | |
| 1074 hbox = gtk_hbox_new(FALSE, 5); | |
| 1075 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
| 1076 gtk_widget_show(hbox); | |
| 1077 | |
| 1078 label = gtk_label_new("TOC Host:"); | |
| 1079 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
| 1080 gtk_widget_show(label); | |
| 1081 | |
| 1082 entry = gtk_entry_new(); | |
| 1083 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
| 1084 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTH); | |
| 1085 gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(toc_print_option), user); | |
| 1086 if (user->proto_opt[USEROPT_AUTH][0]) { | |
| 1087 debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTH]); | |
| 1088 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTH]); | |
| 1089 } else | |
| 1090 gtk_entry_set_text(GTK_ENTRY(entry), "toc.oscar.aol.com"); | |
| 1091 gtk_widget_show(entry); | |
| 1092 | |
| 1093 hbox = gtk_hbox_new(FALSE, 0); | |
| 1094 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
| 1095 gtk_widget_show(hbox); | |
| 1096 | |
| 1097 label = gtk_label_new("TOC Port:"); | |
| 1098 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
| 1099 gtk_widget_show(label); | |
| 1100 | |
| 1101 entry = gtk_entry_new(); | |
| 1102 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
| 1103 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTHPORT); | |
| 1104 gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(toc_print_option), user); | |
| 1105 if (user->proto_opt[USEROPT_AUTHPORT][0]) { | |
| 1106 debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTHPORT]); | |
| 1107 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHPORT]); | |
| 1108 } else | |
| 1109 gtk_entry_set_text(GTK_ENTRY(entry), "9898"); | |
| 1110 | |
| 1111 gtk_widget_show(entry); | |
| 1112 } | |
| 1113 | |
| 1114 static void toc_add_permit(struct gaim_connection *gc, char *who) | |
| 1115 { | |
| 1116 char buf2[BUF_LEN * 2]; | |
| 1117 if (gc->permdeny != 3) | |
| 1118 return; | |
| 1119 g_snprintf(buf2, sizeof(buf2), "toc_add_permit %s", normalize(who)); | |
| 1120 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1121 toc_set_config(gc); | |
| 1122 } | |
| 1123 | |
| 1124 static void toc_add_deny(struct gaim_connection *gc, char *who) | |
| 1125 { | |
| 1126 char buf2[BUF_LEN * 2]; | |
| 1127 if (gc->permdeny != 4) | |
| 1128 return; | |
| 1129 g_snprintf(buf2, sizeof(buf2), "toc_add_deny %s", normalize(who)); | |
| 1130 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1131 toc_set_config(gc); | |
| 1132 } | |
| 1133 | |
| 1134 static void toc_set_permit_deny(struct gaim_connection *gc) | |
| 1135 { | |
| 1136 char buf2[BUF_LEN * 2]; | |
| 1137 GSList *list; | |
| 1138 int at; | |
| 1139 | |
| 1140 switch (gc->permdeny) { | |
| 1141 case 1: | |
| 1142 /* permit all, deny none. to get here reliably we need to have been in permit | |
| 1143 * mode, and send an empty toc_add_deny message, which will switch us to deny none */ | |
| 1144 g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); | |
| 1145 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1146 g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); | |
| 1147 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1148 break; | |
| 1149 case 2: | |
| 1150 /* deny all, permit none. to get here reliably we need to have been in deny | |
| 1151 * mode, and send an empty toc_add_permit message, which will switch us to permit none */ | |
| 1152 g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); | |
| 1153 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1154 g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); | |
| 1155 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1156 break; | |
| 1157 case 3: | |
| 1158 /* permit some. we want to switch to deny mode first, then send the toc_add_permit | |
| 1159 * message, which will clear and set our permit list. toc sucks. */ | |
| 1160 g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); | |
| 1161 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1162 | |
| 1163 at = g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); | |
| 1164 list = gc->permit; | |
| 1165 while (list) { | |
| 1166 at += g_snprintf(buf2 + at, sizeof(buf2) - at, "%s ", normalize(list->data)); | |
| 1167 if (at > MSG_LEN + 32) { /* from out my ass comes greatness */ | |
| 1168 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1169 at = g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); | |
| 1170 } | |
| 1171 list = list->next; | |
| 1172 } | |
| 1173 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1174 break; | |
| 1175 case 4: | |
| 1176 /* deny some. we want to switch to permit mode first, then send the toc_add_deny | |
| 1177 * message, which will clear and set our deny list. toc sucks. */ | |
| 1178 g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); | |
| 1179 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1180 | |
| 1181 at = g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); | |
| 1182 list = gc->deny; | |
| 1183 while (list) { | |
| 1184 at += g_snprintf(buf2 + at, sizeof(buf2) - at, "%s ", normalize(list->data)); | |
| 1185 if (at > MSG_LEN + 32) { /* from out my ass comes greatness */ | |
| 1186 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1187 at = g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); | |
| 1188 } | |
| 1189 list = list->next; | |
| 1190 } | |
| 1191 sflap_send(gc, buf2, -1, TYPE_DATA); | |
| 1192 break; | |
| 1193 default: | |
| 1194 break; | |
| 1195 } | |
| 1196 toc_set_config(gc); | |
| 1197 } | |
| 1198 | |
| 1199 static void toc_rem_permit(struct gaim_connection *gc, char *who) | |
| 1200 { | |
| 1201 if (gc->permdeny != 3) | |
| 1202 return; | |
| 1203 toc_set_permit_deny(gc); | |
| 1204 } | |
| 1205 | |
| 1206 static void toc_rem_deny(struct gaim_connection *gc, char *who) | |
| 1207 { | |
| 1208 if (gc->permdeny != 4) | |
| 1209 return; | |
| 1210 toc_set_permit_deny(gc); | |
| 1211 } | |
| 1212 | |
| 1213 static void toc_draw_new_user(GtkWidget *box) | |
| 1214 { | |
| 1215 GtkWidget *label; | |
| 1216 | |
| 1217 label = gtk_label_new(_("Unfortunately, currently TOC only allows new user registration by " | |
| 1218 "going to http://aim.aol.com/aimnew/Aim/register.adp?promo=106723&pageset=Aim&client=no" | |
| 1219 ". Clicking the Register button will open the URL for you.")); | |
| 1220 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
| 1221 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5); | |
| 1222 gtk_widget_show(label); | |
| 1223 } | |
| 1224 | |
| 1225 static void toc_do_new_user() | |
| 1226 { | |
| 1227 open_url(NULL, "http://aim.aol.com/aimnew/Aim/register.adp?promo=106723&pageset=Aim&client=no"); | |
| 1228 } | |
| 1229 | |
| 1230 static GList *toc_away_states() | |
| 1231 { | |
| 1232 return g_list_append(NULL, GAIM_AWAY_CUSTOM); | |
| 1233 } | |
| 1234 | |
| 1235 static void toc_do_action(struct gaim_connection *gc, char *act) | |
| 1236 { | |
| 1237 if (!strcmp(act, "Set User Info")) { | |
| 1238 show_set_info(gc); | |
| 1239 } else if (!strcmp(act, "Set Dir Info")) { | |
| 1240 show_set_dir(gc); | |
| 1241 } else if (!strcmp(act, "Change Password")) { | |
| 1242 show_change_passwd(gc); | |
| 1243 } | |
| 1244 } | |
| 1245 | |
| 1246 static GList *toc_actions() | |
| 1247 { | |
| 1248 GList *m = NULL; | |
| 1249 | |
| 1250 m = g_list_append(m, "Set User Info"); | |
| 1251 m = g_list_append(m, "Set Dir Info"); | |
| 1252 m = g_list_append(m, "Change Password"); | |
| 1253 | |
| 1254 return m; | |
| 1255 } | |
| 1256 | |
| 1257 static struct prpl *my_protocol = NULL; | |
| 1258 | |
| 1259 void toc_init(struct prpl *ret) | |
| 1260 { | |
| 1261 ret->protocol = PROTO_TOC; | |
| 1262 ret->options = OPT_PROTO_HTML | OPT_PROTO_CORRECT_TIME; | |
| 1263 ret->name = toc_name; | |
| 1264 ret->list_icon = toc_list_icon; | |
| 1265 ret->away_states = toc_away_states; | |
| 1266 ret->actions = toc_actions; | |
| 1267 ret->do_action = toc_do_action; | |
| 1268 ret->buddy_menu = toc_buddy_menu; | |
| 1269 ret->user_opts = toc_user_opts; | |
| 1270 ret->draw_new_user = toc_draw_new_user; | |
| 1271 ret->do_new_user = toc_do_new_user; | |
| 1272 ret->login = toc_login; | |
| 1273 ret->close = toc_close; | |
| 1274 ret->send_im = toc_send_im; | |
| 1275 ret->set_info = toc_set_info; | |
| 1276 ret->get_info = toc_get_info; | |
| 1277 ret->set_away = toc_set_away; | |
| 1278 ret->get_away_msg = NULL; | |
| 1279 ret->set_dir = toc_set_dir; | |
| 1280 ret->get_dir = toc_get_dir; | |
| 1281 ret->dir_search = toc_dir_search; | |
| 1282 ret->set_idle = toc_set_idle; | |
| 1283 ret->change_passwd = toc_change_passwd; | |
| 1284 ret->add_buddy = toc_add_buddy; | |
| 1285 ret->add_buddies = toc_add_buddies; | |
| 1286 ret->remove_buddy = toc_remove_buddy; | |
| 1287 ret->add_permit = toc_add_permit; | |
| 1288 ret->add_deny = toc_add_deny; | |
| 1289 ret->rem_permit = toc_rem_permit; | |
| 1290 ret->rem_deny = toc_rem_deny; | |
| 1291 ret->set_permit_deny = toc_set_permit_deny; | |
| 1292 ret->warn = toc_warn; | |
| 1293 ret->draw_join_chat = toc_draw_join_chat; | |
| 1294 ret->accept_chat = toc_accept_chat; | |
| 1295 ret->join_chat = toc_join_chat; | |
| 1296 ret->chat_invite = toc_chat_invite; | |
| 1297 ret->chat_leave = toc_chat_leave; | |
| 1298 ret->chat_whisper = toc_chat_whisper; | |
| 1299 ret->chat_send = toc_chat_send; | |
| 1300 ret->keepalive = toc_keepalive; | |
| 1301 | |
| 1302 my_protocol = ret; | |
| 1303 } | |
| 1304 | |
| 1305 #ifndef STATIC | |
| 1306 | |
| 1307 char *gaim_plugin_init(GModule *handle) | |
| 1308 { | |
| 1309 load_protocol(toc_init, sizeof(struct prpl)); | |
| 1310 return NULL; | |
| 1311 } | |
| 1312 | |
| 1313 void gaim_plugin_remove() | |
| 1314 { | |
| 1315 struct prpl *p = find_prpl(PROTO_TOC); | |
| 1316 if (p == my_protocol) | |
| 1317 unload_protocol(p); | |
| 1318 } | |
| 1319 | |
| 1320 char *name() | |
| 1321 { | |
| 1322 return "TOC"; | |
| 1323 } | |
| 1324 | |
| 1325 char *description() | |
| 1326 { | |
| 1327 return "Allows gaim to use the TOC protocol."; | |
| 1328 } | |
| 1329 | |
| 1330 #endif | |
| 1331 | |
| 1332 /********* | |
| 1333 * RVOUS ACTIONS | |
| 1334 ********/ | |
| 1335 | |
| 1336 struct file_header { | |
| 1337 char magic[4]; /* 0 */ | |
| 1338 short hdrlen; /* 4 */ | |
| 1339 short hdrtype; /* 6 */ | |
| 1340 char bcookie[8]; /* 8 */ | |
| 1341 short encrypt; /* 16 */ | |
| 1342 short compress; /* 18 */ | |
| 1343 short totfiles; /* 20 */ | |
| 1344 short filesleft; /* 22 */ | |
| 1345 short totparts; /* 24 */ | |
| 1346 short partsleft; /* 26 */ | |
| 1347 long totsize; /* 28 */ | |
| 1348 long size; /* 32 */ | |
| 1349 long modtime; /* 36 */ | |
| 1350 long checksum; /* 40 */ | |
| 1351 long rfrcsum; /* 44 */ | |
| 1352 long rfsize; /* 48 */ | |
| 1353 long cretime; /* 52 */ | |
| 1354 long rfcsum; /* 56 */ | |
| 1355 long nrecvd; /* 60 */ | |
| 1356 long recvcsum; /* 64 */ | |
| 1357 char idstring[32]; /* 68 */ | |
| 1358 char flags; /* 100 */ | |
| 1359 char lnameoffset; /* 101 */ | |
| 1360 char lsizeoffset; /* 102 */ | |
| 1361 char dummy[69]; /* 103 */ | |
| 1362 char macfileinfo[16]; /* 172 */ | |
| 1363 short nencode; /* 188 */ | |
| 1364 short nlanguage; /* 190 */ | |
| 1365 char name[64]; /* 192 */ | |
| 1366 /* 256 */ | |
| 1367 }; | |
| 1368 | |
| 1369 struct file_transfer { | |
| 1370 struct file_header hdr; | |
| 1371 | |
| 1372 struct gaim_connection *gc; | |
| 1373 | |
| 1374 char *user; | |
| 1375 char *cookie; | |
| 1376 char *ip; | |
| 1377 int port; | |
| 1378 long size; | |
| 1379 struct stat st; | |
| 1380 | |
| 1381 GtkWidget *window; | |
| 1382 int files; | |
| 1383 char *filename; | |
| 1384 FILE *file; | |
| 1385 int recvsize; | |
| 1386 | |
| 1387 gint inpa; | |
| 1388 }; | |
| 1389 | |
| 1390 static void debug_header(struct file_transfer *ft) { | |
| 1391 struct file_header *f = (struct file_header *)ft; | |
| 1392 debug_printf("TOC FT HEADER:\n" | |
| 1393 "\t%s %d 0x%04x\n" | |
| 1394 "\t%s %d %d\n" | |
| 1395 "\t%d %d %d %d %ld %ld\n" | |
| 1396 "\t%ld %ld %ld %ld %ld %ld %ld %ld\n" | |
| 1397 "\t%s\n" | |
| 1398 "\t0x%02x, 0x%02x, 0x%02x\n" | |
| 1399 "\t%s %s\n" | |
| 1400 "\t%d %d\n" | |
| 1401 "\t%s\n", | |
| 1402 f->magic, ntohs(f->hdrlen), f->hdrtype, | |
| 1403 f->bcookie, ntohs(f->encrypt), ntohs(f->compress), | |
| 1404 ntohs(f->totfiles), ntohs(f->filesleft), ntohs(f->totparts), | |
| 1405 ntohs(f->partsleft), ntohl(f->totsize), ntohl(f->size), | |
| 1406 ntohl(f->modtime), ntohl(f->checksum), ntohl(f->rfrcsum), ntohl(f->rfsize), | |
| 1407 ntohl(f->cretime), ntohl(f->rfcsum), ntohl(f->nrecvd), | |
| 1408 ntohl(f->recvcsum), | |
| 1409 f->idstring, | |
| 1410 f->flags, f->lnameoffset, f->lsizeoffset, | |
| 1411 f->dummy, f->macfileinfo, | |
| 1412 ntohs(f->nencode), ntohs(f->nlanguage), | |
| 1413 f->name); | |
| 1414 } | |
| 1415 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1416 static void toc_send_file_callback(gpointer data, gint source, GaimInputCondition cond) |
| 2086 | 1417 { |
| 1418 char buf[BUF_LONG]; | |
| 1419 int rt, i; | |
| 1420 | |
| 1421 struct file_transfer *ft = data; | |
| 1422 | |
| 1423 if (ft->hdr.hdrtype != 0x202) { | |
| 1424 char *buf; | |
| 1425 frombase64(ft->cookie, &buf, NULL); | |
| 1426 | |
| 1427 read(source, ft, 8); | |
| 1428 read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); | |
| 1429 debug_header(ft); | |
| 1430 | |
| 1431 ft->hdr.hdrtype = 0x202; | |
| 1432 memcpy(ft->hdr.bcookie, buf, 8); | |
| 1433 g_free(buf); | |
| 1434 ft->hdr.encrypt = 0; ft->hdr.compress = 0; | |
| 1435 debug_header(ft); | |
| 1436 write(source, ft, 256); | |
| 1437 | |
| 1438 if (ft->files == 1) { | |
| 1439 ft->file = fopen(ft->filename, "w"); | |
| 1440 if (!ft->file) { | |
| 1441 buf = g_strdup_printf("Could not open %s for writing!", ft->filename); | |
| 1442 do_error_dialog(buf, _("Error")); | |
| 1443 g_free(buf); | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1444 gaim_input_remove(ft->inpa); |
| 2086 | 1445 close(source); |
| 1446 g_free(ft->filename); | |
| 1447 g_free(ft->user); | |
| 1448 g_free(ft->ip); | |
| 1449 g_free(ft->cookie); | |
| 1450 g_free(ft); | |
| 1451 } | |
| 1452 } else { | |
| 1453 buf = g_strdup_printf("%s/%s", ft->filename, ft->hdr.name); | |
| 1454 ft->file = fopen(buf, "w"); | |
| 1455 g_free(buf); | |
| 1456 if (!ft->file) { | |
| 1457 buf = g_strdup_printf("Could not open %s/%s for writing!", ft->filename, | |
| 1458 ft->hdr.name); | |
| 1459 do_error_dialog(buf, _("Error")); | |
| 1460 g_free(buf); | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1461 gaim_input_remove(ft->inpa); |
| 2086 | 1462 close(source); |
| 1463 g_free(ft->filename); | |
| 1464 g_free(ft->user); | |
| 1465 g_free(ft->ip); | |
| 1466 g_free(ft->cookie); | |
| 1467 g_free(ft); | |
| 1468 } | |
| 1469 } | |
| 1470 | |
| 1471 return; | |
| 1472 } | |
| 1473 | |
| 1474 rt = read(source, buf, MIN(ntohl(ft->hdr.size) - ft->recvsize, 1024)); | |
| 1475 if (rt < 0) { | |
| 1476 do_error_dialog("File transfer failed; other side probably canceled.", "Error"); | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1477 gaim_input_remove(ft->inpa); |
| 2086 | 1478 close(source); |
| 1479 g_free(ft->user); | |
| 1480 g_free(ft->ip); | |
| 1481 g_free(ft->cookie); | |
| 1482 if (ft->file) | |
| 1483 fclose(ft->file); | |
| 1484 g_free(ft); | |
| 1485 return; | |
| 1486 } | |
| 1487 ft->recvsize += rt; | |
| 1488 for (i = 0; i < rt; i++) | |
| 1489 fprintf(ft->file, "%c", buf[i]); | |
| 1490 | |
| 1491 if (ft->recvsize == ntohl(ft->hdr.size)) { | |
| 1492 ft->hdr.hdrtype = htons(0x0204); | |
| 1493 ft->hdr.filesleft = htons(ntohs(ft->hdr.filesleft) - 1); | |
| 1494 ft->hdr.partsleft = htons(ntohs(ft->hdr.partsleft) - 1); | |
| 1495 ft->hdr.recvcsum = ft->hdr.checksum; /* uh... */ | |
| 1496 ft->hdr.nrecvd = htons(ntohs(ft->hdr.nrecvd) + 1); | |
| 1497 ft->hdr.flags = 0; | |
| 1498 write(source, ft, 256); | |
| 1499 debug_header(ft); | |
| 1500 ft->recvsize = 0; | |
| 1501 fclose(ft->file); | |
| 1502 if (ft->hdr.filesleft == 0) { | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1503 gaim_input_remove(ft->inpa); |
| 2086 | 1504 close(source); |
| 1505 g_free(ft->filename); | |
| 1506 g_free(ft->user); | |
| 1507 g_free(ft->ip); | |
| 1508 g_free(ft->cookie); | |
| 1509 g_free(ft); | |
| 1510 } | |
| 1511 } | |
| 1512 } | |
| 1513 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1514 static void toc_send_file_connect(gpointer data, gint src, GaimInputCondition cond) |
| 2086 | 1515 { |
| 1516 struct file_transfer *ft = data; | |
| 1517 | |
| 1518 if (src == -1) { | |
| 1519 do_error_dialog(_("Could not connect for transfer!"), _("Error")); | |
| 1520 g_free(ft->filename); | |
| 1521 g_free(ft->cookie); | |
| 1522 g_free(ft->user); | |
| 1523 g_free(ft->ip); | |
| 1524 g_free(ft); | |
| 1525 return; | |
| 1526 } | |
| 1527 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1528 ft->inpa = gaim_input_add(src, GAIM_INPUT_READ, toc_send_file_callback, ft); |
| 2086 | 1529 } |
| 1530 | |
| 1531 static void toc_send_file(gpointer a, struct file_transfer *old_ft) | |
| 1532 { | |
| 1533 struct file_transfer *ft; | |
| 1534 const char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(old_ft->window)); | |
| 1535 int fd; | |
| 1536 struct aim_user *user; | |
| 1537 char buf[BUF_LEN * 2]; | |
| 1538 | |
| 1539 if (file_is_dir(dirname, old_ft->window)) | |
| 1540 return; | |
| 1541 ft = g_new0(struct file_transfer, 1); | |
| 1542 if (old_ft->files == 1) | |
| 1543 ft->filename = g_strdup(dirname); | |
| 1544 else | |
| 1545 ft->filename = g_dirname(dirname); | |
| 1546 ft->cookie = g_strdup(old_ft->cookie); | |
| 1547 ft->user = g_strdup(old_ft->user); | |
| 1548 ft->ip = g_strdup(old_ft->ip); | |
| 1549 ft->files = old_ft->files; | |
| 1550 ft->port = old_ft->port; | |
| 1551 ft->gc = old_ft->gc; | |
| 1552 user = ft->gc->user; | |
| 1553 gtk_widget_destroy(old_ft->window); | |
| 1554 | |
| 1555 g_snprintf(buf, sizeof(buf), "toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_SEND_UID); | |
| 1556 sflap_send(ft->gc, buf, -1, TYPE_DATA); | |
| 1557 | |
| 1558 fd = | |
| 1559 proxy_connect(ft->ip, ft->port, toc_send_file_connect, ft); | |
| 1560 if (fd < 0) { | |
| 1561 do_error_dialog(_("Could not connect for transfer!"), _("Error")); | |
| 1562 g_free(ft->filename); | |
| 1563 g_free(ft->cookie); | |
| 1564 g_free(ft->user); | |
| 1565 g_free(ft->ip); | |
| 1566 g_free(ft); | |
| 1567 return; | |
| 1568 } | |
| 1569 } | |
| 1570 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1571 static void toc_get_file_callback(gpointer data, gint source, GaimInputCondition cond) |
| 2086 | 1572 { |
| 1573 char buf[BUF_LONG]; | |
| 1574 | |
| 1575 struct file_transfer *ft = data; | |
| 1576 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1577 if (cond & GAIM_INPUT_WRITE) { |
| 2086 | 1578 int remain = MIN(ntohl(ft->hdr.totsize) - ft->recvsize, 1024); |
| 1579 int i; | |
| 1580 for (i = 0; i < remain; i++) | |
| 1581 fscanf(ft->file, "%c", &buf[i]); | |
| 1582 write(source, buf, remain); | |
| 1583 ft->recvsize += remain; | |
| 1584 if (ft->recvsize == ntohl(ft->hdr.totsize)) { | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1585 gaim_input_remove(ft->inpa); |
|
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1586 ft->inpa = gaim_input_add(source, GAIM_INPUT_READ, |
| 2086 | 1587 toc_get_file_callback, ft); |
| 1588 } | |
| 1589 return; | |
| 1590 } | |
| 1591 | |
| 1592 if (ft->hdr.hdrtype == htons(0x1108)) { | |
| 1593 struct tm *fortime; | |
| 1594 struct stat st; | |
| 1595 | |
| 1596 read(source, ft, 8); | |
| 1597 read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); | |
| 1598 debug_header(ft); | |
| 1599 | |
| 1600 stat(ft->filename, &st); | |
| 1601 fortime = localtime(&st.st_mtime); | |
| 1602 g_snprintf(buf, sizeof(buf), "%2d/%2d/%4d %2d:%2d %8ld %s\r\n", | |
| 1603 fortime->tm_mon + 1, fortime->tm_mday, fortime->tm_year + 1900, | |
| 1604 fortime->tm_hour + 1, fortime->tm_min + 1, (long)st.st_size, | |
| 1605 g_basename(ft->filename)); | |
| 1606 write(source, buf, ntohl(ft->hdr.size)); | |
| 1607 return; | |
| 1608 } | |
| 1609 | |
| 1610 if (ft->hdr.hdrtype == htons(0x1209)) { | |
| 1611 read(source, ft, 8); | |
| 1612 read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); | |
| 1613 debug_header(ft); | |
| 1614 return; | |
| 1615 } | |
| 1616 | |
| 1617 if (ft->hdr.hdrtype == htons(0x120b)) { | |
| 1618 read(source, ft, 8); | |
| 1619 read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); | |
| 1620 debug_header(ft); | |
| 1621 | |
| 1622 if (ft->hdr.hdrtype != htons(0x120c)) { | |
| 1623 g_snprintf(buf, sizeof(buf), "%s decided to cancel the transfer", ft->user); | |
| 1624 do_error_dialog(buf, "Error"); | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1625 gaim_input_remove(ft->inpa); |
| 2086 | 1626 close(source); |
| 1627 g_free(ft->filename); | |
| 1628 g_free(ft->user); | |
| 1629 g_free(ft->ip); | |
| 1630 g_free(ft->cookie); | |
| 1631 if (ft->file) | |
| 1632 fclose(ft->file); | |
| 1633 g_free(ft); | |
| 1634 return; | |
| 1635 } | |
| 1636 | |
| 1637 ft->hdr.hdrtype = 0x0101; | |
| 1638 ft->hdr.totfiles = htons(1); ft->hdr.filesleft = htons(1); | |
| 1639 ft->hdr.flags = 0x20; | |
| 1640 write(source, ft, 256); | |
| 1641 return; | |
| 1642 } | |
| 1643 | |
| 1644 if (ft->hdr.hdrtype == 0x0101) { | |
| 1645 read(source, ft, 8); | |
| 1646 read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); | |
| 1647 debug_header(ft); | |
| 1648 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1649 gaim_input_remove(ft->inpa); |
|
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1650 ft->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, |
| 2086 | 1651 toc_get_file_callback, ft); |
| 1652 return; | |
| 1653 } | |
| 1654 | |
| 1655 if (ft->hdr.hdrtype == 0x0202) { | |
| 1656 read(source, ft, 8); | |
| 1657 read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); | |
| 1658 debug_header(ft); | |
| 1659 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1660 gaim_input_remove(ft->inpa); |
| 2086 | 1661 close(source); |
| 1662 g_free(ft->filename); | |
| 1663 g_free(ft->user); | |
| 1664 g_free(ft->ip); | |
| 1665 g_free(ft->cookie); | |
| 1666 if (ft->file) | |
| 1667 fclose(ft->file); | |
| 1668 g_free(ft); | |
| 1669 return; | |
| 1670 } | |
| 1671 } | |
| 1672 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1673 static void toc_get_file_connect(gpointer data, gint src, GaimInputCondition cond) |
| 2086 | 1674 { |
| 1675 struct file_transfer *ft = data; | |
| 1676 struct file_header *hdr; | |
| 1677 char *buf; | |
| 1678 | |
| 1679 if (src == -1) { | |
| 1680 do_error_dialog(_("Could not connect for transfer!"), _("Error")); | |
| 1681 fclose(ft->file); | |
| 1682 g_free(ft->filename); | |
| 1683 g_free(ft->cookie); | |
| 1684 g_free(ft->user); | |
| 1685 g_free(ft->ip); | |
| 1686 g_free(ft); | |
| 1687 return; | |
| 1688 } | |
| 1689 | |
| 1690 hdr = (struct file_header *)ft; | |
| 1691 hdr->magic[0] = 'O'; hdr->magic[1] = 'F'; hdr->magic[2] = 'T'; hdr->magic[3] = '2'; | |
| 1692 hdr->hdrlen = htons(256); | |
| 1693 hdr->hdrtype = htons(0x1108); | |
| 1694 frombase64(ft->cookie, &buf, NULL); | |
| 1695 g_snprintf(hdr->bcookie, 8, "%s", buf); | |
| 1696 g_free(buf); | |
| 1697 hdr->totfiles = htons(1); hdr->filesleft = htons(1); | |
| 1698 hdr->totparts = htons(1); hdr->partsleft = htons(1); | |
| 1699 hdr->totsize = htonl((long)ft->st.st_size); /* combined size of all files */ | |
| 1700 /* size = strlen("mm/dd/yyyy hh:mm sizesize 'name'\r\n") */ | |
| 1701 hdr->size = htonl(28 + strlen(g_basename(ft->filename))); /* size of listing.txt */ | |
| 1702 hdr->modtime = htonl(ft->st.st_mtime); | |
| 1703 hdr->checksum = htonl(0x89f70000); /* uh... */ | |
| 1704 g_snprintf(hdr->idstring, 32, "OFT_Windows ICBMFT V1.1 32"); | |
| 1705 hdr->flags = 0x02; | |
| 1706 hdr->lnameoffset = 0x1A; | |
| 1707 hdr->lsizeoffset = 0x10; | |
| 1708 g_snprintf(hdr->name, 64, "listing.txt"); | |
| 1709 if (write(src, hdr, 256) < 0) { | |
| 1710 do_error_dialog(_("Could not write file header!"), _("Error")); | |
| 1711 fclose(ft->file); | |
| 1712 g_free(ft->filename); | |
| 1713 g_free(ft->cookie); | |
| 1714 g_free(ft->user); | |
| 1715 g_free(ft->ip); | |
| 1716 g_free(ft); | |
| 1717 return; | |
| 1718 } | |
| 1719 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1720 ft->inpa = gaim_input_add(src, GAIM_INPUT_READ, toc_get_file_callback, ft); |
| 2086 | 1721 } |
| 1722 | |
| 1723 static void toc_get_file(gpointer a, struct file_transfer *old_ft) | |
| 1724 { | |
| 1725 struct file_transfer *ft; | |
| 1726 const char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(old_ft->window)); | |
| 1727 int fd; | |
| 1728 struct aim_user *user; | |
| 1729 char *buf, buf2[BUF_LEN * 2]; | |
| 1730 | |
| 1731 if (file_is_dir(dirname, old_ft->window)) | |
| 1732 return; | |
| 1733 ft = g_new0(struct file_transfer, 1); | |
| 1734 ft->filename = g_strdup(dirname); | |
| 1735 ft->file = fopen(ft->filename, "r"); | |
| 1736 if (!ft->file) { | |
| 1737 buf = g_strdup_printf("Unable to open %s for transfer!", ft->filename); | |
| 1738 do_error_dialog(buf, "Error"); | |
| 1739 g_free(buf); | |
| 1740 g_free(ft->filename); | |
| 1741 g_free(ft); | |
| 1742 return; | |
| 1743 } | |
| 1744 if (stat(dirname, &ft->st)) { | |
| 1745 buf = g_strdup_printf("Unable to examine %s!", dirname); | |
| 1746 do_error_dialog(buf, "Error"); | |
| 1747 g_free(buf); | |
| 1748 g_free(ft->filename); | |
| 1749 g_free(ft); | |
| 1750 return; | |
| 1751 } | |
| 1752 ft->cookie = g_strdup(old_ft->cookie); | |
| 1753 ft->user = g_strdup(old_ft->user); | |
| 1754 ft->ip = g_strdup(old_ft->ip); | |
| 1755 ft->port = old_ft->port; | |
| 1756 ft->gc = old_ft->gc; | |
| 1757 user = ft->gc->user; | |
| 1758 gtk_widget_destroy(old_ft->window); | |
| 1759 | |
| 1760 g_snprintf(buf2, sizeof(buf2), "toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_GET_UID); | |
| 1761 sflap_send(ft->gc, buf2, -1, TYPE_DATA); | |
| 1762 | |
| 1763 fd = | |
| 1764 proxy_connect(ft->ip, ft->port, toc_get_file_connect, ft); | |
| 1765 if (fd < 0) { | |
| 1766 do_error_dialog(_("Could not connect for transfer!"), _("Error")); | |
| 1767 fclose(ft->file); | |
| 1768 g_free(ft->filename); | |
| 1769 g_free(ft->cookie); | |
| 1770 g_free(ft->user); | |
| 1771 g_free(ft->ip); | |
| 1772 g_free(ft); | |
| 1773 return; | |
| 1774 } | |
| 1775 } | |
| 1776 | |
| 1777 static void cancel_callback(gpointer a, struct file_transfer *ft) { | |
| 1778 gtk_widget_destroy(ft->window); | |
| 1779 if (a == ft->window) { | |
| 1780 g_free(ft->cookie); | |
| 1781 g_free(ft->user); | |
| 1782 g_free(ft->ip); | |
| 1783 g_free(ft); | |
| 1784 } | |
| 1785 } | |
| 1786 | |
| 1787 static void toc_accept_ft(gpointer a, struct ft_request *fr) { | |
| 1788 GtkWidget *window; | |
| 1789 char buf[BUF_LEN]; | |
| 1790 | |
| 1791 struct file_transfer *ft = g_new0(struct file_transfer, 1); | |
| 1792 ft->gc = fr->gc; | |
| 1793 ft->user = g_strdup(fr->user); | |
| 1794 ft->cookie = g_strdup(fr->cookie); | |
| 1795 ft->ip = g_strdup(fr->ip); | |
| 1796 ft->port = fr->port; | |
| 1797 ft->files = fr->files; | |
| 1798 | |
| 1799 ft->window = window = gtk_file_selection_new(_("Gaim - Save As...")); | |
| 1800 g_snprintf(buf, sizeof(buf), "%s/%s", g_get_home_dir(), fr->filename ? fr->filename : ""); | |
| 1801 gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); | |
| 1802 gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
| 1803 GTK_SIGNAL_FUNC(cancel_callback), ft); | |
| 1804 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button), "clicked", | |
| 1805 GTK_SIGNAL_FUNC(cancel_callback), ft); | |
| 1806 | |
| 1807 if (!strcmp(fr->UID, FILE_SEND_UID)) | |
| 1808 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", | |
| 1809 GTK_SIGNAL_FUNC(toc_send_file), ft); | |
| 1810 else | |
| 1811 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", | |
| 1812 GTK_SIGNAL_FUNC(toc_get_file), ft); | |
| 1813 | |
| 1814 gtk_widget_show(window); | |
| 1815 } | |
| 1816 | |
| 1817 static void toc_reject_ft(gpointer a, struct ft_request *ft) { | |
| 1818 g_free(ft->user); | |
| 1819 g_free(ft->filename); | |
| 1820 g_free(ft->ip); | |
| 1821 g_free(ft->cookie); | |
| 1822 if (ft->message) | |
| 1823 g_free(ft->message); | |
| 1824 g_free(ft); | |
| 1825 } | |
| 1826 | |
| 1827 static void accept_file_dialog(struct ft_request *ft) { | |
| 1828 char buf[BUF_LONG]; | |
| 1829 if (!strcmp(ft->UID, FILE_SEND_UID)) { | |
| 1830 /* holy crap. who the fuck would transfer gigabytes through AIM?! */ | |
| 1831 static char *sizes[4] = { "bytes", "KB", "MB", "GB" }; | |
| 1832 float size = ft->size; | |
| 1833 int index = 0; | |
| 1834 while ((index < 4) && (size > 1024)) { | |
| 1835 size /= 1024; | |
| 1836 index++; | |
| 1837 } | |
| 1838 g_snprintf(buf, sizeof(buf), _("%s requests %s to accept %d file%s: %s (%.2f %s)%s%s"), | |
| 1839 ft->user, ft->gc->username, ft->files, (ft->files == 1) ? "" : "s", | |
| 1840 ft->filename, size, sizes[index], (ft->message) ? "\n" : "", | |
| 1841 (ft->message) ? ft->message : ""); | |
| 1842 } else { | |
| 1843 g_snprintf(buf, sizeof(buf), _("%s requests you to send them a file"), ft->user); | |
| 1844 } | |
| 1845 do_ask_dialog(buf, ft, toc_accept_ft, toc_reject_ft); | |
| 1846 } |
