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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 */
21
22
23 /*
24 * Heavily modified by Nadeem Riaz (nads@bleh.org)
25 * for use in libtoc
26 */
27
28 #include <netdb.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 <sys/socket.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <time.h>
39 #include "toc.h"
40
41 /* descriptor for talking to TOC */
42 static int toc_fd;
43 static int seqno;
44 static unsigned int peer_ver=0;
45 int state;
46 /* static int inpa=-1; */
47 int permdeny = PERMIT_PERMITALL;
48
toc_login(char * username,char * password)49 int toc_login(char *username, char *password)
50 {
51 char *config;
52 struct in_addr *sin;
53 char buf[80];
54 char buf2[2048];
55
56 toc_debug_printf("looking up host! %s", aim_host);
57
58 sin = (struct in_addr *)get_address(aim_host);
59 if (!sin) {
60 set_state(STATE_OFFLINE);
61 toc_msg_printf(TOC_CONNECT_MSGS,"Unable to lookup %s", aim_host);
62 return -1;
63 }
64
65 snprintf(toc_addy, sizeof(toc_addy), "%s", inet_ntoa(*sin));
66 snprintf(buf, sizeof(buf), "Connecting to %s", inet_ntoa(*sin));
67
68 toc_msg_printf(TOC_CONNECT_MSGS,"%s",buf);
69
70 toc_fd = connect_address(sin->s_addr, aim_port);
71
72 if (toc_fd < 0) {
73 set_state(STATE_OFFLINE);
74 toc_msg_printf(TOC_CONNECT_MSGS,"Connect to %s failed", inet_ntoa(*sin));
75 return -1;
76 }
77
78 free(sin);
79
80 toc_msg_printf(TOC_CONNECT_MSGS,"Signon: %s",username);
81
82 if (toc_signon(username, password) < 0) {
83 set_state(STATE_OFFLINE);
84 toc_msg_printf(TOC_CONNECT_MSGS,"Disconnected.");
85 return -1;
86 }
87
88 toc_msg_printf(TOC_CONNECT_MSGS,"Waiting for reply...");
89 if (toc_wait_signon() < 0) {
90 set_state(STATE_OFFLINE);
91 toc_msg_printf(TOC_CONNECT_MSGS,"Authentication Failed");
92 return -1;
93 }
94
95
96 snprintf(aim_username, sizeof(aim_username), "%s", username);
97 snprintf(aim_password, sizeof(aim_password), "%s", password);
98
99 save_prefs();
100
101 toc_msg_printf(TOC_CONNECT_MSGS,"Retrieving config...");
102 if ((config=toc_wait_config()) == NULL) {
103 toc_msg_printf(TOC_CONNECT_MSGS,"No Configuration\n");
104 set_state(STATE_OFFLINE);
105 return -1;
106
107 }
108
109 init_lists();
110 /* gtk_widget_hide(mainwindow);
111 show_buddy_list(); */
112 parse_toc_buddy_list(config);
113 /* refresh_buddy_window(); */
114
115 snprintf(buf2, sizeof(buf2), "toc_init_done");
116 sflap_send(buf2, -1, TYPE_DATA);
117
118 serv_finish_login();
119 return 0;
120 }
121
toc_close()122 void toc_close()
123 {
124 seqno = 0;
125 state = STATE_OFFLINE;
126 toc_remove_input_stream(toc_fd);
127 close(toc_fd);
128 toc_fd=-1;
129 }
130
toc_signon(char * username,char * password)131 int toc_signon(char *username, char *password)
132 {
133 char buf[BUF_LONG];
134 int res;
135 struct signon so;
136
137 toc_debug_printf("State = %d\n", state);
138
139 strncpy(aim_username, username, sizeof(aim_username));
140
141 if ((res = write(toc_fd, FLAPON, strlen(FLAPON))) < 0)
142 return res;
143 /* Wait for signon packet */
144
145 state = STATE_FLAPON;
146
147 if ((res = wait_reply(buf, sizeof(buf)) < 0))
148 return res;
149
150 if (state != STATE_SIGNON_REQUEST) {
151 toc_debug_printf( "State should be %d, but is %d instead\n", STATE_SIGNON_REQUEST, state);
152 return -1;
153 }
154
155 /* Compose a response */
156
157 snprintf(so.username, sizeof(so.username), "%s", username);
158 so.ver = ntohl(1);
159 so.tag = ntohs(1);
160 so.namelen = htons(strlen(so.username));
161
162 sflap_send((char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON);
163
164 snprintf(buf, sizeof(buf),
165 "toc_signon %s %d %s %s %s \"%s\"",
166 login_host, login_port, normalize(username), roast_password(password), LANGUAGE, REVISION);
167
168 toc_debug_printf("Send: %s\n", buf);
169
170 return sflap_send(buf, -1, TYPE_DATA);
171 }
172
toc_wait_signon()173 int toc_wait_signon()
174 {
175 /* Wait for the SIGNON to be approved */
176 char buf[BUF_LEN];
177 int res;
178 res = wait_reply(buf, sizeof(buf));
179 if (res < 0)
180 return res;
181 if (state != STATE_SIGNON_ACK) {
182 toc_debug_printf("State should be %d, but is %d instead\n",STATE_SIGNON_ACK, state);
183 return -1;
184 }
185 return 0;
186 }
187
188
wait_reply(char * buffer,int buflen)189 int wait_reply(char *buffer, int buflen)
190 {
191 int res=6;
192 struct sflap_hdr *hdr=(struct sflap_hdr *)buffer;
193 char *c;
194
195 while((res = read(toc_fd, buffer, 1))) {
196 if (res < 0)
197 return res;
198 if (buffer[0] == '*')
199 break;
200
201 }
202
203 res = read(toc_fd, buffer+1, sizeof(struct sflap_hdr) - 1);
204
205 if (res < 0)
206 return res;
207
208 res += 1;
209
210
211 toc_debug_printf( "Rcv: %s %s\n",print_header(buffer), "");
212
213 while (res < (sizeof(struct sflap_hdr) + ntohs(hdr->len))) {
214 res += read(toc_fd, buffer + res, (ntohs(hdr->len) + sizeof(struct sflap_hdr)) - res);
215 /* while(gtk_events_pending())
216 gtk_main_iteration(); */
217 }
218
219 if (res >= sizeof(struct sflap_hdr))
220 buffer[res]='\0';
221 else
222 return res - sizeof(struct sflap_hdr);
223
224 switch(hdr->type) {
225 case TYPE_SIGNON:
226 memcpy(&peer_ver, buffer + sizeof(struct sflap_hdr), 4);
227 peer_ver = ntohl(peer_ver);
228 seqno = ntohs(hdr->seqno);
229 state = STATE_SIGNON_REQUEST;
230 break;
231 case TYPE_DATA:
232 if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "SIGN_ON:", strlen("SIGN_ON:")))
233 state = STATE_SIGNON_ACK;
234 else if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "CONFIG:", strlen("CONFIG:"))) {
235 state = STATE_CONFIG;
236 } else if (state != STATE_ONLINE && !strncasecmp(buffer + sizeof(struct sflap_hdr), "ERROR:", strlen("ERROR:"))) {
237 c = strtok(buffer + sizeof(struct sflap_hdr) + strlen("ERROR:"), ":");
238 translate_toc_error_code(c);
239 toc_debug_printf("ERROR CODE: %s\n",c);
240 }
241
242 toc_debug_printf("Data: %s\n",buffer + sizeof(struct sflap_hdr));
243
244 break;
245 default:
246 toc_debug_printf("Unknown/unimplemented packet type %d\n",hdr->type);
247 }
248 return res;
249 }
250
sflap_send(char * buf,int olen,int type)251 int sflap_send(char *buf, int olen, int type)
252 {
253 int len;
254 int slen=0;
255 struct sflap_hdr hdr;
256 char obuf[MSG_LEN];
257
258 /* One _last_ 2048 check here! This shouldn't ever
259 * get hit though, hopefully. If it gets hit on an IM
260 * It'll lose the last " and the message won't go through,
261 * but this'll stop a segfault. */
262 if (strlen(buf) > (MSG_LEN - sizeof(hdr))) {
263 buf[MSG_LEN - sizeof(hdr) - 3] = '"';
264 buf[MSG_LEN - sizeof(hdr) - 2] = '\0';
265 }
266
267 toc_debug_printf("%s [Len %d]\n", buf, strlen(buf));
268
269
270 if (olen < 0)
271 len = escape_message(buf);
272 else
273 len = olen;
274 hdr.ast = '*';
275 hdr.type = type;
276 hdr.seqno = htons(seqno++ & 0xffff);
277 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1));
278
279 toc_debug_printf("Escaped message is '%s'\n",buf);
280
281 memcpy(obuf, &hdr, sizeof(hdr));
282 slen += sizeof(hdr);
283 memcpy(&obuf[slen], buf, len);
284 slen += len;
285 if (type != TYPE_SIGNON) {
286 obuf[slen]='\0';
287 slen += 1;
288 }
289 /* print_buffer(obuf, slen); */
290
291 return write(toc_fd, obuf, slen);
292 }
293
roast_password(char * pass)294 unsigned char *roast_password(char *pass)
295 {
296 /* Trivial "encryption" */
297 static char rp[256];
298 static char *roast = ROAST;
299 int pos=2;
300 int x;
301 strcpy(rp, "0x");
302 for (x=0;(x<150) && pass[x]; x++)
303 pos+=sprintf(&rp[pos],"%02x", pass[x] ^ roast[x % strlen(roast)]);
304 rp[pos]='\0';
305 return rp;
306 }
307
print_header(void * hdr_v)308 char *print_header(void *hdr_v)
309 {
310 static char s[80];
311 struct sflap_hdr *hdr = (struct sflap_hdr *)hdr_v;
312 snprintf(s,sizeof(s), "[ ast: %c, type: %d, seqno: %d, len: %d ]",
313 hdr->ast, hdr->type, ntohs(hdr->seqno), ntohs(hdr->len));
314 return s;
315 }
316
toc_callback(int fd)317 int toc_callback(int fd)
318 {
319 char *buf;
320 char *c;
321 char **args = NULL;
322 char *dup,*raw;
323 char *l;
324 int numargs =0;
325
326 buf = malloc(BUF_LONG);
327
328 if (wait_reply(buf, BUF_LONG) < 0) {
329 toc_signoff();
330 toc_debug_printf("need to do proper sign off on this\n");
331 toc_msg_printf(TOC_CONNECT_MSGS,"Connection Closed");
332 return -1;
333 }
334
335 dup = strdup(buf+sizeof(struct sflap_hdr));
336 raw = rindex(dup,':');
337 c=strtok(buf+sizeof(struct sflap_hdr),":"); /* Ditch the first part */
338 if (!strcasecmp(c,"UPDATE_BUDDY")) {
339 char *uc, *t;
340 int logged, evil, idle, type = 0;
341 long signon;
342 time_t time_idle;
343
344 numargs = 7;
345 args = (char **) malloc(sizeof(char *)*numargs);
346 use_handler(TOC_RAW_HANDLE,TOC_UPDATE_BUDDY,raw);
347 c = strtok(NULL,":"); /* c is name */
348 args[0] = strdup(c);
349
350 l = strtok(NULL,":"); /* l is T/F logged status */
351 args[1] = strdup(l);
352
353 t = strtok(NULL, ":");
354 args[2] = strdup(t);
355 sscanf(t, "%d", &evil);
356
357 t = strtok(NULL, ":");
358 args[3] = strdup(t);
359 sscanf(t, "%ld", &signon);
360
361 t = strtok(NULL, ":");
362 args[4] = strdup(t);
363 sscanf(t, "%d", &idle);
364
365 uc = strtok(NULL, ":");
366 args[5] = strdup(uc);
367
368 if (!strncasecmp(l,"T",1))
369 logged = 1;
370 else
371 logged = 0;
372
373
374 if (uc[0] == 'A')
375 type |= UC_AOL;
376
377 switch(uc[1]) {
378 case 'A':
379 type |= UC_ADMIN;
380 break;
381 case 'U':
382 type |= UC_UNCONFIRMED;
383 break;
384 case 'O':
385 type |= UC_NORMAL;
386 break;
387 default:
388 break;
389 }
390
391 switch(uc[2]) {
392 case 'U':
393 type |= UC_UNAVAILABLE;
394 break;
395 default:
396 break;
397 }
398
399 if (idle) {
400 time(&time_idle);
401 time_idle -= idle*60;
402 } else
403 time_idle = 0;
404
405 serv_got_update(c, logged, evil, signon, time_idle, type);
406 args[6] = NULL;
407 use_handler(TOC_HANDLE,TOC_UPDATE_BUDDY,args);
408 } else if (!strcasecmp(c, "ERROR")) {
409 use_handler(TOC_RAW_HANDLE,TOC_ERROR,raw);
410 c = strtok(NULL,":");
411 translate_toc_error_code(c);
412 args = (char **) malloc(sizeof(char *)*1 + 1);
413 numargs = 1;
414 args[0] = strdup(c);
415 use_handler(TOC_HANDLE,TOC_ERROR,args);
416 toc_debug_printf("ERROR: %s",c);
417 } else if (!strcasecmp(c, "NICK")) {
418 use_handler(TOC_RAW_HANDLE,TOC_NICK,raw);
419 c = strtok(NULL,":");
420 snprintf(aim_username, sizeof(aim_username), "%s", c);
421 numargs = 2;
422 args = (char **) malloc(sizeof(char *)*numargs);
423 args[0] = strdup(c);
424 args[1] = NULL;
425 use_handler(TOC_HANDLE,TOC_NICK,args);
426 } else if (!strcasecmp(c, "IM_IN")) {
427 char *away, *message;
428 int a = 0;
429 use_handler(TOC_RAW_HANDLE,TOC_IM_IN,raw);
430 c = strtok(NULL,":");
431 away = strtok(NULL,":");
432
433 message = away;
434
435 while(*message && (*message != ':'))
436 message++;
437
438 message++;
439
440 if (!strncasecmp(away, "T", 1))
441 a = 1;
442
443 if ( serv_got_im(c, message,a) > 0 ) {
444 numargs = 3;
445 args = (char **) malloc(sizeof(char *)*numargs);
446 args[0] = strdup(c);
447 args[1] = strdup(message);
448 args[2] = NULL;
449 use_handler(TOC_HANDLE,TOC_IM_IN,args);
450 }
451 } else if (!strcasecmp(c, "GOTO_URL")) {
452 char *name;
453 char *url;
454
455 char tmp[256];
456
457 use_handler(TOC_RAW_HANDLE,TOC_GOTO_URL,raw);
458 name = strtok(NULL, ":");
459 url = strtok(NULL, ":");
460
461
462 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
466 numargs = 2;
467 args = (char **) malloc(sizeof(char *)*numargs);
468 args[0] = strdup(tmp);
469 args[1] = NULL;
470 use_handler(TOC_HANDLE,TOC_GOTO_URL,args);
471 /* statusprintf("GOTO_URL: %s","tmp"); */
472 } else if (!strcasecmp(c, "EVILED")) {
473 int lev;
474 char *name = NULL;
475 char *levc;
476
477 use_handler(TOC_RAW_HANDLE,TOC_EVILED,raw);
478 levc = strtok(NULL, ":");
479 sscanf(levc, "%d", &lev);
480 name = strtok(NULL, ":");
481
482 toc_debug_printf("evil: %s | %d\n", name, lev);
483
484 numargs = 3;
485 my_evil = lev;
486 args = (char **) malloc(sizeof(char *)*numargs);
487 if ( name != NULL )
488 args[0] = strdup(name);
489 else
490 args[0] = NULL;
491 args[1] = strdup(levc);
492 args[2] = NULL;
493 use_handler(TOC_HANDLE,TOC_EVILED,args);
494
495 } else if (!strcasecmp(c, "CHAT_JOIN")) {
496 char *name,*idc;
497 int id;
498
499 use_handler(TOC_RAW_HANDLE,TOC_CHAT_JOIN,raw);
500 idc = strtok(NULL, ":");
501 sscanf(idc, "%d", &id);
502 name = strtok(NULL, ":");
503 serv_got_joined_chat(id, name);
504 numargs = 3;
505 args = (char **) malloc(sizeof(char *)*numargs);
506 args[0] = strdup(idc);
507 args[1] = strdup(name);
508 args[2] = NULL;
509 use_handler(TOC_HANDLE,TOC_CHAT_JOIN,args);
510 } else if (!strcasecmp(c, "DIR_STATUS")) {
511 char *status;
512 use_handler(TOC_RAW_HANDLE,TOC_DIR_STATUS,raw);
513 status = strtok(NULL,":");
514 numargs = 2;
515 args = (char **) malloc(sizeof(char *)*numargs);
516 args[0] = strdup(status);
517 args[1] = NULL;
518 use_handler(TOC_HANDLE,TOC_DIR_STATUS,args);
519 } else if (!strcasecmp(c, "CHAT_UPDATE_BUDDY")) {
520 int id;
521 char *in,*idc;
522 char *buddy;
523 LLE t;
524 struct buddy_chat *b = NULL;
525
526 use_handler(TOC_RAW_HANDLE,TOC_CHAT_UPDATE_BUDDY,raw);
527 idc = strtok(NULL, ":");
528 sscanf(idc, "%d", &id);
529
530 in = strtok(NULL, ":");
531
532 for ( TLL(buddy_chats,t) ) {
533 b = (struct buddy_chat *)t->data;
534 if (id == b->id)
535 break;
536 b = NULL;
537 }
538
539 if (!b)
540 return -2;
541
542
543 if (!strcasecmp(in, "T")) {
544 while((buddy = strtok(NULL, ":")) != NULL) {
545 /*
546 * Fuxin aim causes a problem here
547 */
548 AddToLL(b->in_room, buddy,NULL);
549 if ( b->init_chat ) {
550 args = (char **) malloc(sizeof(char *)*3);
551 args[0] = strdup(b->name);
552 args[1] = strdup(buddy);
553 args[2] = NULL;
554 use_handler(TOC_HANDLE,TOC_BUDDY_JOIN_CHAT,args);
555 free(args[0]); free(args[1]); free(args); args = NULL;
556 }
557 }
558 /*
559 * init_chat is so that the user doenst get flooded
560 * with user joined chat when he first joins a chat
561 */
562 b->init_chat = 1;
563 } else {
564 while((buddy = strtok(NULL, ":")) != NULL) {
565 RemoveFromLLByKey(b->in_room, buddy);
566 /*
567 * Since we might get multiple leave/joins at once
568 * we allocate & deallocate here
569 */
570 args = (char **) malloc(sizeof(char *)*3);
571 args[0] = strdup(b->name);
572 args[1] = strdup(buddy);
573 args[2] = NULL;
574 use_handler(TOC_HANDLE,TOC_BUDDY_LEFT_CHAT,args);
575 free(args[0]); free(args[1]); free(args); args = NULL;
576 }
577 }
578 } else if (!strcasecmp(c, "CHAT_LEFT")) {
579 char *idc;
580 int id;
581
582 use_handler(TOC_RAW_HANDLE,TOC_CHAT_LEFT,raw);
583 idc = strtok(NULL, ":");
584 sscanf(idc, "%d", &id);
585
586 serv_got_chat_left(id);
587
588 numargs = 2;
589 args = (char **) malloc(sizeof(char *)*numargs);
590 args[0] = strdup(idc);
591 args[1] = NULL;
592 use_handler(TOC_HANDLE,TOC_CHAT_LEFT,args);
593 } else if (!strcasecmp(c, "CHAT_IN")) {
594
595 int id, w;
596 char *m,*idc;
597 char *who, *whisper, *chan;
598 struct buddy_chat *b;
599
600 use_handler(TOC_RAW_HANDLE,TOC_CHAT_IN,raw);
601 idc = strtok(NULL, ":");
602 sscanf(idc, "%d", &id);
603 who = strtok(NULL, ":");
604 whisper = strtok(NULL, ":");
605 m = whisper;
606 while(*m && (*m != ':')) m++;
607 m++;
608
609 if (!strcasecmp(whisper, "T"))
610 w = 1;
611 else
612 w = 0;
613
614 /* serv_got_chat_in(id, who, w, m); */
615 b = buddy_chat_getbyid(id);
616 if ( ! b ) {
617 chan = (char *) malloc(50);
618 strcpy(chan,"ERROR Couldn't lookup chan!");
619 } else {
620 chan = (char *) malloc(strlen(b->name)+1);
621 strcpy(chan,b->name);
622 }
623 numargs = 6;
624 args = (char **) malloc(sizeof(char *)*numargs);
625 args[0] = strdup(idc);
626 args[1] = strdup(who);
627 args[2] = strdup(whisper);
628 args[3] = strdup(m);
629 /* Added arg to make things simple */
630 args[4] = chan;
631 args[5] = NULL;
632 use_handler(TOC_HANDLE,TOC_CHAT_IN,args);
633 } else if (!strcasecmp(c, "CHAT_INVITE")) {
634 char *name;
635 char *who;
636 char *message,*idc;
637 int id, *pid;
638
639 use_handler(TOC_RAW_HANDLE,TOC_CHAT_INVITE,raw);
640 name = strtok(NULL, ":");
641 idc = strtok(NULL, ":");
642 sscanf(idc, "%d", &id);
643 who = strtok(NULL, ":");
644 message = strtok(NULL, ":");
645 /* serv_got_chat_invite(name, id, who, message); */
646 pid = (int *) malloc(sizeof(int));
647 *pid = id;
648 AddToLL(invited_chats,name,pid);
649 numargs = 5;
650 args = (char **) malloc(sizeof(char *)*numargs);
651 args[0] = strdup(name);
652 args[1] = strdup(idc);
653 args[2] = strdup(who);
654 args[3] = strdup(message);
655 args[4] = NULL;
656 use_handler(TOC_HANDLE,TOC_CHAT_INVITE,args);
657 } else {
658 toc_debug_printf("don't know what to do with %s\n", c);
659 }
660 free(dup);
661 free(buf);
662 if ( args != NULL ) {
663 int x;
664 /* toc_debug_printf("\nGOING TO FREE!: numargs = %d",numargs); */
665 for (x=0;x< numargs; x++)
666 if ( args[x] != NULL ) {
667 /* toc_debug_printf("freeing %d",x); */
668 free(args[x]);
669 }
670 /* toc_debug_printf(""); */
671 free(args);
672 }
673 return 1;
674 }
675
toc_wait_config()676 char *toc_wait_config()
677 {
678 /* Waits for configuration packet, returning the contents of the packet */
679 static char buf[BUF_LEN];
680 int res;
681 res = wait_reply(buf, sizeof(buf));
682 if (res < 0)
683 return NULL;
684 if (state != STATE_CONFIG) {
685 toc_debug_printf("State should be %d, but is %d instead\n",STATE_CONFIG, state);
686 return NULL;
687 }
688 /* At this point, it's time to setup automatic handling of incoming packets */
689 state = STATE_ONLINE;
690
691 // inpa = gdk_input_add(toc_fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_callback, NULL);
692 toc_add_input_stream(toc_fd,&toc_callback);
693
694 return buf;
695 }
696
parse_toc_buddy_list(char * config)697 void parse_toc_buddy_list(char *config)
698 {
699 char *c;
700 char current[256];
701 char *name;
702 LL bud = CreateLL();
703
704 /* skip "CONFIG:" (if it exists)*/
705
706 c = strncmp(config + sizeof(struct sflap_hdr),"CONFIG:",strlen("CONFIG:"))?
707 strtok(config, "\n"):
708 strtok(config + sizeof(struct sflap_hdr)+strlen("CONFIG:"), "\n");
709
710 do {
711 if (c == NULL)
712 break;
713 if (*c == 'g') {
714 strncpy(current,c+2, sizeof(current));
715 add_group(current);
716 } else if (*c == 'b') {
717 add_buddy(current, c+2);
718 AddToLL(bud, c+2, NULL);
719 } else if (*c == 'p') {
720 name = malloc(strlen(c+2) + 2);
721 snprintf(name, strlen(c+2) + 1, "%s", c+2);
722 AddToLL(permit, name, NULL);
723 } else if (*c == 'd') {
724 name = malloc(strlen(c+2) + 2);
725 snprintf(name, strlen(c+2) + 1, "%s", c+2);
726 AddToLL(deny, name,NULL);
727 } else if (*c == 'm') {
728 sscanf(c + strlen(c) - 1, "%d", &permdeny);
729 if (permdeny == 0)
730 permdeny = PERMIT_PERMITALL;
731 }
732 } while ((c=strtok(NULL,"\n")));
733
734 serv_add_buddies(bud);
735 FreeLL(bud);
736 serv_set_permit_deny();
737 }
738
toc_signoff()739 int toc_signoff() {
740 /* Leaking memory like a MOFO */
741 FreeLL(groups);
742 FreeLL(buddy_chats);
743 FreeLL(invited_chats);
744 FreeLL(permit);
745 FreeLL(deny);
746 deny = groups = permit = buddy_chats = invited_chats = NULL;
747 toc_debug_printf("LEAKING MEMORY LIKE A BITCH in toc_signoff!");
748
749 serv_close();
750 toc_msg_printf(TOC_CONNECT_MSGS,"%s signed off",aim_username);
751 return 1;
752 }
753
toc_build_config(char * s,int len)754 void toc_build_config(char *s, int len)
755 {
756 struct group *g;
757 struct buddy *b;
758 LLE t,t1;
759 LL mem;
760
761 int pos=0;
762 toc_debug_printf("FIX this permdeny hack shit!");
763
764 if (!permdeny)
765 permdeny = PERMIT_PERMITALL;
766 pos += snprintf(&s[pos], len - pos, "m %d\n", permdeny);
767
768 /* Create Buddy List */
769 for ( TLL(groups,t) ) {
770 g = (struct group *)t->data;
771 pos += snprintf(&s[pos], len - pos, "g %s\n", g->name);
772 mem = g->members;
773 for ( TLL(mem,t1) ) {
774 b = (struct buddy *)t1->data;
775 pos += snprintf(&s[pos], len - pos, "b %s\n", b->name);
776 }
777 }
778
779 /* Create Permit and Deny Lists */;
780 for ( TLL(permit,t) ) {
781 toc_debug_printf("permit: added %s\n",(char *)t->key);
782 pos += snprintf(&s[pos], len - pos, "p %s\n", (char *)t->key);
783 }
784 for ( TLL(deny,t) ) {
785 toc_debug_printf("deny: added %s\n",(char *)t->key);
786 pos += snprintf(&s[pos], len - pos, "d %s\n", (char *)t->key);
787 }
788 }
789
translate_toc_error_code(char * c)790 void translate_toc_error_code(char *c) {
791
792 int no = atoi(c);
793 char *w = strtok(NULL, ":");
794 char buf[256];
795
796 switch ( no ) {
797 case 901:
798 snprintf(buf, sizeof(buf), "%s not currently logged in.", w);
799 break;
800 case 902:
801 snprintf(buf, sizeof(buf), "Warning of %s not allowed.", w);
802 break;
803 case 903:
804 snprintf(buf, sizeof(buf), "A message has been dropped, you are exceeding the server speed limit.");
805 break;
806 case 950:
807 snprintf(buf, sizeof(buf), "Chat in %s is not available.", w);
808 break;
809 case 960:
810 snprintf(buf, sizeof(buf), "You are sending messages too fast to %s.", w);
811 break;
812 case 961:
813 snprintf(buf, sizeof(buf), "You missed an IM from %s because it was too big.", w);
814 break;
815 case 962:
816 snprintf(buf, sizeof(buf), "You missed an IM from %s because it was sent too fast.", w);
817 break;
818 case 970:
819 snprintf(buf, sizeof(buf), "Failure.");
820 break;
821 case 971:
822 snprintf(buf, sizeof(buf), "Too many matches.");
823 break;
824 case 972:
825 snprintf(buf, sizeof(buf), "Need more qualifiers.");
826 break;
827 case 973:
828 snprintf(buf, sizeof(buf), "Dir service temporarily unavailable.");
829 break;
830 case 974:
831 snprintf(buf, sizeof(buf), "Email lookup restricted.");
832 break;
833 case 975:
834 snprintf(buf, sizeof(buf), "Keyword ignored.");
835 break;
836 case 976:
837 snprintf(buf, sizeof(buf), "No keywords.");
838 break;
839 case 977:
840 snprintf(buf, sizeof(buf), "User has no directory information.");
841 /* snprintf(buf, sizeof(buf), "Language not supported."); */
842 break;
843 case 978:
844 snprintf(buf, sizeof(buf), "Country not supported.");
845 break;
846 case 979:
847 snprintf(buf, sizeof(buf), "Failure unknown: %s.", w);
848 break;
849 case 980:
850 snprintf(buf, sizeof(buf), "Incorrect nickname or password.");
851 break;
852 case 981:
853 snprintf(buf, sizeof(buf), "The service is temporarily unavailable.");
854 break;
855 case 982:
856 snprintf(buf, sizeof(buf), "Your warning level is currently too high to log in.");
857 break;
858 case 983:
859 snprintf(buf, sizeof(buf), "You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.");
860 break;
861 case 989:
862 snprintf(buf, sizeof(buf), "An unknown signon error has occurred: %s.", w);
863 break;
864 default:
865 snprintf(buf, sizeof(buf), "An unknown error, %d, has occured. Info: %s", no, w);
866 }
867 toc_msg_printf(TOC_TRANSLATED_ERROR,buf);
868 return;
869 }
870