| |
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 |
| |
149 if (applet_buddy_auto_show) { |
| |
150 make_buddy(); |
| |
151 parse_toc_buddy_list(config); |
| |
152 refresh_buddy_window(); |
| |
153 set_applet_draw_open(); |
| |
154 } else { |
| |
155 make_buddy(); |
| |
156 gnome_buddy_hide(); |
| |
157 parse_toc_buddy_list(config); |
| |
158 set_applet_draw_closed(); |
| |
159 } |
| |
160 |
| |
161 |
| |
162 setUserState(online); |
| |
163 #else |
| |
164 gtk_widget_hide(mainwindow); |
| |
165 show_buddy_list(); |
| |
166 parse_toc_buddy_list(config); |
| |
167 refresh_buddy_window(); |
| |
168 #endif |
| |
169 |
| |
170 |
| |
171 g_snprintf(buf2, sizeof(buf2), "toc_init_done"); |
| |
172 sflap_send(buf2, -1, TYPE_DATA); |
| |
173 |
| |
174 #if 0 |
| |
175 g_snprintf(buf2, sizeof(buf2), "toc_set_caps %s", |
| |
176 FILETRANS_UID); |
| |
177 sflap_send(buf2, -1, TYPE_DATA); |
| |
178 #endif |
| |
179 |
| |
180 serv_finish_login(); |
| |
181 return 0; |
| |
182 } |
| |
183 |
| |
184 void toc_close() |
| |
185 { |
| |
186 #ifdef USE_APPLET |
| |
187 setUserState(offline); |
| |
188 #endif /* USE_APPLET */ |
| |
189 seqno = 0; |
| |
190 state = STATE_OFFLINE; |
| |
191 if (inpa > 0) |
| |
192 gdk_input_remove(inpa); |
| |
193 close(toc_fd); |
| |
194 toc_fd=-1; |
| |
195 inpa=-1; |
| |
196 } |
| |
197 |
| |
198 unsigned char *roast_password(char *pass) |
| |
199 { |
| |
200 /* Trivial "encryption" */ |
| |
201 static char rp[256]; |
| |
202 static char *roast = ROAST; |
| |
203 int pos=2; |
| |
204 int x; |
| |
205 strcpy(rp, "0x"); |
| |
206 for (x=0;(x<150) && pass[x]; x++) |
| |
207 pos+=sprintf(&rp[pos],"%02x", pass[x] ^ roast[x % strlen(roast)]); |
| |
208 rp[pos]='\0'; |
| |
209 return rp; |
| |
210 } |
| |
211 |
| |
212 |
| |
213 char *print_header(void *hdr_v) |
| |
214 { |
| |
215 static char s[80]; |
| |
216 struct sflap_hdr *hdr = (struct sflap_hdr *)hdr_v; |
| |
217 g_snprintf(s,sizeof(s), "[ ast: %c, type: %d, seqno: %d, len: %d ]", |
| |
218 hdr->ast, hdr->type, ntohs(hdr->seqno), ntohs(hdr->len)); |
| |
219 return s; |
| |
220 } |
| |
221 |
| |
222 void print_buffer(char *buf, int len) |
| |
223 { |
| |
224 #if 0 |
| |
225 int x; |
| |
226 printf("[ "); |
| |
227 for (x=0;x<len;x++) |
| |
228 printf("%d ", buf[x]); |
| |
229 printf("]\n"); |
| |
230 printf("[ "); |
| |
231 for (x=0;x<len;x++) |
| |
232 printf("%c ", buf[x]); |
| |
233 printf("]\n"); |
| |
234 #endif |
| |
235 } |
| |
236 |
| |
237 int sflap_send(char *buf, int olen, int type) |
| |
238 { |
| |
239 int len; |
| |
240 int slen=0; |
| |
241 struct sflap_hdr hdr; |
| |
242 char obuf[MSG_LEN]; |
| |
243 |
| |
244 /* One _last_ 2048 check here! This shouldn't ever |
| |
245 * get hit though, hopefully. If it gets hit on an IM |
| |
246 * It'll lose the last " and the message won't go through, |
| |
247 * but this'll stop a segfault. */ |
| |
248 if (strlen(buf) > (MSG_LEN - sizeof(hdr))) { |
| |
249 buf[MSG_LEN - sizeof(hdr) - 3] = '"'; |
| |
250 buf[MSG_LEN - sizeof(hdr) - 2] = '\0'; |
| |
251 } |
| |
252 |
| |
253 sprintf(debug_buff,"%s [Len %d]\n", buf, strlen(buf)); |
| |
254 debug_print(debug_buff); |
| |
255 |
| |
256 |
| |
257 |
| |
258 if (olen < 0) |
| |
259 len = escape_message(buf); |
| |
260 else |
| |
261 len = olen; |
| |
262 hdr.ast = '*'; |
| |
263 hdr.type = type; |
| |
264 hdr.seqno = htons(seqno++ & 0xffff); |
| |
265 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); |
| |
266 |
| |
267 sprintf(debug_buff,"Escaped message is '%s'\n",buf); |
| |
268 debug_print(debug_buff); |
| |
269 |
| |
270 memcpy(obuf, &hdr, sizeof(hdr)); |
| |
271 slen += sizeof(hdr); |
| |
272 memcpy(&obuf[slen], buf, len); |
| |
273 slen += len; |
| |
274 if (type != TYPE_SIGNON) { |
| |
275 obuf[slen]='\0'; |
| |
276 slen += 1; |
| |
277 } |
| |
278 print_buffer(obuf, slen); |
| |
279 |
| |
280 return write(toc_fd, obuf, slen); |
| |
281 } |
| |
282 |
| |
283 |
| |
284 int wait_reply(char *buffer, int buflen) |
| |
285 { |
| |
286 int res=6; |
| |
287 struct sflap_hdr *hdr=(struct sflap_hdr *)buffer; |
| |
288 char *c; |
| |
289 |
| |
290 while((res = read(toc_fd, buffer, 1))) { |
| |
291 if (res < 0) |
| |
292 return res; |
| |
293 if (buffer[0] == '*') |
| |
294 break; |
| |
295 |
| |
296 } |
| |
297 |
| |
298 res = read(toc_fd, buffer+1, sizeof(struct sflap_hdr) - 1); |
| |
299 |
| |
300 if (res < 0) |
| |
301 return res; |
| |
302 |
| |
303 res += 1; |
| |
304 |
| |
305 |
| |
306 sprintf(debug_buff, "Rcv: %s %s\n",print_header(buffer), ""); |
| |
307 debug_print(debug_buff); |
| |
308 |
| |
309 |
| |
310 |
| |
311 while (res < (sizeof(struct sflap_hdr) + ntohs(hdr->len))) { |
| |
312 res += read(toc_fd, buffer + res, (ntohs(hdr->len) + sizeof(struct sflap_hdr)) - res); |
| |
313 while(gtk_events_pending()) |
| |
314 gtk_main_iteration(); |
| |
315 } |
| |
316 |
| |
317 if (res >= sizeof(struct sflap_hdr)) |
| |
318 buffer[res]='\0'; |
| |
319 else |
| |
320 return res - sizeof(struct sflap_hdr); |
| |
321 |
| |
322 switch(hdr->type) { |
| |
323 case TYPE_SIGNON: |
| |
324 memcpy(&peer_ver, buffer + sizeof(struct sflap_hdr), 4); |
| |
325 peer_ver = ntohl(peer_ver); |
| |
326 seqno = ntohs(hdr->seqno); |
| |
327 state = STATE_SIGNON_REQUEST; |
| |
328 break; |
| |
329 case TYPE_DATA: |
| |
330 if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "SIGN_ON:", strlen("SIGN_ON:"))) |
| |
331 state = STATE_SIGNON_ACK; |
| |
332 else if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "CONFIG:", strlen("CONFIG:"))) { |
| |
333 state = STATE_CONFIG; |
| |
334 } else if (state != STATE_ONLINE && !strncasecmp(buffer + sizeof(struct sflap_hdr), "ERROR:", strlen("ERROR:"))) { |
| |
335 c = strtok(buffer + sizeof(struct sflap_hdr) + strlen("ERROR:"), ":"); |
| |
336 show_error_dialog(c); |
| |
337 } |
| |
338 |
| |
339 sprintf(debug_buff, "Data: %s\n",buffer + sizeof(struct sflap_hdr)); |
| |
340 debug_print(debug_buff); |
| |
341 |
| |
342 break; |
| |
343 default: |
| |
344 sprintf(debug_buff, "Unknown/unimplemented packet type %d\n",hdr->type); |
| |
345 debug_print(debug_buff); |
| |
346 } |
| |
347 return res; |
| |
348 } |
| |
349 |
| |
350 |
| |
351 |
| |
352 void toc_callback( gpointer data, |
| |
353 gint source, |
| |
354 GdkInputCondition condition ) |
| |
355 { |
| |
356 char *buf; |
| |
357 char *c; |
| |
358 char *l; |
| |
359 |
| |
360 buf = g_malloc(BUF_LONG); |
| |
361 if (wait_reply(buf, BUF_LONG) < 0) { |
| |
362 signoff(); |
| |
363 hide_login_progress("Connection Closed"); |
| |
364 g_free(buf); |
| |
365 return; |
| |
366 } |
| |
367 |
| |
368 |
| |
369 c=strtok(buf+sizeof(struct sflap_hdr),":"); /* Ditch the first part */ |
| |
370 if (!strcasecmp(c,"UPDATE_BUDDY")) { |
| |
371 char *uc; |
| |
372 int logged, evil, idle, type = 0; |
| |
373 time_t signon; |
| |
374 time_t time_idle; |
| |
375 |
| |
376 c = strtok(NULL,":"); /* c is name */ |
| |
377 |
| |
378 l = strtok(NULL,":"); /* l is T/F logged status */ |
| |
379 |
| |
380 sscanf(strtok(NULL, ":"), "%d", &evil); |
| |
381 |
| |
382 sscanf(strtok(NULL, ":"), "%ld", &signon); |
| |
383 |
| |
384 sscanf(strtok(NULL, ":"), "%d", &idle); |
| |
385 |
| |
386 uc = strtok(NULL, ":"); |
| |
387 |
| |
388 |
| |
389 if (!strncasecmp(l,"T",1)) |
| |
390 logged = 1; |
| |
391 else |
| |
392 logged = 0; |
| |
393 |
| |
394 |
| |
395 if (uc[0] == 'A') |
| |
396 type |= UC_AOL; |
| |
397 |
| |
398 switch(uc[1]) { |
| |
399 case 'A': |
| |
400 type |= UC_ADMIN; |
| |
401 break; |
| |
402 case 'U': |
| |
403 type |= UC_UNCONFIRMED; |
| |
404 break; |
| |
405 case 'O': |
| |
406 type |= UC_NORMAL; |
| |
407 break; |
| |
408 default: |
| |
409 break; |
| |
410 } |
| |
411 |
| |
412 switch(uc[2]) { |
| |
413 case 'U': |
| |
414 type |= UC_UNAVAILABLE; |
| |
415 break; |
| |
416 default: |
| |
417 break; |
| |
418 } |
| |
419 |
| |
420 if (idle) { |
| |
421 time(&time_idle); |
| |
422 time_idle -= idle*60; |
| |
423 } else |
| |
424 time_idle = 0; |
| |
425 |
| |
426 serv_got_update(c, logged, evil, signon, time_idle, type); |
| |
427 |
| |
428 } else if (!strcasecmp(c, "ERROR")) { |
| |
429 c = strtok(NULL,":"); |
| |
430 show_error_dialog(c); |
| |
431 } else if (!strcasecmp(c, "NICK")) { |
| |
432 c = strtok(NULL,":"); |
| |
433 g_snprintf(current_user->username, sizeof(current_user->username), "%s", c); |
| |
434 } else if (!strcasecmp(c, "IM_IN")) { |
| |
435 char *away, *message; |
| |
436 int a = 0; |
| |
437 |
| |
438 c = strtok(NULL,":"); |
| |
439 away = strtok(NULL,":"); |
| |
440 |
| |
441 message = away; |
| |
442 |
| |
443 while(*message && (*message != ':')) |
| |
444 message++; |
| |
445 |
| |
446 message++; |
| |
447 |
| |
448 if (!strncasecmp(away, "T", 1)) |
| |
449 a = 1; |
| |
450 serv_got_im(c, message, a); |
| |
451 |
| |
452 } else if (!strcasecmp(c, "GOTO_URL")) { |
| |
453 char *name; |
| |
454 char *url; |
| |
455 |
| |
456 char tmp[256]; |
| |
457 |
| |
458 name = strtok(NULL, ":"); |
| |
459 url = strtok(NULL, ":"); |
| |
460 |
| |
461 |
| |
462 g_snprintf(tmp, sizeof(tmp), "http://%s:%d/%s", toc_addy, aim_port, url); |
| |
463 /* fprintf(stdout, "Name: %s\n%s\n", name, url); |
| |
464 printf("%s", grab_url(tmp));*/ |
| |
465 g_show_info(tmp); |
| |
466 } else if (!strcasecmp(c, "EVILED")) { |
| |
467 int lev; |
| |
468 char *name = NULL; |
| |
469 |
| |
470 sscanf(strtok(NULL, ":"), "%d", &lev); |
| |
471 name = strtok(NULL, ":"); |
| |
472 |
| |
473 sprintf(debug_buff,"%s | %d\n", name, lev); |
| |
474 debug_print(debug_buff); |
| |
475 |
| |
476 serv_got_eviled(name, lev); |
| |
477 |
| |
478 } else if (!strcasecmp(c, "CHAT_JOIN")) { |
| |
479 char *name; |
| |
480 int id; |
| |
481 |
| |
482 |
| |
483 sscanf(strtok(NULL, ":"), "%d", &id); |
| |
484 name = strtok(NULL, ":"); |
| |
485 serv_got_joined_chat(id, name); |
| |
486 |
| |
487 } else if (!strcasecmp(c, "DIR_STATUS")) { |
| |
488 } else if (!strcasecmp(c, "CHAT_UPDATE_BUDDY")) { |
| |
489 int id; |
| |
490 char *in; |
| |
491 char *buddy; |
| |
492 GList *bcs = buddy_chats; |
| |
493 struct buddy_chat *b = NULL; |
| |
494 |
| |
495 sscanf(strtok(NULL, ":"), "%d", &id); |
| |
496 |
| |
497 in = strtok(NULL, ":"); |
| |
498 |
| |
499 while(bcs) { |
| |
500 b = (struct buddy_chat *)bcs->data; |
| |
501 if (id == b->id) |
| |
502 break; |
| |
503 bcs = bcs->next; |
| |
504 b = NULL; |
| |
505 } |
| |
506 |
| |
507 if (!b) |
| |
508 return; |
| |
509 |
| |
510 |
| |
511 if (!strcasecmp(in, "T")) { |
| |
512 while((buddy = strtok(NULL, ":")) != NULL) { |
| |
513 add_chat_buddy(b, buddy); |
| |
514 } |
| |
515 } else { |
| |
516 while((buddy = strtok(NULL, ":")) != NULL) { |
| |
517 remove_chat_buddy(b, buddy); |
| |
518 } |
| |
519 } |
| |
520 |
| |
521 } else if (!strcasecmp(c, "CHAT_LEFT")) { |
| |
522 int id; |
| |
523 |
| |
524 |
| |
525 sscanf(strtok(NULL, ":"), "%d", &id); |
| |
526 |
| |
527 serv_got_chat_left(id); |
| |
528 |
| |
529 |
| |
530 } else if (!strcasecmp(c, "CHAT_IN")) { |
| |
531 |
| |
532 int id, w; |
| |
533 char *m; |
| |
534 char *who, *whisper; |
| |
535 |
| |
536 |
| |
537 sscanf(strtok(NULL, ":"), "%d", &id); |
| |
538 who = strtok(NULL, ":"); |
| |
539 whisper = strtok(NULL, ":"); |
| |
540 m = whisper; |
| |
541 while(*m && (*m != ':')) m++; |
| |
542 m++; |
| |
543 |
| |
544 if (!strcasecmp(whisper, "T")) |
| |
545 w = 1; |
| |
546 else |
| |
547 w = 0; |
| |
548 |
| |
549 serv_got_chat_in(id, who, w, m); |
| |
550 |
| |
551 |
| |
552 } else if (!strcasecmp(c, "CHAT_INVITE")) { |
| |
553 char *name; |
| |
554 char *who; |
| |
555 char *message; |
| |
556 int id; |
| |
557 |
| |
558 |
| |
559 name = strtok(NULL, ":"); |
| |
560 sscanf(strtok(NULL, ":"), "%d", &id); |
| |
561 who = strtok(NULL, ":"); |
| |
562 message = strtok(NULL, ":"); |
| |
563 |
| |
564 serv_got_chat_invite(name, id, who, message); |
| |
565 |
| |
566 |
| |
567 #if 0 |
| |
568 } else if (!strcasecmp(c, "RVOUS_PROPOSE")) { |
| |
569 /* File trans. Yummy. */ |
| |
570 char *user; |
| |
571 char *uuid; |
| |
572 char *cookie; |
| |
573 int seq; |
| |
574 char *rip, *pip, *vip; |
| |
575 int port; |
| |
576 int unk[4]; |
| |
577 char *messages[4]; |
| |
578 int subtype, files, totalsize; |
| |
579 char *name; |
| |
580 char *tmp; |
| |
581 int i; |
| |
582 struct file_transfer *ft; |
| |
583 |
| |
584 |
| |
585 user = strtok(NULL, ":"); |
| |
586 uuid = strtok(NULL, ":"); |
| |
587 cookie = strtok(NULL, ":"); |
| |
588 sscanf(strtok(NULL, ":"), "%d", &seq); |
| |
589 rip = strtok(NULL, ":"); |
| |
590 pip = strtok(NULL, ":"); |
| |
591 vip = strtok(NULL, ":"); |
| |
592 sscanf(strtok(NULL, ":"), "%d", &port); |
| |
593 for (i=0; i<4; i++) { |
| |
594 sscanf(strtok(NULL, ":"), "%d", &unk[i]); |
| |
595 if (unk[i] == 10001) |
| |
596 break; |
| |
597 messages[i] = frombase64(strtok(NULL, ":")); |
| |
598 } |
| |
599 |
| |
600 tmp = frombase64(strtok(NULL, ":")); |
| |
601 |
| |
602 subtype = tmp[1]; |
| |
603 files = tmp[3]; /* These are fine */ |
| |
604 |
| |
605 totalsize = (tmp[4] << 24 & 0xff) | |
| |
606 (tmp[5] << 16 & 0xff) | |
| |
607 (tmp[6] << 8 & 0xff) | |
| |
608 (tmp[7] & 0xff); |
| |
609 |
| |
610 name = tmp + 8; |
| |
611 |
| |
612 ft = g_new0(struct file_transfer, 1); |
| |
613 |
| |
614 ft->cookie = g_strdup(cookie); |
| |
615 ft->ip = g_strdup(pip); |
| |
616 ft->port = port; |
| |
617 if (i) |
| |
618 ft->message = g_strdup(messages[0]); |
| |
619 else |
| |
620 ft->message = NULL; |
| |
621 ft->filename = g_strdup(name); |
| |
622 ft->user = g_strdup(user); |
| |
623 ft->size = totalsize; |
| |
624 |
| |
625 g_free(tmp); |
| |
626 |
| |
627 for (i--; i >= 0; i--) |
| |
628 g_free(messages[i]); |
| |
629 |
| |
630 accept_file_dialog(ft); |
| |
631 #endif |
| |
632 } else { |
| |
633 sprintf(debug_buff,"don't know what to do with %s\n", c); |
| |
634 debug_print(debug_buff); |
| |
635 } |
| |
636 g_free(buf); |
| |
637 } |
| |
638 |
| |
639 |
| |
640 int toc_signon(char *username, char *password) |
| |
641 { |
| |
642 char buf[BUF_LONG]; |
| |
643 int res; |
| |
644 struct signon so; |
| |
645 |
| |
646 sprintf(debug_buff,"State = %d\n", state); |
| |
647 debug_print(debug_buff); |
| |
648 |
| |
649 if ((res = write(toc_fd, FLAPON, strlen(FLAPON))) < 0) |
| |
650 return res; |
| |
651 /* Wait for signon packet */ |
| |
652 |
| |
653 state = STATE_FLAPON; |
| |
654 |
| |
655 if ((res = wait_reply(buf, sizeof(buf)) < 0)) |
| |
656 return res; |
| |
657 |
| |
658 if (state != STATE_SIGNON_REQUEST) { |
| |
659 sprintf(debug_buff, "State should be %d, but is %d instead\n", STATE_SIGNON_REQUEST, state); |
| |
660 debug_print(debug_buff); |
| |
661 return -1; |
| |
662 } |
| |
663 |
| |
664 /* Compose a response */ |
| |
665 |
| |
666 g_snprintf(so.username, sizeof(so.username), "%s", username); |
| |
667 so.ver = ntohl(1); |
| |
668 so.tag = ntohs(1); |
| |
669 so.namelen = htons(strlen(so.username)); |
| |
670 |
| |
671 sflap_send((char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON); |
| |
672 |
| |
673 g_snprintf(buf, sizeof(buf), |
| |
674 "toc_signon %s %d %s %s %s \"%s\"", |
| |
675 login_host, login_port, normalize(username), roast_password(password), LANGUAGE, REVISION); |
| |
676 |
| |
677 sprintf(debug_buff,"Send: %s\n", buf); |
| |
678 debug_print(debug_buff); |
| |
679 |
| |
680 return sflap_send(buf, -1, TYPE_DATA); |
| |
681 } |
| |
682 |
| |
683 int toc_wait_signon() |
| |
684 { |
| |
685 /* Wait for the SIGNON to be approved */ |
| |
686 char buf[BUF_LEN]; |
| |
687 int res; |
| |
688 res = wait_reply(buf, sizeof(buf)); |
| |
689 if (res < 0) |
| |
690 return res; |
| |
691 if (state != STATE_SIGNON_ACK) { |
| |
692 sprintf(debug_buff, "State should be %d, but is %d instead\n",STATE_SIGNON_ACK, state); |
| |
693 debug_print(debug_buff); |
| |
694 return -1; |
| |
695 } |
| |
696 return 0; |
| |
697 } |
| |
698 |
| |
699 #ifdef _WIN32 |
| |
700 gint win32_read() |
| |
701 { |
| |
702 int ret; |
| |
703 struct fd_set fds; |
| |
704 struct timeval tv; |
| |
705 |
| |
706 FD_ZERO(&fds); |
| |
707 |
| |
708 tv.tv_sec = 0; |
| |
709 tv.tv_usec = 200; |
| |
710 |
| |
711 FD_SET(toc_fd, &fds); |
| |
712 |
| |
713 ret = select(toc_fd + 1, &fds, NULL, NULL, &tv); |
| |
714 |
| |
715 if (ret == 0) { |
| |
716 return TRUE; |
| |
717 } |
| |
718 |
| |
719 toc_callback(NULL, 0, (GdkInputCondition)0); |
| |
720 return TRUE; |
| |
721 } |
| |
722 #endif |
| |
723 |
| |
724 |
| |
725 char *toc_wait_config() |
| |
726 { |
| |
727 /* Waits for configuration packet, returning the contents of the packet */ |
| |
728 static char buf[BUF_LEN]; |
| |
729 int res; |
| |
730 res = wait_reply(buf, sizeof(buf)); |
| |
731 if (res < 0) |
| |
732 return NULL; |
| |
733 if (state != STATE_CONFIG) { |
| |
734 sprintf(debug_buff , "State should be %d, but is %d instead\n",STATE_CONFIG, state); |
| |
735 debug_print(debug_buff); |
| |
736 return NULL; |
| |
737 } |
| |
738 /* At this point, it's time to setup automatic handling of incoming packets */ |
| |
739 state = STATE_ONLINE; |
| |
740 #ifdef _WIN32 |
| |
741 win32_r = gtk_timeout_add(1000, (GtkFunction)win32_read, NULL); |
| |
742 #else |
| |
743 inpa = gdk_input_add(toc_fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_callback, NULL); |
| |
744 #endif |
| |
745 return buf; |
| |
746 } |
| |
747 |
| |
748 |
| |
749 void toc_build_config(char *s, int len) |
| |
750 { |
| |
751 GList *grp = groups; |
| |
752 GList *mem; |
| |
753 struct group *g; |
| |
754 struct buddy *b; |
| |
755 GList *plist = permit; |
| |
756 GList *dlist = deny; |
| |
757 |
| |
758 int pos=0; |
| |
759 |
| |
760 if (!permdeny) |
| |
761 permdeny = 1; |
| |
762 pos += g_snprintf(&s[pos], len - pos, "m %d\n", permdeny); |
| |
763 while(grp) { |
| |
764 g = (struct group *)grp->data; |
| |
765 pos += g_snprintf(&s[pos], len - pos, "g %s\n", g->name); |
| |
766 mem = g->members; |
| |
767 while(mem) { |
| |
768 b = (struct buddy *)mem->data; |
| |
769 pos += g_snprintf(&s[pos], len - pos, "b %s\n", b->name); |
| |
770 mem = mem->next; |
| |
771 } |
| |
772 grp = grp ->next; |
| |
773 } |
| |
774 while(plist) { |
| |
775 pos += g_snprintf(&s[pos], len - pos, "p %s\n", (char *)plist->data); |
| |
776 plist=plist->next; |
| |
777 |
| |
778 } |
| |
779 while(dlist) { |
| |
780 pos += g_snprintf(&s[pos], len - pos, "d %s\n", (char *)dlist->data); |
| |
781 dlist=dlist->next; |
| |
782 } |
| |
783 } |
| |
784 |
| |
785 void parse_toc_buddy_list(char *config) |
| |
786 { |
| |
787 char *c; |
| |
788 char current[256]; |
| |
789 char *name; |
| |
790 GList *bud; |
| |
791 /* Clean out the permit/deny list!*/ |
| |
792 g_list_free(permit); |
| |
793 g_list_free(deny); |
| |
794 permit = NULL; |
| |
795 deny = NULL; |
| |
796 bud = NULL; |
| |
797 |
| |
798 |
| |
799 /* skip "CONFIG:" (if it exists)*/ |
| |
800 |
| |
801 c = strncmp(config + sizeof(struct sflap_hdr),"CONFIG:",strlen("CONFIG:"))? |
| |
802 strtok(config, "\n"): |
| |
803 strtok(config + sizeof(struct sflap_hdr)+strlen("CONFIG:"), "\n"); |
| |
804 do { |
| |
805 if (c == NULL) |
| |
806 break; |
| |
807 if (*c == 'g') { |
| |
808 strncpy(current,c+2, sizeof(current)); |
| |
809 add_group(current); |
| |
810 } else if (*c == 'b') { |
| |
811 add_buddy(current, c+2); |
| |
812 bud = g_list_append(bud, c+2); |
| |
813 } else if (*c == 'p') { |
| |
814 name = g_malloc(strlen(c+2) + 2); |
| |
815 g_snprintf(name, strlen(c+2) + 1, "%s", c+2); |
| |
816 permit = g_list_append(permit, name); |
| |
817 } else if (*c == 'd') { |
| |
818 name = g_malloc(strlen(c+2) + 2); |
| |
819 g_snprintf(name, strlen(c+2) + 1, "%s", c+2); |
| |
820 deny = g_list_append(deny, name); |
| |
821 } else if (*c == 'm') { |
| |
822 sscanf(c + strlen(c) - 1, "%d", &permdeny); |
| |
823 if (permdeny == 0) |
| |
824 permdeny = 1; |
| |
825 } |
| |
826 }while((c=strtok(NULL,"\n"))); |
| |
827 #if 0 |
| |
828 fprintf(stdout, "Sending message '%s'\n",buf); |
| |
829 #endif |
| |
830 |
| |
831 serv_add_buddies(bud); |
| |
832 serv_set_permit_deny(); |
| |
833 } |