/[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.25 - (show annotations) (download) (as text)
Fri Oct 19 01:55:05 2001 UTC (17 years, 10 months ago) by tothwolf
Branch: MAIN
Changes since 1.24: +7 -7 lines
File MIME type: text/x-chdr
* removed obsolete EGG_CHECK_FUNC_VSPRINTF autoconf macro
* removed obsolete EGG_HEADER_STDC autoconf macro
* added EGG_C_LONG_LONG autoconf macro
* added EGG_FUNC_C99_VSNPRINTF autoconf macro
* added EGG_REPLACE_SNPRINTF autoconf macro
* added EGG_TYPE_32BIT autoconf macro

* removed unused dlfcn.h header check from configure.ac
* removed AC_CHECK_SIZEOF long and int from configure.ac
* added many required autoconf macros to configure.ac
* added AC_REPLACE_FUNCS to configure.ac for compat functions
* many configure.ac cleanups

* updated compat/snprintf.c with latest version from Samba
* added code to link libm with compat library for snprintf.c
* added support for LIBOBJS to compat/Makefile.am
* added memset back to compat
* added memcpy back to compat
* many compat cleanups

* renamed egg_strcasecmp() to strcasecmp()
* renamed egg_strncasecmp() to strncasecmp()
* renamed egg_snprintf() to snprintf()
* renamed egg_vsnprintf() to vsnprintf()
* renamed egg_strftime() to strftime()
* renamed egg_inet_aton() to inet_aton()
* renamed egg_inet_ntop() to inet_ntop()
* renamed egg_inet_pton() to inet_pton()

* exported strftime() for modules
* exported inet_ntop() for modules
* exported inet_pton() for modules
* exported vasprintf() for modules
* exported asprintf() for modules

* renamed u_32bit_t typedef to u_32int_t
* extended stat.h to support standard bits and checks

* major function changes:
  + egg_strcasecmp -> strcasecmp
  + egg_strncasecmp -> strncasecmp
  + egg_snprintf -> snprintf
  + egg_vsnprintf -> vsnprintf
  + egg_strftime -> strftime
  + egg_inet_aton -> inet_aton
  + egg_inet_ntop -> inet_ntop
  + egg_inet_pton -> inet_pton

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23