/[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.35 - (show annotations) (download) (as text)
Sat Feb 15 05:04:58 2003 UTC (16 years, 5 months ago) by wcc
Branch: MAIN
Changes since 1.34: +4 -72 lines
File MIME type: text/x-chdr
* Removed share.mod (will be part of the new botnet module).
* More transfer removal.
* More botnet removal.
* Regenerated gettext stuff.
* More doc stuff.
* Removed eggdrop.conf (replaced by config.tcl for now).

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23