comparison src/toc.c @ 1:2846a03bda67

[gaim-migrate @ 10] The other missing files :) committer: Tailor Script <tailor@pidgin.im>
author Rob Flynn <gaim@robflynn.com>
date Thu, 23 Mar 2000 03:13:54 +0000
parents
children 34db9f242899
comparison
equal deleted inserted replaced
0:a5ace2e037bc 1:2846a03bda67
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 }