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