00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <sys/stat.h>
00029 #include "main.h"
00030 #include "users.h"
00031 #include "chan.h"
00032 #include "modules.h"
00033 #include "tandem.h"
00034
00035 extern struct dcc_t *dcc;
00036 extern struct chanset_t *chanset;
00037 extern int default_flags, default_uflags, quiet_save, dcc_total, share_greet;
00038 extern char userfile[], ver[], botnetnick[];
00039 extern time_t now;
00040
00041 int noshare = 1;
00042 int sort_users = 0;
00043 struct userrec *userlist = NULL;
00044 struct userrec *lastuser = NULL;
00045 maskrec *global_bans = NULL, *global_exempts = NULL, *global_invites = NULL;
00046 struct igrec *global_ign = NULL;
00047 int cache_hit = 0, cache_miss = 0;
00048 int strict_host = 1;
00049 int userfile_perm = 0600;
00050
00051
00052 void *_user_malloc(int size, const char *file, int line)
00053 {
00054 #ifdef DEBUG_MEM
00055 char x[1024];
00056 const char *p;
00057
00058 p = strrchr(file, '/');
00059 simple_sprintf(x, "userrec.c:%s", p ? p + 1 : file);
00060 return n_malloc(size, x, line);
00061 #else
00062 return nmalloc(size);
00063 #endif
00064 }
00065
00066 void *_user_realloc(void *ptr, int size, const char *file, int line)
00067 {
00068 #ifdef DEBUG_MEM
00069 char x[1024];
00070 const char *p;
00071
00072 p = strrchr(file, '/');
00073 simple_sprintf(x, "userrec.c:%s", p ? p + 1 : file);
00074 return n_realloc(ptr, size, x, line);
00075 #else
00076 return nrealloc(ptr, size);
00077 #endif
00078 }
00079
00080 inline int expmem_mask(struct maskrec *m)
00081 {
00082 int result = 0;
00083
00084 for (; m; m = m->next) {
00085 result += sizeof(struct maskrec);
00086 result += strlen(m->mask) + 1;
00087 if (m->user)
00088 result += strlen(m->user) + 1;
00089 if (m->desc)
00090 result += strlen(m->desc) + 1;
00091 }
00092
00093 return result;
00094 }
00095
00096
00097
00098 int expmem_users()
00099 {
00100 int tot;
00101 struct userrec *u;
00102 struct chanuserrec *ch;
00103 struct chanset_t *chan;
00104 struct user_entry *ue;
00105 struct igrec *i;
00106
00107 tot = 0;
00108 for (u = userlist; u; u = u->next) {
00109 for (ch = u->chanrec; ch; ch = ch->next) {
00110 tot += sizeof(struct chanuserrec);
00111
00112 if (ch->info != NULL)
00113 tot += strlen(ch->info) + 1;
00114 }
00115 tot += sizeof(struct userrec);
00116
00117 for (ue = u->entries; ue; ue = ue->next) {
00118 tot += sizeof(struct user_entry);
00119
00120 if (ue->name) {
00121 tot += strlen(ue->name) + 1;
00122 tot += list_type_expmem(ue->u.list);
00123 } else
00124 tot += ue->type->expmem(ue);
00125 }
00126 }
00127
00128 for (chan = chanset; chan; chan = chan->next) {
00129
00130
00131 tot += expmem_mask(chan->bans);
00132
00133
00134 tot += expmem_mask(chan->exempts);
00135
00136
00137 tot += expmem_mask(chan->invites);
00138 }
00139
00140 tot += expmem_mask(global_bans);
00141 tot += expmem_mask(global_exempts);
00142 tot += expmem_mask(global_invites);
00143
00144 for (i = global_ign; i; i = i->next) {
00145 tot += sizeof(struct igrec);
00146
00147 tot += strlen(i->igmask) + 1;
00148 if (i->user)
00149 tot += strlen(i->user) + 1;
00150 if (i->msg)
00151 tot += strlen(i->msg) + 1;
00152 }
00153 return tot;
00154 }
00155
00156 int count_users(struct userrec *bu)
00157 {
00158 int tot = 0;
00159 struct userrec *u;
00160
00161 for (u = bu; u; u = u->next)
00162 tot++;
00163 return tot;
00164 }
00165
00166
00167
00168
00169 char *fixfrom(char *s)
00170 {
00171 static char uhost[UHOSTLEN];
00172 char *p = uhost;
00173
00174 if (!s || !*s || strict_host)
00175 return s;
00176
00177 while (*s) {
00178 *p++ = *s;
00179 if (*s == '!' && strchr("~+-^=", s[1]) && s[2] != '@') {
00180 strcpy(p, s + 2);
00181 return uhost;
00182 }
00183 s++;
00184 }
00185
00186 *p = 0;
00187 return uhost;
00188 }
00189
00190 struct userrec *check_dcclist_hand(char *handle)
00191 {
00192 int i;
00193
00194 for (i = 0; i < dcc_total; i++)
00195 if (!egg_strcasecmp(dcc[i].nick, handle))
00196 return dcc[i].user;
00197 return NULL;
00198 }
00199
00200 struct userrec *get_user_by_handle(struct userrec *bu, char *handle)
00201 {
00202 struct userrec *u, *ret;
00203
00204 if (!handle)
00205 return NULL;
00206
00207 rmspace(handle);
00208 if (!handle[0] || (handle[0] == '*'))
00209 return NULL;
00210 if (bu == userlist) {
00211 if (lastuser && !egg_strcasecmp(lastuser->handle, handle)) {
00212 cache_hit++;
00213 return lastuser;
00214 }
00215 ret = check_dcclist_hand(handle);
00216 if (ret) {
00217 cache_hit++;
00218 return ret;
00219 }
00220 ret = check_chanlist_hand(handle);
00221 if (ret) {
00222 cache_hit++;
00223 return ret;
00224 }
00225 cache_miss++;
00226 }
00227 for (u = bu; u; u = u->next)
00228 if (!egg_strcasecmp(u->handle, handle)) {
00229 if (bu == userlist)
00230 lastuser = u;
00231 return u;
00232 }
00233 return NULL;
00234 }
00235
00236
00237
00238 void correct_handle(char *handle)
00239 {
00240 struct userrec *u;
00241
00242 u = get_user_by_handle(userlist, handle);
00243 if (u == NULL || handle == u->handle)
00244 return;
00245 strcpy(handle, u->handle);
00246 }
00247
00248
00249
00250
00251 void clear_masks(maskrec *m)
00252 {
00253 maskrec *temp = NULL;
00254
00255 for (; m; m = temp) {
00256 temp = m->next;
00257 if (m->mask)
00258 nfree(m->mask);
00259 if (m->user)
00260 nfree(m->user);
00261 if (m->desc)
00262 nfree(m->desc);
00263 nfree(m);
00264 }
00265 }
00266
00267 void clear_userlist(struct userrec *bu)
00268 {
00269 struct userrec *u, *v;
00270 int i;
00271
00272 for (u = bu; u; u = v) {
00273 v = u->next;
00274 freeuser(u);
00275 }
00276 if (userlist == bu) {
00277 struct chanset_t *cst;
00278
00279 for (i = 0; i < dcc_total; i++)
00280 dcc[i].user = NULL;
00281 clear_chanlist();
00282 lastuser = NULL;
00283
00284 while (global_ign)
00285 delignore(global_ign->igmask);
00286
00287 clear_masks(global_bans);
00288 clear_masks(global_exempts);
00289 clear_masks(global_invites);
00290 global_exempts = global_invites = global_bans = NULL;
00291
00292 for (cst = chanset; cst; cst = cst->next) {
00293 clear_masks(cst->bans);
00294 clear_masks(cst->exempts);
00295 clear_masks(cst->invites);
00296
00297 cst->bans = cst->exempts = cst->invites = NULL;
00298 }
00299 }
00300
00301 }
00302
00303
00304
00305
00306
00307
00308 struct userrec *get_user_by_host(char *host)
00309 {
00310 struct userrec *u, *ret;
00311 struct list_type *q;
00312 int cnt, i;
00313 char host2[UHOSTLEN];
00314
00315 if (host == NULL)
00316 return NULL;
00317 rmspace(host);
00318 if (!host[0])
00319 return NULL;
00320 ret = check_chanlist(host);
00321 cnt = 0;
00322 if (ret != NULL) {
00323 cache_hit++;
00324 return ret;
00325 }
00326 cache_miss++;
00327 strncpyz(host2, host, sizeof host2);
00328 host = fixfrom(host);
00329 for (u = userlist; u; u = u->next) {
00330 q = get_user(&USERENTRY_HOSTS, u);
00331 for (; q; q = q->next) {
00332 i = match_useraddr(q->extra, host);
00333 if (i > cnt) {
00334 ret = u;
00335 cnt = i;
00336 }
00337 }
00338 }
00339 if (ret != NULL) {
00340 lastuser = ret;
00341 set_chanlist(host2, ret);
00342 }
00343 return ret;
00344 }
00345
00346
00347
00348 struct userrec *get_user_by_equal_host(char *host)
00349 {
00350 struct userrec *u;
00351 struct list_type *q;
00352
00353 for (u = userlist; u; u = u->next)
00354 for (q = get_user(&USERENTRY_HOSTS, u); q; q = q->next)
00355 if (!rfc_casecmp(q->extra, host))
00356 return u;
00357 return NULL;
00358 }
00359
00360
00361
00362
00363 int u_pass_match(struct userrec *u, char *pass)
00364 {
00365 char *cmp, new[32];
00366
00367 if (!u)
00368 return 0;
00369 cmp = get_user(&USERENTRY_PASS, u);
00370 if (!cmp && (!pass[0] || (pass[0] == '-')))
00371 return 1;
00372 if (!cmp || !pass || !pass[0] || (pass[0] == '-'))
00373 return 0;
00374 if (u->flags & USER_BOT) {
00375 if (!strcmp(cmp, pass))
00376 return 1;
00377 } else {
00378 if (strlen(pass) > 30)
00379 pass[30] = 0;
00380 encrypt_pass(pass, new);
00381 if (!strcmp(cmp, new))
00382 return 1;
00383 }
00384 return 0;
00385 }
00386
00387 int write_user(struct userrec *u, FILE *f, int idx)
00388 {
00389 char s[181];
00390 long tv;
00391 struct chanuserrec *ch;
00392 struct chanset_t *cst;
00393 struct user_entry *ue;
00394 struct flag_record fr = { FR_GLOBAL, 0, 0, 0, 0, 0 };
00395
00396 fr.global = u->flags;
00397
00398 fr.udef_global = u->flags_udef;
00399 build_flags(s, &fr, NULL);
00400 if (fprintf(f, "%-10s - %-24s\n", u->handle, s) == EOF)
00401 return 0;
00402 for (ch = u->chanrec; ch; ch = ch->next) {
00403 cst = findchan_by_dname(ch->channel);
00404 if (cst && ((idx < 0) || channel_shared(cst))) {
00405 if (idx >= 0) {
00406 fr.match = (FR_CHAN | FR_BOT);
00407 get_user_flagrec(dcc[idx].user, &fr, ch->channel);
00408 } else
00409 fr.chan = BOT_SHARE;
00410 if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
00411 fr.match = FR_CHAN;
00412 fr.chan = ch->flags;
00413 fr.udef_chan = ch->flags_udef;
00414 build_flags(s, &fr, NULL);
00415 tv = ch->laston;
00416 if (fprintf(f, "! %-20s %lu %-10s %s\n", ch->channel, tv, s,
00417 (((idx < 0) || share_greet) && ch->info) ? ch->info : "") == EOF)
00418 return 0;
00419 }
00420 }
00421 }
00422 for (ue = u->entries; ue; ue = ue->next) {
00423 if (ue->name) {
00424 struct list_type *lt;
00425
00426 for (lt = ue->u.list; lt; lt = lt->next)
00427 if (fprintf(f, "--%s %s\n", ue->name, lt->extra) == EOF)
00428 return 0;
00429 } else if (!ue->type->write_userfile(f, u, ue))
00430 return 0;
00431 }
00432 return 1;
00433 }
00434
00435 int write_ignores(FILE *f, int idx)
00436 {
00437 struct igrec *i;
00438 char *mask;
00439 long expire, added;
00440
00441 if (global_ign)
00442 if (fprintf(f, IGNORE_NAME " - -\n") == EOF)
00443 return 0;
00444 for (i = global_ign; i; i = i->next) {
00445 mask = str_escape(i->igmask, ':', '\\');
00446 expire = i->expire;
00447 added = i->added;
00448 if (!mask ||
00449 fprintf(f, "- %s:%s%lu:%s:%lu:%s\n", mask,
00450 (i->flags & IGREC_PERM) ? "+" : "", expire,
00451 i->user ? i->user : botnetnick, added,
00452 i->msg ? i->msg : "") == EOF) {
00453 if (mask)
00454 nfree(mask);
00455 return 0;
00456 }
00457 nfree(mask);
00458 }
00459 return 1;
00460 }
00461
00462 int sort_compare(struct userrec *a, struct userrec *b)
00463 {
00464
00465
00466
00467
00468
00469 if (a->flags & b->flags & USER_BOT) {
00470 if (~bot_flags(a) & bot_flags(b) & BOT_HUB)
00471 return 1;
00472 if (bot_flags(a) & ~bot_flags(b) & BOT_HUB)
00473 return 0;
00474 if (~bot_flags(a) & bot_flags(b) & BOT_ALT)
00475 return 1;
00476 if (bot_flags(a) & ~bot_flags(b) & BOT_ALT)
00477 return 0;
00478 if (~bot_flags(a) & bot_flags(b) & BOT_LEAF)
00479 return 1;
00480 if (bot_flags(a) & ~bot_flags(b) & BOT_LEAF)
00481 return 0;
00482 } else {
00483 if (~a->flags & b->flags & USER_BOT)
00484 return 1;
00485 if (a->flags & ~b->flags & USER_BOT)
00486 return 0;
00487 if (~a->flags & b->flags & USER_OWNER)
00488 return 1;
00489 if (a->flags & ~b->flags & USER_OWNER)
00490 return 0;
00491 if (~a->flags & b->flags & USER_MASTER)
00492 return 1;
00493 if (a->flags & ~b->flags & USER_MASTER)
00494 return 0;
00495 if (~a->flags & b->flags & USER_OP)
00496 return 1;
00497 if (a->flags & ~b->flags & USER_OP)
00498 return 0;
00499 if (~a->flags & b->flags & USER_HALFOP)
00500 return 1;
00501 if (a->flags & ~b->flags & USER_HALFOP)
00502 return 0;
00503 }
00504 return (egg_strcasecmp(a->handle, b->handle) > 0);
00505 }
00506
00507 void sort_userlist()
00508 {
00509 int again;
00510 struct userrec *last, *p, *c, *n;
00511
00512 again = 1;
00513 last = NULL;
00514 while ((userlist != last) && (again)) {
00515 p = NULL;
00516 c = userlist;
00517 n = c->next;
00518 again = 0;
00519 while (n != last) {
00520 if (sort_compare(c, n)) {
00521 again = 1;
00522 c->next = n->next;
00523 n->next = c;
00524 if (p == NULL)
00525 userlist = n;
00526 else
00527 p->next = n;
00528 }
00529 p = c;
00530 c = n;
00531 n = n->next;
00532 }
00533 last = c;
00534 }
00535 }
00536
00537
00538
00539
00540 void write_userfile(int idx)
00541 {
00542 FILE *f;
00543 char *new_userfile;
00544 char s1[81];
00545 time_t tt;
00546 struct userrec *u;
00547 int ok;
00548
00549 if (userlist == NULL)
00550 return;
00551
00552 new_userfile = nmalloc(strlen(userfile) + 5);
00553 sprintf(new_userfile, "%s~new", userfile);
00554
00555 f = fopen(new_userfile, "w");
00556 chmod(new_userfile, userfile_perm);
00557 if (f == NULL) {
00558 putlog(LOG_MISC, "*", USERF_ERRWRITE);
00559 nfree(new_userfile);
00560 return;
00561 }
00562 if (!quiet_save)
00563 putlog(LOG_MISC, "*", USERF_WRITING);
00564 if (sort_users)
00565 sort_userlist();
00566 tt = now;
00567 strcpy(s1, ctime(&tt));
00568 fprintf(f, "#4v: %s -- %s -- written %s", ver, botnetnick, s1);
00569 ok = 1;
00570 for (u = userlist; u && ok; u = u->next)
00571 if (!write_user(u, f, idx))
00572 ok = 0;
00573 if (!ok || !write_ignores(f, -1) || fflush(f)) {
00574 putlog(LOG_MISC, "*", "%s (%s)", USERF_ERRWRITE, strerror(ferror(f)));
00575 fclose(f);
00576 nfree(new_userfile);
00577 return;
00578 }
00579 fclose(f);
00580 call_hook(HOOK_USERFILE);
00581 movefile(new_userfile, userfile);
00582 nfree(new_userfile);
00583 }
00584
00585 int change_handle(struct userrec *u, char *newh)
00586 {
00587 int i;
00588 char s[HANDLEN + 1];
00589
00590 if (!u)
00591 return 0;
00592
00593 if (!newh[1] && strchr(BADHANDCHARS, newh[0]))
00594 return 0;
00595 check_tcl_nkch(u->handle, newh);
00596
00597 if (!noshare && !(u->flags & USER_UNSHARED))
00598 shareout(NULL, "h %s %s\n", u->handle, newh);
00599 strncpyz(s, u->handle, sizeof s);
00600 strncpyz(u->handle, newh, sizeof u->handle);
00601 for (i = 0; i < dcc_total; i++)
00602 if ((dcc[i].type == &DCC_CHAT || dcc[i].type == &DCC_CHAT_PASS) &&
00603 !egg_strcasecmp(dcc[i].nick, s)) {
00604 strncpyz(dcc[i].nick, newh, sizeof dcc[i].nick);
00605 if (dcc[i].type == &DCC_CHAT && dcc[i].u.chat->channel >= 0) {
00606 chanout_but(-1, dcc[i].u.chat->channel,
00607 "*** Handle change: %s -> %s\n", s, newh);
00608 if (dcc[i].u.chat->channel < GLOBAL_CHANS)
00609 botnet_send_nkch(i, s);
00610 }
00611 }
00612 return 1;
00613 }
00614
00615 extern int noxtra;
00616
00617 struct userrec *adduser(struct userrec *bu, char *handle, char *host,
00618 char *pass, int flags)
00619 {
00620 struct userrec *u, *x;
00621 struct xtra_key *xk;
00622 int oldshare = noshare;
00623 long tv;
00624
00625 noshare = 1;
00626 u = nmalloc(sizeof *u);
00627
00628
00629 strncpyz(u->handle, handle, sizeof u->handle);
00630 u->next = NULL;
00631 u->chanrec = NULL;
00632 u->entries = NULL;
00633 if (flags != USER_DEFAULT) {
00634 u->flags = flags;
00635 u->flags_udef = 0;
00636 } else {
00637 u->flags = default_flags;
00638 u->flags_udef = default_uflags;
00639 }
00640 set_user(&USERENTRY_PASS, u, pass);
00641 if (!noxtra) {
00642 char *now2;
00643 xk = nmalloc(sizeof *xk);
00644 xk->key = nmalloc(8);
00645 strcpy(xk->key, "created");
00646 now2 = nmalloc(15);
00647 tv = now;
00648 sprintf(now2, "%li", tv);
00649 xk->data = nmalloc(strlen(now2) + 1);
00650 sprintf(xk->data, "%li", tv);
00651 set_user(&USERENTRY_XTRA, u, xk);
00652 nfree(now2);
00653 }
00654
00655 if (host && host[0]) {
00656 char *p;
00657
00658
00659
00660
00661
00662
00663 host = fixfrom(host);
00664
00665 p = strchr(host, ',');
00666 while (p != NULL) {
00667 *p = '?';
00668 p = strchr(host, ',');
00669 }
00670 set_user(&USERENTRY_HOSTS, u, host);
00671 } else
00672 set_user(&USERENTRY_HOSTS, u, "none");
00673 if (bu == userlist)
00674 clear_chanlist();
00675 noshare = oldshare;
00676 if ((!noshare) && (handle[0] != '*') && (!(flags & USER_UNSHARED)) &&
00677 (bu == userlist)) {
00678 struct flag_record fr = { FR_GLOBAL, 0, 0, 0, 0, 0 };
00679 char x[100];
00680
00681 fr.global = u->flags;
00682
00683 fr.udef_global = u->flags_udef;
00684 build_flags(x, &fr, 0);
00685 shareout(NULL, "n %s %s %s %s\n", handle, host && host[0] ? host : "none",
00686 pass, x);
00687 }
00688 if (bu == NULL)
00689 bu = u;
00690 else {
00691 if ((bu == userlist) && (lastuser != NULL))
00692 x = lastuser;
00693 else
00694 x = bu;
00695 while (x->next != NULL)
00696 x = x->next;
00697 x->next = u;
00698 if (bu == userlist)
00699 lastuser = u;
00700 }
00701 return bu;
00702 }
00703
00704 void freeuser(struct userrec *u)
00705 {
00706 struct user_entry *ue, *ut;
00707 struct chanuserrec *ch, *z;
00708
00709 if (u == NULL)
00710 return;
00711
00712 ch = u->chanrec;
00713 while (ch) {
00714 z = ch;
00715 ch = ch->next;
00716 if (z->info != NULL)
00717 nfree(z->info);
00718 nfree(z);
00719 }
00720 u->chanrec = NULL;
00721 for (ue = u->entries; ue; ue = ut) {
00722 ut = ue->next;
00723 if (ue->name) {
00724 struct list_type *lt, *ltt;
00725
00726 for (lt = ue->u.list; lt; lt = ltt) {
00727 ltt = lt->next;
00728 nfree(lt->extra);
00729 nfree(lt);
00730 }
00731 nfree(ue->name);
00732 nfree(ue);
00733 } else
00734 ue->type->kill(ue);
00735 }
00736 nfree(u);
00737 }
00738
00739 int deluser(char *handle)
00740 {
00741 struct userrec *u = userlist, *prev = NULL;
00742 int fnd = 0;
00743
00744 while ((u != NULL) && (!fnd)) {
00745 if (!egg_strcasecmp(u->handle, handle))
00746 fnd = 1;
00747 else {
00748 prev = u;
00749 u = u->next;
00750 }
00751 }
00752 if (!fnd)
00753 return 0;
00754 if (prev == NULL)
00755 userlist = u->next;
00756 else
00757 prev->next = u->next;
00758 if (!noshare && (handle[0] != '*') && !(u->flags & USER_UNSHARED))
00759 shareout(NULL, "k %s\n", handle);
00760 for (fnd = 0; fnd < dcc_total; fnd++)
00761 if (dcc[fnd].user == u)
00762 dcc[fnd].user = 0;
00763
00764 clear_chanlist();
00765 freeuser(u);
00766 lastuser = NULL;
00767 return 1;
00768 }
00769
00770 int delhost_by_handle(char *handle, char *host)
00771 {
00772 struct userrec *u;
00773 struct list_type *q, *qnext, *qprev;
00774 struct user_entry *e = NULL;
00775 int i = 0;
00776
00777 u = get_user_by_handle(userlist, handle);
00778 if (!u)
00779 return 0;
00780 q = get_user(&USERENTRY_HOSTS, u);
00781 qprev = q;
00782 if (q) {
00783 if (!rfc_casecmp(q->extra, host)) {
00784 e = find_user_entry(&USERENTRY_HOSTS, u);
00785 e->u.extra = q->next;
00786 nfree(q->extra);
00787 nfree(q);
00788 i++;
00789 qprev = NULL;
00790 q = e->u.extra;
00791 } else
00792 q = q->next;
00793 while (q) {
00794 qnext = q->next;
00795 if (!rfc_casecmp(q->extra, host)) {
00796 if (qprev)
00797 qprev->next = q->next;
00798 else if (e) {
00799 e->u.extra = q->next;
00800 qprev = NULL;
00801 }
00802 nfree(q->extra);
00803 nfree(q);
00804 i++;
00805 } else
00806 qprev = q;
00807 q = qnext;
00808 }
00809 }
00810 if (!qprev)
00811 set_user(&USERENTRY_HOSTS, u, "none");
00812 if (!noshare && i && !(u->flags & USER_UNSHARED))
00813 shareout(NULL, "-h %s %s\n", handle, host);
00814 clear_chanlist();
00815 return i;
00816 }
00817
00818 void addhost_by_handle(char *handle, char *host)
00819 {
00820 struct userrec *u = get_user_by_handle(userlist, handle);
00821
00822 set_user(&USERENTRY_HOSTS, u, host);
00823
00824 if ((!noshare) && !(u->flags & USER_UNSHARED)) {
00825 if (u->flags & USER_BOT)
00826 shareout(NULL, "+bh %s %s\n", handle, host);
00827 else
00828 shareout(NULL, "+h %s %s\n", handle, host);
00829 }
00830 clear_chanlist();
00831 }
00832
00833 void touch_laston(struct userrec *u, char *where, time_t timeval)
00834 {
00835 if (!u)
00836 return;
00837
00838 if (timeval > 1) {
00839 struct laston_info *li = get_user(&USERENTRY_LASTON, u);
00840
00841 if (!li)
00842 li = nmalloc(sizeof *li);
00843
00844 else if (li->lastonplace)
00845 nfree(li->lastonplace);
00846 li->laston = timeval;
00847 if (where) {
00848 li->lastonplace = nmalloc(strlen(where) + 1);
00849 strcpy(li->lastonplace, where);
00850 } else
00851 li->lastonplace = NULL;
00852 set_user(&USERENTRY_LASTON, u, li);
00853 } else if (timeval == 1)
00854 set_user(&USERENTRY_LASTON, u, 0);
00855 }
00856
00857
00858
00859
00860
00861
00862
00863 struct userrec *get_user_by_nick(char *nick)
00864 {
00865 struct chanset_t *chan;
00866 memberlist *m;
00867
00868 for (chan = chanset; chan; chan = chan->next) {
00869 for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
00870 if (!rfc_casecmp(nick, m->nick)) {
00871 char word[512];
00872
00873 egg_snprintf(word, sizeof word, "%s!%s", m->nick, m->userhost);
00874
00875 return get_user_by_host(word);;
00876 }
00877 }
00878 }
00879
00880 return NULL;
00881 }
00882
00883 void user_del_chan(char *dname)
00884 {
00885 struct chanuserrec *ch, *och;
00886 struct userrec *u;
00887
00888 for (u = userlist; u; u = u->next) {
00889 ch = u->chanrec;
00890 och = NULL;
00891 while (ch) {
00892 if (!rfc_casecmp(dname, ch->channel)) {
00893 if (och)
00894 och->next = ch->next;
00895 else
00896 u->chanrec = ch->next;
00897
00898 if (ch->info)
00899 nfree(ch->info);
00900 nfree(ch);
00901 break;
00902 }
00903 och = ch;
00904 ch = ch->next;
00905 }
00906 }
00907 }
00908
00909
00910
00911
00912
00913
00914 int check_conflags(struct flag_record *fr, int md)
00915 {
00916 if (!glob_owner(*fr))
00917 md &= ~(LOG_RAW | LOG_SRVOUT | LOG_BOTNET | LOG_BOTSHARE);
00918 if (!glob_master(*fr)) {
00919 md &= ~(LOG_FILES | LOG_LEV1 | LOG_LEV2 | LOG_LEV3 | LOG_LEV4 |
00920 LOG_LEV5 | LOG_LEV6 | LOG_LEV7 | LOG_LEV8 | LOG_DEBUG |
00921 LOG_WALL);
00922 if ((fr->match & FR_CHAN) && !chan_master(*fr))
00923 md &= ~(LOG_MISC | LOG_CMDS);
00924 }
00925 if (!glob_botmast(*fr))
00926 md &= ~LOG_BOTS;
00927 return md;
00928 }