/[cvs]/eggdrop1.9/src/userrec.c
ViewVC logotype

Contents of /eggdrop1.9/src/userrec.c

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


Revision 1.8 - (show annotations) (download) (as text)
Tue Dec 21 17:35:10 1999 UTC (20 years, 2 months ago) by fabian
Branch: MAIN
Changes since 1.7: +22 -9 lines
File MIME type: text/x-chdr
Tothwolf's id-header

1 /*
2 * userrec.c -- handles:
3 * add_q() del_q() str2flags() flags2str() str2chflags() chflags2str()
4 * a bunch of functions to find and change user records
5 * change and check user (and channel-specific) flags
6 *
7 * dprintf'ized, 10nov1995
8 *
9 * $Id$
10 */
11 /*
12 * Copyright (C) 1997 Robey Pointer
13 * Copyright (C) 1999 Eggheads
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 */
29
30 #include "main.h"
31 #include <sys/stat.h>
32 #include "users.h"
33 #include "chan.h"
34 #include "modules.h"
35 #include "tandem.h"
36
37 extern struct dcc_t *dcc;
38 extern int dcc_total;
39 extern char userfile[];
40 extern int share_greet;
41 extern struct chanset_t *chanset;
42 extern char ver[];
43 extern char botnetnick[];
44 extern time_t now;
45 extern int default_flags, default_uflags;
46 extern int quiet_save;
47
48 int noshare = 1; /* don't send out to sharebots */
49 int sort_users = 0; /* sort the userlist when saving */
50 struct userrec *userlist = NULL; /* user records are stored here */
51 struct userrec *lastuser = NULL; /* last accessed user record */
52 maskrec *global_bans = NULL,
53 *global_exempts = NULL,
54 *global_invites = NULL;
55 struct igrec *global_ign = NULL;
56 int cache_hit = 0, cache_miss = 0; /* temporary cache accounting */
57
58 #ifdef DEBUG_MEM
59 void *_user_malloc(int size, char *file, int line)
60 {
61 char x[1024];
62
63 simple_sprintf(x, "userrec.c:%s", file);
64 return n_malloc(size, x, line);
65 }
66
67 void *_user_realloc(void *ptr, int size, char *file, int line)
68 {
69 char x[1024];
70
71 simple_sprintf(x, "userrec.c:%s", file);
72 return n_realloc(ptr, size, x, line);
73 }
74 #else
75 void *_user_malloc(int size, char *file, int line)
76 {
77 return nmalloc(size);
78 }
79
80 void *_user_realloc(void *ptr, int size, char *file, int line)
81 {
82 return nrealloc(ptr, size);
83 }
84 #endif
85
86 inline int expmem_mask(struct maskrec *m)
87 {
88 int result = 0;
89
90 while (m) {
91 result += sizeof(struct maskrec);
92 result += strlen(m->mask) + 1;
93 if (m->user)
94 result += strlen(m->user) + 1;
95 if (m->desc)
96 result += strlen(m->desc) + 1;
97
98 m = m->next;
99 }
100
101 return result;
102 }
103
104 /* memory we should be using */
105 int expmem_users()
106 {
107 int tot;
108 struct userrec *u;
109 struct chanuserrec *ch;
110 struct chanset_t *chan;
111 struct user_entry *ue;
112 struct igrec *i;
113
114 Context;
115 tot = 0;
116 u = userlist;
117 while (u != NULL) {
118 ch = u->chanrec;
119 while (ch) {
120 tot += sizeof(struct chanuserrec);
121
122 if (ch->info != NULL)
123 tot += strlen(ch->info) + 1;
124 ch = ch->next;
125 }
126 tot += sizeof(struct userrec);
127
128 for (ue = u->entries; ue; ue = ue->next) {
129 tot += sizeof(struct user_entry);
130
131 if (ue->name) {
132 tot += strlen(ue->name) + 1;
133 tot += list_type_expmem(ue->u.list);
134 } else {
135 tot += ue->type->expmem(ue);
136 }
137 }
138 u = u->next;
139 }
140 /* account for each channel's masks */
141 for (chan = chanset; chan; chan = chan->next) {
142
143 /* account for each channel's ban-list user */
144 tot += expmem_mask(chan->bans);
145
146 /* account for each channel's exempt-list user */
147 tot += expmem_mask(chan->exempts);
148
149 /* account for each channel's invite-list user */
150 tot += expmem_mask(chan->invites);
151 }
152
153 tot += expmem_mask(global_bans);
154 tot += expmem_mask(global_exempts);
155 tot += expmem_mask(global_invites);
156
157 for (i = global_ign; i; i = i->next) {
158 tot += sizeof(struct igrec);
159
160 tot += strlen(i->igmask) + 1;
161 if (i->user)
162 tot += strlen(i->user) + 1;
163 if (i->msg)
164 tot += strlen(i->msg) + 1;
165 }
166 return tot;
167 }
168
169 int count_users(struct userrec *bu)
170 {
171 int tot = 0;
172 struct userrec *u = bu;
173
174 while (u != NULL) {
175 tot++;
176 u = u->next;
177 }
178 return tot;
179 }
180
181 struct userrec *check_dcclist_hand(char *handle)
182 {
183 int i;
184
185 for (i = 0; i < dcc_total; i++)
186 if (!strcasecmp(dcc[i].nick, handle))
187 return dcc[i].user;
188 return NULL;
189 }
190
191 struct userrec *get_user_by_handle(struct userrec *bu, char *handle)
192 {
193 struct userrec *u = bu, *ret;
194
195 if (!handle)
196 return NULL;
197 rmspace(handle);
198 if (!handle[0] || (handle[0] == '*'))
199 return NULL;
200 if (bu == userlist) {
201 if (lastuser && !strcasecmp(lastuser->handle, handle)) {
202 cache_hit++;
203 return lastuser;
204 }
205 ret = check_dcclist_hand(handle);
206 if (ret) {
207 cache_hit++;
208 return ret;
209 }
210 ret = check_chanlist_hand(handle);
211 if (ret) {
212 cache_hit++;
213 return ret;
214 }
215 cache_miss++;
216 }
217 while (u) {
218 if (!strcasecmp(u->handle, handle)) {
219 if (bu == userlist)
220 lastuser = u;
221 return u;
222 }
223 u = u->next;
224 }
225 return NULL;
226 }
227
228 /* fix capitalization, etc */
229 void correct_handle(char *handle)
230 {
231 struct userrec *u;
232
233 u = get_user_by_handle(userlist, handle);
234 if (u == NULL)
235 return;
236 strcpy(handle, u->handle);
237 }
238
239 /* This will be usefull in a lot of places, much more code re-use so we
240 * endup with a smaller executable bot. <cybah>
241 */
242 void clear_masks(maskrec *m)
243 {
244 maskrec *temp = NULL;
245
246 while (m) {
247 temp = m->next;
248
249 if (m->mask)
250 nfree(m->mask);
251 if (m->user)
252 nfree(m->user);
253 if (m->desc)
254 nfree(m->desc);
255
256 nfree(m);
257 m = temp;
258 }
259 }
260
261 void clear_userlist(struct userrec *bu)
262 {
263 struct userrec *u = bu, *v;
264 int i;
265
266 Context;
267 while (u != NULL) {
268 v = u->next;
269 freeuser(u);
270 u = v;
271 }
272 if (userlist == bu) {
273 struct chanset_t *cst;
274
275 for (i = 0; i < dcc_total; i++)
276 dcc[i].user = NULL;
277 clear_chanlist();
278 lastuser = NULL;
279
280 while (global_ign)
281 delignore(global_ign->igmask);
282
283 clear_masks(global_bans);
284 clear_masks(global_exempts);
285 clear_masks(global_invites);
286 global_exempts = global_invites = global_bans = NULL;
287
288 for (cst = chanset; cst; cst = cst->next) {
289 clear_masks(cst->bans);
290 clear_masks(cst->exempts);
291 clear_masks(cst->invites);
292
293 cst->bans = cst->exempts = cst->invites = NULL;
294 }
295 }
296 /* remember to set your userlist to NULL after calling this */
297 Context;
298 }
299
300 /* find CLOSEST host match */
301 /* (if "*!*@*" and "*!*@*clemson.edu" both match, use the latter!) */
302 /* 26feb: CHECK THE CHANLIST FIRST to possibly avoid needless search */
303 struct userrec *get_user_by_host(char *host)
304 {
305 struct userrec *u = userlist, *ret;
306 struct list_type *q;
307 int cnt, i;
308
309 if (host == NULL)
310 return NULL;
311 rmspace(host);
312 if (!host[0])
313 return NULL;
314 ret = check_chanlist(host);
315 cnt = 0;
316 if (ret != NULL) {
317 cache_hit++;
318 return ret;
319 }
320 cache_miss++;
321 while (u != NULL) {
322 q = get_user(&USERENTRY_HOSTS, u);
323 while (q != NULL) {
324 i = wild_match(q->extra, host);
325 if (i > cnt) {
326 ret = u;
327 cnt = i;
328 }
329 q = q->next;
330 }
331 u = u->next;
332 }
333 if (ret != NULL) {
334 lastuser = ret;
335 set_chanlist(host, ret);
336 }
337 return ret;
338 }
339
340 struct userrec *get_user_by_equal_host(char *host)
341 {
342 struct userrec *u = userlist;
343 struct list_type *q;
344
345 while (u != NULL) {
346 q = get_user(&USERENTRY_HOSTS, u);
347 while (q != NULL) {
348 if (!rfc_casecmp(q->extra, host))
349 return u;
350 q = q->next;
351 }
352 u = u->next;
353 }
354 return NULL;
355 }
356
357 /* try: pass_match_by_host("-",host)
358 * will return 1 if no password is set for that host */
359 int u_pass_match(struct userrec *u, char *pass)
360 {
361 char *cmp, new[32];
362
363 if (!u)
364 return 0;
365 cmp = get_user(&USERENTRY_PASS, u);
366 if (!cmp)
367 return 1;
368 if (!pass || !pass[0] || (pass[0] == '-'))
369 return 0;
370 if (u->flags & USER_BOT) {
371 if (!strcmp(cmp, pass))
372 return 1;
373 } else {
374 if (strlen(pass) > 15)
375 pass[15] = 0;
376 encrypt_pass(pass, new);
377 if (!strcmp(cmp, new))
378 return 1;
379 }
380 return 0;
381 }
382
383 int write_user(struct userrec *u, FILE * f, int idx)
384 {
385 char s[181];
386 struct chanuserrec *ch;
387 struct chanset_t *cst;
388 struct user_entry *ue;
389 struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
390
391 fr.global = u->flags;
392 fr.udef_global = u->flags_udef;
393 build_flags(s, &fr, NULL);
394 if (fprintf(f, "%-10s - %-24s\n", u->handle, s) == EOF)
395 return 0;
396 for (ch = u->chanrec; ch; ch = ch->next) {
397 cst = findchan_by_dname(ch->channel);
398 if (cst && ((idx < 0) || channel_shared(cst))) {
399 if (idx >= 0) {
400 fr.match = (FR_CHAN | FR_BOT);
401 get_user_flagrec(dcc[idx].user, &fr, ch->channel);
402 } else
403 fr.chan = BOT_SHARE;
404 if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
405 fr.match = FR_CHAN;
406 fr.chan = ch->flags;
407 fr.udef_chan = ch->flags_udef;
408 build_flags(s, &fr, NULL);
409 if (fprintf(f, "! %-20s %lu %-10s %s\n", ch->channel, ch->laston, s,
410 (((idx < 0) || share_greet) && ch->info) ? ch->info
411 : "") == EOF)
412 return 0;
413 }
414 }
415 }
416 for (ue = u->entries; ue; ue = ue->next) {
417 if (ue->name) {
418 struct list_type *lt;
419
420 for (lt = ue->u.list; lt; lt = lt->next)
421 if (fprintf(f, "--%s %s\n", ue->name, lt->extra) == EOF)
422 return 0;
423 } else {
424 if (!ue->type->write_userfile(f, u, ue))
425 return 0;
426 }
427 }
428 return 1;
429 }
430
431 int sort_compare(struct userrec *a, struct userrec *b)
432 {
433 /* order by flags, then alphabetically
434 * first bots: +h / +a / +l / other bots
435 * then users: +n / +m / +o / other users
436 * return true if (a > b) */
437 if (a->flags & b->flags & USER_BOT) {
438 if (~bot_flags(a) & bot_flags(b) & BOT_HUB)
439 return 1;
440 if (bot_flags(a) & ~bot_flags(b) & BOT_HUB)
441 return 0;
442 if (~bot_flags(a) & bot_flags(b) & BOT_ALT)
443 return 1;
444 if (bot_flags(a) & ~bot_flags(b) & BOT_ALT)
445 return 0;
446 if (~bot_flags(a) & bot_flags(b) & BOT_LEAF)
447 return 1;
448 if (bot_flags(a) & ~bot_flags(b) & BOT_LEAF)
449 return 0;
450 } else {
451 if (~a->flags & b->flags & USER_BOT)
452 return 1;
453 if (a->flags & ~b->flags & USER_BOT)
454 return 0;
455 if (~a->flags & b->flags & USER_OWNER)
456 return 1;
457 if (a->flags & ~b->flags & USER_OWNER)
458 return 0;
459 if (~a->flags & b->flags & USER_MASTER)
460 return 1;
461 if (a->flags & ~b->flags & USER_MASTER)
462 return 0;
463 if (~a->flags & b->flags & USER_OP)
464 return 1;
465 if (a->flags & ~b->flags & USER_OP)
466 return 0;
467 }
468 return (strcasecmp(a->handle, b->handle) > 0);
469 }
470
471 void sort_userlist()
472 {
473 int again;
474 struct userrec *last, *p, *c, *n;
475
476 again = 1;
477 last = NULL;
478 while ((userlist != last) && (again)) {
479 p = NULL;
480 c = userlist;
481 n = c->next;
482 again = 0;
483 while (n != last) {
484 if (sort_compare(c, n)) {
485 again = 1;
486 c->next = n->next;
487 n->next = c;
488 if (p == NULL)
489 userlist = n;
490 else
491 p->next = n;
492 }
493 p = c;
494 c = n;
495 n = n->next;
496 }
497 last = c;
498 }
499 }
500
501 /* rewrite the entire user file */
502 void write_userfile(int idx)
503 {
504 FILE *f;
505 char s[121], s1[81];
506 time_t tt;
507 struct userrec *u;
508 int ok;
509
510 Context;
511 /* also write the channel file at the same time */
512 if (userlist == NULL)
513 return; /* no point in saving userfile */
514 sprintf(s, "%s~new", userfile);
515 f = fopen(s, "w");
516 chmod(s, 0600); /* make it -rw------- */
517 if (f == NULL) {
518 putlog(LOG_MISC, "*", USERF_ERRWRITE);
519 return;
520 }
521 if (!quiet_save)
522 putlog(LOG_MISC, "*", USERF_WRITING);
523 if (sort_users)
524 sort_userlist();
525 tt = now;
526 strcpy(s1, ctime(&tt));
527 fprintf(f, "#4v: %s -- %s -- written %s", ver, botnetnick, s1);
528 Context;
529 ok = 1;
530 u = userlist;
531 while ((u != NULL) && (ok)) {
532 ok = write_user(u, f, idx);
533 u = u->next;
534 }
535 Context;
536 if (!ok || fflush(f)) {
537 putlog(LOG_MISC, "*", "%s (%s)", USERF_ERRWRITE, strerror(ferror(f)));
538 fclose(f);
539 return;
540 }
541 fclose(f);
542 Context;
543 call_hook(HOOK_USERFILE);
544 Context;
545 unlink(userfile);
546 sprintf(s, "%s~new", userfile);
547 movefile(s, userfile);
548 }
549
550 int change_handle(struct userrec *u, char *newh)
551 {
552 int i;
553 char s[16];
554
555 if (!u)
556 return 0;
557 /* nothing that will confuse the userfile */
558 if ((newh[1] == 0) && strchr(BADHANDCHARS, newh[0]))
559 return 0;
560 check_tcl_nkch(u->handle, newh);
561 /* yes, even send bot nick changes now: */
562 if ((!noshare) && !(u->flags & USER_UNSHARED))
563 shareout(NULL, "h %s %s\n", u->handle, newh);
564 strcpy(s, u->handle);
565 strcpy(u->handle, newh);
566 for (i = 0; i < dcc_total; i++) {
567 if (!strcasecmp(dcc[i].nick, s) &&
568 (dcc[i].type != &DCC_BOT)) {
569 strcpy(dcc[i].nick, newh);
570 if ((dcc[i].type == &DCC_CHAT) && (dcc[i].u.chat->channel >= 0)) {
571 chanout_but(-1, dcc[i].u.chat->channel,
572 "*** Nick change: %s -> %s\n", s, newh);
573 if (dcc[i].u.chat->channel < 100000)
574 botnet_send_nkch(i, s);
575 }
576 }
577 }
578 return 1;
579 }
580
581 extern int noxtra;
582
583 struct userrec *adduser(struct userrec *bu, char *handle, char *host,
584 char *pass, int flags)
585 {
586 struct userrec *u, *x;
587 struct xtra_key *xk;
588 int oldshare = noshare;
589
590 noshare = 1;
591 u = (struct userrec *) nmalloc(sizeof(struct userrec));
592
593 /* u->next=bu; bu=u; */
594 strncpy(u->handle, handle, HANDLEN);
595 u->handle[HANDLEN] = 0;
596 u->next = NULL;
597 u->chanrec = NULL;
598 u->entries = NULL;
599 if (flags != USER_DEFAULT) { /* drummer */
600 u->flags = flags;
601 u->flags_udef = 0;
602 } else {
603 u->flags = default_flags;
604 u->flags_udef = default_uflags;
605 }
606 set_user(&USERENTRY_PASS, u, pass);
607 if (!noxtra) {
608 xk = nmalloc(sizeof(struct xtra_key));
609
610 xk->key = nmalloc(8);
611 strcpy(xk->key, "created");
612 xk->data = nmalloc(10);
613 sprintf(xk->data, "%09lu", now);
614 set_user(&USERENTRY_XTRA, u, xk);
615 }
616 /* strip out commas -- they're illegal */
617 if (host && host[0]) {
618 char *p = strchr(host, ',');
619
620 while (p != NULL) {
621 *p = '?';
622 p = strchr(host, ',');
623 }
624 set_user(&USERENTRY_HOSTS, u, host);
625 } else
626 set_user(&USERENTRY_HOSTS, u, "none");
627 if (bu == userlist)
628 clear_chanlist();
629 noshare = oldshare;
630 if ((!noshare) && (handle[0] != '*') && (!(flags & USER_UNSHARED)) &&
631 (bu == userlist)) {
632 struct flag_record fr =
633 {FR_GLOBAL, u->flags, u->flags_udef, 0, 0, 0};
634 char x[100];
635
636 build_flags(x, &fr, 0);
637 shareout(NULL, "n %s %s %s %s\n", handle, host, pass, x);
638 }
639 if (bu == NULL)
640 bu = u;
641 else {
642 if ((bu == userlist) && (lastuser != NULL))
643 x = lastuser;
644 else
645 x = bu;
646 while (x->next != NULL)
647 x = x->next;
648 x->next = u;
649 if (bu == userlist)
650 lastuser = u;
651 }
652 return bu;
653 }
654
655 void freeuser(struct userrec *u)
656 {
657 struct user_entry *ue, *ut;
658 struct chanuserrec *ch, *z;
659
660 if (u == NULL)
661 return;
662 ch = u->chanrec;
663 while (ch) {
664 z = ch;
665 ch = ch->next;
666 if (z->info != NULL)
667 nfree(z->info);
668 nfree(z);
669 }
670 u->chanrec = NULL;
671 for (ue = u->entries; ue; ue = ut) {
672 ut = ue->next;
673 if (ue->name) {
674 struct list_type *lt, *ltt;
675
676 for (lt = ue->u.list; lt; lt = ltt) {
677 ltt = lt->next;
678 nfree(lt->extra);
679 nfree(lt);
680 }
681 nfree(ue->name);
682 nfree(ue);
683 } else {
684 ue->type->kill(ue);
685 }
686 }
687 nfree(u);
688 }
689
690 int deluser(char *handle)
691 {
692 struct userrec *u = userlist, *prev = NULL;
693 int fnd = 0;
694
695 while ((u != NULL) && (!fnd)) {
696 if (!strcasecmp(u->handle, handle))
697 fnd = 1;
698 else {
699 prev = u;
700 u = u->next;
701 }
702 }
703 if (!fnd)
704 return 0;
705 if (prev == NULL)
706 userlist = u->next;
707 else
708 prev->next = u->next;
709 if (!noshare && (handle[0] != '*') && !(u->flags & USER_UNSHARED))
710 shareout(NULL, "k %s\n", handle);
711 for (fnd = 0; fnd < dcc_total; fnd++)
712 if (dcc[fnd].user == u)
713 dcc[fnd].user = 0; /* clear any dcc users for this entry,
714 * null is safe-ish */
715 clear_chanlist();
716 freeuser(u);
717 lastuser = NULL;
718 return 1;
719 }
720
721 int delhost_by_handle(char *handle, char *host)
722 {
723 struct userrec *u;
724 struct list_type *q, *qnext, *qprev;
725 struct user_entry *e = NULL;
726 int i = 0;
727
728 Context;
729 u = get_user_by_handle(userlist, handle);
730 if (!u)
731 return 0;
732 q = get_user(&USERENTRY_HOSTS, u);
733 qprev = q;
734 if (q) {
735 if (!rfc_casecmp(q->extra, host)) {
736 e = find_user_entry(&USERENTRY_HOSTS, u);
737 e->u.extra = q->next;
738 nfree(q->extra);
739 nfree(q);
740 i++;
741 qprev = NULL;
742 q = e->u.extra;
743 } else
744 q = q->next;
745 while (q) {
746 qnext = q->next;
747 if (!rfc_casecmp(q->extra, host)) {
748 if (qprev)
749 qprev->next = q->next;
750 else if (e) {
751 e->u.extra = q->next;
752 qprev = NULL;
753 }
754 nfree(q->extra);
755 nfree(q);
756 i++;
757 } else
758 qprev = q;
759 q = qnext;
760 }
761 }
762 if (!qprev)
763 set_user(&USERENTRY_HOSTS, u, "none");
764 if (!noshare && i && !(u->flags & USER_UNSHARED))
765 shareout(NULL, "-h %s %s\n", handle, host);
766 clear_chanlist();
767 return i;
768 }
769
770 void addhost_by_handle(char *handle, char *host)
771 {
772 struct userrec *u = get_user_by_handle(userlist, handle);
773
774 set_user(&USERENTRY_HOSTS, u, host);
775 /* u will be cached, so really no overhead, even tho this looks dumb: */
776 if ((!noshare) && !(u->flags & USER_UNSHARED)) {
777 if (u->flags & USER_BOT)
778 shareout(NULL, "+bh %s %s\n", handle, host);
779 else
780 shareout(NULL, "+h %s %s\n", handle, host);
781 }
782 clear_chanlist();
783 }
784
785 void touch_laston(struct userrec *u, char *where, time_t timeval)
786 {
787 if (!u)
788 return;
789 if (timeval > 1) {
790 struct laston_info *li =
791 (struct laston_info *) get_user(&USERENTRY_LASTON, u);
792
793 if (!li)
794 li = nmalloc(sizeof(struct laston_info));
795
796 else if (li->lastonplace)
797 nfree(li->lastonplace);
798 li->laston = timeval;
799 if (where) {
800 li->lastonplace = nmalloc(strlen(where) + 1);
801 strcpy(li->lastonplace, where);
802 } else
803 li->lastonplace = NULL;
804 set_user(&USERENTRY_LASTON, u, li);
805 } else if (timeval == 1) {
806 set_user(&USERENTRY_LASTON, u, 0);
807 }
808 }
809
810 /* Go through all channel records and try to find a matching
811 * nick. Will return the user's user record if that is known
812 * to the bot. (Fabian)
813 *
814 * Warning: This is unreliable by concept!
815 */
816 struct userrec *get_user_by_nick(char *nick)
817 {
818 struct chanset_t *chan = chanset;
819 memberlist *m;
820
821 Context;
822 while (chan) {
823 m = chan->channel.member;
824 while (m && m->nick[0]) {
825 if (!rfc_casecmp(nick, m->nick)) {
826 char word[512];
827
828 sprintf(word, "%s!%s", m->nick, m->userhost);
829 /* no need to check the return value ourself */
830 return get_user_by_host(word);;
831 }
832 m = m->next;
833 }
834 chan = chan->next;
835 }
836 /* sorry, no matches */
837 return NULL;
838 }
839
840 void user_del_chan(char *dname)
841 {
842 struct chanuserrec *ch, *z;
843 struct userrec *u;
844
845 for (u = userlist; u; u = u->next) {
846 ch = u->chanrec;
847 while (ch)
848 if (!rfc_casecmp(dname, ch->channel)) {
849 z = ch;
850 ch = ch->next;
851 if (u->chanrec == z)
852 u->chanrec = ch;
853 if (z->info != NULL)
854 nfree(z->info);
855 nfree(z);
856 break;
857 } else
858 ch = ch->next;
859 }
860 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23