📄 m_who.c
字号:
{ if (!IsAnOper(acptr)) return ret | WHO_CANTSEE; if (IsHideOper(acptr)) { if (IsAnOper(sptr)) ret |= WHO_OPERSEE; else return ret | WHO_CANTSEE; } } /* if they only want people who are away */ if ((wfl.want_away == WHO_WANT && !acptr->user->away) || (wfl.want_away == WHO_DONTWANT && acptr->user->away)) return WHO_CANTSEE; /* if they only want people on a certain channel. */ if (wfl.want_channel != WHO_DONTCARE) { aChannel *chan = find_channel(wfl.channel, NULL); if (!chan && wfl.want_channel == WHO_WANT) return WHO_CANTSEE; if ((wfl.want_channel == WHO_WANT) && !IsMember(acptr, chan)) return WHO_CANTSEE; if ((wfl.want_channel == WHO_DONTWANT) && IsMember(acptr, chan)) return WHO_CANTSEE; } /* if they only want people with a certain gecos */ if (wfl.want_gecos != WHO_DONTCARE) { if (((wfl.want_gecos == WHO_WANT) && match(wfl.gecos, acptr->info)) || ((wfl.want_gecos == WHO_DONTWANT) && !match(wfl.gecos, acptr->info))) { return WHO_CANTSEE; } } /* if they only want people with a certain server */ if (wfl.want_server != WHO_DONTCARE) { if (((wfl.want_server == WHO_WANT) && stricmp(wfl.server, acptr->user->server)) || ((wfl.want_server == WHO_DONTWANT) && !stricmp(wfl.server, acptr->user->server))) { return WHO_CANTSEE; } } /* if they only want people with a certain host */ if (wfl.want_host != WHO_DONTCARE) { char *host; if (IsAnOper(sptr)) host = acptr->user->realhost; else host = GetHost(acptr); if (((wfl.want_host == WHO_WANT) && match(wfl.host, host)) || ((wfl.want_host == WHO_DONTWANT) && !match(wfl.host, host))) { return WHO_CANTSEE; } } /* if they only want people with a certain IP */ if (wfl.want_ip != WHO_DONTCARE) { char *ip; ip = acptr->user->ip_str; if (!ip) return WHO_CANTSEE; if (((wfl.want_ip == WHO_WANT) && match(wfl.ip, ip)) || ((wfl.want_ip == WHO_DONTWANT) && !match(wfl.ip, ip))) { return WHO_CANTSEE; } } /* if they only want people with a certain nick.. */ if (wfl.want_nick != WHO_DONTCARE) { if (((wfl.want_nick == WHO_WANT) && match(wfl.nick, acptr->name)) || ((wfl.want_nick == WHO_DONTWANT) && !match(wfl.nick, acptr->name))) { return WHO_CANTSEE; } } /* if they only want people with a certain username */ if (wfl.want_user != WHO_DONTCARE) { if (((wfl.want_user == WHO_WANT) && match(wfl.user, acptr->user->username)) || ((wfl.want_user == WHO_DONTWANT) && !match(wfl.user, acptr->user->username))) { return WHO_CANTSEE; } } /* if they only want people with a certain umode */ if (wfl.umodes_want) { if (!(acptr->umodes & wfl.umodes_want) || (!IsAnOper(sptr) && (acptr->umodes & UMODE_HIDEOPER))) return WHO_CANTSEE; } if (wfl.umodes_dontwant) { if ((acptr->umodes & wfl.umodes_dontwant) && (!(acptr->umodes & UMODE_HIDEOPER) || IsAnOper(sptr))) return WHO_CANTSEE; } /* if they only want common channels */ if (wfl.common_channels_only) { if (!has_common_channels(sptr, acptr)) return WHO_CANTSEE; has_common_chan = 1; } if (channel) { int member = who_flags & WF_ONCHANNEL; if (SecretChannel(channel) || HiddenChannel(channel)) { /* if they aren't on it.. they can't see it */ if (!(who_flags & WF_ONCHANNEL)) break; } if (IsInvisible(acptr) && !member) break; if ((channel->mode.mode & MODE_AUDITORIUM) && !is_chan_op(acptr, channel) && !is_chan_op(sptr, channel)) break; } else { /* a user/mask who */ /* If the common channel info hasn't been set, set it now */ if (!wfl.common_channels_only) has_common_chan = has_common_channels(sptr, acptr); if (IsInvisible(acptr) && !has_common_chan) { /* don't show them unless it's an exact match or it is the user requesting the /who */ if ((who_flags & WF_WILDCARD) && sptr != acptr) break; } } /* phew.. show them. */ return WHO_CANSEE; } while (0); /* if we get here, it's oper-dependant. */ if (IsAnOper(sptr)) return ret | WHO_OPERSEE | WHO_CANSEE; else { if (sptr == acptr) return ret | WHO_CANSEE; else return ret | WHO_CANTSEE; }}static void do_channel_who(aClient *sptr, aChannel *channel, char *mask){ Member *cm = channel->members; if (IsMember(sptr, channel) || IsNetAdmin(sptr)) who_flags |= WF_ONCHANNEL; for (cm = channel->members; cm; cm = cm->next) { aClient *acptr = cm->cptr; char status[20]; int cansee; if ((cansee = can_see(sptr, acptr, channel)) & WHO_CANTSEE) continue; make_who_status(sptr, acptr, channel, cm, status, cansee); send_who_reply(sptr, acptr, channel->chname, status, ""); }}static void make_who_status(aClient *sptr, aClient *acptr, aChannel *channel, Member *cm, char *status, int cansee){int i = 0; if (acptr->user->away) status[i++] = 'G'; else status[i++] = 'H'; if (IsARegNick(acptr)) status[i++] = 'r'; if (acptr->umodes & UMODE_BOT) status[i++] = 'B'; if (IsAnOper(acptr) && (!IsHideOper(acptr) || sptr == acptr || IsAnOper(sptr))) status[i++] = '*'; if (IsAnOper(acptr) && (IsHideOper(acptr) && sptr != acptr && IsAnOper(sptr))) status[i++] = '!'; if (cansee & WHO_OPERSEE) status[i++] = '?'; if (cm) {#ifdef PREFIX_AQ if (cm->flags & CHFL_CHANOWNER) status[i++] = '~'; else if (cm->flags & CHFL_CHANPROT) status[i++] = '&'; else#endif if (cm->flags & CHFL_CHANOP) status[i++] = '@'; else if (cm->flags & CHFL_HALFOP) status[i++] = '%'; else if (cm->flags & CHFL_VOICE) status[i++] = '+'; } status[i] = '\0';}static void do_other_who(aClient *sptr, char *mask){int oper = IsAnOper(sptr); /* wildcard? */#ifndef NO_FDLIST if (lifesux && !IsOper(sptr) && *mask == '*' && *(mask+1) == 0) { sendto_one(sptr, err_str(ERR_HTMDISABLED), me.name, sptr->name, "/WHO"); return; }#endif if (strchr(mask, '*') || strchr(mask, '?')) { int i = 0; /* go through all users.. */ aClient *acptr; who_flags |= WF_WILDCARD; for (acptr = client; acptr; acptr = acptr->next) { int cansee; char status[20]; char *channel; int flg; if (!IsPerson(acptr)) continue; if (!oper) { /* non-opers can only search on nick here */ if (match(mask, acptr->name)) continue; } else { /* opers can search on name, ident, virthost, ip and realhost. * Yes, I like readable if's -- Syzop. */ if (!match(mask, acptr->name) || !match(mask, acptr->user->realhost) || !match(mask, acptr->user->username)) goto matchok; if (IsHidden(acptr) && !match(mask, acptr->user->virthost)) goto matchok; if (acptr->user->ip_str && !match(mask, acptr->user->ip_str)) goto matchok; /* nothing matched... */ continue; }matchok: if ((cansee = can_see(sptr, acptr, NULL)) & WHO_CANTSEE) continue; if (WHOLIMIT && !IsAnOper(sptr) && ++i > WHOLIMIT) { sendto_one(sptr, rpl_str(ERR_WHOLIMEXCEED), me.name, sptr->name, WHOLIMIT); return; } channel = first_visible_channel(sptr, acptr, &flg); make_who_status(sptr, acptr, NULL, NULL, status, cansee); send_who_reply(sptr, acptr, channel, status, (flg & FVC_HIDDEN) ? "~" : ""); } } else { /* just a single client (no wildcards detected) */ aClient *acptr = find_client(mask, NULL); int cansee; char status[20]; char *channel; int flg; if (!acptr) return; if ((cansee = can_see(sptr, acptr, NULL)) == WHO_CANTSEE) return; channel = first_visible_channel(sptr, acptr, &flg); make_who_status(sptr, acptr, NULL, NULL, status, cansee); send_who_reply(sptr, acptr, channel, status, (flg & FVC_HIDDEN) ? "~" : ""); }}static void send_who_reply(aClient *sptr, aClient *acptr, char *channel, char *status, char *xstat){ char *stat; char *host; int flat = (FLAT_MAP && !IsAnOper(sptr)) ? 1 : 0; stat = malloc(strlen(status) + strlen(xstat) + 1); sprintf(stat, "%s%s", status, xstat); if (IsAnOper(sptr)) { if (who_flags & WF_REALHOST) host = acptr->user->realhost; else if (who_flags & WF_IP) host = (acptr->user->ip_str ? acptr->user->ip_str : acptr->user->realhost); else host = GetHost(acptr); } else host = GetHost(acptr); if (IsULine(acptr) && !IsOper(sptr) && HIDE_ULINES) sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name, channel, /* channel name */ acptr->user->username, /* user name */ host, /* hostname */ "hidden", /* let's hide the server from normal users if the server is a uline and HIDE_ULINES is on */ acptr->name, /* nick */ stat, /* status */ 0, /* hops (hidden) */ acptr->info /* realname */ ); else sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name, channel, /* channel name */ acptr->user->username, /* user name */ host, /* hostname */ acptr->user->server, /* server name */ acptr->name, /* nick */ stat, /* status */ flat ? 0 : acptr->hopcount, /* hops */ acptr->info /* realname */ ); free(stat);}static char *first_visible_channel(aClient *sptr, aClient *acptr, int *flg){ Membership *lp; *flg = 0; for (lp = acptr->user->channel; lp; lp = lp->next) { aChannel *chptr = lp->chptr; int cansee = ShowChannel(sptr, chptr); if (cansee && (acptr->umodes & UMODE_HIDEWHOIS) && !IsMember(sptr, chptr)) cansee = 0; if (!cansee) { if (OPCanSeeSecret(sptr)) *flg |= FVC_HIDDEN; else continue; } return chptr->chname; } /* no channels that they can see */ return "*";}static int has_common_channels(aClient *c1, aClient *c2){ Membership *lp; for (lp = c1->user->channel; lp; lp = lp->next) { if (IsMember(c2, lp->chptr)) { if (c1 == c2) return 1; /* We must ensure that c1 is allowed to "see" c2 */ if ((lp->chptr->mode.mode & MODE_AUDITORIUM) && !is_chan_op(c2, lp->chptr) && !is_chan_op(c1, lp->chptr)) break; return 1; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -