ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_set.c
(Generate patch)

Comparing:
ircd-hybrid-7.2/modules/m_set.c (file contents), Revision 646 by michael, Wed Jun 7 12:42:00 2006 UTC vs.
ircd-hybrid/trunk/modules/m_set.c (file contents), Revision 4094 by michael, Sun Jun 29 11:48:50 2014 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  m_set.c: Sets a server parameter.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 1997-2014 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 18 | Line 17
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
19   *  USA
21 *
22 *  $Id$
20   */
21  
22 < /* rewritten by jdc */
22 > /*! \file m_set.c
23 > * \brief Includes required functions for processing the SET command.
24 > * \version $Id$
25 > */
26  
27   #include "stdinc.h"
28 #include "handlers.h"
28   #include "client.h"
29   #include "event.h"
30   #include "irc_string.h"
31   #include "ircd.h"
32   #include "numeric.h"
34 #include "fdlist.h"
35 #include "s_bsd.h"
36 #include "s_serv.h"
33   #include "send.h"
34 < #include "common.h"   /* for NO */
39 < #include "channel.h"
40 < #include "s_log.h"
41 < #include "s_conf.h"
42 < #include "msg.h"
34 > #include "conf.h"
35   #include "parse.h"
36   #include "modules.h"
37 < #include "s_user.h"
46 <
47 <
48 < static void mo_set(struct Client *, struct Client *, int, char *[]);
49 <
50 < struct Message set_msgtab = {
51 <  "SET", 0, 0, 0, 0, MFLG_SLOW, 0,
52 <  {m_unregistered, m_not_oper, m_error, m_ignore, mo_set, m_ignore}
53 < };
54 <
55 < #ifndef STATIC_MODULES
56 < void
57 < _modinit(void)
58 < {
59 <  mod_add_cmd(&set_msgtab);
60 < }
61 <
62 < void
63 < _moddeinit(void)
64 < {
65 <  mod_del_cmd(&set_msgtab);
66 < }
67 <
68 < const char *_version = "$Revision$";
69 < #endif
70 <
71 < /* Structure used for the SET table itself */
72 < struct SetStruct
73 < {
74 <  const char *name;
75 <  void (*handler)();
76 <  int wants_char; /* 1 if it expects (char *, [int]) */
77 <  int wants_int;  /* 1 if it expects ([char *], int) */
78 <  /* eg:  0, 1 == only an int arg
79 <   * eg:  1, 1 == char and int args */
80 < };
37 > #include "misc.h"
38  
82 static void quote_autoconn(struct Client *, const char *, int);
83 static void quote_autoconnall(struct Client *, int);
84 static void quote_floodcount(struct Client *, int);
85 static void quote_identtimeout(struct Client *, int);
86 static void quote_idletime(struct Client *, int);
87 static void quote_log(struct Client *, int);
88 static void quote_max(struct Client *, int);
89 static void quote_msglocale(struct Client *, char *);
90 static void quote_spamnum(struct Client *, int);
91 static void quote_spamtime(struct Client *, int);
92 static void quote_splitmode(struct Client *, char *);
93 static void quote_splitnum(struct Client *, int);
94 static void quote_splitusers(struct Client *, int);
95 static void list_quote_commands(struct Client *);
96 static void quote_jfloodtime(struct Client *, int);
97 static void quote_jfloodcount(struct Client *, int);
98 static void quote_rejecttime(struct Client *, int);
39  
40 < /*
101 < * If this ever needs to be expanded to more than one arg of each
102 < * type, want_char/want_int could be the count of the arguments,
103 < * instead of just a boolean flag...
104 < *
105 < * -davidt
106 < */
107 <
108 < static struct SetStruct set_cmd_table[] =
109 < {
110 <  /* name               function        string arg  int arg */
111 <  /* -------------------------------------------------------- */
112 <  { "AUTOCONN",         quote_autoconn,         1,      1 },
113 <  { "AUTOCONNALL",      quote_autoconnall,      0,      1 },
114 <  { "FLOODCOUNT",       quote_floodcount,       0,      1 },
115 <  { "IDENTTIMEOUT",     quote_identtimeout,     0,      1 },
116 <  { "IDLETIME",         quote_idletime,         0,      1 },
117 <  { "LOG",              quote_log,              0,      1 },
118 <  { "MAX",              quote_max,              0,      1 },
119 <  { "MSGLOCALE",        quote_msglocale,        1,      0 },
120 <  { "SPAMNUM",          quote_spamnum,          0,      1 },
121 <  { "SPAMTIME",         quote_spamtime,         0,      1 },
122 <  { "SPLITMODE",        quote_splitmode,        1,      0 },
123 <  { "SPLITNUM",         quote_splitnum,         0,      1 },
124 <  { "SPLITUSERS",       quote_splitusers,       0,      1 },
125 <  { "JFLOODTIME",       quote_jfloodtime,       0,      1 },
126 <  { "JFLOODCOUNT",      quote_jfloodcount,      0,      1 },
127 <  { "REJECTTIME",       quote_rejecttime,       0,      1 },
128 <  /* -------------------------------------------------------- */
129 <  { NULL,               NULL,           0,      0 }
130 < };
131 <
132 < /*
133 < * list_quote_commands() sends the client all the available commands.
134 < * Four to a line for now.
135 < */
40 > /* SET AUTOCONN */
41   static void
42 < list_quote_commands(struct Client *source_p)
42 > quote_autoconn(struct Client *source_p, const char *arg, int newval)
43   {
44 <  int i;
140 <  int j = 0;
141 <  const char *names[4];
142 <
143 <  sendto_one(source_p, ":%s NOTICE %s :Available QUOTE SET commands:",
144 <             me.name, source_p->name);
145 <
146 <  names[0] = names[1] = names[2] = names[3] = "";
147 <
148 <  for (i = 0; set_cmd_table[i].handler; i++)
44 >  if (!EmptyString(arg))
45    {
46 <    names[j++] = set_cmd_table[i].name;
46 >    struct MaskItem *conf = find_exact_name_conf(CONF_SERVER, NULL, arg, NULL, NULL);
47  
48 <    if (j > 3)
48 >    if (conf)
49      {
50 <      sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
51 <                 me.name, source_p->name,
52 <                 names[0], names[1],
53 <                 names[2], names[3]);
54 <      j = 0;
55 <      names[0] = names[1] = names[2] = names[3] = "";
50 >      if (newval)
51 >        SetConfAllowAutoConn(conf);
52 >      else
53 >        ClearConfAllowAutoConn(conf);
54 >
55 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
56 >                           "%s has changed AUTOCONN for %s to %i",
57 >                           get_oper_name(source_p), arg, newval);
58 >      sendto_one_notice(source_p, &me, ":AUTOCONN for %s is now set to %i",
59 >                        arg, newval);
60      }
61 <
61 >    else
62 >      sendto_one_notice(source_p, &me, ":Cannot find %s", arg);
63    }
64 <  if (j)
65 <    sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
165 <               me.name, source_p->name,
166 <               names[0], names[1],
167 <               names[2], names[3]);
168 < }
169 <
170 < /* SET AUTOCONN */
171 < static void
172 < quote_autoconn(struct Client *source_p, const char *arg, int newval)
173 < {
174 <  set_autoconn(source_p, arg, newval);
64 >  else
65 >    sendto_one_notice(source_p, &me, ":Please specify a server name!");
66   }
67  
68   /* SET AUTOCONNALL */
69   static void
70 < quote_autoconnall(struct Client *source_p, int newval)
70 > quote_autoconnall(struct Client *source_p, const char *arg, int newval)
71   {
72    if (newval >= 0)
73    {
74 <    sendto_realops_flags(UMODE_ALL, L_ALL, "%s has changed AUTOCONNALL to %i",
75 <                         source_p->name, newval);
74 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
75 >                         "%s has changed AUTOCONNALL to %i",
76 >                         get_oper_name(source_p), newval);
77  
78      GlobalSetOptions.autoconn = newval;
79    }
80    else
81 <    sendto_one(source_p, ":%s NOTICE %s :AUTOCONNALL is currently %i",
82 <               me.name, source_p->name, GlobalSetOptions.autoconn);
81 >    sendto_one_notice(source_p, &me, ":AUTOCONNALL is currently %i",
82 >                      GlobalSetOptions.autoconn);
83   }
84  
85   /* SET FLOODCOUNT */
86   static void
87 < quote_floodcount(struct Client *source_p, int newval)
87 > quote_floodcount(struct Client *source_p, const char *arg, int newval)
88   {
89    if (newval >= 0)
90    {
91      GlobalSetOptions.floodcount = newval;
92 <    sendto_realops_flags(UMODE_ALL, L_ALL,
93 <                         "%s has changed FLOODCOUNT to %i", source_p->name,
94 <                         GlobalSetOptions.floodcount);
92 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
93 >                         "%s has changed FLOODCOUNT to %i",
94 >                         get_oper_name(source_p), GlobalSetOptions.floodcount);
95    }
96    else
97 <    sendto_one(source_p, ":%s NOTICE %s :FLOODCOUNT is currently %i",
98 <               me.name, source_p->name, GlobalSetOptions.floodcount);
97 >    sendto_one_notice(source_p, &me, ":FLOODCOUNT is currently %i",
98 >                      GlobalSetOptions.floodcount);
99   }
100  
101   /* SET IDENTTIMEOUT */
102   static void
103 < quote_identtimeout(struct Client *source_p, int newval)
103 > quote_identtimeout(struct Client *source_p, const char *arg, int newval)
104   {
105 <  if (!IsAdmin(source_p))
105 >  if (!HasUMode(source_p, UMODE_ADMIN))
106    {
107 <    sendto_one(source_p, form_str(ERR_NOPRIVS),
216 <               me.name, source_p->name, "set");
107 >    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "set");
108      return;
109    }
110  
111    if (newval > 0)
112    {
113 <    sendto_realops_flags(UMODE_ALL, L_ALL,
114 <                         "%s has changed IDENTTIMEOUT to %d",
115 <                         get_oper_name(source_p), newval);
113 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
114 >                         "%s has changed IDENTTIMEOUT to %d",
115 >                         get_oper_name(source_p), newval);
116      GlobalSetOptions.ident_timeout = newval;
117    }
118    else
119 <    sendto_one(source_p, ":%s NOTICE %s :IDENTTIMEOUT is currently %d",
120 <               me.name, source_p->name, GlobalSetOptions.ident_timeout);
230 < }
231 <
232 < /* SET IDLETIME */
233 < static void
234 < quote_idletime(struct Client *source_p, int newval)
235 < {
236 <  if (newval >= 0)
237 <  {
238 <    if (newval == 0)
239 <    {
240 <      sendto_realops_flags(UMODE_ALL, L_ALL,
241 <                           "%s has disabled idletime checking",
242 <                           source_p->name);
243 <      GlobalSetOptions.idletime = 0;
244 <    }
245 <    else
246 <    {
247 <      sendto_realops_flags(UMODE_ALL, L_ALL,
248 <                           "%s has changed IDLETIME to %i",
249 <                           source_p->name, newval);
250 <      GlobalSetOptions.idletime = (newval*60);
251 <    }
252 <  }
253 <  else
254 <  {
255 <    sendto_one(source_p, ":%s NOTICE %s :IDLETIME is currently %i",
256 <               me.name, source_p->name, GlobalSetOptions.idletime/60);
257 <  }
258 < }
259 <
260 < /* SET LOG */
261 < static void
262 < quote_log( struct Client *source_p, int newval )
263 < {
264 <  const char *log_level_as_string;
265 <
266 <  if (newval >= 0)
267 <  {
268 <    if (newval < L_WARN)
269 <    {
270 <      sendto_one(source_p, ":%s NOTICE %s :LOG must be > %d (L_WARN)",
271 <                 me.name, source_p->name, L_WARN);
272 <      return;
273 <    }
274 <
275 <    if (newval > L_DEBUG)
276 <    {
277 <      newval = L_DEBUG;
278 <    }
279 <
280 <    set_log_level(newval);
281 <    log_level_as_string = get_log_level_as_string(newval);
282 <    sendto_realops_flags(UMODE_ALL, L_ALL,"%s has changed LOG level to %i (%s)",
283 <                         source_p->name, newval, log_level_as_string);
284 <  }
285 <  else
286 <  {
287 <    sendto_one(source_p, ":%s NOTICE %s :LOG level is currently %i (%s)",
288 <               me.name, source_p->name, get_log_level(),
289 <               get_log_level_as_string(get_log_level()));
290 <  }
119 >    sendto_one_notice(source_p, &me, ":IDENTTIMEOUT is currently %d",
120 >                      GlobalSetOptions.ident_timeout);
121   }
122  
123   /* SET MAX */
124   static void
125 < quote_max (struct Client *source_p, int newval)
125 > quote_max(struct Client *source_p, const char *arg, int newval)
126   {
127    if (newval > 0)
128    {
299    recalc_fdlimit(NULL);
300
129      if (newval > MAXCLIENTS_MAX)
130      {
131 <      sendto_one(source_p,
132 <        ":%s NOTICE %s :You cannot set MAXCLIENTS to > %d, restoring to %d",
305 <        me.name, source_p->name, MAXCLIENTS_MAX);
131 >      sendto_one_notice(source_p, &me, ":You cannot set MAXCLIENTS to > %d, restoring to %d",
132 >                        MAXCLIENTS_MAX, ServerInfo.max_clients);
133        return;
134      }
135  
136      if (newval < MAXCLIENTS_MIN)
137      {
138 <      sendto_one(source_p,
139 <        ":%s NOTICE %s :You cannot set MAXCLIENTS to < %d, restoring to %d",
313 <        me.name, source_p->name, MAXCLIENTS_MIN, ServerInfo.max_clients);
138 >      sendto_one_notice(source_p, &me, ":You cannot set MAXCLIENTS to < %d, restoring to %d",
139 >                        MAXCLIENTS_MIN, ServerInfo.max_clients);
140        return;
141      }
142  
143      ServerInfo.max_clients = newval;
144  
145 <    sendto_realops_flags(UMODE_ALL, L_ALL,
146 <        "%s!%s@%s set new MAXCLIENTS to %d (%d current)",
147 <        source_p->name, source_p->username, source_p->host,
322 <        ServerInfo.max_clients, Count.local);
145 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
146 >        "%s set new MAXCLIENTS to %d (%d current)",
147 >        get_oper_name(source_p), ServerInfo.max_clients, Count.local);
148    }
149    else
150 <    sendto_one(source_p, ":%s NOTICE %s :Current MAXCLIENTS = %d (%d)",
151 <               me.name, source_p->name, ServerInfo.max_clients, Count.local);
327 < }
328 <
329 < /* SET MSGLOCALE */
330 < static void
331 < quote_msglocale( struct Client *source_p, char *locale )
332 < {
333 <  if (locale != NULL)
334 <  {
335 <    set_locale(locale);
336 <    rebuild_isupport_message_line();
337 <    sendto_one(source_p, ":%s NOTICE %s :Set MSGLOCALE to '%s'",
338 <               me.name, source_p->name, get_locale());
339 <  }
340 <  else
341 <    sendto_one(source_p, ":%s NOTICE %s :MSGLOCALE is currently '%s'",
342 <               me.name, source_p->name, get_locale());
150 >    sendto_one_notice(source_p, &me, ":Current MAXCLIENTS = %d (%d)",
151 >                      ServerInfo.max_clients, Count.local);
152   }
153  
154   /* SET SPAMNUM */
155   static void
156 < quote_spamnum( struct Client *source_p, int newval )
156 > quote_spamnum(struct Client *source_p, const char *arg, int newval)
157   {
158    if (newval >= 0)
159    {
160      if (newval == 0)
161      {
162 <      sendto_realops_flags(UMODE_ALL, L_ALL,
162 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
163                             "%s has disabled ANTI_SPAMBOT", source_p->name);
164        GlobalSetOptions.spam_num = newval;
165        return;
166      }
167  
168      GlobalSetOptions.spam_num = IRCD_MAX(newval, MIN_SPAM_NUM);
169 <
170 <    sendto_realops_flags(UMODE_ALL, L_ALL,"%s has changed SPAMNUM to %i",
171 <                source_p->name, GlobalSetOptions.spam_num);
169 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
170 >                         "%s has changed SPAMNUM to %i",
171 >                         get_oper_name(source_p), GlobalSetOptions.spam_num);
172    }
173    else
174 <    sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i",
175 <                me.name,
367 <                source_p->name, GlobalSetOptions.spam_num);
174 >    sendto_one_notice(source_p, &me, ":SPAMNUM is currently %i",
175 >                      GlobalSetOptions.spam_num);
176   }
177  
178   /* SET SPAMTIME */
179   static void
180 < quote_spamtime( struct Client *source_p, int newval )
180 > quote_spamtime(struct Client *source_p, const char *arg, int newval)
181   {
182    if (newval > 0)
183    {
184      GlobalSetOptions.spam_time = IRCD_MAX(newval, MIN_SPAM_TIME);
185 <    sendto_realops_flags(UMODE_ALL, L_ALL, "%s has changed SPAMTIME to %i",
186 <                source_p->name, GlobalSetOptions.spam_time);
185 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
186 >                         "%s has changed SPAMTIME to %i",
187 >                         get_oper_name(source_p), GlobalSetOptions.spam_time);
188    }
189    else
190 <    sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i",
191 <                me.name,
383 <                source_p->name, GlobalSetOptions.spam_time);
190 >    sendto_one_notice(source_p, &me, ":SPAMTIME is currently %i",
191 >                      GlobalSetOptions.spam_time);
192   }
193  
194   /* this table is what splitmode may be set to */
# Line 404 | Line 212 | static const char *splitmode_status[] =
212  
213   /* SET SPLITMODE */
214   static void
215 < quote_splitmode(struct Client *source_p, char *charval)
215 > quote_splitmode(struct Client *source_p, const char *charval, int val)
216   {
217    if (charval)
218    {
219      int newval;
220  
221 <    for (newval = 0; splitmode_values[newval]; newval++)
222 <    {
415 <      if (irccmp(splitmode_values[newval], charval) == 0)
221 >    for (newval = 0; splitmode_values[newval]; ++newval)
222 >      if (!irccmp(splitmode_values[newval], charval))
223          break;
417    }
224  
225      /* OFF */
226      if (newval == 0)
227      {
228 <      sendto_realops_flags(UMODE_ALL, L_ALL,
228 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
229                             "%s is disabling splitmode",
230                             get_oper_name(source_p));
231  
232        splitmode = 0;
233        splitchecking = 0;
234  
235 <      eventDelete(check_splitmode, NULL);
235 >      event_delete(&splitmode_event);
236      }
237      /* ON */
238      else if (newval == 1)
239      {
240 <      sendto_realops_flags(UMODE_ALL, L_ALL,
240 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
241                             "%s is enabling and activating splitmode",
242 <                           get_oper_name(source_p));
243 <                
242 >                           get_oper_name(source_p));
243 >
244        splitmode = 1;
245        splitchecking = 0;
246  
247        /* we might be deactivating an automatic splitmode, so pull the event */
248 <      eventDelete(check_splitmode, NULL);
248 >      event_delete(&splitmode_event);
249      }
250      /* AUTO */
251      else if (newval == 2)
252      {
253 <      sendto_realops_flags(UMODE_ALL, L_ALL,
253 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
254                             "%s is enabling automatic splitmode",
255 <                           get_oper_name(source_p));
255 >                           get_oper_name(source_p));
256  
257        splitchecking = 1;
258        check_splitmode(NULL);
259      }
260    }
261    else
262 <    /* if we add splitchecking to splitmode*2 we get a unique table to
262 >    /* if we add splitchecking to splitmode*2 we get a unique table to
263       * pull values back out of, splitmode can be four states - but you can
264       * only set to three, which means we cant use the same table --fl_
265       */
266 <    sendto_one(source_p, ":%s NOTICE %s :SPLITMODE is currently %s",
267 <               me.name, source_p->name,
462 <               splitmode_status[(splitchecking + (splitmode*2))]);
266 >    sendto_one_notice(source_p, &me, ":SPLITMODE is currently %s",
267 >                      splitmode_status[(splitchecking + (splitmode * 2))]);
268   }
269  
270   /* SET SPLITNUM */
271   static void
272 < quote_splitnum(struct Client *source_p, int newval)
272 > quote_splitnum(struct Client *source_p, const char *arg, int newval)
273   {
274    if (newval >= 0)
275    {
276 <    sendto_realops_flags(UMODE_ALL, L_ALL,
277 <                         "%s has changed SPLITNUM to %i",
278 <                         source_p->name, newval);
276 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
277 >                         "%s has changed SPLITNUM to %i",
278 >                         get_oper_name(source_p), newval);
279      split_servers = newval;
280  
281      if (splitchecking)
282        check_splitmode(NULL);
283    }
284    else
285 <    sendto_one(source_p, ":%s NOTICE %s :SPLITNUM is currently %i",
286 <               me.name, source_p->name, split_servers);
285 >    sendto_one_notice(source_p, &me, ":SPLITNUM is currently %i",
286 >                      split_servers);
287   }
288  
289   /* SET SPLITUSERS */
290   static void
291 < quote_splitusers(struct Client *source_p, int newval)
291 > quote_splitusers(struct Client *source_p, const char *arg, int newval)
292   {
293    if (newval >= 0)
294    {
295 <    sendto_realops_flags(UMODE_ALL, L_ALL,
296 <                         "%s has changed SPLITUSERS to %i",
297 <                         source_p->name, newval);
295 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
296 >                         "%s has changed SPLITUSERS to %i",
297 >                         get_oper_name(source_p), newval);
298      split_users = newval;
299  
300      if (splitchecking)
301        check_splitmode(NULL);
302    }
303    else
304 <    sendto_one(source_p, ":%s NOTICE %s :SPLITUSERS is currently %i",
305 <               me.name, source_p->name, split_users);
304 >    sendto_one_notice(source_p, &me, ":SPLITUSERS is currently %i",
305 >                      split_users);
306   }
307  
308   /* SET JFLOODTIME */
309   static void
310 < quote_jfloodtime(struct Client *source_p, int newval)
310 > quote_jfloodtime(struct Client *source_p, const char *arg, int newval)
311   {
312    if (newval >= 0)
313    {
314 <    sendto_realops_flags(UMODE_ALL, L_ALL,
315 <                         "%s has changed JFLOODTIME to %i",
316 <                         source_p->name, newval);
314 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
315 >                         "%s has changed JFLOODTIME to %i",
316 >                         get_oper_name(source_p), newval);
317      GlobalSetOptions.joinfloodtime = newval;
318    }
319    else
320 <    sendto_one(source_p, ":%s NOTICE %s :JFLOODTIME is currently %i",
321 <               me.name, source_p->name, GlobalSetOptions.joinfloodtime);
320 >    sendto_one_notice(source_p, &me, ":JFLOODTIME is currently %i",
321 >                      GlobalSetOptions.joinfloodtime);
322   }
323  
324   /* SET JFLOODCOUNT */
325   static void
326 < quote_jfloodcount(struct Client *source_p, int newval)
326 > quote_jfloodcount(struct Client *source_p, const char *arg, int newval)
327   {
328    if (newval >= 0)
329    {
330 <    sendto_realops_flags(UMODE_ALL, L_ALL,
331 <                         "%s has changed JFLOODCOUNT to %i",
332 <                         source_p->name, newval);
330 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
331 >                         "%s has changed JFLOODCOUNT to %i",
332 >                         get_oper_name(source_p), newval);
333      GlobalSetOptions.joinfloodcount = newval;
334    }
335    else
336 <    sendto_one(source_p, ":%s NOTICE %s :JFLOODCOUNT is currently %i",
337 <               me.name, source_p->name, GlobalSetOptions.joinfloodcount);
336 >    sendto_one_notice(source_p, &me, ":JFLOODCOUNT is currently %i",
337 >                      GlobalSetOptions.joinfloodcount);
338   }
339  
340 < /* SET REJECTTIME */
340 > /* Structure used for the SET table itself */
341 > struct SetStruct
342 > {
343 >  const char *name;
344 >  void (*handler)(struct Client *, const char *, int);
345 >  const unsigned int wants_char;  /* 1 if it expects (char *, [int]) */
346 >  const unsigned int wants_int;  /* 1 if it expects ([char *], int) */
347 >  /* eg:  0, 1 == only an int arg
348 >   * eg:  1, 1 == char and int args */
349 > };
350 >
351 > /*
352 > * If this ever needs to be expanded to more than one arg of each
353 > * type, want_char/want_int could be the count of the arguments,
354 > * instead of just a boolean flag...
355 > *
356 > * -davidt
357 > */
358 > static const struct SetStruct set_cmd_table[] =
359 > {
360 >  /* name               function        string arg  int arg */
361 >  /* -------------------------------------------------------- */
362 >  { "AUTOCONN",         quote_autoconn,         1,      1 },
363 >  { "AUTOCONNALL",      quote_autoconnall,      0,      1 },
364 >  { "FLOODCOUNT",       quote_floodcount,       0,      1 },
365 >  { "IDENTTIMEOUT",     quote_identtimeout,     0,      1 },
366 >  { "MAX",              quote_max,              0,      1 },
367 >  { "SPAMNUM",          quote_spamnum,          0,      1 },
368 >  { "SPAMTIME",         quote_spamtime,         0,      1 },
369 >  { "SPLITMODE",        quote_splitmode,        1,      0 },
370 >  { "SPLITNUM",         quote_splitnum,         0,      1 },
371 >  { "SPLITUSERS",       quote_splitusers,       0,      1 },
372 >  { "JFLOODTIME",       quote_jfloodtime,       0,      1 },
373 >  { "JFLOODCOUNT",      quote_jfloodcount,      0,      1 },
374 >  /* -------------------------------------------------------- */
375 >  { NULL,               NULL,                   0,      0 }
376 > };
377 >
378 > /*
379 > * list_quote_commands() sends the client all the available commands.
380 > * Four to a line for now.
381 > */
382   static void
383 < quote_rejecttime(struct Client *source_p, int newval)
383 > list_quote_commands(struct Client *source_p)
384   {
385 <  if (newval >= 0)
385 >  unsigned int j = 0;
386 >  const char *names[4] = { "", "", "", "" };
387 >
388 >  sendto_one_notice(source_p, &me, ":Available QUOTE SET commands:");
389 >
390 >  for (const struct SetStruct *tab = set_cmd_table; tab->handler; ++tab)
391    {
392 <    sendto_realops_flags(UMODE_ALL, L_ALL,
393 <                         "%s has changed REJECTTIME to %i seconds",
394 <                         source_p->name, newval);
395 <    GlobalSetOptions.rejecttime = newval;
392 >    names[j++] = tab->name;
393 >
394 >    if (j > 3)
395 >    {
396 >      sendto_one_notice(source_p, &me, ":%s %s %s %s",
397 >                        names[0], names[1],
398 >                        names[2], names[3]);
399 >      j = 0;
400 >      names[0] = names[1] = names[2] = names[3] = "";
401 >    }
402    }
403 <  else
404 <    sendto_one(source_p, ":%s NOTICE %s :REJECTTIME is currently %i seconds",
405 <               me.name, source_p->name, GlobalSetOptions.rejecttime);
403 >
404 >  if (j)
405 >    sendto_one_notice(source_p, &me, ":%s %s %s %s",
406 >                      names[0], names[1],
407 >                      names[2], names[3]);
408   }
409  
410   /*
411   * mo_set - SET command handler
412   * set options while running
413   */
414 < static void
415 < mo_set(struct Client *client_p, struct Client *source_p,
557 <       int parc, char *parv[])
414 > static int
415 > mo_set(struct Client *source_p, int parc, char *parv[])
416   {
559  int i;
417    int n;
418    int newval;
419 <  const char *arg    = NULL;
419 >  const char *strarg = NULL;
420    const char *intarg = NULL;
421  
422 +  if (!HasOFlag(source_p, OPER_FLAG_SET))
423 +  {
424 +    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "set");
425 +    return 0;
426 +  }
427 +
428    if (parc > 1)
429    {
430 <    /* Go through all the commands in set_cmd_table, until one is
431 <     * matched.  I realize strcmp() is more intensive than a numeric
432 <     * lookup, but at least it's better than a big-ass switch/case
570 <     * statement.
430 >    /*
431 >     * Go through all the commands in set_cmd_table, until one is
432 >     * matched.
433       */
434 <    for (i = 0; set_cmd_table[i].handler; i++)
434 >    for (const struct SetStruct *tab = set_cmd_table; tab->handler; ++tab)
435      {
436 <      if (irccmp(set_cmd_table[i].name, parv[1]) == 0)
437 <      {
576 <        /*
577 <         * Command found; now execute the code
578 <         */
579 <        n = 2;
436 >      if (irccmp(tab->name, parv[1]))
437 >        continue;
438  
439 <        if (set_cmd_table[i].wants_char)
440 <        {
441 <          arg = parv[n++];
442 <        }
439 >      /*
440 >       * Command found; now execute the code
441 >       */
442 >      n = 2;
443  
444 <        if (set_cmd_table[i].wants_int)
445 <        {
588 <          intarg = parv[n++];
589 <        }
444 >      if (tab->wants_char)
445 >        strarg = parv[n++];
446  
447 <        if ((n - 1) > parc)
448 <        {
593 <          if (parc > 2)
594 <            sendto_one(source_p,
595 <                       ":%s NOTICE %s :SET %s expects (\"%s%s\") args",
596 <                       me.name, source_p->name, set_cmd_table[i].name,
597 <                       (set_cmd_table[i].wants_char ? "string, " : ""),
598 <                       (set_cmd_table[i].wants_char ? "int" : "")
599 <                      );
600 <        }
447 >      if (tab->wants_int)
448 >        intarg = parv[n++];
449  
450 <        if (parc <= 2)
451 <        {
452 <          arg = NULL;
453 <          intarg = NULL;
606 <        }
450 >      if ((n - 1) > parc)
451 >        sendto_one_notice(source_p, &me, ":SET %s expects (\"%s%s\") args", tab->name,
452 >                          (tab->wants_char ? "string, " : ""),
453 >                          (tab->wants_int ? "int" : ""));
454  
455 <        if (!strcmp(set_cmd_table[i].name, "AUTOCONN") && (parc < 4))
456 <        {
457 <          sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
458 <                     me.name, source_p->name, "SET");
459 <          return;
613 <        }
455 >      if (parc <= 2)
456 >      {
457 >        strarg = NULL;
458 >        intarg = NULL;
459 >      }
460  
461 <        if (set_cmd_table[i].wants_int && (parc > 2))
461 >      if (tab->wants_int && parc > 2)
462 >      {
463 >        if (intarg)
464          {
465 <          if (intarg)
466 <          {
467 <            if (irccmp(intarg, "yes") == 0 || irccmp(intarg, "on") == 0)
468 <              newval = 1;
621 <            else if (irccmp(intarg, "no") == 0|| irccmp(intarg, "off") == 0)
622 <              newval = 0;
623 <            else
624 <              newval = atoi(intarg);
625 <          }
465 >          if (!irccmp(intarg, "yes") || !irccmp(intarg, "on"))
466 >            newval = 1;
467 >          else if (!irccmp(intarg, "no") || !irccmp(intarg, "off"))
468 >            newval = 0;
469            else
470 <          {
628 <            newval = -1;
629 <          }
630 <
631 <          if (newval < 0)
632 <          {
633 <            sendto_one(source_p,
634 <                       ":%s NOTICE %s :Value less than 0 illegal for %s",
635 <                       me.name, source_p->name,
636 <                       set_cmd_table[i].name);
637 <
638 <            return;
639 <          }
470 >            newval = atoi(intarg);
471          }
472          else
473            newval = -1;
474  
475 <        if (set_cmd_table[i].wants_char)
645 <        {
646 <          if (set_cmd_table[i].wants_int)
647 <            set_cmd_table[i].handler(source_p, arg, newval);
648 <          else
649 <            set_cmd_table[i].handler(source_p, arg);
650 <          return;
651 <        }
652 <        else
475 >        if (newval < 0)
476          {
477 <          if (set_cmd_table[i].wants_int)
478 <            set_cmd_table[i].handler(source_p, newval);
479 <          else
657 <            /* Just in case someone actually wants a
658 <             * set function that takes no args.. *shrug* */
659 <            set_cmd_table[i].handler(source_p);
660 <          return;
477 >          sendto_one_notice(source_p, &me, ":Value less than 0 illegal for %s",
478 >                            tab->name);
479 >          return 0;
480          }
481        }
482 +      else
483 +        newval = -1;
484 +
485 +      tab->handler(source_p, strarg, newval);
486 +      return 0;
487      }
488  
489      /*
490       * Code here will be executed when a /QUOTE SET command is not
491       * found within set_cmd_table.
492       */
493 <    sendto_one(source_p, ":%s NOTICE %s :Variable not found.",
494 <               me.name, source_p->name);
671 <    return;
493 >    sendto_one_notice(source_p, &me, ":Variable not found.");
494 >    return 0;
495    }
496  
497    list_quote_commands(source_p);
498 +  return 0;
499   }
500  
501 + static struct Message set_msgtab =
502 + {
503 +  "SET", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
504 +  { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_set, m_ignore }
505 + };
506 +
507 + static void
508 + module_init(void)
509 + {
510 +  mod_add_cmd(&set_msgtab);
511 + }
512 +
513 + static void
514 + module_exit(void)
515 + {
516 +  mod_del_cmd(&set_msgtab);
517 + }
518 +
519 + struct module module_entry =
520 + {
521 +  .node    = { NULL, NULL, NULL },
522 +  .name    = NULL,
523 +  .version = "$Revision$",
524 +  .handle  = NULL,
525 +  .modinit = module_init,
526 +  .modexit = module_exit,
527 +  .flags   = 0
528 + };

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)