static int pub_seennick(char *nick, char *host, char *hand, char *channel, char *text) { seendat *l; char *dest; #if EGG_IS_MIN_VER(10500) struct chanset_t *chan; #endif Context; if (seenflood()) return 0; if (nopub(channel)) return 0; putlog(LOG_CMDS, "*", "<<%s>> !%s! seennick %s", nick, hand, text); reset_global_vars(); glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, channel)); glob_nick = nick; #if EGG_IS_MIN_VER(10500) chan = findchan_by_dname(channel); if (chan) dest = chan->name; else dest = channel; #else dest = channel; #endif text = newsplit(&text); l = findseen(text); if (!l) { glob_query = text; if (quietseen(channel)) { set_prefix(SLNOTPREFIX); dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, SLNOTSEEN); } else { set_prefix(SLPUBPREFIX); dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, SLNOTSEEN); } return 0; } if (quietseen(channel)) { set_prefix(SLNOTPREFIX); dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, do_seennick(l)); } else { set_prefix(SLPUBPREFIX); dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, do_seennick(l)); } return 0; }
static void update (dnode_t *pnode) { Tkvindex_t tkvi; dnode_t *list, *cnode; seennode_t *seennode; char *s; long i, n; indent += 2; n = ((Ttable_t *) pnode->vo)->n; if (!(list = malloc (n * sizeof (dnode_t)))) panic1 (POS, "update", "list malloc failed"); for ( cnode = &list[0], Tgetfirst (pnode->vo, &tkvi); tkvi.kvp; cnode++, Tgetnext (&tkvi) ) { cnode->ko = tkvi.kvp->ko; cnode->vo = tkvi.kvp->vo; cnode->ttype = Tgettype (cnode->vo); } qsort ((char *) list, n, sizeof (dnode_t), cmp); for (i = 0, cnode = &list[0]; i < n; i++, cnode++) { cnode->path = Spath (pnode->path, cnode->ko); seennode = findseen (cnode); if (seennode) { pr ((s = Sseen (cnode->ko, seennode->path))), free (s); } else { add2seen (cnode); if (cnode->ttype == T_TABLE) { pr ((s = Stfull (cnode->ko))), free (s); update (cnode); pr ("];"); } else { pr ((s = Ssfull (cnode->ko, cnode->vo))), free (s); } } } free (list); indent -= 2; }
static int cmd_seennick(struct userrec *u, int idx, char *text) { seendat *l; Context; if (seenflood()) return 0; putlog(LOG_CMDS, "*", "#%s# seennick %s", dcc[idx].nick, text); reset_global_vars(); glob_slang = slang_find(coreslangs, default_slang); glob_nick = dcc[idx].nick; set_prefix(SLMSGPREFIX); text = newsplit(&text); l = findseen(text); if (!l) { glob_query = text; dprintf(idx, "%s%s\n", reply_prefix, SLNOTSEEN); return 0; } dprintf(idx, "%s%s\n", reply_prefix, do_seennick(l)); return 0; }
static int msg_seennick(char *nick, char *uhost, struct userrec *u, char *text) { seendat *l; Context; if (seenflood()) return 0; putlog(LOG_CMDS, "*", "(%s!%s) !%s! seennick %s", nick, uhost, u ? u->handle : "*", text); reset_global_vars(); glob_slang = slang_getbynick(coreslangs, nick); glob_nick = nick; set_prefix(SLMSGPREFIX); text = newsplit(&text); l = findseen(text); if (!l) { glob_query = text; dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", nick, reply_prefix, SLNOTSEEN); return 0; } dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", nick, reply_prefix, do_seennick(l)); return 0; }
/* update is called only for TXT_FULL tables */ static void update (txtnode_t *pnode, long ptim) { txtnode_t *cnode, *seennode; long ctim; int i; Gawsetmode (&Gwidgets[pnode->u.f.t.mwi], TRUE); if (!pnode->u.f.t.list) buildlist (pnode); else if (ptim < Tgettime (pnode->vo)) rebuildlist (pnode); for ( i = 0, cnode = &pnode->u.f.t.list[0]; i < pnode->u.f.t.n; i++, cnode++ ) { ctim = cnode->time; if (txtvo2toggle == cnode->vo) { switch (cnode->mode) { case TXT_SEEN: break; case TXT_ABSTRACT: unfillnode (cnode); cnode->mode = TXT_FULL; fillnode (pnode, cnode); break; case TXT_FULL: unfillnode (cnode); cnode->mode = TXT_ABSTRACT; fillnode (pnode, cnode); break; } } if (!(seennode = findseen (cnode))) add2seen (cnode); if ( seennode && cnode->mode == TXT_SEEN && seennode->ko != cnode->u.s.ko ) { unfillnode (cnode); cnode->u.s.txtnode = seennode; cnode->u.s.ko = seennode->ko; fillnode (pnode, cnode); } else if (seennode && cnode->mode != TXT_SEEN) { unfillnode (cnode); cnode->mode = TXT_SEEN; cnode->u.s.txtnode = seennode; cnode->u.s.ko = seennode->ko; fillnode (pnode, cnode); } else if (!seennode && cnode->mode == TXT_SEEN) { unfillnode (cnode); cnode->mode = TXT_ABSTRACT; fillnode (pnode, cnode); } else if (cnode->time == -1) { unfillnode (cnode); if (seennode) cnode->u.s.txtnode = seennode; fillnode (pnode, cnode); } if (cnode->ttype == T_TABLE && cnode->mode == TXT_FULL) update (cnode, ctim); } Gaworder (&Gwidgets[pnode->u.f.t.mwi], pnode, orderfunc); Gawsetmode (&Gwidgets[pnode->u.f.t.mwi], FALSE); }
/* findseens(): * interface for webseen.mod * find all results for a query and return a pointer to this list * (basically the core of do_seen()) */ static gseenres *findseens(char *mask, int *ret, int fuzzy) { char hostbuf[UHOSTLEN + 1], *host, *newhost; seendat *l; int wild; Context; start_seentime_calc(); *ret = WS_OK; l = NULL; host = hostbuf; newhost = NULL; mask = newsplit(&mask); while (mask[0] == ' ') mask++; if (!mask[0]) { *ret = WS_NOPARAM; return NULL; } 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) { *ret = WS_NOWILDCARDS; return NULL; } wild = 1; } else { if (strlen(mask) > seen_nick_len) { // don't process if requested nick is too long *ret = WS_TOOLONGNICK; // (e.g. stop stupid jokes) return NULL; } add_seenreq(mask, "www-user", "unknown_host", "webinterface", 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 return this result if (l && (!fuzzy_search || !fuzzy)) { numresults = 1; add_seenresult(l); end_seentime_calc(); return results; } if (!l) { // no matching user was found :( *ret = WS_NORESULT; end_seentime_calc(); return NULL; } // 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 { *ret = WS_TOOLONGHOST; end_seentime_calc(); return NULL; } } if (l && (l->type == SEEN_CHPT)) { numresults = 1; add_seenresult(l); end_seentime_calc(); return results; } 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) { // no match :( *ret = WS_NORESULT; end_seentime_calc(); return NULL; } if (numresults >= max_matches) { free_seenresults(); *ret = WS_TOOMANYMATCHES; end_seentime_calc(); return NULL; } sortresults(); *ret = 0; end_seentime_calc(); return results; }
/* 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; }