/* Contains the logic to decide wether we want to punish someone. Returns * true (1) if we want to, false (0) if not. */ static int want_to_revenge(struct chanset_t *chan, struct userrec *u, struct userrec *u2, char *badnick, char *victim, int mevictim) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; /* Do not take revenge upon ourselves. */ if (match_my_nick(badnick)) return 0; get_user_flagrec(u, &fr, chan->dname); /* Kickee is not a friend? */ if (!chan_friend(fr) && !glob_friend(fr) && rfc_casecmp(badnick, victim)) { if (mevictim && channel_revengebot(chan)) return 1; else if (channel_revenge(chan) && u2) { struct flag_record fr2 = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; get_user_flagrec(u2, &fr2, chan->dname); /* Protecting friends? */ if ((channel_protectfriends(chan) && (chan_friend(fr2) || (glob_friend(fr2) && !chan_deop(fr2)))) || (channel_protectops(chan) && (chan_op(fr2) || (glob_op(fr2) && !chan_deop(fr2))))) return 1; } } return 0; }
int whois_access(struct userrec *user, struct userrec *whois_user) { if (user == whois_user) return 1; struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 }, whois = { FR_GLOBAL | FR_CHAN, 0, 0, 0}; get_user_flagrec(user, &fr, NULL); get_user_flagrec(whois_user, &whois, NULL); /* Don't show hub bots from leaf bots. */ if (!conf.bot->hub && whois_user->bot && bot_hublevel(whois_user) < 999) return 0; if ( (isowner(whois_user->handle) && !isowner(user->handle)) || (glob_admin(whois) && !glob_admin(fr)) || (glob_owner(whois) && !glob_owner(fr)) || (glob_master(whois) && !glob_master(fr)) || (glob_bot(whois) && !glob_master(fr)) ) return 0; return 1; }
static void cmd_mns_chrec(int idx, char *par) { char *nick = NULL, *chn = NULL; struct userrec *u1 = NULL; struct chanuserrec *chanrec = NULL; if (!par[0]) { dprintf(idx, "Usage: -chrec <user> [channel]\n"); return; } nick = newsplit(&par); u1 = get_user_by_handle(userlist, nick); if (!u1) { dprintf(idx, "No such user.\n"); return; } if (!par[0]) { struct chanset_t *chan; chan = findchan_by_dname(dcc[idx].u.chat->con_chan); if (chan) chn = chan->dname; else { dprintf(idx, "Invalid console channel.\n"); return; } } else chn = newsplit(&par); get_user_flagrec(dcc[idx].user, &user, chn); get_user_flagrec(u1, &victim, chn); if (privchan(user, findchan_by_dname(chn), PRIV_OP)) { dprintf(idx, "No such channel.\n"); return; } if ((!glob_master(user) && !chan_master(user)) || /* drummer */ (chan_owner(victim) && !chan_owner(user) && !glob_owner(user)) || (glob_owner(victim) && !glob_owner(user))) { dprintf(idx, "You have no permission to do that.\n"); return; } chanrec = get_chanrec(u1, chn); if (!chanrec) { dprintf(idx, "User %s doesn't have a channel record for %s.\n", nick, chn); return; } putlog(LOG_CMDS, "*", "#%s# -chrec %s %s", dcc[idx].nick, nick, chn); del_chanrec(u1, chn); dprintf(idx, "Removed %s channel record from %s.\n", chn, nick); if (conf.bot->hub) write_userfile(idx); }
/* Check for tcl-bound dcc command, return 1 if found * dcc: proc-name <handle> <sock> <args...> */ int check_tcl_dcc(const char *cmd, int idx, const char *args) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; int x; char s[11]; get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan); egg_snprintf(s, sizeof s, "%ld", dcc[idx].sock); Tcl_SetVar(interp, "_dcc1", (char *) dcc[idx].nick, 0); Tcl_SetVar(interp, "_dcc2", (char *) s, 0); Tcl_SetVar(interp, "_dcc3", (char *) args, 0); x = check_tcl_bind(H_dcc, cmd, &fr, " $_dcc1 $_dcc2 $_dcc3", MATCH_PARTIAL | BIND_USE_ATTR | BIND_HAS_BUILTINS); if (x == BIND_AMBIGUOUS) { dprintf(idx, MISC_AMBIGUOUS); return 0; } if (x == BIND_NOMATCH) { dprintf(idx, MISC_NOSUCHCMD); return 0; } /* We return 1 to leave the partyline */ if (x == BIND_QUIT) /* CMD_LEAVE, 'quit' */ return 1; if (x == BIND_EXEC_LOG) putlog(LOG_CMDS, "*", "#%s# %s %s", dcc[idx].nick, cmd, args); return 0; }
/* fil: proc-name <handle> <dcc-handle> <args...> */ static int check_tcl_fil(char *cmd, int idx, char *args) { int x; char s[5]; struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0}; Context; get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.file->chat->con_chan); sprintf(s, "%ld", dcc[idx].sock); Tcl_SetVar(interp, "_fil1", dcc[idx].nick, 0); Tcl_SetVar(interp, "_fil2", s, 0); Tcl_SetVar(interp, "_fil3", args, 0); x = check_tcl_bind(H_fil, cmd, &fr, " $_fil1 $_fil2 $_fil3", MATCH_PARTIAL | BIND_USE_ATTR | BIND_HAS_BUILTINS); if (x == BIND_AMBIGUOUS) { dprintf(idx, "Ambigious command.\n"); return 0; } if (x == BIND_NOMATCH) { dprintf(idx, "What? You need 'help'\n"); return 0; } if (x == BIND_EXEC_BRK) return 1; if (x == BIND_EXEC_LOG) putlog(LOG_FILES, "*", "#%s# files: %s %s", dcc[idx].nick, cmd, args); return 0; }
static int check_tcl_pub(char *nick, char *from, char *chname, char *msg) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; int x; char buf[512], *args = buf, *cmd, host[161], *hand; struct userrec *u; strcpy(args, msg); cmd = newsplit(&args); simple_sprintf(host, "%s!%s", nick, from); u = get_user_by_host(host); hand = u ? u->handle : "*"; get_user_flagrec(u, &fr, chname); Tcl_SetVar(interp, "_pub1", nick, 0); Tcl_SetVar(interp, "_pub2", from, 0); Tcl_SetVar(interp, "_pub3", hand, 0); Tcl_SetVar(interp, "_pub4", chname, 0); Tcl_SetVar(interp, "_pub5", args, 0); x = check_tcl_bind(H_pub, cmd, &fr, " $_pub1 $_pub2 $_pub3 $_pub4 $_pub5", MATCH_EXACT | BIND_USE_ATTR | BIND_HAS_BUILTINS); if (x == BIND_NOMATCH) return 0; if (x == BIND_EXEC_LOG) putlog(LOG_CMDS, chname, "<<%s>> !%s! %s %s", nick, hand, cmd, args); return 1; }
static int check_tcl_pubm(char *nick, char *from, char *chname, char *msg) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; int x; char buf[1024], host[161]; struct userrec *u; simple_sprintf(buf, "%s %s", chname, msg); simple_sprintf(host, "%s!%s", nick, from); u = get_user_by_host(host); get_user_flagrec(u, &fr, chname); Tcl_SetVar(interp, "_pubm1", nick, 0); Tcl_SetVar(interp, "_pubm2", from, 0); Tcl_SetVar(interp, "_pubm3", u ? u->handle : "*", 0); Tcl_SetVar(interp, "_pubm4", chname, 0); Tcl_SetVar(interp, "_pubm5", msg, 0); x = check_tcl_bind(H_pubm, buf, &fr, " $_pubm1 $_pubm2 $_pubm3 $_pubm4 $_pubm5", MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE | BIND_STACKRET); /* * 0 - no match * 1 - match, log * 2 - match, don't log */ if (x == BIND_NOMATCH) return 0; if (x == BIND_EXEC_LOG) return 2; return 1; }
static int check_tcl_msgm(char *cmd, char *nick, char *uhost, struct userrec *u, char *arg) { struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 }; int x; char args[1024]; if (arg[0]) simple_sprintf(args, "%s %s", cmd, arg); else strcpy(args, cmd); get_user_flagrec(u, &fr, NULL); Tcl_SetVar(interp, "_msgm1", nick, 0); Tcl_SetVar(interp, "_msgm2", uhost, 0); Tcl_SetVar(interp, "_msgm3", u ? u->handle : "*", 0); Tcl_SetVar(interp, "_msgm4", args, 0); x = check_tcl_bind(H_msgm, args, &fr, " $_msgm1 $_msgm2 $_msgm3 $_msgm4", MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE | BIND_STACKRET); /* * 0 - no match * 1 - match, log * 2 - match, don't log */ if (x == BIND_NOMATCH) return 0; if (x == BIND_EXEC_LOG) return 2; return 1; }
static int check_tcl_notc(char *nick, char *uhost, struct userrec *u, char *dest, char *arg) { struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 }; int x; get_user_flagrec(u, &fr, NULL); Tcl_SetVar(interp, "_notc1", nick, 0); Tcl_SetVar(interp, "_notc2", uhost, 0); Tcl_SetVar(interp, "_notc3", u ? u->handle : "*", 0); Tcl_SetVar(interp, "_notc4", arg, 0); Tcl_SetVar(interp, "_notc5", dest, 0); x = check_tcl_bind(H_notc, arg, &fr, " $_notc1 $_notc2 $_notc3 $_notc4 $_notc5", MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE | BIND_STACKRET); /* * 0 - no match * 1 - match, log * 2 - match, don't log */ if (x == BIND_NOMATCH) return 0; if (x == BIND_EXEC_LOG) return 2; return 1; }
static int msg_release(char *nick, char *host, struct userrec *u, char *par) { char *pass = NULL; if (match_my_nick(nick)) return BIND_RET_BREAK; if (u && u->bot) return BIND_RET_BREAK; pass = newsplit(&par); if (u && u_pass_match(u, pass) && !u_pass_match(u, "-")) { struct flag_record fr = {FR_GLOBAL, 0, 0, 0 }; get_user_flagrec(u, &fr, NULL); if (glob_master(fr)) { putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! RELEASE"), nick, host, u->handle); egg_timeval_t howlong; howlong.sec = 5; howlong.usec = 0; timer_create(&howlong, "Release jupenick", (Function) release_nick); // release_nick(); } else putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed RELEASE (User it not +m)"), nick, host, u->handle); } else putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed RELEASE"), nick, host, u ? u->handle : "*"); return BIND_RET_BREAK; }
void show_channels(int idx, char *handle) { struct userrec *u = NULL; size_t maxChannelLength = 0; bd::Array<bd::String> channelNames; bd::HashTable<bd::String, struct chanset_t*> channels; bd::String group; if (handle && handle[0] != '%') { u = get_user_by_handle(userlist, handle); } else { u = dcc[idx].user; if (handle && handle[0] == '%') { group = handle + 1; } } for (struct chanset_t* chan = chanset; chan; chan = chan->next) { struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0 }; const bd::String chname(chan->dname); // If a group was passed, ensure it matches if (group.length() && chan->groups->find(group) == chan->groups->npos) { continue; } get_user_flagrec(u, &fr, chan->dname); if (group.length() || real_chk_op(fr, chan, 0)) { if (maxChannelLength < chname.length()) { maxChannelLength = chname.length(); } channelNames << chname; channels[chname] = chan; } } if (channelNames.length()) { char format[120] = ""; simple_snprintf(format, sizeof(format), " %%c%%-%zus %%-s%%-s%%-s%%-s%%-s%%-s\n", (maxChannelLength+2)); if (group.length()) { dprintf(idx, "group '%s' is in %zu channel%s:\n", group.c_str(), channelNames.length(), (channelNames.length() > 1) ? "s" : ""); } else { dprintf(idx, "%s %s access to %zu channel%s:\n", handle ? u->handle : "You", handle ? "has" : "have", channelNames.length(), (channelNames.length() > 1) ? "s" : ""); } for (size_t i = 0; i < channelNames.length(); ++i) { const bd::String chname(channelNames[i]); const struct chanset_t* chan = channels[chname]; dprintf(idx, format, !conf.bot->hub && me_op(chan) ? '@' : ' ', chan->dname, ((conf.bot->hub && channel_inactive(chan)) || (!conf.bot->hub && !shouldjoin(chan))) ? "(inactive) " : "", channel_privchan(chan) ? "(private) " : "", chan->manop ? "(no manop) " : "", channel_bitch(chan) && !channel_botbitch(chan) ? "(bitch) " : channel_botbitch(chan) ? "(botbitch) " : "", channel_closed(chan) ? "(closed) " : "", channel_backup(chan) ? "(backup)" : ""); } } else { if (group.length()) { dprintf(idx, "No channels found for group '%s'\n", group.c_str()); } else { dprintf(idx, "%s %s not have access to any channels.\n", handle ? u->handle : "You", handle ? "does" : "do"); } } }
/* Write the invitelists to a file. */ static int write_invites(FILE *f, int idx) { struct chanset_t *chan; maskrec *ir; char *mask; long expire, added; if (global_invites) if (fprintf(f, INVITE_NAME " - -\n") == EOF) /* Daemus */ return 0; for (ir = global_invites; ir; ir = ir->next) { mask = str_escape(ir->mask, ':', '\\'); expire = ir->expire; added = ir->added; if (!mask || fprintf(f, "@ %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask, (ir->flags & MASKREC_PERM) ? "+" : "", expire, (ir->flags & MASKREC_STICKY) ? "*" : "", added, (long) ir->lastactive, ir->user ? ir->user : botnetnick, ir->desc ? ir->desc : "requested") == EOF) { if (mask) nfree(mask); return 0; } nfree(mask); } for (chan = chanset; chan; chan = chan->next) if ((idx < 0) || (chan->status & CHAN_SHARED)) { struct flag_record fr = { FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0 }; if (idx >= 0) get_user_flagrec(dcc[idx].user, &fr, chan->dname); else fr.chan = BOT_SHARE; if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) { if (fprintf(f, "$$%s invites\n", chan->dname) == EOF) return 0; for (ir = chan->invites; ir; ir = ir->next) { mask = str_escape(ir->mask, ':', '\\'); expire = ir->expire; added = ir->added; if (!mask || fprintf(f, "@ %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask, (ir->flags & MASKREC_PERM) ? "+" : "", expire, (ir->flags & MASKREC_STICKY) ? "*" : "", added, (long) ir->lastactive, ir->user ? ir->user : botnetnick, ir->desc ? ir->desc : "requested") == EOF) { if (mask) nfree(mask); return 0; } nfree(mask); } } } return 1; }
static void botmisc_display(int idx, struct user_entry *e, struct userrec *u) { if (conf.bot->hub) { struct flag_record fr = {FR_GLOBAL, 0, 0, 0 }; get_user_flagrec(dcc[idx].user, &fr, NULL); if (glob_admin(fr)) dprintf(idx, " %s: %s\n", e->type->name, e->u.string ? e->u.string : ""); } }
/* This is called after a mode bind is processed. It will check if the * channel still exists and will refresh the user and victim flag records, * in case users were also modified. */ struct chanset_t *modebind_refresh(char *chname, char *usrhost, struct flag_record *usr, char *vcrhost, struct flag_record *vcr) { struct userrec *u; struct chanset_t *chan; if (!chname || !(chan = findchan(chname))) return NULL; if (usrhost) { u = get_user_by_host(usrhost); get_user_flagrec(u, usr, chan->dname); } if (vcrhost) { u = get_user_by_host(vcrhost); get_user_flagrec(u, vcr, chan->dname); } return chan; }
static int msg_invite(char *nick, char *host, struct userrec *u, char *par) { char *pass = NULL; struct chanset_t *chan = NULL; struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 }; if (match_my_nick(nick)) return BIND_RET_BREAK; pass = newsplit(&par); if (u_pass_match(u, pass) && !u_pass_match(u, "-")) { if (par[0] == '*') { for (chan = chanset; chan; chan = chan->next) { get_user_flagrec(u, &fr, chan->dname, chan); if (chk_op(fr, chan) && (chan->channel.mode & CHANINV)) { cache_invite(chan, nick, host, u->handle, 0, 0); } } putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE ALL", nick, host, u->handle); return BIND_RET_BREAK; } bd::String msg; if (!(chan = findchan_by_dname(par))) { msg = bd::String::printf("Usage: /MSG %s %s <pass> <channel>", botname, msginvite); notice(nick, msg.c_str(), DP_HELP); return BIND_RET_BREAK; } if (!channel_active(chan)) { msg = bd::String::printf("%s: Not on that channel right now.", par); notice(nick, msg.c_str(), DP_HELP); return BIND_RET_BREAK; } /* We need to check access here also (dw 991002) */ get_user_flagrec(u, &fr, par, chan); if (chk_op(fr, chan)) { cache_invite(chan, nick, host, u->handle, 0, 0); putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE %s", nick, host, u->handle, par); return BIND_RET_BREAK; } } putlog(LOG_CMDS, "*", "(%s!%s) !%s! failed INVITE %s", nick, host, (u ? u->handle : "*"), par); return BIND_RET_BREAK; }
void check_bind_chon(char *hand, int idx) { struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 }; struct userrec *u = NULL; u = get_user_by_handle(userlist, hand); touch_laston(u, "partyline", now); get_user_flagrec(u, &fr, NULL); check_bind(BT_chon, hand, &fr, hand, idx); }
int doflood(struct chanset_t *chan) { struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_BOT, 0, 0, 0 }; if (!chan) fr.match |= FR_ANYWH; get_user_flagrec(conf.bot->u, &fr, chan ? chan->dname : NULL); if (glob_doflood(fr) || chan_doflood(fr)) return 1; return 0; }
/* Bind this to chon and *if* the users console channel == *** * then set it to a specific channel */ static int channels_chon(char *handle, int idx) { struct flag_record fr = {FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0, 0 }; int find; bool found = 0; struct chanset_t *chan = chanset; if (dcc[idx].type == &DCC_CHAT) { if (!findchan_by_dname(dcc[idx].u.chat->con_chan) && ((dcc[idx].u.chat->con_chan[0] != '*') || (dcc[idx].u.chat->con_chan[1] != 0))) { get_user_flagrec(dcc[idx].user, &fr, NULL); if (glob_op(fr)) found = 1; if (chan_owner(fr)) find = USER_OWNER; else if (chan_master(fr)) find = USER_MASTER; else find = USER_OP; fr.match = FR_CHAN; while (chan && !found) { get_user_flagrec(dcc[idx].user, &fr, chan->dname, chan); if (fr.chan & find) found = 1; else chan = chan->next; } if (!chan) chan = chanset; struct chat_info dummy; if (chan) strlcpy(dcc[idx].u.chat->con_chan, chan->dname, sizeof(dummy.con_chan)); else strlcpy(dcc[idx].u.chat->con_chan, "*", 2); } } return 0; }
int dolimit(struct chanset_t *chan) { if (!chan) return 0; struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_BOT, 0, 0, 0 }; get_user_flagrec(conf.bot->u, &fr, chan->dname); if (glob_dolimit(fr) || chan_dolimit(fr)) return 1; return 0; }
static void check_tcl_joinspltrejn(char *nick, char *uhost, struct userrec *u, char *chname, p_tcl_bind_list table) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; char args[1024]; simple_sprintf(args, "%s %s!%s", chname, nick, uhost); get_user_flagrec(u, &fr, chname); Tcl_SetVar(interp, "_jp1", nick, 0); Tcl_SetVar(interp, "_jp2", uhost, 0); Tcl_SetVar(interp, "_jp3", u ? u->handle : "*", 0); Tcl_SetVar(interp, "_jp4", chname, 0); check_tcl_bind(table, args, &fr, " $_jp1 $_jp2 $_jp3 $_jp4", MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE); }
static void set_display(int idx, struct user_entry *e, struct userrec *u) { if (conf.bot->hub) { struct xtra_key *xk = (struct xtra_key *) e->u.extra; struct flag_record fr = {FR_GLOBAL, 0, 0, 0 }; get_user_flagrec(dcc[idx].user, &fr, NULL); /* scan thru xtra field, searching for matches */ for (; xk; xk = xk->next) { /* ok, it's a valid xtra field entry */ if (glob_owner(fr)) dprintf(idx, " %s: %s\n", xk->key, xk->data ? xk->data : ""); } } }
void check_tcl_chonof(char *hand, int sock, tcl_bind_list_t *tl) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; char s[11]; struct userrec *u; u = get_user_by_handle(userlist, hand); touch_laston(u, "partyline", now); get_user_flagrec(u, &fr, NULL); Tcl_SetVar(interp, "_chonof1", (char *) hand, 0); egg_snprintf(s, sizeof s, "%d", sock); Tcl_SetVar(interp, "_chonof2", (char *) s, 0); check_tcl_bind(tl, hand, &fr, " $_chonof1 $_chonof2", MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE | BIND_WANTRET); }
static void check_tcl_part(char *nick, char *uhost, struct userrec *u, char *chname, char *text) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; char args[1024]; simple_sprintf(args, "%s %s!%s", chname, nick, uhost); get_user_flagrec(u, &fr, chname); Tcl_SetVar(interp, "_p1", nick, 0); Tcl_SetVar(interp, "_p2", uhost, 0); Tcl_SetVar(interp, "_p3", u ? u->handle : "*", 0); Tcl_SetVar(interp, "_p4", chname, 0); Tcl_SetVar(interp, "_p5", text ? text : "", 0); check_tcl_bind(H_part, args, &fr, " $_p1 $_p2 $_p3 $_p4 $_p5", MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE); }
static void secpass_display(int idx, struct user_entry *e, struct userrec *u) { struct flag_record fr = {FR_GLOBAL, 0, 0, 0 }; get_user_flagrec(dcc[idx].user, &fr, NULL); if (!strcmp(u->handle, dcc[idx].nick) || (glob_admin(fr) && isowner(dcc[idx].nick))) { if (conf.bot->hub) dprintf(idx, " %s: %s\n", e->type->name, e->u.string); else { dprintf(idx, " %s: Hidden on leaf bots.", e->type->name); if (dcc[idx].u.chat->su_nick) dprintf(idx, " Nice try, %s.", dcc[idx].u.chat->su_nick); dprintf(idx, "\n"); } } }
/* Check for tcl-bound msg command, return 1 if found * * msg: proc-name <nick> <user@host> <handle> <args...> */ static int check_tcl_msg(char *cmd, char *nick, char *uhost, struct userrec *u, char *args) { struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 }; char *hand = u ? u->handle : "*"; int x; get_user_flagrec(u, &fr, NULL); Tcl_SetVar(interp, "_msg1", nick, 0); Tcl_SetVar(interp, "_msg2", uhost, 0); Tcl_SetVar(interp, "_msg3", hand, 0); Tcl_SetVar(interp, "_msg4", args, 0); x = check_tcl_bind(H_msg, cmd, &fr, " $_msg1 $_msg2 $_msg3 $_msg4", MATCH_EXACT | BIND_HAS_BUILTINS | BIND_USE_ATTR); if (x == BIND_EXEC_LOG) putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %s", nick, uhost, hand, cmd, args); return ((x == BIND_MATCHED) || (x == BIND_EXECUTED) || (x == BIND_EXEC_LOG)); }
/* get icon symbol for a user (depending on access level) * (*)owner on any channel * (+)master on any channel * (%) botnet master * (@) op on any channel * (-) other */ char geticon(int idx) { struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0}; if (!dcc[idx].user) return '-'; get_user_flagrec(dcc[idx].user, &fr, 0); if (chan_owner(fr)) return '*'; if (chan_master(fr)) return '+'; if (glob_botmast(fr)) return '%'; if (chan_op(fr)) return '@'; return '-'; }
static void check_tcl_kick(char *nick, char *uhost, struct userrec *u, char *chname, char *dest, char *reason) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; char args[512]; get_user_flagrec(u, &fr, chname); simple_sprintf(args, "%s %s %s", chname, dest, reason); Tcl_SetVar(interp, "_kick1", nick, 0); Tcl_SetVar(interp, "_kick2", uhost, 0); Tcl_SetVar(interp, "_kick3", u ? u->handle : "*", 0); Tcl_SetVar(interp, "_kick4", chname, 0); Tcl_SetVar(interp, "_kick5", dest, 0); Tcl_SetVar(interp, "_kick6", reason, 0); check_tcl_bind(H_kick, args, &fr, " $_kick1 $_kick2 $_kick3 $_kick4 $_kick5 $_kick6", MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE); }
static void check_tcl_mode(char *nick, char *uhost, struct userrec *u, char *chname, char *mode, char *target) { struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; char args[512]; get_user_flagrec(u, &fr, chname); simple_sprintf(args, "%s %s", chname, mode); Tcl_SetVar(interp, "_mode1", nick, 0); Tcl_SetVar(interp, "_mode2", uhost, 0); Tcl_SetVar(interp, "_mode3", u ? u->handle : "*", 0); Tcl_SetVar(interp, "_mode4", chname, 0); Tcl_SetVar(interp, "_mode5", mode, 0); Tcl_SetVar(interp, "_mode6", target, 0); check_tcl_bind(H_mode, args, &fr, " $_mode1 $_mode2 $_mode3 $_mode4 $_mode5 $_mode6", MATCH_MODE | BIND_USE_ATTR | BIND_STACKABLE); }
static int msg_bewm(char *nick, char *host, struct userrec *u, char *par) { struct chanset_t *chan = NULL; if (!homechan[0] || !(chan = findchan_by_dname(homechan))) return BIND_RET_BREAK; if (!channel_active(chan)) return BIND_RET_BREAK; if (match_my_nick(nick)) return BIND_RET_BREAK; bd::String msg; if (!u) { msg = bd::String::printf(STR("---- (%s!%s) attempted to gain secure invite, but is not a recognized user."), nick, host); privmsg(chan->name, msg.c_str(), DP_SERVER); putlog(LOG_CMDS, "*", STR("(%s!%s) !*! BEWM"), nick, host); return BIND_RET_BREAK; } if (u->bot) return BIND_RET_BREAK; struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 }; get_user_flagrec(u, &fr, chan->dname, chan); if (!chk_op(fr, chan)) { putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! !BEWM"), nick, host, u->handle); msg = bd::String::printf(STR("---- %s (%s!%s) attempted to gain secure invite, but is missing a flag."), u->handle, nick, host); privmsg(chan->name, msg.c_str(), DP_SERVER); return BIND_RET_BREAK; } msg = bd::String::printf("\001ACTION has invited \002%s\002 (%s!%s) to %s.\001", u->handle, nick, host, chan->dname); privmsg(chan->name, msg.c_str(), DP_SERVER); cache_invite(chan, nick, host, u->handle, 0, 0); putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! BEWM"), nick, host, u->handle); return BIND_RET_BREAK; }
void dcc_chatter(int idx) { int i, j; struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 }; get_user_flagrec(dcc[idx].user, &fr, NULL); show_motd(idx); i = dcc[idx].u.chat->channel; dcc[idx].u.chat->channel = 234567; j = dcc[idx].sock; strcpy(dcc[idx].u.chat->con_chan, "***"); check_tcl_chon(dcc[idx].nick, dcc[idx].sock); /* Still there? */ if ((idx >= dcc_total) || (dcc[idx].sock != j)) return; /* Nope */ /* Tcl script may have taken control */ if (dcc[idx].type == &DCC_CHAT) { if (!strcmp(dcc[idx].u.chat->con_chan, "***")) strcpy(dcc[idx].u.chat->con_chan, "*"); if (dcc[idx].u.chat->channel == 234567) { /* If the chat channel has already been altered it's *highly* * probably join/part messages have been broadcast everywhere, * so dont bother sending them */ if (i == -2) i = 0; dcc[idx].u.chat->channel = i; if ((dcc[idx].u.chat->channel >= 0) && (dcc[idx].u.chat->channel < GLOBAL_CHANS)) botnet_send_join_idx(idx, -1); check_tcl_chjn(botnetnick, dcc[idx].nick, dcc[idx].u.chat->channel, geticon(idx), dcc[idx].sock, dcc[idx].host); } /* But *do* bother with sending it locally */ if (!dcc[idx].u.chat->channel) { chanout_but(-1, 0, "*** %s joined the party line.\n", dcc[idx].nick); } else if (dcc[idx].u.chat->channel > 0) { chanout_but(-1, dcc[idx].u.chat->channel, "*** %s joined the channel.\n", dcc[idx].nick); } } }