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

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

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


Revision 1.22 - (show annotations) (download) (as text)
Wed Feb 2 11:45:27 2000 UTC (19 years, 9 months ago) by per
Branch: MAIN
CVS Tags: eggdrop104030RC2, eggdrop10403RC1, eggdrop10404, eggdrop10403, HEAD
Changes since 1.21: +4 -3 lines
File MIME type: text/x-chdr
def_set.patch by dw

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23