Mercurial > pidgin
annotate src/toc.c @ 142:fbabd28795d2
[gaim-migrate @ 152]
Added auto-load for plugins. Rob pointed out this might be a bad idea: what
if plugins modify the buddy list; the plugins are loaded before signon, thus
before the buddy list appears. That would cause errors; then when the list
does appear, the plugin doesn't work right because it didn't start off well.
My response:
EWarmenhoven: there are ways around that
EWarmenhoven: in gaim_plugin_init you could have:
EWarmenhoven:
if (blist) {
do_the_normal_thing();
} else {
gaim_signal_connect(handle, event_signon, now_the_buddy_list_is_here, NULL);
}
EWarmenhoven: and actually, that's the way it should be for all plugins that
modify the buddy list, because there will be at least one point during
execution that it could be loaded when the person is signed off (and i'm not
talking about when they first start it up, i'm talking about when they choose
'sign off' instead of 'close' in the buddy list menu)
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Thu, 20 Apr 2000 00:12:58 +0000 |
| parents | 55faf2e3a134 |
| children | 9d684979f507 |
| rev | line source |
|---|---|
| 1 | 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 #include <netdb.h> | |
| 25 #include <gtk/gtk.h> | |
| 26 #include <unistd.h> | |
| 27 #include <errno.h> | |
| 28 #include <netinet/in.h> | |
| 29 #include <arpa/inet.h> | |
| 30 #include <string.h> | |
| 31 #include <stdlib.h> | |
| 32 #include <stdio.h> | |
| 33 #include <time.h> | |
| 34 #include <sys/socket.h> | |
| 35 #include "gaim.h" | |
| 36 #include "gnome_applet_mgr.h" | |
| 37 | |
| 38 | |
| 39 | |
| 40 /* descriptor for talking to TOC */ | |
| 41 static int toc_fd; | |
| 42 static int seqno; | |
| 43 static unsigned int peer_ver=0; | |
| 44 static int state; | |
| 45 static int inpa=-1; | |
| 46 #ifdef _WIN32 | |
| 47 static int win32_r; | |
| 48 #endif | |
| 49 | |
| 50 int toc_signon(char *username, char *password); | |
| 51 | |
| 52 | |
| 53 | |
| 54 int toc_login(char *username, char *password) | |
| 55 { | |
| 56 char *config; | |
| 57 struct in_addr *sin; | |
| 58 struct aim_user *u; | |
| 59 char buf[80]; | |
| 60 char buf2[2048]; | |
| 61 | |
| 62 g_snprintf(buf, sizeof(buf), "Looking up %s", aim_host); | |
| 63 set_login_progress(1, buf); | |
| 64 | |
| 65 sin = (struct in_addr *)get_address(aim_host); | |
| 66 if (!sin) { | |
| 67 | |
| 68 #ifdef USE_APPLET | |
| 69 setUserState(offline); | |
| 70 #endif /* USE_APPLET */ | |
| 71 set_state(STATE_OFFLINE); | |
| 72 g_snprintf(buf, sizeof(buf), "Unable to lookup %s", aim_host); | |
| 73 hide_login_progress(buf); | |
| 74 return -1; | |
| 75 } | |
| 76 | |
| 77 g_snprintf(toc_addy, sizeof(toc_addy), "%s", inet_ntoa(*sin)); | |
| 78 g_snprintf(buf, sizeof(buf), "Connecting to %s", inet_ntoa(*sin)); | |
| 79 | |
| 80 set_login_progress(2, buf); | |
| 81 | |
| 82 | |
| 83 | |
| 84 toc_fd = connect_address(sin->s_addr, aim_port); | |
| 85 | |
| 86 if (toc_fd < 0) { | |
| 87 #ifdef USE_APPLET | |
| 88 setUserState(offline); | |
| 89 #endif /* USE_APPLET */ | |
| 90 set_state(STATE_OFFLINE); | |
| 91 g_snprintf(buf, sizeof(buf), "Connect to %s failed", | |
| 92 inet_ntoa(*sin)); | |
| 93 hide_login_progress(buf); | |
| 94 return -1; | |
| 95 } | |
| 96 | |
| 97 g_free(sin); | |
| 98 | |
| 99 g_snprintf(buf, sizeof(buf), "Signon: %s",username); | |
| 100 | |
| 101 set_login_progress(3, buf); | |
| 102 | |
| 103 if (toc_signon(username, password) < 0) { | |
| 104 #ifdef USE_APPLET | |
| 105 setUserState(offline); | |
| 106 #endif /* USE_APPLET */ | |
| 107 set_state(STATE_OFFLINE); | |
| 108 hide_login_progress("Disconnected."); | |
| 109 return -1; | |
| 110 } | |
| 111 | |
| 112 g_snprintf(buf, sizeof(buf), "Waiting for reply..."); | |
| 113 set_login_progress(4, buf); | |
| 114 if (toc_wait_signon() < 0) { | |
| 115 #ifdef USE_APPLET | |
| 116 setUserState(offline); | |
| 117 #endif /* USE_APPLET */ | |
| 118 set_state(STATE_OFFLINE); | |
| 119 hide_login_progress("Authentication Failed"); | |
| 120 return -1; | |
| 121 } | |
| 122 | |
| 123 u = find_user(username); | |
| 124 | |
| 125 if (!u) { | |
| 126 u = g_new0(struct aim_user, 1); | |
| 127 g_snprintf(u->user_info, sizeof(u->user_info), DEFAULT_INFO); | |
| 128 aim_users = g_list_append(aim_users, u); | |
| 129 } | |
| 130 | |
| 131 current_user = u; | |
| 132 | |
| 133 g_snprintf(current_user->username, sizeof(current_user->username), "%s", username); | |
| 134 g_snprintf(current_user->password, sizeof(current_user->password), "%s", password); | |
| 135 | |
| 136 save_prefs(); | |
| 137 | |
| 138 g_snprintf(buf, sizeof(buf), "Retrieving config..."); | |
| 139 set_login_progress(5, buf); | |
| 140 if ((config=toc_wait_config()) == NULL) { | |
| 141 hide_login_progress("No Configuration"); | |
| 142 set_state(STATE_OFFLINE); | |
| 143 return -1; | |
| 144 | |
| 145 } | |
| 146 | |
| 147 | |
| 148 #ifdef USE_APPLET | |
|
107
55faf2e3a134
[gaim-migrate @ 117]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
79
diff
changeset
|
149 make_buddy(); |
| 10 | 150 if (general_options & OPT_GEN_APP_BUDDY_SHOW) { |
| 50 | 151 gnome_buddy_show(); |
| 1 | 152 parse_toc_buddy_list(config); |
| 50 | 153 createOnlinePopup(); |
| 1 | 154 set_applet_draw_open(); |
| 155 } else { | |
| 156 gnome_buddy_hide(); | |
| 157 parse_toc_buddy_list(config); | |
| 158 set_applet_draw_closed(); | |
| 159 } | |
| 160 | |
| 161 | |
| 162 setUserState(online); | |
| 10 | 163 gtk_widget_hide(mainwindow); |
| 1 | 164 #else |
| 165 gtk_widget_hide(mainwindow); | |
| 166 show_buddy_list(); | |
| 167 parse_toc_buddy_list(config); | |
| 168 refresh_buddy_window(); | |
| 169 #endif | |
| 170 | |
| 171 | |
| 172 g_snprintf(buf2, sizeof(buf2), "toc_init_done"); | |
| 173 sflap_send(buf2, -1, TYPE_DATA); | |
| 174 | |
| 175 #if 0 | |
| 176 g_snprintf(buf2, sizeof(buf2), "toc_set_caps %s", | |
| 177 FILETRANS_UID); | |
| 178 sflap_send(buf2, -1, TYPE_DATA); | |
| 179 #endif | |
| 180 | |
| 181 serv_finish_login(); | |
| 182 return 0; | |
| 183 } | |
| 184 | |
| 185 void toc_close() | |
| 186 { | |
| 187 #ifdef USE_APPLET | |
| 188 setUserState(offline); | |
| 189 #endif /* USE_APPLET */ | |
| 190 seqno = 0; | |
| 191 state = STATE_OFFLINE; | |
| 192 if (inpa > 0) | |
| 193 gdk_input_remove(inpa); | |
| 194 close(toc_fd); | |
| 195 toc_fd=-1; | |
| 196 inpa=-1; | |
| 197 } | |
| 198 | |
| 199 unsigned char *roast_password(char *pass) | |
| 200 { | |
| 201 /* Trivial "encryption" */ | |
| 202 static char rp[256]; | |
| 203 static char *roast = ROAST; | |
| 204 int pos=2; | |
| 205 int x; | |
| 206 strcpy(rp, "0x"); | |
| 207 for (x=0;(x<150) && pass[x]; x++) | |
| 208 pos+=sprintf(&rp[pos],"%02x", pass[x] ^ roast[x % strlen(roast)]); | |
| 209 rp[pos]='\0'; | |
| 210 return rp; | |
| 211 } | |
| 212 | |
| 213 | |
| 214 char *print_header(void *hdr_v) | |
| 215 { | |
| 216 static char s[80]; | |
| 217 struct sflap_hdr *hdr = (struct sflap_hdr *)hdr_v; | |
| 218 g_snprintf(s,sizeof(s), "[ ast: %c, type: %d, seqno: %d, len: %d ]", | |
| 219 hdr->ast, hdr->type, ntohs(hdr->seqno), ntohs(hdr->len)); | |
| 220 return s; | |
| 221 } | |
| 222 | |
| 223 void print_buffer(char *buf, int len) | |
| 224 { | |
| 225 #if 0 | |
| 226 int x; | |
| 227 printf("[ "); | |
| 228 for (x=0;x<len;x++) | |
| 229 printf("%d ", buf[x]); | |
| 230 printf("]\n"); | |
| 231 printf("[ "); | |
| 232 for (x=0;x<len;x++) | |
| 233 printf("%c ", buf[x]); | |
| 234 printf("]\n"); | |
| 235 #endif | |
| 236 } | |
| 237 | |
| 238 int sflap_send(char *buf, int olen, int type) | |
| 239 { | |
| 240 int len; | |
| 241 int slen=0; | |
| 242 struct sflap_hdr hdr; | |
| 243 char obuf[MSG_LEN]; | |
| 244 | |
| 245 /* One _last_ 2048 check here! This shouldn't ever | |
| 246 * get hit though, hopefully. If it gets hit on an IM | |
| 247 * It'll lose the last " and the message won't go through, | |
| 248 * but this'll stop a segfault. */ | |
| 249 if (strlen(buf) > (MSG_LEN - sizeof(hdr))) { | |
| 250 buf[MSG_LEN - sizeof(hdr) - 3] = '"'; | |
| 251 buf[MSG_LEN - sizeof(hdr) - 2] = '\0'; | |
| 252 } | |
| 253 | |
| 254 sprintf(debug_buff,"%s [Len %d]\n", buf, strlen(buf)); | |
| 255 debug_print(debug_buff); | |
| 256 | |
| 257 | |
| 258 | |
| 259 if (olen < 0) | |
| 260 len = escape_message(buf); | |
| 261 else | |
| 262 len = olen; | |
| 263 hdr.ast = '*'; | |
| 264 hdr.type = type; | |
| 265 hdr.seqno = htons(seqno++ & 0xffff); | |
| 266 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); | |
| 267 | |
| 268 sprintf(debug_buff,"Escaped message is '%s'\n",buf); | |
| 269 debug_print(debug_buff); | |
| 270 | |
| 271 memcpy(obuf, &hdr, sizeof(hdr)); | |
| 272 slen += sizeof(hdr); | |
| 273 memcpy(&obuf[slen], buf, len); | |
| 274 slen += len; | |
| 275 if (type != TYPE_SIGNON) { | |
| 276 obuf[slen]='\0'; | |
| 277 slen += 1; | |
| 278 } | |
| 279 print_buffer(obuf, slen); | |
| 280 | |
| 281 return write(toc_fd, obuf, slen); | |
| 282 } | |
| 283 | |
| 284 | |
| 79 | 285 int wait_reply(char *buffer, size_t buflen) |
| 1 | 286 { |
| 79 | 287 size_t res=-1; |
| 288 int read_rv = -1; | |
| 1 | 289 struct sflap_hdr *hdr=(struct sflap_hdr *)buffer; |
| 290 char *c; | |
| 291 | |
| 79 | 292 if(buflen < sizeof(struct sflap_hdr)) { |
| 293 do_error_dialog("Buffer too small", "Gaim - Error (internal)"); | |
| 294 return -1; | |
| 295 } | |
| 296 | |
| 297 while((read_rv = read(toc_fd, buffer, 1))) { | |
| 298 if (read_rv < 0 || read_rv > 1) | |
| 299 return -1; | |
| 1 | 300 if (buffer[0] == '*') |
| 301 break; | |
| 302 | |
| 303 } | |
| 304 | |
| 79 | 305 read_rv = read(toc_fd, buffer+1, sizeof(struct sflap_hdr) - 1); |
| 1 | 306 |
| 79 | 307 if (read_rv < 0) |
| 308 return read_rv; | |
| 1 | 309 |
| 79 | 310 res = read_rv + 1; |
| 1 | 311 |
| 312 | |
| 313 sprintf(debug_buff, "Rcv: %s %s\n",print_header(buffer), ""); | |
| 314 debug_print(debug_buff); | |
| 315 | |
| 316 | |
| 79 | 317 if(buflen < sizeof(struct sflap_hdr) + ntohs(hdr->len) + 1) { |
| 318 do_error_dialog("Buffer too small", "Gaim - Error (internal)"); | |
| 319 return -1; | |
| 320 } | |
| 1 | 321 |
| 322 while (res < (sizeof(struct sflap_hdr) + ntohs(hdr->len))) { | |
| 79 | 323 read_rv = read(toc_fd, buffer + res, (ntohs(hdr->len) + sizeof(struct sflap_hdr)) - res); |
| 324 if(read_rv < 0) return read_rv; | |
| 325 res += read_rv; | |
| 1 | 326 while(gtk_events_pending()) |
| 327 gtk_main_iteration(); | |
| 328 } | |
| 329 | |
| 330 if (res >= sizeof(struct sflap_hdr)) | |
| 331 buffer[res]='\0'; | |
| 332 else | |
| 333 return res - sizeof(struct sflap_hdr); | |
| 334 | |
| 335 switch(hdr->type) { | |
| 336 case TYPE_SIGNON: | |
| 337 memcpy(&peer_ver, buffer + sizeof(struct sflap_hdr), 4); | |
| 338 peer_ver = ntohl(peer_ver); | |
| 339 seqno = ntohs(hdr->seqno); | |
| 340 state = STATE_SIGNON_REQUEST; | |
| 341 break; | |
| 342 case TYPE_DATA: | |
| 343 if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "SIGN_ON:", strlen("SIGN_ON:"))) | |
| 344 state = STATE_SIGNON_ACK; | |
| 345 else if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "CONFIG:", strlen("CONFIG:"))) { | |
| 346 state = STATE_CONFIG; | |
| 347 } else if (state != STATE_ONLINE && !strncasecmp(buffer + sizeof(struct sflap_hdr), "ERROR:", strlen("ERROR:"))) { | |
| 348 c = strtok(buffer + sizeof(struct sflap_hdr) + strlen("ERROR:"), ":"); | |
| 349 show_error_dialog(c); | |
| 350 } | |
| 351 | |
| 352 sprintf(debug_buff, "Data: %s\n",buffer + sizeof(struct sflap_hdr)); | |
| 353 debug_print(debug_buff); | |
| 354 | |
| 355 break; | |
| 356 default: | |
| 357 sprintf(debug_buff, "Unknown/unimplemented packet type %d\n",hdr->type); | |
| 358 debug_print(debug_buff); | |
| 359 } | |
| 360 return res; | |
| 361 } | |
| 362 | |
| 363 | |
| 364 | |
| 365 void toc_callback( gpointer data, | |
| 366 gint source, | |
| 367 GdkInputCondition condition ) | |
| 368 { | |
| 369 char *buf; | |
| 370 char *c; | |
| 371 char *l; | |
| 372 | |
| 373 buf = g_malloc(BUF_LONG); | |
| 374 if (wait_reply(buf, BUF_LONG) < 0) { | |
| 375 signoff(); | |
| 376 hide_login_progress("Connection Closed"); | |
| 377 g_free(buf); | |
| 378 return; | |
| 379 } | |
| 380 | |
| 381 | |
| 382 c=strtok(buf+sizeof(struct sflap_hdr),":"); /* Ditch the first part */ | |
| 383 if (!strcasecmp(c,"UPDATE_BUDDY")) { | |
| 384 char *uc; | |
| 385 int logged, evil, idle, type = 0; | |
| 386 time_t signon; | |
| 387 time_t time_idle; | |
| 388 | |
| 389 c = strtok(NULL,":"); /* c is name */ | |
| 390 | |
| 391 l = strtok(NULL,":"); /* l is T/F logged status */ | |
| 392 | |
| 393 sscanf(strtok(NULL, ":"), "%d", &evil); | |
| 394 | |
| 395 sscanf(strtok(NULL, ":"), "%ld", &signon); | |
| 396 | |
| 397 sscanf(strtok(NULL, ":"), "%d", &idle); | |
| 398 | |
| 399 uc = strtok(NULL, ":"); | |
| 400 | |
| 401 | |
| 402 if (!strncasecmp(l,"T",1)) | |
| 403 logged = 1; | |
| 404 else | |
| 405 logged = 0; | |
| 406 | |
| 407 | |
| 408 if (uc[0] == 'A') | |
| 409 type |= UC_AOL; | |
| 410 | |
| 411 switch(uc[1]) { | |
| 412 case 'A': | |
| 413 type |= UC_ADMIN; | |
| 414 break; | |
| 415 case 'U': | |
| 416 type |= UC_UNCONFIRMED; | |
| 417 break; | |
| 418 case 'O': | |
| 419 type |= UC_NORMAL; | |
| 420 break; | |
| 421 default: | |
| 422 break; | |
| 423 } | |
| 424 | |
| 425 switch(uc[2]) { | |
| 426 case 'U': | |
| 427 type |= UC_UNAVAILABLE; | |
| 428 break; | |
| 429 default: | |
| 430 break; | |
| 431 } | |
| 432 | |
| 433 if (idle) { | |
| 434 time(&time_idle); | |
| 435 time_idle -= idle*60; | |
| 436 } else | |
| 437 time_idle = 0; | |
| 438 | |
| 439 serv_got_update(c, logged, evil, signon, time_idle, type); | |
| 440 | |
| 441 } else if (!strcasecmp(c, "ERROR")) { | |
| 442 c = strtok(NULL,":"); | |
| 443 show_error_dialog(c); | |
| 444 } else if (!strcasecmp(c, "NICK")) { | |
| 445 c = strtok(NULL,":"); | |
| 446 g_snprintf(current_user->username, sizeof(current_user->username), "%s", c); | |
| 447 } else if (!strcasecmp(c, "IM_IN")) { | |
| 448 char *away, *message; | |
| 449 int a = 0; | |
| 450 | |
| 451 c = strtok(NULL,":"); | |
| 452 away = strtok(NULL,":"); | |
| 453 | |
| 454 message = away; | |
| 455 | |
| 456 while(*message && (*message != ':')) | |
| 457 message++; | |
| 458 | |
| 459 message++; | |
| 460 | |
| 461 if (!strncasecmp(away, "T", 1)) | |
| 462 a = 1; | |
| 463 serv_got_im(c, message, a); | |
| 464 | |
| 465 } else if (!strcasecmp(c, "GOTO_URL")) { | |
| 466 char *name; | |
| 467 char *url; | |
| 468 | |
| 469 char tmp[256]; | |
| 470 | |
| 471 name = strtok(NULL, ":"); | |
| 472 url = strtok(NULL, ":"); | |
| 473 | |
| 474 | |
| 475 g_snprintf(tmp, sizeof(tmp), "http://%s:%d/%s", toc_addy, aim_port, url); | |
| 476 /* fprintf(stdout, "Name: %s\n%s\n", name, url); | |
| 477 printf("%s", grab_url(tmp));*/ | |
| 478 g_show_info(tmp); | |
| 479 } else if (!strcasecmp(c, "EVILED")) { | |
| 480 int lev; | |
| 481 char *name = NULL; | |
| 482 | |
| 483 sscanf(strtok(NULL, ":"), "%d", &lev); | |
| 484 name = strtok(NULL, ":"); | |
| 485 | |
| 486 sprintf(debug_buff,"%s | %d\n", name, lev); | |
| 487 debug_print(debug_buff); | |
| 488 | |
| 489 serv_got_eviled(name, lev); | |
| 490 | |
| 491 } else if (!strcasecmp(c, "CHAT_JOIN")) { | |
| 492 char *name; | |
| 493 int id; | |
| 494 | |
| 495 | |
| 496 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 497 name = strtok(NULL, ":"); | |
| 498 serv_got_joined_chat(id, name); | |
| 499 | |
| 500 } else if (!strcasecmp(c, "DIR_STATUS")) { | |
| 501 } else if (!strcasecmp(c, "CHAT_UPDATE_BUDDY")) { | |
| 502 int id; | |
| 503 char *in; | |
| 504 char *buddy; | |
| 505 GList *bcs = buddy_chats; | |
| 506 struct buddy_chat *b = NULL; | |
| 507 | |
| 508 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 509 | |
| 510 in = strtok(NULL, ":"); | |
| 511 | |
| 512 while(bcs) { | |
| 513 b = (struct buddy_chat *)bcs->data; | |
| 514 if (id == b->id) | |
| 515 break; | |
| 516 bcs = bcs->next; | |
| 517 b = NULL; | |
| 518 } | |
| 519 | |
| 44 | 520 if (!b) { |
| 45 | 521 g_free(buf); |
| 1 | 522 return; |
| 44 | 523 } |
| 1 | 524 |
| 525 | |
| 526 if (!strcasecmp(in, "T")) { | |
| 527 while((buddy = strtok(NULL, ":")) != NULL) { | |
| 528 add_chat_buddy(b, buddy); | |
| 529 } | |
| 530 } else { | |
| 531 while((buddy = strtok(NULL, ":")) != NULL) { | |
| 532 remove_chat_buddy(b, buddy); | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 } else if (!strcasecmp(c, "CHAT_LEFT")) { | |
| 537 int id; | |
| 538 | |
| 539 | |
| 540 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 541 | |
| 542 serv_got_chat_left(id); | |
| 543 | |
| 544 | |
| 545 } else if (!strcasecmp(c, "CHAT_IN")) { | |
| 546 | |
| 547 int id, w; | |
| 548 char *m; | |
| 549 char *who, *whisper; | |
| 550 | |
| 551 | |
| 552 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 553 who = strtok(NULL, ":"); | |
| 554 whisper = strtok(NULL, ":"); | |
| 555 m = whisper; | |
| 556 while(*m && (*m != ':')) m++; | |
| 557 m++; | |
| 558 | |
| 559 if (!strcasecmp(whisper, "T")) | |
| 560 w = 1; | |
| 561 else | |
| 562 w = 0; | |
| 563 | |
| 564 serv_got_chat_in(id, who, w, m); | |
| 565 | |
| 566 | |
| 567 } else if (!strcasecmp(c, "CHAT_INVITE")) { | |
| 568 char *name; | |
| 569 char *who; | |
| 570 char *message; | |
| 571 int id; | |
| 572 | |
| 573 | |
| 574 name = strtok(NULL, ":"); | |
| 575 sscanf(strtok(NULL, ":"), "%d", &id); | |
| 576 who = strtok(NULL, ":"); | |
| 577 message = strtok(NULL, ":"); | |
| 578 | |
| 579 serv_got_chat_invite(name, id, who, message); | |
| 580 | |
| 581 | |
| 582 #if 0 | |
| 583 } else if (!strcasecmp(c, "RVOUS_PROPOSE")) { | |
| 584 /* File trans. Yummy. */ | |
| 585 char *user; | |
| 586 char *uuid; | |
| 587 char *cookie; | |
| 588 int seq; | |
| 589 char *rip, *pip, *vip; | |
| 590 int port; | |
| 591 int unk[4]; | |
| 592 char *messages[4]; | |
| 593 int subtype, files, totalsize; | |
| 594 char *name; | |
| 595 char *tmp; | |
| 596 int i; | |
| 597 struct file_transfer *ft; | |
| 598 | |
| 599 | |
| 600 user = strtok(NULL, ":"); | |
| 601 uuid = strtok(NULL, ":"); | |
| 602 cookie = strtok(NULL, ":"); | |
| 603 sscanf(strtok(NULL, ":"), "%d", &seq); | |
| 604 rip = strtok(NULL, ":"); | |
| 605 pip = strtok(NULL, ":"); | |
| 606 vip = strtok(NULL, ":"); | |
| 607 sscanf(strtok(NULL, ":"), "%d", &port); | |
| 608 for (i=0; i<4; i++) { | |
| 609 sscanf(strtok(NULL, ":"), "%d", &unk[i]); | |
| 610 if (unk[i] == 10001) | |
| 611 break; | |
| 612 messages[i] = frombase64(strtok(NULL, ":")); | |
| 613 } | |
| 614 | |
| 615 tmp = frombase64(strtok(NULL, ":")); | |
| 616 | |
| 617 subtype = tmp[1]; | |
| 618 files = tmp[3]; /* These are fine */ | |
| 619 | |
| 620 totalsize = (tmp[4] << 24 & 0xff) | | |
| 621 (tmp[5] << 16 & 0xff) | | |
| 622 (tmp[6] << 8 & 0xff) | | |
| 623 (tmp[7] & 0xff); | |
| 624 | |
| 625 name = tmp + 8; | |
| 626 | |
| 627 ft = g_new0(struct file_transfer, 1); | |
| 628 | |
| 629 ft->cookie = g_strdup(cookie); | |
| 630 ft->ip = g_strdup(pip); | |
| 631 ft->port = port; | |
| 632 if (i) | |
| 633 ft->message = g_strdup(messages[0]); | |
| 634 else | |
| 635 ft->message = NULL; | |
| 636 ft->filename = g_strdup(name); | |
| 637 ft->user = g_strdup(user); | |
| 638 ft->size = totalsize; | |
| 639 | |
| 640 g_free(tmp); | |
| 641 | |
| 642 for (i--; i >= 0; i--) | |
| 643 g_free(messages[i]); | |
| 644 | |
| 645 accept_file_dialog(ft); | |
| 646 #endif | |
| 647 } else { | |
| 648 sprintf(debug_buff,"don't know what to do with %s\n", c); | |
| 649 debug_print(debug_buff); | |
| 650 } | |
| 651 g_free(buf); | |
| 652 } | |
| 653 | |
| 654 | |
| 655 int toc_signon(char *username, char *password) | |
| 656 { | |
| 657 char buf[BUF_LONG]; | |
| 658 int res; | |
| 659 struct signon so; | |
| 660 | |
| 661 sprintf(debug_buff,"State = %d\n", state); | |
| 662 debug_print(debug_buff); | |
| 663 | |
| 664 if ((res = write(toc_fd, FLAPON, strlen(FLAPON))) < 0) | |
| 665 return res; | |
| 666 /* Wait for signon packet */ | |
| 667 | |
| 668 state = STATE_FLAPON; | |
| 669 | |
| 670 if ((res = wait_reply(buf, sizeof(buf)) < 0)) | |
| 671 return res; | |
| 672 | |
| 673 if (state != STATE_SIGNON_REQUEST) { | |
| 674 sprintf(debug_buff, "State should be %d, but is %d instead\n", STATE_SIGNON_REQUEST, state); | |
| 675 debug_print(debug_buff); | |
| 676 return -1; | |
| 677 } | |
| 678 | |
| 679 /* Compose a response */ | |
| 680 | |
| 681 g_snprintf(so.username, sizeof(so.username), "%s", username); | |
| 682 so.ver = ntohl(1); | |
| 683 so.tag = ntohs(1); | |
| 684 so.namelen = htons(strlen(so.username)); | |
| 685 | |
| 686 sflap_send((char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON); | |
| 687 | |
| 688 g_snprintf(buf, sizeof(buf), | |
| 689 "toc_signon %s %d %s %s %s \"%s\"", | |
| 690 login_host, login_port, normalize(username), roast_password(password), LANGUAGE, REVISION); | |
| 691 | |
| 692 sprintf(debug_buff,"Send: %s\n", buf); | |
| 693 debug_print(debug_buff); | |
| 694 | |
| 695 return sflap_send(buf, -1, TYPE_DATA); | |
| 696 } | |
| 697 | |
| 698 int toc_wait_signon() | |
| 699 { | |
| 700 /* Wait for the SIGNON to be approved */ | |
| 701 char buf[BUF_LEN]; | |
| 702 int res; | |
| 703 res = wait_reply(buf, sizeof(buf)); | |
| 704 if (res < 0) | |
| 705 return res; | |
| 706 if (state != STATE_SIGNON_ACK) { | |
| 707 sprintf(debug_buff, "State should be %d, but is %d instead\n",STATE_SIGNON_ACK, state); | |
| 708 debug_print(debug_buff); | |
| 709 return -1; | |
| 710 } | |
| 711 return 0; | |
| 712 } | |
| 713 | |
| 714 #ifdef _WIN32 | |
| 715 gint win32_read() | |
| 716 { | |
| 717 int ret; | |
| 718 struct fd_set fds; | |
| 719 struct timeval tv; | |
| 720 | |
| 721 FD_ZERO(&fds); | |
| 722 | |
| 723 tv.tv_sec = 0; | |
| 724 tv.tv_usec = 200; | |
| 725 | |
| 726 FD_SET(toc_fd, &fds); | |
| 727 | |
| 728 ret = select(toc_fd + 1, &fds, NULL, NULL, &tv); | |
| 729 | |
| 730 if (ret == 0) { | |
| 731 return TRUE; | |
| 732 } | |
| 733 | |
| 734 toc_callback(NULL, 0, (GdkInputCondition)0); | |
| 735 return TRUE; | |
| 736 } | |
| 737 #endif | |
| 738 | |
| 739 | |
| 740 char *toc_wait_config() | |
| 741 { | |
| 742 /* Waits for configuration packet, returning the contents of the packet */ | |
| 743 static char buf[BUF_LEN]; | |
| 744 int res; | |
| 745 res = wait_reply(buf, sizeof(buf)); | |
| 746 if (res < 0) | |
| 747 return NULL; | |
| 748 if (state != STATE_CONFIG) { | |
| 749 sprintf(debug_buff , "State should be %d, but is %d instead\n",STATE_CONFIG, state); | |
| 750 debug_print(debug_buff); | |
| 751 return NULL; | |
| 752 } | |
| 753 /* At this point, it's time to setup automatic handling of incoming packets */ | |
| 754 state = STATE_ONLINE; | |
| 755 #ifdef _WIN32 | |
| 756 win32_r = gtk_timeout_add(1000, (GtkFunction)win32_read, NULL); | |
| 757 #else | |
| 758 inpa = gdk_input_add(toc_fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_callback, NULL); | |
| 759 #endif | |
| 760 return buf; | |
| 761 } | |
| 762 | |
| 763 | |
| 764 void toc_build_config(char *s, int len) | |
| 765 { | |
| 766 GList *grp = groups; | |
| 767 GList *mem; | |
| 768 struct group *g; | |
| 769 struct buddy *b; | |
| 770 GList *plist = permit; | |
| 771 GList *dlist = deny; | |
| 772 | |
| 773 int pos=0; | |
| 774 | |
| 775 if (!permdeny) | |
| 776 permdeny = 1; | |
| 777 pos += g_snprintf(&s[pos], len - pos, "m %d\n", permdeny); | |
| 778 while(grp) { | |
| 779 g = (struct group *)grp->data; | |
| 780 pos += g_snprintf(&s[pos], len - pos, "g %s\n", g->name); | |
| 781 mem = g->members; | |
| 782 while(mem) { | |
| 783 b = (struct buddy *)mem->data; | |
| 784 pos += g_snprintf(&s[pos], len - pos, "b %s\n", b->name); | |
| 785 mem = mem->next; | |
| 786 } | |
| 787 grp = grp ->next; | |
| 788 } | |
| 789 while(plist) { | |
| 790 pos += g_snprintf(&s[pos], len - pos, "p %s\n", (char *)plist->data); | |
| 791 plist=plist->next; | |
| 792 | |
| 793 } | |
| 794 while(dlist) { | |
| 795 pos += g_snprintf(&s[pos], len - pos, "d %s\n", (char *)dlist->data); | |
| 796 dlist=dlist->next; | |
| 797 } | |
| 798 } | |
| 799 | |
| 800 void parse_toc_buddy_list(char *config) | |
| 801 { | |
| 802 char *c; | |
| 803 char current[256]; | |
| 804 char *name; | |
| 805 GList *bud; | |
| 806 /* Clean out the permit/deny list!*/ | |
| 807 g_list_free(permit); | |
| 808 g_list_free(deny); | |
| 809 permit = NULL; | |
| 810 deny = NULL; | |
| 811 bud = NULL; | |
| 812 | |
| 813 | |
| 814 /* skip "CONFIG:" (if it exists)*/ | |
| 815 | |
| 816 c = strncmp(config + sizeof(struct sflap_hdr),"CONFIG:",strlen("CONFIG:"))? | |
| 817 strtok(config, "\n"): | |
| 818 strtok(config + sizeof(struct sflap_hdr)+strlen("CONFIG:"), "\n"); | |
| 819 do { | |
| 820 if (c == NULL) | |
| 821 break; | |
| 822 if (*c == 'g') { | |
| 823 strncpy(current,c+2, sizeof(current)); | |
| 824 add_group(current); | |
| 825 } else if (*c == 'b') { | |
| 826 add_buddy(current, c+2); | |
| 827 bud = g_list_append(bud, c+2); | |
| 828 } else if (*c == 'p') { | |
| 829 name = g_malloc(strlen(c+2) + 2); | |
| 830 g_snprintf(name, strlen(c+2) + 1, "%s", c+2); | |
| 831 permit = g_list_append(permit, name); | |
| 832 } else if (*c == 'd') { | |
| 833 name = g_malloc(strlen(c+2) + 2); | |
| 834 g_snprintf(name, strlen(c+2) + 1, "%s", c+2); | |
| 835 deny = g_list_append(deny, name); | |
| 836 } else if (*c == 'm') { | |
| 837 sscanf(c + strlen(c) - 1, "%d", &permdeny); | |
| 838 if (permdeny == 0) | |
| 839 permdeny = 1; | |
| 840 } | |
| 841 }while((c=strtok(NULL,"\n"))); | |
| 842 #if 0 | |
| 843 fprintf(stdout, "Sending message '%s'\n",buf); | |
| 844 #endif | |
| 845 | |
| 846 serv_add_buddies(bud); | |
| 847 serv_set_permit_deny(); | |
| 848 } |
