Go to the source code of this file.
Defines | |
#define | PLUS 0x01 |
#define | MINUS 0x02 |
#define | CHOP 0x04 |
#define | BAN 0x08 |
#define | VOICE 0x10 |
#define | EXEMPT 0x20 |
#define | INVITE 0x40 |
#define | CHHOP 0x80 |
Functions | |
struct chanset_t * | modebind_refresh (char *chname, char *usrhost, struct flag_record *usr, char *vcrhost, struct flag_record *vcr) |
static void | flush_mode (struct chanset_t *chan, int pri) |
static void | real_add_mode (struct chanset_t *chan, char plus, char mode, char *op) |
static void | got_key (struct chanset_t *chan, char *nick, char *from, char *key) |
static void | got_op (struct chanset_t *chan, char *nick, char *from, char *who, struct userrec *opu, struct flag_record *opper) |
static void | got_halfop (struct chanset_t *chan, char *nick, char *from, char *who, struct userrec *opu, struct flag_record *opper) |
static void | got_deop (struct chanset_t *chan, char *nick, char *from, char *who, struct userrec *opu) |
static void | got_dehalfop (struct chanset_t *chan, char *nick, char *from, char *who, struct userrec *opu) |
static void | got_ban (struct chanset_t *chan, char *nick, char *from, char *who, char *ch, struct userrec *u) |
static void | got_unban (struct chanset_t *chan, char *nick, char *from, char *who, char *ch, struct userrec *u) |
static void | got_exempt (struct chanset_t *chan, char *nick, char *from, char *who, char *ch, struct userrec *u) |
static void | got_unexempt (struct chanset_t *chan, char *nick, char *from, char *who, char *ch, struct userrec *u) |
static void | got_invite (struct chanset_t *chan, char *nick, char *from, char *who, char *ch, struct userrec *u) |
static void | got_uninvite (struct chanset_t *chan, char *nick, char *from, char *who, char *ch, struct userrec *u) |
static int | gotmode (char *from, char *origmsg) |
Variables | |
static int | reversing = 0 |
static struct flag_record | user = { 0x00000001 | 0x00000004 , 0, 0, 0, 0, 0 } |
static struct flag_record | victim = { 0x00000001 | 0x00000004 , 0, 0, 0, 0, 0 } |
#define BAN 0x08 |
Definition at line 34 of file mode.c.
Referenced by flush_mode(), and real_add_mode().
#define CHHOP 0x80 |
Definition at line 38 of file mode.c.
Referenced by flush_mode(), and real_add_mode().
#define CHOP 0x04 |
Definition at line 33 of file mode.c.
Referenced by flush_mode(), and real_add_mode().
#define EXEMPT 0x20 |
Definition at line 36 of file mode.c.
Referenced by flush_mode(), and real_add_mode().
#define INVITE 0x40 |
Definition at line 37 of file mode.c.
Referenced by flush_mode(), and real_add_mode().
#define MINUS 0x02 |
Definition at line 32 of file mode.c.
Referenced by flush_mode(), and real_add_mode().
#define PLUS 0x01 |
Definition at line 31 of file mode.c.
Referenced by flush_mode(), and real_add_mode().
#define VOICE 0x10 |
Definition at line 35 of file mode.c.
Referenced by real_add_mode().
static void flush_mode | ( | struct chanset_t * | chan, | |
int | pri | |||
) | [static] |
Definition at line 67 of file mode.c.
References BAN, chanset_t::bytes, CHHOP, CHOP, chanset_t::cmode, chanset_t::compat, DP_MODE, DP_SERVER, dprintf, egg_strcatn, EXEMPT, INVITE, chanset_t::key, chanset_t::limit, MINUS, chanset_t::mns, modesperline, chanset_t::name, nfree, NULL, chanset_t::op, chanset_t::pls, PLUS, QUICK, chanset_t::rmkey, and chanset_t::type.
Referenced by real_add_mode().
00068 { 00069 char *p, out[512], post[512]; 00070 size_t postsize = sizeof(post); 00071 int i, plus = 2; /* 0 = '-', 1 = '+', 2 = none */ 00072 00073 p = out; 00074 post[0] = 0, postsize--; 00075 00076 if (chan->mns[0]) { 00077 *p++ = '-', plus = 0; 00078 for (i = 0; i < strlen(chan->mns); i++) 00079 *p++ = chan->mns[i]; 00080 chan->mns[0] = 0; 00081 } 00082 00083 if (chan->pls[0]) { 00084 *p++ = '+', plus = 1; 00085 for (i = 0; i < strlen(chan->pls); i++) 00086 *p++ = chan->pls[i]; 00087 chan->pls[0] = 0; 00088 } 00089 00090 chan->bytes = 0; 00091 chan->compat = 0; 00092 00093 /* +k or +l ? */ 00094 if (chan->key && !chan->rmkey) { 00095 if (plus != 1) { 00096 *p++ = '+', plus = 1; 00097 } 00098 *p++ = 'k'; 00099 00100 postsize -= egg_strcatn(post, chan->key, sizeof(post)); 00101 postsize -= egg_strcatn(post, " ", sizeof(post)); 00102 00103 nfree(chan->key), chan->key = NULL; 00104 } 00105 00106 /* max +l is signed 2^32 on IRCnet at least... so makesure we've got at least 00107 * a 13 char buffer for '-2147483647 \0'. We'll be overwriting the existing 00108 * terminating null in 'post', so makesure postsize >= 12. 00109 */ 00110 if (chan->limit != 0 && postsize >= 12) { 00111 if (plus != 1) { 00112 *p++ = '+', plus = 1; 00113 } 00114 *p++ = 'l'; 00115 00116 /* 'sizeof(post) - 1' is used because we want to overwrite the old null */ 00117 postsize -= 00118 sprintf(&post[(sizeof(post) - 1) - postsize], "%d ", chan->limit); 00119 00120 chan->limit = 0; 00121 } 00122 00123 /* -k ? */ 00124 if (chan->rmkey) { 00125 if (plus) { 00126 *p++ = '-', plus = 0; 00127 } 00128 *p++ = 'k'; 00129 00130 postsize -= egg_strcatn(post, chan->rmkey, sizeof(post)); 00131 postsize -= egg_strcatn(post, " ", sizeof(post)); 00132 00133 nfree(chan->rmkey), chan->rmkey = NULL; 00134 } 00135 00136 /* Do -{b,e,I} before +{b,e,I} to avoid the server ignoring overlaps */ 00137 for (i = 0; i < modesperline; i++) { 00138 if ((chan->cmode[i].type & MINUS) && postsize > strlen(chan->cmode[i].op)) { 00139 if (plus) { 00140 *p++ = '-', plus = 0; 00141 } 00142 00143 *p++ = ((chan->cmode[i].type & BAN) ? 'b' : 00144 ((chan->cmode[i].type & CHOP) ? 'o' : 00145 ((chan->cmode[i].type & CHHOP) ? 'h' : 00146 ((chan->cmode[i].type & EXEMPT) ? 'e' : 00147 ((chan->cmode[i].type & INVITE) ? 'I' : 'v'))))); 00148 00149 postsize -= egg_strcatn(post, chan->cmode[i].op, sizeof(post)); 00150 postsize -= egg_strcatn(post, " ", sizeof(post)); 00151 00152 nfree(chan->cmode[i].op), chan->cmode[i].op = NULL; 00153 chan->cmode[i].type = 0; 00154 } 00155 } 00156 00157 /* now do all the + modes... */ 00158 for (i = 0; i < modesperline; i++) { 00159 if ((chan->cmode[i].type & PLUS) && postsize > strlen(chan->cmode[i].op)) { 00160 if (plus != 1) { 00161 *p++ = '+', plus = 1; 00162 } 00163 00164 *p++ = ((chan->cmode[i].type & BAN) ? 'b' : 00165 ((chan->cmode[i].type & CHOP) ? 'o' : 00166 ((chan->cmode[i].type & CHHOP) ? 'h' : 00167 ((chan->cmode[i].type & EXEMPT) ? 'e' : 00168 ((chan->cmode[i].type & INVITE) ? 'I' : 'v'))))); 00169 00170 postsize -= egg_strcatn(post, chan->cmode[i].op, sizeof(post)); 00171 postsize -= egg_strcatn(post, " ", sizeof(post)); 00172 00173 nfree(chan->cmode[i].op), chan->cmode[i].op = NULL; 00174 chan->cmode[i].type = 0; 00175 } 00176 } 00177 00178 /* remember to terminate the buffer ('out')... */ 00179 *p = 0; 00180 00181 if (post[0]) { 00182 /* remove the trailing space... */ 00183 size_t index = (sizeof(post) - 1) - postsize; 00184 00185 if (index > 0 && post[index - 1] == ' ') 00186 post[index - 1] = 0; 00187 00188 egg_strcatn(out, " ", sizeof(out)); 00189 egg_strcatn(out, post, sizeof(out)); 00190 } 00191 if (out[0]) { 00192 if (pri == QUICK) 00193 dprintf(DP_MODE, "MODE %s %s\n", chan->name, out); 00194 else 00195 dprintf(DP_SERVER, "MODE %s %s\n", chan->name, out); 00196 } 00197 }
static void got_ban | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
char * | ch, | |||
struct userrec * | u | |||
) | [static] |
Definition at line 758 of file mode.c.
References add_mode, chanset_t::bans, botname, botuserhost, bounce_bans, bounce_modes, chan_deop, chan_friend, chan_master, chan_op, chanset_t::channel, channel_enforcebans, channel_nouserbans, channel_pending, check_tcl_mode(), maskrec::desc, chanset_t::dname, egg_snprintf, get_user_by_host, get_user_flagrec, glob_bot, glob_friend, glob_master, glob_op, global_bans, HALFOP_CANTDOMODE, IRC_BANNED, IRC_PREBANNED, isexempted, kick_all(), maskrec::mask, match_addr, match_my_nick(), chan_t::member, modebind_refresh(), newban, maskrec::next, memstruct::next, memstruct::nick, NULL, refresh_exempt(), reversing, u_equals_mask(), UHOSTLEN, and memstruct::userhost.
Referenced by gotmode().
00760 { 00761 char me[UHOSTLEN], s[UHOSTLEN], s1[UHOSTLEN]; 00762 memberlist *m; 00763 struct userrec *targ; 00764 00765 egg_snprintf(me, sizeof me, "%s!%s", botname, botuserhost); 00766 egg_snprintf(s, sizeof s, "%s!%s", nick, from); 00767 newban(chan, who, s); 00768 check_tcl_mode(nick, from, u, chan->dname, "+b", who); 00769 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 00770 return; 00771 00772 if (channel_pending(chan) || HALFOP_CANTDOMODE('b')) 00773 return; 00774 00775 if (match_addr(who, me) && !isexempted(chan, me)) { 00776 add_mode(chan, '-', 'b', who); 00777 reversing = 1; 00778 return; 00779 } 00780 if (!match_my_nick(nick)) { 00781 if (nick[0] && channel_nouserbans(chan) && !glob_bot(user) && 00782 !glob_master(user) && !chan_master(user)) { 00783 add_mode(chan, '-', 'b', who); 00784 return; 00785 } 00786 for (m = chan->channel.member; m && m->nick[0]; m = m->next) { 00787 egg_snprintf(s1, sizeof s1, "%s!%s", m->nick, m->userhost); 00788 if (match_addr(who, s1)) { 00789 targ = get_user_by_host(s1); 00790 if (targ) { 00791 get_user_flagrec(targ, &victim, chan->dname); 00792 if ((glob_friend(victim) || (glob_op(victim) && !chan_deop(victim)) || 00793 chan_friend(victim) || chan_op(victim)) && !glob_master(user) && 00794 !glob_bot(user) && !chan_master(user) && !isexempted(chan, s1)) { 00795 add_mode(chan, '-', 'b', who); 00796 return; 00797 } 00798 } 00799 } 00800 } 00801 } 00802 refresh_exempt(chan, who); 00803 if (nick[0] && channel_enforcebans(chan)) { 00804 register maskrec *b; 00805 int cycle; 00806 char resn[512] = ""; 00807 00808 for (cycle = 0; cycle < 2; cycle++) { 00809 for (b = cycle ? chan->bans : global_bans; b; b = b->next) { 00810 if (match_addr(b->mask, who)) { 00811 if (b->desc && b->desc[0] != '@') 00812 egg_snprintf(resn, sizeof resn, "%s %s", IRC_PREBANNED, b->desc); 00813 else 00814 resn[0] = 0; 00815 } 00816 } 00817 } 00818 kick_all(chan, who, resn[0] ? resn : IRC_BANNED, 00819 match_my_nick(nick) ? 0 : 1); 00820 } 00821 if (!nick[0] && (bounce_bans || bounce_modes) && 00822 (!u_equals_mask(global_bans, who) || !u_equals_mask(chan->bans, who))) 00823 add_mode(chan, '-', 'b', who); 00824 }
static void got_dehalfop | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
struct userrec * | opu | |||
) | [static] |
Definition at line 688 of file mode.c.
References add_mode, CHAN_BADCHANMODE, chan_dehalfop, chan_friend, chan_halfop, chan_hasop, chan_master, CHAN_PEND, CHANHALFOP, channel_bitch, channel_pending, channel_protectfriends, channel_protecthalfops, CHANVOICE, check_tcl_mode(), chanset_t::dname, FAKEHALFOP, memstruct::flags, get_user_by_host, get_user_flagrec, glob_bot, glob_dehalfop, glob_friend, glob_halfop, glob_master, HALFOP_CANDOMODE, ismember, LOG_MISC, LOG_MODES, match_my_nick(), modebind_refresh(), chanset_t::name, memstruct::nick, putlog, refresh_who_chan(), reversing, rfc_casecmp, SENTDEHALFOP, simple_sprintf, chanset_t::status, STOPWHO, UHOSTLEN, memstruct::userhost, and WASHALFOP.
Referenced by gotmode().
00690 { 00691 memberlist *m; 00692 char ch[sizeof chan->name]; 00693 char s[UHOSTLEN], s1[UHOSTLEN]; 00694 struct userrec *u; 00695 int had_halfop; 00696 00697 m = ismember(chan, who); 00698 if (!m) { 00699 if (channel_pending(chan)) 00700 return; 00701 putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, who); 00702 chan->status |= CHAN_PEND; 00703 refresh_who_chan(chan->name); 00704 return; 00705 } 00706 00707 strcpy(ch, chan->name); 00708 simple_sprintf(s, "%s!%s", m->nick, m->userhost); 00709 simple_sprintf(s1, "%s!%s", nick, from); 00710 u = get_user_by_host(s); 00711 get_user_flagrec(u, &victim, chan->dname); 00712 00713 had_halfop = chan_hasop(m); 00714 /* Flags need to be set correctly right from the beginning now, so that 00715 * add_mode() doesn't get irritated. 00716 */ 00717 m->flags &= ~(CHANHALFOP | SENTDEHALFOP | FAKEHALFOP); 00718 check_tcl_mode(nick, from, opu, chan->dname, "-h", who); 00719 if (!(chan = modebind_refresh(ch, from, &user, s, &victim)) || 00720 !(m = ismember(chan, who))) 00721 return; 00722 /* Check comments in got_op() (drummer) */ 00723 m->flags &= ~WASHALFOP; 00724 00725 if (channel_pending(chan)) 00726 return; 00727 00728 /* Dehalfop'd someone on my oplist? */ 00729 if (HALFOP_CANDOMODE('h')) { 00730 int ok = 1; 00731 00732 if (!glob_dehalfop(victim) && !chan_dehalfop(victim)) { 00733 if (channel_protecthalfops(chan) && (glob_master(victim) || 00734 chan_master(victim) || glob_halfop(victim) || chan_halfop(victim))) 00735 ok = 0; 00736 else if (channel_protectfriends(chan) && (glob_friend(victim) || 00737 chan_friend(victim))) 00738 ok = 0; 00739 } 00740 if ((reversing || !ok) && had_halfop && !match_my_nick(nick) && 00741 rfc_casecmp(who, nick) && !match_my_nick(who) && !glob_master(user) && 00742 !chan_master(user) && !glob_bot(user) && ((chan_halfop(victim) || 00743 (glob_halfop(victim) && !chan_dehalfop(victim))) || 00744 !channel_bitch(chan))) 00745 add_mode(chan, '+', 'h', who); 00746 } 00747 00748 if (!nick[0]) 00749 putlog(LOG_MODES, chan->dname, "TS resync (%s): %s deopped by %s", 00750 chan->dname, who, from); 00751 if (!(m->flags & (CHANVOICE | STOPWHO))) { 00752 chan->status |= CHAN_PEND; 00753 refresh_who_chan(chan->name); 00754 m->flags |= STOPWHO; 00755 } 00756 }
static void got_deop | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
struct userrec * | opu | |||
) | [static] |
Definition at line 595 of file mode.c.
References add_mode, CHAN_BADCHANMODE, chan_deop, chan_friend, chan_hasop, chan_master, chan_op, CHAN_PEND, CHANHALFOP, chanset_t::channel, channel_bitch, channel_pending, channel_protectfriends, channel_protectops, CHANOP, CHANVOICE, check_tcl_mode(), check_tcl_need(), detect_chan_flood(), chanset_t::dname, do_tcl, FAKEOP, memstruct::flags, FLOOD_DEOP, get_user_by_host, get_user_flagrec, glob_bot, glob_deop, glob_friend, glob_master, glob_op, HALFOP_CANDOMODE, ismember, LOG_MISC, LOG_MODES, match_my_nick(), maybe_revenge(), chan_t::member, modebind_refresh(), chanset_t::name, chanset_t::need_op, memstruct::next, memstruct::nick, putlog, refresh_who_chan(), REVENGE_DEOP, reversing, rfc_casecmp, SENTDEOP, SENTDEVOICE, SENTKICK, SENTOP, SENTVOICE, simple_sprintf, chanset_t::status, STOPWHO, UHOSTLEN, memstruct::userhost, and WASOP.
Referenced by gotmode().
00597 { 00598 memberlist *m; 00599 char ch[sizeof chan->name]; 00600 char s[UHOSTLEN], s1[UHOSTLEN]; 00601 struct userrec *u; 00602 int had_halfop; 00603 00604 m = ismember(chan, who); 00605 if (!m) { 00606 if (channel_pending(chan)) 00607 return; 00608 putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, who); 00609 chan->status |= CHAN_PEND; 00610 refresh_who_chan(chan->name); 00611 return; 00612 } 00613 00614 strcpy(ch, chan->name); 00615 simple_sprintf(s, "%s!%s", m->nick, m->userhost); 00616 simple_sprintf(s1, "%s!%s", nick, from); 00617 u = get_user_by_host(s); 00618 get_user_flagrec(u, &victim, chan->dname); 00619 00620 had_halfop = chan_hasop(m); 00621 /* Flags need to be set correctly right from the beginning now, so that 00622 * add_mode() doesn't get irritated. 00623 */ 00624 m->flags &= ~(CHANOP | SENTDEOP | FAKEOP); 00625 check_tcl_mode(nick, from, opu, chan->dname, "-o", who); 00626 if (!(chan = modebind_refresh(ch, from, &user, s, &victim)) || 00627 !(m = ismember(chan, who))) 00628 return; 00629 m->flags &= ~WASOP; 00630 00631 if (channel_pending(chan)) 00632 return; 00633 00634 if (HALFOP_CANDOMODE('o')) { 00635 int ok = 1; 00636 00637 if (!glob_deop(victim) && !chan_deop(victim)) { 00638 if (channel_protectops(chan) && (glob_master(victim) || 00639 chan_master(victim) || glob_op(victim) || chan_op(victim))) 00640 ok = 0; 00641 else if (channel_protectfriends(chan) && (glob_friend(victim) || 00642 chan_friend(victim))) 00643 ok = 0; 00644 } 00645 if ((reversing || !ok) && had_halfop && !match_my_nick(nick) && 00646 rfc_casecmp(who, nick) && !match_my_nick(who) && !glob_master(user) && 00647 !chan_master(user) && !glob_bot(user) && ((chan_op(victim) || 00648 (glob_op(victim) && !chan_deop(victim))) || !channel_bitch(chan))) 00649 add_mode(chan, '+', 'o', who); 00650 } 00651 00652 if (!nick[0]) 00653 putlog(LOG_MODES, chan->dname, "TS resync (%s): %s deopped by %s", 00654 chan->dname, who, from); 00655 00656 /* Check for mass deop */ 00657 if (nick[0]) 00658 detect_chan_flood(nick, from, s1, chan, FLOOD_DEOP, who); 00659 00660 /* Having op hides your +v and +h status -- so now that someone's lost ops, 00661 * check to see if they have +v or +h 00662 */ 00663 if (!(m->flags & (CHANVOICE | CHANHALFOP | STOPWHO))) { 00664 chan->status |= CHAN_PEND; 00665 refresh_who_chan(chan->name); 00666 m->flags |= STOPWHO; 00667 } 00668 00669 /* Was the bot deopped? */ 00670 if (match_my_nick(who)) { 00671 /* Cancel any pending kicks and modes */ 00672 memberlist *m2; 00673 00674 for (m2 = chan->channel.member; m2 && m2->nick[0]; m2 = m2->next) 00675 m2->flags &= ~(SENTKICK | SENTDEOP | SENTOP | SENTVOICE | SENTDEVOICE); 00676 00677 check_tcl_need(chan->dname, "op"); 00678 if (chan->need_op[0]) 00679 do_tcl("need-op", chan->need_op); 00680 if (!nick[0]) 00681 putlog(LOG_MODES, chan->dname, "TS resync deopped me on %s :(", 00682 chan->dname); 00683 } 00684 if (nick[0]) 00685 maybe_revenge(chan, s1, s, REVENGE_DEOP); 00686 }
static void got_exempt | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
char * | ch, | |||
struct userrec * | u | |||
) | [static] |
Definition at line 859 of file mode.c.
References add_mode, bounce_exempts, bounce_modes, chan_master, channel_nouserexempts, channel_pending, check_tcl_mode(), chanset_t::dname, chanset_t::exempts, glob_bot, glob_master, global_exempts, HALFOP_CANTDOMODE, match_my_nick(), modebind_refresh(), newexempt, NULL, reversing, simple_sprintf, u_equals_mask(), and UHOSTLEN.
Referenced by gotmode().
00861 { 00862 char s[UHOSTLEN]; 00863 00864 simple_sprintf(s, "%s!%s", nick, from); 00865 newexempt(chan, who, s); 00866 check_tcl_mode(nick, from, u, chan->dname, "+e", who); 00867 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 00868 return; 00869 00870 if (channel_pending(chan) || HALFOP_CANTDOMODE('e')) 00871 return; 00872 00873 if (!match_my_nick(nick)) { 00874 if (nick[0] && channel_nouserexempts(chan) && !glob_bot(user) && 00875 !glob_master(user) && !chan_master(user)) { 00876 add_mode(chan, '-', 'e', who); 00877 return; 00878 } 00879 if (!nick[0] && bounce_modes) 00880 reversing = 1; 00881 } 00882 if (reversing || (bounce_exempts && !nick[0] && 00883 (!u_equals_mask(global_exempts, who) || 00884 !u_equals_mask(chan->exempts, who)))) 00885 add_mode(chan, '-', 'e', who); 00886 }
static void got_halfop | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
struct userrec * | opu, | |||
struct flag_record * | opper | |||
) | [static] |
Definition at line 498 of file mode.c.
References add_mode, chan_autohalfop, CHAN_BADCHANMODE, chan_dehalfop, chan_exempt, chan_halfop, chan_master, chan_op, CHAN_PEND, chan_washalfop, chan_washalfoptest, CHANHALFOP, channel_autohalfop, channel_bitch, channel_pending, check_tcl_mode(), chanset_t::dname, FAKEHALFOP, memstruct::flags, get_user_by_host, get_user_flagrec, glob_autohalfop, glob_bot, glob_dehalfop, glob_exempt, glob_halfop, glob_master, glob_op, glob_washalfoptest, HALFOP_CANDOMODE, ismember, LOG_MISC, match_my_nick(), me_halfop(), me_op(), modebind_refresh(), chanset_t::name, memstruct::nick, putlog, recheck_channel(), refresh_who_chan(), reversing, SENTHALFOP, simple_sprintf, chanset_t::status, chanset_t::stopnethack_mode, UHOSTLEN, memstruct::user, memstruct::userhost, and WASHALFOP.
Referenced by gotmode().
00501 { 00502 memberlist *m; 00503 char s[UHOSTLEN]; 00504 char ch[sizeof chan->name]; 00505 struct userrec *u; 00506 int check_chan = 0; 00507 int snm = chan->stopnethack_mode; 00508 00509 m = ismember(chan, who); 00510 if (!m) { 00511 if (channel_pending(chan)) 00512 return; 00513 putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, who); 00514 chan->status |= CHAN_PEND; 00515 refresh_who_chan(chan->name); 00516 return; 00517 } 00518 00519 /* Did *I* just get halfopped? */ 00520 if (!me_op(chan) && !me_halfop(chan) && match_my_nick(who)) 00521 check_chan = 1; 00522 00523 strcpy(ch, chan->name); 00524 simple_sprintf(s, "%s!%s", m->nick, m->userhost); 00525 if (!m->user) 00526 u = get_user_by_host(s); 00527 else 00528 u = m->user; 00529 00530 get_user_flagrec(u, &victim, chan->dname); 00531 /* Flags need to be set correctly right from the beginning now, so that 00532 * add_mode() doesn't get irritated. 00533 */ 00534 m->flags |= CHANHALFOP; 00535 check_tcl_mode(nick, from, opu, chan->dname, "+h", who); 00536 if (!(chan = modebind_refresh(ch, from, opper, s, &victim)) || 00537 !(m = ismember(chan, who))) 00538 return; 00539 m->flags &= ~SENTHALFOP; 00540 00541 if (channel_pending(chan)) 00542 return; 00543 00544 if (nick[0] && HALFOP_CANDOMODE('h') && !match_my_nick(who) && 00545 !match_my_nick(nick)) { 00546 if (channel_bitch(chan) && !(glob_master(*opper) || glob_bot(*opper)) && 00547 !chan_master(*opper) && !(glob_halfop(victim) || glob_op(victim) || 00548 glob_bot(victim)) && !chan_op(victim) && !chan_halfop(victim)) 00549 add_mode(chan, '-', 'h', who); 00550 else if ((chan_dehalfop(victim) || (glob_dehalfop(victim) && 00551 !chan_halfop(victim))) && !glob_master(*opper) && 00552 !chan_master(*opper)) 00553 add_mode(chan, '-', 'h', who); 00554 else if (reversing) 00555 add_mode(chan, '-', 'h', who); 00556 } else if (reversing && HALFOP_CANDOMODE('h') && !match_my_nick(who) && 00557 !match_my_nick(nick)) 00558 add_mode(chan, '-', 'h', who); 00559 if (!nick[0] && HALFOP_CANDOMODE('h') && !match_my_nick(who)) { 00560 if (chan_dehalfop(victim) || (glob_dehalfop(victim) && 00561 !chan_halfop(victim))) { 00562 m->flags |= FAKEHALFOP; 00563 add_mode(chan, '-', 'h', who); 00564 } else if (snm > 0 && snm < 7 && !((channel_autohalfop(chan) || 00565 glob_autohalfop(victim) || chan_autohalfop(victim)) && 00566 (chan_halfop(victim) || (glob_halfop(victim) && 00567 !chan_dehalfop(victim)))) && !glob_exempt(victim) && 00568 !chan_exempt(victim)) { 00569 if (snm == 5) 00570 snm = channel_bitch(chan) ? 1 : 3; 00571 if (snm == 6) 00572 snm = channel_bitch(chan) ? 4 : 2; 00573 if (chan_washalfoptest(victim) || glob_washalfoptest(victim) || snm == 2) { 00574 if (!chan_washalfop(m)) { 00575 m->flags |= FAKEHALFOP; 00576 add_mode(chan, '-', 'h', who); 00577 } 00578 } else if (!(chan_halfop(victim) || (glob_halfop(victim) && 00579 !chan_dehalfop(victim)))) { 00580 if (snm == 1 || snm == 4 || (snm == 3 && !chan_washalfop(m))) { 00581 add_mode(chan, '-', 'h', who); 00582 m->flags |= FAKEHALFOP; 00583 } 00584 } else if (snm == 4 && !chan_washalfop(m)) { 00585 add_mode(chan, '-', 'h', who); 00586 m->flags |= FAKEHALFOP; 00587 } 00588 } 00589 } 00590 m->flags |= WASHALFOP; 00591 if (check_chan) 00592 recheck_channel(chan, 1); 00593 }
static void got_invite | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
char * | ch, | |||
struct userrec * | u | |||
) | [static] |
Definition at line 936 of file mode.c.
References add_mode, bounce_invites, bounce_modes, chan_master, channel_nouserinvites, channel_pending, check_tcl_mode(), chanset_t::dname, glob_bot, glob_master, global_invites, HALFOP_CANTDOMODE, chanset_t::invites, match_my_nick(), modebind_refresh(), newinvite, NULL, reversing, simple_sprintf, u_equals_mask(), and UHOSTLEN.
Referenced by gotmode().
00938 { 00939 char s[UHOSTLEN]; 00940 00941 simple_sprintf(s, "%s!%s", nick, from); 00942 newinvite(chan, who, s); 00943 check_tcl_mode(nick, from, u, chan->dname, "+I", who); 00944 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 00945 return; 00946 00947 if (channel_pending(chan) || HALFOP_CANTDOMODE('I')) 00948 return; 00949 00950 if (!match_my_nick(nick)) { 00951 if (nick[0] && channel_nouserinvites(chan) && !glob_bot(user) && 00952 !glob_master(user) && !chan_master(user)) { 00953 add_mode(chan, '-', 'I', who); 00954 return; 00955 } 00956 if ((!nick[0]) && (bounce_modes)) 00957 reversing = 1; 00958 } 00959 if (reversing || (bounce_invites && (!nick[0]) && 00960 (!u_equals_mask(global_invites, who) || 00961 !u_equals_mask(chan->invites, who)))) 00962 add_mode(chan, '-', 'I', who); 00963 }
static void got_key | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | key | |||
) | [static] |
Definition at line 382 of file mode.c.
References add_mode, bounce_modes, chan_master, CHANKEY, glob_bot, glob_master, chanset_t::key_prot, match_my_nick(), chanset_t::mode_mns_prot, chanset_t::mode_pls_prot, and reversing.
Referenced by gotmode().
00383 { 00384 if (!nick[0] && bounce_modes) 00385 reversing = 1; 00386 00387 if (!(glob_master(user) || glob_bot(user) || chan_master(user)) && 00388 !match_my_nick(nick)) { 00389 if ((reversing && !chan->key_prot[0]) || (chan->mode_mns_prot & CHANKEY)) { 00390 if (strlen(key) != 0) 00391 add_mode(chan, '-', 'k', key); 00392 else 00393 add_mode(chan, '-', 'k', ""); 00394 } 00395 if ((chan->mode_pls_prot & CHANKEY) && (chan->key_prot[0] != 0) && 00396 strcmp(key, chan->key_prot)) { 00397 add_mode(chan, '+', 'k', chan->key_prot); 00398 } 00399 } 00400 }
static void got_op | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
struct userrec * | opu, | |||
struct flag_record * | opper | |||
) | [static] |
Definition at line 402 of file mode.c.
References add_mode, chan_autoop, CHAN_BADCHANMODE, chan_deop, chan_exempt, chan_master, chan_op, CHAN_PEND, chan_wasop, chan_wasoptest, channel_autoop, channel_bitch, channel_pending, CHANOP, check_tcl_mode(), chanset_t::dname, FAKEOP, memstruct::flags, get_user_by_host, get_user_flagrec, glob_autoop, glob_bot, glob_deop, glob_exempt, glob_master, glob_op, glob_wasoptest, HALFOP_CANDOMODE, ismember, LOG_MISC, match_my_nick(), me_op(), modebind_refresh(), chanset_t::name, memstruct::nick, putlog, recheck_channel(), refresh_who_chan(), reversing, SENTOP, simple_sprintf, chanset_t::status, chanset_t::stopnethack_mode, UHOSTLEN, memstruct::user, memstruct::userhost, and WASOP.
Referenced by gotmode().
00404 { 00405 memberlist *m; 00406 char ch[sizeof chan->name]; 00407 char s[UHOSTLEN]; 00408 struct userrec *u; 00409 int check_chan = 0, snm = chan->stopnethack_mode; 00410 00411 m = ismember(chan, who); 00412 if (!m) { 00413 if (channel_pending(chan)) 00414 return; 00415 putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, who); 00416 chan->status |= CHAN_PEND; 00417 refresh_who_chan(chan->name); 00418 return; 00419 } 00420 00421 /* Did *I* just get opped? */ 00422 if (!me_op(chan) && match_my_nick(who)) 00423 check_chan = 1; 00424 00425 strcpy(ch, chan->name); 00426 simple_sprintf(s, "%s!%s", m->nick, m->userhost); 00427 if (!m->user) 00428 u = get_user_by_host(s); 00429 else 00430 u = m->user; 00431 00432 get_user_flagrec(u, &victim, chan->dname); 00433 /* Flags need to be set correctly right from the beginning now, so that 00434 * add_mode() doesn't get irritated. 00435 */ 00436 m->flags |= CHANOP; 00437 check_tcl_mode(nick, from, opu, chan->dname, "+o", who); 00438 if (!(chan = modebind_refresh(ch, from, opper, s, &victim)) || 00439 !(m = ismember(chan, who))) 00440 return; 00441 /* Added new meaning of WASOP: 00442 * In mode binds it means: was the user an op before got (de)opped. A script 00443 * now can use [wasop nick chan] to check if user was op or wasnt. 00444 * (drummer) 00445 */ 00446 m->flags &= ~SENTOP; 00447 00448 if (channel_pending(chan)) 00449 return; 00450 00451 if (nick[0] && HALFOP_CANDOMODE('o') && !match_my_nick(who) && 00452 !match_my_nick(nick)) { 00453 if (channel_bitch(chan) && !(glob_master(*opper) || glob_bot(*opper)) && 00454 !chan_master(*opper) && !(glob_op(victim) || glob_bot(victim)) && 00455 !chan_op(victim)) 00456 add_mode(chan, '-', 'o', who); 00457 else if ((chan_deop(victim) || (glob_deop(victim) && !chan_op(victim))) && 00458 !glob_master(*opper) && !chan_master(*opper)) 00459 add_mode(chan, '-', 'o', who); 00460 else if (reversing) 00461 add_mode(chan, '-', 'o', who); 00462 } else if (reversing && HALFOP_CANDOMODE('o') && !match_my_nick(who) && 00463 !match_my_nick(nick)) 00464 add_mode(chan, '-', 'o', who); 00465 if (!nick[0] && HALFOP_CANDOMODE('o') && !match_my_nick(who)) { 00466 if (chan_deop(victim) || (glob_deop(victim) && !chan_op(victim))) { 00467 m->flags |= FAKEOP; 00468 add_mode(chan, '-', 'o', who); 00469 } else if (snm > 0 && snm < 7 && !((channel_autoop(chan) || 00470 glob_autoop(victim) || chan_autoop(victim)) && (chan_op(victim) || 00471 (glob_op(victim) && !chan_deop(victim)))) && 00472 !glob_exempt(victim) && !chan_exempt(victim)) { 00473 if (snm == 5) 00474 snm = channel_bitch(chan) ? 1 : 3; 00475 if (snm == 6) 00476 snm = channel_bitch(chan) ? 4 : 2; 00477 if (chan_wasoptest(victim) || glob_wasoptest(victim) || snm == 2) { 00478 if (!chan_wasop(m)) { 00479 m->flags |= FAKEOP; 00480 add_mode(chan, '-', 'o', who); 00481 } 00482 } else if (!(chan_op(victim) || (glob_op(victim) && !chan_deop(victim)))) { 00483 if (snm == 1 || snm == 4 || (snm == 3 && !chan_wasop(m))) { 00484 add_mode(chan, '-', 'o', who); 00485 m->flags |= FAKEOP; 00486 } 00487 } else if (snm == 4 && !chan_wasop(m)) { 00488 add_mode(chan, '-', 'o', who); 00489 m->flags |= FAKEOP; 00490 } 00491 } 00492 } 00493 m->flags |= WASOP; 00494 if (check_chan) 00495 recheck_channel(chan, 1); 00496 }
static void got_unban | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
char * | ch, | |||
struct userrec * | u | |||
) | [static] |
Definition at line 826 of file mode.c.
References add_mode, chan_t::ban, chanset_t::bans, bot_flags, BOT_SHARE, chan_dehalfop, chan_deop, chan_halfop, chan_op, chanset_t::channel, channel_dynamicbans, channel_pending, check_tcl_mode(), chanset_t::dname, glob_bot, glob_halfop, glob_op, global_bans, maskstruct::mask, modebind_refresh(), maskstruct::next, nfree, NULL, rfc_casecmp, u_equals_mask(), u_sticky_mask(), and maskstruct::who.
Referenced by gotmode().
00828 { 00829 masklist *b, *old; 00830 00831 old = NULL; 00832 for (b = chan->channel.ban; b->mask[0] && rfc_casecmp(b->mask, who); 00833 old = b, b = b->next); 00834 if (b->mask[0]) { 00835 if (old) 00836 old->next = b->next; 00837 else 00838 chan->channel.ban = b->next; 00839 nfree(b->mask); 00840 nfree(b->who); 00841 nfree(b); 00842 } 00843 check_tcl_mode(nick, from, u, chan->dname, "-b", who); 00844 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 00845 return; 00846 00847 if (channel_pending(chan)) 00848 return; 00849 00850 if ((u_sticky_mask(chan->bans, who) || u_sticky_mask(global_bans, who)) || 00851 ((u_equals_mask(global_bans, who) || u_equals_mask(chan->bans, who)) && 00852 !channel_dynamicbans(chan) && ((!glob_bot(user) || 00853 !(bot_flags(u) & BOT_SHARE)) && ((!glob_op(user) || chan_deop(user)) && 00854 !chan_op(user)) && ((!glob_halfop(user) || chan_dehalfop(user)) && 00855 !chan_halfop(user))))) 00856 add_mode(chan, '+', 'b', who); 00857 }
static void got_unexempt | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
char * | ch, | |||
struct userrec * | u | |||
) | [static] |
Definition at line 888 of file mode.c.
References add_mode, chan_t::ban, bot_flags, BOT_SHARE, chan_master, chanset_t::channel, channel_dynamicexempts, channel_pending, check_tcl_mode(), chanset_t::dname, e, chan_t::exempt, chanset_t::exempts, glob_bot, glob_master, global_exempts, maskstruct::mask, mask_match, me_op(), modebind_refresh(), maskstruct::next, nfree, NULL, rfc_casecmp, u_equals_mask(), u_sticky_mask(), and maskstruct::who.
Referenced by gotmode().
00890 { 00891 masklist *e = chan->channel.exempt, *old = NULL; 00892 masklist *b; 00893 int match = 0; 00894 00895 while (e && e->mask[0] && rfc_casecmp(e->mask, who)) { 00896 old = e; 00897 e = e->next; 00898 } 00899 if (e && e->mask[0]) { 00900 if (old) 00901 old->next = e->next; 00902 else 00903 chan->channel.exempt = e->next; 00904 nfree(e->mask); 00905 nfree(e->who); 00906 nfree(e); 00907 } 00908 check_tcl_mode(nick, from, u, chan->dname, "-e", who); 00909 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 00910 return; 00911 00912 if (channel_pending(chan)) 00913 return; 00914 00915 if (u_sticky_mask(chan->exempts, who) || u_sticky_mask(global_exempts, who)) 00916 add_mode(chan, '+', 'e', who); 00917 00918 /* If exempt was removed by master then leave it else check for bans */ 00919 if (!nick[0] && glob_bot(user) && !glob_master(user) && !chan_master(user)) { 00920 b = chan->channel.ban; 00921 while (b->mask[0] && !match) { 00922 if (mask_match(b->mask, who)) { 00923 add_mode(chan, '+', 'e', who); 00924 match = 1; 00925 } else 00926 b = b->next; 00927 } 00928 } 00929 if ((u_equals_mask(global_exempts, who) || 00930 u_equals_mask(chan->exempts, who)) && me_op(chan) && 00931 !channel_dynamicexempts(chan) && (!glob_bot(user) || 00932 !(bot_flags(u) & BOT_SHARE))) 00933 add_mode(chan, '+', 'e', who); 00934 }
static void got_uninvite | ( | struct chanset_t * | chan, | |
char * | nick, | |||
char * | from, | |||
char * | who, | |||
char * | ch, | |||
struct userrec * | u | |||
) | [static] |
Definition at line 965 of file mode.c.
References add_mode, bot_flags, BOT_SHARE, chan_master, CHANINV, chanset_t::channel, channel_dynamicinvites, channel_pending, check_tcl_mode(), chanset_t::dname, glob_bot, glob_master, global_invites, chan_t::invite, chanset_t::invites, maskstruct::mask, me_op(), chan_t::mode, modebind_refresh(), maskstruct::next, nfree, NULL, rfc_casecmp, u_equals_mask(), u_sticky_mask(), and maskstruct::who.
Referenced by gotmode().
00967 { 00968 masklist *inv = chan->channel.invite, *old = NULL; 00969 00970 while (inv->mask[0] && rfc_casecmp(inv->mask, who)) { 00971 old = inv; 00972 inv = inv->next; 00973 } 00974 if (inv->mask[0]) { 00975 if (old) 00976 old->next = inv->next; 00977 else 00978 chan->channel.invite = inv->next; 00979 nfree(inv->mask); 00980 nfree(inv->who); 00981 nfree(inv); 00982 } 00983 check_tcl_mode(nick, from, u, chan->dname, "-I", who); 00984 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 00985 return; 00986 00987 if (channel_pending(chan)) 00988 return; 00989 00990 if (u_sticky_mask(chan->invites, who) || u_sticky_mask(global_invites, who)) 00991 add_mode(chan, '+', 'I', who); 00992 if (!nick[0] && glob_bot(user) && !glob_master(user) && !chan_master(user) && 00993 (chan->channel.mode & CHANINV)) 00994 add_mode(chan, '+', 'I', who); 00995 if ((u_equals_mask(global_invites, who) || 00996 u_equals_mask(chan->invites, who)) && me_op(chan) && 00997 !channel_dynamicinvites(chan) && (!glob_bot(user) || 00998 !(bot_flags(u) & BOT_SHARE))) 00999 add_mode(chan, '+', 'I', who); 01000 }
static int gotmode | ( | char * | from, | |
char * | origmsg | |||
) | [static] |
Definition at line 1002 of file mode.c.
References add_mode, bounce_modes, CHAN_ASKEDMODES, CHAN_BADCHANMODE, chan_deop, CHAN_DESYNCMODE, CHAN_DESYNCMODE_KICK, chan_fakehalfop, CHAN_FAKEMODE, CHAN_FAKEMODE_KICK, chan_fakeop, CHAN_FORCEJOIN, chan_friend, chan_gvoice, chan_hashalfop, chan_hasop, chan_master, chan_op, CHAN_PEND, chan_quiet, chan_voice, CHANANON, CHANDELJN, CHANINV, CHANINVIS, CHANKEY, CHANLIMIT, CHANLONLY, CHANMETA, CHANMODER, CHANMODREG, chanset_t::channel, channel_active, channel_autovoice, channel_dontkickops, channel_nodesynch, channel_pending, CHANNOAMSG, CHANNOCLR, CHANNOCTCP, CHANNOMSG, CHANNONOTC, CHANPRIV, CHANQUIET, CHANREGON, CHANSEC, CHANSTRIP, CHANTOPIC, CHANVOICE, check_tcl_mode(), chanset_t::dname, DP_MODE, DP_SERVER, dprintf, findchan, fixcolon, memstruct::flags, get_user_by_host, get_user_flagrec, glob_friend, glob_gvoice, glob_master, glob_op, glob_quiet, glob_voice, got_ban(), got_dehalfop(), got_deop(), got_exempt(), got_halfop(), got_invite(), got_key(), got_op(), got_unban(), got_unexempt(), got_uninvite(), int_to_base10, ismember, chan_t::key, chanset_t::key_prot, memstruct::last, chanset_t::limit_prot, LOG_MISC, LOG_MODES, match_my_nick(), chan_t::maxmembers, me_halfop(), me_op(), chan_t::mode, chanset_t::mode_mns_prot, chanset_t::mode_pls_prot, modebind_refresh(), chanset_t::name, newsplit, memstruct::nick, now, NULL, putlog, refresh_who_chan(), reversing, SENTDEVOICE, SENTKICK, SENTVOICE, set_key(), simple_sprintf, splitnick, chanset_t::status, UHOSTLEN, memstruct::user, and memstruct::userhost.
01003 { 01004 char *nick, *ch, *op, *chg, *msg; 01005 char s[UHOSTLEN], buf[511]; 01006 char ms2[3]; 01007 int z; 01008 struct userrec *u; 01009 memberlist *m; 01010 struct chanset_t *chan; 01011 01012 strncpy(buf, origmsg, 510); 01013 buf[510] = 0; 01014 msg = buf; 01015 /* Usermode changes? */ 01016 if (msg[0] && (strchr(CHANMETA, msg[0]) != NULL)) { 01017 ch = newsplit(&msg); 01018 chg = newsplit(&msg); 01019 reversing = 0; 01020 chan = findchan(ch); 01021 if (!chan) { 01022 putlog(LOG_MISC, "*", CHAN_FORCEJOIN, ch); 01023 dprintf(DP_SERVER, "PART %s\n", ch); 01024 } else if (channel_active(chan) || channel_pending(chan)) { 01025 z = strlen(msg); 01026 if (msg[--z] == ' ') /* I hate cosmetic bugs :P -poptix */ 01027 msg[z] = 0; 01028 putlog(LOG_MODES, chan->dname, "%s: mode change '%s %s' by %s", ch, chg, 01029 msg, from); 01030 u = get_user_by_host(from); 01031 get_user_flagrec(u, &user, ch); 01032 nick = splitnick(&from); 01033 m = ismember(chan, nick); 01034 if (m) 01035 m->last = now; 01036 if (m && channel_active(chan) && (me_op(chan) || (me_halfop(chan) && 01037 !chan_hasop(m))) && !(glob_friend(user) || chan_friend(user) || 01038 (channel_dontkickops(chan) && (chan_op(user) || (glob_op(user) && 01039 !chan_deop(user))))) && !match_my_nick(nick)) { 01040 if (chan_fakeop(m) || chan_fakehalfop(m)) { 01041 putlog(LOG_MODES, ch, CHAN_FAKEMODE, ch); 01042 dprintf(DP_MODE, "KICK %s %s :%s\n", ch, nick, CHAN_FAKEMODE_KICK); 01043 m->flags |= SENTKICK; 01044 reversing = 1; 01045 } else if (!chan_hasop(m) && !chan_hashalfop(m) && 01046 !channel_nodesynch(chan)) { 01047 putlog(LOG_MODES, ch, CHAN_DESYNCMODE, ch); 01048 dprintf(DP_MODE, "KICK %s %s :%s\n", ch, nick, CHAN_DESYNCMODE_KICK); 01049 m->flags |= SENTKICK; 01050 reversing = 1; 01051 } 01052 } 01053 ms2[0] = '+'; 01054 ms2[2] = 0; 01055 while ((ms2[1] = *chg)) { 01056 int todo = 0; 01057 01058 switch (*chg) { 01059 case '+': 01060 ms2[0] = '+'; 01061 break; 01062 case '-': 01063 ms2[0] = '-'; 01064 break; 01065 case 'i': 01066 todo = CHANINV; 01067 if (!nick[0] && bounce_modes) 01068 reversing = 1; 01069 break; 01070 case 'p': 01071 todo = CHANPRIV; 01072 if (!nick[0] && bounce_modes) 01073 reversing = 1; 01074 break; 01075 case 's': 01076 todo = CHANSEC; 01077 if (!nick[0] && bounce_modes) 01078 reversing = 1; 01079 break; 01080 case 'm': 01081 todo = CHANMODER; 01082 if (!nick[0] && bounce_modes) 01083 reversing = 1; 01084 break; 01085 case 'c': 01086 todo = CHANNOCLR; 01087 if (!nick[0] && bounce_modes) 01088 reversing = 1; 01089 break; 01090 case 'C': 01091 todo = CHANNOCTCP; 01092 if (!nick[0] && bounce_modes) 01093 reversing = 1; 01094 break; 01095 case 'R': 01096 todo = CHANREGON; 01097 if (!nick[0] && bounce_modes) 01098 reversing = 1; 01099 break; 01100 case 'M': 01101 todo = CHANMODREG; 01102 if (!nick[0] && bounce_modes) 01103 reversing = 1; 01104 break; 01105 case 'r': 01106 todo = CHANLONLY; 01107 if (!nick[0] && bounce_modes) 01108 reversing = 1; 01109 break; 01110 case 'D': 01111 todo = CHANDELJN; 01112 if (!nick[0] && bounce_modes) 01113 reversing = 1; 01114 break; 01115 case 'u': 01116 todo = CHANSTRIP; 01117 if (!nick[0] && bounce_modes) 01118 reversing = 1; 01119 break; 01120 case 'N': 01121 todo = CHANNONOTC; 01122 if (!nick[0] && bounce_modes) 01123 reversing = 1; 01124 break; 01125 case 'T': 01126 todo = CHANNOAMSG; 01127 if (!nick[0] && bounce_modes) 01128 reversing = 1; 01129 break; 01130 case 'd': 01131 todo = CHANINVIS; 01132 break; 01133 case 't': 01134 todo = CHANTOPIC; 01135 if (!nick[0] && bounce_modes) 01136 reversing = 1; 01137 break; 01138 case 'n': 01139 todo = CHANNOMSG; 01140 if (!nick[0] && bounce_modes) 01141 reversing = 1; 01142 break; 01143 case 'a': 01144 todo = CHANANON; 01145 if (!nick[0] && bounce_modes) 01146 reversing = 1; 01147 break; 01148 case 'q': 01149 todo = CHANQUIET; 01150 if (!nick[0] && bounce_modes) 01151 reversing = 1; 01152 break; 01153 case 'l': 01154 if (!nick[0] && bounce_modes) 01155 reversing = 1; 01156 if (ms2[0] == '-') { 01157 check_tcl_mode(nick, from, u, chan->dname, ms2, ""); 01158 /* The Tcl proc might have modified/removed the chan or user */ 01159 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 01160 return 0; 01161 if (channel_active(chan)) { 01162 if (reversing && (chan->channel.maxmembers != 0)) { 01163 simple_sprintf(s, "%d", chan->channel.maxmembers); 01164 add_mode(chan, '+', 'l', s); 01165 } else if ((chan->limit_prot != 0) && !glob_master(user) && 01166 !chan_master(user) && !match_my_nick(nick)) { 01167 simple_sprintf(s, "%d", chan->limit_prot); 01168 add_mode(chan, '+', 'l', s); 01169 } 01170 } 01171 chan->channel.maxmembers = 0; 01172 } else { 01173 op = newsplit(&msg); 01174 fixcolon(op); 01175 if (op == '\0') 01176 break; 01177 chan->channel.maxmembers = atoi(op); 01178 check_tcl_mode(nick, from, u, chan->dname, ms2, 01179 int_to_base10(chan->channel.maxmembers)); 01180 /* The Tcl proc might have modified/removed the chan or user */ 01181 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 01182 return 0; 01183 if (channel_pending(chan)) 01184 break; 01185 if ((reversing && !(chan->mode_pls_prot & CHANLIMIT)) || 01186 ((chan->mode_mns_prot & CHANLIMIT) && !glob_master(user) && 01187 !chan_master(user))) 01188 add_mode(chan, '-', 'l', ""); 01189 if ((chan->limit_prot != chan->channel.maxmembers) && 01190 (chan->mode_pls_prot & CHANLIMIT) && (chan->limit_prot != 0) && 01191 !glob_master(user) && !chan_master(user)) { 01192 simple_sprintf(s, "%d", chan->limit_prot); 01193 add_mode(chan, '+', 'l', s); 01194 } 01195 } 01196 break; 01197 case 'k': 01198 if (ms2[0] == '+') 01199 chan->channel.mode |= CHANKEY; 01200 else 01201 chan->channel.mode &= ~CHANKEY; 01202 op = newsplit(&msg); 01203 fixcolon(op); 01204 if (op == '\0') { 01205 break; 01206 } 01207 check_tcl_mode(nick, from, u, chan->dname, ms2, op); 01208 /* The Tcl proc might have modified/removed the chan or user */ 01209 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 01210 return 0; 01211 if (ms2[0] == '+') { 01212 set_key(chan, op); 01213 if (channel_active(chan)) 01214 got_key(chan, nick, from, op); 01215 } else { 01216 if (channel_active(chan)) { 01217 if (reversing && chan->channel.key[0]) 01218 add_mode(chan, '+', 'k', chan->channel.key); 01219 else if (chan->key_prot[0] && !glob_master(user) && 01220 !chan_master(user) && !match_my_nick(nick)) 01221 add_mode(chan, '+', 'k', chan->key_prot); 01222 } 01223 set_key(chan, NULL); 01224 } 01225 break; 01226 case 'o': 01227 op = newsplit(&msg); 01228 fixcolon(op); 01229 if (ms2[0] == '+') 01230 got_op(chan, nick, from, op, u, &user); 01231 else 01232 got_deop(chan, nick, from, op, u); 01233 break; 01234 case 'h': 01235 op = newsplit(&msg); 01236 fixcolon(op); 01237 if (ms2[0] == '+') 01238 got_halfop(chan, nick, from, op, u, &user); 01239 else 01240 got_dehalfop(chan, nick, from, op, u); 01241 break; 01242 case 'v': 01243 op = newsplit(&msg); 01244 fixcolon(op); 01245 m = ismember(chan, op); 01246 if (!m) { 01247 if (channel_pending(chan)) 01248 break; 01249 putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, op); 01250 chan->status |= CHAN_PEND; 01251 refresh_who_chan(chan->name); 01252 } else { 01253 simple_sprintf(s, "%s!%s", m->nick, m->userhost); 01254 get_user_flagrec(m->user ? m->user : get_user_by_host(s), 01255 &victim, chan->dname); 01256 if (ms2[0] == '+') { 01257 m->flags &= ~SENTVOICE; 01258 m->flags |= CHANVOICE; 01259 check_tcl_mode(nick, from, u, chan->dname, ms2, op); 01260 if (!(chan = modebind_refresh(ch, from, &user, s, &victim))) 01261 return 0; 01262 if (channel_active(chan) && !glob_master(user) && 01263 !chan_master(user) && !match_my_nick(nick)) { 01264 if (chan_quiet(victim) || 01265 (glob_quiet(victim) && !chan_voice(victim))) 01266 add_mode(chan, '-', 'v', op); 01267 else if (reversing) 01268 add_mode(chan, '-', 'v', op); 01269 } 01270 } else { 01271 m->flags &= ~SENTDEVOICE; 01272 m->flags &= ~CHANVOICE; 01273 check_tcl_mode(nick, from, u, chan->dname, ms2, op); 01274 if (!(chan = modebind_refresh(ch, from, &user, s, &victim))) 01275 return 0; 01276 if (channel_active(chan) && !glob_master(user) && 01277 !chan_master(user) && !match_my_nick(nick)) { 01278 if ((channel_autovoice(chan) && !chan_quiet(victim) && 01279 (chan_voice(victim) || glob_voice(victim))) || 01280 (!chan_quiet(victim) && (glob_gvoice(victim) || 01281 chan_gvoice(victim)))) 01282 add_mode(chan, '+', 'v', op); 01283 else if (reversing) 01284 add_mode(chan, '+', 'v', op); 01285 } 01286 } 01287 } 01288 break; 01289 case 'b': 01290 op = newsplit(&msg); 01291 fixcolon(op); 01292 if (ms2[0] == '+') 01293 got_ban(chan, nick, from, op, ch, u); 01294 else 01295 got_unban(chan, nick, from, op, ch, u); 01296 break; 01297 case 'e': 01298 op = newsplit(&msg); 01299 fixcolon(op); 01300 if (ms2[0] == '+') 01301 got_exempt(chan, nick, from, op, ch, u); 01302 else 01303 got_unexempt(chan, nick, from, op, ch, u); 01304 break; 01305 case 'I': 01306 op = newsplit(&msg); 01307 fixcolon(op); 01308 if (ms2[0] == '+') 01309 got_invite(chan, nick, from, op, ch, u); 01310 else 01311 got_uninvite(chan, nick, from, op, ch, u); 01312 break; 01313 } 01314 if (todo) { 01315 check_tcl_mode(nick, from, u, chan->dname, ms2, ""); 01316 if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL))) 01317 return 0; 01318 if (ms2[0] == '+') 01319 chan->channel.mode |= todo; 01320 else 01321 chan->channel.mode &= ~todo; 01322 if (channel_active(chan)) { 01323 if ((((ms2[0] == '+') && (chan->mode_mns_prot & todo)) || 01324 ((ms2[0] == '-') && (chan->mode_pls_prot & todo))) && 01325 !glob_master(user) && !chan_master(user) && 01326 !match_my_nick(nick)) 01327 add_mode(chan, ms2[0] == '+' ? '-' : '+', *chg, ""); 01328 else if (reversing && ((ms2[0] == '+') || 01329 (chan->mode_pls_prot & todo)) && ((ms2[0] == '-') || 01330 (chan->mode_mns_prot & todo))) 01331 add_mode(chan, ms2[0] == '+' ? '-' : '+', *chg, ""); 01332 } 01333 } 01334 chg++; 01335 } 01336 if (!me_op(chan) && !nick[0]) 01337 chan->status |= CHAN_ASKEDMODES; 01338 } 01339 } 01340 return 0; 01341 }
struct chanset_t* modebind_refresh | ( | char * | chname, | |
char * | usrhost, | |||
struct flag_record * | usr, | |||
char * | vcrhost, | |||
struct flag_record * | vcr | |||
) | [read] |
Definition at line 47 of file mode.c.
References chanset_t::dname, findchan, get_user_by_host, get_user_flagrec, and NULL.
Referenced by got_ban(), got_dehalfop(), got_deop(), got_exempt(), got_halfop(), got_invite(), got_op(), got_unban(), got_unexempt(), got_uninvite(), and gotmode().
00050 { 00051 struct userrec *u; 00052 struct chanset_t *chan; 00053 00054 if (!chname || !(chan = findchan(chname))) 00055 return NULL; 00056 if (usrhost) { 00057 u = get_user_by_host(usrhost); 00058 get_user_flagrec(u, usr, chan->dname); 00059 } 00060 if (vcrhost) { 00061 u = get_user_by_host(vcrhost); 00062 get_user_flagrec(u, vcr, chan->dname); 00063 } 00064 return chan; 00065 }
static void real_add_mode | ( | struct chanset_t * | chan, | |
char | plus, | |||
char | mode, | |||
char * | op | |||
) | [static] |
Definition at line 201 of file mode.c.
References chan_t::ban, BAN, chanset_t::bans, chanset_t::bytes, chan_hashalfop, chan_hasop, chan_hasvoice, chan_sentdehalfop, chan_sentdeop, chan_sentdevoice, chan_senthalfop, chan_sentop, chan_sentvoice, chanset_t::channel, channel_malloc(), CHHOP, CHOP, chanset_t::cmode, chanset_t::compat, chan_t::exempt, EXEMPT, chanset_t::exempts, memstruct::flags, flush_mode(), HALFOP_CANTDOMODE, include_lk, chan_t::invite, INVITE, chanset_t::invites, ischanban, ischanexempt, ischaninvite, ismember, chanset_t::key, chanset_t::limit, maskstruct::mask, max_bans, max_exempts, max_invites, max_modes, me_op(), MINUS, chanset_t::mns, mode_buf_len, modesperline, maskstruct::next, nfree, NORMAL, NULL, chanset_t::op, chanset_t::pls, PLUS, prevent_mixing, rfc_casecmp, chanset_t::rmkey, SENTDEHALFOP, SENTDEOP, SENTDEVOICE, SENTHALFOP, SENTOP, SENTVOICE, chanset_t::type, and VOICE.
Referenced by irc_close(), and irc_start().
00203 { 00204 int i, type, modes, l; 00205 masklist *m; 00206 memberlist *mx; 00207 char s[21]; 00208 00209 /* Some IRCds do not allow halfops to set certain modes. The modes halfops 00210 * are not allowed to set can be changed in chan.h. */ 00211 #ifdef NO_HALFOP_CHANMODES 00212 if (!me_op(chan)) 00213 #else 00214 if (HALFOP_CANTDOMODE(mode)) 00215 #endif 00216 return; 00217 00218 if (mode == 'o' || mode == 'h' || mode == 'v') { 00219 mx = ismember(chan, op); 00220 if (!mx) 00221 return; 00222 if (plus == '-' && mode == 'o') { 00223 if (chan_sentdeop(mx) || !chan_hasop(mx)) 00224 return; 00225 mx->flags |= SENTDEOP; 00226 } 00227 if (plus == '+' && mode == 'o') { 00228 if (chan_sentop(mx) || chan_hasop(mx)) 00229 return; 00230 mx->flags |= SENTOP; 00231 } 00232 if (plus == '-' && mode == 'h') { 00233 if (chan_sentdehalfop(mx) || !chan_hashalfop(mx)) 00234 return; 00235 mx->flags |= SENTDEHALFOP; 00236 } 00237 if (plus == '+' && mode == 'h') { 00238 if (chan_senthalfop(mx) || chan_hashalfop(mx)) 00239 return; 00240 mx->flags |= SENTHALFOP; 00241 } 00242 if (plus == '-' && mode == 'v') { 00243 if (chan_sentdevoice(mx) || !chan_hasvoice(mx)) 00244 return; 00245 mx->flags |= SENTDEVOICE; 00246 } 00247 if (plus == '+' && mode == 'v') { 00248 if (chan_sentvoice(mx) || chan_hasvoice(mx)) 00249 return; 00250 mx->flags |= SENTVOICE; 00251 } 00252 } 00253 00254 if (chan->compat == 0) { 00255 if (mode == 'e' || mode == 'I') 00256 chan->compat = 2; 00257 else 00258 chan->compat = 1; 00259 } else if (mode == 'e' || mode == 'I') { 00260 if (prevent_mixing && chan->compat == 1) 00261 flush_mode(chan, NORMAL); 00262 } else if (prevent_mixing && chan->compat == 2) 00263 flush_mode(chan, NORMAL); 00264 00265 if (mode == 'o' || mode == 'h' || mode == 'b' || mode == 'v' || mode == 'e' || 00266 mode == 'I') { 00267 type = (plus == '+' ? PLUS : MINUS) | (mode == 'o' ? CHOP : (mode == 'h' ? 00268 CHHOP : (mode == 'b' ? BAN : (mode == 'v' ? VOICE : (mode == 'e' ? 00269 EXEMPT : INVITE))))); 00270 /* 00271 * FIXME: Some networks remove overlapped bans, 00272 * IRCnet does not (poptix/drummer) 00273 * 00274 * Note: On IRCnet ischanXXX() should be used, otherwise isXXXed(). 00275 */ 00276 if ((plus == '-' && ((mode == 'b' && !ischanban(chan, op)) || 00277 (mode == 'e' && !ischanexempt(chan, op)) || 00278 (mode == 'I' && !ischaninvite(chan, op)))) || (plus == '+' && 00279 ((mode == 'b' && ischanban(chan, op)) || 00280 (mode == 'e' && ischanexempt(chan, op)) || 00281 (mode == 'I' && ischaninvite(chan, op))))) 00282 return; 00283 00284 /* If there are already max_bans bans, max_exempts exemptions, 00285 * max_invites invitations or max_modes +b/+e/+I modes on the 00286 * channel, don't try to add one more. 00287 */ 00288 if (plus == '+' && (mode == 'b' || mode == 'e' || mode == 'I')) { 00289 int bans = 0, exempts = 0, invites = 0; 00290 00291 for (m = chan->channel.ban; m && m->mask[0]; m = m->next) 00292 bans++; 00293 if ((mode == 'b') && (bans >= max_bans)) 00294 return; 00295 00296 for (m = chan->channel.exempt; m && m->mask[0]; m = m->next) 00297 exempts++; 00298 if ((mode == 'e') && (exempts >= max_exempts)) 00299 return; 00300 00301 for (m = chan->channel.invite; m && m->mask[0]; m = m->next) 00302 invites++; 00303 if ((mode == 'I') && (invites >= max_invites)) 00304 return; 00305 00306 if (bans + exempts + invites >= max_modes) 00307 return; 00308 } 00309 00310 /* op-type mode change */ 00311 for (i = 0; i < modesperline; i++) 00312 if (chan->cmode[i].type == type && chan->cmode[i].op != NULL && 00313 !rfc_casecmp(chan->cmode[i].op, op)) 00314 return; /* Already in there :- duplicate */ 00315 l = strlen(op) + 1; 00316 if (chan->bytes + l > mode_buf_len) 00317 flush_mode(chan, NORMAL); 00318 for (i = 0; i < modesperline; i++) 00319 if (chan->cmode[i].type == 0) { 00320 chan->cmode[i].type = type; 00321 chan->cmode[i].op = (char *) channel_malloc(l); 00322 chan->bytes += l; /* Add 1 for safety */ 00323 strcpy(chan->cmode[i].op, op); 00324 break; 00325 } 00326 } 00327 00328 /* +k ? store key */ 00329 else if (plus == '+' && mode == 'k') { 00330 if (chan->key) 00331 nfree(chan->key); 00332 chan->key = (char *) channel_malloc(strlen(op) + 1); 00333 if (chan->key) 00334 strcpy(chan->key, op); 00335 } 00336 /* -k ? store removed key */ 00337 else if (plus == '-' && mode == 'k') { 00338 if (chan->rmkey) 00339 nfree(chan->rmkey); 00340 chan->rmkey = (char *) channel_malloc(strlen(op) + 1); 00341 if (chan->rmkey) 00342 strcpy(chan->rmkey, op); 00343 } 00344 /* +l ? store limit */ 00345 else if (plus == '+' && mode == 'l') 00346 chan->limit = atoi(op); 00347 else { 00348 /* Typical mode changes */ 00349 if (plus == '+') 00350 strcpy(s, chan->pls); 00351 else 00352 strcpy(s, chan->mns); 00353 if (!strchr(s, mode)) { 00354 if (plus == '+') { 00355 chan->pls[strlen(chan->pls) + 1] = 0; 00356 chan->pls[strlen(chan->pls)] = mode; 00357 } else { 00358 chan->mns[strlen(chan->mns) + 1] = 0; 00359 chan->mns[strlen(chan->mns)] = mode; 00360 } 00361 } 00362 } 00363 modes = modesperline; /* Check for full buffer. */ 00364 for (i = 0; i < modesperline; i++) 00365 if (chan->cmode[i].type) 00366 modes--; 00367 if (include_lk && chan->limit) 00368 modes--; 00369 if (include_lk && chan->rmkey) 00370 modes--; 00371 if (include_lk && chan->key) 00372 modes--; 00373 if (modes < 1) 00374 flush_mode(chan, NORMAL); /* Full buffer! Flush modes. */ 00375 }
int reversing = 0 [static] |
Definition at line 29 of file mode.c.
Referenced by got_ban(), got_dehalfop(), got_deop(), got_exempt(), got_halfop(), got_invite(), got_key(), got_op(), and gotmode().
struct flag_record user = { 0x00000001 | 0x00000004 , 0, 0, 0, 0, 0 } [static] |
struct flag_record victim = { 0x00000001 | 0x00000004 , 0, 0, 0, 0, 0 } [static] |