📄 m_who.c
字号:
/* m_who.c - Because s_user.c was just crazy. * Copyright (C) 1990 Jarkko Oikarinen and * University of Oulu, Computing Center * * See file AUTHORS in IRC package for additional names of * the programmers. * * This program is free softwmare; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* rewritten 06/02 by larne, the old one was unreadable. *//* changed indentation + some parts rewritten by Syzop. *//* $Id: m_who.c,v 1.1.6.10 2006/12/22 21:10:34 syzop Exp $ */#include "config.h"#include "struct.h"#include "common.h"#include "sys.h"#include "numeric.h"#include "msg.h"#include "proto.h"#include "channel.h"#include <time.h>#include <sys/stat.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef _WIN32#include <io.h>#endif#include <fcntl.h>#include "h.h"#ifdef STRIPBADWORDS#include "badwords.h"#endif#ifdef _WIN32#include "version.h"#endifDLLFUNC int m_who(aClient *cptr, aClient *sptr, int parc, char *parv[]);/* Place includes here */#define MSG_WHO "WHO"#define TOK_WHO "\""ModuleHeader MOD_HEADER(m_who) = { "who", /* Name of module */ "$Id: m_who.c,v 1.1.6.10 2006/12/22 21:10:34 syzop Exp $", /* Version */ "command /who", /* Short description of module */ "3.2-b8-1", NULL };/* This is called on module init, before Server Ready */DLLFUNC int MOD_INIT(m_who)(ModuleInfo *modinfo){ /* * We call our add_Command crap here */ add_Command(MSG_WHO, TOK_WHO, m_who, MAXPARA); MARK_AS_OFFICIAL_MODULE(modinfo); return MOD_SUCCESS;}/* Is first run when server is 100% ready */DLLFUNC int MOD_LOAD(m_who)(int module_load){ return MOD_SUCCESS;}/* Called when module is unloaded */DLLFUNC int MOD_UNLOAD(m_who)(int module_unload){ if (del_Command(MSG_WHO, TOK_WHO, m_who) < 0) { sendto_realops("Failed to delete commands when unloading %s", MOD_HEADER(m_who).name); } return MOD_SUCCESS;}static void do_channel_who(aClient *sptr, aChannel *channel, char *mask);static void make_who_status(aClient *, aClient *, aChannel *, Member *, char *, int);static void do_other_who(aClient *sptr, char *mask);static void send_who_reply(aClient *, aClient *, char *, char *, char *);static char *first_visible_channel(aClient *, aClient *, int *);static int parse_who_options(aClient *, int, char**);static void who_sendhelp(aClient *);static int has_common_channels(aClient *, aClient *);#define WF_OPERONLY 0x01 /**< only show opers */#define WF_ONCHANNEL 0x02 /**< we're on the channel we're /who'ing */#define WF_WILDCARD 0x04 /**< a wildcard /who */#define WF_REALHOST 0x08 /**< want real hostnames */#define WF_IP 0x10 /**< want IP addresses */static int who_flags;#define WHO_CANTSEE 0x01 /**< set if we can't see them */#define WHO_CANSEE 0x02 /**< set if we can */#define WHO_OPERSEE 0x04 /**< set if we only saw them because we're an oper */#define FVC_HIDDEN 0x01#define WHO_WANT 1#define WHO_DONTWANT 2#define WHO_DONTCARE 0struct { int want_away; int want_channel; char *channel; /**< if they want one */ int want_gecos; char *gecos; int want_server; char *server; int want_host; char *host; int want_nick; char *nick; int want_user; char *user; int want_ip; char *ip; int want_umode; int umodes_dontwant; int umodes_want; int common_channels_only;} wfl;/** The /who command: retrieves information from users. */DLLFUNC int m_who(aClient *cptr, aClient *sptr, int parc, char *parv[]){aChannel *target_channel;char *mask = parv[1];char star[] = "*";int i = 0; who_flags = 0; memset(&wfl, 0, sizeof(wfl)); if (parc > 1) { i = parse_who_options(sptr, parc - 1, parv + 1); if (i < 0) { sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, parv[0], mask); return 0; } } if (parc-i < 2 || strcmp(parv[1 + i], "0") == 0) mask = star; else mask = parv[1 + i]; if (!i && parc > 2 && *parv[2] == 'o') who_flags |= WF_OPERONLY; collapse(mask); if (*mask == '\0') { /* no mask given */ sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, parv[0], "*"); return 0; } if ((target_channel = find_channel(mask, NULL)) != NULL) { do_channel_who(sptr, target_channel, mask); sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, parv[0], mask); return 0; } if (wfl.channel && wfl.want_channel == WHO_WANT && (target_channel = find_channel(wfl.channel, NULL)) != NULL) { do_channel_who(sptr, target_channel, mask); sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, parv[0], mask); return 0; } else { do_other_who(sptr, mask); sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, parv[0], mask); return 0; } return 0;}static void who_sendhelp(aClient *sptr){ char *who_help[] = { "/WHO [+|-][achmnsuM] [args]", "Flags are specified like channel modes, the flags chmnsu all have arguments", "Flags are set to a positive check by +, a negative check by -", "The flags work as follows:", "Flag a: user is away", "Flag c <channel>: user is on <channel>,", " no wildcards accepted", "Flag h <host>: user has string <host> in his/her hostname,", " wildcards accepted", "Flag m <usermodes>: user has <usermodes> set, only", " O/o/C/A/a/N/B are allowed", "Flag n <nick>: user has string <nick> in his/her nickname,", " wildcards accepted", "Flag s <server>: user is on server <server>,", " wildcards not accepted", "Flag u <user>: user has string <user> in his/her username,", " wildcards accepted", "Behavior flags:", "Flag M: check for user in channels I am a member of", NULL }; char *who_oper_help[] = { "/WHO [+|-][acghimnsuMRI] [args]", "Flags are specified like channel modes, the flags chigmnsu all have arguments", "Flags are set to a positive check by +, a negative check by -", "The flags work as follows:", "Flag a: user is away", "Flag c <channel>: user is on <channel>,", " no wildcards accepted", "Flag g <gcos/realname>: user has string <gcos> in his/her GCOS,", " wildcards accepted", "Flag h <host>: user has string <host> in his/her hostname,", " wildcards accepted", "Flag i <ip>: user has string <ip> in his/her IP address,", " wildcards accepted", "Flag m <usermodes>: user has <usermodes> set", "Flag n <nick>: user has string <nick> in his/her nickname,", " wildcards accepted", "Flag s <server>: user is on server <server>,", " wildcards not accepted", "Flag u <user>: user has string <user> in his/her username,", " wildcards accepted", "Behavior flags:", "Flag M: check for user in channels I am a member of", "Flag R: show users' real hostnames", "Flag I: show users' IP addresses", NULL }; char **s; if (IsAnOper(sptr)) s = who_oper_help; else s = who_help; for (; *s; s++) sendto_one(sptr, getreply(RPL_LISTSYNTAX), me.name, sptr->name, *s);}#define WHO_ADD 1#define WHO_DEL 2static int parse_who_options(aClient *sptr, int argc, char **argv){char *s = argv[0];int what = WHO_ADD;int i = 1;/* A few helper macro's because this is used a lot, added during recode by Syzop. *//** function requiress a parameter: check if there's one, if not: return -1. */#define REQUIRE_PARAM() { if (i >= argc) { \ who_sendhelp(sptr); \ return -1; \ } } while(0);/** set option 'x' depending on 'what' (add/want or del/dontwant) */#define SET_OPTION(x) { if (what == WHO_ADD) \ x = WHO_WANT; \ else \ x = WHO_DONTWANT; \ } while(0);/** Eat a param, set the param in memory and set the option to want or dontwant */#define DOIT(x,y) { REQUIRE_PARAM(); x = argv[i]; SET_OPTION(y); i++; } while(0); if (*s != '-' && *s != '+') return 0; while (*s) { switch (*s) { case '+': what = WHO_ADD; break; case '-': what = WHO_DEL; break; case 'a': SET_OPTION(wfl.want_away); break; case 'c': DOIT(wfl.channel, wfl.want_channel); break; case 'g': REQUIRE_PARAM() if (!IsAnOper(sptr)) break; /* oper-only */ wfl.gecos = argv[i]; SET_OPTION(wfl.want_gecos); i++; break; case 's': DOIT(wfl.server, wfl.want_server); break; case 'h': DOIT(wfl.host, wfl.want_host); break; case 'i': REQUIRE_PARAM() if (!IsAnOper(sptr)) break; /* oper-only */ wfl.ip = argv[i]; SET_OPTION(wfl.want_ip); i++; break; case 'n': DOIT(wfl.nick, wfl.want_nick); break; case 'u': DOIT(wfl.user, wfl.want_user); break; case 'm': REQUIRE_PARAM() { char *s = argv[i]; int *umodes; if (what == WHO_ADD) umodes = &wfl.umodes_want; else umodes = &wfl.umodes_dontwant; while (*s) { int i; for (i = 0; i <= Usermode_highest; i++) if (*s == Usermode_Table[i].flag) { *umodes |= Usermode_Table[i].mode; break; } s++; } if (!IsAnOper(sptr)) *umodes = *umodes & (UMODE_OPER | UMODE_LOCOP | UMODE_SADMIN | UMODE_ADMIN | UMODE_COADMIN | UMODE_NETADMIN | UMODE_BOT); if (*umodes == 0) return -1; } i++; break; case 'M': SET_OPTION(wfl.common_channels_only); break; case 'R': if (!IsAnOper(sptr)) break; if (what == WHO_ADD) who_flags |= WF_REALHOST; else who_flags &= ~WF_REALHOST; break; case 'I': if (!IsAnOper(sptr)) break; if (what == WHO_ADD) who_flags |= WF_IP; else who_flags &= ~WF_IP; break; default: who_sendhelp(sptr); return -1; } s++; } return i;#undef REQUIRE_PARAM#undef SET_OPTION#undef DOIT}static int can_see(aClient *sptr, aClient *acptr, aChannel *channel){int ret = 0;char has_common_chan = 0; do { /* can only see people */ if (!IsPerson(acptr)) return WHO_CANTSEE; /* can only see opers if thats what they want */ if (who_flags & WF_OPERONLY)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -