/[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.11 - (show annotations) (download) (as text)
Mon Jan 17 22:36:07 2000 UTC (19 years, 6 months ago) by fabian
Branch: MAIN
Changes since 1.10: +2 -2 lines
File MIME type: text/x-chdr
Eule's copyright patch, updated by him for 1.5

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23