Go to the source code of this file.
Defines | |
#define | CHANNEL_ID_LEN 5 |
Functions | |
static memberlist * | newmember (struct chanset_t *chan) |
static void | sync_members (struct chanset_t *chan) |
static void | update_idle (char *chname, char *nick) |
static char * | getchanmode (struct chanset_t *chan) |
static void | check_exemptlist (struct chanset_t *chan, char *from) |
static void | do_mask (struct chanset_t *chan, masklist *m, char *mask, char mode) |
static int | detect_chan_flood (char *floodnick, char *floodhost, char *from, struct chanset_t *chan, int which, char *victim) |
static char * | quickban (struct chanset_t *chan, char *uhost) |
static void | kick_all (struct chanset_t *chan, char *hostmask, char *comment, int bantype) |
static void | refresh_ban_kick (struct chanset_t *chan, char *user, char *nick) |
static void | refresh_exempt (struct chanset_t *chan, char *user) |
static void | refresh_invite (struct chanset_t *chan, char *user) |
static void | enforce_bans (struct chanset_t *chan) |
static void | recheck_bans (struct chanset_t *chan) |
static void | recheck_exempts (struct chanset_t *chan) |
static void | recheck_invites (struct chanset_t *chan) |
static void | resetmasks (struct chanset_t *chan, masklist *m, maskrec *mrec, maskrec *global_masks, char mode) |
static void | check_this_ban (struct chanset_t *chan, char *banmask, int sticky) |
static void | recheck_channel_modes (struct chanset_t *chan) |
static void | check_this_member (struct chanset_t *chan, char *nick, struct flag_record *fr) |
static void | check_this_user (char *hand, int delete, char *host) |
static void | recheck_channel (struct chanset_t *chan, int dobans) |
static int | got324 (char *from, char *msg) |
static int | got352or4 (struct chanset_t *chan, char *user, char *host, char *nick, char *flags) |
static int | got352 (char *from, char *msg) |
static int | got354 (char *from, char *msg) |
static int | got315 (char *from, char *msg) |
static int | got367 (char *from, char *origmsg) |
static int | got368 (char *from, char *msg) |
static int | got348 (char *from, char *origmsg) |
static int | got349 (char *from, char *msg) |
static int | got346 (char *from, char *origmsg) |
static int | got347 (char *from, char *msg) |
static int | got405 (char *from, char *msg) |
static int | got403 (char *from, char *msg) |
static int | got471 (char *from, char *msg) |
static int | got473 (char *from, char *msg) |
static int | got474 (char *from, char *msg) |
static int | got475 (char *from, char *msg) |
static int | gotinvite (char *from, char *msg) |
static void | set_topic (struct chanset_t *chan, char *k) |
static int | gottopic (char *from, char *msg) |
static int | got331 (char *from, char *msg) |
static int | got332 (char *from, char *msg) |
static void | set_delay (struct chanset_t *chan, char *nick) |
static int | gotjoin (char *from, char *chname) |
static int | gotpart (char *from, char *msg) |
static int | gotkick (char *from, char *origmsg) |
static int | gotnick (char *from, char *msg) |
static int | gotquit (char *from, char *msg) |
static int | gotmsg (char *from, char *msg) |
static int | gotnotice (char *from, char *msg) |
Variables | |
static time_t | last_ctcp = (time_t) 0L |
static int | count_ctcp = 0 |
static time_t | last_invtime = (time_t) 0L |
static char | last_invchan [300] = "" |
static cmd_t | irc_raw [] |
#define CHANNEL_ID_LEN 5 |
static void check_exemptlist | ( | struct chanset_t * | chan, | |
char * | from | |||
) | [static] |
Definition at line 147 of file chan.c.
References add_mode, chanset_t::channel, e, chan_t::exempt, flush_mode(), maskstruct::mask, match_addr, maskstruct::next, prevent_mixing, QUICK, and use_exempts.
Referenced by check_this_member(), cmd_kickban(), detect_chan_flood(), gotjoin(), gotmsg(), gotnotice(), and refresh_ban_kick().
00148 { 00149 masklist *e; 00150 int ok = 0; 00151 00152 if (!use_exempts) 00153 return; 00154 00155 for (e = chan->channel.exempt; e->mask[0]; e = e->next) 00156 if (match_addr(e->mask, from)) { 00157 add_mode(chan, '-', 'e', e->mask); 00158 ok = 1; 00159 } 00160 if (prevent_mixing && ok) 00161 flush_mode(chan, QUICK); 00162 }
static void check_this_ban | ( | struct chanset_t * | chan, | |
char * | banmask, | |||
int | sticky | |||
) | [static] |
Definition at line 638 of file chan.c.
References add_mode, chanset_t::channel, channel_dynamicbans, chanset_t::exempts, global_exempts, HALFOP_CANTDOMODE, isbanned, match_addr, chan_t::member, memstruct::next, memstruct::nick, refresh_ban_kick(), u_match_mask(), UHOSTLEN, use_exempts, user, and memstruct::userhost.
00639 { 00640 memberlist *m; 00641 char user[UHOSTLEN]; 00642 00643 if (HALFOP_CANTDOMODE('b')) 00644 return; 00645 00646 for (m = chan->channel.member; m && m->nick[0]; m = m->next) { 00647 sprintf(user, "%s!%s", m->nick, m->userhost); 00648 if (match_addr(banmask, user) && 00649 !(use_exempts && 00650 (u_match_mask(global_exempts, user) || 00651 u_match_mask(chan->exempts, user)))) 00652 refresh_ban_kick(chan, user, m->nick); 00653 } 00654 if (!isbanned(chan, banmask) && (!channel_dynamicbans(chan) || sticky)) 00655 add_mode(chan, '+', 'b', banmask); 00656 }
static void check_this_member | ( | struct chanset_t * | chan, | |
char * | nick, | |||
struct flag_record * | fr | |||
) | [static] |
Definition at line 750 of file chan.c.
References add_mode, chanset_t::aop_min, chanset_t::bans, chan_autohalfop, chan_autoop, chan_dehalfop, chan_deop, chan_gvoice, chan_halfop, chan_hashalfop, chan_hasop, chan_hasvoice, chan_kick, chan_op, chan_quiet, chan_sentkick, chan_sentop, chan_voice, channel_autohalfop, channel_autoop, channel_autovoice, channel_bitch, check_exemptlist(), DP_SERVER, dprintf, chanset_t::exempts, memstruct::flags, get_user, glob_autohalfop, glob_autoop, glob_dehalfop, glob_deop, glob_gvoice, glob_halfop, glob_kick, glob_op, glob_quiet, glob_voice, global_bans, global_exempts, global_invites, HALFOP_CANDOMODE, chanset_t::invites, IRC_POLITEKICK, ismember, match_my_nick(), me_halfop(), me_op(), chanset_t::name, memstruct::nick, NOHALFOPS_MODES, NULL, quickban(), refresh_ban_kick(), refresh_invite(), SENTHALFOP, SENTKICK, SENTOP, SENTVOICE, set_delay(), u_match_mask(), UHOSTLEN, use_exempts, use_invites, memstruct::user, USERENTRY_COMMENT, and memstruct::userhost.
Referenced by check_this_user(), gotnick(), and recheck_channel().
00752 { 00753 memberlist *m; 00754 char s[UHOSTLEN], *p; 00755 00756 m = ismember(chan, nick); 00757 if (!m || match_my_nick(nick) || (!me_op(chan) && !me_halfop(chan))) 00758 return; 00759 00760 00761 #ifdef NO_HALFOP_CHANMODES 00762 if (me_op(chan)) { 00763 #else 00764 if (me_op(chan) || me_halfop(chan)) { 00765 #endif 00766 if (HALFOP_CANDOMODE('o')) { 00767 if (chan_hasop(m) && ((chan_deop(*fr) || (glob_deop(*fr) && 00768 !chan_op(*fr))) || (channel_bitch(chan) && (!chan_op(*fr) && 00769 !(glob_op(*fr) && !chan_deop(*fr)))))) { 00770 add_mode(chan, '-', 'o', m->nick); 00771 } 00772 if (!chan_hasop(m) && (chan_op(*fr) || (glob_op(*fr) && 00773 !chan_deop(*fr))) && (channel_autoop(chan) || glob_autoop(*fr) || 00774 chan_autoop(*fr))) { 00775 if (!chan->aop_min) 00776 add_mode(chan, '+', 'o', m->nick); 00777 else { 00778 set_delay(chan, m->nick); 00779 m->flags |= SENTOP; 00780 } 00781 } 00782 } 00783 00784 if (HALFOP_CANDOMODE('h')) { 00785 if (chan_hashalfop(m) && ((chan_dehalfop(*fr) || (glob_dehalfop(*fr) && 00786 !chan_halfop(*fr)) || (channel_bitch(chan) && (!chan_halfop(*fr) && 00787 !(glob_halfop(*fr) && !chan_dehalfop(*fr))))))) 00788 add_mode(chan, '-', 'h', m->nick); 00789 if (!chan_sentop(m) && !chan_hasop(m) && !chan_hashalfop(m) && 00790 (chan_halfop(*fr) || (glob_halfop(*fr) && !chan_dehalfop(*fr))) && 00791 (channel_autohalfop(chan) || glob_autohalfop(*fr) || 00792 chan_autohalfop(*fr))) { 00793 if (!chan->aop_min) 00794 add_mode(chan, '+', 'h', m->nick); 00795 else { 00796 set_delay(chan, m->nick); 00797 m->flags |= SENTHALFOP; 00798 } 00799 } 00800 } 00801 00802 if (HALFOP_CANDOMODE('v')) { 00803 if (chan_hasvoice(m) && (chan_quiet(*fr) || (glob_quiet(*fr) && 00804 !chan_voice(*fr)))) 00805 add_mode(chan, '-', 'v', m->nick); 00806 if (!chan_hasvoice(m) && !chan_hasop(m) && !chan_hashalfop(m) && 00807 (chan_voice(*fr) || (glob_voice(*fr) && !chan_quiet(*fr))) && 00808 (channel_autovoice(chan) || glob_gvoice(*fr) || chan_gvoice(*fr))) { 00809 if (!chan->aop_min) 00810 add_mode(chan, '+', 'v', m->nick); 00811 else { 00812 set_delay(chan, m->nick); 00813 m->flags |= SENTVOICE; 00814 } 00815 } 00816 } 00817 } 00818 00819 if (!me_op(chan) && (!me_halfop(chan) || 00820 (strchr(NOHALFOPS_MODES, 'b') != NULL) || 00821 (strchr(NOHALFOPS_MODES, 'e') != NULL) || 00822 (strchr(NOHALFOPS_MODES, 'I') != NULL))) 00823 return; 00824 00825 sprintf(s, "%s!%s", m->nick, m->userhost); 00826 if (use_invites && (u_match_mask(global_invites, s) || 00827 u_match_mask(chan->invites, s))) 00828 refresh_invite(chan, s); 00829 if (!(use_exempts && (u_match_mask(global_exempts, s) || 00830 u_match_mask(chan->exempts, s)))) { 00831 if (u_match_mask(global_bans, s) || u_match_mask(chan->bans, s)) 00832 refresh_ban_kick(chan, s, m->nick); 00833 if (!chan_sentkick(m) && (chan_kick(*fr) || glob_kick(*fr)) && 00834 (me_op(chan) || (me_halfop(chan) && !chan_hasop(m)))) { 00835 check_exemptlist(chan, s); 00836 quickban(chan, m->userhost); 00837 p = get_user(&USERENTRY_COMMENT, m->user); 00838 dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, 00839 p ? p : IRC_POLITEKICK); 00840 m->flags |= SENTKICK; 00841 } 00842 } 00843 }
static void check_this_user | ( | char * | hand, | |
int | delete, | |||
char * | host | |||
) | [static] |
Definition at line 845 of file chan.c.
References chanset_t::channel, chanset, check_this_member(), chanset_t::dname, egg_strcasecmp, fixfrom, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, userrec::handle, match_addr, chan_t::member, memstruct::next, chanset_t::next, memstruct::nick, NULL, UHOSTLEN, memstruct::user, and memstruct::userhost.
Referenced by cmd_adduser(), msg_addhost(), and msg_ident().
00846 { 00847 char s[UHOSTLEN]; 00848 memberlist *m; 00849 struct userrec *u; 00850 struct chanset_t *chan; 00851 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 00852 00853 for (chan = chanset; chan; chan = chan->next) 00854 for (m = chan->channel.member; m && m->nick[0]; m = m->next) { 00855 sprintf(s, "%s!%s", m->nick, m->userhost); 00856 u = m->user ? m->user : get_user_by_host(s); 00857 if ((u && !egg_strcasecmp(u->handle, hand) && delete < 2) || 00858 (!u && delete == 2 && match_addr(host, fixfrom(s)))) { 00859 u = delete ? NULL : u; 00860 get_user_flagrec(u, &fr, chan->dname); 00861 check_this_member(chan, m->nick, &fr); 00862 } 00863 } 00864 }
static int detect_chan_flood | ( | char * | floodnick, | |
char * | floodhost, | |||
char * | from, | |||
struct chanset_t * | chan, | |||
int | which, | |||
char * | victim | |||
) | [static] |
Definition at line 181 of file chan.c.
References chan_t::ban, chanset_t::ban_time, chanset_t::bans, botnetnick, botuserhost, chan_deop, CHAN_FLOOD, chan_friend, chan_hasop, CHAN_MASSDEOP, CHAN_MASSDEOP_KICK, chan_master, chan_op, chan_sentkick, chanset_t::channel, channel_dontkickops, channel_enforcebans, check_exemptlist(), check_tcl_flud(), chanset_t::deopd, chanset_t::dname, do_mask(), DP_MODE, DP_SERVER, dprintf, egg_strcasecmp, chanset_t::exempts, memstruct::flags, FLOOD_CHAN_MAX, FLOOD_CTCP, chanset_t::flood_ctcp_thr, chanset_t::flood_ctcp_time, FLOOD_DEOP, chanset_t::flood_deop_thr, chanset_t::flood_deop_time, FLOOD_JOIN, chanset_t::flood_join_thr, chanset_t::flood_join_time, FLOOD_KICK, chanset_t::flood_kick_thr, chanset_t::flood_kick_time, FLOOD_NICK, chanset_t::flood_nick_thr, chanset_t::flood_nick_time, FLOOD_NOTICE, FLOOD_PRIVMSG, chanset_t::flood_pub_thr, chanset_t::flood_pub_time, chanset_t::floodnum, chanset_t::floodtime, chanset_t::floodwho, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, glob_bot, glob_friend, glob_master, glob_op, global_bans, global_exempts, IRC_FLOODIGNORE3, IRC_FLOODIGNORE4, IRC_FLOODKICK, IRC_JOIN_FLOOD, IRC_MASSKICK, IRC_NICK_FLOOD, isbanned, ismember, memstruct::joined, LOG_JOIN, LOG_MISC, LOG_MODES, match_my_nick(), me_halfop(), me_op(), chan_t::member, chanset_t::name, memstruct::next, memstruct::nick, now, putlog, rfc_casecmp, SENTKICK, simple_sprintf, u_addban(), u_match_mask(), UHOSTLEN, use_exempts, memstruct::userhost, and wild_match.
Referenced by got_deop(), gotjoin(), gotkick(), gotmsg(), gotnick(), and gotnotice().
00183 { 00184 char h[UHOSTLEN], ftype[12], *p; 00185 struct userrec *u; 00186 memberlist *m; 00187 int thr = 0, lapse = 0; 00188 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 00189 00190 if (!chan || (which < 0) || (which >= FLOOD_CHAN_MAX)) 00191 return 0; 00192 00193 /* Okay, make sure i'm not flood-checking myself */ 00194 if (match_my_nick(floodnick)) 00195 return 0; 00196 00197 /* My user@host (?) */ 00198 if (!egg_strcasecmp(floodhost, botuserhost)) 00199 return 0; 00200 00201 m = ismember(chan, floodnick); 00202 00203 /* Do not punish non-existant channel members and IRC services like 00204 * ChanServ 00205 */ 00206 if (!m && (which != FLOOD_JOIN)) 00207 return 0; 00208 00209 get_user_flagrec(get_user_by_host(from), &fr, chan->dname); 00210 if (glob_bot(fr) || ((which == FLOOD_DEOP) && (glob_master(fr) || 00211 chan_master(fr)) && (glob_friend(fr) || chan_friend(fr))) || 00212 ((which == FLOOD_KICK) && (glob_master(fr) || chan_master(fr)) && 00213 (glob_friend(fr) || chan_friend(fr))) || ((which != FLOOD_DEOP) && 00214 (which != FLOOD_KICK) && (glob_friend(fr) || chan_friend(fr))) || 00215 (channel_dontkickops(chan) && (chan_op(fr) || (glob_op(fr) && 00216 !chan_deop(fr))))) 00217 return 0; 00218 00219 /* Determine how many are necessary to make a flood. */ 00220 switch (which) { 00221 case FLOOD_PRIVMSG: 00222 case FLOOD_NOTICE: 00223 thr = chan->flood_pub_thr; 00224 lapse = chan->flood_pub_time; 00225 strcpy(ftype, "pub"); 00226 break; 00227 case FLOOD_CTCP: 00228 thr = chan->flood_ctcp_thr; 00229 lapse = chan->flood_ctcp_time; 00230 strcpy(ftype, "pub"); 00231 break; 00232 case FLOOD_NICK: 00233 thr = chan->flood_nick_thr; 00234 lapse = chan->flood_nick_time; 00235 strcpy(ftype, "nick"); 00236 break; 00237 case FLOOD_JOIN: 00238 thr = chan->flood_join_thr; 00239 lapse = chan->flood_join_time; 00240 strcpy(ftype, "join"); 00241 break; 00242 case FLOOD_DEOP: 00243 thr = chan->flood_deop_thr; 00244 lapse = chan->flood_deop_time; 00245 strcpy(ftype, "deop"); 00246 break; 00247 case FLOOD_KICK: 00248 thr = chan->flood_kick_thr; 00249 lapse = chan->flood_kick_time; 00250 strcpy(ftype, "kick"); 00251 break; 00252 } 00253 if ((thr == 0) || (lapse == 0)) 00254 return 0; /* no flood protection */ 00255 00256 if ((which == FLOOD_KICK) || (which == FLOOD_DEOP)) 00257 p = floodnick; 00258 else { 00259 p = strchr(floodhost, '@'); 00260 if (p) { 00261 p++; 00262 } 00263 if (!p) 00264 return 0; 00265 } 00266 if (rfc_casecmp(chan->floodwho[which], p)) { /* new */ 00267 strncpy(chan->floodwho[which], p, 80); 00268 chan->floodwho[which][80] = 0; 00269 chan->floodtime[which] = now; 00270 chan->floodnum[which] = 1; 00271 return 0; 00272 } 00273 if (chan->floodtime[which] < now - lapse) { 00274 /* Flood timer expired, reset it */ 00275 chan->floodtime[which] = now; 00276 chan->floodnum[which] = 1; 00277 return 0; 00278 } 00279 /* Deop'n the same person, sillyness ;) - so just ignore it */ 00280 if (which == FLOOD_DEOP) { 00281 if (!rfc_casecmp(chan->deopd, victim)) 00282 return 0; 00283 else 00284 strcpy(chan->deopd, victim); 00285 } 00286 chan->floodnum[which]++; 00287 if (chan->floodnum[which] >= thr) { /* FLOOD */ 00288 /* Reset counters */ 00289 chan->floodnum[which] = 0; 00290 chan->floodtime[which] = 0; 00291 chan->floodwho[which][0] = 0; 00292 if (which == FLOOD_DEOP) 00293 chan->deopd[0] = 0; 00294 u = get_user_by_host(from); 00295 if (check_tcl_flud(floodnick, floodhost, u, ftype, chan->dname)) 00296 return 0; 00297 switch (which) { 00298 case FLOOD_PRIVMSG: 00299 case FLOOD_NOTICE: 00300 case FLOOD_CTCP: 00301 /* Flooding chan! either by public or notice */ 00302 if (!chan_sentkick(m) && 00303 (me_op(chan) || (me_halfop(chan) && !chan_hasop(m)))) { 00304 putlog(LOG_MODES, chan->dname, IRC_FLOODKICK, floodnick); 00305 dprintf(DP_MODE, "KICK %s %s :%s\n", chan->name, floodnick, CHAN_FLOOD); 00306 m->flags |= SENTKICK; 00307 } 00308 return 1; 00309 case FLOOD_JOIN: 00310 case FLOOD_NICK: 00311 if (use_exempts && (u_match_mask(global_exempts, from) || 00312 u_match_mask(chan->exempts, from))) 00313 return 1; 00314 simple_sprintf(h, "*!*@%s", p); 00315 if (!isbanned(chan, h) && (me_op(chan) || me_halfop(chan))) { 00316 check_exemptlist(chan, from); 00317 do_mask(chan, chan->channel.ban, h, 'b'); 00318 } 00319 if ((u_match_mask(global_bans, from)) || 00320 (u_match_mask(chan->bans, from))) 00321 return 1; /* Already banned */ 00322 if (which == FLOOD_JOIN) 00323 putlog(LOG_MISC | LOG_JOIN, chan->dname, IRC_FLOODIGNORE3, p); 00324 else 00325 putlog(LOG_MISC | LOG_JOIN, chan->dname, IRC_FLOODIGNORE4, p); 00326 strcpy(ftype + 4, " flood"); 00327 u_addban(chan, h, botnetnick, ftype, now + (60 * chan->ban_time), 0); 00328 if (!channel_enforcebans(chan) && (me_op(chan) || me_halfop(chan))) { 00329 char s[UHOSTLEN]; 00330 00331 for (m = chan->channel.member; m && m->nick[0]; m = m->next) { 00332 sprintf(s, "%s!%s", m->nick, m->userhost); 00333 if (wild_match(h, s) && (m->joined >= chan->floodtime[which]) && 00334 !chan_sentkick(m) && !match_my_nick(m->nick) && (me_op(chan) || 00335 (me_halfop(chan) && !chan_hasop(m)))) { 00336 m->flags |= SENTKICK; 00337 if (which == FLOOD_JOIN) 00338 dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, 00339 IRC_JOIN_FLOOD); 00340 else 00341 dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, 00342 IRC_NICK_FLOOD); 00343 } 00344 } 00345 } 00346 return 1; 00347 case FLOOD_KICK: 00348 if ((me_op(chan) || (me_halfop(chan) && !chan_hasop(m))) && 00349 !chan_sentkick(m)) { 00350 putlog(LOG_MODES, chan->dname, "Kicking %s, for mass kick.", floodnick); 00351 dprintf(DP_MODE, "KICK %s %s :%s\n", chan->name, floodnick, 00352 IRC_MASSKICK); 00353 m->flags |= SENTKICK; 00354 } 00355 return 1; 00356 case FLOOD_DEOP: 00357 if ((me_op(chan) || (me_halfop(chan) && !chan_hasop(m))) && 00358 !chan_sentkick(m)) { 00359 putlog(LOG_MODES, chan->dname, CHAN_MASSDEOP, chan->dname, from); 00360 dprintf(DP_MODE, "KICK %s %s :%s\n", 00361 chan->name, floodnick, CHAN_MASSDEOP_KICK); 00362 m->flags |= SENTKICK; 00363 } 00364 return 1; 00365 } 00366 } 00367 return 0; 00368 }
Definition at line 169 of file chan.c.
References add_mode, cmp_masks, flush_mode(), maskstruct::mask, maskstruct::next, QUICK, and rfc_casecmp.
Referenced by cmd_kickban(), detect_chan_flood(), quickban(), refresh_ban_kick(), refresh_exempt(), and refresh_invite().
00170 { 00171 for (; m && m->mask[0]; m = m->next) 00172 if (cmp_masks(mask, m->mask) && rfc_casecmp(mask, m->mask)) 00173 add_mode(chan, '-', mode, m->mask); 00174 add_mode(chan, '+', mode, mask); 00175 flush_mode(chan, QUICK); 00176 }
static void enforce_bans | ( | struct chanset_t * | chan | ) | [static] |
Definition at line 518 of file chan.c.
References chan_t::ban, botname, botuserhost, chanset_t::channel, HALFOP_CANTDOMODE, IRC_YOUREBANNED, isexempted, kick_all(), maskstruct::mask, match_addr, maskstruct::next, simple_sprintf, and UHOSTLEN.
Referenced by recheck_channel().
00519 { 00520 char me[UHOSTLEN]; 00521 masklist *b; 00522 00523 if (HALFOP_CANTDOMODE('b')) 00524 return; 00525 00526 simple_sprintf(me, "%s!%s", botname, botuserhost); 00527 /* Go through all bans, kicking the users. */ 00528 for (b = chan->channel.ban; b && b->mask[0]; b = b->next) { 00529 if (!match_addr(b->mask, me)) 00530 if (!isexempted(chan, b->mask)) 00531 kick_all(chan, b->mask, IRC_YOUREBANNED, 1); 00532 } 00533 }
static char* getchanmode | ( | struct chanset_t * | chan | ) | [static] |
Definition at line 93 of file chan.c.
References CHANANON, CHANDELJN, CHANINV, CHANINVIS, CHANKEY, CHANLONLY, CHANMODER, CHANMODREG, chanset_t::channel, CHANNOAMSG, CHANNOCLR, CHANNOCTCP, CHANNOMSG, CHANNONOTC, CHANPRIV, CHANREGON, CHANSEC, CHANSTRIP, CHANTOPIC, chan_t::key, chan_t::maxmembers, and chan_t::mode.
Referenced by cmd_channel(), and status_log().
00094 { 00095 static char s[121]; 00096 int atr, i; 00097 00098 s[0] = '+'; 00099 i = 1; 00100 atr = chan->channel.mode; 00101 if (atr & CHANINV) 00102 s[i++] = 'i'; 00103 if (atr & CHANPRIV) 00104 s[i++] = 'p'; 00105 if (atr & CHANSEC) 00106 s[i++] = 's'; 00107 if (atr & CHANMODER) 00108 s[i++] = 'm'; 00109 if (atr & CHANNOCLR) 00110 s[i++] = 'c'; 00111 if (atr & CHANNOCTCP) 00112 s[i++] = 'C'; 00113 if (atr & CHANREGON) 00114 s[i++] = 'R'; 00115 if (atr & CHANTOPIC) 00116 s[i++] = 't'; 00117 if (atr & CHANMODREG) 00118 s[i++] = 'M'; 00119 if (atr & CHANLONLY) 00120 s[i++] = 'r'; 00121 if (atr & CHANDELJN) 00122 s[i++] = 'D'; 00123 if (atr & CHANSTRIP) 00124 s[i++] = 'u'; 00125 if (atr & CHANNONOTC) 00126 s[i++] = 'N'; 00127 if (atr & CHANNOAMSG) 00128 s[i++] = 'T'; 00129 if (atr & CHANINVIS) 00130 s[i++] = 'd'; 00131 if (atr & CHANNOMSG) 00132 s[i++] = 'n'; 00133 if (atr & CHANANON) 00134 s[i++] = 'a'; 00135 if (atr & CHANKEY) 00136 s[i++] = 'k'; 00137 if (chan->channel.maxmembers != 0) 00138 s[i++] = 'l'; 00139 s[i] = 0; 00140 if (chan->channel.key[0]) 00141 i += sprintf(s + i, " %s", chan->channel.key); 00142 if (chan->channel.maxmembers != 0) 00143 sprintf(s + i, " %d", chan->channel.maxmembers); 00144 return s; 00145 }
static int got315 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1126 of file chan.c.
References botname, CHAN_ACTIVE, CHAN_PEND, CHAN_STOP_CYCLE, chanset_t::channel, channel_pending, clear_channel(), chanset_t::dname, DP_SERVER, dprintf, findchan, ismember, chan_t::key, chanset_t::key, chanset_t::key_prot, LOG_JOIN, LOG_MISC, me_op(), chan_t::members, chanset_t::name, newsplit, putlog, recheck_channel(), chanset_t::status, and sync_members().
01127 { 01128 char *chname, *key; 01129 struct chanset_t *chan; 01130 01131 newsplit(&msg); 01132 chname = newsplit(&msg); 01133 chan = findchan(chname); 01134 if (!chan || !channel_pending(chan)) /* Left channel before we got a 315? */ 01135 return 0; 01136 01137 sync_members(chan); 01138 chan->status |= CHAN_ACTIVE; 01139 chan->status &= ~CHAN_PEND; 01140 if (!ismember(chan, botname)) { /* Am I on the channel now? */ 01141 putlog(LOG_MISC | LOG_JOIN, chan->dname, "Oops, I'm not really on %s.", 01142 chan->dname); 01143 clear_channel(chan, 1); 01144 chan->status &= ~CHAN_ACTIVE; 01145 01146 key = chan->channel.key[0] ? chan->channel.key : chan->key_prot; 01147 if (key[0]) 01148 dprintf(DP_SERVER, "JOIN %s %s\n", 01149 chan->name[0] ? chan->name : chan->dname, key); 01150 else 01151 dprintf(DP_SERVER, "JOIN %s\n", 01152 chan->name[0] ? chan->name : chan->dname); 01153 } else if (me_op(chan)) 01154 recheck_channel(chan, 1); 01155 else if (chan->channel.members == 1) 01156 chan->status |= CHAN_STOP_CYCLE; 01157 return 0; /* Don't check for I-Lines here. */ 01158 }
static int got324 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 931 of file chan.c.
References CHAN_ASKEDMODES, CHANANON, CHANDELJN, CHANINV, CHANINVIS, CHANKEY, CHANLONLY, CHANMODER, CHANMODREG, chanset_t::channel, CHANNOAMSG, CHANNOCLR, CHANNOCTCP, CHANNOMSG, CHANNONOTC, CHANPRIV, CHANQUIET, CHANREGON, CHANSEC, CHANSTRIP, CHANTOPIC, DP_SERVER, dprintf, findchan, IRC_UNEXPECTEDMODE, chan_t::key, LOG_MISC, chan_t::maxmembers, chan_t::mode, newsplit, NULL, putlog, recheck_channel_modes(), set_key(), and chanset_t::status.
00932 { 00933 int i = 1, ok = 0; 00934 char *p, *q, *chname; 00935 struct chanset_t *chan; 00936 00937 newsplit(&msg); 00938 chname = newsplit(&msg); 00939 chan = findchan(chname); 00940 if (!chan) { 00941 putlog(LOG_MISC, "*", "%s: %s", IRC_UNEXPECTEDMODE, chname); 00942 dprintf(DP_SERVER, "PART %s\n", chname); 00943 return 0; 00944 } 00945 if (chan->status & CHAN_ASKEDMODES) 00946 ok = 1; 00947 chan->status &= ~CHAN_ASKEDMODES; 00948 chan->channel.mode = 0; 00949 while (msg[i] != 0) { 00950 if (msg[i] == 'i') 00951 chan->channel.mode |= CHANINV; 00952 if (msg[i] == 'p') 00953 chan->channel.mode |= CHANPRIV; 00954 if (msg[i] == 's') 00955 chan->channel.mode |= CHANSEC; 00956 if (msg[i] == 'm') 00957 chan->channel.mode |= CHANMODER; 00958 if (msg[i] == 'c') 00959 chan->channel.mode |= CHANNOCLR; 00960 if (msg[i] == 'C') 00961 chan->channel.mode |= CHANNOCTCP; 00962 if (msg[i] == 'R') 00963 chan->channel.mode |= CHANREGON; 00964 if (msg[i] == 'M') 00965 chan->channel.mode |= CHANMODREG; 00966 if (msg[i] == 'r') 00967 chan->channel.mode |= CHANLONLY; 00968 if (msg[i] == 'D') 00969 chan->channel.mode |= CHANDELJN; 00970 if (msg[i] == 'u') 00971 chan->channel.mode |= CHANSTRIP; 00972 if (msg[i] == 'N') 00973 chan->channel.mode |= CHANNONOTC; 00974 if (msg[i] == 'T') 00975 chan->channel.mode |= CHANNOAMSG; 00976 if (msg[i] == 'd') 00977 chan->channel.mode |= CHANINVIS; 00978 if (msg[i] == 't') 00979 chan->channel.mode |= CHANTOPIC; 00980 if (msg[i] == 'n') 00981 chan->channel.mode |= CHANNOMSG; 00982 if (msg[i] == 'a') 00983 chan->channel.mode |= CHANANON; 00984 if (msg[i] == 'q') 00985 chan->channel.mode |= CHANQUIET; 00986 if (msg[i] == 'k') { 00987 chan->channel.mode |= CHANKEY; 00988 p = strchr(msg, ' '); 00989 if (p != NULL) { /* Test for null key assignment */ 00990 p++; 00991 q = strchr(p, ' '); 00992 if (q != NULL) { 00993 *q = 0; 00994 set_key(chan, p); 00995 strcpy(p, q + 1); 00996 } else { 00997 set_key(chan, p); 00998 *p = 0; 00999 } 01000 } 01001 if ((chan->channel.mode & CHANKEY) && (!chan->channel.key[0] || 01002 !strcmp("*", chan->channel.key))) 01003 /* Undernet use to show a blank channel key if one was set when 01004 * you first joined a channel; however, this has been replaced by 01005 * an asterisk and this has been agreed upon by other major IRC 01006 * networks so we'll check for an asterisk here as well 01007 * (guppy 22Dec2001) */ 01008 chan->status |= CHAN_ASKEDMODES; 01009 } 01010 if (msg[i] == 'l') { 01011 p = strchr(msg, ' '); 01012 if (p != NULL) { /* test for null limit assignment */ 01013 p++; 01014 q = strchr(p, ' '); 01015 if (q != NULL) { 01016 *q = 0; 01017 chan->channel.maxmembers = atoi(p); 01018 strcpy(p, q + 1); 01019 } else { 01020 chan->channel.maxmembers = atoi(p); 01021 *p = 0; 01022 } 01023 } 01024 } 01025 i++; 01026 } 01027 if (ok) 01028 recheck_channel_modes(chan); 01029 return 0; 01030 }
static int got331 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1580 of file chan.c.
References check_tcl_topc, chanset_t::dname, findchan, newsplit, NULL, and set_topic().
01581 { 01582 char *chname; 01583 struct chanset_t *chan; 01584 01585 newsplit(&msg); 01586 chname = newsplit(&msg); 01587 chan = findchan(chname); 01588 if (chan) { 01589 set_topic(chan, NULL); 01590 check_tcl_topc("*", "*", NULL, chan->dname, ""); 01591 } 01592 return 0; 01593 }
static int got332 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1598 of file chan.c.
References check_tcl_topc, chanset_t::dname, findchan, fixcolon, newsplit, NULL, and set_topic().
01599 { 01600 struct chanset_t *chan; 01601 char *chname; 01602 01603 newsplit(&msg); 01604 chname = newsplit(&msg); 01605 chan = findchan(chname); 01606 if (chan) { 01607 fixcolon(msg); 01608 set_topic(chan, msg); 01609 check_tcl_topc("*", "*", NULL, chan->dname, msg); 01610 } 01611 return 0; 01612 }
static int got346 | ( | char * | from, | |
char * | origmsg | |||
) | [static] |
Definition at line 1256 of file chan.c.
References channel_active, channel_pending, findchan, newinvite, newsplit, and use_invites.
01257 { 01258 char *invite, *who, *chname, buf[511], *msg; 01259 struct chanset_t *chan; 01260 01261 strncpy(buf, origmsg, 510); 01262 buf[510] = 0; 01263 msg = buf; 01264 if (use_invites == 0) 01265 return 0; 01266 newsplit(&msg); 01267 chname = newsplit(&msg); 01268 chan = findchan(chname); 01269 if (!chan || !(channel_pending(chan) || channel_active(chan))) 01270 return 0; 01271 invite = newsplit(&msg); 01272 who = newsplit(&msg); 01273 /* Extended timestamp format? */ 01274 if (who[0]) 01275 newinvite(chan, invite, who); 01276 else 01277 newinvite(chan, invite, "existent"); 01278 return 0; 01279 }
static int got347 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1284 of file chan.c.
References CHAN_ASKED_INVITED, findchan, chanset_t::ircnet_status, newsplit, and use_invites.
01285 { 01286 struct chanset_t *chan; 01287 char *chname; 01288 01289 if (use_invites == 1) { 01290 newsplit(&msg); 01291 chname = newsplit(&msg); 01292 chan = findchan(chname); 01293 if (chan) 01294 chan->ircnet_status &= ~CHAN_ASKED_INVITED; 01295 } 01296 return 0; 01297 }
static int got348 | ( | char * | from, | |
char * | origmsg | |||
) | [static] |
Definition at line 1209 of file chan.c.
References channel_active, channel_pending, findchan, newexempt, newsplit, and use_exempts.
01210 { 01211 char *exempt, *who, *chname, buf[511], *msg; 01212 struct chanset_t *chan; 01213 01214 if (use_exempts == 0) 01215 return 0; 01216 01217 strncpy(buf, origmsg, 510); 01218 buf[510] = 0; 01219 msg = buf; 01220 newsplit(&msg); 01221 chname = newsplit(&msg); 01222 chan = findchan(chname); 01223 if (!chan || !(channel_pending(chan) || channel_active(chan))) 01224 return 0; 01225 exempt = newsplit(&msg); 01226 who = newsplit(&msg); 01227 /* Extended timestamp format? */ 01228 if (who[0]) 01229 newexempt(chan, exempt, who); 01230 else 01231 newexempt(chan, exempt, "existent"); 01232 return 0; 01233 }
static int got349 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1238 of file chan.c.
References CHAN_ASKED_EXEMPTS, findchan, chanset_t::ircnet_status, newsplit, and use_exempts.
01239 { 01240 struct chanset_t *chan; 01241 char *chname; 01242 01243 if (use_exempts == 1) { 01244 newsplit(&msg); 01245 chname = newsplit(&msg); 01246 chan = findchan(chname); 01247 if (chan) 01248 chan->ircnet_status &= ~CHAN_ASKED_EXEMPTS; 01249 } 01250 return 0; 01251 }
static int got352 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1079 of file chan.c.
References findchan, got352or4(), newsplit, and user.
01080 { 01081 char *nick, *user, *host, *chname, *flags; 01082 struct chanset_t *chan; 01083 01084 newsplit(&msg); /* Skip my nick - effeciently */ 01085 chname = newsplit(&msg); /* Grab the channel */ 01086 chan = findchan(chname); /* See if I'm on channel */ 01087 if (chan) { /* Am I? */ 01088 user = newsplit(&msg); /* Grab the user */ 01089 host = newsplit(&msg); /* Grab the host */ 01090 newsplit(&msg); /* Skip the server */ 01091 nick = newsplit(&msg); /* Grab the nick */ 01092 flags = newsplit(&msg); /* Grab the flags */ 01093 got352or4(chan, user, host, nick, flags); 01094 } 01095 return 0; 01096 }
static int got352or4 | ( | struct chanset_t * | chan, | |
char * | user, | |||
char * | host, | |||
char * | nick, | |||
char * | flags | |||
) | [static] |
Definition at line 1032 of file chan.c.
References any_ops(), botuserhost, CHANHALFOP, CHANOP, CHANVOICE, check_tcl_need(), memstruct::delay, chanset_t::dname, do_tcl, memstruct::flags, get_user_by_host, ismember, memstruct::joined, memstruct::last, match_my_nick(), me_op(), chanset_t::need_op, newmember(), memstruct::nick, now, NULL, opchars, simple_sprintf, memstruct::split, STOPWHO, UHOSTLEN, memstruct::user, memstruct::userhost, WASHALFOP, WASOP, and WHO_SYNCED.
Referenced by got352(), and got354().
01034 { 01035 char userhost[UHOSTLEN]; 01036 memberlist *m; 01037 01038 m = ismember(chan, nick); /* In my channel list copy? */ 01039 if (!m) { /* Nope, so update */ 01040 m = newmember(chan); /* Get a new channel entry */ 01041 m->joined = m->split = m->delay = 0L; /* Don't know when he joined */ 01042 m->flags = 0; /* No flags for now */ 01043 m->last = now; /* Last time I saw him */ 01044 } 01045 strcpy(m->nick, nick); /* Store the nick in list */ 01046 /* Store the userhost */ 01047 simple_sprintf(m->userhost, "%s@%s", user, host); 01048 simple_sprintf(userhost, "%s!%s", nick, m->userhost); 01049 /* Combine n!u@h */ 01050 m->user = NULL; /* No handle match (yet) */ 01051 if (match_my_nick(nick)) /* Is it me? */ 01052 strcpy(botuserhost, m->userhost); /* Yes, save my own userhost */ 01053 m->flags |= WHO_SYNCED; 01054 if (strpbrk(flags, opchars) != NULL) 01055 m->flags |= (CHANOP | WASOP); 01056 else 01057 m->flags &= ~(CHANOP | WASOP); 01058 if (strchr(flags, '%') != NULL) 01059 m->flags |= (CHANHALFOP | WASHALFOP); 01060 else 01061 m->flags &= ~(CHANHALFOP | WASHALFOP); 01062 if (strchr(flags, '+') != NULL) 01063 m->flags |= CHANVOICE; 01064 else 01065 m->flags &= ~CHANVOICE; 01066 if (!(m->flags & (CHANVOICE | CHANOP | CHANHALFOP))) 01067 m->flags |= STOPWHO; 01068 if (match_my_nick(nick) && any_ops(chan) && !me_op(chan)) { 01069 check_tcl_need(chan->dname, "op"); 01070 if (chan->need_op[0]) 01071 do_tcl("need-op", chan->need_op); 01072 } 01073 m->user = get_user_by_host(userhost); 01074 return 0; 01075 }
static int got354 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1100 of file chan.c.
References CHANMETA, findchan, got352or4(), newsplit, NULL, use_354, and user.
01101 { 01102 char *nick, *user, *host, *chname, *flags; 01103 struct chanset_t *chan; 01104 01105 if (use_354) { 01106 newsplit(&msg); /* Skip my nick - effeciently */ 01107 if (msg[0] && (strchr(CHANMETA, msg[0]) != NULL)) { 01108 chname = newsplit(&msg); /* Grab the channel */ 01109 chan = findchan(chname); /* See if I'm on channel */ 01110 if (chan) { /* Am I? */ 01111 user = newsplit(&msg); /* Grab the user */ 01112 host = newsplit(&msg); /* Grab the host */ 01113 nick = newsplit(&msg); /* Grab the nick */ 01114 flags = newsplit(&msg); /* Grab the flags */ 01115 got352or4(chan, user, host, nick, flags); 01116 } 01117 } 01118 } 01119 return 0; 01120 }
static int got367 | ( | char * | from, | |
char * | origmsg | |||
) | [static] |
Definition at line 1163 of file chan.c.
References channel_active, channel_pending, findchan, newban, and newsplit.
01164 { 01165 char *ban, *who, *chname, buf[511], *msg; 01166 struct chanset_t *chan; 01167 01168 strncpy(buf, origmsg, 510); 01169 buf[510] = 0; 01170 msg = buf; 01171 newsplit(&msg); 01172 chname = newsplit(&msg); 01173 chan = findchan(chname); 01174 if (!chan || !(channel_pending(chan) || channel_active(chan))) 01175 return 0; 01176 ban = newsplit(&msg); 01177 who = newsplit(&msg); 01178 /* Extended timestamp format? */ 01179 if (who[0]) 01180 newban(chan, ban, who); 01181 else 01182 newban(chan, ban, "existent"); 01183 return 0; 01184 }
static int got368 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1189 of file chan.c.
References CHAN_ASKEDBANS, findchan, newsplit, and chanset_t::status.
01190 { 01191 struct chanset_t *chan; 01192 char *chname; 01193 01194 /* Okay, now add bans that i want, which aren't set yet */ 01195 newsplit(&msg); 01196 chname = newsplit(&msg); 01197 chan = findchan(chname); 01198 if (chan) 01199 chan->status &= ~CHAN_ASKEDBANS; 01200 /* If i sent a mode -b on myself (deban) in got367, either 01201 * resetbans() or recheck_bans() will flush that. 01202 */ 01203 return 0; 01204 }
static int got403 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1317 of file chan.c.
References chanset_t::dname, DP_SERVER, dprintf, findchan, findchan_by_dname, LOG_MISC, newsplit, and putlog.
01318 { 01319 char *chname; 01320 struct chanset_t *chan; 01321 01322 newsplit(&msg); 01323 chname = newsplit(&msg); 01324 if (chname && chname[0] == '!') { 01325 chan = findchan_by_dname(chname); 01326 if (!chan) { 01327 chan = findchan(chname); 01328 if (!chan) 01329 return 0; /* Ignore it */ 01330 /* We have the channel unique name, so we have attempted to join 01331 * a specific !channel that doesnt exist. Now attempt to join the 01332 * channel using it's short name. 01333 */ 01334 putlog(LOG_MISC, "*", 01335 "Unique channel %s does not exist... Attempting to join with " 01336 "short name.", chname); 01337 dprintf(DP_SERVER, "JOIN %s\n", chan->dname); 01338 } else { 01339 /* We have found the channel, so the server has given us the short 01340 * name. Prefix another '!' to it, and attempt the join again... 01341 */ 01342 putlog(LOG_MISC, "*", 01343 "Channel %s does not exist... Attempting to create it.", chname); 01344 dprintf(DP_SERVER, "JOIN !%s\n", chan->dname); 01345 } 01346 } 01347 return 0; 01348 }
static int got405 | ( | char * | from, | |
char * | msg | |||
) | [static] |
static int got471 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1352 of file chan.c.
References CHANNEL_ID_LEN, check_tcl_need(), chanset_t::dname, do_tcl, findchan_by_dname, IRC_CHANFULL, LOG_JOIN, chanset_t::need_limit, newsplit, and putlog.
01353 { 01354 char *chname; 01355 struct chanset_t *chan; 01356 01357 newsplit(&msg); 01358 chname = newsplit(&msg); 01359 /* !channel short names (also referred to as 'description names' 01360 * can be received by skipping over the unique ID. 01361 */ 01362 if ((chname[0] == '!') && (strlen(chname) > CHANNEL_ID_LEN)) { 01363 chname += CHANNEL_ID_LEN; 01364 chname[0] = '!'; 01365 } 01366 /* We use dname because name is first set on JOIN and we might not 01367 * have joined the channel yet. 01368 */ 01369 chan = findchan_by_dname(chname); 01370 if (chan) { 01371 putlog(LOG_JOIN, chan->dname, IRC_CHANFULL, chan->dname); 01372 check_tcl_need(chan->dname, "limit"); 01373 01374 chan = findchan_by_dname(chname); 01375 if (!chan) 01376 return 0; 01377 01378 if (chan->need_limit[0]) 01379 do_tcl("need-limit", chan->need_limit); 01380 } else 01381 putlog(LOG_JOIN, chname, IRC_CHANFULL, chname); 01382 return 0; 01383 }
static int got473 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1387 of file chan.c.
References CHANNEL_ID_LEN, check_tcl_need(), chanset_t::dname, do_tcl, findchan_by_dname, IRC_CHANINVITEONLY, LOG_JOIN, chanset_t::need_invite, newsplit, and putlog.
01388 { 01389 char *chname; 01390 struct chanset_t *chan; 01391 01392 newsplit(&msg); 01393 chname = newsplit(&msg); 01394 /* !channel short names (also referred to as 'description names' 01395 * can be received by skipping over the unique ID. 01396 */ 01397 if ((chname[0] == '!') && (strlen(chname) > CHANNEL_ID_LEN)) { 01398 chname += CHANNEL_ID_LEN; 01399 chname[0] = '!'; 01400 } 01401 /* We use dname because name is first set on JOIN and we might not 01402 * have joined the channel yet. 01403 */ 01404 chan = findchan_by_dname(chname); 01405 if (chan) { 01406 putlog(LOG_JOIN, chan->dname, IRC_CHANINVITEONLY, chan->dname); 01407 check_tcl_need(chan->dname, "invite"); 01408 01409 chan = findchan_by_dname(chname); 01410 if (!chan) 01411 return 0; 01412 01413 if (chan->need_invite[0]) 01414 do_tcl("need-invite", chan->need_invite); 01415 } else 01416 putlog(LOG_JOIN, chname, IRC_CHANINVITEONLY, chname); 01417 return 0; 01418 }
static int got474 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1422 of file chan.c.
References CHANNEL_ID_LEN, check_tcl_need(), chanset_t::dname, do_tcl, findchan_by_dname, IRC_BANNEDFROMCHAN, LOG_JOIN, chanset_t::need_unban, newsplit, and putlog.
01423 { 01424 char *chname; 01425 struct chanset_t *chan; 01426 01427 newsplit(&msg); 01428 chname = newsplit(&msg); 01429 /* !channel short names (also referred to as 'description names' 01430 * can be received by skipping over the unique ID. 01431 */ 01432 if ((chname[0] == '!') && (strlen(chname) > CHANNEL_ID_LEN)) { 01433 chname += CHANNEL_ID_LEN; 01434 chname[0] = '!'; 01435 } 01436 /* We use dname because name is first set on JOIN and we might not 01437 * have joined the channel yet. 01438 */ 01439 chan = findchan_by_dname(chname); 01440 if (chan) { 01441 putlog(LOG_JOIN, chan->dname, IRC_BANNEDFROMCHAN, chan->dname); 01442 check_tcl_need(chan->dname, "unban"); 01443 01444 chan = findchan_by_dname(chname); 01445 if (!chan) 01446 return 0; 01447 01448 if (chan->need_unban[0]) 01449 do_tcl("need-unban", chan->need_unban); 01450 } else 01451 putlog(LOG_JOIN, chname, IRC_BANNEDFROMCHAN, chname); 01452 return 0; 01453 }
static int got475 | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1457 of file chan.c.
References chanset_t::channel, CHANNEL_ID_LEN, channel_malloc(), check_tcl_need(), chanset_t::dname, do_tcl, DP_SERVER, dprintf, findchan_by_dname, IRC_BADCHANKEY, chan_t::key, chanset_t::key_prot, LOG_JOIN, chanset_t::need_key, newsplit, nfree, and putlog.
01458 { 01459 char *chname; 01460 struct chanset_t *chan; 01461 01462 newsplit(&msg); 01463 chname = newsplit(&msg); 01464 /* !channel short names (also referred to as 'description names' 01465 * can be received by skipping over the unique ID. 01466 */ 01467 if ((chname[0] == '!') && (strlen(chname) > CHANNEL_ID_LEN)) { 01468 chname += CHANNEL_ID_LEN; 01469 chname[0] = '!'; 01470 } 01471 /* We use dname because name is first set on JOIN and we might not 01472 * have joined the channel yet. 01473 */ 01474 chan = findchan_by_dname(chname); 01475 if (chan) { 01476 putlog(LOG_JOIN, chan->dname, IRC_BADCHANKEY, chan->dname); 01477 if (chan->channel.key[0]) { 01478 nfree(chan->channel.key); 01479 chan->channel.key = (char *) channel_malloc(1); 01480 chan->channel.key[0] = 0; 01481 01482 if (chan->key_prot[0]) 01483 dprintf(DP_SERVER, "JOIN %s %s\n", chan->dname, chan->key_prot); 01484 else 01485 dprintf(DP_SERVER, "JOIN %s\n", chan->dname); 01486 } else { 01487 check_tcl_need(chan->dname, "key"); 01488 01489 chan = findchan_by_dname(chname); 01490 if (!chan) 01491 return 0; 01492 01493 if (chan->need_key[0]) 01494 do_tcl("need-key", chan->need_key); 01495 } 01496 } else 01497 putlog(LOG_JOIN, chname, IRC_BADCHANKEY, chname); 01498 return 0; 01499 }
static int gotinvite | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1503 of file chan.c.
References chanset_t::channel, channel_active, channel_inactive, channel_pending, chanset_t::dname, DP_HELP, DP_SERVER, dprintf, findchan, findchan_by_dname, fixcolon, chan_t::key, chanset_t::key, chanset_t::key_prot, last_invchan, last_invtime, LOG_MISC, chanset_t::name, newsplit, now, putlog, rfc_casecmp, and splitnick.
01504 { 01505 char *nick, *key; 01506 struct chanset_t *chan; 01507 01508 newsplit(&msg); 01509 fixcolon(msg); 01510 nick = splitnick(&from); 01511 if (!rfc_casecmp(last_invchan, msg)) 01512 if (now - last_invtime < 30) 01513 return 0; /* Two invites to the same channel in 30 seconds? */ 01514 putlog(LOG_MISC, "*", "%s!%s invited me to %s", nick, from, msg); 01515 strncpy(last_invchan, msg, 299); 01516 last_invchan[299] = 0; 01517 last_invtime = now; 01518 chan = findchan(msg); 01519 if (!chan) 01520 /* Might be a short-name */ 01521 chan = findchan_by_dname(msg); 01522 01523 if (chan && (channel_pending(chan) || channel_active(chan))) 01524 dprintf(DP_HELP, "NOTICE %s :I'm already here.\n", nick); 01525 else if (chan && !channel_inactive(chan)) { 01526 01527 key = chan->channel.key[0] ? chan->channel.key : chan->key_prot; 01528 if (key[0]) 01529 dprintf(DP_SERVER, "JOIN %s %s\n", 01530 chan->name[0] ? chan->name : chan->dname, key); 01531 else 01532 dprintf(DP_SERVER, "JOIN %s\n", 01533 chan->name[0] ? chan->name : chan->dname); 01534 } 01535 return 0; 01536 }
static int gotjoin | ( | char * | from, | |
char * | chname | |||
) | [static] |
Definition at line 1670 of file chan.c.
References add_mode, chanset_t::aop_min, chan_t::ban, chanset_t::bans, CHAN_ACTIVE, chan_autohalfop, chan_autoop, chan_dehalfop, chan_deop, chan_friend, chan_gvoice, chan_halfop, chan_hashalfop, chan_hasop, CHAN_INACTIVE, CHAN_JUPED, chan_kick, chan_op, CHAN_PEND, chan_quiet, CHAN_RESETALL, CHAN_RESETTOPIC, chan_sentkick, CHAN_STOP_CYCLE, chan_voice, chanset_t::channel, channel_active, channel_autohalfop, channel_autoop, channel_autovoice, channel_enforcebans, channel_greet, CHANNEL_ID_LEN, channel_inactive, channel_pending, check_exemptlist(), check_tcl_join, check_tcl_rejn, memstruct::delay, detect_chan_flood(), chanset_t::dname, DP_HELP, DP_MODE, DP_SERVER, dprintf, egg_snprintf, egg_strcasecmp, chanset_t::exempts, findchan, findchan_by_dname, fixcolon, userrec::flags, memstruct::flags, FLOOD_JOIN, FR_CHAN, FR_GLOBAL, get_chanrec(), get_handle_chaninfo(), get_user, get_user_by_host, get_user_flagrec, glob_autohalfop, glob_autoop, glob_friend, glob_gvoice, glob_halfop, glob_kick, glob_op, glob_voice, global_bans, global_exempts, global_invites, userrec::handle, chanset_t::invites, IRC_COMMENTKICK, IRC_YOUREBANNED, isexempted, ismember, memstruct::joined, killmember(), memstruct::last, laston_info::laston, chanuserrec::laston, LOG_JOIN, LOG_MISC, maskstruct::mask, match_addr, match_my_nick(), me_halfop(), me_op(), chanset_t::name, newmember(), maskstruct::next, nfree, memstruct::nick, nmalloc, no_chanrec_info, NOHALFOPS_MODES, now, NULL, putlog, quickban(), refresh_ban_kick(), refresh_invite(), reset_chan_info(), SENTHALFOP, SENTKICK, SENTOP, SENTVOICE, set_delay(), set_handle_laston(), memstruct::split, splitnick, chanset_t::status, STOPWHO, u_match_mask(), UHOSTLEN, use_exempts, use_info, memstruct::user, USER_BOT, USERENTRY_COMMENT, USERENTRY_INFO, USERENTRY_LASTON, memstruct::userhost, wait_info, WASHALFOP, and WASOP.
01671 { 01672 char *nick, *p, buf[UHOSTLEN], *uhost = buf; 01673 char *ch_dname = NULL; 01674 struct chanset_t *chan; 01675 memberlist *m; 01676 masklist *b; 01677 struct userrec *u; 01678 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 01679 01680 fixcolon(chname); 01681 chan = findchan(chname); 01682 if (!chan && chname[0] == '!') { 01683 /* As this is a !channel, we need to search for it by display (short) 01684 * name now. This will happen when we initially join the channel, as we 01685 * dont know the unique channel name that the server has made up. <cybah> 01686 */ 01687 int l_chname = strlen(chname); 01688 01689 if (l_chname > (CHANNEL_ID_LEN + 1)) { 01690 ch_dname = nmalloc(l_chname + 1); 01691 if (ch_dname) { 01692 egg_snprintf(ch_dname, l_chname + 2, "!%s", 01693 chname + (CHANNEL_ID_LEN + 1)); 01694 chan = findchan_by_dname(ch_dname); 01695 if (!chan) { 01696 /* Hmm.. okay. Maybe the admin's a genius and doesn't know the 01697 * difference between id and descriptive channel names. Search 01698 * the channel name in the dname list using the id-name. 01699 */ 01700 chan = findchan_by_dname(chname); 01701 if (chan) { 01702 /* Duh, I was right. Mark this channel as inactive and log 01703 * the incident. 01704 */ 01705 chan->status |= CHAN_INACTIVE; 01706 putlog(LOG_MISC, "*", "Deactivated channel %s, because it uses " 01707 "an ID channel-name. Use the descriptive name instead.", 01708 chname); 01709 dprintf(DP_SERVER, "PART %s\n", chname); 01710 goto exit; 01711 } 01712 } 01713 } 01714 } 01715 } else if (!chan) { 01716 /* As this is not a !chan, we need to search for it by display name now. 01717 * Unlike !chan's, we dont need to remove the unique part. 01718 */ 01719 chan = findchan_by_dname(chname); 01720 } 01721 01722 if (!chan || channel_inactive(chan)) { 01723 strcpy(uhost, from); 01724 nick = splitnick(&uhost); 01725 if (match_my_nick(nick)) { 01726 putlog(LOG_MISC, "*", "joined %s but didn't want to!", chname); 01727 dprintf(DP_MODE, "PART %s\n", chname); 01728 } 01729 } else if (!channel_pending(chan)) { 01730 chan->status &= ~CHAN_STOP_CYCLE; 01731 strcpy(uhost, from); 01732 nick = splitnick(&uhost); 01733 detect_chan_flood(nick, uhost, from, chan, FLOOD_JOIN, NULL); 01734 01735 chan = findchan(chname); 01736 if (!chan) { 01737 if (ch_dname) 01738 chan = findchan_by_dname(ch_dname); 01739 else 01740 chan = findchan_by_dname(chname); 01741 } 01742 if (!chan) 01743 /* The channel doesn't exist anymore, so get out of here. */ 01744 goto exit; 01745 01746 /* Grab last time joined before we update it */ 01747 u = get_user_by_host(from); 01748 get_user_flagrec(u, &fr, chan->dname); /* Lam: fix to work with !channels */ 01749 if (!channel_active(chan) && !match_my_nick(nick)) { 01750 /* uh, what?! i'm on the channel?! */ 01751 putlog(LOG_MISC, chan->dname, 01752 "confused bot: guess I'm on %s and didn't realize it", 01753 chan->dname); 01754 chan->status |= CHAN_ACTIVE; 01755 chan->status &= ~CHAN_PEND; 01756 reset_chan_info(chan, CHAN_RESETALL); 01757 } else { 01758 m = ismember(chan, nick); 01759 if (m && m->split && !egg_strcasecmp(m->userhost, uhost)) { 01760 check_tcl_rejn(nick, uhost, u, chan->dname); 01761 01762 chan = findchan(chname); 01763 if (!chan) { 01764 if (ch_dname) 01765 chan = findchan_by_dname(ch_dname); 01766 else 01767 chan = findchan_by_dname(chname); 01768 } 01769 if (!chan) 01770 /* The channel doesn't exist anymore, so get out of here. */ 01771 goto exit; 01772 01773 /* The tcl binding might have deleted the current user. Recheck. */ 01774 u = get_user_by_host(from); 01775 m->split = 0; 01776 m->last = now; 01777 m->delay = 0L; 01778 m->flags = (chan_hasop(m) ? WASOP : 0) | (chan_hashalfop(m) ? WASHALFOP : 0); 01779 m->user = u; 01780 set_handle_laston(chan->dname, u, now); 01781 m->flags |= STOPWHO; 01782 putlog(LOG_JOIN, chan->dname, "%s (%s) returned to %s.", nick, uhost, 01783 chan->dname); 01784 } else { 01785 if (m) 01786 killmember(chan, nick); 01787 m = newmember(chan); 01788 m->joined = now; 01789 m->split = 0L; 01790 m->flags = 0; 01791 m->last = now; 01792 m->delay = 0L; 01793 strcpy(m->nick, nick); 01794 strcpy(m->userhost, uhost); 01795 m->user = u; 01796 m->flags |= STOPWHO; 01797 01798 check_tcl_join(nick, uhost, u, chan->dname); 01799 01800 /* The tcl binding might have deleted the current user and the 01801 * current channel, so we'll now have to re-check whether they 01802 * both still exist. 01803 */ 01804 chan = findchan(chname); 01805 if (!chan) { 01806 if (ch_dname) 01807 chan = findchan_by_dname(ch_dname); 01808 else 01809 chan = findchan_by_dname(chname); 01810 } 01811 if (!chan) 01812 /* The channel doesn't exist anymore, so get out of here. */ 01813 goto exit; 01814 01815 /* The record saved in the channel record always gets updated, 01816 * so we can use that. */ 01817 u = m->user; 01818 01819 if (match_my_nick(nick)) { 01820 /* It was me joining! Need to update the channel record with the 01821 * unique name for the channel (as the server see's it). <cybah> 01822 */ 01823 strncpy(chan->name, chname, 81); 01824 chan->name[80] = 0; 01825 chan->status &= ~CHAN_JUPED; 01826 01827 /* ... and log us joining. Using chan->dname for the channel is 01828 * important in this case. As the config file will never contain 01829 * logs with the unique name. 01830 */ 01831 if (chname[0] == '!') 01832 putlog(LOG_JOIN | LOG_MISC, chan->dname, "%s joined %s (%s)", 01833 nick, chan->dname, chname); 01834 else 01835 putlog(LOG_JOIN | LOG_MISC, chan->dname, "%s joined %s.", nick, 01836 chname); 01837 reset_chan_info(chan, (CHAN_RESETALL & ~CHAN_RESETTOPIC)); 01838 } else { 01839 struct chanuserrec *cr; 01840 01841 putlog(LOG_JOIN, chan->dname, 01842 "%s (%s) joined %s.", nick, uhost, chan->dname); 01843 /* Don't re-display greeting if they've been on the channel 01844 * recently. 01845 */ 01846 if (u) { 01847 struct laston_info *li = 0; 01848 01849 cr = get_chanrec(m->user, chan->dname); 01850 if (!cr && no_chanrec_info) 01851 li = get_user(&USERENTRY_LASTON, m->user); 01852 if (channel_greet(chan) && use_info && 01853 ((cr && now - cr->laston > wait_info) || 01854 (no_chanrec_info && (!li || now - li->laston > wait_info)))) { 01855 char s1[512], *s; 01856 01857 if (!(u->flags & USER_BOT)) { 01858 s = get_user(&USERENTRY_INFO, u); 01859 get_handle_chaninfo(u->handle, chan->dname, s1); 01860 /* Locked info line overides non-locked channel specific 01861 * info line. 01862 */ 01863 if (!s || (s1[0] && (s[0] != '@' || s1[0] == '@'))) 01864 s = s1; 01865 if (s[0] == '@') 01866 s++; 01867 if (s && s[0]) 01868 dprintf(DP_HELP, "PRIVMSG %s :[%s] %s\n", chan->name, nick, 01869 s); 01870 } 01871 } 01872 } 01873 set_handle_laston(chan->dname, u, now); 01874 } 01875 } 01876 if (me_op(chan) || me_halfop(chan)) { 01877 /* Check for and reset exempts and invites. 01878 * 01879 * This will require further checking to account for when to use the 01880 * various modes. 01881 */ 01882 if ((me_op(chan) || (strchr(NOHALFOPS_MODES, 'I') == NULL)) && 01883 (u_match_mask(global_invites, from) || 01884 u_match_mask(chan->invites, from))) 01885 refresh_invite(chan, from); 01886 if ((me_op(chan) || (strchr(NOHALFOPS_MODES, 'b') == NULL)) && 01887 (!use_exempts || (!u_match_mask(global_exempts, from) && 01888 !u_match_mask(chan->exempts, from)))) { 01889 if (channel_enforcebans(chan) && !chan_op(fr) && !glob_op(fr) && 01890 !glob_friend(fr) && !chan_friend(fr) && !chan_sentkick(m) && 01891 (!use_exempts || !isexempted(chan, from)) && (me_op(chan) || 01892 (me_halfop(chan) && !chan_hasop(m)))) { 01893 for (b = chan->channel.ban; b->mask[0]; b = b->next) { 01894 if (match_addr(b->mask, from)) { 01895 dprintf(DP_SERVER, "KICK %s %s :%s\n", chname, m->nick, 01896 IRC_YOUREBANNED); 01897 m->flags |= SENTKICK; 01898 goto exit; 01899 } 01900 } 01901 } 01902 /* If it matches a ban, dispose of them. */ 01903 if (u_match_mask(global_bans, from) || u_match_mask(chan->bans, from)) 01904 refresh_ban_kick(chan, from, nick); 01905 else if (!chan_sentkick(m) && (glob_kick(fr) || chan_kick(fr)) && 01906 (me_op(chan) || (me_halfop(chan) && !chan_hasop(m)))) { 01907 check_exemptlist(chan, from); 01908 quickban(chan, from); 01909 p = get_user(&USERENTRY_COMMENT, m->user); 01910 dprintf(DP_MODE, "KICK %s %s :%s\n", chname, nick, 01911 (p && (p[0] != '@')) ? p : IRC_COMMENTKICK); 01912 m->flags |= SENTKICK; 01913 } 01914 } 01915 #ifdef NO_HALFOP_CHANMODES 01916 if (me_op(chan)) { 01917 #endif 01918 if ((me_op(chan) || (strchr(NOHALFOPS_MODES, 'o') == NULL)) && 01919 (chan_op(fr) || (glob_op(fr) && !chan_deop(fr))) && 01920 (channel_autoop(chan) || glob_autoop(fr) || chan_autoop(fr))) { 01921 if (!chan->aop_min) 01922 add_mode(chan, '+', 'o', nick); 01923 else { 01924 set_delay(chan, nick); 01925 m->flags |= SENTOP; 01926 } 01927 } else if ((me_op(chan) || (strchr(NOHALFOPS_MODES, 'h') == NULL)) && 01928 (chan_halfop(fr) || (glob_halfop(fr) && 01929 !chan_dehalfop(fr))) && (channel_autohalfop(chan) || 01930 glob_autohalfop(fr) || chan_autohalfop(fr))) { 01931 if (!chan->aop_min) 01932 add_mode(chan, '+', 'h', nick); 01933 else { 01934 set_delay(chan, nick); 01935 m->flags |= SENTHALFOP; 01936 } 01937 } else if ((me_op(chan) || (strchr(NOHALFOPS_MODES, 'v') == NULL)) && 01938 ((channel_autovoice(chan) && (chan_voice(fr) || 01939 (glob_voice(fr) && !chan_quiet(fr)))) || 01940 ((glob_gvoice(fr) || chan_gvoice(fr)) && 01941 !chan_quiet(fr)))) { 01942 if (!chan->aop_min) 01943 add_mode(chan, '+', 'v', nick); 01944 else { 01945 set_delay(chan, nick); 01946 m->flags |= SENTVOICE; 01947 } 01948 } 01949 #ifdef NO_HALFOP_CHANMODES 01950 } 01951 #endif 01952 } 01953 } 01954 } 01955 01956 exit: 01957 if (ch_dname) 01958 nfree(ch_dname); 01959 return 0; 01960 }
static int gotkick | ( | char * | from, | |
char * | origmsg | |||
) | [static] |
Definition at line 2029 of file chan.c.
References CHAN_ACTIVE, CHAN_PEND, chanset_t::channel, channel_active, channel_inactive, channel_pending, check_lonely_channel(), check_tcl_kick(), clear_channel(), detect_chan_flood(), chanset_t::dname, DP_SERVER, dprintf, findchan, fixcolon, FLOOD_KICK, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, ismember, chan_t::key, chanset_t::key_prot, killmember(), memstruct::last, LOG_MODES, match_my_nick(), maybe_revenge(), chanset_t::name, newsplit, memstruct::nick, now, putlog, REVENGE_KICK, set_handle_laston(), simple_sprintf, splitnick, chanset_t::status, UHOSTLEN, and memstruct::userhost.
02030 { 02031 char *nick, *whodid, *chname, s1[UHOSTLEN], buf[UHOSTLEN], *uhost = buf; 02032 char buf2[511], *msg, *key; 02033 memberlist *m; 02034 struct chanset_t *chan; 02035 struct userrec *u; 02036 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 02037 02038 strncpy(buf2, origmsg, 510); 02039 buf2[510] = 0; 02040 msg = buf2; 02041 chname = newsplit(&msg); 02042 chan = findchan(chname); 02043 if (!chan) 02044 return 0; 02045 nick = newsplit(&msg); 02046 if (match_my_nick(nick) && channel_pending(chan) && 02047 !channel_inactive(chan)) { 02048 chan->status &= ~(CHAN_ACTIVE | CHAN_PEND); 02049 02050 key = chan->channel.key[0] ? chan->channel.key : chan->key_prot; 02051 if (key[0]) 02052 dprintf(DP_SERVER, "JOIN %s %s\n", 02053 chan->name[0] ? chan->name : chan->dname, key); 02054 else 02055 dprintf(DP_SERVER, "JOIN %s\n", 02056 chan->name[0] ? chan->name : chan->dname); 02057 clear_channel(chan, 1); 02058 return 0; /* rejoin if kicked before getting needed info <Wcc[08/08/02]> */ 02059 } 02060 if (channel_active(chan)) { 02061 fixcolon(msg); 02062 u = get_user_by_host(from); 02063 strcpy(uhost, from); 02064 whodid = splitnick(&uhost); 02065 detect_chan_flood(whodid, uhost, from, chan, FLOOD_KICK, nick); 02066 02067 chan = findchan(chname); 02068 if (!chan) 02069 return 0; 02070 02071 m = ismember(chan, whodid); 02072 if (m) 02073 m->last = now; 02074 /* This _needs_ to use chan->dname <cybah> */ 02075 get_user_flagrec(u, &fr, chan->dname); 02076 set_handle_laston(chan->dname, u, now); 02077 check_tcl_kick(whodid, uhost, u, chan->dname, nick, msg); 02078 02079 chan = findchan(chname); 02080 if (!chan) 02081 return 0; 02082 02083 m = ismember(chan, nick); 02084 if (m) { 02085 struct userrec *u2; 02086 02087 simple_sprintf(s1, "%s!%s", m->nick, m->userhost); 02088 u2 = get_user_by_host(s1); 02089 set_handle_laston(chan->dname, u2, now); 02090 maybe_revenge(chan, from, s1, REVENGE_KICK); 02091 } 02092 putlog(LOG_MODES, chan->dname, "%s kicked from %s by %s: %s", s1, 02093 chan->dname, from, msg); 02094 /* Kicked ME?!? the sods! */ 02095 if (match_my_nick(nick) && !channel_inactive(chan)) { 02096 chan->status &= ~(CHAN_ACTIVE | CHAN_PEND); 02097 02098 key = chan->channel.key[0] ? chan->channel.key : chan->key_prot; 02099 if (key[0]) 02100 dprintf(DP_SERVER, "JOIN %s %s\n", 02101 chan->name[0] ? chan->name : chan->dname, key); 02102 else 02103 dprintf(DP_SERVER, "JOIN %s\n", 02104 chan->name[0] ? chan->name : chan->dname); 02105 clear_channel(chan, 1); 02106 } else { 02107 killmember(chan, nick); 02108 check_lonely_channel(chan); 02109 } 02110 } 02111 return 0; 02112 }
static int gotmsg | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 2285 of file chan.c.
References addignore, answer_ctcp, ban_fun, chanset_t::ban_time, botnetnick, chan_deop, chan_friend, chan_hasop, chan_op, chan_sentkick, CHANMETA, channel_dontkickops, check_exemptlist(), check_tcl_ctcp, check_tcl_pub(), check_tcl_pubm(), count_ctcp, ctcp_mode, ctcp_reply, detect_avalanche(), detect_chan_flood(), chanset_t::dname, DP_HELP, DP_SERVER, dprintf, exclusive_binds, chanset_t::exempts, findchan, fixcolon, memstruct::flags, FLOOD_CTCP, FLOOD_PRIVMSG, flud_ctcp_thr, flud_ctcp_time, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, glob_friend, glob_op, global_exempts, ignore_time, IRC_FUNKICK, ismember, kick_fun, last_ctcp, LOG_MODES, LOG_PUBLIC, match_ignore, me_halfop(), me_op(), chanset_t::name, newsplit, now, NULL, putlog, quickban(), SENTKICK, simple_sprintf, splitnick, trigger_on_ignore, u_addban(), u_match_mask(), UHOSTLEN, update_idle(), and use_exempts.
02286 { 02287 char *to, *realto, buf[UHOSTLEN], *nick, buf2[512], *uhost = buf, *p, *p1, 02288 *code, *ctcp; 02289 int ctcp_count = 0, ignoring; 02290 struct chanset_t *chan; 02291 struct userrec *u; 02292 memberlist *m; 02293 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 02294 02295 /* Only handle if message is to a channel, or to @#channel. */ 02296 /* FIXME: Properly handle ovNotices (@+#channel), vNotices (+#channel), etc. */ 02297 if (!strchr(CHANMETA "@", msg[0])) 02298 return 0; 02299 02300 to = newsplit(&msg); 02301 realto = (to[0] == '@') ? to + 1 : to; 02302 chan = findchan(realto); 02303 if (!chan) 02304 return 0; /* Unknown channel; don't process. */ 02305 02306 fixcolon(msg); 02307 strcpy(uhost, from); 02308 nick = splitnick(&uhost); 02309 ignoring = match_ignore(from); 02310 /* Only check if flood-ctcp is active */ 02311 if (flud_ctcp_thr && detect_avalanche(msg)) { 02312 u = get_user_by_host(from); 02313 get_user_flagrec(u, &fr, chan->dname); 02314 m = ismember(chan, nick); 02315 /* Discard -- kick user if it was to the channel */ 02316 if (m && (me_op(chan) || (me_halfop(chan) && !chan_hasop(m))) && 02317 !chan_sentkick(m) && !chan_friend(fr) && !glob_friend(fr) && 02318 !(channel_dontkickops(chan) && (chan_op(fr) || (glob_op(fr) && 02319 !chan_deop(fr)))) && !(use_exempts && ban_fun && 02320 (u_match_mask(global_exempts, from) || 02321 u_match_mask(chan->exempts, from)))) { 02322 if (ban_fun) { 02323 check_exemptlist(chan, from); 02324 u_addban(chan, quickban(chan, uhost), botnetnick, IRC_FUNKICK, 02325 now + (60 * chan->ban_time), 0); 02326 } 02327 if (kick_fun) { 02328 /* This can induce kickflood - arthur2 */ 02329 dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, nick, IRC_FUNKICK); 02330 m->flags |= SENTKICK; 02331 } 02332 } 02333 if (!ignoring) { 02334 putlog(LOG_MODES, "*", "Avalanche from %s!%s in %s - ignoring", 02335 nick, uhost, chan->dname); 02336 p = strchr(uhost, '@'); 02337 if (p) 02338 p++; 02339 else 02340 p = uhost; 02341 simple_sprintf(buf2, "*!*@%s", p); 02342 addignore(buf2, botnetnick, "ctcp avalanche", now + (60 * ignore_time)); 02343 } 02344 return 0; 02345 } 02346 /* Check for CTCP: */ 02347 ctcp_reply[0] = 0; 02348 p = strchr(msg, 1); 02349 while (p && *p) { 02350 p++; 02351 p1 = p; 02352 while ((*p != 1) && *p) 02353 p++; 02354 if (*p == 1) { 02355 *p = 0; 02356 ctcp = buf2; 02357 strcpy(ctcp, p1); 02358 strcpy(p1 - 1, p + 1); 02359 detect_chan_flood(nick, uhost, from, chan, strncmp(ctcp, "ACTION ", 7) ? 02360 FLOOD_CTCP : FLOOD_PRIVMSG, NULL); 02361 02362 chan = findchan(realto); 02363 if (!chan) 02364 return 0; 02365 02366 /* Respond to the first answer_ctcp */ 02367 p = strchr(msg, 1); 02368 if (ctcp_count < answer_ctcp) { 02369 ctcp_count++; 02370 if (ctcp[0] != ' ') { 02371 code = newsplit(&ctcp); 02372 u = get_user_by_host(from); 02373 if (!ignoring || trigger_on_ignore) { 02374 if (!check_tcl_ctcp(nick, uhost, u, to, code, ctcp)) { 02375 chan = findchan(realto); 02376 if (!chan) 02377 return 0; 02378 02379 update_idle(chan->dname, nick); 02380 } 02381 if (!ignoring) { 02382 /* Log DCC, it's to a channel damnit! */ 02383 if (!strcmp(code, "ACTION")) { 02384 putlog(LOG_PUBLIC, chan->dname, "Action: %s %s", nick, ctcp); 02385 } else { 02386 putlog(LOG_PUBLIC, chan->dname, 02387 "CTCP %s: %s from %s (%s) to %s", code, ctcp, nick, 02388 from, to); 02389 } 02390 } 02391 } 02392 } 02393 } 02394 } 02395 } 02396 02397 /* Send out possible ctcp responses. */ 02398 if (ctcp_reply[0]) { 02399 if (ctcp_mode != 2) { 02400 dprintf(DP_HELP, "NOTICE %s :%s\n", nick, ctcp_reply); 02401 } else { 02402 if (now - last_ctcp > flud_ctcp_time) { 02403 dprintf(DP_HELP, "NOTICE %s :%s\n", nick, ctcp_reply); 02404 count_ctcp = 1; 02405 } else if (count_ctcp < flud_ctcp_thr) { 02406 dprintf(DP_HELP, "NOTICE %s :%s\n", nick, ctcp_reply); 02407 count_ctcp++; 02408 } 02409 last_ctcp = now; 02410 } 02411 } 02412 02413 if (msg[0]) { 02414 int result = 0; 02415 02416 /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */ 02417 detect_chan_flood(nick, uhost, from, chan, FLOOD_PRIVMSG, NULL); 02418 02419 chan = findchan(realto); 02420 if (!chan) 02421 return 0; 02422 02423 update_idle(chan->dname, nick); 02424 02425 if (!ignoring || trigger_on_ignore) { 02426 result = check_tcl_pubm(nick, uhost, chan->dname, msg); 02427 02428 if (!result || !exclusive_binds) 02429 if (check_tcl_pub(nick, uhost, chan->dname, msg)) 02430 return 0; 02431 } 02432 02433 if (!ignoring && result != 2) { 02434 if (to[0] == '@') 02435 putlog(LOG_PUBLIC, chan->dname, "@<%s> %s", nick, msg); 02436 else 02437 putlog(LOG_PUBLIC, chan->dname, "<%s> %s", nick, msg); 02438 } 02439 } 02440 return 0; 02441 }
static int gotnick | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 2116 of file chan.c.
References chan_sentdehalfop, chan_sentdeop, chan_sentdevoice, chan_senthalfop, chan_sentkick, chan_sentop, chan_sentvoice, chan_stopcheck, chanset, check_tcl_nick, check_this_member(), clear_chanlist_member, detect_chan_flood(), chanset_t::dname, findchan_by_dname, fixcolon, memstruct::flags, FLOOD_NICK, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, ismember, killmember(), memstruct::last, LOG_JOIN, LOG_MISC, chanset_t::next, memstruct::nick, now, NULL, putlog, rfc_casecmp, SENTDEHALFOP, SENTDEOP, SENTDEVOICE, SENTHALFOP, SENTKICK, SENTOP, SENTVOICE, memstruct::split, splitnick, STOPCHECK, UHOSTLEN, and memstruct::user.
02117 { 02118 char *nick, *chname, s1[UHOSTLEN], buf[UHOSTLEN], *uhost = buf; 02119 unsigned char found = 0; 02120 memberlist *m, *mm; 02121 struct chanset_t *chan, *oldchan = NULL; 02122 struct userrec *u; 02123 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 02124 02125 strcpy(uhost, from); 02126 nick = splitnick(&uhost); 02127 fixcolon(msg); 02128 clear_chanlist_member(nick); /* Cache for nick 'nick' is meaningless now. */ 02129 for (chan = chanset; chan; chan = chan->next) { 02130 oldchan = chan; 02131 chname = chan->dname; 02132 m = ismember(chan, nick); 02133 if (m) { 02134 putlog(LOG_JOIN, chan->dname, "Nick change: %s -> %s", nick, msg); 02135 m->last = now; 02136 if (rfc_casecmp(nick, msg)) { 02137 /* Not just a capitalization change */ 02138 mm = ismember(chan, msg); 02139 if (mm) { 02140 /* Someone on channel with old nick?! */ 02141 if (mm->split) 02142 putlog(LOG_JOIN, chan->dname, 02143 "Possible future nick collision: %s", mm->nick); 02144 else 02145 putlog(LOG_MISC, chan->dname, 02146 "* Bug: nick change to existing nick"); 02147 killmember(chan, mm->nick); 02148 } 02149 } 02150 /* 02151 * Banned? 02152 */ 02153 /* Compose a nick!user@host for the new nick */ 02154 sprintf(s1, "%s!%s", msg, uhost); 02155 strcpy(m->nick, msg); 02156 detect_chan_flood(msg, uhost, from, chan, FLOOD_NICK, NULL); 02157 02158 if (!findchan_by_dname(chname)) { 02159 chan = oldchan; 02160 continue; 02161 } 02162 /* don't fill the serverqueue with modes or kicks in a nickflood */ 02163 if (chan_sentkick(m) || chan_sentdeop(m) || chan_sentop(m) || 02164 chan_sentdehalfop(m) || chan_senthalfop(m) || chan_sentdevoice(m) || 02165 chan_sentvoice(m)) 02166 m->flags |= STOPCHECK; 02167 /* Any pending kick or mode to the old nick is lost. */ 02168 m->flags &= ~(SENTKICK | SENTDEOP | SENTOP | SENTDEHALFOP | SENTHALFOP | 02169 SENTVOICE | SENTDEVOICE); 02170 /* nick-ban or nick is +k or something? */ 02171 if (!chan_stopcheck(m)) { 02172 get_user_flagrec(m->user ? m->user : get_user_by_host(s1), &fr, 02173 chan->dname); 02174 check_this_member(chan, m->nick, &fr); 02175 } 02176 /* Make sure this is in the loop, someone could have changed the record 02177 * in an earlier iteration of the loop. */ 02178 u = get_user_by_host(from); 02179 found = 1; 02180 check_tcl_nick(nick, uhost, u, chan->dname, msg); 02181 02182 if (!findchan_by_dname(chname)) { 02183 chan = oldchan; 02184 continue; 02185 } 02186 } 02187 } 02188 if (!found) { 02189 u = get_user_by_host(from); 02190 s1[0] = '*'; 02191 s1[1] = 0; 02192 check_tcl_nick(nick, uhost, u, s1, msg); 02193 } 02194 return 0; 02195 }
static int gotnotice | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 2445 of file chan.c.
References ban_fun, chanset_t::ban_time, botnetnick, chan_deop, chan_friend, chan_op, chan_sentkick, CHANMETA, channel_dontkickops, check_exemptlist(), check_tcl_ctcr, check_tcl_notc(), detect_avalanche(), detect_chan_flood(), chanset_t::dname, DP_SERVER, dprintf, chanset_t::exempts, findchan, fixcolon, memstruct::flags, FLOOD_CTCP, FLOOD_NOTICE, FLOOD_PRIVMSG, flud_ctcp_thr, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, glob_friend, glob_op, global_exempts, IRC_FUNKICK, ismember, kick_fun, LOG_MODES, LOG_PUBLIC, match_ignore, me_op(), chanset_t::name, newsplit, now, NULL, putlog, quickban(), SENTKICK, splitnick, trigger_on_ignore, u_addban(), u_match_mask(), update_idle(), and use_exempts.
02446 { 02447 char *to, *realto, *nick, buf2[512], *p, *p1, buf[512], *uhost = buf; 02448 char *ctcp, *code; 02449 struct userrec *u; 02450 memberlist *m; 02451 struct chanset_t *chan; 02452 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 02453 int ignoring; 02454 02455 if (!strchr(CHANMETA "@", *msg)) 02456 return 0; 02457 ignoring = match_ignore(from); 02458 to = newsplit(&msg); 02459 realto = (*to == '@') ? to + 1 : to; 02460 chan = findchan(realto); 02461 if (!chan) 02462 return 0; /* Notice to an unknown channel?? */ 02463 fixcolon(msg); 02464 strcpy(uhost, from); 02465 nick = splitnick(&uhost); 02466 u = get_user_by_host(from); 02467 if (flud_ctcp_thr && detect_avalanche(msg)) { 02468 get_user_flagrec(u, &fr, chan->dname); 02469 m = ismember(chan, nick); 02470 /* Discard -- kick user if it was to the channel */ 02471 if (me_op(chan) && m && !chan_sentkick(m) && !chan_friend(fr) && 02472 !glob_friend(fr) && !(channel_dontkickops(chan) && (chan_op(fr) || 02473 (glob_op(fr) && !chan_deop(fr)))) && !(use_exempts && ban_fun && 02474 (u_match_mask(global_exempts, from) || 02475 u_match_mask(chan->exempts, from)))) { 02476 if (ban_fun) { 02477 check_exemptlist(chan, from); 02478 u_addban(chan, quickban(chan, uhost), botnetnick, 02479 IRC_FUNKICK, now + (60 * chan->ban_time), 0); 02480 } 02481 if (kick_fun) { 02482 /* This can induce kickflood - arthur2 */ 02483 dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, nick, IRC_FUNKICK); 02484 m->flags |= SENTKICK; 02485 } 02486 } 02487 if (!ignoring) 02488 putlog(LOG_MODES, "*", "Avalanche from %s", from); 02489 return 0; 02490 } 02491 /* Check for CTCP: */ 02492 p = strchr(msg, 1); 02493 while (p && *p) { 02494 p++; 02495 p1 = p; 02496 while ((*p != 1) && *p) 02497 p++; 02498 if (*p == 1) { 02499 *p = 0; 02500 ctcp = buf2; 02501 strcpy(ctcp, p1); 02502 strcpy(p1 - 1, p + 1); 02503 p = strchr(msg, 1); 02504 detect_chan_flood(nick, uhost, from, chan, 02505 strncmp(ctcp, "ACTION ", 7) ? 02506 FLOOD_CTCP : FLOOD_PRIVMSG, NULL); 02507 02508 chan = findchan(realto); 02509 if (!chan) 02510 return 0; 02511 02512 if (ctcp[0] != ' ') { 02513 code = newsplit(&ctcp); 02514 if (!ignoring || trigger_on_ignore) { 02515 check_tcl_ctcr(nick, uhost, u, chan->dname, code, msg); 02516 02517 chan = findchan(realto); 02518 if (!chan) 02519 return 0; 02520 02521 if (!ignoring) { 02522 putlog(LOG_PUBLIC, chan->dname, 02523 "CTCP reply %s: %s from %s (%s) to %s", code, msg, nick, 02524 from, chan->dname); 02525 update_idle(chan->dname, nick); 02526 } 02527 } 02528 } 02529 } 02530 } 02531 if (msg[0]) { 02532 02533 /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */ 02534 detect_chan_flood(nick, uhost, from, chan, FLOOD_NOTICE, NULL); 02535 02536 chan = findchan(realto); 02537 if (!chan) 02538 return 0; 02539 02540 update_idle(chan->dname, nick); 02541 02542 if (!ignoring || trigger_on_ignore) 02543 if (check_tcl_notc(nick, uhost, u, to, msg) == 2) 02544 return 0; 02545 02546 if (!ignoring) 02547 putlog(LOG_PUBLIC, chan->dname, "-%s:%s- %s", nick, to, msg); 02548 } 02549 return 0; 02550 }
static int gotpart | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1964 of file chan.c.
References CHAN_ACTIVE, CHAN_PEND, CHAN_RESETALL, chanset_t::channel, channel_active, channel_inactive, channel_pending, check_lonely_channel(), check_tcl_part(), clear_channel(), chanset_t::dname, DP_SERVER, dprintf, findchan, fixcolon, get_user_by_host, chan_t::key, chanset_t::key_prot, killmember(), LOG_JOIN, LOG_MISC, match_my_nick(), chanset_t::name, newsplit, now, putlog, reset_chan_info(), set_handle_laston(), splitnick, and chanset_t::status.
01965 { 01966 char *nick, *chname, *key; 01967 struct chanset_t *chan; 01968 struct userrec *u; 01969 01970 chname = newsplit(&msg); 01971 fixcolon(chname); 01972 fixcolon(msg); 01973 chan = findchan(chname); 01974 if (chan && channel_inactive(chan)) { 01975 clear_channel(chan, 1); 01976 chan->status &= ~(CHAN_ACTIVE | CHAN_PEND); 01977 return 0; 01978 } 01979 if (chan && !channel_pending(chan)) { 01980 u = get_user_by_host(from); 01981 nick = splitnick(&from); 01982 if (!channel_active(chan)) { 01983 /* whoa! */ 01984 putlog(LOG_MISC, chan->dname, 01985 "confused bot: guess I'm on %s and didn't realize it", 01986 chan->dname); 01987 chan->status |= CHAN_ACTIVE; 01988 chan->status &= ~CHAN_PEND; 01989 reset_chan_info(chan, CHAN_RESETALL); 01990 } 01991 set_handle_laston(chan->dname, u, now); 01992 /* This must be directly above the killmember, in case we're doing anything 01993 * to the record that would affect the above */ 01994 check_tcl_part(nick, from, u, chan->dname, msg); 01995 01996 chan = findchan(chname); 01997 if (!chan) 01998 return 0; 01999 02000 killmember(chan, nick); 02001 if (msg[0]) 02002 putlog(LOG_JOIN, chan->dname, "%s (%s) left %s (%s).", nick, from, 02003 chan->dname, msg); 02004 else 02005 putlog(LOG_JOIN, chan->dname, "%s (%s) left %s.", nick, from, 02006 chan->dname); 02007 /* If it was me, all hell breaks loose... */ 02008 if (match_my_nick(nick)) { 02009 clear_channel(chan, 1); 02010 chan->status &= ~(CHAN_ACTIVE | CHAN_PEND); 02011 if (!channel_inactive(chan)) { 02012 02013 key = chan->channel.key[0] ? chan->channel.key : chan->key_prot; 02014 if (key[0]) 02015 dprintf(DP_SERVER, "JOIN %s %s\n", 02016 chan->name[0] ? chan->name : chan->dname, key); 02017 else 02018 dprintf(DP_SERVER, "JOIN %s\n", 02019 chan->name[0] ? chan->name : chan->dname); 02020 } 02021 } else 02022 check_lonely_channel(chan); 02023 } 02024 return 0; 02025 }
static int gotquit | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 2199 of file chan.c.
References botname, chanset, check_lonely_channel(), check_tcl_sign, check_tcl_splt, chanset_t::dname, DP_SERVER, dprintf, findchan_by_dname, fixcolon, get_altbotnick(), get_user_by_host, IRC_GETALTNICK, IRC_GETORIGNICK, ismember, keepnick, killmember(), LOG_JOIN, LOG_MISC, chanset_t::next, NICKMAX, now, NULL, origbotname, putlog, rfc_casecmp, set_handle_laston(), memstruct::split, splitnick, and UHOSTMAX.
02200 { 02201 char *nick, *chname, *p, *alt; 02202 int split = 0; 02203 char from2[NICKMAX + UHOSTMAX + 1]; 02204 memberlist *m; 02205 struct chanset_t *chan, *oldchan = NULL; 02206 struct userrec *u; 02207 02208 strcpy(from2, from); 02209 u = get_user_by_host(from2); 02210 nick = splitnick(&from); 02211 fixcolon(msg); 02212 /* Fred1: Instead of expensive wild_match on signoff, quicker method. 02213 * Determine if signoff string matches "%.% %.%", and only one 02214 * space. 02215 */ 02216 p = strchr(msg, ' '); 02217 if (p && (p == strrchr(msg, ' '))) { 02218 char *z1, *z2; 02219 02220 *p = 0; 02221 z1 = strchr(p + 1, '.'); 02222 z2 = strchr(msg, '.'); 02223 if (z1 && z2 && (*(z1 + 1) != 0) && (z1 - 1 != p) && 02224 (z2 + 1 != p) && (z2 != msg)) { 02225 /* Server split, or else it looked like it anyway (no harm in 02226 * assuming) 02227 */ 02228 split = 1; 02229 } else 02230 *p = ' '; 02231 } 02232 for (chan = chanset; chan; chan = chan->next) { 02233 oldchan = chan; 02234 chname = chan->dname; 02235 m = ismember(chan, nick); 02236 if (m) { 02237 u = get_user_by_host(from2); 02238 if (u) 02239 /* If you remove this, the bot will crash when the user record in 02240 * question is removed/modified during the tcl binds below, and the 02241 * users was on more than one monitored channel */ 02242 set_handle_laston(chan->dname, u, now); 02243 if (split) { 02244 m->split = now; 02245 check_tcl_splt(nick, from, u, chan->dname); 02246 02247 if (!findchan_by_dname(chname)) { 02248 chan = oldchan; 02249 continue; 02250 } 02251 putlog(LOG_JOIN, chan->dname, "%s (%s) got netsplit.", nick, from); 02252 } else { 02253 check_tcl_sign(nick, from, u, chan->dname, msg); 02254 02255 if (!findchan_by_dname(chname)) { 02256 chan = oldchan; 02257 continue; 02258 } 02259 putlog(LOG_JOIN, chan->dname, "%s (%s) left irc: %s", nick, from, msg); 02260 killmember(chan, nick); 02261 check_lonely_channel(chan); 02262 } 02263 } 02264 } 02265 /* Our nick quit? if so, grab it. Heck, our altnick quit maybe, maybe 02266 * we want it. 02267 */ 02268 if (keepnick) { 02269 alt = get_altbotnick(); 02270 if (!rfc_casecmp(nick, origbotname)) { 02271 putlog(LOG_MISC, "*", IRC_GETORIGNICK, origbotname); 02272 dprintf(DP_SERVER, "NICK %s\n", origbotname); 02273 } else if (alt[0]) { 02274 if (!rfc_casecmp(nick, alt) && strcmp(botname, origbotname)) { 02275 putlog(LOG_MISC, "*", IRC_GETALTNICK, alt); 02276 dprintf(DP_SERVER, "NICK %s\n", alt); 02277 } 02278 } 02279 } 02280 return 0; 02281 }
static int gottopic | ( | char * | from, | |
char * | msg | |||
) | [static] |
Definition at line 1553 of file chan.c.
References check_tcl_topc, chanset_t::dname, findchan, fixcolon, get_user_by_host, ismember, memstruct::last, LOG_JOIN, newsplit, now, NULL, putlog, set_topic(), and splitnick.
01554 { 01555 char *nick, *chname; 01556 memberlist *m; 01557 struct chanset_t *chan; 01558 struct userrec *u; 01559 01560 chname = newsplit(&msg); 01561 fixcolon(msg); 01562 u = get_user_by_host(from); 01563 nick = splitnick(&from); 01564 chan = findchan(chname); 01565 if (chan) { 01566 putlog(LOG_JOIN, chan->dname, "Topic changed on %s by %s!%s: %s", 01567 chan->dname, nick, from, msg); 01568 m = ismember(chan, nick); 01569 if (m != NULL) 01570 m->last = now; 01571 set_topic(chan, msg); 01572 check_tcl_topc(nick, from, u, chan->dname, msg); 01573 } 01574 return 0; 01575 }
static void kick_all | ( | struct chanset_t * | chan, | |
char * | hostmask, | |||
char * | comment, | |||
int | bantype | |||
) | [static] |
Definition at line 384 of file chan.c.
References chan_deop, chan_friend, chan_hasop, chan_issplit, chan_op, chan_sentkick, chanset_t::channel, channel_dontkickops, chanset_t::dname, DP_SERVER, dprintf, chanset_t::exempts, memstruct::flags, flush_mode(), FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, glob_friend, glob_op, global_exempts, isexempted, kick_method, match_addr, match_my_nick(), me_halfop(), me_op(), chan_t::member, chanset_t::name, memstruct::next, memstruct::nick, QUICK, SENTKICK, u_match_mask(), UHOSTLEN, use_exempts, memstruct::user, and memstruct::userhost.
Referenced by enforce_bans(), got_ban(), and refresh_ban_kick().
00386 { 00387 memberlist *m; 00388 char kicknick[512], s[UHOSTLEN]; 00389 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 00390 int k, l, flushed; 00391 00392 if (!me_op(chan) && !me_halfop(chan)) 00393 return; 00394 00395 k = 0; 00396 flushed = 0; 00397 kicknick[0] = 0; 00398 for (m = chan->channel.member; m && m->nick[0]; m = m->next) { 00399 sprintf(s, "%s!%s", m->nick, m->userhost); 00400 get_user_flagrec(m->user ? m->user : get_user_by_host(s), &fr, chan->dname); 00401 if ((me_op(chan) || (me_halfop(chan) && !chan_hasop(m))) && 00402 match_addr(hostmask, s) && !chan_sentkick(m) && 00403 !match_my_nick(m->nick) && !chan_issplit(m) && 00404 !glob_friend(fr) && !chan_friend(fr) && !(use_exempts && ((bantype && 00405 isexempted(chan, s)) || (u_match_mask(global_exempts, s) || 00406 u_match_mask(chan->exempts, s)))) && !(channel_dontkickops(chan) && 00407 (chan_op(fr) || (glob_op(fr) && !chan_deop(fr))))) { 00408 if (!flushed) { 00409 /* We need to kick someone, flush eventual bans first */ 00410 flush_mode(chan, QUICK); 00411 flushed += 1; 00412 } 00413 m->flags |= SENTKICK; /* Mark as pending kick */ 00414 if (kicknick[0]) 00415 strcat(kicknick, ","); 00416 strcat(kicknick, m->nick); 00417 k += 1; 00418 l = strlen(chan->name) + strlen(kicknick) + strlen(comment) + 5; 00419 if ((kick_method != 0 && k == kick_method) || (l > 480)) { 00420 dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, kicknick, comment); 00421 k = 0; 00422 kicknick[0] = 0; 00423 } 00424 } 00425 } 00426 if (k > 0) 00427 dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, kicknick, comment); 00428 }
static memberlist* newmember | ( | struct chanset_t * | chan | ) | [static] |
Definition at line 42 of file chan.c.
References chanset_t::channel, channel_malloc(), memstruct::delay, memstruct::last, chan_t::member, chan_t::members, memstruct::next, memstruct::nick, NULL, and memstruct::split.
Referenced by got352or4(), and gotjoin().
00043 { 00044 memberlist *x; 00045 00046 for (x = chan->channel.member; x && x->nick[0]; x = x->next); 00047 x->next = (memberlist *) channel_malloc(sizeof(memberlist)); 00048 x->next->next = NULL; 00049 x->next->nick[0] = 0; 00050 x->next->split = 0L; 00051 x->next->last = 0L; 00052 x->next->delay = 0L; 00053 chan->channel.members++; 00054 return x; 00055 }
static char* quickban | ( | struct chanset_t * | chan, | |
char * | uhost | |||
) | [static] |
Definition at line 372 of file chan.c.
References chan_t::ban, chanset_t::ban_type, chanset_t::channel, do_mask(), and maskaddr.
Referenced by check_this_member(), cmd_kickban(), gotjoin(), gotmsg(), and gotnotice().
00373 { 00374 static char s1[512]; 00375 00376 maskaddr(uhost, s1, chan->ban_type); 00377 do_mask(chan, chan->channel.ban, s1, 'b'); 00378 return s1; 00379 }
static void recheck_bans | ( | struct chanset_t * | chan | ) | [static] |
Definition at line 540 of file chan.c.
References add_mode, chanset_t::bans, channel_dynamicbans, maskrec::flags, global_bans, isbanned, maskrec::mask, MASKREC_STICKY, and maskrec::next.
Referenced by recheck_channel(), and resetmasks().
00541 { 00542 maskrec *u; 00543 int cycle; 00544 00545 /* Check global bans in first cycle and channel bans in second cycle. */ 00546 for (cycle = 0; cycle < 2; cycle++) { 00547 for (u = cycle ? chan->bans : global_bans; u; u = u->next) 00548 if (!isbanned(chan, u->mask) && (!channel_dynamicbans(chan) || 00549 (u->flags & MASKREC_STICKY))) 00550 add_mode(chan, '+', 'b', u->mask); 00551 } 00552 }
static void recheck_channel | ( | struct chanset_t * | chan, | |
int | dobans | |||
) | [static] |
Definition at line 868 of file chan.c.
References CHAN_ASKED_EXEMPTS, CHAN_ASKED_INVITED, CHAN_ASKEDMODES, chan_hasop, CHAN_RESETEXEMPTS, CHAN_RESETINVITED, chanset_t::channel, channel_enforcebans, channel_inactive, channel_nouserbans, channel_nouserexempts, channel_nouserinvites, check_this_member(), chanset_t::dname, DP_MODE, dprintf, enforce_bans(), memstruct::flags, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, glob_bot, chanset_t::ircnet_status, match_my_nick(), chan_t::member, chanset_t::name, memstruct::next, memstruct::nick, recheck_bans(), recheck_channel_modes(), recheck_exempts(), recheck_invites(), reset_chan_info(), resetbans, resetexempts, resetinvites, SENTHALFOP, SENTKICK, chanset_t::status, memstruct::tried_getuser, UHOSTLEN, use_exempts, use_invites, memstruct::user, memstruct::userhost, and userlist.
Referenced by got315(), got_halfop(), and got_op().
00869 { 00870 memberlist *m; 00871 char s[UHOSTLEN]; 00872 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 00873 static int stacking = 0; 00874 int stop_reset = 0; 00875 00876 if (stacking || !userlist) 00877 return; 00878 00879 stacking++; 00880 /* Okay, sort through who needs to be deopped. */ 00881 for (m = chan->channel.member; m && m->nick[0]; m = m->next) { 00882 sprintf(s, "%s!%s", m->nick, m->userhost); 00883 if (!m->user && !m->tried_getuser) { 00884 m->tried_getuser = 1; 00885 m->user = get_user_by_host(s); 00886 } 00887 get_user_flagrec(m->user, &fr, chan->dname); 00888 if (glob_bot(fr) && chan_hasop(m) && !match_my_nick(m->nick)) 00889 stop_reset = 1; 00890 /* Perhaps we were halfop and tried to halfop/kick the user earlier but 00891 * the server rejected the request, so let's try again. */ 00892 m->flags &= ~(SENTHALFOP | SENTKICK); 00893 check_this_member(chan, m->nick, &fr); 00894 } 00895 /* Most IRCDs nowadays require +h/+o for getting e/I lists, 00896 * so if we're still waiting for these, we'll request them here. 00897 * In case we got them on join, nothing will be done */ 00898 if (chan->ircnet_status & (CHAN_ASKED_EXEMPTS | CHAN_ASKED_INVITED)) { 00899 chan->ircnet_status &= ~(CHAN_ASKED_EXEMPTS | CHAN_ASKED_INVITED); 00900 reset_chan_info(chan, CHAN_RESETEXEMPTS | CHAN_RESETINVITED); 00901 } 00902 if (dobans) { 00903 if (channel_nouserbans(chan) && !stop_reset) 00904 resetbans(chan); 00905 else 00906 recheck_bans(chan); 00907 if (use_invites) { 00908 if (channel_nouserinvites(chan) && !stop_reset) 00909 resetinvites(chan); 00910 else 00911 recheck_invites(chan); 00912 } 00913 if (use_exempts) { 00914 if (channel_nouserexempts(chan) && !stop_reset) 00915 resetexempts(chan); 00916 else 00917 recheck_exempts(chan); 00918 } 00919 if (channel_enforcebans(chan)) 00920 enforce_bans(chan); 00921 if ((chan->status & CHAN_ASKEDMODES) && !channel_inactive(chan)) 00922 dprintf(DP_MODE, "MODE %s\n", chan->name); 00923 recheck_channel_modes(chan); 00924 } 00925 stacking--; 00926 }
static void recheck_channel_modes | ( | struct chanset_t * | chan | ) | [static] |
Definition at line 658 of file chan.c.
References add_mode, CHAN_ASKEDMODES, CHANANON, CHANDELJN, CHANINV, CHANKEY, CHANLIMIT, CHANLONLY, CHANMODER, CHANMODREG, chanset_t::channel, CHANNOAMSG, CHANNOCLR, CHANNOCTCP, CHANNOMSG, CHANNONOTC, CHANPRIV, CHANQUIET, CHANREGON, CHANSEC, CHANSTRIP, CHANTOPIC, chan_t::key, chanset_t::key_prot, chanset_t::limit_prot, chan_t::maxmembers, chan_t::mode, chanset_t::mode_mns_prot, chanset_t::mode_pls_prot, rfc_casecmp, and chanset_t::status.
Referenced by got324(), and recheck_channel().
00659 { 00660 int cur = chan->channel.mode, mns = chan->mode_mns_prot, 00661 pls = chan->mode_pls_prot; 00662 00663 if (!(chan->status & CHAN_ASKEDMODES)) { 00664 if (pls & CHANINV && !(cur & CHANINV)) 00665 add_mode(chan, '+', 'i', ""); 00666 else if (mns & CHANINV && cur & CHANINV) 00667 add_mode(chan, '-', 'i', ""); 00668 if (pls & CHANPRIV && !(cur & CHANPRIV)) 00669 add_mode(chan, '+', 'p', ""); 00670 else if (mns & CHANPRIV && cur & CHANPRIV) 00671 add_mode(chan, '-', 'p', ""); 00672 if (pls & CHANSEC && !(cur & CHANSEC)) 00673 add_mode(chan, '+', 's', ""); 00674 else if (mns & CHANSEC && cur & CHANSEC) 00675 add_mode(chan, '-', 's', ""); 00676 if (pls & CHANMODER && !(cur & CHANMODER)) 00677 add_mode(chan, '+', 'm', ""); 00678 else if (mns & CHANMODER && cur & CHANMODER) 00679 add_mode(chan, '-', 'm', ""); 00680 if (pls & CHANNOCLR && !(cur & CHANNOCLR)) 00681 add_mode(chan, '+', 'c', ""); 00682 else if (mns & CHANNOCLR && cur & CHANNOCLR) 00683 add_mode(chan, '-', 'c', ""); 00684 if (pls & CHANNOCTCP && !(cur & CHANNOCTCP)) 00685 add_mode(chan, '+', 'C', ""); 00686 else if (mns & CHANNOCTCP && cur & CHANNOCTCP) 00687 add_mode(chan, '-', 'C', ""); 00688 if (pls & CHANREGON && !(cur & CHANREGON)) 00689 add_mode(chan, '+', 'R', ""); 00690 else if (mns & CHANREGON && cur & CHANREGON) 00691 add_mode(chan, '-', 'R', ""); 00692 if (pls & CHANMODREG && !(cur & CHANMODREG)) 00693 add_mode(chan, '+', 'M', ""); 00694 else if (mns & CHANMODREG && cur & CHANMODREG) 00695 add_mode(chan, '-', 'M', ""); 00696 if (pls & CHANLONLY && !(cur & CHANLONLY)) 00697 add_mode(chan, '+', 'r', ""); 00698 else if (mns & CHANLONLY && cur & CHANLONLY) 00699 add_mode(chan, '-', 'r', ""); 00700 if (pls & CHANDELJN && !(cur & CHANDELJN)) 00701 add_mode(chan, '+', 'D', ""); 00702 else if (mns & CHANDELJN && cur & CHANDELJN) 00703 add_mode(chan, '-', 'D', ""); 00704 if (pls & CHANSTRIP && !(cur & CHANSTRIP)) 00705 add_mode(chan, '+', 'u', ""); 00706 else if (mns & CHANSTRIP && cur & CHANSTRIP) 00707 add_mode(chan, '-', 'u', ""); 00708 if (pls & CHANNONOTC && !(cur & CHANNONOTC)) 00709 add_mode(chan, '+', 'N', ""); 00710 else if (mns & CHANNONOTC && cur & CHANNONOTC) 00711 add_mode(chan, '-', 'N', ""); 00712 if (pls & CHANNOAMSG && !(cur & CHANNOAMSG)) 00713 add_mode(chan, '+', 'T', ""); 00714 else if (mns & CHANNOAMSG && cur & CHANNOAMSG) 00715 add_mode(chan, '-', 'T', ""); 00716 if (pls & CHANTOPIC && !(cur & CHANTOPIC)) 00717 add_mode(chan, '+', 't', ""); 00718 else if (mns & CHANTOPIC && cur & CHANTOPIC) 00719 add_mode(chan, '-', 't', ""); 00720 if (pls & CHANNOMSG && !(cur & CHANNOMSG)) 00721 add_mode(chan, '+', 'n', ""); 00722 else if ((mns & CHANNOMSG) && (cur & CHANNOMSG)) 00723 add_mode(chan, '-', 'n', ""); 00724 if ((pls & CHANANON) && !(cur & CHANANON)) 00725 add_mode(chan, '+', 'a', ""); 00726 else if ((mns & CHANANON) && (cur & CHANANON)) 00727 add_mode(chan, '-', 'a', ""); 00728 if ((pls & CHANQUIET) && !(cur & CHANQUIET)) 00729 add_mode(chan, '+', 'q', ""); 00730 else if ((mns & CHANQUIET) && (cur & CHANQUIET)) 00731 add_mode(chan, '-', 'q', ""); 00732 if ((chan->limit_prot != 0) && (chan->channel.maxmembers == 0)) { 00733 char s[50]; 00734 00735 sprintf(s, "%d", chan->limit_prot); 00736 add_mode(chan, '+', 'l', s); 00737 } else if ((mns & CHANLIMIT) && (chan->channel.maxmembers != 0)) 00738 add_mode(chan, '-', 'l', ""); 00739 if (chan->key_prot[0]) { 00740 if (rfc_casecmp(chan->channel.key, chan->key_prot) != 0) { 00741 if (chan->channel.key[0]) 00742 add_mode(chan, '-', 'k', chan->channel.key); 00743 add_mode(chan, '+', 'k', chan->key_prot); 00744 } 00745 } else if ((mns & CHANKEY) && (chan->channel.key[0])) 00746 add_mode(chan, '-', 'k', chan->channel.key); 00747 } 00748 }
static void recheck_exempts | ( | struct chanset_t * | chan | ) | [static] |
Definition at line 559 of file chan.c.
References add_mode, chan_t::ban, chanset_t::channel, channel_dynamicexempts, e, chanset_t::exempts, maskrec::flags, global_exempts, isexempted, maskstruct::mask, maskrec::mask, mask_match, MASKREC_STICKY, maskstruct::next, and maskrec::next.
Referenced by recheck_channel(), and resetmasks().
00560 { 00561 maskrec *e; 00562 masklist *b; 00563 int cycle; 00564 00565 /* Check global exempts in first cycle and channel exempts in second cycle. */ 00566 for (cycle = 0; cycle < 2; cycle++) { 00567 for (e = cycle ? chan->exempts : global_exempts; e; e = e->next) { 00568 if (!isexempted(chan, e->mask) && 00569 (!channel_dynamicexempts(chan) || (e->flags & MASKREC_STICKY))) 00570 add_mode(chan, '+', 'e', e->mask); 00571 for (b = chan->channel.ban; b && b->mask[0]; b = b->next) { 00572 if (mask_match(b->mask, e->mask) && 00573 !isexempted(chan, e->mask)) 00574 add_mode(chan, '+', 'e', e->mask); 00575 /* do_mask(chan, chan->channel.exempt, e->mask, 'e'); */ 00576 } 00577 } 00578 } 00579 }
static void recheck_invites | ( | struct chanset_t * | chan | ) | [static] |
Definition at line 586 of file chan.c.
References add_mode, CHANINV, chanset_t::channel, channel_dynamicinvites, maskrec::flags, global_invites, chanset_t::invites, isinvited, maskrec::mask, MASKREC_STICKY, chan_t::mode, and maskrec::next.
Referenced by recheck_channel(), and resetmasks().
00587 { 00588 maskrec *ir; 00589 int cycle; 00590 00591 /* Check global invites in first cycle and channel invites in second cycle. */ 00592 for (cycle = 0; cycle < 2; cycle++) { 00593 for (ir = cycle ? chan->invites : global_invites; ir; ir = ir->next) { 00594 /* If invite isn't set and (channel is not dynamic invites and not invite 00595 * only) or invite is sticky. 00596 */ 00597 if (!isinvited(chan, ir->mask) && ((!channel_dynamicinvites(chan) && 00598 !(chan->channel.mode & CHANINV)) || ir->flags & MASKREC_STICKY)) 00599 add_mode(chan, '+', 'I', ir->mask); 00600 /* do_mask(chan, chan->channel.invite, ir->mask, 'I'); */ 00601 } 00602 } 00603 }
static void refresh_ban_kick | ( | struct chanset_t * | chan, | |
char * | user, | |||
char * | nick | |||
) | [static] |
Definition at line 432 of file chan.c.
References add_mode, chan_t::ban, chanset_t::bans, chan_friend, chan_sentkick, chanset_t::channel, check_exemptlist(), maskrec::desc, chanset_t::dname, do_mask(), egg_snprintf, FR_CHAN, FR_GLOBAL, get_user_by_host, get_user_flagrec, glob_friend, global_bans, IRC_PREBANNED, IRC_YOUREBANNED, ismember, kick_all(), maskrec::lastactive, maskrec::mask, match_addr, maskrec::next, memstruct::nick, now, UHOSTLEN, memstruct::user, and memstruct::userhost.
Referenced by check_this_ban(), check_this_member(), and gotjoin().
00433 { 00434 register maskrec *b; 00435 memberlist *m; 00436 int cycle; 00437 00438 m = ismember(chan, nick); 00439 if (!m || chan_sentkick(m)) 00440 return; 00441 00442 /* Check global bans in first cycle and channel bans in second cycle. */ 00443 for (cycle = 0; cycle < 2; cycle++) { 00444 for (b = cycle ? chan->bans : global_bans; b; b = b->next) { 00445 if (match_addr(b->mask, user)) { 00446 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 00447 char c[512]; /* The ban comment. */ 00448 char s[UHOSTLEN]; 00449 00450 sprintf(s, "%s!%s", m->nick, m->userhost); 00451 get_user_flagrec(m->user ? m->user : get_user_by_host(s), &fr, 00452 chan->dname); 00453 if (!glob_friend(fr) && !chan_friend(fr)) { 00454 add_mode(chan, '-', 'o', nick); /* Guess it can't hurt. */ 00455 check_exemptlist(chan, user); 00456 do_mask(chan, chan->channel.ban, b->mask, 'b'); 00457 b->lastactive = now; 00458 if (b->desc && b->desc[0] != '@') 00459 egg_snprintf(c, sizeof c, "%s %s", IRC_PREBANNED, b->desc); 00460 else 00461 c[0] = 0; 00462 kick_all(chan, b->mask, c[0] ? c : IRC_YOUREBANNED, 0); 00463 return; /* Drop out on 1st ban. */ 00464 } 00465 } 00466 } 00467 } 00468 }
static void refresh_exempt | ( | struct chanset_t * | chan, | |
char * | user | |||
) | [static] |
Definition at line 473 of file chan.c.
References chan_t::ban, chanset_t::channel, do_mask(), e, chan_t::exempt, chanset_t::exempts, global_exempts, isexempted, maskrec::lastactive, maskstruct::mask, maskrec::mask, mask_match, maskstruct::next, maskrec::next, and now.
Referenced by got_ban().
00474 { 00475 maskrec *e; 00476 masklist *b; 00477 int cycle; 00478 00479 /* Check global exempts in first cycle and channel exempts in second cycle. */ 00480 for (cycle = 0; cycle < 2; cycle++) { 00481 for (e = cycle ? chan->exempts : global_exempts; e; e = e->next) { 00482 if (mask_match(user, e->mask)) { 00483 for (b = chan->channel.ban; b && b->mask[0]; b = b->next) { 00484 if (mask_match(b->mask, user)) { 00485 if (e->lastactive < now - 60 && !isexempted(chan, e->mask)) { 00486 do_mask(chan, chan->channel.exempt, e->mask, 'e'); 00487 e->lastactive = now; 00488 } 00489 } 00490 } 00491 } 00492 } 00493 } 00494 }
static void refresh_invite | ( | struct chanset_t * | chan, | |
char * | user | |||
) | [static] |
Definition at line 496 of file chan.c.
References CHANINV, chanset_t::channel, do_mask(), maskrec::flags, global_invites, chan_t::invite, chanset_t::invites, isinvited, maskrec::lastactive, maskrec::mask, MASKREC_STICKY, match_addr, chan_t::mode, maskrec::next, and now.
Referenced by check_this_member(), and gotjoin().
00497 { 00498 maskrec *i; 00499 int cycle; 00500 00501 /* Check global invites in first cycle and channel invites in second cycle. */ 00502 for (cycle = 0; cycle < 2; cycle++) { 00503 for (i = cycle ? chan->invites : global_invites; i; i = i->next) { 00504 if (match_addr(i->mask, user) && 00505 ((i->flags & MASKREC_STICKY) || (chan->channel.mode & CHANINV))) { 00506 if (i->lastactive < now - 60 && !isinvited(chan, i->mask)) { 00507 do_mask(chan, chan->channel.invite, i->mask, 'I'); 00508 i->lastactive = now; 00509 return; 00510 } 00511 } 00512 } 00513 } 00514 }
static void resetmasks | ( | struct chanset_t * | chan, | |
masklist * | m, | |||
maskrec * | mrec, | |||
maskrec * | global_masks, | |||
char | mode | |||
) | [static] |
Definition at line 607 of file chan.c.
References add_mode, LOG_MISC, maskstruct::mask, me_halfop(), me_op(), maskstruct::next, NOHALFOPS_MODES, NULL, putlog, recheck_bans(), recheck_exempts(), recheck_invites(), and u_equals_mask().
00609 { 00610 if (!me_op(chan) && (!me_halfop(chan) || 00611 (strchr(NOHALFOPS_MODES, 'b') != NULL) || 00612 (strchr(NOHALFOPS_MODES, 'e') != NULL) || 00613 (strchr(NOHALFOPS_MODES, 'I') != NULL))) 00614 return; 00615 00616 /* Remove masks we didn't put there */ 00617 for (; m && m->mask[0]; m = m->next) { 00618 if (!u_equals_mask(global_masks, m->mask) && !u_equals_mask(mrec, m->mask)) 00619 add_mode(chan, '-', mode, m->mask); 00620 } 00621 00622 /* Make sure the intended masks are still there */ 00623 switch (mode) { 00624 case 'b': 00625 recheck_bans(chan); 00626 break; 00627 case 'e': 00628 recheck_exempts(chan); 00629 break; 00630 case 'I': 00631 recheck_invites(chan); 00632 break; 00633 default: 00634 putlog(LOG_MISC, "*", "(!) Invalid mode '%c' in resetmasks()", mode); 00635 break; 00636 } 00637 }
static void set_delay | ( | struct chanset_t * | chan, | |
char * | nick | |||
) | [static] |
Definition at line 1616 of file chan.c.
References chanset_t::aop_max, chanset_t::aop_min, chanset_t::channel, count, memstruct::delay, memstruct::flags, FULL_DELAY, ismember, chan_t::member, modesperline, memstruct::next, memstruct::nick, now, randint, and time_t.
Referenced by check_this_member(), and gotjoin().
01617 { 01618 time_t a_delay; 01619 int aop_min, aop_max, aop_diff, count = 0; 01620 memberlist *m, *m2; 01621 01622 m = ismember(chan, nick); 01623 if (!m) 01624 return; 01625 01626 /* aop-delay 5:30 -- aop_min:aop_max */ 01627 aop_min = chan->aop_min; 01628 aop_max = chan->aop_max; 01629 aop_diff = aop_max - aop_min; 01630 01631 /* If either min or max is less than or equal to 0 we don't delay. */ 01632 if ((aop_min <= 0) || (aop_max <= 0)) { 01633 a_delay = now + 1; 01634 01635 /* Use min value for delay if min greater then or equal to max or if the 01636 * difference of max and min is greater than RANDOM_MAX (sanity check). 01637 */ 01638 } else if ((aop_min >= aop_max) || (aop_diff > RANDOM_MAX)) { 01639 a_delay = now + aop_min; 01640 01641 /* Set a random delay based on the difference of max and min */ 01642 } else { 01643 a_delay = now + randint(aop_diff) + aop_min + 1; 01644 } 01645 01646 for (m2 = chan->channel.member; m2 && m2->nick[0]; m2 = m2->next) 01647 if (m2->delay && !(m2->flags & FULL_DELAY)) 01648 count++; 01649 01650 if (count) { 01651 for (m2 = chan->channel.member; m2 && m2->nick[0]; m2 = m2->next) { 01652 if (m2->delay && !(m2->flags & FULL_DELAY)) { 01653 m2->delay = a_delay; 01654 01655 if (count + 1 >= modesperline) 01656 m2->flags |= FULL_DELAY; 01657 01658 } 01659 } 01660 } 01661 01662 if (count + 1 >= modesperline) 01663 m->flags |= FULL_DELAY; 01664 01665 m->delay = a_delay; 01666 }
static void set_topic | ( | struct chanset_t * | chan, | |
char * | k | |||
) | [static] |
Definition at line 1540 of file chan.c.
References chanset_t::channel, channel_malloc(), nfree, NULL, and chan_t::topic.
Referenced by got331(), got332(), and gottopic().
01541 { 01542 if (chan->channel.topic) 01543 nfree(chan->channel.topic); 01544 if (k && k[0]) { 01545 chan->channel.topic = (char *) channel_malloc(strlen(k) + 1); 01546 strcpy(chan->channel.topic, k); 01547 } else 01548 chan->channel.topic = NULL; 01549 }
static void sync_members | ( | struct chanset_t * | chan | ) | [inline, static] |
Definition at line 58 of file chan.c.
References chan_whosynced, chanset_t::channel, chan_t::member, chan_t::members, memstruct::next, nfree, and memstruct::nick.
Referenced by got315().
00059 { 00060 memberlist *m, *next, *prev; 00061 00062 for (m = chan->channel.member, prev = 0; m && m->nick[0]; m = next) { 00063 next = m->next; 00064 if (!chan_whosynced(m)) { 00065 if (prev) 00066 prev->next = next; 00067 else 00068 chan->channel.member = next; 00069 nfree(m); 00070 chan->channel.members--; 00071 } else 00072 prev = m; 00073 } 00074 }
static void update_idle | ( | char * | chname, | |
char * | nick | |||
) | [static] |
Definition at line 78 of file chan.c.
References findchan_by_dname, ismember, memstruct::last, and now.
Referenced by gotmsg(), and gotnotice().
00079 { 00080 memberlist *m; 00081 struct chanset_t *chan; 00082 00083 chan = findchan_by_dname(chname); 00084 if (chan) { 00085 m = ismember(chan, nick); 00086 if (m) 00087 m->last = now; 00088 } 00089 }
int count_ctcp = 0 [static] |
Definition at line 2552 of file chan.c.
Referenced by irc_close(), and irc_start().
char last_invchan[300] = "" [static] |
Definition at line 33 of file chan.c.
Referenced by gotinvite().
time_t last_invtime = (time_t) 0L [static] |
Definition at line 32 of file chan.c.
Referenced by gotinvite().