static int egg_chan_active(char *chan) { if (!list_secret_chans && secretchan(chan)) return 0; if (inactivechan(chan)) return 0; return 1; }
static void add_seenreq(char *nick, char *from, char *host, char *chan, time_t when) { seenreq *l, *nl; seenreq_by *b, *nb; char buf[10] = "[secret]"; Context; if (!tell_seens) return; if (strcmp(chan, "[partyline]") && secretchan(chan)) chan = buf; for (l = requests; l; l = l->next) { if (!strcasecmp(nick, l->nick)) { for (b = l->by; b; b = b->next) { if (!strcasecmp(from, b->who)) { nfree(b->chan); b->chan = nmalloc(strlen(chan) + 1); strcpy(b->chan, chan); b->when = when; return; } } b = l->by; while (b && b->next) b = b->next; nb = nmalloc(sizeof(seenreq_by)); nb->who = nmalloc(strlen(from) + 1); strcpy(nb->who, from); nb->host = nmalloc(strlen(host) + 1); strcpy(nb->host, host); nb->chan = nmalloc(strlen(chan) + 1); strcpy(nb->chan, chan); nb->when = when; nb->next = NULL; if (l->by) b->next = nb; else l->by = nb; return; } } nb = nmalloc(sizeof(seenreq_by)); nb->who = nmalloc(strlen(from) + 1); strcpy(nb->who, from); nb->host = nmalloc(strlen(host) + 1); strcpy(nb->host, host); nb->chan = nmalloc(strlen(chan) + 1); strcpy(nb->chan, chan); nb->when = when; nb->next = NULL; l = requests; while (l && l->next) l = l->next; nl = nmalloc(sizeof(seenreq)); nl->nick = nmalloc(strlen(nick) + 1); strcpy(nl->nick, nick); nl->by = nb; nl->next = NULL; if (requests) l->next = nl; else requests = nl; }
/* do_seen(): Checks if someone matches the mask, and returns the reply * mask : first paramater (e.g. "G`Quann", "G`Quann", "*!*@*.isp.de", ...) * nick : nick of the one, who triggered the command * uhost: user@host of nick * chan : chan, where the command was triggered * bns : * 1 : do a botnet-seen if no matches are found * 0 : don't do a botnet-seen * -1 : return NULL instead of text, if no matches were found * (necessary for botnet seen) */ static char *do_seen(char *mask, char *nick, char *uhost, char *chan, int bns) { char hostbuf[UHOSTLEN + 1], *host, *newhost, *tmp, *dur; seendat *l; gseenres *r; int wild, nr; char bnquery[256]; struct userrec *u; struct laston_info *li; struct chanset_t *ch; Context; start_seentime_calc(); if (seen_reply) { nfree(seen_reply); seen_reply = NULL; } l = NULL; li = NULL; host = hostbuf; newhost = NULL; mask = newsplit(&mask); glob_query = mask; while (mask[0] == ' ') mask++; if (!mask[0]) { return SLNOPARAM; } if (strchr(mask, '?') || strchr(mask, '*')) { // if wildcard-searches ares not allowed, then either return // NULL (for botnet-seen), or a appropriate warning if (!wildcard_search) { if (bns == -1) return NULL; else return SLNOWILDCARDS; } else wild = 1; } else { if (strlen(mask) > seen_nick_len) // don't process if requested nick is too long return SLTOOLONGNICK; // (e.g. stop stupid jokes) if (!strcasecmp(mask, nick)) { return SLMIRROR; } // check if the nick is on the current channel if (onchan(mask, chan)) return SLONCHAN; if ((glob_othernick = handonchan(mask, chan))) return SLHANDONCHAN; // check if it is on any other channel if ((ch = onanychan(mask))) { #if EGG_IS_MIN_VER(10500) if (!secretchan(ch->dname)) { glob_otherchan = ch->dname; return SLONOTHERCHAN; } #else if (!secretchan(ch->name)) { glob_otherchan = ch->name; return SLONOTHERCHAN; } #endif } // check if the user who uses this handle is on the channel under // a different nick if ((ch = handonanychan(mask))) { #if EGG_IS_MIN_VER(10500) if (!secretchan(ch->dname)) { glob_otherchan = ch->dname; return SLONOTHERCHAN; } #else if (!secretchan(ch->name)) { glob_otherchan = ch->name; return SLONOTHERCHAN; } #endif } add_seenreq(mask, nick, uhost, chan, now); wild = 0; l = findseen(mask); // if there's a result, and if we don't want to search for the same user // under a different nick, just make a do_seennick on the result if (l && !fuzzy_search) { tmp = do_seennick(l); end_seentime_calc(); return tmp; } if (!l) { u = get_user_by_handle(userlist, mask); if (u) { li = get_user(&USERENTRY_LASTON, u); } if (!u || !li) { if (bns == -1) { // if bns is 0, then do_seen() was triggered by end_seentime_calc(); // a botnet seen function, which needs a clear return NULL; // NULL to detect if there was a result or not } tmp = SLNOTSEEN; if (bns && ((strlen(mask) + strlen(nick) + strlen(uhost) + strlen(chan) + 20) < 255)) { debug0("trying botnet seen"); if (bnsnick) nfree(bnsnick); if (bnschan) nfree(bnschan); bnsnick = nmalloc(strlen(nick) + 1); strcpy(bnsnick, nick); bnschan = nmalloc(strlen(chan) + 1); strcpy(bnschan, chan); sprintf(bnquery, "gseen_req %s %s %s %s", mask, nick, uhost, chan); botnet_send_zapf_broad(-1, botnetnick, NULL, bnquery); } } else { // we have a matching handle, no seen-entry, but a laston entry // in the userbase, so let's just return that one. dur = gseen_duration(now - li->laston); glob_laston = dur; tmp = SLPOORSEEN; seen_reply = nmalloc(strlen(tmp) + 1); strcpy(seen_reply, tmp); end_seentime_calc(); return seen_reply; } end_seentime_calc(); return tmp; } // now prepare the host for fuzzy-search if (strlen(l->host) < UHOSTLEN) { maskstricthost(l->host, host); host = strchr(host, '!') + 1; // strip nick from host for faster search } else { end_seentime_calc(); return "error, too long host"; } } if (l && (l->type == SEEN_CHPT)) { tmp = do_seennick(l); end_seentime_calc(); return tmp; } numresults = 0; // wildmatch_seens uses a global var to store hosts in it // (to prevent massive nmalloc/nfree-usage), so don't forget // to initialize and free it temp_wildmatch_host = my_malloc(1); wildmatch_seens(host, mask, wild); my_free(temp_wildmatch_host); temp_wildmatch_host = NULL; if (!results) { end_seentime_calc(); if (bns == -1) return NULL; // let the botnet seen function know, that seen failed return SLNOMATCH; } if (numresults >= max_matches) { end_seentime_calc(); free_seenresults(); return SLTOOMANYMATCHES; } sortresults(); if (strcasecmp(results->seen->nick, mask)) { // if the user's latest nick is not the nick for which we were searching, // say that there were multiple matches and display the latest one if (numresults == 1) tmp = SLONEMATCH; else if (numresults <= 20) tmp = SLLITTLEMATCHES; else tmp = SLMANYMATCHES; seen_reply = nmalloc(strlen(tmp) + 1); strcpy(seen_reply, tmp); nr = 0; for (r = results; (r && (nr < 20)); r = r->next) { nr++; if (nr > 1) { seen_reply = nrealloc(seen_reply, 1 + strlen(seen_reply) + 1 + strlen(r->seen->nick) + 1); strcat(seen_reply, ", "); } else { seen_reply = nrealloc(seen_reply, 1 + strlen(seen_reply) + strlen(r->seen->nick) + 1); strcat(seen_reply, " "); } strcat(seen_reply, r->seen->nick); } tmp = do_seennick(results->seen); seen_reply = nrealloc(seen_reply, 2 + strlen(seen_reply) + strlen(tmp) + 1); sprintf(seen_reply, "%s. %s", seen_reply, tmp); } else { // first result is the nick which we were searching for // just return the info for this nick and don't care about other results tmp = do_seennick(results->seen); seen_reply = nmalloc(strlen(tmp) + 1); strcpy(seen_reply, tmp); } free_seenresults(); end_seentime_calc(); return seen_reply; }