/[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.17 - (show annotations) (download) (as text)
Sun Dec 10 15:10:27 2000 UTC (18 years, 7 months ago) by guppy
Branch: MAIN
Changes since 1.16: +8 -80 lines
File MIME type: text/x-chdr
guppy: core_cleanup.diff ...

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23