/[cvs]/eggdrop1.9/src/userent.c
ViewVC logotype

Contents of /eggdrop1.9/src/userent.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.14 - (show annotations) (download) (as text)
Thu Mar 23 23:17:56 2000 UTC (19 years, 7 months ago) by fabian
Branch: MAIN
CVS Tags: eggdrop10403
Changes since 1.13: +13 -13 lines
File MIME type: text/x-chdr
conf_make_fix6 patch

1 /*
2 * userent.c -- handles:
3 * user-entry handling, new stylem more versatile.
4 *
5 * $Id: userent.c,v 1.13 2000/02/01 20:17:36 fabian Exp $
6 */
7 /*
8 * Copyright (C) 1997 Robey Pointer
9 * Copyright (C) 1999, 2000 Eggheads
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25
26 #include "main.h"
27 #include "users.h"
28
29 extern int noshare;
30 extern struct userrec *userlist;
31 extern struct dcc_t *dcc;
32 extern Tcl_Interp *interp;
33 extern char whois_fields[];
34
35
36 int share_greet = 0; /* Share greeting info */
37 static struct user_entry_type *entry_type_list;
38
39
40 void init_userent()
41 {
42 entry_type_list = 0;
43 add_entry_type(&USERENTRY_COMMENT);
44 add_entry_type(&USERENTRY_XTRA);
45 add_entry_type(&USERENTRY_INFO);
46 add_entry_type(&USERENTRY_LASTON);
47 add_entry_type(&USERENTRY_BOTADDR);
48 add_entry_type(&USERENTRY_PASS);
49 add_entry_type(&USERENTRY_HOSTS);
50 add_entry_type(&USERENTRY_BOTFL);
51 }
52
53 void list_type_kill(struct list_type *t)
54 {
55 struct list_type *u;
56
57 while (t) {
58 u = t->next;
59 if (t->extra)
60 nfree(t->extra);
61 nfree(t);
62 t = u;
63 }
64 }
65
66 int list_type_expmem(struct list_type *t)
67 {
68 int tot = 0;
69
70 for (; t; t = t->next)
71 tot += sizeof(struct list_type) + strlen(t->extra) + 1;
72
73 return tot;
74 }
75
76 int def_unpack(struct userrec *u, struct user_entry *e)
77 {
78 char *tmp;
79
80 Context;
81 Assert(e);
82 Assert(e->name);
83 tmp = e->u.list->extra;
84 e->u.list->extra = NULL;
85 list_type_kill(e->u.list);
86 e->u.string = tmp;
87 return 1;
88 }
89
90 int def_pack(struct userrec *u, struct user_entry *e)
91 {
92 char *tmp;
93
94 Assert(e);
95 Assert(!e->name);
96 tmp = e->u.string;
97 e->u.list = user_malloc(sizeof(struct list_type));
98 e->u.list->next = NULL;
99 e->u.list->extra = tmp;
100 return 1;
101 }
102
103 int def_kill(struct user_entry *e)
104 {
105 Context;
106 nfree(e->u.string);
107 nfree(e);
108 return 1;
109 }
110
111 int def_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
112 {
113 Context;
114 if (fprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
115 return 0;
116 return 1;
117 }
118
119 void *def_get(struct userrec *u, struct user_entry *e)
120 {
121 return e->u.string;
122 }
123
124 int def_set(struct userrec *u, struct user_entry *e, void *buf)
125 {
126 char *string = (char *) buf;
127 ContextNote("drummer's bug?");
128
129 if (string && !string[0])
130 string = NULL;
131 if (!string && !e->u.string)
132 return 1;
133 Context;
134 Assert(string != e->u.string);
135 if (string) {
136 int l = strlen (string);
137 char *i;
138
139 if (l > 160)
140 l = 160;
141
142
143 e->u.string = user_realloc (e->u.string, l + 1);
144
145 strncpy (e->u.string, string, l);
146 e->u.string[l] = 0;
147
148 for (i = e->u.string; *i; i++)
149 /* Allow bold, inverse, underline, color text here...
150 * But never add cr or lf!! --rtc
151 */
152 if ((unsigned int) *i < 32 && !strchr ("\002\003\026\037", *i))
153 *i = '?';
154 } else { /* string == NULL && e->u.string != NULL */
155 nfree(e->u.string);
156 e->u.string = NULL;
157 }
158 Assert(u);
159 if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED))) {
160 if (e->type != &USERENTRY_INFO || share_greet)
161 shareout(NULL, "c %s %s %s\n", e->type->name, u->handle,
162 e->u.string ? e->u.string : "");
163 }
164 Context;
165 return 1;
166 }
167
168 int def_gotshare(struct userrec *u, struct user_entry *e,
169 char *data, int idx)
170 {
171 putlog(LOG_CMDS, "*", "%s: change %s %s", dcc[idx].nick, e->type->name,
172 u->handle);
173 return e->type->set(u, e, data);
174 }
175
176 int def_tcl_get(Tcl_Interp * interp, struct userrec *u,
177 struct user_entry *e, int argc, char **argv)
178 {
179 Tcl_AppendResult(interp, e->u.string, NULL);
180 return TCL_OK;
181 }
182
183 int def_tcl_set(Tcl_Interp * irp, struct userrec *u,
184 struct user_entry *e, int argc, char **argv)
185 {
186 BADARGS(4, 4, " handle type setting");
187 e->type->set(u, e, argv[3]);
188 return TCL_OK;
189 }
190
191 int def_expmem(struct user_entry *e)
192 {
193 Context;
194 return strlen(e->u.string) + 1;
195 }
196
197 void def_display(int idx, struct user_entry *e)
198 {
199 Context;
200 dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
201 }
202
203 int def_dupuser(struct userrec *new, struct userrec *old,
204 struct user_entry *e)
205 {
206 return set_user(e->type, new, e->u.string);
207 }
208
209 static void comment_display(int idx, struct user_entry *e)
210 {
211 Context;
212 if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
213 dprintf(idx, " COMMENT: %.70s\n", e->u.string);
214 }
215
216 struct user_entry_type USERENTRY_COMMENT =
217 {
218 0, /* always 0 ;) */
219 def_gotshare,
220 def_dupuser,
221 def_unpack,
222 def_pack,
223 def_write_userfile,
224 def_kill,
225 def_get,
226 def_set,
227 def_tcl_get,
228 def_tcl_set,
229 def_expmem,
230 comment_display,
231 "COMMENT"
232 };
233
234 struct user_entry_type USERENTRY_INFO =
235 {
236 0, /* always 0 ;) */
237 def_gotshare,
238 def_dupuser,
239 def_unpack,
240 def_pack,
241 def_write_userfile,
242 def_kill,
243 def_get,
244 def_set,
245 def_tcl_get,
246 def_tcl_set,
247 def_expmem,
248 def_display,
249 "INFO"
250 };
251
252 int pass_set(struct userrec *u, struct user_entry *e, void *buf)
253 {
254 char new[32];
255 register char *pass = buf;
256
257 if (e->u.extra)
258 nfree(e->u.extra);
259 if (!pass || !pass[0] || (pass[0] == '-'))
260 e->u.extra = NULL;
261 else {
262 unsigned char *p = (unsigned char *) pass;
263
264 if (strlen(pass) > 15)
265 pass[15] = 0;
266 while (*p) {
267 if ((*p <= 32) || (*p == 127))
268 *p = '?';
269 p++;
270 }
271 if ((u->flags & USER_BOT) || (pass[0] == '+'))
272 strcpy(new, pass);
273 else
274 encrypt_pass(pass, new);
275 e->u.extra = user_malloc(strlen(new) + 1);
276 strcpy(e->u.extra, new);
277 }
278 if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
279 shareout(NULL, "c PASS %s %s\n", u->handle, pass ? pass : "");
280 return 1;
281 }
282
283 static int pass_tcl_set(Tcl_Interp * irp, struct userrec *u,
284 struct user_entry *e, int argc, char **argv)
285 {
286 BADARGS(3, 4, " handle PASS ?newpass?");
287 pass_set(u, e, argv[3]);
288 return TCL_OK;
289 }
290
291 struct user_entry_type USERENTRY_PASS =
292 {
293 0,
294 def_gotshare,
295 0,
296 def_unpack,
297 def_pack,
298 def_write_userfile,
299 def_kill,
300 def_get,
301 pass_set,
302 def_tcl_get,
303 pass_tcl_set,
304 def_expmem,
305 0,
306 "PASS"
307 };
308
309 static int laston_unpack(struct userrec *u, struct user_entry *e)
310 {
311 char *par, *arg;
312 struct laston_info *li;
313
314 Context;
315 Assert(e);
316 Assert(e->name);
317 par = e->u.list->extra;
318 Assert(par);
319 arg = newsplit (&par);
320 if (!par[0])
321 par = "???";
322 li = user_malloc(sizeof(struct laston_info));
323 li->lastonplace = user_malloc(strlen(par) + 1);
324 li->laston = atoi(arg);
325 strcpy(li->lastonplace, par);
326 list_type_kill(e->u.list);
327 e->u.extra = li;
328 return 1;
329 }
330
331 static int laston_pack(struct userrec *u, struct user_entry *e)
332 {
333 char work[1024];
334 struct laston_info *li;
335 int l;
336
337 Assert(e);
338 Assert(e->u.extra);
339 Assert(!e->name);
340 li = (struct laston_info *) e->u.extra;
341 l = sprintf(work, "%lu %s", li->laston, li->lastonplace);
342 e->u.list = user_malloc(sizeof(struct list_type));
343 e->u.list->next = NULL;
344 e->u.list->extra = user_malloc(l + 1);
345 strcpy(e->u.list->extra, work);
346 nfree(li->lastonplace);
347 nfree(li);
348 return 1;
349 }
350
351 static int laston_write_userfile(FILE * f,
352 struct userrec *u,
353 struct user_entry *e)
354 {
355 struct laston_info *li = (struct laston_info *) e->u.extra;
356
357 Context;
358 if (fprintf(f, "--LASTON %lu %s\n", li->laston,
359 li->lastonplace ? li->lastonplace : "") == EOF)
360 return 0;
361 return 1;
362 }
363
364 static int laston_kill(struct user_entry *e)
365 {
366 Context;
367 if (((struct laston_info *) (e->u.extra))->lastonplace)
368 nfree(((struct laston_info *) (e->u.extra))->lastonplace);
369 nfree(e->u.extra);
370 nfree(e);
371 return 1;
372 }
373
374 static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
375 {
376 struct laston_info *li = (struct laston_info *) e->u.extra;
377
378 Context;
379 if (li != buf) {
380 if (li) {
381 Assert(li->lastonplace);
382 nfree(li->lastonplace);
383 nfree(li);
384 }
385 ContextNote("(sharebug) occurred in laston_set");
386
387 li = e->u.extra = buf;
388 }
389 /* donut share laston info */
390 return 1;
391 }
392
393 static int laston_tcl_get(Tcl_Interp * irp, struct userrec *u,
394 struct user_entry *e, int argc, char **argv)
395 {
396 struct laston_info *li = (struct laston_info *) e->u.extra;
397 char number[20];
398 struct chanuserrec *cr;
399
400 BADARGS(3, 4, " handle LASTON ?channel?");
401 if (argc == 4) {
402 for (cr = u->chanrec; cr; cr = cr->next)
403 if (!rfc_casecmp(cr->channel, argv[3])) {
404 Tcl_AppendResult(irp, int_to_base10(cr->laston), NULL);
405 break;
406 }
407 if (!cr)
408 Tcl_AppendResult(irp, "0", NULL);
409 } else {
410 sprintf(number, "%lu ", li->laston);
411 Tcl_AppendResult(irp, number, li->lastonplace, NULL);
412 }
413 return TCL_OK;
414 }
415
416 static int laston_tcl_set(Tcl_Interp * irp, struct userrec *u,
417 struct user_entry *e, int argc, char **argv)
418 {
419 struct laston_info *li;
420 struct chanuserrec *cr;
421
422 BADARGS(4, 5, " handle LASTON time ?place?");
423
424 if ((argc == 5) && argv[4][0] && strchr(CHANMETA, argv[4][0])) {
425 /* Search for matching channel */
426 for (cr = u->chanrec; cr; cr = cr->next)
427 if (!rfc_casecmp(cr->channel, argv[4])) {
428 cr->laston = atoi(argv[3]);
429 break;
430 }
431 }
432 /* Save globally */
433 li = user_malloc(sizeof(struct laston_info));
434
435 if (argc == 5) {
436 li->lastonplace = user_malloc(strlen(argv[4]) + 1);
437 strcpy(li->lastonplace, argv[4]);
438 } else {
439 li->lastonplace = user_malloc(1);
440 li->lastonplace[0] = 0;
441 }
442 li->laston = atoi(argv[3]);
443 set_user(&USERENTRY_LASTON, u, li);
444 return TCL_OK;
445 }
446
447 static int laston_expmem(struct user_entry *e)
448 {
449 Context;
450 return sizeof(struct laston_info) +
451 strlen(((struct laston_info *) (e->u.extra))->lastonplace) + 1;
452 }
453
454 static int laston_dupuser(struct userrec *new, struct userrec *old,
455 struct user_entry *e)
456 {
457 struct laston_info *li = e->u.extra, *li2;
458
459 if (li) {
460 li2 = user_malloc(sizeof(struct laston_info));
461
462 li2->laston = li->laston;
463 li2->lastonplace = user_malloc(strlen(li->lastonplace) + 1);
464 strcpy(li2->lastonplace, li->lastonplace);
465 return set_user(&USERENTRY_LASTON, new, li2);
466 }
467 return 0;
468 }
469
470 struct user_entry_type USERENTRY_LASTON =
471 {
472 0, /* always 0 ;) */
473 0,
474 laston_dupuser,
475 laston_unpack,
476 laston_pack,
477 laston_write_userfile,
478 laston_kill,
479 def_get,
480 laston_set,
481 laston_tcl_get,
482 laston_tcl_set,
483 laston_expmem,
484 0,
485 "LASTON"
486 };
487
488 static int botaddr_unpack(struct userrec *u, struct user_entry *e)
489 {
490 char *p, *q;
491 struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
492
493 Context;
494 Assert(e);
495 Assert(e->name);
496 egg_bzero(bi, sizeof(struct bot_addr));
497
498 if (!(q = strchr ((p = e->u.list->extra), ':'))) {
499 bi->address = user_malloc(strlen (p) + 1);
500 strcpy (bi->address, p);
501 } else {
502 bi->address = user_malloc((q - p) + 1);
503 strncpy(bi->address, p, q - p);
504 bi->address[q - p] = 0;
505 q++;
506 bi->telnet_port = atoi(q);
507 if ((q = strchr(q, '/')))
508 bi->relay_port = atoi(q + 1);
509 }
510 if (!bi->telnet_port)
511 bi->telnet_port = 3333;
512 if (!bi->relay_port)
513 bi->relay_port = bi->telnet_port;
514 list_type_kill(e->u.list);
515 e->u.extra = bi;
516 return 1;
517 }
518
519 static int botaddr_pack(struct userrec *u, struct user_entry *e)
520 {
521 char work[1024];
522 struct bot_addr *bi;
523 int l;
524
525 Assert(e);
526 Assert(!e->name);
527 bi = (struct bot_addr *) e->u.extra;
528 l = simple_sprintf(work, "%s:%u/%u", bi->address, bi->telnet_port,
529 bi->relay_port);
530 e->u.list = user_malloc(sizeof(struct list_type));
531 e->u.list->next = NULL;
532 e->u.list->extra = user_malloc(l + 1);
533 strcpy(e->u.list->extra, work);
534 nfree(bi->address);
535 nfree(bi);
536 return 1;
537 }
538
539 static int botaddr_kill(struct user_entry *e)
540 {
541 Context;
542 nfree(((struct bot_addr *) (e->u.extra))->address);
543 nfree(e->u.extra);
544 nfree(e);
545 Context;
546 return 1;
547 }
548
549 static int botaddr_write_userfile(FILE *f, struct userrec *u,
550 struct user_entry *e)
551 {
552 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
553
554 Context;
555 if (fprintf(f, "--%s %s:%u/%u\n", e->type->name, bi->address,
556 bi->telnet_port, bi->relay_port) == EOF)
557 return 0;
558 return 1;
559 }
560
561 static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
562 {
563 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
564
565 Context;
566 if (!bi && !buf)
567 return 1;
568 if (bi != buf) {
569 if (bi) {
570 Assert(bi->address);
571 nfree(bi->address);
572 nfree(bi);
573 }
574 ContextNote("(sharebug) occurred in botaddr_set");
575 bi = e->u.extra = buf;
576 }
577 Assert(u);
578 if (bi && !noshare && !(u->flags & USER_UNSHARED)) {
579 shareout(NULL, "c BOTADDR %s %s %d %d\n", u->handle,
580 bi->address, bi->telnet_port, bi->relay_port);
581 }
582 return 1;
583 }
584
585 static int botaddr_tcl_get(Tcl_Interp *interp, struct userrec *u,
586 struct user_entry *e, int argc, char **argv)
587 {
588 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
589 char number[20];
590
591 Context;
592 sprintf(number, " %d", bi->telnet_port);
593 Tcl_AppendResult(interp, bi->address, number, NULL);
594 sprintf(number, " %d", bi->relay_port);
595 Tcl_AppendResult(interp, number, NULL);
596 return TCL_OK;
597 }
598
599 static int botaddr_tcl_set(Tcl_Interp *irp, struct userrec *u,
600 struct user_entry *e, int argc, char **argv)
601 {
602 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
603
604 BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
605 if (u->flags & USER_BOT) {
606 /* Silently ignore for users */
607 if (!bi) {
608 bi = user_malloc(sizeof(struct bot_addr));
609 egg_bzero(bi, sizeof (struct bot_addr));
610 } else {
611 Assert(bi->address);
612 nfree(bi->address);
613 }
614 bi->address = user_malloc(strlen(argv[3]) + 1);
615 strcpy(bi->address, argv[3]);
616 if (argc > 4)
617 bi->telnet_port = atoi(argv[4]);
618 if (argc > 5)
619 bi->relay_port = atoi(argv[5]);
620 if (!bi->telnet_port)
621 bi->telnet_port = 3333;
622 if (!bi->relay_port)
623 bi->relay_port = bi->telnet_port;
624 botaddr_set(u, e, bi);
625 }
626 return TCL_OK;
627 }
628
629 static int botaddr_expmem(struct user_entry *e)
630 {
631 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
632
633 Context;
634 return strlen(bi->address) + 1 + sizeof(struct bot_addr);
635 }
636
637 static void botaddr_display(int idx, struct user_entry *e)
638 {
639 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
640
641 Context;
642 dprintf(idx, " ADDRESS: %.70s\n", bi->address);
643 dprintf(idx, " telnet: %d, relay: %d\n", bi->telnet_port, bi->relay_port);
644 }
645
646 static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
647 char *buf, int idx)
648 {
649 struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
650 char *arg;
651
652 egg_bzero(bi, sizeof(struct bot_addr));
653 arg = newsplit(&buf);
654 bi->address = user_malloc(strlen(arg) + 1);
655 strcpy(bi->address, arg);
656 arg = newsplit(&buf);
657 bi->telnet_port = atoi(arg);
658 bi->relay_port = atoi(buf);
659 if (!bi->telnet_port)
660 bi->telnet_port = 3333;
661 if (!bi->relay_port)
662 bi->relay_port = bi->telnet_port;
663 if (!(dcc[idx].status & STAT_GETTING))
664 putlog(LOG_CMDS, "*", "%s: change botaddr %s", dcc[idx].nick,
665 u->handle);
666 return botaddr_set(u, e, bi);
667 }
668
669 static int botaddr_dupuser(struct userrec *new, struct userrec *old,
670 struct user_entry *e)
671 {
672 if (old->flags & USER_BOT) {
673 struct bot_addr *bi = e->u.extra, *bi2;
674
675 if (bi) {
676 bi2 = user_malloc(sizeof(struct bot_addr));
677
678 bi2->telnet_port = bi->telnet_port;
679 bi2->relay_port = bi->relay_port;
680 bi2->address = user_malloc(strlen(bi->address) + 1);
681 strcpy(bi2->address, bi->address);
682 return set_user(&USERENTRY_BOTADDR, new, bi2);
683 }
684 }
685 return 0;
686 }
687
688 struct user_entry_type USERENTRY_BOTADDR =
689 {
690 0, /* always 0 ;) */
691 botaddr_gotshare,
692 botaddr_dupuser,
693 botaddr_unpack,
694 botaddr_pack,
695 botaddr_write_userfile,
696 botaddr_kill,
697 def_get,
698 botaddr_set,
699 botaddr_tcl_get,
700 botaddr_tcl_set,
701 botaddr_expmem,
702 botaddr_display,
703 "BOTADDR"
704 };
705
706 int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
707 {
708 struct xtra_key *curr, *old = NULL, *new = buf;
709
710 Context;
711 Assert(new);
712 for (curr = e->u.extra; curr; curr = curr->next) {
713 if (curr->key && !egg_strcasecmp(curr->key, new->key)) {
714 old = curr;
715 break;
716 }
717 }
718 if (!old && (!new->data || !new->data[0])) {
719 /* Delete non-existant entry -- doh ++rtc */
720 nfree(new->key);
721 if (new->data)
722 nfree(new->data);
723 nfree(new);
724 return TCL_OK;
725 }
726
727 /* We will possibly free new below, so let's send the information
728 * to the botnet now
729 */
730 if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
731 shareout(NULL, "c XTRA %s %s %s\n", u->handle, new->key,
732 new->data ? new->data : "");
733 if ((old && old != new) || !new->data || !new->data[0]) {
734 list_delete((struct list_type **) (&e->u.extra),
735 (struct list_type *) old);
736 nfree(old->key);
737 nfree(old->data);
738 nfree(old);
739 }
740 if (old != new && new->data) {
741 if (new->data[0])
742 list_insert((&e->u.extra), new) /* do not add a ';' here */
743 else {
744 nfree(new->data);
745 nfree(new->key);
746 nfree(new);
747 }
748 }
749 return TCL_OK;
750 }
751
752 static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
753 struct user_entry *e, int argc, char **argv)
754 {
755 struct xtra_key *xk;
756 int l;
757
758 BADARGS(4, 5, " handle type key ?value?");
759 xk = user_malloc(sizeof(struct xtra_key));
760 l = strlen(argv[3]);
761 egg_bzero(xk, sizeof (struct xtra_key));
762 if (l > 500)
763 l = 500;
764 xk->key = user_malloc(l + 1);
765 strncpy(xk->key, argv[3], l);
766 xk->key[l] = 0;
767
768 if (argc == 5) {
769 int k = strlen(argv[4]);
770
771 if (k > 500 - l)
772 k = 500 - l;
773 xk->data = user_malloc(k + 1);
774 strncpy(xk->data, argv[4], k);
775 xk->data[k] = 0;
776 }
777 xtra_set(u, e, xk);
778 return TCL_OK;
779 }
780
781 int xtra_unpack(struct userrec *u, struct user_entry *e)
782 {
783 struct list_type *curr, *head;
784 struct xtra_key *t;
785 char *key, *data;
786
787 Context;
788 Assert(e);
789 Assert(e->name);
790 head = curr = e->u.list;
791 e->u.extra = NULL;
792 while (curr) {
793 t = user_malloc(sizeof(struct xtra_key));
794
795 data = curr->extra;
796 key = newsplit(&data);
797 if (data[0]) {
798 t->key = user_malloc(strlen(key) + 1);
799 strcpy(t->key, key);
800 t->data = user_malloc(strlen(data) + 1);
801 strcpy(t->data, data);
802 list_insert((&e->u.extra), t);
803 }
804 curr = curr->next;
805 }
806 list_type_kill(head);
807 return 1;
808 }
809
810 static int xtra_pack(struct userrec *u, struct user_entry *e)
811 {
812 struct list_type *t;
813 struct xtra_key *curr, *next;
814
815 Context;
816 Assert(e);
817 Assert(!e->name);
818 curr = e->u.extra;
819 e->u.list = NULL;
820 while (curr) {
821 t = user_malloc(sizeof(struct list_type));
822 t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
823 sprintf(t->extra, "%s %s", curr->key, curr->data);
824 list_insert((&e->u.list), t);
825 next = curr->next;
826 nfree(curr->key);
827 nfree(curr->data);
828 nfree(curr);
829 curr = next;
830 }
831 return 1;
832 }
833
834 static void xtra_display(int idx, struct user_entry *e)
835 {
836 int code, lc, j;
837 struct xtra_key *xk;
838 char **list;
839
840 Context;
841 code = Tcl_SplitList(interp, whois_fields, &lc, &list);
842 if (code == TCL_ERROR)
843 return;
844 /* Scan thru xtra field, searching for matches */
845 Context;
846 for (xk = e->u.extra; xk; xk = xk->next) {
847 /* Ok, it's a valid xtra field entry */
848 Context;
849 for (j = 0; j < lc; j++) {
850 if (egg_strcasecmp(list[j], xk->key) == 0)
851 dprintf(idx, " %s: %s\n", xk->key, xk->data);
852 }
853 }
854 Tcl_Free((char *) list);
855 Context;
856 }
857
858 static int xtra_gotshare(struct userrec *u, struct user_entry *e,
859 char *buf, int idx)
860 {
861 char *arg;
862 struct xtra_key *xk;
863 int l;
864
865 arg = newsplit (&buf);
866 if (!arg[0])
867 return 1;
868
869 xk = user_malloc (sizeof(struct xtra_key));
870 egg_bzero(xk, sizeof(struct xtra_key));
871 l = strlen(arg);
872 if (l > 500)
873 l = 500;
874 xk->key = user_malloc(l + 1);
875 strncpy(xk->key, arg, l);
876 xk->key[l] = 0;
877
878 if (buf[0]) {
879 int k = strlen(buf);
880
881 if (k > 500 - l)
882 k = 500 - l;
883 xk->data = user_malloc(k + 1);
884 strncpy(xk->data, buf, k);
885 xk->data[k] = 0;
886 }
887 xtra_set(u, e, xk);
888 return 1;
889 }
890
891 static int xtra_dupuser(struct userrec *new, struct userrec *old,
892 struct user_entry *e)
893 {
894 struct xtra_key *x1, *x2;
895
896 for (x1 = e->u.extra; x1; x1 = x1->next) {
897 x2 = user_malloc(sizeof(struct xtra_key));
898
899 x2->key = user_malloc(strlen(x1->key) + 1);
900 strcpy(x2->key, x1->key);
901 x2->data = user_malloc(strlen(x1->data) + 1);
902 strcpy(x2->data, x1->data);
903 set_user(&USERENTRY_XTRA, new, x2);
904 }
905 return 1;
906 }
907
908 static int xtra_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
909 {
910 struct xtra_key *x;
911
912 for (x = e->u.extra; x; x = x->next)
913 if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
914 return 0;
915 return 1;
916 }
917
918 int xtra_kill(struct user_entry *e)
919 {
920 struct xtra_key *x, *y;
921
922 Context;
923 for (x = e->u.extra; x; x = y) {
924 y = x->next;
925 nfree(x->key);
926 nfree(x->data);
927 nfree(x);
928 }
929 nfree(e);
930 Context;
931 return 1;
932 }
933
934 static int xtra_tcl_get(Tcl_Interp *irp, struct userrec *u,
935 struct user_entry *e, int argc, char **argv)
936 {
937 struct xtra_key *x;
938
939 BADARGS(3, 4, " handle XTRA ?key?");
940 if (argc == 4) {
941 for (x = e->u.extra; x; x = x->next)
942 if (!egg_strcasecmp(argv[3], x->key)) {
943 Tcl_AppendResult(irp, x->data, NULL);
944 return TCL_OK;
945 }
946 return TCL_OK;
947 }
948 for (x = e->u.extra; x; x = x->next) {
949 char *p, *list[2];
950
951 list[0] = x->key;
952 list[1] = x->data;
953 p = Tcl_Merge(2, list);
954 Tcl_AppendElement(irp, p);
955 Tcl_Free((char *) p);
956 }
957 return TCL_OK;
958 }
959
960 static int xtra_expmem(struct user_entry *e)
961 {
962 struct xtra_key *x;
963 int tot = 0;
964
965 for (x = e->u.extra; x; x = x->next) {
966 tot += sizeof(struct xtra_key);
967
968 tot += strlen(x->key) + 1;
969 tot += strlen(x->data) + 1;
970 }
971 return tot;
972 }
973
974 struct user_entry_type USERENTRY_XTRA =
975 {
976 0,
977 xtra_gotshare,
978 xtra_dupuser,
979 xtra_unpack,
980 xtra_pack,
981 xtra_write_userfile,
982 xtra_kill,
983 def_get,
984 xtra_set,
985 xtra_tcl_get,
986 xtra_tcl_set,
987 xtra_expmem,
988 xtra_display,
989 "XTRA"
990 };
991
992 static int hosts_dupuser(struct userrec *new, struct userrec *old,
993 struct user_entry *e)
994 {
995 struct list_type *h;
996
997 for (h = e->u.extra; h; h = h->next)
998 set_user(&USERENTRY_HOSTS, new, h->extra);
999 return 1;
1000 }
1001
1002 static int hosts_null(struct userrec *u, struct user_entry *e)
1003 {
1004 return 1;
1005 }
1006
1007 static int hosts_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
1008 {
1009 struct list_type *h;
1010
1011 for (h = e->u.extra; h; h = h->next)
1012 if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
1013 return 0;
1014 return 1;
1015 }
1016
1017 static int hosts_kill(struct user_entry *e)
1018 {
1019 list_type_kill(e->u.list);
1020 nfree(e);
1021 return 1;
1022 }
1023
1024 static int hosts_expmem(struct user_entry *e)
1025 {
1026 return list_type_expmem(e->u.list);
1027 }
1028
1029 static void hosts_display(int idx, struct user_entry *e)
1030 {
1031 char s[1024];
1032 struct list_type *q;
1033
1034 s[0] = 0;
1035 strcpy(s, " HOSTS: ");
1036 for (q = e->u.list; q; q = q->next) {
1037 if (s[0] && !s[9])
1038 strcat(s, q->extra);
1039 else if (!s[0])
1040 simple_sprintf(s, " %s", q->extra);
1041 else {
1042 if (strlen(s) + strlen(q->extra) + 2 > 65) {
1043 dprintf(idx, "%s\n", s);
1044 simple_sprintf(s, " %s", q->extra);
1045 } else {
1046 strcat(s, ", ");
1047 strcat(s, q->extra);
1048 }
1049 }
1050 }
1051 if (s[0])
1052 dprintf(idx, "%s\n", s);
1053 }
1054
1055 static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
1056 {
1057 Context;
1058 if (!buf || !egg_strcasecmp(buf, "none")) {
1059 ContextNote("SEGV with sharing bug track");
1060 /* When the bot crashes, it's in this part, not in the 'else' part */
1061 ContextNote(e ? "e is valid" : "e is NULL!");
1062 Assert(e); /* e cannot be null -- rtc */
1063 ContextNote((e->u.list) ? "(sharebug) e->u.list is valid" : "(sharebug) e->u.list is NULL!");
1064 list_type_kill(e->u.list);
1065 ContextNote("(sharebug[c1]) occurred in hosts_set - added 99/03/26");
1066 e->u.list = NULL;
1067 ContextNote("(sharebug[c2]) occurred in hosts_set - added 99/03/26");
1068 } else {
1069 char *host = buf, *p = strchr(host, ',');
1070 struct list_type **t;
1071
1072 ContextNote("SEGV with sharing bug track");
1073 /* Can't have ,'s in hostmasks */
1074 while (p) {
1075 *p = '?';
1076 p = strchr(host, ',');
1077 }
1078 /* fred1: check for redundant hostmasks with
1079 * controversial "superpenis" algorithm ;) */
1080 /* I'm surprised Raistlin hasn't gotten involved in this controversy */
1081 t = &(e->u.list);
1082 while (*t) {
1083 if (wild_match(host, (*t)->extra)) {
1084 struct list_type *u;
1085
1086 u = *t;
1087 *t = (*t)->next;
1088 if (u->extra)
1089 nfree(u->extra);
1090 nfree(u);
1091 } else
1092 t = &((*t)->next);
1093 }
1094 *t = user_malloc(sizeof(struct list_type));
1095
1096 (*t)->next = NULL;
1097 (*t)->extra = user_malloc(strlen(host) + 1);
1098 strcpy((*t)->extra, host);
1099 }
1100 ContextNote("please visit http://www.eggheads.org/bugs.html now.");
1101 return 1;
1102 }
1103
1104 static int hosts_tcl_get(Tcl_Interp *irp, struct userrec *u,
1105 struct user_entry *e, int argc, char **argv)
1106 {
1107 struct list_type *x;
1108
1109 BADARGS(3, 3, " handle HOSTS");
1110 for (x = e->u.list; x; x = x->next)
1111 Tcl_AppendElement(irp, x->extra);
1112 return TCL_OK;
1113 }
1114
1115 static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
1116 struct user_entry *e, int argc, char **argv)
1117 {
1118 BADARGS(3, 4, " handle HOSTS ?host?");
1119 if (argc == 4)
1120 addhost_by_handle(u->handle, argv[3]);
1121 else
1122 addhost_by_handle(u->handle, "none"); /* drummer */
1123 return TCL_OK;
1124 }
1125
1126 static int hosts_gotshare(struct userrec *u, struct user_entry *e,
1127 char *buf, int idx)
1128 {
1129 /* doh, try to be too clever and it bites your butt */
1130 return 0;
1131 }
1132
1133 struct user_entry_type USERENTRY_HOSTS =
1134 {
1135 0,
1136 hosts_gotshare,
1137 hosts_dupuser,
1138 hosts_null,
1139 hosts_null,
1140 hosts_write_userfile,
1141 hosts_kill,
1142 def_get,
1143 hosts_set,
1144 hosts_tcl_get,
1145 hosts_tcl_set,
1146 hosts_expmem,
1147 hosts_display,
1148 "HOSTS"
1149 };
1150
1151 int list_append(struct list_type **h, struct list_type *i)
1152 {
1153 for (; *h; h = &((*h)->next));
1154 *h = i;
1155 return 1;
1156 }
1157
1158 int list_delete(struct list_type **h, struct list_type *i)
1159 {
1160 for (; *h; h = &((*h)->next))
1161 if (*h == i) {
1162 *h = i->next;
1163 return 1;
1164 }
1165 return 0;
1166 }
1167
1168 int list_contains(struct list_type *h, struct list_type *i)
1169 {
1170 for (; h; h = h->next)
1171 if (h == i) {
1172 return 1;
1173 }
1174 return 0;
1175 }
1176
1177 int add_entry_type(struct user_entry_type *type)
1178 {
1179 struct userrec *u;
1180
1181 list_insert(&entry_type_list, type);
1182 for (u = userlist; u; u = u->next) {
1183 struct user_entry *e = find_user_entry(type, u);
1184
1185 if (e && e->name) {
1186 e->type = type;
1187 e->type->unpack(u, e);
1188 nfree(e->name);
1189 e->name = NULL;
1190 }
1191 }
1192 return 1;
1193 }
1194
1195 int del_entry_type(struct user_entry_type *type)
1196 {
1197 struct userrec *u;
1198
1199 for (u = userlist; u; u = u->next) {
1200 struct user_entry *e = find_user_entry(type, u);
1201
1202 if (e && !e->name) {
1203 e->type->pack(u, e);
1204 e->name = user_malloc(strlen(e->type->name) + 1);
1205 strcpy(e->name, e->type->name);
1206 e->type = NULL;
1207 }
1208 }
1209 return list_delete((struct list_type **) &entry_type_list,
1210 (struct list_type *) type);
1211 }
1212
1213 struct user_entry_type *find_entry_type(char *name)
1214 {
1215 struct user_entry_type *p;
1216
1217 for (p = entry_type_list; p; p = p->next) {
1218 if (!egg_strcasecmp(name, p->name))
1219 return p;
1220 }
1221 return NULL;
1222 }
1223
1224 struct user_entry *find_user_entry(struct user_entry_type *et,
1225 struct userrec *u)
1226 {
1227 struct user_entry **e, *t;
1228
1229 for (e = &(u->entries); *e; e = &((*e)->next)) {
1230 if (((*e)->type == et) ||
1231 ((*e)->name && !egg_strcasecmp((*e)->name, et->name))) {
1232 t = *e;
1233 *e = t->next;
1234 t->next = u->entries;
1235 u->entries = t;
1236 return t;
1237 }
1238 }
1239 return NULL;
1240 }
1241
1242 void *get_user(struct user_entry_type *et, struct userrec *u)
1243 {
1244 struct user_entry *e;
1245
1246 if (u && (e = find_user_entry(et, u)))
1247 return et->get(u, e);
1248 return 0;
1249 }
1250
1251 int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1252 {
1253 struct user_entry *e;
1254 int r;
1255
1256 if (!u || !et)
1257 return 0;
1258
1259 if (!(e = find_user_entry(et, u))) {
1260 e = user_malloc(sizeof(struct user_entry));
1261
1262 e->type = et;
1263 e->name = NULL;
1264 e->u.list = NULL;
1265 list_insert((&(u->entries)), e);
1266 }
1267 r = et->set(u, e, d);
1268 if (!e->u.list) {
1269 list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1270 nfree(e);
1271 }
1272 return r;
1273 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23