"Fossies" - the Fresh Open Source Software Archive

Member "bahamut-2.1.5/src/s_serv.c" (28 May 2020, 101178 Bytes) of package /linux/privat/bahamut-2.1.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "s_serv.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.1.4_vs_2.1.5.

    1 /************************************************************************
    2  *   IRC - Internet Relay Chat, src/s_serv.c
    3  *   Copyright (C) 1990 Jarkko Oikarinen and
    4  *                      University of Oulu, Computing Center
    5  *
    6  *   See file AUTHORS in IRC package for additional names of
    7  *   the programmers.
    8  *
    9  *   This program is free software; you can redistribute it and/or modify
   10  *   it under the terms of the GNU General Public License as published by
   11  *   the Free Software Foundation; either version 1, or (at your option)
   12  *   any later version.
   13  *
   14  *   This program is distributed in the hope that it will be useful,
   15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  *   GNU General Public License for more details.
   18  *
   19  *   You should have received a copy of the GNU General Public License
   20  *   along with this program; if not, write to the Free Software
   21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   22  */
   23 
   24 #include "struct.h"
   25 #include "common.h"
   26 #include "sys.h"
   27 #include "numeric.h"
   28 #include "msg.h"
   29 #include "channel.h"
   30 #include "nameser.h"
   31 #include "resolv.h"
   32 #include "dh.h"
   33 #include "zlink.h"
   34 #include "userban.h"
   35 
   36 #if defined(AIX) || defined(SVR3)
   37 #include <time.h>
   38 #endif
   39 #include <sys/stat.h>
   40 #include <sys/utsname.h>
   41 #include <fcntl.h>
   42 #include "h.h"
   43 #if defined( HAVE_STRING_H )
   44 #include <string.h>
   45 #else
   46 /* older unices don't have strchr/strrchr .. help them out */
   47 #include <strings.h>
   48 #undef strchr
   49 #define strchr index
   50 #endif
   51 #include "fdlist.h"
   52 #include "throttle.h"
   53 #include "clones.h"
   54 #include "memcount.h"
   55 #include <zlib.h>
   56 
   57 static char buf[BUFSIZE];
   58 extern int  rehashed;
   59 extern int  forked;
   60 
   61 /* external variables */
   62 
   63 /* external functions */
   64 
   65 extern char *smalldate(time_t); /* defined in s_misc.c */
   66 extern void outofmemory(void);  /* defined in list.c */
   67 extern void s_die(void);
   68 extern int  match(char *, char *);      /* defined in match.c */
   69 extern char *engine_name(); /* defined in socketengine_*.c */
   70 extern struct FlagList xflags_list[]; /* for m_check() */
   71 
   72 /* Local function prototypes */
   73 
   74 int         send_motd(aClient *, aClient *, int, char **);
   75 void        read_motd(char *);
   76 void        read_shortmotd(char *);
   77 
   78 char        motd_last_changed_date[MAX_DATE_STRING]; /* enough room for date */ 
   79 
   80 void fakeserver_list(aClient *);
   81 int fakelinkscontrol(int, char **);
   82 void fakelinkserver_update(char *, char *);
   83 void fakeserver_sendserver(aClient *);
   84 
   85 int is_luserslocked();
   86 void send_fake_users(aClient *);
   87 void send_fake_lusers(aClient *);
   88 void fakelusers_sendlock(aClient *);
   89 
   90 int local_rehash(aClient *, aClient *, char *, char *);
   91 
   92 /*
   93  * m_functions execute protocol messages on this server: *
   94  * 
   95  * cptr: 
   96  ** always NON-NULL, pointing to a *LOCAL* client
   97  ** structure (with an open socket connected!). This 
   98  ** is the physical socket where the message originated (or
   99  ** which caused the m_function to be executed--some
  100  ** m_functions may call others...). 
  101  * 
  102  * sptr:
  103  ** the source of the message, defined by the
  104  ** prefix part of the message if present. If not or
  105  ** prefix not found, then sptr==cptr. 
  106  * 
  107  *      *Always* true (if 'parse' and others are working correct): 
  108  * 
  109  *      1)      sptr->from == cptr  (note: cptr->from == cptr) 
  110  * 
  111  *      2)      MyConnect(sptr) <=> sptr == cptr (e.g. sptr 
  112  * cannot be a local connection, unless it's actually cptr!). 
  113  *
  114  * MyConnect(x) should probably  be defined as (x == x->from) --msa
  115  * 
  116  * parc:    
  117  ** number of variable parameter strings (if zero, 
  118  ** parv is allowed to be NULL)
  119  * 
  120  * parv:    
  121  ** a NULL terminated list of parameter pointers,
  122  *** parv[0], sender (prefix string), if not present his points to 
  123  *** an empty string.
  124  *
  125  ** [parc-1]:
  126  *** pointers to additional parameters 
  127  *** parv[parc] == NULL, *always* 
  128  * 
  129  * note:   it is guaranteed that parv[0]..parv[parc-1] are all
  130  *         non-NULL pointers.
  131  */
  132 
  133 /*
  134  * * m_version 
  135  *      parv[0] = sender prefix 
  136  *      parv[1] = remote server
  137  */
  138 int 
  139 m_version(aClient *cptr, aClient *sptr, int parc, char *parv[])
  140 {
  141 
  142     if (hunt_server(cptr, sptr, ":%s VERSION :%s", 1, parc, parv) ==
  143         HUNTED_ISME)
  144         send_rplversion(sptr);
  145 
  146     return 0;
  147 }
  148 
  149 /*
  150  * m_squit
  151  * there are two types of squits: those going downstream (to the target server)
  152  * and those going back upstream (from the target server).
  153  * previously, it wasn't necessary to distinguish between these two types of 
  154  * squits because they neatly echoed back all of the QUIT messages during
  155  * an squit.  This, however, is no longer practical.
  156  * 
  157  * To clarify here, DOWNSTREAM signifies an SQUIT heading towards the target
  158  * server UPSTREAM signifies an SQUIT which has successfully completed,
  159  * heading out everywhere.
  160  *
  161  * acptr is the server being squitted.
  162  * a DOWNSTREAM squit is where the notice did not come from acptr->from.
  163  * an UPSTREAM squit is where the notice DID come from acptr->from.
  164  *
  165  *        parv[0] = sender prefix 
  166  *        parv[1] = server name 
  167  *        parv[2] = comment
  168  */
  169 int 
  170 m_squit(aClient *cptr, aClient *sptr, int parc, char *parv[])
  171 {
  172     aConnect *aconn;
  173     char *server;
  174     aClient *acptr;
  175     char *comment = (parc > 2) ? parv[2] : sptr->name;
  176 
  177     if (!IsPrivileged(sptr)) 
  178     {
  179         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
  180         return 0;
  181     }
  182 
  183     if (parc > 1) 
  184     {
  185         server = parv[1];
  186         /* To accomodate host masking, a squit for a masked server
  187          * name is expanded if the incoming mask is the same as the
  188          * server name for that link to the name of link.
  189          */
  190         while ((*server == '*') && IsServer(cptr))
  191         {
  192             aconn = cptr->serv->aconn;
  193             if (!aconn)
  194                 break;
  195             if (!mycmp(server, my_name_for_link(me.name, aconn)))
  196                 server = cptr->name;
  197             break;                      /* WARNING is normal here */
  198             /* NOTREACHED */
  199         }
  200         /*
  201          * The following allows wild cards in SQUIT. Only useful when
  202          * the command is issued by an oper.
  203          */
  204         for (acptr = client; (acptr = next_client(acptr, server)); 
  205              acptr = acptr->next)
  206             if (IsServer(acptr) || IsMe(acptr))
  207                 break;
  208         if (acptr && IsMe(acptr)) 
  209         {
  210             acptr = cptr;
  211             server = cptr->name;
  212         }
  213     }
  214     else
  215     {
  216         /* This is actually protocol error. But, well, closing the
  217          * link is very proper answer to that...
  218          */
  219         server = cptr->name;
  220         acptr = cptr;
  221     }
  222 
  223     if (!acptr) 
  224     {
  225         sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
  226                    me.name, parv[0], server);
  227         return 0;
  228     }
  229 
  230     if (MyClient(sptr) && ((!OPCanGRoute(sptr) && !MyConnect(acptr)) || 
  231                            (!OPCanLRoute(sptr) && MyConnect(acptr)))) 
  232     {
  233         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
  234         return 0;
  235     }
  236 
  237     /* If the server is mine, we don't care about upstream or downstream,
  238        just kill it and do the notice. */
  239     
  240     if (MyConnect(acptr)) 
  241     {
  242         sendto_gnotice("from %s: Received SQUIT %s from %s (%s)",
  243                        me.name, acptr->name, get_client_name(sptr, HIDEME),
  244                        comment);
  245         sendto_serv_butone(NULL, ":%s GNOTICE :Received SQUIT %s from %s (%s)",
  246                            me.name, server, get_client_name(sptr, HIDEME),
  247                            comment);
  248         
  249 #if defined(USE_SYSLOG) && defined(SYSLOG_SQUIT)
  250         syslog(LOG_DEBUG, "SQUIT From %s : %s (%s)",
  251                parv[0], server, comment);
  252 #endif
  253         /* I am originating this squit! Not cptr! */
  254         /* ack, but if cptr is squitting itself.. */
  255         if(cptr == sptr)
  256         {
  257             exit_client(&me, acptr, sptr, comment);
  258             return FLUSH_BUFFER; /* kludge */
  259         }
  260         return exit_client(&me, acptr, sptr, comment);
  261     }
  262     
  263     /* the server is not connected to me. Determine whether this is an upstream
  264        or downstream squit */
  265     
  266     if(sptr->from == acptr->from) /* upstream */
  267     {
  268         sendto_realops_lev(DEBUG_LEV,
  269                            "Exiting server %s due to upstream squit by %s [%s]",
  270                            acptr->name, sptr->name, comment);
  271         return exit_client(cptr, acptr, sptr, comment);
  272     }
  273 
  274     /* fallthrough: downstream */
  275 
  276     if(!(IsUnconnect(acptr->from))) /* downstream not unconnect capable */
  277     {
  278         sendto_realops_lev(DEBUG_LEV,
  279                     "Exiting server %s due to non-unconnect server %s [%s]",
  280                     acptr->name, acptr->from->name, comment);
  281         return exit_client(&me, acptr, sptr, comment);
  282     }
  283 
  284     
  285     sendto_realops_lev(DEBUG_LEV, "Passing along SQUIT for %s by %s [%s]",
  286                        acptr->name, sptr->name, comment);
  287     sendto_one(acptr->from, ":%s SQUIT %s :%s", parv[0], acptr->name, comment);
  288 
  289     return 0;
  290 }
  291 
  292 /*
  293  * m_svinfo 
  294  *       parv[0] = sender prefix 
  295  *       parv[1] = TS_CURRENT for the server 
  296  *       parv[2] = TS_MIN for the server 
  297  *       parv[3] = server is standalone or connected to non-TS only 
  298  *       parv[4] = server's idea of UTC time
  299  */
  300 int m_svinfo(aClient *cptr, aClient *sptr, int parc, char *parv[])
  301 {
  302     time_t      deltat, tmptime, theirtime;
  303     
  304     if (!IsServer(sptr) || !MyConnect(sptr))
  305         return 0;
  306 
  307     if(parc == 2 && mycmp(parv[1], "ZIP") == 0)
  308     {
  309         SetZipIn(sptr);
  310         sptr->serv->zip_in = zip_create_input_session();
  311         sendto_gnotice("from %s: Input from %s is now compressed",
  312                        me.name, get_client_name(sptr, HIDEME));
  313         sendto_serv_butone(sptr,
  314                            ":%s GNOTICE :Input from %s is now compressed",
  315                            me.name, get_client_name(sptr, HIDEME));
  316         return ZIP_NEXT_BUFFER;
  317     }
  318     
  319     if(parc < 5 || !DoesTS(sptr))
  320         return 0;
  321     
  322     if (TS_CURRENT < atoi(parv[2]) || atoi(parv[1]) < TS_MIN) 
  323     {
  324         /* a server with the wrong TS version connected; since we're
  325          * TS_ONLY we can't fall back to the non-TS protocol so we drop
  326          * the link  -orabidoo
  327          */
  328         sendto_ops("Link %s dropped, wrong TS protocol version (%s,%s)",
  329                    get_client_name(sptr, HIDEME), parv[1], parv[2]);
  330         return exit_client(sptr, sptr, sptr, "Incompatible TS version");
  331     }
  332     
  333     tmptime = time(NULL);
  334     theirtime = atol(parv[4]);
  335     deltat = abs(theirtime - tmptime);
  336     
  337     if (deltat > tsmaxdelta) 
  338     {
  339         sendto_gnotice("from %s: Link %s dropped, excessive TS delta (my "
  340                        "TS=%ld, their TS=%ld, delta=%ld)",
  341                        me.name, get_client_name(sptr, HIDEME),
  342                (long)tmptime, (long)theirtime, (long)deltat);
  343         sendto_serv_butone(sptr, ":%s GNOTICE :Link %s dropped, excessive "
  344                            "TS delta (delta=%ld)",
  345                            me.name, get_client_name(sptr, HIDEME),
  346                (long)deltat);
  347         return exit_client(sptr, sptr, sptr, "Excessive TS delta");
  348     }
  349 
  350     if (deltat > tswarndelta) 
  351     {
  352         sendto_realops("Link %s notable TS delta (my TS=%ld, their TS=%ld, "
  353                        "delta=%ld)", get_client_name(sptr, HIDEME),
  354                (long)tmptime, (long)theirtime, (long)deltat);
  355     }
  356 
  357     return 0;
  358 }
  359 
  360 /* 
  361  * m_burst
  362  *      parv[0] = sender prefix
  363  *      parv[1] = SendQ if an EOB
  364  */
  365 int 
  366 m_burst(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
  367 {
  368   
  369     if (!IsServer(sptr) || sptr != cptr || parc > 2 || !IsBurst(sptr))
  370         return 0;
  371     if (parc == 2) { /* This is an EOB */
  372         sptr->flags &= ~(FLAGS_EOBRECV);
  373         if (sptr->flags & (FLAGS_SOBSENT|FLAGS_BURST)) return 0;
  374         
  375         /* we've already sent our EOB.. we synched first
  376          * no need to check IsBurst because we shouldn't receive a BURST if 
  377          * they're not BURST capab
  378          */
  379         
  380         sendto_gnotice("from %s: synch to %s in %ld %s at %s sendq", me.name,
  381                        *parv, (long)(timeofday-sptr->firsttime),
  382                        (timeofday-sptr->firsttime)==1?"sec":"secs", parv[1]);
  383         sendto_serv_butone(NULL,
  384                            ":%s GNOTICE :synch to %s in %ld %s at %s sendq",
  385                            me.name, sptr->name, (long)(timeofday-sptr->firsttime),
  386                            (timeofday-sptr->firsttime)==1?"sec":"secs",
  387                            parv[1]);
  388         
  389     }
  390     else
  391     {
  392         sptr->flags |= FLAGS_EOBRECV;
  393     }
  394     return 0;
  395 }
  396 
  397 /*
  398  * * m_info 
  399  *      parv[0] = sender prefix 
  400  *      parv[1] = servername
  401  */
  402 int 
  403 m_info(aClient *cptr, aClient *sptr, int parc, char *parv[])
  404 {
  405     char      **text = infotext;
  406 
  407     static time_t last_used = 0L;
  408     struct utsname uninfo;
  409 
  410     if (hunt_server(cptr,sptr,":%s INFO :%s",1,parc,parv) == HUNTED_ISME) 
  411     {
  412         if(!IsULine(sptr) && !IsServer(sptr))
  413         {
  414             sendto_realops_lev(SPY_LEV, "INFO requested by %s (%s@%s) [%s]",
  415                                sptr->name, sptr->user->username, sptr->user->host,
  416                                sptr->user->server);
  417                         
  418             if (!IsAnOper(sptr)) 
  419             {
  420                 if (IsSquelch(sptr)) {
  421                     sendto_one(sptr, rpl_str(RPL_ENDOFINFO), me.name, parv[0]);
  422                     return 0;
  423                 }
  424                 if (!MyConnect(sptr))
  425                     return 0;
  426                 if ((last_used + MOTD_WAIT) > NOW) 
  427                     return 0;
  428                 else 
  429                     last_used = NOW;
  430             }
  431         }
  432         while (*text)
  433             sendto_one(sptr, rpl_str(RPL_INFO),
  434                        me.name, parv[0], *text++);
  435                         
  436         if(IsAdmin(sptr) || IsULine(sptr))
  437         {
  438             uname(&uninfo);
  439             sendto_one(sptr, ":%s %d %s :OS: %s %s %s %s",
  440                        me.name, RPL_INFO, parv[0], uninfo.sysname,
  441                        uninfo.release, uninfo.machine, uninfo.version);
  442             sendto_one(sptr, ":%s %d %s :Socket Engine Type: %s", me.name,
  443                        RPL_INFO, parv[0], engine_name());
  444 #ifdef USE_SSL
  445             sendto_one(sptr, ":%s %d %s :OpenSSL Version: %s", me.name,
  446                        RPL_INFO, parv[0], SSLeay_version(SSLEAY_VERSION));
  447 #endif
  448             sendto_one(sptr, ":%s %d %s :zlib version: %s", me.name,
  449                        RPL_INFO, parv[0], ZLIB_VERSION);
  450             sendto_one(sptr, ":%s %d %s :FD_SETSIZE=%d WRITEV_IOV=%d "
  451                        "MAXCONNECTIONS=%d MAX_BUFFER=%d MAXCLIENTS=%d",
  452                        me.name, RPL_INFO, parv[0], FD_SETSIZE,
  453 #ifdef WRITEV_IOV
  454                        WRITEV_IOV,
  455 #else
  456                        0,
  457 #endif
  458                        MAXCONNECTIONS, MAX_BUFFER, MAXCLIENTS);
  459         }
  460 
  461         sendto_one(sptr, rpl_str(RPL_INFO), me.name, parv[0], "");
  462 
  463         /* I am -definately- going to come up with a replacement for this! */
  464         /* you didnt, so i removed it.. kinda stupid anyway.  -epi */
  465         
  466         sendto_one(sptr,
  467                    ":%s %d %s :Birth Date: %s, compile #%s",
  468                    me.name, RPL_INFO, parv[0], creation, generation);
  469         sendto_one(sptr, ":%s %d %s :On-line since %s",
  470                    me.name, RPL_INFO, parv[0],
  471                    myctime(me.firsttime));
  472         sendto_one(sptr, rpl_str(RPL_ENDOFINFO), me.name, parv[0]);
  473     }
  474  
  475     return 0;
  476 }
  477 
  478 /*
  479  * * m_links 
  480  *      parv[0] = sender prefix 
  481  *      parv[1] = servername mask 
  482  * or 
  483  *      parv[0] = sender prefix 
  484  *      parv[1] = server to query 
  485  *      parv[2] = servername mask
  486  */
  487 int 
  488 m_links(aClient *cptr, aClient *sptr, int parc, char *parv[])
  489 {
  490     char       *mask;
  491     aClient    *acptr;
  492     char        clean_mask[(2 * HOSTLEN) + 1];
  493     char       *s;
  494     char       *d;
  495     int         n;
  496 
  497     /* reject non-local requests */
  498     if (IsServer(sptr) || (!IsAnOper(sptr) && !MyConnect(sptr)))
  499         return 0;
  500 
  501     mask = (parc < 2) ? NULL : parv[1];
  502     
  503     /*
  504      * * sigh* Before the kiddies find this new and exciting way of
  505      * * annoying opers, lets clean up what is sent to all opers
  506      * * -Dianora
  507      */
  508 
  509     if (mask) 
  510     {      /* only necessary if there is a mask */
  511         s = mask;
  512         d = clean_mask;
  513         n = (2 * HOSTLEN) - 2;
  514         while (*s && n > 0) 
  515         {
  516             /* Is it a control character? */
  517             if ((unsigned char) *s < (unsigned char) ' ') 
  518             {
  519                 *d++ = '^';
  520                 /* turn it into a printable */
  521                 *d++ = (char) ((unsigned char)*s + 0x40); 
  522                 s++;
  523                 n -= 2;
  524             }
  525             else if ((unsigned char) *s > (unsigned char) '~') 
  526             {
  527                 *d++ = '.';
  528                 s++;
  529                 n--;
  530             }
  531             else 
  532             {
  533                 *d++ = *s++;
  534                 n--;
  535             }
  536         }
  537         *d = '\0';
  538     }
  539 
  540     if (MyConnect(sptr))
  541         sendto_realops_lev(SPY_LEV,
  542                            "LINKS %s requested by %s (%s@%s) [%s]",
  543                            mask ? clean_mask : "all",
  544                            sptr->name, sptr->user->username,
  545                            sptr->user->host, sptr->user->server);
  546 
  547     if(!(confopts & FLAGS_SHOWLINKS) && !IsAnOper(sptr))
  548         fakeserver_list(sptr);
  549     else
  550     for (acptr = client, (void) collapse(mask); acptr; acptr = acptr->next) 
  551     {
  552         if (!IsServer(acptr) && !IsMe(acptr))
  553             continue;
  554         if (!BadPtr(mask) && match(mask, acptr->name))
  555             continue;
  556 #ifdef HIDEULINEDSERVS
  557         if (!IsOper(sptr) && IsULine(acptr))
  558             continue;
  559 #endif
  560         sendto_one(sptr, rpl_str(RPL_LINKS),
  561                    me.name, parv[0], acptr->name, acptr->serv->up,
  562                    acptr->hopcount, (acptr->info[0] ? acptr->info :
  563                                      "(Unknown Location)"));
  564     }
  565     sendto_one(sptr, rpl_str(RPL_ENDOFLINKS), me.name, parv[0],
  566                BadPtr(mask) ? "*" : clean_mask);
  567     return 0;
  568 }
  569 
  570 /*
  571  * * m_users 
  572  *        parv[0] = sender prefix 
  573  *        parv[1] = servername
  574  */
  575 int 
  576 m_users(aClient *cptr, aClient *sptr, int parc, char *parv[])
  577 {
  578     if (hunt_server(cptr, sptr, ":%s USERS :%s", 1, parc, parv) == HUNTED_ISME) 
  579     {
  580         if(is_luserslocked())
  581         {
  582             send_fake_users(sptr);
  583             return 0;
  584         }
  585         /* No one uses this any more... so lets remap it..   -Taner */
  586         sendto_one(sptr, rpl_str(RPL_LOCALUSERS), me.name, parv[0],
  587                    Count.local, Count.max_loc);
  588         sendto_one(sptr, rpl_str(RPL_GLOBALUSERS), me.name, parv[0],
  589                    Count.total, Count.max_tot);
  590     }
  591     return 0;
  592 }
  593 
  594 /*
  595  * * Note: At least at protocol level ERROR has only one parameter, 
  596  * although this is called internally from other functions  --msa 
  597  *
  598  *      parv[0] = sender prefix 
  599  *      parv[*] = parameters
  600  */
  601 int 
  602 m_error(aClient *cptr, aClient *sptr, int parc, char *parv[])
  603 {
  604     char   *para;
  605 
  606     para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>";
  607 
  608     Debug((DEBUG_ERROR, "Received ERROR message from %s: %s",
  609            sptr->name, para));
  610     /*
  611      * * Ignore error messages generated by normal user clients 
  612      * (because ill-behaving user clients would flood opers screen
  613      * otherwise). Pass ERROR's from other sources to the local
  614      * operator...
  615      */
  616     if (IsPerson(cptr) || IsUnknown(cptr))
  617         return 0;
  618 
  619     sendto_serv_butone_super(cptr, 0, ":%s GNOTICE :Error -- %s", parv[0], para);
  620     sendto_gnotice("from %s: Error -- %s", parv[0], para);
  621 
  622     return 0;
  623 }
  624 
  625 /*
  626  * m_help
  627  * parv[0] = sender prefix
  628  * 
  629  * Forward help requests to HelpServ if defined, and is invoked
  630  * by non-opers, otherwise sends opers.txt to opers (if present),
  631  * or sends a big list of commands to non-opers (and opers if
  632  * opers.txt is not present). -srd
  633  */
  634 int 
  635 m_help(aClient *cptr, aClient *sptr, int parc, char *parv[])
  636 {
  637     int         i;
  638     aMotd *helpfile_ptr;
  639 
  640     static time_t last_used = 0L;
  641 
  642 #ifdef HELP_FORWARD_HS
  643     if (!IsAnOper(sptr))
  644     {
  645        if (parc < 2 || *parv[1] == '\0')
  646        {
  647           sendto_one(sptr, ":%s NOTICE %s :For a list of help topics, type "
  648                      "/%s %s", me.name, sptr->name, HELPSERV, DEF_HELP_CMD);
  649           return -1;
  650        }
  651         return m_aliased(cptr, sptr, parc, parv, &aliastab[AII_HS]);
  652  
  653        return 0;
  654     }
  655 #endif
  656     
  657     if (!IsAnOper(sptr))
  658     {
  659        /* reject non local requests */
  660        if ((last_used + MOTD_WAIT) > NOW)
  661           return 0;   
  662        else
  663           last_used = NOW;
  664     }
  665 
  666     if (!IsAnOper(sptr) || (helpfile == (aMotd *) NULL))
  667     {
  668         for (i = 0; msgtab[i].cmd; i++)
  669             sendto_one(sptr, ":%s NOTICE %s :%s",
  670                        me.name, parv[0], msgtab[i].cmd);
  671         return 0;
  672     }
  673        
  674     helpfile_ptr = helpfile;
  675     while (helpfile_ptr)
  676     {
  677         sendto_one(sptr,
  678                    ":%s NOTICE %s :%s",
  679                    me.name, parv[0], helpfile_ptr->line);
  680         helpfile_ptr = helpfile_ptr->next;
  681     }
  682        
  683     return 0;
  684 }
  685 
  686 /*
  687  * parv[0] = sender parv[1] = host/server mask. 
  688  * parv[2] = server to query
  689  * 
  690  * 199970918 JRL hacked to ignore parv[1] completely and require parc > 3
  691  * to cause a force
  692  *
  693  * Now if parv[1] is anything other than *, it forces a recount.
  694  *    -Quension [May 2005]
  695  */
  696 int 
  697 m_lusers(aClient *cptr, aClient *sptr, int parc, char *parv[])
  698 {
  699     int send_lusers(aClient *, aClient *, int, char **);
  700 
  701     if (parc > 2) 
  702     {
  703         if (hunt_server(cptr, sptr, ":%s LUSERS %s :%s", 2, parc, parv) !=
  704             HUNTED_ISME)
  705             return 0;
  706     }
  707 
  708     if(!IsAnOper(sptr) && is_luserslocked())
  709     {
  710        send_fake_lusers(sptr);
  711        return 0;
  712     }           
  713 
  714     return send_lusers(cptr,sptr,parc,parv);
  715 }
  716 
  717 /*
  718  * send_lusers
  719  *     parv[0] = sender
  720  *     parv[1] = anything but "*" to force a recount
  721  *     parv[2] = server to query
  722  */
  723 int send_lusers(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
  724 {
  725     /* forced recount */
  726     if (IsAnOper(sptr) && (parc > 1) && (*parv[1] != '*')) 
  727     {
  728         int s_count = 0;
  729         int c_count = 0;
  730         int u_count = 0;
  731         int i_count = 0;
  732         int o_count = 0;
  733         int m_client = 0;
  734         int m_server = 0;
  735         int m_ulined = 0;
  736         aClient *acptr;
  737         
  738         for (acptr = client; acptr; acptr = acptr->next) 
  739         {
  740             switch (acptr->status) 
  741             {
  742             case STAT_SERVER:
  743                 if (MyConnect(acptr))
  744                 {
  745                     m_server++;
  746                     if(IsULine(acptr))
  747                         m_ulined++;
  748                 }
  749             case STAT_ME:
  750                 s_count++;
  751                 break;
  752             case STAT_CLIENT:
  753                 if (IsAnOper(acptr))
  754                     o_count++;
  755 #ifdef  SHOW_INVISIBLE_LUSERS
  756                 if (MyConnect(acptr))
  757                     m_client++;
  758                 if (!IsInvisible(acptr))
  759                     c_count++;
  760                 else
  761                     i_count++;
  762 #else
  763                 if (MyConnect(acptr)) 
  764                 {
  765                     if (IsInvisible(acptr)) 
  766                     {
  767                         if (IsAnOper(sptr))
  768                             m_client++;
  769                     }
  770                     else
  771                         m_client++;
  772                 }
  773                 if (!IsInvisible(acptr))
  774                     c_count++;
  775                 else
  776                     i_count++;
  777 #endif
  778                 break;
  779             default:
  780                 u_count++;
  781                 break;
  782             }
  783         }
  784 
  785         /* sanity check */
  786         if (m_server != Count.myserver)
  787         {
  788             sendto_realops_lev(DEBUG_LEV, "Local server count off by %d",
  789                                Count.myserver - m_server);
  790             Count.myserver = m_server;
  791         }
  792         if (m_ulined != Count.myulined)
  793         {
  794             sendto_realops_lev(DEBUG_LEV, "Local superserver count off by %d",
  795                                Count.myulined - m_ulined);
  796             Count.myulined = m_ulined;
  797         }
  798         if (s_count != Count.server)
  799         {
  800             sendto_realops_lev(DEBUG_LEV, "Server count off by %d",
  801                                Count.server - s_count);
  802             Count.server = s_count;
  803         }
  804         if (i_count != Count.invisi)
  805         {
  806             sendto_realops_lev(DEBUG_LEV, "Invisible client count off by %d",
  807                                Count.invisi - i_count);
  808             Count.invisi = i_count;
  809         }
  810         if ((c_count + i_count) != Count.total)
  811         {
  812             sendto_realops_lev(DEBUG_LEV, "Total client count off by %d",
  813                                Count.total - (c_count + i_count));
  814             Count.total = c_count + i_count;
  815         }
  816         if (m_client != Count.local)
  817         {
  818             sendto_realops_lev(DEBUG_LEV, "Local client count off by %d",
  819                                Count.local - m_client);
  820             Count.local = m_client;
  821         }
  822         if (o_count != Count.oper)
  823         {
  824             sendto_realops_lev(DEBUG_LEV, "Oper count off by %d",
  825                                Count.oper - o_count);
  826             Count.oper = o_count;
  827         }
  828         if (u_count != Count.unknown)
  829         {
  830             sendto_realops_lev(DEBUG_LEV, "Unknown connection count off by %d",
  831                                Count.unknown - u_count);
  832             Count.unknown = u_count;
  833         }
  834     }   /* Recount loop */
  835 
  836     /* save stats */
  837     if ((timeofday - last_stat_save) > 3600)
  838     {
  839         FILE *fp;
  840         char tmp[PATH_MAX];
  841         
  842         last_stat_save = timeofday;
  843         ircsprintf(tmp, "%s/.maxclients", dpath);
  844         fp = fopen(tmp, "w");
  845         if (fp != NULL)
  846         {
  847             fprintf(fp, "%d %d %li %li %li %ld %ld %ld %ld", Count.max_loc,
  848                     Count.max_tot, Count.weekly, Count.monthly,
  849                     Count.yearly, Count.start, Count.week, Count.month,
  850                     Count.year);
  851             fclose(fp);
  852             sendto_realops_lev(DEBUG_LEV, "Saved maxclient statistics");
  853         }
  854     }
  855     
  856     
  857 #ifndef SHOW_INVISIBLE_LUSERS
  858     if (IsAnOper(sptr) && Count.invisi)
  859 #endif
  860         sendto_one(sptr, rpl_str(RPL_LUSERCLIENT), me.name, parv[0],
  861                    Count.total - Count.invisi, Count.invisi, Count.server);
  862 #ifndef SHOW_INVISIBLE_LUSERS
  863     else
  864         sendto_one(sptr,
  865                    ":%s %d %s :There are %d users on %d servers", me.name,
  866                    RPL_LUSERCLIENT, parv[0], Count.total - Count.invisi,
  867                    Count.server);
  868 #endif
  869 
  870     if (Count.oper)
  871         sendto_one(sptr, rpl_str(RPL_LUSEROP), me.name, parv[0], Count.oper);
  872 
  873     if (IsAnOper(sptr) && Count.unknown)
  874         sendto_one(sptr, rpl_str(RPL_LUSERUNKNOWN), me.name, parv[0],
  875                    Count.unknown);
  876     
  877     /* This should be ok */
  878     if (Count.chan > 0)
  879         sendto_one(sptr, rpl_str(RPL_LUSERCHANNELS),
  880                    me.name, parv[0], Count.chan);
  881     sendto_one(sptr, rpl_str(RPL_LUSERME),
  882 #ifdef HIDEULINEDSERVS
  883                me.name, parv[0], Count.local, 
  884                IsOper(sptr) ? Count.myserver : Count.myserver - Count.myulined);
  885 #else
  886                me.name, parv[0], Count.local, Count.myserver);
  887 #endif
  888 
  889     sendto_one(sptr, rpl_str(RPL_LOCALUSERS), me.name, parv[0],
  890                    Count.local, Count.max_loc);
  891     sendto_one(sptr, rpl_str(RPL_GLOBALUSERS), me.name, parv[0],
  892                Count.total, Count.max_tot);
  893     return 0;
  894 }
  895 
  896 /***********************************************************************
  897  * m_connect() - Added by Jto 11 Feb 1989
  898  ***********************************************************************/
  899 /*
  900  * * m_connect 
  901  *      parv[0] = sender prefix 
  902  *      parv[1] = servername 
  903  *      parv[2] = port number 
  904  *      parv[3] = remote server
  905  */
  906 int 
  907 m_connect(aClient *cptr, aClient *sptr, int parc, char *parv[])
  908 {
  909     int         port, tmpport, retval;
  910     aConnect   *aconn;
  911     aClient    *acptr;
  912 
  913     if (!IsPrivileged(sptr))
  914     {
  915         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
  916         return -1;
  917     }
  918     
  919     if ((MyClient(sptr) && !OPCanGRoute(sptr) && parc > 3) ||
  920         (MyClient(sptr) && !OPCanLRoute(sptr) && parc <= 3))
  921     {
  922         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
  923         return 0;
  924     }
  925     
  926     if (hunt_server(cptr, sptr, ":%s CONNECT %s %s :%s",
  927                     3, parc, parv) != HUNTED_ISME)
  928         return 0;
  929 
  930     if (parc < 2 || *parv[1] == '\0') 
  931     {
  932         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
  933                    me.name, parv[0], "CONNECT");
  934         return -1;
  935     }
  936 
  937     if ((acptr = find_server(parv[1], NULL)))
  938     {
  939         sendto_one(sptr, ":%s NOTICE %s :Connect: Server %s %s %s.",
  940                    me.name, parv[0], parv[1], "already exists from",
  941                    acptr->from->name);
  942         return 0;
  943     }
  944 
  945     if (!(aconn = find_aConnect(parv[1])))
  946     {
  947         sendto_one(sptr, "NOTICE %s :Connect: No Connect block found for %s.",
  948                    parv[0], parv[1]);
  949         return 0;
  950     }
  951     /*
  952      * * Get port number from user, if given. If not specified, use
  953      * the default form configuration structure. If missing from
  954      * there, then use the precompiled default.
  955      */
  956     tmpport = port = aconn->port;
  957     if (parc > 2 && !BadPtr(parv[2])) 
  958     {
  959         if ((port = atoi(parv[2])) <= 0) 
  960         {
  961             sendto_one(sptr,
  962                        "NOTICE %s :Connect: Illegal port number",
  963                        parv[0]);
  964             return 0;
  965         }
  966     }
  967     else if (port <= 0 && (port = PORTNUM) <= 0) 
  968     {
  969         sendto_one(sptr, ":%s NOTICE %s :Connect: missing port number",
  970                    me.name, parv[0]);
  971         return 0;
  972     }
  973     /*
  974      * * Notify all operators about remote connect requests
  975      * Let's notify about local connects, too. - lucas
  976      * sendto_ops_butone -> sendto_serv_butone(), like in df. -mjs
  977      */
  978     sendto_gnotice("from %s: %s CONNECT %s %s from %s",
  979                    me.name,  IsAnOper(cptr) ? "Local" : "Remote", 
  980                    parv[1], parv[2] ? parv[2] : "",
  981                    sptr->name);
  982     sendto_serv_butone(NULL, ":%s GNOTICE :%s CONNECT %s %s from %s", 
  983                        me.name, IsAnOper(cptr) ? "Local" : "Remote",
  984                        parv[1], parv[2] ? parv[2] : "",
  985                        sptr->name);
  986 
  987 #if defined(USE_SYSLOG) && defined(SYSLOG_CONNECT)
  988     syslog(LOG_DEBUG, "CONNECT From %s : %s %s", parv[0], parv[1], 
  989            parv[2] ? parv[2] : "");
  990 #endif
  991     
  992     aconn->port = port;
  993     switch (retval = connect_server(aconn, sptr, NULL))
  994     {
  995         case 0:
  996             sendto_one(sptr, ":%s NOTICE %s :*** Connecting to %s.",
  997                        me.name, parv[0], aconn->name);
  998             break;
  999         case -1:
 1000             sendto_one(sptr, ":%s NOTICE %s :*** Couldn't connect to %s.",
 1001                        me.name, parv[0], aconn->name);
 1002             break;
 1003         case -2:
 1004             sendto_one(sptr, ":%s NOTICE %s :*** Host %s is unknown.",
 1005                        me.name, parv[0], aconn->name);
 1006             break;
 1007         default:
 1008             sendto_one(sptr, ":%s NOTICE %s :*** Connection to %s failed: %s",
 1009                        me.name, parv[0], aconn->name, strerror(retval));
 1010     }
 1011     aconn->port = tmpport;
 1012     return 0;
 1013 }
 1014 
 1015 /*
 1016  * * m_wallops (write to *all* opers currently online) 
 1017  *      parv[0] = sender prefix 
 1018  *      parv[1] = message text
 1019  */
 1020 int 
 1021 m_wallops(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1022 {
 1023     char       *message = parc > 1 ? parv[1] : NULL;
 1024     
 1025     if (BadPtr(message)) 
 1026     {
 1027         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
 1028                    me.name, parv[0], "WALLOPS");
 1029         return 0;
 1030     }
 1031     
 1032     if (!IsServer(sptr) && MyConnect(sptr) && !OPCanWallOps(sptr)) 
 1033     {
 1034         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1035         return (0);
 1036     }
 1037     
 1038     sendto_wallops_butone(IsServer(cptr) ? cptr : NULL, sptr,
 1039                           ":%s WALLOPS :%s", parv[0], message);
 1040     return 0;
 1041 }
 1042 
 1043 /*
 1044  * * m_locops (write to *all* local opers currently online) 
 1045  *      parv[0] = sender prefix 
 1046  *      parv[1] = message text
 1047  */
 1048 int 
 1049 m_locops(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1050 {
 1051     char       *message = parc > 1 ? parv[1] : NULL;
 1052 
 1053     if (BadPtr(message)) 
 1054     {
 1055         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
 1056                    me.name, parv[0], "LOCOPS");
 1057         return 0;
 1058     }
 1059 
 1060     if (!IsServer(sptr) && MyConnect(sptr) && !OPCanLocOps(sptr)) 
 1061     {
 1062         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1063         return (0);
 1064     }
 1065     sendto_locops("from %s: %s", parv[0], message);
 1066     return (0);
 1067 }
 1068 
 1069 /*
 1070  * m_goper  (Russell) sort of like wallop, but only to ALL +o clients
 1071  * on every server. 
 1072  *      parv[0] = sender prefix 
 1073  *      parv[1] = message text 
 1074  * Taken from df465, ported to hybrid. -mjs
 1075  */
 1076 int 
 1077 m_goper(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1078 {
 1079     char       *message = parc > 1 ? parv[1] : NULL;
 1080 
 1081     if (BadPtr(message)) 
 1082     {
 1083         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
 1084                    me.name, parv[0], "GOPER");
 1085         return 0;
 1086     }
 1087     if (!IsServer(sptr) || !IsULine(sptr)) 
 1088     {
 1089         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1090         return 0;
 1091     }
 1092 
 1093     sendto_serv_butone_super(cptr, 0, ":%s GOPER :%s", parv[0], message);
 1094     sendto_ops("from %s: %s", parv[0], message);
 1095     return 0;
 1096 }
 1097 
 1098 /*
 1099  * m_gnotice  (Russell) sort of like wallop, but only to +g clients on *
 1100  * this server. 
 1101  *      parv[0] = sender prefix 
 1102  *      parv[1] = message text 
 1103  * ported from df465 to hybrid -mjs
 1104  *
 1105  * This function itself doesnt need any changes for the move to +n routing
 1106  * notices, to sendto takes care of it.  Now only sends to +n clients -epi
 1107  */
 1108 int 
 1109 m_gnotice(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1110 {
 1111 
 1112     char       *message = parc > 1 ? parv[1] : NULL;
 1113     
 1114     if (BadPtr(message)) 
 1115     {
 1116         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
 1117                    me.name, parv[0], "GNOTICE");
 1118         return 0;
 1119     }
 1120     if (!IsServer(sptr) && MyConnect(sptr)) 
 1121     {
 1122         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1123         return 0;
 1124     }
 1125 
 1126     sendto_serv_butone_super(cptr, 0, ":%s GNOTICE :%s", parv[0], message);
 1127     sendto_gnotice("from %s: %s", parv[0], message);
 1128     return 0;
 1129 }
 1130 
 1131 int 
 1132 m_globops(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1133 {
 1134     char       *message = parc > 1 ? parv[1] : NULL;
 1135 
 1136     /* a few changes, servers weren't able to globop -mjs */
 1137 
 1138     if (BadPtr(message)) 
 1139     {
 1140         if (MyClient(sptr))
 1141             sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
 1142                        me.name, parv[0], "GLOBOPS");
 1143         return 0;
 1144     }
 1145 
 1146     if (MyClient(sptr) && !OPCanGlobOps(sptr)) 
 1147     {
 1148         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1149         return 0;
 1150     }
 1151     if (strlen(message) > TOPICLEN)
 1152         message[TOPICLEN] = '\0';
 1153     sendto_serv_butone_super(cptr, ULF_NOGLOBOPS, ":%s GLOBOPS :%s", parv[0], message);
 1154     send_globops("from %s: %s", parv[0], message);
 1155     return 0;
 1156 }
 1157 
 1158 int 
 1159 m_chatops(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1160 {
 1161     char       *message = parc > 1 ? parv[1] : NULL;
 1162 
 1163     if (BadPtr(message)) 
 1164     {
 1165         if (MyClient(sptr))
 1166             sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
 1167                        me.name, parv[0], "CHATOPS");
 1168         return 0;
 1169     }
 1170 
 1171     if (MyClient(sptr) && (!IsAnOper(sptr) || !SendChatops(sptr))) 
 1172     {
 1173         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1174         return 0;
 1175     }
 1176     
 1177     if (strlen(message) > TOPICLEN)
 1178         message[TOPICLEN] = '\0';
 1179     sendto_serv_butone_super(cptr, 0, ":%s CHATOPS :%s", parv[0], message);
 1180     send_chatops("from %s: %s", parv[0], message);
 1181     return 0;
 1182 }
 1183 
 1184 /*
 1185  * * m_time 
 1186  *       parv[0] = sender prefix 
 1187  *       parv[1] = servername
 1188  */
 1189 
 1190 int 
 1191 m_time(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1192 {
 1193     if (hunt_server(cptr, sptr, ":%s TIME :%s", 1, parc, parv) == HUNTED_ISME)
 1194         sendto_one(sptr, rpl_str(RPL_TIME), me.name,
 1195                    parv[0], me.name, NOW, date((long) 0));
 1196     return 0;
 1197 }
 1198 
 1199 /*
 1200  * * m_admin 
 1201  *        parv[0] = sender prefix 
 1202  *        parv[1] = servername
 1203  */
 1204 int 
 1205 m_admin(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1206 {
 1207     
 1208     if (hunt_server(cptr, sptr, ":%s ADMIN :%s", 1, parc, parv) != HUNTED_ISME)
 1209         return 0;
 1210     
 1211     if (IsPerson(sptr))
 1212         sendto_realops_lev(SPY_LEV, "ADMIN requested by %s (%s@%s) [%s]",
 1213                            sptr->name, sptr->user->username, sptr->user->host,
 1214                            sptr->user->server);
 1215     
 1216     sendto_one(sptr, rpl_str(RPL_ADMINME),
 1217                    me.name, parv[0], me.name);
 1218     sendto_one(sptr, rpl_str(RPL_ADMINLOC1),
 1219                    me.name, parv[0], MeLine->admin[0] ? MeLine->admin[0] : "");
 1220     sendto_one(sptr, rpl_str(RPL_ADMINLOC2),
 1221                    me.name, parv[0], MeLine->admin[1] ? MeLine->admin[1] : "");
 1222     sendto_one(sptr, rpl_str(RPL_ADMINEMAIL),
 1223                    me.name, parv[0], MeLine->admin[2] ? MeLine->admin[2] : "");
 1224     return 0;
 1225 }
 1226 
 1227 /* Shadowfax's server side, anti flood code */
 1228 #ifdef FLUD
 1229 extern int  flud_num;
 1230 extern int  flud_time;
 1231 extern int  flud_block;
 1232 #endif
 1233 
 1234 #ifdef ANTI_SPAMBOT
 1235 extern int  spam_num;
 1236 extern int  spam_time;
 1237 #endif
 1238 
 1239 /* m_set - set options while running */
 1240 int 
 1241 m_set(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1242 {
 1243     char       *command;
 1244 
 1245     if (!MyClient(sptr) || !IsOper(sptr)) 
 1246     {
 1247         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1248         return 0;
 1249     }
 1250 
 1251     if (parc > 1) 
 1252     {
 1253         command = parv[1];
 1254         if (!strncasecmp(command, "MAX", 3)) 
 1255         {
 1256             if (parc > 2) 
 1257             {
 1258                 int new_value = atoi(parv[2]);
 1259 
 1260                 if (new_value > MAX_ACTIVECONN) 
 1261                 {
 1262                     sendto_one(sptr,
 1263                                ":%s NOTICE %s :You cannot set MAXCLIENTS "
 1264                                "above the compiled FD limit (%d)", me.name,
 1265                                parv[0], MAX_ACTIVECONN);
 1266                     return 0;
 1267                 }
 1268                 if (new_value < 0)
 1269                     new_value = 0;
 1270                 MAXCLIENTS = new_value;
 1271                 sendto_one(sptr, ":%s NOTICE %s :NEW MAXCLIENTS = %d (Current "
 1272                            "= %d)", me.name, parv[0], MAXCLIENTS, Count.local);
 1273                 sendto_realops("%s!%s@%s set new MAXCLIENTS to %d "
 1274                                "(%d current)", parv[0], sptr->user->username,
 1275                                sptr->sockhost, MAXCLIENTS, Count.local);
 1276                 return 0;
 1277             }
 1278             sendto_one(sptr, ":%s NOTICE %s :MAXCLIENTS is %d (%d online)",
 1279                        me.name, parv[0], MAXCLIENTS, Count.local);
 1280             return 0;
 1281         }
 1282 #ifdef FLUD
 1283         else if (!strncasecmp(command, "FLUDNUM", 7)) 
 1284         {
 1285             if (parc > 2) 
 1286             {
 1287                 int newval = atoi(parv[2]);
 1288                 if (newval <= 0) 
 1289                 {
 1290                     sendto_one(sptr, ":%s NOTICE %s :flud NUM must be > 0",
 1291                                me.name, parv[0]);
 1292                     return 0;
 1293                 }
 1294                 flud_num = newval;
 1295                 sendto_ops("%s has changed flud NUM to %i", parv[0], flud_num);
 1296                 sendto_one(sptr, ":%s NOTICE %s :flud NUM is now set to %i",
 1297                            me.name, parv[0], flud_num);
 1298                 return 0;
 1299             }
 1300             else
 1301             {
 1302                 sendto_one(sptr, ":%s NOTICE %s :flud NUM is currently %i",
 1303                            me.name, parv[0], flud_num);
 1304                 return 0;
 1305             }
 1306         }
 1307         else if (!strncasecmp(command, "FLUDTIME", 8)) 
 1308         {
 1309             if (parc > 2) 
 1310             {
 1311                 int newval = atoi(parv[2]);
 1312                 if (newval <= 0) 
 1313                 {
 1314                     sendto_one(sptr, ":%s NOTICE %s :flud TIME must be > 0",
 1315                                me.name, parv[0]);
 1316                     return 0;
 1317                 }
 1318                 flud_time = newval;
 1319                 sendto_ops("%s has changed flud TIME to %i", parv[0],
 1320                            flud_time);
 1321                 sendto_one(sptr, ":%s NOTICE %s :flud TIME is now set to %i",
 1322                            me.name, parv[0], flud_time);
 1323                 return 0;
 1324             }
 1325             else 
 1326             {
 1327                 sendto_one(sptr, ":%s NOTICE %s :flud TIME is currently %i",
 1328                            me.name, parv[0], flud_time);
 1329                 return 0;
 1330             }
 1331         }
 1332         else if (!strncasecmp(command, "FLUDBLOCK", 9)) 
 1333         {
 1334             if (parc > 2) 
 1335             {
 1336                 int newval = atoi(parv[2]);
 1337                 if (newval < 0) 
 1338                 {
 1339                     sendto_one(sptr, ":%s NOTICE %s :flud BLOCK must be >= 0",
 1340                                me.name, parv[0]);
 1341                     return 0;
 1342                 }
 1343                 flud_block = newval;
 1344                 if (flud_block == 0)
 1345                 {
 1346                     sendto_ops("%s has disabled flud detection/protection",
 1347                                parv[0]);
 1348                     sendto_one(sptr, ":%s NOTICE %s :flud detection disabled",
 1349                                me.name, parv[0]);
 1350                 }
 1351                 else
 1352                 {
 1353                     sendto_ops("%s has changed flud BLOCK to %i",
 1354                                parv[0], flud_block);
 1355                     sendto_one(sptr, ":%s NOTICE %s :flud BLOCK is now set "
 1356                                "to %i", me.name, parv[0], flud_block);
 1357                 }
 1358                 return 0;
 1359             }
 1360             else
 1361             {
 1362                 sendto_one(sptr, ":%s NOTICE %s :flud BLOCK is currently %i",
 1363                            me.name, parv[0], flud_block);
 1364                 return 0;
 1365             }
 1366         }
 1367 #endif
 1368 #ifdef ANTI_SPAMBOT
 1369         /* int spam_time = MIN_JOIN_LEAVE_TIME; 
 1370          * int spam_num = MAX_JOIN_LEAVE_COUNT;
 1371          */
 1372         else if (!strncasecmp(command, "SPAMNUM", 7)) 
 1373         {
 1374             if (parc > 2) 
 1375             {
 1376                 int newval = atoi(parv[2]);
 1377                 if (newval <= 0) 
 1378                 {
 1379                     sendto_one(sptr, ":%s NOTICE %s :spam NUM must be > 0",
 1380                                me.name, parv[0]);
 1381                     return 0;
 1382                 }
 1383                 if (newval < MIN_SPAM_NUM)
 1384                     spam_num = MIN_SPAM_NUM;
 1385                 else
 1386                     spam_num = newval;
 1387                 sendto_ops("%s has changed spam NUM to %i", parv[0], spam_num);
 1388                 sendto_one(sptr, ":%s NOTICE %s :spam NUM is now set to %i",
 1389                            me.name, parv[0], spam_num);
 1390                 return 0;
 1391             }
 1392             else 
 1393             {
 1394                 sendto_one(sptr, ":%s NOTICE %s :spam NUM is currently %i",
 1395                            me.name, parv[0], spam_num);
 1396                 return 0;
 1397             }
 1398         }
 1399         else if (!strncasecmp(command, "SPAMTIME", 8)) 
 1400         {
 1401             if (parc > 2) 
 1402             {
 1403                 int newval = atoi(parv[2]);
 1404                 if (newval <= 0) 
 1405                 {
 1406                     sendto_one(sptr, ":%s NOTICE %s :spam TIME must be > 0",
 1407                                me.name, parv[0]);
 1408                     return 0;
 1409                 }
 1410                 if (newval < MIN_SPAM_TIME)
 1411                     spam_time = MIN_SPAM_TIME;
 1412                 else
 1413                     spam_time = newval;
 1414                 sendto_ops("%s has changed spam TIME to %i", parv[0],
 1415                            spam_time);
 1416                 sendto_one(sptr, ":%s NOTICE %s :SPAM TIME is now set to %i",
 1417                            me.name, parv[0], spam_time);
 1418                 return 0;
 1419             }
 1420             else 
 1421             {
 1422                 sendto_one(sptr, ":%s NOTICE %s :spam TIME is currently %i",
 1423                            me.name, parv[0], spam_time);
 1424                 return 0;
 1425             }
 1426         }
 1427 
 1428 #endif
 1429 #ifdef THROTTLE_ENABLE
 1430         else if (!strncasecmp(command, "THROTTLE", 8))  
 1431         {
 1432            char *changed = NULL;
 1433            char *to = NULL;
 1434            /* several values available:
 1435             * ENABLE [on|off] to enable the code
 1436             * COUNT [n] to set a max count, must be > 1
 1437             * TIME [n] to set a max time before expiry, must be > 5
 1438             * RECORDTIME [n] to set a time for the throttle records to expire
 1439             * HASH [n] to set the size of the hash table, must be bigger than
 1440             *          the default */
 1441 
 1442 
 1443            /* only handle individual settings if parc > 3 (they're actually
 1444             * changing stuff) */
 1445            if (parc > 3) {
 1446                if (!strcasecmp(parv[2], "ENABLE"))  {
 1447                   changed = "ENABLE";
 1448                   if (ToLower(*parv[3]) == 'y' || !strcasecmp(parv[3], "on")) {
 1449                      throttle_enable = 1;
 1450                      to = "ON";
 1451                   } else if (ToLower(*parv[3]) == 'n' ||
 1452                            !strcasecmp(parv[3], "off")) {
 1453                      throttle_enable = 0;
 1454                      to = "OFF";
 1455                   }
 1456                } else if (!strcasecmp(parv[2], "COUNT")) {
 1457                   int cnt;
 1458                   changed = "COUNT";
 1459                   cnt = atoi(parv[3]);
 1460                   if (cnt > 1) {
 1461                      throttle_tcount = cnt;
 1462                      to = parv[3];
 1463                   }
 1464                } else if (!strcasecmp(parv[2], "TIME")) {
 1465                   int cnt;
 1466                   changed = "TIME";
 1467                   cnt = atoi(parv[3]);
 1468                   if (cnt >= 5) {
 1469                      throttle_ttime = cnt;
 1470                      to = parv[3];
 1471                   } 
 1472                } else if (!strcasecmp(parv[2], "RECORDTIME")) {
 1473                   int cnt;
 1474                   changed = "RECORDTIME";
 1475                   cnt = atoi(parv[3]);
 1476                   if (cnt >= 30) {
 1477                      throttle_rtime = cnt;
 1478                      to = parv[3];
 1479                   }
 1480                } else if (!strcasecmp(parv[2], "HASH")) {
 1481                   int cnt;
 1482                   changed = "HASH";
 1483                   cnt = atoi(parv[3]);
 1484                   if (cnt >= THROTTLE_HASHSIZE) {
 1485                      throttle_resize(cnt);
 1486                      to = parv[3];
 1487                   }
 1488                }
 1489 
 1490                if (to != NULL) {
 1491                   sendto_ops("%s has changed throttle %s to %s", parv[0],
 1492                         changed, to);
 1493                   sendto_one(sptr, ":%s NOTICE %s :set throttle %s to %s",
 1494                         me.name, parv[0], changed, to);
 1495                }
 1496            } else {
 1497               /* report various things, we cannot easily get the hash size, so
 1498                * leave that alone. */
 1499               sendto_one(sptr, ":%s NOTICE %s :THROTTLE %s", me.name, parv[0],
 1500                     throttle_enable ? "enabled" : "disabled");
 1501               sendto_one(sptr, ":%s NOTICE %s :THROTTLE COUNT=%d", me.name,
 1502                     parv[0], throttle_tcount);
 1503               sendto_one(sptr, ":%s NOTICE %s :THROTTLE TIME=%d sec", me.name,
 1504                     parv[0], throttle_ttime);
 1505               sendto_one(sptr, ":%s NOTICE %s :THROTTLE RECORDTIME=%d sec", me.name,
 1506                     parv[0], throttle_rtime);
 1507            }
 1508         }
 1509         else if (!strncasecmp(command, "LCLONES", 3))
 1510         {
 1511             if (parc > 3)
 1512             {
 1513                 int limit, rval;
 1514 
 1515                 limit = atoi(parv[3]);
 1516                 rval = clones_set(parv[2], CLIM_SOFT_LOCAL, limit);
 1517 
 1518                 if (rval < 0)
 1519                     sendto_one(sptr, ":%s NOTICE %s :Invalid IP or limit.",
 1520                                me.name, parv[0]);
 1521                 else if (rval > 0 && limit == 0)
 1522                 {
 1523                     sendto_ops("%s removed soft local clone limit for %s",
 1524                                parv[0], parv[2]);
 1525                     sendto_one(sptr, ":%s NOTICE %s :removed soft local clone"
 1526                                " limit for %s", me.name, parv[0], parv[2]);
 1527                 }
 1528                 else if (rval > 0)
 1529                 {
 1530                     sendto_ops("%s changed soft local clone limit for %s from"
 1531                                " %d to %d", parv[0], parv[2], rval, limit);
 1532                     sendto_one(sptr, ":%s NOTICE %s :changed soft local clone"
 1533                                " limit for %s from %d to %d", me.name, parv[0],
 1534                                parv[2], rval, limit);
 1535                 }
 1536                 else if (limit == 0)
 1537                 {
 1538                     sendto_one(sptr, ":%s NOTICE %s :no soft local clone limit"
 1539                                " for %s", me.name, parv[0], parv[2]);
 1540                 }
 1541                 else
 1542                 {
 1543                     sendto_ops("%s set soft local clone limit for %s to %d",
 1544                                parv[0], parv[2], limit);
 1545                     sendto_one(sptr, ":%s NOTICE %s :set soft local clone"
 1546                                " limit for %s to %d", me.name, parv[0],
 1547                                parv[2], limit);
 1548                 }
 1549             }
 1550             else if (parc > 2)
 1551             {
 1552                 int hglimit, sglimit, sllimit;
 1553 
 1554                 clones_get(parv[2], &hglimit, &sglimit, &sllimit);
 1555 
 1556                 if (!sllimit)
 1557                     sendto_one(sptr, ":%s NOTICE %s :no soft local clone limit"
 1558                                " for %s", me.name, parv[0], parv[2]);
 1559                 else
 1560                     sendto_one(sptr, ":%s NOTICE %s :soft local clone limit"
 1561                                " for %s is %d", me.name, parv[0], parv[2],
 1562                                sllimit);
 1563             }
 1564             else
 1565                 sendto_one(sptr, ":%s NOTICE %s :Usage: LCLONES <ip> [<limit>]",
 1566                            me.name, parv[0]);
 1567         }
 1568         else if (!strncasecmp(command, "GCLONES", 3))
 1569         {
 1570             int hglimit, sglimit, sllimit, limit, rval;
 1571 
 1572             if (parc > 3)
 1573             {
 1574                 limit = atoi(parv[3]);
 1575                 clones_get(parv[2], &hglimit, &sglimit, &sllimit);
 1576 
 1577                 if (hglimit && limit > hglimit)
 1578                     sendto_one(sptr, ":%s NOTICE %s :Cannot set soft global"
 1579                                " clone limit for %s above services-set hard"
 1580                                " limit (%d)", me.name, parv[0], parv[2],
 1581                                hglimit);
 1582                 else
 1583                 {
 1584                     rval = clones_set(parv[2], CLIM_SOFT_GLOBAL, limit);
 1585 
 1586                     if (rval < 0)
 1587                         sendto_one(sptr, ":%s NOTICE %s :Invalid IP or limit.",
 1588                                    me.name, parv[0]);
 1589                     else if (rval > 0 && limit == 0)
 1590                     {
 1591                         sendto_ops("%s removed soft global clone limit for %s",
 1592                                    parv[0], parv[2]);
 1593                         sendto_one(sptr, ":%s NOTICE %s :removed soft global"
 1594                                    " clone limit for %s", me.name, parv[0],
 1595                                    parv[2]);
 1596                     }
 1597                     else if (rval > 0)
 1598                     {
 1599                         sendto_ops("%s changed soft global clone limit for %s"
 1600                                    " from %d to %d", parv[0], parv[2], rval,
 1601                                    limit);
 1602                         sendto_one(sptr, ":%s NOTICE %s :changed soft global"
 1603                                    " clone limit for %s from %d to %d",
 1604                                    me.name, parv[0], parv[2], rval, limit);
 1605                     }
 1606                     else if (limit == 0)
 1607                     {
 1608                         sendto_one(sptr, ":%s NOTICE %s :no soft global clone"
 1609                                    " limit for %s", me.name, parv[0], parv[2]);
 1610                     }
 1611                     else
 1612                     {
 1613                         sendto_ops("%s set soft global clone limit for %s to"
 1614                                    " %d", parv[0], parv[2], limit);
 1615                         sendto_one(sptr, ":%s NOTICE %s :set soft global clone"
 1616                                    " limit for %s to %d", me.name, parv[0],
 1617                                    parv[2], limit);
 1618                     }
 1619                 }
 1620             }
 1621             else if (parc > 2)
 1622             {
 1623                 clones_get(parv[2], &hglimit, &sglimit, &sllimit);
 1624 
 1625                 if (sglimit)
 1626                     sendto_one(sptr, ":%s NOTICE %s :soft global clone limit"
 1627                                " for %s is %d", me.name, parv[0], parv[2],
 1628                                sglimit);
 1629                 else
 1630                     sendto_one(sptr, ":%s NOTICE %s :no soft global clone"
 1631                                " limit for %s", me.name, parv[0], parv[2]);
 1632 
 1633                 if (hglimit)
 1634                     sendto_one(sptr, ":%s NOTICE %s :hard global clone limit"
 1635                                " for %s is %d", me.name, parv[0], parv[2],
 1636                                hglimit);
 1637             }
 1638             else
 1639                 sendto_one(sptr, ":%s NOTICE %s :Usage: GCLONES <ip> [<limit>]",
 1640                            me.name, parv[0]);
 1641         }
 1642         else if (!strncasecmp(command, "DEFLCLONE", 6))
 1643         {
 1644             char *eptr;
 1645 
 1646             if (parc > 2)
 1647             {
 1648                 local_ip_limit = strtol(parv[2], &eptr, 10);
 1649                 if (*eptr != 0)
 1650                     local_ip24_limit = atoi(eptr+1);
 1651 
 1652                 if (local_ip_limit < 1)
 1653                     local_ip_limit = DEFAULT_LOCAL_IP_CLONES;
 1654                 if (local_ip24_limit < 1)
 1655                     local_ip24_limit = DEFAULT_LOCAL_IP24_CLONES;
 1656 
 1657                 sendto_ops("%s set default local clone limit to %d:%d"
 1658                            " (host:site)", parv[0], local_ip_limit,
 1659                            local_ip24_limit);
 1660                 sendto_one(sptr, ":%s NOTICE %s :set default local clone limit"
 1661                            " to %d:%d (host:site)", me.name, parv[0],
 1662                            local_ip_limit, local_ip24_limit);
 1663             }
 1664             else
 1665                 sendto_one(sptr, ":%s NOTICE %s :default local clone limit is"
 1666                            " %d:%d (host:site)", me.name, parv[0],
 1667                            local_ip_limit, local_ip24_limit);
 1668         }
 1669         else if (!strncasecmp(command, "DEFGCLONE", 6))
 1670         {
 1671             char *eptr;
 1672 
 1673             if (parc > 2)
 1674             {
 1675                 global_ip_limit = strtol(parv[2], &eptr, 10);
 1676                 if (*eptr != 0)
 1677                     global_ip24_limit = atoi(eptr+1);
 1678 
 1679                 if (global_ip_limit < 1)
 1680                     global_ip_limit = DEFAULT_GLOBAL_IP_CLONES;
 1681                 if (global_ip24_limit < 1)
 1682                     global_ip24_limit = DEFAULT_GLOBAL_IP24_CLONES;
 1683 
 1684                 sendto_ops("%s set default global clone limit to %d:%d"
 1685                            " (host:site)", parv[0], global_ip_limit,
 1686                            global_ip24_limit);
 1687                 sendto_one(sptr, ":%s NOTICE %s :set default global clone"
 1688                            " limit to %d:%d (host:site)", me.name, parv[0],
 1689                            global_ip_limit, global_ip24_limit);
 1690             }
 1691             else
 1692                 sendto_one(sptr, ":%s NOTICE %s :default global clone limit is"
 1693                            " %d:%d (host:site)", me.name, parv[0],
 1694                            global_ip_limit, global_ip24_limit);
 1695         }
 1696 #endif
 1697     }
 1698     else 
 1699     {
 1700         sendto_one(sptr, ":%s NOTICE %s :Options: MAX",
 1701                    me.name, parv[0]);
 1702 #ifdef FLUD
 1703         sendto_one(sptr, ":%s NOTICE %s :Options: FLUDNUM, FLUDTIME, "
 1704                    "FLUDBLOCK", me.name, parv[0]);
 1705 #endif
 1706 
 1707 #ifdef ANTI_SPAMBOT
 1708         sendto_one(sptr, ":%s NOTICE %s :Options: SPAMNUM, SPAMTIME",
 1709                    me.name, parv[0]);
 1710 #endif
 1711 
 1712 #ifdef THROTTLE_ENABLE
 1713         sendto_one(sptr, ":%s NOTICE %s :Options: THROTTLE "
 1714               "<ENABLE|COUNT|TIME|RECORDTIME|HASH> [setting]", me.name, parv[0]);
 1715         sendto_one(sptr, ":%s NOTICE %s :Options: LCLONES, GCLONES, "
 1716                    "DEFLCLONES, DEFGCLONES", me.name, parv[0]);
 1717 #endif
 1718     }
 1719     return 0;
 1720 }
 1721 
 1722 /* local_rehash
 1723  * Takes over m_rehash() once the targeted server is reached,
 1724  * whether local or remote rehash is being performed.
 1725  * - Holbrook
 1726  */
 1727 int
 1728 local_rehash(aClient *cptr, aClient *sptr, char *sender, char *option)
 1729 {
 1730     if (mycmp(option, "DNS") == 0)
 1731     {
 1732         flush_cache();          /* Flush the DNS cache */
 1733         res_init();         /* Re-Read /etc/resolv.conf file */
 1734         sendto_one(sptr, ":%s NOTICE %s :Rehashing DNS", me.name, sender);
 1735         sendto_ops("%s is rehashing DNS while whistling innocently", sender);
 1736         return 0;
 1737     }
 1738     else if (mycmp(option, "TKLINES") == 0)
 1739     {
 1740         remove_userbans_match_flags(UBAN_LOCAL|UBAN_TEMPORARY, 0);
 1741         sendto_one(sptr, ":%s NOTICE %s :Clearing temp klines", me.name, sender);
 1742         sendto_ops("%s is clearing temp klines while whistling innocently", sender);
 1743         return 0;
 1744     }
 1745     else if (mycmp(option, "GC") == 0)
 1746     {
 1747         block_garbage_collect();
 1748         sendto_one(sptr, ":%s NOTICE %s :Garbage collecting", me.name, sender);
 1749         sendto_ops("%s is garbage collecting while whistling innocently", sender);
 1750         return 0;
 1751     }
 1752     else if (mycmp(option, "MOTD") == 0)
 1753     {
 1754         read_motd(MOTD);
 1755 
 1756         if (confopts & FLAGS_SMOTD)
 1757             read_shortmotd(SHORTMOTD);
 1758 
 1759         sendto_one(sptr, ":%s NOTICE %s :Re-reading MOTD file", me.name, sender);
 1760         sendto_ops("%s is forcing re-reading of MOTD file", sender);
 1761         return 0;
 1762     }
 1763     else if (mycmp(option, "AKILLS") == 0)
 1764     {
 1765         remove_userbans_match_flags(UBAN_NETWORK, 0);
 1766         sendto_one(sptr, ":%s NOTICE %s :Rehashing akills", me.name, sender);
 1767         sendto_ops("%s is rehashing akills", sender);
 1768         return 0;
 1769     }
 1770     else if (mycmp(option, "THROTTLES") == 0)
 1771     {
 1772         throttle_rehash();
 1773         sendto_one(sptr, ":%s NOTICE %s :Rehashing throttles", me.name, sender);
 1774         sendto_ops("%s is rehashing throttles", sender);
 1775         return 0;
 1776     }
 1777     else if (mycmp(option, "SQLINES") == 0)
 1778     {
 1779         remove_simbans_match_flags(SBAN_NICK|SBAN_NETWORK, 0);
 1780         remove_simbans_match_flags(SBAN_CHAN|SBAN_NETWORK, 0);
 1781         sendto_one(sptr, ":%s NOTICE %s :Rehashing sqlines", me.name, sender);
 1782         sendto_ops("%s is rehashing sqlines", sender);
 1783         return 0;
 1784     }
 1785     else if (mycmp(option, "SGLINES") == 0)
 1786     {
 1787         remove_simbans_match_flags(SBAN_GCOS|SBAN_NETWORK, 0);
 1788         sendto_one(sptr, ":%s NOTICE %s :Rehashing sqlines", me.name, sender);
 1789         sendto_ops("%s is rehashing sglines", sender);
 1790         return 0;
 1791     }
 1792     else if (mycmp(option, "TSQGLINES") == 0)
 1793     {
 1794         remove_simbans_match_flags(SBAN_GCOS|SBAN_TEMPORARY, 0);
 1795         remove_simbans_match_flags(SBAN_NICK|SBAN_TEMPORARY, 0);
 1796         remove_simbans_match_flags(SBAN_CHAN|SBAN_TEMPORARY, 0);
 1797         sendto_one(sptr, ":%s NOTICE %s :Rehashing temporary sqlines/sglines", me.name, sender);
 1798         sendto_ops("%s is rehashing temporary sqlines/sglines", sender);
 1799         return 0;
 1800     }
 1801 #ifdef USE_SSL
 1802     else if (mycmp(option, "SSL") == 0)
 1803     {
 1804         ssl_rehash();
 1805         sendto_one(sptr, ":%s NOTICE %s :Rehashing SSL", me.name, sender);
 1806         sendto_ops("%s is rehashing SSL", sender);
 1807         return 0;
 1808     }
 1809 #endif
 1810     else if (mycmp(option, "CONF") == 0)
 1811     {
 1812         if (!MyClient(sptr))
 1813             sendto_one(sptr, ":%s NOTICE %s :Rehashing server config file", me.name, sender);
 1814         else
 1815             sendto_one(sptr, rpl_str(RPL_REHASHING), me.name, sender, configfile);
 1816 
 1817         sendto_ops("%s is rehashing Server config file while whistling innocently", sender);
 1818 
 1819 #ifdef USE_SYSLOG
 1820         syslog(LOG_INFO, "REHASH from %s\n", get_client_name(sptr, FALSE));
 1821 #endif
 1822 
 1823         return rehash(cptr, sptr, 0);
 1824     }
 1825     else
 1826     {
 1827         sendto_one(sptr, ":%s NOTICE %s :Invalid rehash option (%s) given. Rehash aborted.", me.name, sender, option);
 1828         return -1;
 1829     }
 1830 
 1831     return 0;       /* Shouldn't ever get here either! */
 1832 }
 1833 
 1834 /* m_rehash
 1835  * parv[0] = sender prefix
 1836  * parv[1] = server name or rehash option if no parv[2]
 1837  * parv[2] = rehash option
 1838  *
 1839  * Changed m_rehash to handle determination of local vs remote rehash.
 1840  * local_rehash() takes over the old m_rehash().
 1841  * - Holbrook
 1842  */
 1843 int
 1844 m_rehash(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1845 {
 1846     char *option = "CONF";
 1847 
 1848     if (MyClient(sptr))
 1849     {
 1850         if (!OPCanRehash(sptr))
 1851         {
 1852             sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1853             return -1;
 1854         }
 1855 
 1856         if (parc > 3)
 1857         {
 1858             sendto_one(sptr, ":%s NOTICE %s :Too many parameters given. Rehash aborted.", me.name, parv[0]);
 1859             return -1;
 1860         }
 1861 
 1862         else if (parc > 2)
 1863         {
 1864             if (hunt_server(cptr, sptr, ":%s REHASH %s :%s", 1, parc, parv) != HUNTED_ISME)
 1865                 return 0;
 1866             else
 1867                 option = parv[2];
 1868         }
 1869 
 1870         else if (parc > 1)
 1871         {
 1872             if (strchr(parv[1], '.'))
 1873             {
 1874                 if (hunt_server(cptr, sptr, ":%s REHASH %s :CONF", 1, parc, parv) != HUNTED_ISME)
 1875                     return 0;
 1876             }
 1877             else
 1878                 option = parv[1];
 1879         }
 1880 
 1881         local_rehash(cptr, sptr, parv[0], option);
 1882         return 0;
 1883     }
 1884     else
 1885     {
 1886         if (!IsPrivileged(sptr))
 1887         {
 1888             sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1889             return -1;
 1890         }
 1891 
 1892         if (hunt_server(cptr, sptr, ":%s REHASH %s %s", 1, parc, parv) != HUNTED_ISME)
 1893             return 0;
 1894 
 1895         if (!(confopts & FLAGS_REMREHOK))
 1896         {
 1897             sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1898             return -1;
 1899         }
 1900 
 1901         local_rehash(cptr, sptr, parv[0], parv[2]);
 1902     }
 1903 
 1904     return 0;       /* Should never reach here. */
 1905 }
 1906 
 1907 /* m_restart */
 1908 int 
 1909 m_restart(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1910 {
 1911     char       *pass = NULL;
 1912     
 1913     if (!OPCanRestart(sptr))
 1914     {
 1915         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1916         return 0;
 1917     }
 1918     /*
 1919      * m_restart is now password protected as in df465 only change --
 1920      * this one doesn't allow a reason to be specified. future changes:
 1921      * crypt()ing of password, reason to be re-added -mjs
 1922      */
 1923     if ((pass = MeLine->restartpass)) 
 1924     {
 1925         if (parc < 2) 
 1926         {
 1927             sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0],
 1928                        "RESTART");
 1929             return 0;
 1930         }
 1931         if (strcmp(pass, parv[1])) 
 1932         {
 1933             sendto_one(sptr, err_str(ERR_PASSWDMISMATCH), me.name, parv[0]);
 1934             return 0;
 1935         }
 1936     }
 1937     
 1938 #ifdef USE_SYSLOG
 1939     syslog(LOG_WARNING, "Server RESTART by %s\n",
 1940            get_client_name(sptr, FALSE));
 1941 #endif
 1942     sprintf(buf, "Server RESTART by %s", get_client_name(sptr, FALSE));
 1943     restart(buf);
 1944     return 0;                   /* NOT REACHED */
 1945 }
 1946 
 1947 /*
 1948  * * m_trace 
 1949  *        parv[0] = sender prefix 
 1950  *        parv[1] = servername
 1951  */
 1952 int 
 1953 m_trace(aClient *cptr, aClient *sptr, int parc, char *parv[])
 1954 {
 1955     int      i;
 1956     aClient *acptr=NULL;
 1957     aClass      *cltmp;
 1958     char        *tname;
 1959     int          doall, link_s[MAXCONNECTIONS], link_u[MAXCONNECTIONS];
 1960     int          wilds = 0, dow = 0;
 1961         
 1962     tname = (parc > 1) ? parv[1] : me.name;
 1963 
 1964 #ifdef NO_USER_TRACE
 1965     if(!IsAnOper(sptr))
 1966     {
 1967         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1968         return 0;
 1969     }
 1970 #endif
 1971 
 1972 #ifdef HIDEULINEDSERVS
 1973     if((acptr = next_client_double(client, tname)))
 1974     {
 1975         if (!(IsAnOper(sptr)) && IsULine(acptr))
 1976         {
 1977             sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 1978             return 0;
 1979         }
 1980         acptr = NULL; /* shrug, we borrowed it, reset it just in case */
 1981     }
 1982 #endif
 1983     
 1984     if (parc > 2)
 1985         if (hunt_server(cptr, sptr, ":%s TRACE %s :%s", 2, parc, parv))
 1986             return 0;
 1987 
 1988     switch (hunt_server(cptr, sptr, ":%s TRACE :%s", 1, parc, parv)) 
 1989     {
 1990         case HUNTED_PASS:   /*  note: gets here only if parv[1] exists */
 1991         {
 1992             aClient    *ac2ptr = next_client_double(client, tname);
 1993             if (ac2ptr)
 1994                 sendto_one(sptr, rpl_str(RPL_TRACELINK), me.name, parv[0],
 1995                            version, debugmode, tname, 
 1996                            ac2ptr->from->name);
 1997             else
 1998                 sendto_one(sptr, rpl_str(RPL_TRACELINK), me.name, parv[0],
 1999                            version, debugmode, tname, 
 2000                            "ac2ptr_is_NULL!!");
 2001             return 0;
 2002         }
 2003         case HUNTED_ISME:
 2004             break;
 2005         default:
 2006             return 0;
 2007     }
 2008     if(!IsAnOper(sptr)) 
 2009     {
 2010         if (parv[1] && !strchr(parv[1],'.') && 
 2011             (strchr(parv[1], '*') || strchr(parv[1], '?'))) 
 2012             /* bzzzt, no wildcard nicks for nonopers */
 2013         {
 2014             sendto_one(sptr, rpl_str(RPL_ENDOFTRACE),me.name,
 2015                        parv[0], parv[1]);
 2016             return 0;        
 2017         }
 2018     }
 2019     sendto_realops_lev(SPY_LEV, "TRACE requested by %s (%s@%s) [%s]",
 2020                        sptr->name, sptr->user->username, sptr->user->host,
 2021                        sptr->user->server);
 2022         
 2023     doall = (parv[1] && (parc > 1)) ? !match(tname, me.name) : TRUE;
 2024     wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
 2025     dow = wilds || doall;
 2026     if(!IsAnOper(sptr) || !dow) /* non-oper traces must be full nicks */
 2027         /* lets also do this for opers tracing nicks */
 2028     {
 2029         char      *name, *class;
 2030         acptr = hash_find_client(tname,(aClient *)NULL);
 2031         if(!acptr || !IsPerson(acptr)) 
 2032         {
 2033             /* this should only be reached if the matching
 2034                target is this server */
 2035             sendto_one(sptr, rpl_str(RPL_ENDOFTRACE),me.name,
 2036                        parv[0], tname);
 2037             return 0;
 2038                           
 2039         }
 2040         if(acptr->class)
 2041             class = acptr->class->name;
 2042         else
 2043             class = "NONE";
 2044 #ifdef USER_HOSTMASKING
 2045         if(IsUmodeH(acptr) && !IsAnOper(sptr))
 2046             name = get_client_name(acptr,HIDEME);
 2047         else
 2048 #endif
 2049             name = get_client_name(acptr,FALSE);
 2050         if (IsAnOper(acptr)) 
 2051         {
 2052             sendto_one(sptr, rpl_str(RPL_TRACEOPERATOR),
 2053                        me.name, parv[0], class, name,
 2054                        timeofday - acptr->lasttime);
 2055         }
 2056         else
 2057         {
 2058             sendto_one(sptr,rpl_str(RPL_TRACEUSER),
 2059                        me.name, parv[0], class, name,
 2060                        timeofday - acptr->lasttime);
 2061         }
 2062         sendto_one(sptr, rpl_str(RPL_ENDOFTRACE),me.name,
 2063                    parv[0], tname);
 2064         return 0;        
 2065     }
 2066 
 2067     memset((char *) link_s, '\0', sizeof(link_s));
 2068     memset((char *) link_u, '\0', sizeof(link_u));
 2069     /* Count up all the servers and clients in a downlink. */
 2070     if (doall)
 2071         for (acptr = client; acptr; acptr = acptr->next) 
 2072         {
 2073             if (IsPerson(acptr) && (!IsInvisible(acptr) || IsAnOper(sptr)))
 2074                 link_u[acptr->from->fd]++;
 2075             else if (IsServer(acptr))
 2076 #ifdef HIDEULINEDSERVS
 2077                 if (IsOper(sptr) || !IsULine(acptr))
 2078 #endif
 2079                     link_s[acptr->from->fd]++;
 2080         }
 2081                 
 2082         
 2083     /* report all direct connections */
 2084         
 2085     for (i = 0; i <= highest_fd; i++) 
 2086     {
 2087         char       *name, *class;
 2088                 
 2089         if (!(acptr = local[i]))        /* Local Connection? */
 2090             continue;
 2091 #ifdef HIDEULINEDSERVS
 2092         if (!IsOper(sptr) && IsULine(acptr))
 2093             continue;
 2094 #endif
 2095         if (IsInvisible(acptr) && dow &&
 2096             !(MyConnect(sptr) && IsAnOper(sptr)) &&
 2097             !IsAnOper(acptr) && (acptr != sptr))
 2098             continue;
 2099         if (!doall && wilds && match(tname, acptr->name))
 2100             continue;
 2101         if (!dow && mycmp(tname, acptr->name))
 2102             continue;
 2103         /* only show IPs of unknowns or clients to opers */
 2104         if (IsAnOper(sptr) && 
 2105                 (acptr->status == STAT_CLIENT || acptr->status == STAT_UNKNOWN))
 2106             name = get_client_name(acptr, FALSE);
 2107         else
 2108             name = get_client_name(acptr, HIDEME);
 2109         if(acptr->class)
 2110             class = acptr->class->name;
 2111         else
 2112             class = "NONE";
 2113                 
 2114         switch (acptr->status) 
 2115         {
 2116             case STAT_CONNECTING:
 2117                 sendto_one(sptr, rpl_str(RPL_TRACECONNECTING), me.name,
 2118                            parv[0], class, name);
 2119                 break;
 2120             case STAT_HANDSHAKE:
 2121                 sendto_one(sptr, rpl_str(RPL_TRACEHANDSHAKE), me.name,
 2122                            parv[0], class, name);
 2123                 break;
 2124             case STAT_ME:
 2125                 break;
 2126             case STAT_UNKNOWN:
 2127                 /* added time -Taner */
 2128                 sendto_one(sptr, rpl_str(RPL_TRACEUNKNOWN),
 2129                           me.name, parv[0], class, name,
 2130                           acptr->firsttime ? timeofday - acptr->firsttime : -1);
 2131                 break;
 2132             case STAT_CLIENT:
 2133                 /*
 2134                  * Only opers see users if there is a wildcard but
 2135                  * anyone can see all the opers.
 2136                  */
 2137                 if (((IsAnOper(sptr) && (MyClient(sptr))) 
 2138                         || !(dow && IsInvisible(acptr))) || !dow || 
 2139                     IsAnOper(acptr)) 
 2140                 {
 2141                     if (IsAnOper(acptr))
 2142                         sendto_one(sptr, rpl_str(RPL_TRACEOPERATOR),
 2143                                me.name, parv[0], class, name,
 2144                                timeofday - acptr->lasttime);
 2145                 }
 2146                 break;
 2147             case STAT_SERVER:
 2148                 sendto_one(sptr, rpl_str(RPL_TRACESERVER),
 2149                            me.name, parv[0], class, link_s[i],
 2150                            link_u[i], name, 
 2151                            *(acptr->serv->bynick) ? acptr->serv->bynick : "*", 
 2152                            *(acptr->serv->byuser) ? acptr->serv->byuser : "*", 
 2153                            *(acptr->serv->byhost) ? acptr->serv->byhost : 
 2154                            me.name, timeofday - acptr->lasttime);
 2155                 break;
 2156             case STAT_LOG:
 2157                 sendto_one(sptr, rpl_str(RPL_TRACELOG), me.name,
 2158                            parv[0], LOGFILE, acptr->port);
 2159                 break;
 2160             default:                /* ...we actually shouldn't come here... */
 2161                 sendto_one(sptr, rpl_str(RPL_TRACENEWTYPE), me.name,
 2162                            parv[0], name);
 2163                 break;
 2164         }
 2165     }
 2166 
 2167     /* let the user have some idea that its at the end of the trace */
 2168     sendto_one(sptr, rpl_str(RPL_TRACESERVER),
 2169                 me.name, parv[0], "NONE", link_s[me.fd],
 2170                 link_u[me.fd], me.name, "*", "*", me.name,
 2171                 acptr ? timeofday - acptr->lasttime : 0);
 2172 #ifdef HIDEULINEDSERVS
 2173     if (IsOper(sptr))
 2174 #endif
 2175         for (cltmp = classes; doall && cltmp; cltmp = cltmp->next)
 2176             if (cltmp->links > 0)
 2177                 sendto_one(sptr, rpl_str(RPL_TRACECLASS), me.name,
 2178                            parv[0], cltmp->name, cltmp->links);
 2179         
 2180     sendto_one(sptr, rpl_str(RPL_ENDOFTRACE), me.name, parv[0], tname);
 2181     return 0;
 2182 }
 2183 
 2184 /*
 2185  * * m_motd 
 2186  *       parv[0] = sender prefix 
 2187  *       parv[1] = servername
 2188  */
 2189 int 
 2190 m_motd(aClient *cptr, aClient *sptr, int parc, char *parv[])
 2191 {
 2192     static time_t last_used = 0L;
 2193     if (hunt_server(cptr, sptr, ":%s MOTD :%s", 1, parc, parv) != HUNTED_ISME)
 2194         return 0;
 2195     if(!IsAnOper(sptr)) 
 2196     {
 2197         if (IsSquelch(sptr)) 
 2198         {
 2199             sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, parv[0]);
 2200             return 0;
 2201         }
 2202         if ((last_used + MOTD_WAIT) > NOW)
 2203             return 0;
 2204         else
 2205             last_used = NOW;
 2206 
 2207     }
 2208     sendto_realops_lev(SPY_LEV, "MOTD requested by %s (%s@%s) [%s]",
 2209                        sptr->name, sptr->user->username, sptr->user->host,
 2210                        sptr->user->server);
 2211     send_motd(cptr, sptr, parc, parv);
 2212     return 0;
 2213 }
 2214 
 2215 /*
 2216 ** send_motd
 2217 **  parv[0] = sender prefix
 2218 **  parv[1] = servername
 2219 **
 2220 ** This function split off so a server notice could be generated on a
 2221 ** user requested motd, but not on each connecting client.
 2222 ** -Dianora
 2223 */
 2224 int 
 2225 send_motd(aClient *cptr, aClient *sptr, int parc, char *parv[])
 2226 {
 2227     aMotd *temp;
 2228     
 2229     if (motd == (aMotd *) NULL) 
 2230     {
 2231         sendto_one(sptr, err_str(ERR_NOMOTD), me.name, parv[0]);
 2232         return 0;
 2233     }
 2234     sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);
 2235 
 2236     sendto_one(sptr, ":%s %d %s :-%s", me.name, RPL_MOTD, parv[0], 
 2237                motd_last_changed_date);
 2238 
 2239     temp = motd;
 2240     while (temp) 
 2241     {
 2242         sendto_one(sptr, rpl_str(RPL_MOTD),  me.name, parv[0], temp->line);
 2243         temp = temp->next;
 2244     }
 2245     sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, parv[0]);
 2246     return 0;
 2247 }
 2248 
 2249 /*
 2250  * read_motd() - From CoMSTuD, added Aug 29, 1996
 2251  */
 2252 void 
 2253 read_motd(char *filename)
 2254 {
 2255     aMotd *temp, *last;
 2256     struct tm *motd_tm;
 2257     struct stat sb;
 2258     char        buffer[MOTDLINELEN], *tmp;
 2259     int         fd;
 2260 
 2261     /* Clear out the old MOTD */
 2262 
 2263     while (motd) 
 2264     {
 2265         temp = motd->next;
 2266         MyFree(motd);
 2267         motd = temp;
 2268     }
 2269     fd = open(filename, O_RDONLY);
 2270     if (fd == -1)
 2271     {
 2272         if(!forked)
 2273                 printf("WARNING:  MOTD file %s could not be found.  "
 2274                        "Skipping MOTD load.\n", filename);
 2275         return;
 2276     }
 2277     fstat(fd, &sb);
 2278     motd_tm = localtime(&sb.st_mtime);
 2279     last = (aMotd *) NULL;
 2280 
 2281     while (dgets(fd, buffer, MOTDLINELEN - 1) > 0) 
 2282     {
 2283         if ((tmp = (char *) strchr(buffer, '\n')))
 2284             *tmp = '\0';
 2285         if ((tmp = (char *) strchr(buffer, '\r')))
 2286             *tmp = '\0';
 2287         temp = (aMotd *) MyMalloc(sizeof(aMotd));
 2288 
 2289         strncpyzt(temp->line, buffer, MOTDLINELEN);
 2290         temp->next = (aMotd *) NULL;
 2291         if (!motd)
 2292             motd = temp;
 2293         else
 2294             last->next = temp;
 2295         last = temp;
 2296     }
 2297     close(fd);
 2298 
 2299     sprintf(motd_last_changed_date, "%d/%d/%d %d:%02d", motd_tm->tm_mday,
 2300             motd_tm->tm_mon + 1, 1900 + motd_tm->tm_year, motd_tm->tm_hour,
 2301             motd_tm->tm_min);
 2302 }
 2303 
 2304 void 
 2305 read_shortmotd(char *filename)
 2306 {
 2307     aMotd *temp, *last;
 2308     char        buffer[MOTDLINELEN], *tmp;
 2309     int         fd;
 2310 
 2311     /* Clear out the old MOTD */
 2312 
 2313     while (shortmotd)
 2314     {
 2315         temp = shortmotd->next;
 2316         MyFree(shortmotd);
 2317         shortmotd = temp;
 2318     }
 2319     fd = open(filename, O_RDONLY);
 2320     if (fd == -1)
 2321     {
 2322         if(!forked)
 2323                 printf("WARNING:  sMOTD file %s could not be found.  "
 2324                        "Skipping sMOTD load.\n", filename);
 2325         return;
 2326     }
 2327     
 2328     last = (aMotd *) NULL;
 2329 
 2330     while (dgets(fd, buffer, MOTDLINELEN - 1) > 0) 
 2331     {
 2332         if ((tmp = (char *) strchr(buffer, '\n')))
 2333             *tmp = '\0';
 2334         if ((tmp = (char *) strchr(buffer, '\r')))
 2335             *tmp = '\0';
 2336         temp = (aMotd *) MyMalloc(sizeof(aMotd));
 2337 
 2338         strncpyzt(temp->line, buffer, MOTDLINELEN);
 2339         temp->next = (aMotd *) NULL;
 2340         if (!shortmotd)
 2341             shortmotd = temp;
 2342         else
 2343             last->next = temp;
 2344         last = temp;
 2345     }
 2346     close(fd);
 2347 }
 2348 
 2349 /*
 2350  * read_help() - modified from from CoMSTuD's read_motd added Aug 29,
 2351  * 1996 modifed  Aug 31 1997 - Dianora
 2352  * 
 2353  * Use the same idea for the oper helpfile
 2354  */
 2355 void 
 2356 read_help(char *filename)
 2357 {
 2358     aMotd *temp, *last;
 2359     char        buffer[MOTDLINELEN], *tmp;
 2360     int         fd;
 2361 
 2362     /* Clear out the old HELPFILE */
 2363 
 2364     while (helpfile) 
 2365     {
 2366         temp = helpfile->next;
 2367         MyFree(helpfile);
 2368         helpfile = temp;
 2369     }
 2370 
 2371     fd = open(filename, O_RDONLY);
 2372     if (fd == -1)
 2373     {
 2374         if(!forked)
 2375                 printf("WARNING:  Help file %s could not be found.  "
 2376                        "Skipping Help file load.\n", filename);
 2377         return;
 2378     }
 2379 
 2380     last = (aMotd *) NULL;
 2381 
 2382     while (dgets(fd, buffer, MOTDLINELEN - 1) > 0) 
 2383     {
 2384         if ((tmp = (char *) strchr(buffer, '\n')))
 2385             *tmp = '\0';
 2386         if ((tmp = (char *) strchr(buffer, '\r')))
 2387             *tmp = '\0';
 2388         temp = (aMotd *) MyMalloc(sizeof(aMotd));
 2389 
 2390         strncpyzt(temp->line, buffer, MOTDLINELEN);
 2391         temp->next = (aMotd *) NULL;
 2392         if (!helpfile)
 2393             helpfile = temp;
 2394         else
 2395             last->next = temp;
 2396         last = temp;
 2397     }
 2398     close(fd);
 2399 }
 2400 
 2401 /* m_close - added by Darren Reed Jul 13 1992. */
 2402 int 
 2403 m_close(aClient *cptr, aClient *sptr, int parc, char *parv[])
 2404 {
 2405     aClient *acptr;
 2406     int     i;
 2407     int         closed = 0;
 2408 
 2409     if (!MyOper(sptr)) 
 2410     {
 2411         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 2412         return 0;
 2413     }
 2414 
 2415     for (i = highest_fd; i; i--) 
 2416     {
 2417         if (!(acptr = local[i]))
 2418             continue;
 2419         if (!IsUnknown(acptr) && !IsConnecting(acptr) &&
 2420             !IsHandshake(acptr))
 2421             continue;
 2422         sendto_one(sptr, rpl_str(RPL_CLOSING), me.name, parv[0],
 2423                    get_client_name(acptr, TRUE), acptr->status);
 2424         exit_client(acptr, acptr, acptr, "Oper Closing");
 2425         closed++;
 2426     }
 2427     sendto_one(sptr, rpl_str(RPL_CLOSEEND), me.name, parv[0], closed);
 2428     return 0;
 2429 }
 2430 
 2431 int 
 2432 m_die(aClient *cptr, aClient *sptr, int parc, char *parv[])
 2433 {
 2434     aClient *acptr;
 2435     int     i;
 2436     char       *pass = NULL;
 2437 
 2438     if (!OPCanDie(sptr))
 2439     {
 2440         sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
 2441         return 0;
 2442     }
 2443     /* X line -mjs */
 2444 
 2445     if ((pass = MeLine->diepass))
 2446     {
 2447         if (parc < 2) 
 2448         {
 2449             sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name,
 2450                        parv[0], "DIE");
 2451             return 0;
 2452         }
 2453         if (strcmp(pass, parv[1])) 
 2454         {
 2455             sendto_one(sptr, err_str(ERR_PASSWDMISMATCH), me.name, parv[0]);
 2456             return 0;
 2457         }
 2458     }
 2459 
 2460     for (i = 0; i <= highest_fd; i++) 
 2461     {
 2462         if (!(acptr = local[i]))
 2463             continue;
 2464         if (IsClient(acptr))
 2465             sendto_one(acptr,
 2466                        ":%s NOTICE %s :Server Terminating. %s",
 2467                        me.name, acptr->name,
 2468                        get_client_name(sptr, FALSE));
 2469         else if (IsServer(acptr))
 2470             sendto_one(acptr, ":%s ERROR :Terminated by %s",
 2471                        me.name, get_client_name(sptr, TRUE));
 2472     }
 2473     s_die();
 2474     return 0;
 2475 }
 2476 
 2477 /*
 2478  * m_capab 
 2479  * Communicate what I can do to another server 
 2480  * This has to be able to be sent and understood while
 2481  * the client is UNREGISTERED. Therefore, we
 2482  * absolutely positively must not check to see if
 2483  * this is a server or a client. It's probably an unknown!
 2484  */
 2485 int 
 2486 m_capab(aClient *cptr, aClient *sptr, int parc, char *parv[])
 2487 {
 2488     int         i;
 2489 
 2490     /* If it's not local, or it has already set capabilities,
 2491      * silently ignore it.
 2492      * Dont ignore clients where we have set some capabilities already
 2493      * that would suck for connecting TO servers.
 2494      */
 2495     
 2496     if(cptr != sptr)
 2497         return 0;
 2498 
 2499     for (i = 1; i < parc; i++) 
 2500     {
 2501         if (strcmp(parv[i], "BURST") == 0)
 2502             SetBurst(sptr);
 2503         else if (strcmp(parv[i], "UNCONNECT") == 0)
 2504             SetUnconnect(cptr);
 2505         else if (strcmp(parv[i], "DKEY") == 0)
 2506             SetDKEY(cptr);
 2507         else if (strcmp(parv[i], "ZIP") == 0)
 2508             SetZipCapable(cptr);
 2509 #ifdef NOQUIT
 2510         else if (strcmp(parv[i], "NOQUIT") == 0)
 2511             SetNoquit(cptr);
 2512 #endif
 2513     else if (strcmp(parv[i], "NICKIPSTR") == 0)
 2514         SetNickIPStr(cptr);
 2515     }
 2516 
 2517     return 0;
 2518 }
 2519 
 2520 /* m_svskill - Just about the same as outta df
 2521  *  - Raistlin
 2522  * parv[0] = servername
 2523  * parv[1] = client
 2524  * parv[2] = nick stamp
 2525  * parv[3] = kill message
 2526  */
 2527          
 2528 int 
 2529 m_svskill(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 2530 {
 2531     aClient *acptr;
 2532     char *comment;
 2533     char reason[TOPICLEN + 1];
 2534     ts_val ts = 0;
 2535 
 2536     if (parc < 2)
 2537         return 0;
 2538 
 2539     if (parc > 3) 
 2540     {
 2541         comment = parv[3] ? parv[3] : parv[0];
 2542         ts = atol(parv[2]);
 2543     }
 2544     else
 2545         comment = (parc > 2 && parv[2]) ? parv[2] : parv[0];
 2546       
 2547     if(!IsULine(sptr)) return -1;
 2548     if((acptr = find_client(parv[1], NULL)) && (!ts || ts == acptr->tsinfo))
 2549     {
 2550         if(MyClient(acptr))
 2551         {
 2552             strcpy(reason, "SVSKilled: ");
 2553             strncpy(reason + 11, comment, TOPICLEN - 11);
 2554             reason[TOPICLEN] = '\0';
 2555             exit_client(acptr, acptr, sptr, reason);
 2556             return (acptr == cptr) ? FLUSH_BUFFER : 0;
 2557         }
 2558         if(acptr->from == cptr)
 2559         {
 2560             sendto_realops_lev(DEBUG_LEV, "Received wrong-direction SVSKILL"
 2561                                " for %s (behind %s) from %s", 
 2562                                acptr->name, cptr->name,
 2563                                get_client_name(sptr, HIDEME));
 2564             return 0;
 2565         }
 2566         else if(ts == 0) 
 2567             sendto_one(acptr->from, ":%s SVSKILL %s :%s", parv[0], parv[1],
 2568                                comment);
 2569         else
 2570             sendto_one(acptr->from, ":%s SVSKILL %s %ld :%s", parv[0], parv[1],
 2571                                ts, comment);
 2572     }
 2573     return 0;
 2574 }
 2575          
 2576 /* m_akill -
 2577  * Parse AKILL command
 2578  * parv[1]=host 
 2579  * parv[2]=user
 2580  * parv[3]=length
 2581  * parv[4]=akiller
 2582  * parv[5]=time set
 2583  * parv[6]=reason
 2584  */      
 2585 int 
 2586 m_akill(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 2587 {
 2588     char *user, *host, *reason, *akiller, buffer[1024], *current_date;
 2589     time_t length=0, timeset=0;
 2590     struct userBan *ban, *oban;
 2591 
 2592     if(!IsServer(sptr) || (parc < 6))
 2593         return 0;
 2594         
 2595     if(!IsULine(sptr)) 
 2596     {
 2597         sendto_serv_butone(&me,":%s GLOBOPS :Non-ULined server %s trying to "
 2598                            "AKILL!", me.name, sptr->name);
 2599         send_globops("From %s: Non-ULined server %s trying to AKILL!", me.name,
 2600                      sptr->name);
 2601         return 0;
 2602     }
 2603         
 2604     host=parv[1];
 2605     user=parv[2];
 2606     akiller=parv[4];
 2607     length=atoi(parv[3]);
 2608     timeset=atoi(parv[5]);
 2609     reason=(parv[6] ? parv[6] : "<no reason>");
 2610 
 2611     if(length == 0) /* a "permanent" akill? */
 2612        length = (86400 * 7); /* hold it for a week */
 2613 
 2614     /* is this an old bogus akill? */
 2615     if(timeset + length <= NOW)
 2616     {
 2617        /* Let's warn about bogus akills but also try to fix them as services will only send AKILL commands
 2618           when it really wants to take out the users (now)... -Kobi_S */
 2619        sendto_realops_lev(DEBUG_LEV, "m_akill: Got bogus akill from %s with timeset=%ld when NOW=%ld for %s@%s",
 2620                           sptr->name, (long)timeset, (long)NOW, user, host);
 2621        timeset = NOW;
 2622        length = 30;
 2623     }
 2624 
 2625     current_date=smalldate((time_t)timeset);
 2626     /* cut reason down a little, eh? */
 2627     /* 250 chars max */
 2628     if(strlen(reason)>250)
 2629         reason[251]=0;
 2630 
 2631     ban = make_hostbased_ban(user, host);
 2632     if(!ban)
 2633     {
 2634        sendto_realops_lev(DEBUG_LEV, "make_hostbased_ban(%s, %s) failed"
 2635                                      " on akill", user, host);
 2636        return 0;
 2637     }
 2638 
 2639     /* if it already exists, pass it on */
 2640     oban = find_userban_exact(ban, 0);
 2641     if(oban)
 2642     {
 2643         /* pass along the akill anyways */
 2644         sendto_serv_butone(cptr, ":%s AKILL %s %s %ld %s %ld :%s",
 2645                            sptr->name, host, user, (long)length, akiller,
 2646                            (long)timeset, reason);
 2647        userban_free(ban);
 2648        return 0;
 2649     }
 2650         
 2651     ircsprintf(buffer, "%s (%s)", reason, current_date);
 2652     ban->flags |= (UBAN_NETWORK|UBAN_TEMPORARY);
 2653     ban->reason = (char *) MyMalloc(strlen(buffer) + 1);
 2654     strcpy(ban->reason, buffer);
 2655     ban->timeset = timeset;
 2656     ban->duration = length;
 2657 
 2658     add_hostbased_userban(ban);
 2659 
 2660     /* send it off to any other servers! */
 2661     sendto_serv_butone(cptr, ":%s AKILL %s %s %ld %s %ld :%s",
 2662                        sptr->name, host, user, (long)length, akiller,
 2663                        (long)timeset, reason);
 2664 
 2665     /* Check local users against it */
 2666     userban_sweep(ban);
 2667         
 2668     return 0;
 2669 }
 2670   
 2671 int 
 2672 m_rakill(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 2673 {
 2674     struct userBan *ban, *oban;
 2675 
 2676     if(!IsServer(sptr))
 2677         return 0;
 2678 
 2679     /* just quickly find the akill and be rid of it! */
 2680     if(parc<3) 
 2681     {
 2682         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0],
 2683                    "RAKILL");
 2684         return 0;
 2685     }
 2686 
 2687     if(!IsULine(sptr)) 
 2688     {
 2689         sendto_serv_butone(&me, ":%s GLOBOPS :Non-ULined server %s trying to "
 2690                            "RAKILL!",  me.name, sptr->name);
 2691         send_globops("From %s: Non-ULined server %s trying to RAKILL!",
 2692                      me.name,
 2693                      sptr->name);
 2694         return 0;
 2695     }
 2696 
 2697     ban = make_hostbased_ban(parv[2], parv[1]);
 2698     if(!ban)
 2699     {
 2700        sendto_realops_lev(DEBUG_LEV, "make_hostbased_ban(%s, %s) failed"
 2701                                      " on rakill", parv[2], parv[1]);
 2702        return 0;
 2703     }
 2704 
 2705     ban->flags |= UBAN_NETWORK;
 2706     oban = find_userban_exact(ban, UBAN_NETWORK);
 2707     if(oban)
 2708     {
 2709        remove_userban(oban);
 2710        userban_free(oban);
 2711     }
 2712 
 2713     userban_free(ban);
 2714 
 2715     sendto_serv_butone(cptr, ":%s RAKILL %s %s", sptr->name, parv[1], parv[2]);
 2716     return 0;
 2717 }
 2718 
 2719 /*
 2720  * Allow U-lined servers to remove all network-wide bans in case of an emergency -xPsycho
 2721  */
 2722 
 2723 int
 2724 m_nbanreset(aClient *cptr, aClient *sptr, int parc, char *parv[])
 2725 {
 2726     if(!IsServer(sptr))
 2727     {
 2728         return 0;
 2729     }
 2730 
 2731     if(!IsULine(sptr))
 2732     {
 2733         sendto_serv_butone(&me, ":%s GLOBOPS :Non-ULined server %s trying to NBANRESET!",  me.name, sptr->name);
 2734         send_globops("From %s: Non-ULined server %s trying to NBANRESET!", me.name, sptr->name);
 2735         return 0;
 2736     }
 2737 
 2738     sendto_ops("%s is removing all network bans and resetting throttles", sptr->name);
 2739 
 2740     remove_userbans_match_flags(UBAN_NETWORK, 0);
 2741     remove_simbans_match_flags(SBAN_NICK|SBAN_NETWORK, 0);
 2742     remove_simbans_match_flags(SBAN_CHAN|SBAN_NETWORK, 0);
 2743     remove_simbans_match_flags(SBAN_GCOS|SBAN_NETWORK, 0);
 2744     throttle_rehash();
 2745 
 2746     sendto_serv_butone(cptr, ":%s NBANRESET", sptr->name);
 2747 
 2748     return 0;
 2749 }
 2750 
 2751         
 2752 /*
 2753  * RPL_NOWON   - Online at the moment (Succesfully added to WATCH-list)
 2754  * RPL_NOWOFF  - Offline at the moement (Succesfully added to WATCH-list)
 2755  * RPL_WATCHOFF   - Succesfully removed from WATCH-list.
 2756  * ERR_TOOMANYWATCH - Take a guess :>  Too many WATCH entries.
 2757  */
 2758 static void 
 2759 show_watch(aClient *cptr, char *name, int rpl1, int rpl2) 
 2760 {
 2761     aClient *acptr;     
 2762     
 2763     if ((acptr = find_person(name, NULL)))
 2764         sendto_one(cptr, rpl_str(rpl1), me.name, cptr->name,
 2765                    acptr->name, acptr->user->username,
 2766 #ifdef USER_HOSTMASKING
 2767                    IsUmodeH(acptr)?acptr->user->mhost:
 2768 #endif
 2769                                                       acptr->user->host,
 2770                    acptr->lasttime);
 2771     else
 2772         sendto_one(cptr, rpl_str(rpl2), me.name, cptr->name,
 2773                    name, "*", "*", 0);
 2774 }
 2775         
 2776 /* m_watch */
 2777 int 
 2778 m_watch(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 2779 {
 2780     aClient  *acptr;
 2781     char  *s, *p, *user;
 2782     char def[2] = "l";
 2783     int listreq = 0;
 2784     int listcount = 0;
 2785         
 2786     if (parc < 2) 
 2787     {
 2788         /* Default to 'l' - list who's currently online */
 2789         parc = 2;
 2790         parv[1] = def;
 2791     }
 2792     
 2793     for (p = NULL, s = strtoken(&p, parv[1], ", "); s;
 2794          s = strtoken(&p, NULL, ", ")) 
 2795     {
 2796         if ((user = (char *)strchr(s, '!')))
 2797             *user++ = '\0'; /* Not used */
 2798                 
 2799         /*
 2800          * Prefix of "+", they want to add a name to their WATCH
 2801          * list. 
 2802          */
 2803         if (*s == '+') 
 2804         {
 2805             if (*(s+1)) 
 2806             {
 2807                 if ((sptr->watches >= MAXWATCH) && !IsAnOper(sptr))
 2808                 {
 2809                     sendto_one(sptr, err_str(ERR_TOOMANYWATCH),
 2810                                me.name, cptr->name, s+1);                                       
 2811                     continue;
 2812                 }                               
 2813                 add_to_watch_hash_table(s+1, sptr);
 2814             }
 2815             show_watch(sptr, s+1, RPL_NOWON, RPL_NOWOFF);
 2816             listcount++;
 2817             continue;
 2818         }
 2819         
 2820         /*
 2821          * Prefix of "-", coward wants to remove somebody from their
 2822          * WATCH list.  So do it. :-)
 2823          */
 2824         if (*s == '-') 
 2825         {
 2826             del_from_watch_hash_table(s+1, sptr);
 2827             show_watch(sptr, s+1, RPL_WATCHOFF, RPL_WATCHOFF);
 2828             listcount++;
 2829             continue;
 2830         }
 2831                                         
 2832         /*
 2833          * Fancy "C" or "c", they want to nuke their WATCH list and start
 2834          * over, so be it.
 2835          */
 2836         if (*s == 'C' || *s == 'c') 
 2837         {
 2838             hash_del_watch_list(sptr);
 2839             continue;
 2840         }
 2841                 
 2842         /*
 2843          * Now comes the fun stuff, "S" or "s" returns a status report of
 2844          * their WATCH list.  I imagine this could be CPU intensive if its
 2845          * done alot, perhaps an auto-lag on this?
 2846          */
 2847         if (*s == 'S' || *s == 's') 
 2848         {
 2849             Link *lp;
 2850             aWatch *anptr;
 2851             int  count = 0;
 2852             
 2853             /* only allowed once per command */
 2854             if (listreq & 0x1)
 2855                 continue;
 2856             listreq |= 0x1;
 2857                                                         
 2858             /*
 2859              * Send a list of how many users they have on their WATCH list
 2860              * and how many WATCH lists they are on.
 2861              */
 2862             anptr = hash_get_watch(sptr->name);
 2863             if (anptr)
 2864                 for (lp = anptr->watch, count = 1; (lp = lp->next); count++);
 2865             sendto_one(sptr, rpl_str(RPL_WATCHSTAT), me.name, parv[0],
 2866                        sptr->watches, count);
 2867                         
 2868             /*
 2869              * Send a list of everybody in their WATCH list. Be careful
 2870              * not to buffer overflow.
 2871              */
 2872             if ((lp = sptr->watch) == NULL) 
 2873             {
 2874                 sendto_one(sptr, rpl_str(RPL_ENDOFWATCHLIST), me.name, parv[0],
 2875                            *s);
 2876                 continue;
 2877             }
 2878             *buf = '\0';
 2879             strcpy(buf, lp->value.wptr->nick);
 2880             count = strlen(parv[0])+strlen(me.name)+10+strlen(buf);
 2881             while ((lp = lp->next)) 
 2882             {
 2883                 if (count+strlen(lp->value.wptr->nick)+1 > BUFSIZE - 2) 
 2884                 {
 2885                     sendto_one(sptr, rpl_str(RPL_WATCHLIST), me.name,
 2886                                parv[0], buf);
 2887                     listcount++;
 2888                     *buf = '\0';
 2889                     count = strlen(parv[0])+strlen(me.name)+10;
 2890                 }
 2891                 strcat(buf, " ");
 2892                 strcat(buf, lp->value.wptr->nick);
 2893                 count += (strlen(lp->value.wptr->nick)+1);
 2894             }
 2895             sendto_one(sptr, rpl_str(RPL_WATCHLIST), me.name, parv[0], buf);
 2896             sendto_one(sptr, rpl_str(RPL_ENDOFWATCHLIST), me.name, parv[0],
 2897                        *s);
 2898             listcount++;
 2899             continue;
 2900         }
 2901                 
 2902         /*
 2903          * Well that was fun, NOT.  Now they want a list of everybody in
 2904          * their WATCH list AND if they are online or offline? Sheesh,
 2905          * greedy arn't we?
 2906          */
 2907         if (*s == 'L' || *s == 'l') 
 2908         {
 2909             Link *lp = sptr->watch;
 2910                         
 2911             /* only allowed once per command */
 2912             if (listreq & 0x2)
 2913                 continue;
 2914             listreq |= 0x2;
 2915 
 2916             while (lp) 
 2917             {
 2918                 if ((acptr = find_person(lp->value.wptr->nick, NULL)))
 2919                     sendto_one(sptr, rpl_str(RPL_NOWON), me.name, parv[0],
 2920                                acptr->name, acptr->user->username,
 2921 #ifdef USER_HOSTMASKING
 2922                                IsUmodeH(acptr)?acptr->user->mhost:
 2923 #endif
 2924                                                                   acptr->user->host,
 2925                                acptr->tsinfo);
 2926                 /*
 2927                  * But actually, only show them offline if its a capital
 2928                  * 'L' (full list wanted).
 2929                  */
 2930                 else if (IsUpper(*s))
 2931                     sendto_one(sptr, rpl_str(RPL_NOWOFF), me.name, parv[0],
 2932                                lp->value.wptr->nick, "*", "*",
 2933                                lp->value.wptr->lasttime);
 2934                 lp = lp->next;
 2935                 listcount++;
 2936             }
 2937                         
 2938             sendto_one(sptr, rpl_str(RPL_ENDOFWATCHLIST), me.name, parv[0],
 2939                        *s);
 2940             continue;
 2941         }
 2942         /* Hmm.. unknown prefix character.. Ignore it. :-) */
 2943     }
 2944         
 2945     /* discourage repetitive listings */
 2946 #ifdef NO_OPER_FLOOD
 2947     if (!IsAnOper(sptr))
 2948 #endif
 2949     if (!NoMsgThrottle(sptr))
 2950         sptr->since += listcount/4;
 2951     
 2952     return 0;
 2953 }
 2954 
 2955 int 
 2956 m_sqline(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 2957 {
 2958     struct simBan *ban;
 2959     unsigned int flags;
 2960     char *reason;
 2961 
 2962     if(!(IsServer(sptr) || IsULine(sptr)))
 2963         return 0;
 2964 
 2965     if(parc < 2) 
 2966     {
 2967         /* we should not get malformed sqlines.  complain loud */
 2968         sendto_realops("%s attempted to add sqline with insufficient params!"
 2969                        " (ignored) Contact coders!", sptr->name);
 2970         return 0;
 2971     }
 2972         
 2973     /* if we have any Q:lines (SQ or Q) that match
 2974      * this Q:line, just return (no need to waste cpu */
 2975 
 2976     flags = SBAN_NETWORK;
 2977     if(parv[1][0] == '#')
 2978        flags |= SBAN_CHAN;
 2979     else
 2980        flags |= SBAN_NICK;
 2981     ban = make_simpleban(flags, parv[1]);
 2982     if(!ban)
 2983     {
 2984         sendto_realops("make_simpleban(%s) failed on sqline!", parv[1]);
 2985         return 0;
 2986     }
 2987 
 2988     reason = BadPtr(parv[2]) ? "Reserved" : parv[2];
 2989     ban->reason = NULL;
 2990 
 2991     if (find_simban_exact(ban) == NULL)
 2992     {
 2993         ban->reason = (char *) MyMalloc(strlen(reason) + 1);
 2994         strcpy(ban->reason, reason);
 2995         ban->timeset = NOW;
 2996         add_simban(ban);
 2997     }
 2998     else
 2999         simban_free(ban);
 3000 
 3001     sendto_serv_butone(cptr, ":%s SQLINE %s :%s", sptr->name, parv[1],
 3002                        reason);
 3003     return 0;
 3004 }
 3005         
 3006 int 
 3007 m_unsqline(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 3008 {
 3009     int matchit = 0;
 3010     char *mask;
 3011     
 3012     if(!(IsServer(sptr) || IsULine(sptr)))
 3013         return 0;
 3014     
 3015     if(parc < 2) 
 3016     {
 3017         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0],
 3018                    "UNSQLINE");
 3019         return 0;
 3020     }
 3021     
 3022     if (parc == 3) 
 3023     {
 3024         matchit = atoi(parv[1]);
 3025         mask = parv[2];
 3026     }
 3027     else
 3028         mask = parv[1];
 3029 
 3030     /* special case for "UNSQLINE 1 :*" */
 3031     if(mycmp(mask, "*") == 0 && matchit)
 3032     {
 3033        remove_simbans_match_mask(SBAN_CHAN|SBAN_NETWORK, mask, 1);
 3034        remove_simbans_match_mask(SBAN_NICK|SBAN_NETWORK, mask, 1);
 3035     }
 3036     else if(mask[0] == '#')
 3037        remove_simbans_match_mask(SBAN_CHAN|SBAN_NETWORK, mask, matchit);
 3038     else
 3039        remove_simbans_match_mask(SBAN_NICK|SBAN_NETWORK, mask, matchit);
 3040 
 3041     if (parc == 3) 
 3042         sendto_serv_butone(cptr, ":%s UNSQLINE %d :%s", sptr->name, matchit,
 3043                            mask);
 3044     else
 3045         sendto_serv_butone(cptr, ":%s UNSQLINE :%s", sptr->name, mask);
 3046     return 0;
 3047 }
 3048 
 3049 int m_sgline(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 3050 {
 3051     struct simBan *ban;
 3052     unsigned int len;
 3053     unsigned int flags;
 3054     char *mask, *reason;
 3055     
 3056     if(!(IsServer(sptr) || IsULine(sptr)))
 3057         return 0;
 3058 
 3059     if(parc<3) 
 3060     {
 3061         sendto_realops("%s attempted to add sgline with insufficient params!"
 3062                        " (ignored) Contact coders!", sptr->name);
 3063         return 0;
 3064     }
 3065         
 3066     len=atoi(parv[1]);
 3067     mask=parv[2];
 3068     if ((strlen(mask) > len) && (mask[len])==':') 
 3069     {
 3070         mask[len] = '\0';
 3071         reason = mask+len+1;
 3072     } 
 3073     else 
 3074     { /* Bogus */
 3075         return 0;
 3076     }
 3077     
 3078     /* if we have any G:lines (SG or G) that match
 3079      * this G:line, just return (no need to waste cpu */
 3080 
 3081     flags = SBAN_NETWORK|SBAN_GCOS;
 3082     ban = make_simpleban(flags, mask);
 3083     if(!ban)
 3084     {
 3085         sendto_realops("make_simpleban(%s) failed on sgline!", parv[1]);
 3086         return 0;
 3087     }
 3088 
 3089     if(BadPtr(reason))
 3090        reason = "Reserved";
 3091     ban->reason = NULL;
 3092 
 3093     if (find_simban_exact(ban) == NULL)
 3094     {
 3095         ban->reason = (char *) MyMalloc(strlen(reason) + 1);
 3096         strcpy(ban->reason, reason);
 3097         ban->timeset = NOW;
 3098         add_simban(ban);
 3099     }
 3100     else
 3101         simban_free(ban);
 3102 
 3103     sendto_serv_butone(cptr, ":%s SGLINE %d :%s:%s", sptr->name, len,
 3104                        mask, reason);
 3105     return 0;
 3106 }
 3107         
 3108 int 
 3109 m_unsgline(aClient *cptr, aClient *sptr, int parc, char *parv[]) 
 3110 {
 3111     int matchit=0;
 3112     char *mask;
 3113    
 3114     if(!(IsServer(sptr) || IsULine(sptr)))
 3115         return 0;
 3116    
 3117     if(parc<2) 
 3118     {
 3119         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0],
 3120                    "UNSGLINE");
 3121         return 0;
 3122     }
 3123    
 3124 
 3125     if (parc==3) 
 3126     {
 3127         matchit=atoi(parv[1]);
 3128         mask=parv[2];
 3129     }
 3130     else
 3131         mask=parv[1];
 3132     
 3133     remove_simbans_match_mask(SBAN_GCOS|SBAN_NETWORK, mask, matchit);
 3134     
 3135     if (parc==3)
 3136         sendto_serv_butone(cptr, ":%s UNSGLINE %d :%s", sptr->name, matchit,
 3137                            mask);
 3138     else
 3139         sendto_serv_butone(cptr, ":%s UNSGLINE :%s",sptr->name,mask);
 3140     return 0;
 3141 }
 3142 
 3143 int
 3144 m_check(aClient *cptr, aClient *sptr, int parc, char *parv[])
 3145 {
 3146     struct simBan *ban;
 3147 
 3148     if (!IsAnOper(sptr))
 3149     {
 3150         sendto_one(sptr, getreply(ERR_NOPRIVILEGES), me.name, parv[0]);
 3151         return 0;
 3152     }
 3153 
 3154     if (parc < 3 || (mycmp(parv[1], "nick") && mycmp(parv[1], "channel")))
 3155     {
 3156         sendto_one(sptr, "NOTICE %s :Syntax: CHECK NICK <nickname>", parv[0]);
 3157         sendto_one(sptr, "NOTICE %s :Syntax: CHECK CHANNEL <channel>", parv[0]);
 3158         return 0;
 3159     }
 3160     
 3161     if(!mycmp(parv[1], "nick"))
 3162     {
 3163         if ((ban = check_mask_simbanned(parv[2], SBAN_NICK)))
 3164         {
 3165             char *reason = ban->reason ? ban->reason : "<no reason>";
 3166 
 3167             if (ban->flags & SBAN_TEMPORARY)
 3168                 sendto_one(sptr, "NOTICE %s :CHECK NICK: %s [expires in %ldm]: %s",
 3169                            parv[0], ban->mask,
 3170                             (long)((ban->timeset + ban->duration - NOW) / 60),
 3171                            reason);
 3172              else
 3173                 sendto_one(sptr, "NOTICE %s :CHECK NICK: %s [permanent]: %s",
 3174                            parv[0], ban->mask, reason);
 3175         }
 3176         else
 3177         {
 3178             sendto_one(sptr, "NOTICE %s :CHECK NICK: no match", parv[0]);
 3179         }
 3180     }
 3181     if(!mycmp(parv[1], "channel"))
 3182     {
 3183         aChannel *chptr;
 3184         struct FlagList *xflag;
 3185 
 3186         if((chptr = find_channel(parv[2], NULL)))
 3187         {
 3188             sendto_one(sptr, "NOTICE %s :CHECK CHANNEL: %s", parv[0], chptr->chname);
 3189             sendto_one(sptr, "NOTICE %s :JOIN_CONNECT_TIME: %d", parv[0], chptr->join_connect_time);
 3190             sendto_one(sptr, "NOTICE %s :TALK_CONNECT_TIME: %d", parv[0], chptr->talk_connect_time);
 3191             sendto_one(sptr, "NOTICE %s :TALK_JOIN_TIME: %d", parv[0], chptr->talk_join_time);
 3192             sendto_one(sptr, "NOTICE %s :MAX_BANS: %d", parv[0], chptr->max_bans);
 3193             sendto_one(sptr, "NOTICE %s :MAX_INVITES: %d", parv[0], chptr->max_invites);
 3194             sendto_one(sptr, "NOTICE %s :MAX_MSG_TIME: %d:%d", parv[0], chptr->max_messages, chptr->max_messages_time);
 3195             sendto_one(sptr, "NOTICE %s :GREETMSG: %s", parv[0], chptr->greetmsg?chptr->greetmsg:"<NONE>");
 3196             for(xflag = xflags_list; xflag->option; xflag++)
 3197             {
 3198                 if(!strcmp(xflag->option,"USER_VERBOSE") || !strcmp(xflag->option,"OPER_VERBOSE")) continue;
 3199                 sendto_one(sptr, "NOTICE %s :%s: %s", parv[0], xflag->option, (chptr->xflags & xflag->flag)?"On":"Off");
 3200             }
 3201             sendto_one(sptr, "NOTICE %s :*** End of Check ***", parv[0]);
 3202         }
 3203         else
 3204         {
 3205             sendto_one(sptr, "NOTICE %s :CHECK CHANNEL: no match", parv[0]);
 3206         }
 3207     }
 3208     
 3209     return 0;
 3210 }
 3211 
 3212 
 3213 u_long
 3214 memcount_s_serv(MCs_serv *mc)
 3215 {
 3216     aMotd *m;
 3217 
 3218     mc->file = __FILE__;
 3219 
 3220     for (m = motd; m; m = m->next)
 3221     {
 3222         mc->motd.c++;
 3223         mc->motd.m += sizeof(*m);
 3224     }
 3225     mc->total.c += mc->motd.c;
 3226     mc->total.m += mc->motd.m;
 3227 
 3228     for (m = shortmotd; m; m = m->next)
 3229     {
 3230         mc->shortmotd.c++;
 3231         mc->shortmotd.m += sizeof(*m);
 3232     }
 3233     mc->total.c += mc->shortmotd.c;
 3234     mc->total.m += mc->shortmotd.m;
 3235 
 3236     for (m = helpfile; m; m = m->next)
 3237     {
 3238         mc->help.c++;
 3239         mc->help.m += sizeof(*m);
 3240     }
 3241     mc->total.c += mc->help.c;
 3242     mc->total.m += mc->help.m;
 3243 
 3244     return mc->total.m;
 3245 }
 3246