/[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.36 - (show annotations) (download) (as text)
Mon Feb 17 10:22:30 2003 UTC (16 years, 9 months ago) by stdarg
Branch: MAIN
Changes since 1.35: +0 -1 lines
File MIME type: text/x-chdr
* Moved irccmp to libeggdrop
* Initial support for 005 numeric

1 /*
2 * userent.c --
3 *
4 * user-entry handling, new stylem more versatile.
5 */
6
7 #include "main.h"
8 #include "users.h"
9 #include "logfile.h"
10 #include "modules.h" /* encrypt_pass */
11 #include "tcl.h" /* Tcl_Free */
12 #include "flags.h" /* USER_* */
13 #include "dccutil.h" /* dprintf_eggdrop */
14 #include "userrec.h" /* addhost_by_handle */
15 #include "match.h" /* wild_match */
16 #include "userent.h" /* prototypes */
17
18 extern struct userrec *userlist;
19 extern struct dcc_t *dcc;
20 extern Tcl_Interp *interp;
21 extern char whois_fields[];
22
23 static struct user_entry_type *entry_type_list;
24
25
26 void init_userent()
27 {
28 entry_type_list = 0;
29 add_entry_type(&USERENTRY_COMMENT);
30 add_entry_type(&USERENTRY_XTRA);
31 add_entry_type(&USERENTRY_INFO);
32 add_entry_type(&USERENTRY_LASTON);
33 add_entry_type(&USERENTRY_BOTADDR);
34 add_entry_type(&USERENTRY_PASS);
35 add_entry_type(&USERENTRY_HOSTS);
36 add_entry_type(&USERENTRY_BOTFL);
37 }
38
39 void list_type_kill(struct list_type *t)
40 {
41 struct list_type *u;
42
43 while (t) {
44 u = t->next;
45 if (t->extra)
46 free(t->extra);
47 free(t);
48 t = u;
49 }
50 }
51
52 int def_unpack(struct userrec *u, struct user_entry *e)
53 {
54 char *tmp;
55
56 tmp = e->u.list->extra;
57 e->u.list->extra = NULL;
58 list_type_kill(e->u.list);
59 e->u.string = tmp;
60 return 1;
61 }
62
63 int def_pack(struct userrec *u, struct user_entry *e)
64 {
65 char *tmp;
66
67 tmp = e->u.string;
68 e->u.list = malloc(sizeof(struct list_type));
69 e->u.list->next = NULL;
70 e->u.list->extra = tmp;
71 return 1;
72 }
73
74 int def_kill(struct user_entry *e)
75 {
76 free(e->u.string);
77 free(e);
78 return 1;
79 }
80
81 int def_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
82 {
83 if (fprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
84 return 0;
85 return 1;
86 }
87
88 void *def_get(struct userrec *u, struct user_entry *e)
89 {
90 return e->u.string;
91 }
92
93 int def_set(struct userrec *u, struct user_entry *e, void *buf)
94 {
95 char *string = (char *) buf;
96
97 if (string && !string[0])
98 string = NULL;
99 if (!string && !e->u.string)
100 return 1;
101 if (string) {
102 int l = strlen (string);
103 char *i;
104
105 if (l > 160)
106 l = 160;
107
108 e->u.string = realloc(e->u.string, l + 1);
109
110 strlcpy (e->u.string, string, l + 1);
111
112 for (i = e->u.string; *i; i++)
113 /* Allow bold, inverse, underline, color text here...
114 * But never add cr or lf!! --rtc
115 */
116 if ((unsigned int) *i < 32 && !strchr ("\002\003\026\037", *i))
117 *i = '?';
118 } else { /* string == NULL && e->u.string != NULL */
119 free_null(e->u.string);
120 }
121 return 1;
122 }
123
124 int def_gotshare(struct userrec *u, struct user_entry *e,
125 char *data, int idx)
126 {
127 return 0;
128 }
129
130 int def_tcl_get(Tcl_Interp * interp, struct userrec *u,
131 struct user_entry *e, int argc, char **argv)
132 {
133 Tcl_AppendResult(interp, e->u.string, NULL);
134 return TCL_OK;
135 }
136
137 int def_tcl_set(Tcl_Interp * irp, struct userrec *u,
138 struct user_entry *e, int argc, char **argv)
139 {
140 BADARGS(4, 4, " handle type setting");
141 e->type->set(u, e, argv[3]);
142 return TCL_OK;
143 }
144
145 void def_display(int idx, struct user_entry *e)
146 {
147 dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
148 }
149
150 int def_dupuser(struct userrec *new, struct userrec *old,
151 struct user_entry *e)
152 {
153 return set_user(e->type, new, e->u.string);
154 }
155
156 static void comment_display(int idx, struct user_entry *e)
157 {
158 if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
159 dprintf(idx, " COMMENT: %.70s\n", e->u.string);
160 }
161
162 struct user_entry_type USERENTRY_COMMENT =
163 {
164 0, /* always 0 ;) */
165 def_gotshare,
166 def_dupuser,
167 def_unpack,
168 def_pack,
169 def_write_userfile,
170 def_kill,
171 def_get,
172 def_set,
173 def_tcl_get,
174 def_tcl_set,
175 comment_display,
176 "COMMENT"
177 };
178
179 struct user_entry_type USERENTRY_INFO =
180 {
181 0, /* always 0 ;) */
182 def_gotshare,
183 def_dupuser,
184 def_unpack,
185 def_pack,
186 def_write_userfile,
187 def_kill,
188 def_get,
189 def_set,
190 def_tcl_get,
191 def_tcl_set,
192 def_display,
193 "INFO"
194 };
195
196 int pass_set(struct userrec *u, struct user_entry *e, void *buf)
197 {
198 char new[32];
199 register char *pass = buf;
200
201 if (e->u.extra)
202 free(e->u.extra);
203 if (!pass || !pass[0] || (pass[0] == '-'))
204 e->u.extra = NULL;
205 else {
206 unsigned char *p = (unsigned char *) pass;
207
208 if (strlen(pass) > 15)
209 pass[15] = 0;
210 while (*p) {
211 if ((*p <= 32) || (*p == 127))
212 *p = '?';
213 p++;
214 }
215 if ((u->flags & USER_BOT) || (pass[0] == '+'))
216 strcpy(new, pass);
217 else
218 encrypt_pass(pass, new);
219 e->u.extra = strdup(new);
220 }
221 return 1;
222 }
223
224 static int pass_tcl_set(Tcl_Interp * irp, struct userrec *u,
225 struct user_entry *e, int argc, char **argv)
226 {
227 BADARGS(3, 4, " handle PASS ?newpass?");
228 pass_set(u, e, argv[3]);
229 return TCL_OK;
230 }
231
232 struct user_entry_type USERENTRY_PASS =
233 {
234 0,
235 def_gotshare,
236 0,
237 def_unpack,
238 def_pack,
239 def_write_userfile,
240 def_kill,
241 def_get,
242 pass_set,
243 def_tcl_get,
244 pass_tcl_set,
245 0,
246 "PASS"
247 };
248
249 static int laston_unpack(struct userrec *u, struct user_entry *e)
250 {
251 char *par, *arg;
252 struct laston_info *li;
253
254 par = e->u.list->extra;
255 arg = newsplit (&par);
256 if (!par[0])
257 par = "???";
258 li = malloc(sizeof(struct laston_info));
259 li->lastonplace = malloc(strlen(par) + 1);
260 li->laston = atoi(arg);
261 strcpy(li->lastonplace, par);
262 list_type_kill(e->u.list);
263 e->u.extra = li;
264 return 1;
265 }
266
267 static int laston_pack(struct userrec *u, struct user_entry *e)
268 {
269 char work[1024];
270 struct laston_info *li;
271
272 li = (struct laston_info *) e->u.extra;
273 sprintf(work, "%lu %s", li->laston, li->lastonplace);
274 e->u.list = malloc(sizeof(struct list_type));
275 e->u.list->next = NULL;
276 e->u.list->extra = strdup(work);
277 free(li->lastonplace);
278 free(li);
279 return 1;
280 }
281
282 static int laston_write_userfile(FILE * f,
283 struct userrec *u,
284 struct user_entry *e)
285 {
286 struct laston_info *li = (struct laston_info *) e->u.extra;
287
288 if (fprintf(f, "--LASTON %lu %s\n", li->laston,
289 li->lastonplace ? li->lastonplace : "") == EOF)
290 return 0;
291 return 1;
292 }
293
294 static int laston_kill(struct user_entry *e)
295 {
296 if (((struct laston_info *) (e->u.extra))->lastonplace)
297 free(((struct laston_info *) (e->u.extra))->lastonplace);
298 free(e->u.extra);
299 free(e);
300 return 1;
301 }
302
303 static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
304 {
305 struct laston_info *li = (struct laston_info *) e->u.extra;
306
307 if (li != buf) {
308 if (li) {
309 free(li->lastonplace);
310 free(li);
311 }
312
313 li = e->u.extra = buf;
314 }
315 return 1;
316 }
317
318 static int laston_tcl_get(Tcl_Interp * irp, struct userrec *u,
319 struct user_entry *e, int argc, char **argv)
320 {
321 struct laston_info *li = (struct laston_info *) e->u.extra;
322 char number[20];
323 struct chanuserrec *cr;
324
325 BADARGS(3, 4, " handle LASTON ?channel?");
326 if (argc == 4) {
327 for (cr = u->chanrec; cr; cr = cr->next)
328 if (!irccmp(cr->channel, argv[3])) {
329 Tcl_AppendResult(irp, int_to_base10(cr->laston), NULL);
330 break;
331 }
332 if (!cr)
333 Tcl_AppendResult(irp, "0", NULL);
334 } else {
335 sprintf(number, "%lu ", li->laston);
336 Tcl_AppendResult(irp, number, li->lastonplace, NULL);
337 }
338 return TCL_OK;
339 }
340
341 static int laston_tcl_set(Tcl_Interp * irp, struct userrec *u,
342 struct user_entry *e, int argc, char **argv)
343 {
344 struct laston_info *li;
345 struct chanuserrec *cr;
346
347 BADARGS(4, 5, " handle LASTON time ?place?");
348
349 if ((argc == 5) && argv[4][0] && strchr(CHANMETA, argv[4][0])) {
350 /* Search for matching channel */
351 for (cr = u->chanrec; cr; cr = cr->next)
352 if (!irccmp(cr->channel, argv[4])) {
353 cr->laston = atoi(argv[3]);
354 break;
355 }
356 }
357 /* Save globally */
358 li = malloc(sizeof(struct laston_info));
359
360 if (argc == 5)
361 li->lastonplace = strdup(argv[4]);
362 else
363 li->lastonplace = calloc(1, 1);
364
365 li->laston = atoi(argv[3]);
366 set_user(&USERENTRY_LASTON, u, li);
367 return TCL_OK;
368 }
369
370 static int laston_dupuser(struct userrec *new, struct userrec *old,
371 struct user_entry *e)
372 {
373 struct laston_info *li = e->u.extra, *li2;
374
375 if (li) {
376 li2 = malloc(sizeof(struct laston_info));
377
378 li2->laston = li->laston;
379 li2->lastonplace = strdup(li->lastonplace);
380 return set_user(&USERENTRY_LASTON, new, li2);
381 }
382 return 0;
383 }
384
385 struct user_entry_type USERENTRY_LASTON =
386 {
387 0, /* always 0 ;) */
388 0,
389 laston_dupuser,
390 laston_unpack,
391 laston_pack,
392 laston_write_userfile,
393 laston_kill,
394 def_get,
395 laston_set,
396 laston_tcl_get,
397 laston_tcl_set,
398 0,
399 "LASTON"
400 };
401
402 static int botaddr_unpack(struct userrec *u, struct user_entry *e)
403 {
404 char *p = NULL, *q;
405 struct bot_addr *bi;
406
407 bi = calloc(1, sizeof(struct bot_addr));
408 q = (e->u.list->extra);
409 p = strdup(q);
410 if (!(q = strchr_unescape(p, ':', '\\')))
411 bi->address = strdup(p);
412 else {
413 bi->address = strdup(p);
414 bi->telnet_port = atoi(q);
415 if ((q = strchr(q, '/')))
416 bi->relay_port = atoi(q + 1);
417 }
418 free(p);
419 if (!bi->telnet_port)
420 bi->telnet_port = 3333;
421 if (!bi->relay_port)
422 bi->relay_port = bi->telnet_port;
423 list_type_kill(e->u.list);
424 e->u.extra = bi;
425 return 1;
426 }
427
428 static int botaddr_pack(struct userrec *u, struct user_entry *e)
429 {
430 char work[1024];
431 struct bot_addr *bi;
432 char *tmp;
433
434 bi = (struct bot_addr *) e->u.extra;
435 simple_sprintf(work, "%s:%u/%u",
436 (tmp = str_escape(bi->address, ':', '\\')),
437 bi->telnet_port, bi->relay_port);
438 free(tmp);
439 e->u.list = malloc(sizeof(struct list_type));
440 e->u.list->next = NULL;
441 e->u.list->extra = strdup(work);
442 free(bi->address);
443 free(bi);
444 return 1;
445 }
446
447 static int botaddr_kill(struct user_entry *e)
448 {
449 free(((struct bot_addr *) (e->u.extra))->address);
450 free(e->u.extra);
451 free(e);
452 return 1;
453 }
454
455 static int botaddr_write_userfile(FILE *f, struct userrec *u,
456 struct user_entry *e)
457 {
458 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
459 register char *tmp;
460 register int res;
461
462 res = (fprintf(f, "--%s %s:%u/%u\n", e->type->name,
463 (tmp = str_escape(bi->address, ':', '\\')),
464 bi->telnet_port, bi->relay_port) != EOF);
465 free(tmp);
466 return res;
467 }
468
469 static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
470 {
471 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
472
473 if (!bi && !buf)
474 return 1;
475 if (bi != buf) {
476 if (bi) {
477 free(bi->address);
478 free(bi);
479 }
480 bi = e->u.extra = buf;
481 }
482 return 1;
483 }
484
485 static int botaddr_tcl_get(Tcl_Interp *interp, struct userrec *u,
486 struct user_entry *e, int argc, char **argv)
487 {
488 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
489 char number[20];
490
491 sprintf(number, " %d", bi->telnet_port);
492 Tcl_AppendResult(interp, bi->address, number, NULL);
493 sprintf(number, " %d", bi->relay_port);
494 Tcl_AppendResult(interp, number, NULL);
495 return TCL_OK;
496 }
497
498 static int botaddr_tcl_set(Tcl_Interp *irp, struct userrec *u,
499 struct user_entry *e, int argc, char **argv)
500 {
501 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
502
503 BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
504 if (u->flags & USER_BOT) {
505 /* Silently ignore for users */
506 if (!bi) {
507 bi = calloc(1, sizeof(struct bot_addr));
508 } else {
509 free(bi->address);
510 }
511 bi->address = strdup(argv[3]);
512 if (argc > 4)
513 bi->telnet_port = atoi(argv[4]);
514 if (argc > 5)
515 bi->relay_port = atoi(argv[5]);
516 if (!bi->telnet_port)
517 bi->telnet_port = 3333;
518 if (!bi->relay_port)
519 bi->relay_port = bi->telnet_port;
520 botaddr_set(u, e, bi);
521 }
522 return TCL_OK;
523 }
524
525 static void botaddr_display(int idx, struct user_entry *e)
526 {
527 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
528
529 dprintf(idx, " ADDRESS: %.70s\n", bi->address);
530 dprintf(idx, " users: %d, bots: %d\n", bi->relay_port, bi->telnet_port);
531 }
532
533 static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
534 char *buf, int idx)
535 {
536 return 0;
537 }
538
539 static int botaddr_dupuser(struct userrec *new, struct userrec *old,
540 struct user_entry *e)
541 {
542 if (old->flags & USER_BOT) {
543 struct bot_addr *bi = e->u.extra, *bi2;
544
545 if (bi) {
546 bi2 = malloc(sizeof(struct bot_addr));
547
548 bi2->telnet_port = bi->telnet_port;
549 bi2->relay_port = bi->relay_port;
550 bi2->address = strdup(bi->address);
551 return set_user(&USERENTRY_BOTADDR, new, bi2);
552 }
553 }
554 return 0;
555 }
556
557 struct user_entry_type USERENTRY_BOTADDR =
558 {
559 0, /* always 0 ;) */
560 botaddr_gotshare,
561 botaddr_dupuser,
562 botaddr_unpack,
563 botaddr_pack,
564 botaddr_write_userfile,
565 botaddr_kill,
566 def_get,
567 botaddr_set,
568 botaddr_tcl_get,
569 botaddr_tcl_set,
570 botaddr_display,
571 "BOTADDR"
572 };
573
574 int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
575 {
576 struct xtra_key *curr, *old = NULL, *new = buf;
577
578 for (curr = e->u.extra; curr; curr = curr->next) {
579 if (curr->key && !strcasecmp(curr->key, new->key)) {
580 old = curr;
581 break;
582 }
583 }
584 if (!old && (!new->data || !new->data[0])) {
585 /* Delete non-existant entry -- doh ++rtc */
586 free(new->key);
587 if (new->data)
588 free(new->data);
589 free(new);
590 return TCL_OK;
591 }
592
593 if ((old && old != new) || !new->data || !new->data[0]) {
594 list_delete((struct list_type **) (&e->u.extra),
595 (struct list_type *) old);
596 free(old->key);
597 free(old->data);
598 free(old);
599 }
600 if (old != new && new->data) {
601 if (new->data[0])
602 list_insert((&e->u.extra), new) /* do not add a ';' here */
603 } else {
604 if (new->data)
605 free(new->data);
606 free(new->key);
607 free(new);
608 }
609 return TCL_OK;
610 }
611
612 static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
613 struct user_entry *e, int argc, char **argv)
614 {
615 struct xtra_key *xk;
616 int l;
617
618 BADARGS(4, 5, " handle type key ?value?");
619 xk = calloc(1, sizeof(struct xtra_key));
620 l = strlen(argv[3]);
621 if (l > 500)
622 l = 500;
623 xk->key = malloc(l + 1);
624 strlcpy(xk->key, argv[3], l + 1);
625
626 if (argc == 5) {
627 int k = strlen(argv[4]);
628
629 if (k > 500 - l)
630 k = 500 - l;
631 xk->data = malloc(k + 1);
632 strlcpy(xk->data, argv[4], k + 1);
633 }
634 xtra_set(u, e, xk);
635 return TCL_OK;
636 }
637
638 int xtra_unpack(struct userrec *u, struct user_entry *e)
639 {
640 struct list_type *curr, *head;
641 struct xtra_key *t;
642 char *key, *data;
643
644 head = curr = e->u.list;
645 e->u.extra = NULL;
646 while (curr) {
647 t = malloc(sizeof(struct xtra_key));
648
649 data = curr->extra;
650 key = newsplit(&data);
651 if (data[0]) {
652 t->key = strdup(key);
653 t->data = strdup(data);
654 list_insert((&e->u.extra), t);
655 }
656 curr = curr->next;
657 }
658 list_type_kill(head);
659 return 1;
660 }
661
662 static int xtra_pack(struct userrec *u, struct user_entry *e)
663 {
664 struct list_type *t;
665 struct xtra_key *curr, *next;
666
667 curr = e->u.extra;
668 e->u.list = NULL;
669 while (curr) {
670 t = malloc(sizeof(struct list_type));
671 t->extra = malloc(strlen(curr->key) + strlen(curr->data) + 4);
672 sprintf(t->extra, "%s %s", curr->key, curr->data);
673 list_insert((&e->u.list), t);
674 next = curr->next;
675 free(curr->key);
676 free(curr->data);
677 free(curr);
678 curr = next;
679 }
680 return 1;
681 }
682
683 static void xtra_display(int idx, struct user_entry *e)
684 {
685 int code, lc, j;
686 struct xtra_key *xk;
687 char **list;
688
689 code = Tcl_SplitList(interp, whois_fields, &lc, &list);
690 if (code == TCL_ERROR)
691 return;
692 /* Scan thru xtra field, searching for matches */
693 for (xk = e->u.extra; xk; xk = xk->next) {
694 /* Ok, it's a valid xtra field entry */
695 for (j = 0; j < lc; j++) {
696 if (!strcasecmp(list[j], xk->key))
697 dprintf(idx, " %s: %s\n", xk->key, xk->data);
698 }
699 }
700 Tcl_Free((char *) list);
701 }
702
703 static int xtra_gotshare(struct userrec *u, struct user_entry *e,
704 char *buf, int idx)
705 {
706 return 0;
707 }
708
709 static int xtra_dupuser(struct userrec *new, struct userrec *old,
710 struct user_entry *e)
711 {
712 struct xtra_key *x1, *x2;
713
714 for (x1 = e->u.extra; x1; x1 = x1->next) {
715 x2 = malloc(sizeof(struct xtra_key));
716
717 x2->key = strdup(x1->key);
718 x2->data = strdup(x1->data);
719 set_user(&USERENTRY_XTRA, new, x2);
720 }
721 return 1;
722 }
723
724 static int xtra_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
725 {
726 struct xtra_key *x;
727
728 for (x = e->u.extra; x; x = x->next)
729 if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
730 return 0;
731 return 1;
732 }
733
734 int xtra_kill(struct user_entry *e)
735 {
736 struct xtra_key *x, *y;
737
738 for (x = e->u.extra; x; x = y) {
739 y = x->next;
740 free(x->key);
741 free(x->data);
742 free(x);
743 }
744 free(e);
745 return 1;
746 }
747
748 static int xtra_tcl_get(Tcl_Interp *irp, struct userrec *u,
749 struct user_entry *e, int argc, char **argv)
750 {
751 struct xtra_key *x;
752
753 BADARGS(3, 4, " handle XTRA ?key?");
754 if (argc == 4) {
755 for (x = e->u.extra; x; x = x->next)
756 if (!strcasecmp(argv[3], x->key)) {
757 Tcl_AppendResult(irp, x->data, NULL);
758 return TCL_OK;
759 }
760 return TCL_OK;
761 }
762 for (x = e->u.extra; x; x = x->next) {
763 char *p, *list[2];
764
765 list[0] = x->key;
766 list[1] = x->data;
767 p = Tcl_Merge(2, list);
768 Tcl_AppendElement(irp, p);
769 Tcl_Free((char *) p);
770 }
771 return TCL_OK;
772 }
773
774 struct user_entry_type USERENTRY_XTRA =
775 {
776 0,
777 xtra_gotshare,
778 xtra_dupuser,
779 xtra_unpack,
780 xtra_pack,
781 xtra_write_userfile,
782 xtra_kill,
783 def_get,
784 xtra_set,
785 xtra_tcl_get,
786 xtra_tcl_set,
787 xtra_display,
788 "XTRA"
789 };
790
791 static int hosts_dupuser(struct userrec *new, struct userrec *old,
792 struct user_entry *e)
793 {
794 struct list_type *h;
795
796 for (h = e->u.extra; h; h = h->next)
797 set_user(&USERENTRY_HOSTS, new, h->extra);
798 return 1;
799 }
800
801 static int hosts_null(struct userrec *u, struct user_entry *e)
802 {
803 return 1;
804 }
805
806 static int hosts_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
807 {
808 struct list_type *h;
809
810 for (h = e->u.extra; h; h = h->next)
811 if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
812 return 0;
813 return 1;
814 }
815
816 static int hosts_kill(struct user_entry *e)
817 {
818 list_type_kill(e->u.list);
819 free(e);
820 return 1;
821 }
822
823 static void hosts_display(int idx, struct user_entry *e)
824 {
825 char s[1024];
826 struct list_type *q;
827
828 s[0] = 0;
829 strcpy(s, " HOSTS: ");
830 for (q = e->u.list; q; q = q->next) {
831 if (s[0] && !s[9])
832 strcat(s, q->extra);
833 else if (!s[0])
834 sprintf(s, " %s", q->extra);
835 else {
836 if (strlen(s) + strlen(q->extra) + 2 > 65) {
837 dprintf(idx, "%s\n", s);
838 sprintf(s, " %s", q->extra);
839 } else {
840 strcat(s, ", ");
841 strcat(s, q->extra);
842 }
843 }
844 }
845 if (s[0])
846 dprintf(idx, "%s\n", s);
847 }
848
849 static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
850 {
851 if (!buf || !strcasecmp(buf, "none")) {
852 /* When the bot crashes, it's in this part, not in the 'else' part */
853 list_type_kill(e->u.list);
854 e->u.list = NULL;
855 } else {
856 char *host = buf, *p = strchr(host, ',');
857 struct list_type **t;
858
859 /* Can't have ,'s in hostmasks */
860 while (p) {
861 *p = '?';
862 p = strchr(host, ',');
863 }
864 /* fred1: check for redundant hostmasks with
865 * controversial "superpenis" algorithm ;) */
866 /* I'm surprised Raistlin hasn't gotten involved in this controversy */
867 t = &(e->u.list);
868 while (*t) {
869 if (wild_match(host, (*t)->extra)) {
870 struct list_type *u;
871
872 u = *t;
873 *t = (*t)->next;
874 if (u->extra)
875 free(u->extra);
876 free(u);
877 } else
878 t = &((*t)->next);
879 }
880 *t = malloc(sizeof(struct list_type));
881
882 (*t)->next = NULL;
883 (*t)->extra = strdup(host);
884 }
885 return 1;
886 }
887
888 static int hosts_tcl_get(Tcl_Interp *irp, struct userrec *u,
889 struct user_entry *e, int argc, char **argv)
890 {
891 struct list_type *x;
892
893 BADARGS(3, 3, " handle HOSTS");
894 for (x = e->u.list; x; x = x->next)
895 Tcl_AppendElement(irp, x->extra);
896 return TCL_OK;
897 }
898
899 static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
900 struct user_entry *e, int argc, char **argv)
901 {
902 BADARGS(3, 4, " handle HOSTS ?host?");
903 if (argc == 4)
904 addhost_by_handle(u->handle, argv[3]);
905 else
906 addhost_by_handle(u->handle, "none"); /* drummer */
907 return TCL_OK;
908 }
909
910 static int hosts_gotshare(struct userrec *u, struct user_entry *e,
911 char *buf, int idx)
912 {
913 return 0;
914 }
915
916 struct user_entry_type USERENTRY_HOSTS =
917 {
918 0,
919 hosts_gotshare,
920 hosts_dupuser,
921 hosts_null,
922 hosts_null,
923 hosts_write_userfile,
924 hosts_kill,
925 def_get,
926 hosts_set,
927 hosts_tcl_get,
928 hosts_tcl_set,
929 hosts_display,
930 "HOSTS"
931 };
932
933 int list_append(struct list_type **h, struct list_type *i)
934 {
935 for (; *h; h = &((*h)->next));
936 *h = i;
937 return 1;
938 }
939
940 int list_delete(struct list_type **h, struct list_type *i)
941 {
942 for (; *h; h = &((*h)->next))
943 if (*h == i) {
944 *h = i->next;
945 return 1;
946 }
947 return 0;
948 }
949
950 int list_contains(struct list_type *h, struct list_type *i)
951 {
952 for (; h; h = h->next)
953 if (h == i) {
954 return 1;
955 }
956 return 0;
957 }
958
959 int add_entry_type(struct user_entry_type *type)
960 {
961 struct userrec *u;
962
963 list_insert(&entry_type_list, type);
964 for (u = userlist; u; u = u->next) {
965 struct user_entry *e = find_user_entry(type, u);
966
967 if (e && e->name) {
968 e->type = type;
969 e->type->unpack(u, e);
970 free_null(e->name);
971 }
972 }
973 return 1;
974 }
975
976 int del_entry_type(struct user_entry_type *type)
977 {
978 struct userrec *u;
979
980 for (u = userlist; u; u = u->next) {
981 struct user_entry *e = find_user_entry(type, u);
982
983 if (e && !e->name) {
984 e->type->pack(u, e);
985 e->name = strdup(e->type->name);
986 e->type = NULL;
987 }
988 }
989 return list_delete((struct list_type **) &entry_type_list,
990 (struct list_type *) type);
991 }
992
993 struct user_entry_type *find_entry_type(char *name)
994 {
995 struct user_entry_type *p;
996
997 for (p = entry_type_list; p; p = p->next) {
998 if (!strcasecmp(name, p->name))
999 return p;
1000 }
1001 return NULL;
1002 }
1003
1004 struct user_entry *find_user_entry(struct user_entry_type *et,
1005 struct userrec *u)
1006 {
1007 struct user_entry **e, *t;
1008
1009 for (e = &(u->entries); *e; e = &((*e)->next)) {
1010 if (((*e)->type == et) ||
1011 ((*e)->name && !strcasecmp((*e)->name, et->name))) {
1012 t = *e;
1013 *e = t->next;
1014 t->next = u->entries;
1015 u->entries = t;
1016 return t;
1017 }
1018 }
1019 return NULL;
1020 }
1021
1022 void *get_user(struct user_entry_type *et, struct userrec *u)
1023 {
1024 struct user_entry *e;
1025
1026 if (u && (e = find_user_entry(et, u)))
1027 return et->get(u, e);
1028 return 0;
1029 }
1030
1031 int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1032 {
1033 struct user_entry *e;
1034 int r;
1035
1036 if (!u || !et)
1037 return 0;
1038
1039 if (!(e = find_user_entry(et, u))) {
1040 e = malloc(sizeof(struct user_entry));
1041
1042 e->type = et;
1043 e->name = NULL;
1044 e->u.list = NULL;
1045 list_insert((&(u->entries)), e);
1046 }
1047 r = et->set(u, e, d);
1048 if (!e->u.list) {
1049 list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1050 free(e);
1051 }
1052 return r;
1053 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23