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"); } } }
/* private returns 0 if user has access, and 1 if they dont because of +private * This function does not check if the user has "op" access, it only checks if the user is * restricted by +private for the channel */ int privchan(struct flag_record fr, struct chanset_t *chan, int type) { if (!chan || !channel_privchan(chan) || glob_bot(fr) || glob_owner(fr)) return 0; /* user is implicitly not restricted by +private, they may however be lacking other flags */ if (type == PRIV_OP) { /* |o implies all flags above. n| has access to all +private. Bots are exempt. */ if (chan_op(fr)) return 0; } else if (type == PRIV_VOICE) { if (chan_voice(fr) || chan_op(fr)) return 0; } return 1; /* user is restricted by +private */ }
void channels_report(int idx, int details) { int i; char s[1024] = "", s2[100] = ""; struct flag_record fr = {FR_CHAN | FR_GLOBAL, 0, 0, 0 }; for (struct chanset_t *chan = chanset; chan; chan = chan->next) { if (idx != DP_STDOUT) get_user_flagrec(dcc[idx].user, &fr, chan->dname, chan); if (!privchan(fr, chan, PRIV_OP) && ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr))) { s[0] = 0; if (chan_bitch(chan)) strlcat(s, "bitch, ", sizeof(s)); if (s[0]) s[strlen(s) - 2] = 0; if (!s[0]) strlcpy(s, "lurking", sizeof(s)); get_mode_protect(chan, s2, sizeof(s2)); if (channel_closed(chan)) { if (chan->closed_invite) strlcat(s2, "i", sizeof(s2)); if (chan->closed_private) strlcat(s2, "p", sizeof(s2)); } if (shouldjoin(chan)) { if (channel_active(chan)) { /* If it's a !chan, we want to display it's unique name too <cybah> */ if (chan->dname[0]=='!') { dprintf(idx, " %-20s: %2d member%s enforcing \"%s\" (%s), " "unique name %s\n", chan->dname, chan->channel.members, (chan->channel.members==1) ? "," : "s,", s2, s, chan->name); } else { dprintf(idx, " %-20s: %2d member%s enforcing \"%s\" (%s)\n", chan->dname, chan->channel.members, chan->channel.members == 1 ? "," : "s,", s2, s); } } else { if (!conf.bot->hub) dprintf(idx, " %-20s: (%s), enforcing \"%s\" (%s)\n", chan->dname, channel_pending(chan) ? "pending" : "not on channel", s2, s); else dprintf(idx, " %-20s: (%s), enforcing \"%s\" (%s)\n", chan->dname, "limbo", s2, s); } } else { dprintf(idx, " %-20s: channel is set +inactive\n", chan->dname); } if (details) { s[0] = 0; i = 0; i += my_strcpy(s + i, "dynamic "); if (channel_enforcebans(chan)) i += my_strcpy(s + i, "enforcebans "); if (channel_dynamicbans(chan)) i += my_strcpy(s + i, "dynamicbans "); if (!channel_nouserbans(chan)) i += my_strcpy(s + i, "userbans "); if (channel_bitch(chan)) i += my_strcpy(s + i, "bitch "); /* if (channel_revenge(chan)) i += my_strcpy(s + i, "revenge "); if (channel_revenge(chan)) i += my_strcpy(s + i, "revengebot "); */ if (channel_secret(chan)) i += my_strcpy(s + i, "secret "); if (channel_cycle(chan)) i += my_strcpy(s + i, "cycle "); if (channel_dynamicexempts(chan)) i += my_strcpy(s + i, "dynamicexempts "); if (!channel_nouserexempts(chan)) i += my_strcpy(s + i, "userexempts "); if (channel_dynamicinvites(chan)) i += my_strcpy(s + i, "dynamicinvites "); if (!channel_nouserinvites(chan)) i += my_strcpy(s + i, "userinvites "); if (!shouldjoin(chan)) i += my_strcpy(s + i, "inactive "); if (channel_nodesynch(chan)) i += my_strcpy(s + i, "nodesynch "); if (channel_closed(chan)) i += my_strcpy(s + i, "closed "); if (HAVE_TAKE && channel_take(chan)) i += my_strcpy(s + i, "take "); if (channel_voice(chan)) i += my_strcpy(s + i, "voice "); if (channel_autoop(chan)) i += my_strcpy(s + i, "autoop "); if (channel_meankicks(chan)) i += my_strcpy(s + i, "meankicks "); if (channel_rbl(chan)) i += my_strcpy(s + i, "rbl "); if (channel_voicebitch(chan)) i += my_strcpy(s + i, "voicebitch "); if (channel_protect(chan)) i += my_strcpy(s + i, "protect "); /* Chanflag template * if (channel_temp(chan)) * i += my_strcpy(s + i, "temp "); */ if (channel_nomassjoin(chan)) i += my_strcpy(s + i, "nomassjoin "); if (channel_botbitch(chan)) i += my_strcpy(s + i, "botbitch "); if (channel_backup(chan)) i += my_strcpy(s + i, "backup "); if (channel_fastop(chan)) i += my_strcpy(s + i, "fastop "); if (channel_privchan(chan)) i += my_strcpy(s + i, "private "); dprintf(idx, " Options: %s\n", s); if (chan->limitraise) dprintf(idx, " Raising limit +%d every 2 minutes\n", chan->limitraise); /* if (chan->revenge_mode) dprintf(idx, " revenge-mode %d\n", chan->revenge_mode); */ dprintf(idx, " Bans last %d mins.\n", chan->ban_time); dprintf(idx, " Exemptions last %d mins.\n", chan->exempt_time); dprintf(idx, " Invitations last %d mins.\n", chan->invite_time); } } } }
static void cmd_chaninfo(int idx, char *par) { char *chname = NULL, work[512] = ""; struct chanset_t *chan = NULL; int cnt = 0; if (!par[0]) { chname = dcc[idx].u.chat->con_chan; if (chname[0] == '*') { dprintf(idx, "Your console channel is invalid.\n"); return; } } else { chname = newsplit(&par); get_user_flagrec(dcc[idx].user, &user, chname); if (!glob_master(user) && !chan_master(user)) { dprintf(idx, "You don't have access to %s.\n", chname); return; } } if (!strcasecmp(chname, "default")) chan = chanset_default; else chan = findchan_by_dname(chname); if (!chan || (chan && privchan(user, chan, PRIV_OP))) { dprintf(idx, "No such channel.\n"); return; } else { char nick[HANDLEN + 1] = "", date[81] = ""; int deflag = 0; if (chan->added_ts) { strftime(date, sizeof date, "%c %Z", gmtime(&(chan->added_ts))); } else date[0] = 0; if (chan->added_by && chan->added_by[0]) strlcpy(nick, chan->added_by, sizeof(nick)); else nick[0] = 0; putlog(LOG_CMDS, "*", "#%s# chaninfo %s", dcc[idx].nick, chname); if (nick[0] && date[0]) dprintf(idx, "Settings for channel %s (Added %s by %s%s%s):\n", chan->dname, date, BOLD(idx), nick, BOLD_END(idx)); else dprintf(idx, "Settings for channel %s:\n", chan->dname); /* FIXME: SHOW_CHAR() here */ get_mode_protect(chan, work, sizeof(work)); dprintf(idx, "Protect modes (chanmode): %s\n", work[0] ? work : "None"); dprintf(idx, "Groups: %s\n", chan->groups && chan->groups->length() ? static_cast<bd::String>(chan->groups->join(" ")).c_str() : "None"); dprintf(idx, "FiSH Key: %s\n", chan->fish_key[0] ? chan->fish_key : "not set"); // dprintf(idx, "Protect topic (topic) : %s\n", chan->topic[0] ? chan->topic : ""); /* Chanchar template * dprintf(idx, "String temp: %s\n", chan->temp[0] ? chan->temp : "NULL"); */ dprintf(idx, "Channel flags:\n"); work[0] = 0; SHOW_FLAG("autoop", channel_autoop(chan)); SHOW_FLAG("backup", channel_backup(chan)); SHOW_FLAG("bitch", channel_bitch(chan)); SHOW_FLAG("botbitch", channel_botbitch(chan)); SHOW_FLAG("closed", channel_closed(chan)); SHOW_FLAG("cycle", channel_cycle(chan)); SHOW_FLAG("enforcebans", channel_enforcebans(chan)); SHOW_FLAG("fastop", channel_fastop(chan)); SHOW_FLAG("floodban", channel_floodban(chan)); SHOW_FLAG("inactive", channel_inactive(chan)); SHOW_FLAG("nodesynch", channel_nodesynch(chan)); SHOW_FLAG("private", channel_privchan(chan)); SHOW_FLAG("protect", channel_protect(chan)); SHOW_FLAG("rbl", channel_rbl(chan)); if (HAVE_TAKE) SHOW_FLAG("take", channel_take(chan)); SHOW_FLAG("voice", channel_voice(chan)); SHOW_FLAG("voicebitch", channel_voicebitch(chan)); SHOW_FLAG("", 0); SHOW_FLAG("dynamicbans", channel_dynamicbans(chan)); SHOW_FLAG("userbans", !channel_nouserbans(chan)); SHOW_FLAG("dynamicexempts", channel_dynamicexempts(chan)); SHOW_FLAG("userexempts", !channel_nouserexempts(chan)); SHOW_FLAG("dynamicinvites", channel_dynamicinvites(chan)); SHOW_FLAG("userinvites", !channel_nouserinvites(chan)); SHOW_FLAG("", 0); work[0] = 0; /* Chanflag template * SHOW_FLAG("template", channel_template(chan)); * also include %ctemp in dprintf. */ work[0] = cnt = 0; /* Chanint template * SHOW_INT("Desc: ", integer, "YES", "NO"); */ dprintf(idx, "Channel settings:\n"); deflag = chan->bad_cookie; SHOW_INT("Auto-delay: ", chan->auto_delay, NULL, "None"); SHOW_INT("Bad-cookie:" , chan->bad_cookie, DEFLAG_STR, "Ignore"); SHOW_INT("Ban-time: ", chan->ban_time, NULL, "Forever"); SHOW_INT("Ban-type: ", chan->ban_type, NULL, "3"); SHOW_INT("Closed-ban: ", chan->closed_ban, NULL, "Don't!"); SHOW_INT("Closed-invite:", chan->closed_invite, NULL, "Don't!"); SHOW_INT("Closed-Private:", chan->closed_private, NULL, "Don't!"); SHOW_INT("Closed-Exempt:", chan->closed_exempt_mode, F_STR(chan->closed_exempt_mode), "None"); SHOW_INT("Exempt-time: ", chan->exempt_time, NULL, "Forever"); SHOW_INT("Flood-exempt: ", chan->flood_exempt_mode, F_STR(chan->flood_exempt_mode), "None"); SHOW_INT("Flood-lock-time: ", chan->flood_lock_time, NULL, "Don't"); SHOW_INT("Caps-Limit(%): ", chan->capslimit, NULL, "None"); SHOW_INT("Color-Limit: ", chan->colorlimit, NULL, "None"); SHOW_INT("Invite-time: ", chan->invite_time, NULL, "Forever"); SHOW_INT("Knock: ", chan->knock_flags, F_STR(chan->knock_flags), "None"); SHOW_INT("Limit raise (limit): ", chan->limitraise, NULL, "Disabled"); deflag = chan->manop; SHOW_INT("Manop: ", chan->manop, DEFLAG_STR, "Ignore"); deflag = chan->mdop; SHOW_INT("Mdop: ", chan->mdop, DEFLAG_STR, "Ignore"); deflag = chan->mop; SHOW_INT("Mop: ", chan->mop, DEFLAG_STR, "Ignore"); deflag = chan->revenge; SHOW_INT("Revenge: ", chan->revenge, DEFLAG_STR, "Ignore"); SHOW_INT("Protect-backup: ", chan->protect_backup, "Do!", "Don't!"); SHOW_INT("Voice-non-ident: ", chan->voice_non_ident, "Do!", "Don't!"); SHOW_INT("Voice-moderate:", chan->voice_moderate, "Do!", "Don't!"); dprintf(idx, "Flood settings: chan bytes ctcp join kick deop nick mjoin mpub mbytes mctcp\n"); dprintf(idx, " number: %3d %4d %3d %3d %3d %3d %3d %3d %3d %4d %3d\n", chan->flood_pub_thr, chan->flood_bytes_thr, chan->flood_ctcp_thr, chan->flood_join_thr, chan->flood_kick_thr, chan->flood_deop_thr, chan->flood_nick_thr, chan->flood_mjoin_thr, chan->flood_mpub_thr, chan->flood_mbytes_thr, chan->flood_mctcp_thr); dprintf(idx, " time : %3u %4u %3u %3u %3u %3u %3u %3u %3u %4u %4u\n", chan->flood_pub_time, chan->flood_bytes_time, chan->flood_ctcp_time, chan->flood_join_time, chan->flood_kick_time, chan->flood_deop_time, chan->flood_nick_time, chan->flood_mjoin_time, chan->flood_mpub_time, chan->flood_mbytes_time, chan->flood_mctcp_time); } }