Просмотр исходного кода

* Rewrote config/botconfig from scratch as [bot]set with list support. See 'help set'.

svn: 2152
Bryan Drewery 21 лет назад
Родитель
Сommit
c94eeddd8d

+ 2 - 2
doc/UPDATES

@@ -16,6 +16,7 @@ Lines prefixed with '-' were disabled before release and are not finished, or ar
 
 
 1.2.3
 1.2.3
 * HUB/LEAF binaries have been combined into 1 binary named 'wraith'
 * HUB/LEAF binaries have been combined into 1 binary named 'wraith'
+* Rewrote config/botconfig from scratch as [bot]set with list support. See 'help set'.
 * Read in '.resolv.conf' before '/etc/resolv.conf'
 * Read in '.resolv.conf' before '/etc/resolv.conf'
 * Fixed binary getting an excess of 1-15 bytes during write. 
 * Fixed binary getting an excess of 1-15 bytes during write. 
 * Binary writing is now a bit faster as the hash is calculated on the fly now.
 * Binary writing is now a bit faster as the hash is calculated on the fly now.
@@ -31,7 +32,6 @@ Lines prefixed with '-' were disabled before release and are not finished, or ar
 * Using a cmd with a cmdpass without proper flags now acts as if cmd is not valid (no longer spams wrong pass error)
 * Using a cmd with a cmdpass without proper flags now acts as if cmd is not valid (no longer spams wrong pass error)
 * cmd_deluser change: only allow a |m user to remove users whom they have added.
 * cmd_deluser change: only allow a |m user to remove users whom they have added.
 * Fixed some botnet userfile sharing logs showing up on leaf bots.
 * Fixed some botnet userfile sharing logs showing up on leaf bots.
-* cmd_botconfig now supports wildcards for the bot parameter
 * Eliminated a duplicate struct (conffile)
 * Eliminated a duplicate struct (conffile)
 * Removed chanset cookie-time-slack
 * Removed chanset cookie-time-slack
 * Fixed a memory leak in dns
 * Fixed a memory leak in dns
@@ -42,6 +42,7 @@ Lines prefixed with '-' were disabled before release and are not finished, or ar
 * Fixed some bad passes being generated/set beginning with -/+
 * Fixed some bad passes being generated/set beginning with -/+
 * Fixed binary exiting with ERR_NOBOTS under conditions that it shouldn't. (updating)
 * Fixed binary exiting with ERR_NOBOTS under conditions that it shouldn't. (updating)
 * Fixed bots not rechecking channel for invalid users after a .-chrec
 * Fixed bots not rechecking channel for invalid users after a .-chrec
+* Fixed dccauth not correctly working according to it's setting (#30)
 * Users who are v|o in a +private chan are now voiced, as before |v was needed.
 * Users who are v|o in a +private chan are now voiced, as before |v was needed.
 * Added channel flag +|-botbitch, when set only bots will be allowed to be opped, users are auto-deopped.
 * Added channel flag +|-botbitch, when set only bots will be allowed to be opped, users are auto-deopped.
 * chanset -bitch/-private/-botbitch/+botbitch/+closed/+private will now trigger bots to recheck channel (op/deop/kick people)
 * chanset -bitch/-private/-botbitch/+botbitch/+closed/+private will now trigger bots to recheck channel (op/deop/kick people)
@@ -91,7 +92,6 @@ Lines prefixed with '-' were disabled before release and are not finished, or ar
    -New bots are spawned and added (if linked)
    -New bots are spawned and added (if linked)
    -Changed (NEW) ip/host for bots are added to the botnet (if linked)
    -Changed (NEW) ip/host for bots are added to the botnet (if linked)
    -Removed bots are killed and removed from the userlist (if linked)
    -Removed bots are killed and removed from the userlist (if linked)
-* Fixed dccauth not correctly working according to it's [bot]config setting (#30)
 * Added match option for cmd_botcmd: '&' will match on all localhubs (first bot in config) (#28)
 * Added match option for cmd_botcmd: '&' will match on all localhubs (first bot in config) (#28)
 * Added some debug logging when a telnet connection is ignored.
 * Added some debug logging when a telnet connection is ignored.
 * Fixed some missing sanity checking on certain user flags for channel records.
 * Fixed some missing sanity checking on certain user flags for channel records.

+ 82 - 16
misc/help.txt

@@ -251,16 +251,6 @@ See also: -ban, +ban, console%{+m|m}, chanset, chaninfo%{-}, stick, unstick
    Just using '&' for 'bot' will do the cmd on all localhub bots. (first bot in config).
    Just using '&' for 'bot' will do the cmd on all localhub bots. (first bot in config).
  
  
 See also: bc, cmdpass
 See also: bc, cmdpass
-:hub:botconfig:
-###  $bbotconfig$b <bot> [name [value|-]]
-   Set's a bot specific entry.
-   <bot> may contain wildcards.
-   NOTE: 'config' and 'botconfig' have different entries. 
-   If there is a botconfig entry for 'name' and a config entry for 'name', 
-   the bot will use the 'botconfig' entry. Otherwise, the 'config' entry
-   will be used for all options.
- 
-See also: config
 ::botjoin
 ::botjoin
 ###  $bbotjoin$b <bot> <channel> [options]
 ###  $bbotjoin$b <bot> <channel> [options]
     Adds a channel to the bot's channel list. If options are specified, the 
     Adds a channel to the bot's channel list. If options are specified, the 
@@ -310,6 +300,18 @@ See also: downbots%{+n}, bottree%{-}
    The bot will display it's current server and lag over DCC.
    The bot will display it's current server and lag over DCC.
  
  
 See also: netserver, servers%{+n}, config%{-}
 See also: netserver, servers%{+n}, config%{-}
+:hub:botset:
+###  $bbotset$b <bot> [<+/->list] [<var> [data|-]]
+   Set's a bot specific entry.
+   <bot> may contain wildcards.
+   NOTE: 'set' and 'botset' have different entries. 
+   If there is a botset entry for 'name' and a set entry for 'name', 
+   the bot will use the 'botset' entry. Otherwise, the 'set' entry
+   will be used for all options.
+ 
+   See 'set' for a full help listing.
+ 
+See also: set
 :hub:bottree
 :hub:bottree
 ###  $bbottree$b
 ###  $bbottree$b
    Shows a tree-format diagram of the bots currently on the botnet. It's just a
    Shows a tree-format diagram of the bots currently on the botnet. It's just a
@@ -713,12 +715,6 @@ See also: console, echo, login, page, strip
     $bhomedir$b, $bbinpath$b, $bbinname$b, $bportmin$b, $bportmax$b, $bpscloak$b
     $bhomedir$b, $bbinpath$b, $bbinname$b, $bportmin$b, $bportmax$b, $bpscloak$b
  
  
 See also: newleaf
 See also: newleaf
-:hub:config:
-###  $bconfig$b [name [value|-]]
-   Sets various config options. Type alone to see all config entries. To set
-   an entry do 'config name VALUE'. Use '-' as a value to clear an entry.
- 
-See also: botconfig
 ::console:
 ::console:
 ###  $bconsole$b [channel] [modes]
 ###  $bconsole$b [channel] [modes]
    Changes your console level so that you will see only the types of console
    Changes your console level so that you will see only the types of console
@@ -1468,6 +1464,76 @@ See also: reload, backup
    bot is booted up.  after that, you can add servers with the
    bot is booted up.  after that, you can add servers with the
    $b'%djump'$b command.  the server list will indicate which server the
    $b'%djump'$b command.  the server list will indicate which server the
    bot is currently on.
    bot is currently on.
+:hub:set:
+###  $bset$b [<+/->list] [<var> [data|-]]
+   Sets various options. Type alone to see all set entries. To set
+   an entry do '%dset name VALUE'. Use '-' as a value to clear an entry.
+ 
+   The '+' may be used to add 1 element to a comma separated list. (ie, servers)
+   The '-' may be used to remove 1 element from a comma separated list. (ie, servers)
+   The 'list' may be used to list a comma separated variable as a vertical listing. (like %dservers)
+ 
+ 
+   Current variables:
+ 
+   $uB$u:    Boolean (0 or 1)
+   $uS$u:    String
+   $uN$u:    Number
+   $uL$u:    List capable
+   $uR$u:    Rate. Set as 'number:interval', ie, '1:5'
+   $uD$u:    Detected vars have the folloing options: $bignore$b/0, $bwarn$b/1, $bdie$b/2, 
+                                                      $breject$b/3, $bsuicide$b/4
+ 
+[S]  $bchanset$b         List of default options for when a channel is added. Same format 
+                          as 'chanset'.
+[N]  $bserver-port$b     Default port to use for server connections.
+[S]  $bauth-key$b        The authkey used during authing.G ive to users if they need to auth. 
+                          (can be bot specific)
+[C]  $bauth-prefix$b     The prefix character used for msg cmds, ie: $u!$uop or $u.$uop
+ 
+  *  Msg cmd vars may be left blank to disable usage of cmd.
+[S]  $bmsgop$b           Defines the cmd for opping via msging the bot.
+[S]  $bmsgpass$b         Defines the cmd for setting a pass via msging the bot.
+[S]  $bmsginvite$b       Defines the cmd for requesting invite via msging the bot.
+[S]  $bmsgident$b        Defines the cmd for identing via msging the bot.
+ 
+[N]  $bfork-interval$b   Number of seconds in between each fork() call made by the bot. 
+                          (Resets PID/CPU)
+ 
+[D]  $blogin$b           How to handle someone logging in to the shell.
+[D]  $btrace$b           How to handle someone tracing/debugging the bot.
+[D]  $bpromisc$b         How to handle when a interface is set to promiscuous mode.
+[D]  $bbad-process$b     How to handle when a running process not listed in process-list 
+                         is detected.
+[SL] $bprocess-list$b    Comma-separated list of "expected processes" running on the bots uid.
+[D]  $bhijack$b          How to handle when a commonly used hijack method attempt is detected. 
+ 
+[SL] $bservers$b         Comma-separated list of servers the bot will use.
+[SL] $bservers6$b        Comma-separated list of servers the bot will use (FOR IPv6).
+ 
+[S]  $brealname$b        The bot's "real name" when connecting.
+[S]  $bnick$b            The bot's preferred nickname on IRC.
+ 
+[B]  $bdccauth$b         Boolean (0 or 1). Set to use auth checking on dcc/telnet login.
+[N]  $bop-bots$b         Number of bots to ask every time a oprequest is to be made.
+[N]  $bin-bots$b         Number of bots to ask every time a inrequest is to be made.
+ 
+[R]  $bop-requests$b     (requests:seconds) limits how often the bot will ask for ops.
+[R]  $bclose-threshold$b (H:L) When at least H hubs but L or less leafs are linked, close 
+                          all channels.
+ 
+[N]  $blag-threshold$b   Maximum acceptable server lag for the bot to send/honor requests.
+[N]  $bkill-threshold$b  When more than this many bots have been killed/klined in the last
+                          minute, close all channels.
+[N]  $bfight-threshold$b When more than this many +ob/-ob/kicks have happened on a channel in 
+                          1 minute, the channel is closed.
+ 
+[N]  $bcloak-script$b    Decides which script the bot cloaks as. 
+                          If set to 0, a random script will be used.
+                          1=plain bitchx, 2=crackrock, 3=neonapple, 4=tunnelvision, 
+                          5=argon, 6=evolver, 7=prevail 8=cypress 9=mIRC
+ 
+See also: botset
 ::sha1
 ::sha1
 ###  $bsha1$b <string>
 ###  $bsha1$b <string>
    Returns the SHA1 hash of the specified string.
    Returns the SHA1 hash of the specified string.

+ 1 - 1
src/Makefile.in

@@ -22,7 +22,6 @@ OBJS = auth.o \
 	botnet.o \
 	botnet.o \
 	chanprog.o \
 	chanprog.o \
 	cmds.o \
 	cmds.o \
-	cfg.o \
 	core_binds.o \
 	core_binds.o \
 	conf.o \
 	conf.o \
 	crypt.o \
 	crypt.o \
@@ -44,6 +43,7 @@ OBJS = auth.o \
 	profile.o \
 	profile.o \
 	response.o \
 	response.o \
 	rfc1459.o \
 	rfc1459.o \
+	set.o \
 	shell.o \
 	shell.o \
 	socket.o \
 	socket.o \
 	sprintf.o \
 	sprintf.o \

+ 2 - 1
src/auth.c

@@ -12,6 +12,7 @@
 #include "settings.h"
 #include "settings.h"
 #include "types.h"
 #include "types.h"
 #include "userrec.h"
 #include "userrec.h"
+#include "set.h"
 #include "core_binds.h"
 #include "core_binds.h"
 #include "egg_timer.h"
 #include "egg_timer.h"
 #include "users.h"
 #include "users.h"
@@ -267,7 +268,7 @@ void makehash(struct userrec *u, const char *randstring, char *out, size_t out_s
     secpass = strdup((char *) get_user(&USERENTRY_SECPASS, u));
     secpass = strdup((char *) get_user(&USERENTRY_SECPASS, u));
     secpass[strlen(secpass)] = 0;
     secpass[strlen(secpass)] = 0;
   }
   }
-  simple_snprintf(hash, sizeof hash, "%s%s%s", randstring, (secpass && secpass[0]) ? secpass : "", authkey);
+  simple_snprintf(hash, sizeof hash, "%s%s%s", randstring, (secpass && secpass[0]) ? secpass : "", auth_key);
   if (secpass)
   if (secpass)
     free(secpass);
     free(secpass);
 
 

+ 0 - 3
src/auth.h

@@ -1,7 +1,6 @@
 #ifndef _AUTH_H
 #ifndef _AUTH_H
 #  define _AUTH_H
 #  define _AUTH_H
 
 
-#  include "cfg.h"
 #  include "crypt.h"
 #  include "crypt.h"
 #  include "hash_table.h"
 #  include "hash_table.h"
 
 
@@ -54,6 +53,4 @@ void makehash(struct userrec *u, const char *randstring, char *out, size_t out_s
 
 
 void check_auth_dcc(Auth *, const char *, const char *);
 void check_auth_dcc(Auth *, const char *, const char *);
 
 
-#  define authkey CFG_AUTHKEY.ldata ? CFG_AUTHKEY.ldata : CFG_AUTHKEY.gdata ? CFG_AUTHKEY.gdata : ""
-
 #endif /* !_AUTH_H */
 #endif /* !_AUTH_H */

+ 10 - 7
src/botcmd.c

@@ -17,7 +17,6 @@
 #include "misc.h"
 #include "misc.h"
 #include "dcc.h"
 #include "dcc.h"
 #include "userrec.h"
 #include "userrec.h"
-#include "cfg.h"
 #include "dccutil.h"
 #include "dccutil.h"
 #include "cmds.h"
 #include "cmds.h"
 #include "chanprog.h"
 #include "chanprog.h"
@@ -106,14 +105,14 @@ void bot_cmdpass(int idx, char *par)
   set_cmd_pass(par, 0);
   set_cmd_pass(par, 0);
 }
 }
 
 
-void bot_config(int idx, char *par)
+void bot_set(int idx, char *par)
 {
 {
-  got_config_share(idx, par, 0);
+  var_userfile_share_line(par, idx, 0);
 }
 }
 
 
-void bot_configbroad(int idx, char *par)
+void bot_setbroad(int idx, char *par)
 {
 {
-  got_config_share(idx, par, 1);
+  var_userfile_share_line(par, idx, 1);
 }
 }
 
 
 void bot_remotecmd(int idx, char *par) {
 void bot_remotecmd(int idx, char *par) {
@@ -1154,8 +1153,10 @@ botcmd_t C_bot[] =
   {"aw",		bot_away, 0},
   {"aw",		bot_away, 0},
   {"bye",		bot_bye, 0},
   {"bye",		bot_bye, 0},
   {"c",			bot_chan2, 0},
   {"c",			bot_chan2, 0},
-  {"cg",                bot_config, 0},
-  {"cgb",		bot_configbroad, 0},
+/* FIXME: remove after 1.2.3 */
+  {"cg",                bot_set, 0},
+/* FIXME: remove after 1.2.3 */
+  {"cgb",		bot_setbroad, 0},
   {"cp", 		bot_cmdpass, 0},
   {"cp", 		bot_cmdpass, 0},
   {"ct",		bot_chat, 0},
   {"ct",		bot_chat, 0},
   {"e",			bot_error, 0},
   {"e",			bot_error, 0},
@@ -1184,6 +1185,8 @@ botcmd_t C_bot[] =
   {"ul",		bot_unlink, 0},
   {"ul",		bot_unlink, 0},
   {"un",		bot_unlinked, 0},
   {"un",		bot_unlinked, 0},
   {"v",			bot_versions, 0},
   {"v",			bot_versions, 0},
+  {"va",                bot_set, 0},
+  {"vab",		bot_setbroad, 0},
   {"w",			bot_who, 0},
   {"w",			bot_who, 0},
   {"z",			bot_zapf, 0},
   {"z",			bot_zapf, 0},
   {"zb",		bot_zapfbroad, 0},
   {"zb",		bot_zapfbroad, 0},

+ 5 - 5
src/botmsg.c

@@ -13,9 +13,9 @@
 #include "dcc.h"
 #include "dcc.h"
 #include "userrec.h"
 #include "userrec.h"
 #include "main.h"
 #include "main.h"
+#include "set.h"
 #include "net.h"
 #include "net.h"
 #include "users.h"
 #include "users.h"
-#include "cfg.h"
 #include "botmsg.h"
 #include "botmsg.h"
 #include "dccutil.h"
 #include "dccutil.h"
 #include "cmds.h"
 #include "cmds.h"
@@ -326,15 +326,15 @@ void botnet_send_zapf_broad(int idx, char *a, char *b, char *c)
   }
   }
 }
 }
 
 
-void botnet_send_cfg(int idx, struct cfg_entry * entry) {
-  size_t len = simple_snprintf(OBUF, sizeof(OBUF), "cg %s %s\n", entry->name, entry->gdata ? entry->gdata : "");
+void botnet_send_var(int idx, variable_t *var) {
+  size_t len = simple_snprintf(OBUF, sizeof(OBUF), "va %s %s\n", var->name, var->gdata ? var->gdata : "");
 
 
   tputs(dcc[idx].sock, OBUF, len);
   tputs(dcc[idx].sock, OBUF, len);
 }
 }
 
 
-void botnet_send_cfg_broad(int idx, struct cfg_entry * entry) {
+void botnet_send_var_broad(int idx, variable_t *var) {
   if (tands > 0) {
   if (tands > 0) {
-    size_t len = simple_snprintf(OBUF, sizeof(OBUF), "cgb %s %s\n", entry->name, entry->gdata ? entry->gdata : "");
+    size_t len = simple_snprintf(OBUF, sizeof(OBUF), "vab %s %s\n", var->name, var->gdata ? var->gdata : "");
 
 
     send_tand_but(idx, OBUF, len);
     send_tand_but(idx, OBUF, len);
   }
   }

+ 3 - 3
src/botmsg.h

@@ -2,7 +2,7 @@
 #define _BOTMSG_H
 #define _BOTMSG_H
 
 
 #include "common.h"
 #include "common.h"
-#include "cfg.h"
+#include "set.h"
 
 
 /* Return codes for add_note */
 /* Return codes for add_note */
 #define NOTE_ERROR      0       /* error                        */
 #define NOTE_ERROR      0       /* error                        */
@@ -13,8 +13,8 @@
 #define NOTE_AWAY       5       /* away; stored                 */
 #define NOTE_AWAY       5       /* away; stored                 */
 #define NOTE_FWD        6       /* away; forwarded              */
 #define NOTE_FWD        6       /* away; forwarded              */
 
 
-void botnet_send_cfg(int idx, struct cfg_entry *entry);
-void botnet_send_cfg_broad(int idx, struct cfg_entry *entry);
+void botnet_send_var(int idx, variable_t *);
+void botnet_send_var_broad(int idx, variable_t *);
 void putbot(char *, char *);
 void putbot(char *, char *);
 void putallbots(char *);
 void putallbots(char *);
 int add_note(char *, char *, char *, int, int);
 int add_note(char *, char *, char *, int, int);

+ 0 - 802
src/cfg.c

@@ -1,802 +0,0 @@
-/*
- * config.c -- handles:
- *   botnet config
- *   cmdpass functions
- */
-
-
-#include "common.h"
-#include "cfg.h"
-#include "cmds.h"
-#include "userrec.h"
-#include "auth.h"
-#include "misc.h"
-#include "users.h"
-#include "dccutil.h"
-#include "botmsg.h"
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include "chan.h"
-#include "tandem.h"
-#include "src/mod/channels.mod/channels.h"
-#include "src/mod/ctcp.mod/ctcp.h"
-#include "src/chanprog.h"
-#include "src/mod/server.mod/server.h"
-#include "botnet.h"
-#include <net/if.h>
-
-#include "stat.h"
-
-int 				cfg_count = 0;
-bool				cfg_noshare = 0;
-struct cfg_entry 		**cfg = NULL;
-char 				cmdprefix = '+';	/* This is the prefix for msg/channel cmds */
-struct cmd_pass 		*cmdpass = NULL;
-
-static void chanset_describe(struct cfg_entry * entry, int idx) {
-  dprintf(idx, STR("chanset is a list of default options for when a channel is added. Same format as .chanset.\n"));
-}
-
-static void chanset_changed(struct cfg_entry *entry, int *valid) {
-  if (entry->ldata)
-    strlcpy(cfg_glob_chanset, (char *) entry->ldata, 512);
-  else if (entry->gdata)
-    strlcpy(cfg_glob_chanset, (char *) entry->gdata, 512);
-}
-
-struct cfg_entry CFG_CHANSET = {
-	"chanset", CFGF_LOCAL | CFGF_GLOBAL | CFGF_LEAF, NULL, NULL, 
-	chanset_changed, chanset_changed, chanset_describe
-};
-
-static void servport_describe(struct cfg_entry * entry, int idx) {
-  dprintf(idx, STR("servport is the default port to use for server connections.\n"));
-}
-
-static void servport_changed(struct cfg_entry *entry, int *valid) {
-  if (entry->ldata)
-    default_port = atoi(entry->ldata);
-  else if (entry->gdata)
-    default_port = atoi(entry->gdata);
-}
-
-struct cfg_entry CFG_SERVPORT = {
-	"servport", CFGF_LOCAL | CFGF_GLOBAL | CFGF_LEAF, NULL, NULL, 
-	servport_changed, servport_changed, servport_describe
-};
-
-static void authkey_describe(struct cfg_entry *entry, int idx) {
-  dprintf(idx, 
-  STR("authkey is used for authing, give to your users if they are to use DCC chat or IRC cmds. (can be bot specific)\n"));
-}
-
-struct cfg_entry CFG_AUTHKEY = {
-	"authkey", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
-	NULL, NULL, authkey_describe
-};
-
-static void msgcmds_describe(struct cfg_entry *entry, int idx) {
-  if (entry == &CFG_MSGOP)
-    dprintf(idx, STR("msgop defines the cmd for opping via msging the bot (leave blank to disable)\n"));
-  else if (entry == &CFG_MSGPASS)
-    dprintf(idx, STR("msgpass defines the cmd for setting a pass via msging the bot (leave blank to disable)\n"));
-  else if (entry == &CFG_MSGINVITE)
-    dprintf(idx, STR("msginvite defines the cmd for requesting invite via msging the bot (leave blank to disable)\n"));
-  else if (entry == &CFG_MSGIDENT)
-    dprintf(idx, STR("msgident defines the cmd for identing via msging the bot (leave blank to disable)\n"));
-}
-
-struct cfg_entry CFG_MSGOP = {
-	"msgop", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
-	NULL, NULL, msgcmds_describe
-};
-
-struct cfg_entry CFG_MSGPASS = {
-	"msgpass", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
-	NULL, NULL, msgcmds_describe
-};
-
-struct cfg_entry CFG_MSGINVITE = {
-	"msginvite", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
-	NULL, NULL, msgcmds_describe
-};
-
-struct cfg_entry CFG_MSGIDENT = {
-	"msgident", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
-	NULL, NULL, msgcmds_describe
-};
-
-static void cmdprefix_describe(struct cfg_entry *entry, int idx) {
-  dprintf(idx, STR("cmdprefix is the prefix character used for msg cmds, ie: !op or .op\n"));
-}
-
-static void cmdprefix_changed(struct cfg_entry *entry, int *valid) {
-  if (entry->ldata)
-    cmdprefix = entry->ldata[0];
-  else if (entry->gdata)
-    cmdprefix = entry->gdata[0];
-}
-
-struct cfg_entry CFG_CMDPREFIX = {
-	"cmdprefix", CFGF_LOCAL | CFGF_GLOBAL | CFGF_LEAF, NULL, NULL,
-	cmdprefix_changed, cmdprefix_changed, cmdprefix_describe
-};
-
-int deflag_translate(const char *buf)
-{
-  int num = atoi(buf);
-
-  if (egg_isdigit(num))
-    return num;
-
-  if (!egg_strcasecmp(buf, "ignore"))
-    return P_IGNORE;
-  else if (!egg_strcasecmp(buf, "deop"))
-    return P_DEOP;
-  else if (!egg_strcasecmp(buf, "kick"))
-    return P_KICK;
-  else if (!egg_strcasecmp(buf, "delete") || !egg_strcasecmp(buf, "remove"))
-    return P_DELETE;  
-  return P_IGNORE;
-}
-
-void deflag_user(struct userrec *u, int why, char *msg, struct chanset_t *chan)
-{
-  if (!u)
-    return;
-
-  char tmp[256] = "", tmp2[1024] = "";
-  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
-  int which = 0;
-
-  switch (why) {
-  case DEFLAG_BADCOOKIE:
-    strcpy(tmp, "Bad op cookie");
-    which = chan->bad_cookie;
-    break;
-  case DEFLAG_MANUALOP:
-    strcpy(tmp, STR("Manual op in -manop channel"));
-    which = chan->manop;
-    break;
-#ifdef G_MEAN
-  case DEFLAG_MEAN_DEOP:
-    strcpy(tmp, STR("Deopped bot in +mean channel"));
-    ent = &CFG_MEANDEOP;
-    break;
-  case DEFLAG_MEAN_KICK:
-    strcpy(tmp, STR("Kicked bot in +mean channel"));
-    ent = &CFG_MEANDEOP;
-    break;
-  case DEFLAG_MEAN_BAN:
-    strcpy(tmp, STR("Banned bot in +mean channel"));
-    ent = &CFG_MEANDEOP;
-    break;
-#endif /* G_MEAN */
-  case DEFLAG_MDOP:
-    strcpy(tmp, "Mass deop");
-    which = chan->mdop;
-    break;
-  case DEFLAG_MOP:
-    strcpy(tmp, "Mass op");
-    which = chan->mop;
-    break;
-  default:
-    simple_sprintf(tmp, "Reason #%i", why);
-  }
-  if (which == P_DEOP) {
-    putlog(LOG_WARN, "*",  "Setting %s +d (%s): %s", u->handle, tmp, msg);
-    simple_sprintf(tmp2, "+d: %s (%s)", tmp, msg);
-    set_user(&USERENTRY_COMMENT, u, tmp2);
-    get_user_flagrec(u, &fr, chan->dname);
-    fr.global = USER_DEOP;
-    fr.chan = USER_DEOP;
-    set_user_flagrec(u, &fr, chan->dname);
-  } else if (which == P_KICK) {
-    putlog(LOG_WARN, "*",  "Setting %s +dk (%s): %s", u->handle, tmp, msg);
-    simple_sprintf(tmp2, "+dk: %s (%s)", tmp, msg);
-    set_user(&USERENTRY_COMMENT, u, tmp2);
-    get_user_flagrec(u, &fr, chan->dname);
-    fr.global = USER_DEOP | USER_KICK;
-    fr.chan = USER_DEOP | USER_KICK;
-    set_user_flagrec(u, &fr, chan->dname);
-  } else if (which == P_DELETE) {
-    putlog(LOG_WARN, "*",  "Deleting %s (%s): %s", u->handle, tmp, msg);
-    deluser(u->handle);
-  } else {
-    putlog(LOG_WARN, "*",  "No user flag effects for %s (%s): %s", u->handle, tmp, msg);
-    simple_sprintf(tmp2, "Warning: %s (%s)", tmp, msg);
-    set_user(&USERENTRY_COMMENT, u, tmp2);
-  }
-}
-
-static void misc_describe(struct cfg_entry *cfgent, int idx)
-{
-  int i = 0;
-
-  if (!strcmp(cfgent->name, "fork-interval")) {
-    dprintf(idx, STR("fork-interval is number of seconds in between each fork() call made by the bot, to change process ID and reset cpu usage counters.\n"));
-    i = 1;
-  } else if (!strcmp(cfgent->name, "login")) {
-    dprintf(idx, STR("login sets how to handle someone logging in to the shell\n"));
-  } else if (!strcmp(cfgent->name, "trace")) {
-    dprintf(idx, STR("trace sets how to handle someone tracing/debugging the bot\n"));
-  } else if (!strcmp(cfgent->name, "promisc")) {
-    dprintf(idx, STR("promisc sets how to handle when a interface is set to promiscuous mode\n"));
-  } else if (!strcmp(cfgent->name, "bad-process")) {
-    dprintf(idx, STR("bad-process sets how to handle when a running process not listed in process-list is detected\n"));
-  } else if (!strcmp(cfgent->name, "process-list")) {
-    dprintf(idx, STR("process-list is a comma-separated list of \"expected processes\" running on the bots uid\n"));
-    i = 1;
-  } else if (!strcmp(cfgent->name, "hijack")) {
-    dprintf(idx, STR("hijack sets how to handle when a commonly used hijack method attempt is detected. (recommended: die)\n"));
-  }
-  if (!i)
-    dprintf(idx, "Valid settings are: ignore, warn, die, reject, suicide\n");
-}
-
-static void fork_lchanged(struct cfg_entry * cfgent, int * valid) {
-  if (!cfgent->ldata)
-    return;
-  if (atoi(cfgent->ldata) <= 0)
-    *valid = 0;
-}
-
-static void fork_gchanged(struct cfg_entry * cfgent, int * valid) {
-  if (!cfgent->gdata)
-    return;
-  if (atoi(cfgent->gdata) <= 0)
-    *valid = 0;
-}
-
-static void fork_describe(struct cfg_entry * cfgent, int idx) {
-  dprintf(idx, STR("fork-interval is number of seconds in between each fork() call made by the bot, to change process ID and reset cpu usage counters.\n"));
-}
-
-struct cfg_entry CFG_FORKINTERVAL = {
-	"fork-interval", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	fork_gchanged, fork_lchanged, fork_describe
-};
-
-static void detect_lchanged(struct cfg_entry * cfgent, int * valid) {
-  char *p = NULL;
-
-  if (!(p = (char *) cfgent->ldata))
-    *valid = 1;
-  else if (strcmp(p, "ignore") && strcmp(p, "die") && strcmp(p, "reject") && strcmp(p, "suicide") && strcmp(p, "warn"))
-    *valid = 0;
-}
-
-static void detect_gchanged(struct cfg_entry * cfgent, int * valid) {
-  char *p = (char *) cfgent->ldata;
-  if (!p)
-    *valid=1;
-  else if (strcmp(p, "ignore") && strcmp(p, "die") && strcmp(p, "reject") && strcmp(p, "suicide") && strcmp(p, "warn"))
-    *valid=0;
-}
-
-struct cfg_entry CFG_LOGIN = {
-	"login", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	detect_gchanged, detect_lchanged, misc_describe
-};
-struct cfg_entry CFG_HIJACK = {
-	"hijack", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	detect_gchanged, detect_lchanged, misc_describe
-};
-struct cfg_entry CFG_TRACE = {
-	"trace", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	detect_gchanged, detect_lchanged, misc_describe
-};
-struct cfg_entry CFG_PROMISC = {
-	"promisc", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	detect_gchanged, detect_lchanged, misc_describe
-};
-struct cfg_entry CFG_BADPROCESS = {
-	"bad-process", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	detect_gchanged, detect_lchanged, misc_describe
-};
-
-struct cfg_entry CFG_PROCESSLIST = {
-	"process-list", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	NULL, NULL, misc_describe
-};
-
-static void servers_changed(struct cfg_entry * entry, int * valid) {
-  if (!strcmp(entry->name, "servers")) {
-    if (conf.bot->net.host6 || conf.bot->net.ip6) /* we want to use the servers6 entry. */
-      return;
-  } else if (!strcmp(entry->name, "servers6")) {
-    if (!conf.bot->net.host6 && !conf.bot->net.ip6) /* we probably want to use the normal server list.. */
-      return;
-  }
-
-  char *slist = NULL, *p = NULL;
-
-  slist = (char *) (entry->ldata ? entry->ldata : (entry->gdata ? entry->gdata : ""));
-  if (serverlist) {
-    clearq(serverlist);
-    serverlist = NULL;
-  }
-  shuffle(slist, ",");
-  p = strdup(slist);
-  add_server(p);
-  free(p);
-}
-
-static void servers_describe(struct cfg_entry * entry, int idx) {
-  if (!strcmp(entry->name, "servers")) 
-    dprintf(idx, STR("servers is a comma-separated list of servers the bot will use\n"));
-  else
-    dprintf(idx, STR("servers6 is a comma-separated list of servers the bot will use (FOR IPv6)\n"));
-}
-
-struct cfg_entry CFG_SERVERS = {
-	"servers", CFGF_LOCAL | CFGF_GLOBAL | CFGF_LEAF, NULL, NULL,
-	servers_changed, servers_changed, servers_describe
-};
-
-struct cfg_entry CFG_SERVERS6 = {
-	"servers6", CFGF_LOCAL | CFGF_GLOBAL | CFGF_LEAF, NULL, NULL,
-	servers_changed, servers_changed, servers_describe
-};
-
-static void nick_changed(struct cfg_entry * entry, int * valid) {
-  char *p = NULL;
-
-  if (entry->ldata)
-    p = entry->ldata;
-  else if (entry->gdata)
-    p = entry->gdata;
-  else
-    p = NULL;
-  if (p && p[0])
-    strlcpy(origbotname, p, NICKLEN + 1);
-  else
-    strlcpy(origbotname, conf.bot->nick, NICKLEN + 1);
-  if (server_online)
-    dprintf(DP_SERVER, "NICK %s\n", origbotname);
-}
-
-static void nick_describe(struct cfg_entry * entry, int idx) {
-  dprintf(idx, STR("nick is the bots preferred nick when connecting/using .resetnick\n"));
-}
-
-struct cfg_entry CFG_NICK = {
-	"nick", CFGF_LOCAL | CFGF_GLOBAL | CFGF_LEAF, NULL, NULL,
-	nick_changed, nick_changed, nick_describe
-};
-
-static void realname_describe(struct cfg_entry * entry, int idx) {
-  dprintf(idx, STR("realname is the bots \"real name\" when connecting\n"));
-}
-
-static void realname_changed(struct cfg_entry * entry, int * valid) {
-  if (entry->ldata)
-    strlcpy(botrealname, (char *) entry->ldata, 121);
-  else if (entry->gdata)
-    strlcpy(botrealname, (char *) entry->gdata, 121);
-}
-
-struct cfg_entry CFG_REALNAME = {
-	"realname", CFGF_LOCAL | CFGF_GLOBAL | CFGF_LEAF, NULL, NULL,
-	realname_changed, realname_changed, realname_describe
-};
-
-static void dccauth_describe(struct cfg_entry *cfgent, int idx)
-{
-  dprintf(idx, STR("dccauth is boolean (0 or 1). Set to use auth checking on dcc/telnet login.\n"));
-}
-
-struct cfg_entry CFG_DCCAUTH = {
-	"dccauth", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
-	NULL, NULL, dccauth_describe
-};
-
-static void getin_describe(struct cfg_entry *cfgent, int idx)
-{
-  if (!strcmp(cfgent->name, "op-bots"))
-    dprintf(idx, STR("op-bots is number of bots to ask every time a oprequest is to be made\n"));
-  else if (!strcmp(cfgent->name, "in-bots"))
-    dprintf(idx, STR("in-bots is number of bots to ask every time a inrequest is to be made\n"));
-  else if (!strcmp(cfgent->name, "op-requests"))
-    dprintf(idx, STR("op-requests (requests:seconds) limits how often the bot will ask for ops\n"));
-  else if (!strcmp(cfgent->name, "lag-threshold"))
-    dprintf(idx, STR("lag-threshold is maximum acceptable server lag for the bot to send/honor requests\n"));
-  else if (!strcmp(cfgent->name, "op-time-slack"))
-    dprintf(idx, STR("op-time-slack is number of seconds a opcookies encoded time value can be off from the bots current time\n"));
-  else if (!strcmp(cfgent->name, "close-threshold"))
-    dprintf(idx, STR("Format H:L. When at least H hubs but L or less leafs are linked, close all channels\n"));
-  else if (!strcmp(cfgent->name, "kill-threshold"))
-    dprintf(idx, STR("When more than kill-threshold bots have been killed/k-lined the last minute, channels are locked\n"));
-  else if (!strcmp(cfgent->name, "fight-threshold"))
-    dprintf(idx, STR("When more than fight-threshold ops/deops/kicks/bans/unbans altogether have happened on a channel in one minute, the channel is locked\n"));
-  else {
-    dprintf(idx, STR("No description for %s ???\n"), cfgent->name);
-    putlog(LOG_ERRORS, "*", STR("getin_describe() called with unknown config entry %s"), cfgent->name);
-  }
-}
-
-static void getin_changed(struct cfg_entry *cfgent, int *valid)
-{
-  if (!cfgent->gdata)
-    return;
-
-  *valid = 0;
-  if (!strcmp(cfgent->name, "op-requests")) {
-    int L,
-      R;
-    char *value = cfgent->gdata;
-
-    L = atoi(value);
-    value = strchr(value, ':');
-    if (!value)
-      return;
-    value++;
-    R = atoi(value);
-    if ((R >= 60) || (R <= 3) || (L < 1) || (L > R))
-      return;
-    *valid = 1;
-    return;
-  }
-  if (!strcmp(cfgent->name, "close-threshold")) {
-    int L, R;
-    char *value = NULL;
-
-    value = cfgent->gdata;
-
-    L = atoi(value);
-    value = strchr(value, ':');
-    if (!value)
-      return;
-    value++;
-    R = atoi(value);
-    if ((R >= 1000) || (R < 0) || (L < 0) || (L > 100))
-      return;
-    *valid = 1;
-    return;
-  }
-
-  int i = atoi(cfgent->gdata);
-
-  if (!strcmp(cfgent->name, "op-bots")) {
-    if ((i < 1) || (i > 10))
-      return;
-  } else if (!strcmp(cfgent->name, "lag-threshold")) {
-    if ((i < 3) || (i > 60))
-      return;
-  } else if (!strcmp(cfgent->name, "fight-threshold")) {
-    if (i && ((i < 50) || (i > 1000)))
-      return;
-  } else if (!strcmp(cfgent->name, "kill-threshold")) {
-    if ((i < 0) || (i >= 200))
-      return;
-  }
-  *valid = 1;
-  return;
-}
-
-struct cfg_entry CFG_OPBOTS = {
-	"op-bots", CFGF_GLOBAL, NULL, NULL,
-	getin_changed, NULL, getin_describe
-};
-
-struct cfg_entry CFG_FIGHTTHRESHOLD = {
-	"fight-threshold", CFGF_GLOBAL, NULL, NULL,
-	getin_changed, NULL, getin_describe
-};
-
-struct cfg_entry CFG_CLOSETHRESHOLD = {
-	"close-threshold", CFGF_GLOBAL, NULL, NULL,
-	getin_changed, NULL, getin_describe
-};
-
-struct cfg_entry CFG_KILLTHRESHOLD = {
-	"kill-threshold", CFGF_GLOBAL, NULL, NULL,
-	getin_changed, NULL, getin_describe
-};
-
-struct cfg_entry CFG_INBOTS = {
-	"in-bots", CFGF_GLOBAL, NULL, NULL,
-	getin_changed, NULL, getin_describe
-};
-
-struct cfg_entry CFG_LAGTHRESHOLD = {
-	"lag-threshold", CFGF_GLOBAL, NULL, NULL,
-	getin_changed, NULL, getin_describe
-};
-
-struct cfg_entry CFG_OPREQUESTS = {
-	"op-requests", CFGF_GLOBAL, NULL, NULL,
-	getin_changed, NULL, getin_describe
-};
-
-void add_cfg(struct cfg_entry *entry)
-{
-  cfg = (struct cfg_entry **) my_realloc(cfg, sizeof(void *) * (cfg_count + 1));
-  cfg[cfg_count] = entry;
-  cfg_count++;
-  entry->ldata = NULL;
-  entry->gdata = NULL;
-}
-
-static struct cfg_entry *check_can_set_cfg(char *target, char *entryname)
-{
-  struct cfg_entry *entry = NULL;
-
-  for (int i = 0; i < cfg_count; i++)
-    if (!strcmp(cfg[i]->name, entryname)) {
-      entry = cfg[i];
-      break;
-    }
-  if (!entry)
-    return 0;
-
-  struct userrec *u = NULL;
-
-  if (target) {
-    if (!(entry->flags & CFGF_LOCAL))
-      return 0;
-    if (!(u = get_user_by_handle(userlist, target)))
-      return 0;
-    if (!u->bot)
-      return 0;
-  } else {
-    if (!(entry->flags & CFGF_GLOBAL))
-      return 0;
-  }
-  return entry;
-}
-
-void set_cfg_str(char *target, char *entryname, char *data)
-{
-  struct cfg_entry *entry = NULL;
-  bool dochange = 0;
-
-  if (!(entry = check_can_set_cfg(target, entryname)))
-    return;
-
-  if (!(entry->flags & (CFGF_HUB|CFGF_LEAF)) ||
-     (conf.bot->hub && entry->flags & CFGF_HUB) || (!conf.bot->hub && entry->flags & CFGF_LEAF))
-    dochange = 1;
-
-  if (data && !strcmp(data, "-"))
-    data = NULL;
-  if (data && (strlen(data) >= 1024))
-    data[1023] = 0;
-  if (target) {
-    struct userrec *u = get_user_by_handle(userlist, target);
-    struct xtra_key *xk = NULL;
-    char *olddata = entry->ldata;
-
-    if (u && !strcmp(conf.bot->nick, u->handle)) {
-      if (data) {
-        entry->ldata = strdup(data);
-      } else
-        entry->ldata = NULL;
-      if (dochange && entry->localchanged) {
-        int valid = 1;
-
-        /* entry->localchanged(entry, olddata, &valid); */
-        entry->localchanged(entry, &valid);
-        if (!valid) {
-          if (entry->ldata)
-            free(entry->ldata);
-          entry->ldata = olddata;
-          data = olddata;
-          olddata = NULL;
-        }
-      }
-    }
-    xk = (struct xtra_key *) my_calloc(1, sizeof(struct xtra_key));
-    xk->key = strdup(entry->name);
-    if (data) {
-      xk->data = strdup(data);
-    }
-    set_user(&USERENTRY_CONFIG, u, xk);
-    if (olddata)
-      free(olddata);
-  } else {
-    char *olddata = entry->gdata;
-
-    if (data) {
-      entry->gdata = strdup(data);
-    } else
-      entry->gdata = NULL;
-    if (dochange && entry->globalchanged) {
-      int valid = 1;
-
-      /* entry->globalchanged(entry, olddata, &valid); */
-      entry->globalchanged(entry, &valid);
-      if (!valid) {
-        if (entry->gdata)
-          free(entry->gdata);
-        entry->gdata = olddata;
-        olddata = NULL;
-      }
-    }
-    if (!cfg_noshare)
-      botnet_send_cfg_broad(-1, entry);
-    if (olddata)
-      free(olddata);
-  }
-}
-
-struct cfg_entry CFG_MOTD = { 
-	"motd", CFGF_GLOBAL, NULL, NULL, 
-	NULL, NULL, NULL
-};
-
-void init_cfg()
-{
-  add_cfg(&CFG_AUTHKEY);
-  add_cfg(&CFG_BADPROCESS);
-  add_cfg(&CFG_DCCAUTH);
-  add_cfg(&CFG_CHANSET);
-  add_cfg(&CFG_CLOAK_SCRIPT);
-  add_cfg(&CFG_CLOSETHRESHOLD);
-  add_cfg(&CFG_CMDPREFIX);
-  add_cfg(&CFG_FIGHTTHRESHOLD);
-  add_cfg(&CFG_FORKINTERVAL);
-  add_cfg(&CFG_HIJACK);
-  add_cfg(&CFG_INBOTS);
-  add_cfg(&CFG_KILLTHRESHOLD);
-  add_cfg(&CFG_LAGTHRESHOLD);
-  add_cfg(&CFG_LOGIN);
-  add_cfg(&CFG_MOTD);
-#ifdef G_MEAN
-  add_cfg(&CFG_MEANBAN);
-  add_cfg(&CFG_MEANDEOP);
-  add_cfg(&CFG_MEANKICK);
-#endif /* G_MEAN */
-  add_cfg(&CFG_MSGIDENT);
-  add_cfg(&CFG_MSGINVITE);
-  add_cfg(&CFG_MSGOP);
-  add_cfg(&CFG_MSGPASS);
-  add_cfg(&CFG_NICK);
-  add_cfg(&CFG_OPBOTS);
-  add_cfg(&CFG_OPREQUESTS);
-  add_cfg(&CFG_PROCESSLIST);
-  add_cfg(&CFG_PROMISC);
-  add_cfg(&CFG_REALNAME);
-  add_cfg(&CFG_SERVERS);
-  add_cfg(&CFG_SERVERS6);
-  add_cfg(&CFG_SERVPORT);
-  add_cfg(&CFG_TRACE);
-}
-
-int check_cmd_pass(const char *cmd, char *pass)
-{
-  if (check_master_hash(NULL, pass))
-    return 1;
-
-  struct cmd_pass *cp = NULL;
-
-  for (cp = cmdpass; cp; cp = cp->next)
-    if (!egg_strcasecmp(cmd, cp->name)) {
-      char tmp[32] = "";
-
-      encrypt_pass(pass, tmp);
-      if (!strcmp(tmp, cp->pass))
-        return 1;
-      return 0;
-    }
-  return 0;
-}
-
-int has_cmd_pass(const char *cmd) 
-{
-  struct cmd_pass *cp = NULL;
-
-  for (cp = cmdpass; cp; cp = cp->next)
-    if (!egg_strcasecmp(cmd, cp->name))
-      return 1;
-  return 0;
-}
-
-void set_cmd_pass(char *ln, int shareit) 
-{
-  struct cmd_pass *cp = NULL;
-  char *cmd = NULL;
-
-  cmd = newsplit(&ln);
-  for (cp = cmdpass; cp; cp = cp->next)
-    if (!strcmp(cmd, cp->name))
-      break;
-  if (cp)
-    if (ln[0]) {
-      /* change */
-      strcpy(cp->pass, ln);
-      if (shareit)
-        botnet_send_cmdpass(-1, cp->name, cp->pass);
-    } else {
-      if (cp == cmdpass)
-        cmdpass = cp->next;
-      else {
-        struct cmd_pass *cp2;
-
-        cp2 = cmdpass;
-        while (cp2->next != cp)
-          cp2 = cp2->next;
-        cp2->next = cp->next;
-      }
-      if (shareit)
-        botnet_send_cmdpass(-1, cp->name, "");
-      free(cp->name);
-      free(cp);
-  } else if (ln[0]) {
-    /* create */
-    cp = (struct cmd_pass *) my_calloc(1, sizeof(struct cmd_pass));
-    cp->next = cmdpass;
-    cmdpass = cp;
-    cp->name = strdup(cmd);
-    strcpy(cp->pass, ln);
-    if (shareit)
-      botnet_send_cmdpass(-1, cp->name, cp->pass);
-  }
-}
-
-void userfile_cfg_line(char *ln)
-{
-  char *name = NULL;
-  int i;
-  struct cfg_entry *cfgent = NULL;
-
-  name = newsplit(&ln);
-  for (i = 0; !cfgent && (i < cfg_count); i++)
-    if (!strcmp(cfg[i]->name, name))
-      cfgent = cfg[i];
-  if (cfgent) {
-    /* if we are a leaf, dont share the cfg line. */
-    if (bot_hublevel(conf.bot->u) == 999)
-      cfg_noshare = 1;
-    set_cfg_str(NULL, cfgent->name, (ln && ln[0]) ? ln : NULL);
-    /* regardless of leaf/hub it is safe to set this to 0 */
-    cfg_noshare = 0;
-  } else
-    putlog(LOG_ERRORS, "*", "Unrecognized config entry %s in userfile", name);
-
-}
-
-void got_config_share(int idx, char *ln, int broad)
-{
-  char *name = NULL;
-  int i;
-  struct cfg_entry *cfgent = NULL;
-
-  cfg_noshare = 1;
-  name = newsplit(&ln);
-  for (i = 0; !cfgent && (i < cfg_count); i++)
-    if (!strcmp(cfg[i]->name, name))
-      cfgent = cfg[i];
-  if (cfgent) {
-    set_cfg_str(NULL, cfgent->name, (ln && ln[0]) ? ln : NULL);
-    if (broad)
-      botnet_send_cfg_broad(idx, cfgent);
-  } else
-    putlog(LOG_ERRORS, "*", "Unrecognized config entry %s in userfile", name);
-  cfg_noshare = 0;
-}
-
-void trigger_cfg_changed()
-{
-  int i;
-  struct xtra_key *xk = NULL;
-
-  /* look for local cfgs inside our own USERENTRY_CONFIG and set them in our cfg struct */
-  cfg_noshare = 1;			/* why bother sharing out our LOCAL cfg settings? */
-  for (i = 0; i < cfg_count; i++) {
-    if (cfg[i]->flags & CFGF_LOCAL) {
-      xk = (struct xtra_key *) get_user(&USERENTRY_CONFIG, conf.bot->u);
-      while (xk && strcmp(xk->key, cfg[i]->name))
-	xk = xk->next;
-      if (xk) {
-	putlog(LOG_DEBUG, "*", "trigger_cfg_changed for %s", cfg[i]->name ? cfg[i]->name : "(null)");
-	if (!strcmp(cfg[i]->name, xk->key ? xk->key : "")) {
-	  set_cfg_str(conf.bot->nick, cfg[i]->name, xk->data);
-	}
-      }
-    }
-  }
-  cfg_noshare = 0;
-}

+ 0 - 63
src/cfg.h

@@ -1,63 +0,0 @@
-#ifndef _CFG_H
-#define _CFG_H
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#define CFGF_GLOBAL  BIT0          /* Accessible as .config */
-#define CFGF_LOCAL   BIT1          /* Accessible as .botconfig */
-#define CFGF_HUB     BIT2
-#define CFGF_LEAF    BIT3
-
-typedef struct cfg_entry {
-  char *name;
-  int flags;
-  char *gdata;
-  char *ldata;
-  void (*globalchanged) (struct cfg_entry *, int *valid);
-  void (*localchanged) (struct cfg_entry *, int *valid);
-  void (*describe) (struct cfg_entry *, int idx);
-} cfg_entry_T;
-
-extern struct cfg_entry CFG_MOTD, CFG_CMDPREFIX, CFG_FORKINTERVAL, CFG_CHANSET, CFG_SERVERS, CFG_SERVERS6, 
-                        CFG_NICK, CFG_REALNAME, CFG_INBOTS, CFG_LAGTHRESHOLD, CFG_OPREQUESTS,
-                        CFG_OPBOTS, CFG_INBOTS, CFG_SERVPORT, CFG_AUTHKEY, CFG_MSGOP, CFG_MSGPASS, 
-			CFG_MSGINVITE, CFG_MSGIDENT, CFG_LOGIN, CFG_HIJACK, CFG_TRACE, CFG_PROMISC, 
-			CFG_BADPROCESS, CFG_PROCESSLIST, CFG_FIGHTTHRESHOLD, CFG_CLOSETHRESHOLD, CFG_KILLTHRESHOLD,
-			CFG_DCCAUTH;
-#ifdef G_MEAN
-extern struct cfg_entry CFG_MEANDEOP, CFG_MEANKICK, CFG_MEANBAN;
-#endif /* G_MEAN */
-void deflag_user(struct userrec *, int, char *, struct chanset_t *);
-int deflag_translate(const char *);
-void set_cfg_str(char *, char *, char *);
-void add_cfg(struct cfg_entry *);
-void got_config_share(int, char *, int);
-void userfile_cfg_line(char *);
-void trigger_cfg_changed();
-int check_cmd_pass(const char *, char *);
-int has_cmd_pass(const char *);
-void set_cmd_pass(char *, int);
-void init_cfg(void);
-
-extern struct cmd_pass            *cmdpass;
-
-extern char			cmdprefix;
-extern int			cfg_count;
-extern bool			cfg_noshare;
-extern struct cfg_entry		**cfg;
-
-#define OP_BOTS (CFG_OPBOTS.gdata ? atoi(CFG_OPBOTS.gdata) : 1)
-#define IN_BOTS (CFG_INBOTS.gdata ? atoi(CFG_INBOTS.gdata) : 1)
-#define LAG_THRESHOLD (CFG_LAGTHRESHOLD.gdata ? atoi(CFG_LAGTHRESHOLD.gdata) : 15)
-#define OPREQ_COUNT (CFG_OPREQUESTS.gdata ? atoi( CFG_OPREQUESTS.gdata ) : 2)
-#define OPREQ_SECONDS (CFG_OPREQUESTS.gdata ? atoi( strchr(CFG_OPREQUESTS.gdata, ':') + 1 ) : 5)
-#define msgop (CFG_MSGOP.ldata ? CFG_MSGOP.ldata : CFG_MSGOP.gdata ? CFG_MSGOP.gdata : "")
-#define msgpass (CFG_MSGPASS.ldata ? CFG_MSGPASS.ldata : CFG_MSGPASS.gdata ? CFG_MSGPASS.gdata : "")
-#define msginvite (CFG_MSGINVITE.ldata ? CFG_MSGINVITE.ldata : CFG_MSGINVITE.gdata ? CFG_MSGINVITE.gdata : "")
-#define msgident (CFG_MSGIDENT.ldata ? CFG_MSGIDENT.ldata : CFG_MSGIDENT.gdata ? CFG_MSGIDENT.gdata : "")
-#define kill_threshold (CFG_KILLTHRESHOLD.gdata ? atoi(CFG_KILLTHRESHOLD.gdata) : 0)
-#define dccauth (CFG_DCCAUTH.ldata ? atoi(CFG_DCCAUTH.ldata) : CFG_DCCAUTH.gdata ? atoi(CFG_DCCAUTH.gdata) : 0)
-
-#endif /* !_CFG_H */

+ 3 - 1
src/chanprog.c

@@ -527,6 +527,7 @@ void chanprog()
     checkchans(0);
     checkchans(0);
     readuserfile(userfile, &userlist);
     readuserfile(userfile, &userlist);
     checkchans(1);
     checkchans(1);
+    var_parse_my_botset();
     loading = 0;
     loading = 0;
   }
   }
 
 
@@ -563,7 +564,7 @@ void chanprog()
   set_user(&USERENTRY_USERNAME, conf.bot->u, conf.username);
   set_user(&USERENTRY_USERNAME, conf.bot->u, conf.username);
   set_user(&USERENTRY_NODENAME, conf.bot->u, un.nodename);
   set_user(&USERENTRY_NODENAME, conf.bot->u, un.nodename);
 
 
-  trigger_cfg_changed();
+  var_parse_my_botset();
 
 
   /* We should be safe now */
   /* We should be safe now */
 
 
@@ -592,6 +593,7 @@ void reload()
   Auth::FillUsers();
   Auth::FillUsers();
   checkchans(1);
   checkchans(1);
   loading = 0;
   loading = 0;
+  var_parse_my_botset();
   reaffirm_owners();
   reaffirm_owners();
   hook_read_userfile();
   hook_read_userfile();
 }
 }

+ 1 - 1
src/chanprog.h

@@ -26,7 +26,7 @@ int shouldjoin(struct chanset_t *);
 char *samechans(const char *, const char *);
 char *samechans(const char *, const char *);
 
 
 extern struct chanset_t		*chanset;
 extern struct chanset_t		*chanset;
-extern char			admin[], origbotname[], botname[];
+extern char			admin[], origbotname[NICKLEN + 1], botname[];
 extern port_t			my_port;
 extern port_t			my_port;
 extern bool			reset_chans;
 extern bool			reset_chans;
 
 

+ 22 - 180
src/cmds.c

@@ -206,192 +206,34 @@ static void cmd_whom(int idx, char *par)
   answer_local_whom(idx, chan);
   answer_local_whom(idx, chan);
 }
 }
 
 
-/*
-   .config
-   Usage + available entry list
-   .config name
-   Show current value + description
-   .config name value
-   Set
- */
-static void cmd_config(int idx, char *par)
+static void cmd_botset(int idx, char *par)
 {
 {
-  char *name = NULL;
-  struct cfg_entry *cfgent = NULL;
-  int cnt, i;
-  bool describe = conf.bot->hub;
+  char *botnick = NULL;
 
 
-  putlog(LOG_CMDS, "*", "#%s# config %s", dcc[idx].nick, par);
-  if (!par[0]) {
-    char *outbuf = NULL;
-
-    outbuf = (char *) my_calloc(1, 1);
-
-    dprintf(idx, "Usage: config [name [value|-]]\n");
-    dprintf(idx, "Defined config entry names:\n");
-    cnt = 0;
-    for (i = 0; i < cfg_count; i++) {
-      if (conf.bot->hub && (cfg[i]->flags & CFGF_GLOBAL) && (cfg[i]->describe)) {
-	if (!cnt) {
-          outbuf = (char *) my_realloc(outbuf, 2 + 1);
-	  simple_sprintf(outbuf, "  ");
-        }
-        outbuf = (char *) my_realloc(outbuf, strlen(outbuf) + strlen(cfg[i]->name) + 1 + 1);
-	simple_sprintf(outbuf, "%s%s ", outbuf, cfg[i]->name);
-	cnt++;
-	if (cnt == 10) {
-	  dprintf(idx, "%s\n", outbuf);
-	  cnt = 0;
-	}
-      }
-    }
-    if (cnt)
-      dprintf(idx, "%s\n", outbuf);
-    if (outbuf)
-      free(outbuf);
-    return;
-  }
-  name = newsplit(&par);
-  for (i = 0; !cfgent && (i < cfg_count); i++)
-    if (!strcmp(cfg[i]->name, name))
-      cfgent = cfg[i];
-  if (describe && (!cfgent || !cfgent->describe)) {
-    dprintf(idx, "No such config entry\n");
+  if (!par[0] || !(botnick = newsplit(&par))) {
+    dprintf(idx, "Usage: botset <bot> [<+/->list] [<var> [data|-]]\n");
     return;
     return;
   }
   }
-  if (!isowner(dcc[idx].nick)) {
-    int no = 0;
-    if (!egg_strcasecmp(name, "authkey"))
-      no++;
-    if (!egg_strcasecmp(name, "cmdprefix"))
-      no++;
-    if (!egg_strcasecmp(name, "hijack"))
-      no++;
-    if (!egg_strcasecmp(name, "bad-cookie"))
-      no++;
-
-    if (no) {
-      dprintf(idx, "Only permanent owners may change '%s'.\n", name);
-      return;
-    }
-  }
-  if (!par[0]) {
-    if (describe)
-      cfgent->describe(cfgent, idx);
-    if (!cfgent->gdata)
-      dprintf(idx, "No current value\n");
-    else {
-      dprintf(idx, "Currently: %s\n", cfgent->gdata);
-    }
-    return;
-  }
-  if (strlen(par) >= 2048) {
-    dprintf(idx, "Value can't be longer than 2048 chars");
-    return;
-  }
-  set_cfg_str(NULL, cfgent->name, par);
-  if (!cfgent->gdata)
-    dprintf(idx, "Now: (not set)\n");
-  else {
-    dprintf(idx, "Now: %s\n", cfgent->gdata);
-  }
-  write_userfile(idx);
-}
 
 
-static void cmd_botconfig(int idx, char *par)
-{
-  struct userrec *u2 = NULL;
-  char *entry = NULL, *botm = NULL;
-  struct xtra_key *k = NULL;
-  struct cfg_entry *cfgent = NULL;
-  int i, cnt;
-  tand_t *tbot = NULL;
-  bool found = 0, described = 0, describe = conf.bot->hub;
+  struct userrec *u = get_user_by_handle(userlist, botnick);
 
 
-  /* botconfig bot [name [value]]  */
-  putlog(LOG_CMDS, "*", "#%s# botconfig %s", dcc[idx].nick, par);
-  if (!par[0]) {
-    dprintf(idx, "Usage: botconfig <bot> [name [value|-]]\n");
-    dprintf(idx, " <bot> may contain wildcards\n");
-    cnt = 0;
-    for (i = 0; i < cfg_count; i++) {
-      if (cfg[i]->flags & CFGF_LOCAL) {
-	dprintf(idx, "%s ", cfg[i]->name);
-	cnt++;
-	if (cnt == 10) {
-	  dprintf(idx, "\n");
-	  cnt=0;
-	}
-      }
-    }
-    if (cnt > 0)
-      dprintf(idx, "\n");
+  if (!u || !u->bot) {
+    dprintf(idx, "%s is not a valid bot.\n", botnick);
     return;
     return;
   }
   }
-  botm = newsplit(&par);
-  entry = newsplit(&par);
-
-  for (tbot = tandbot; tbot; tbot = tbot->next) {
-    if (wild_match(botm, tbot->bot)) {
-      u2 = get_user_by_handle(userlist, tbot->bot);
-      if (!u2)
-        continue;
-
-      found = 1;
-
-      dprintf(idx, "%s:\n", tbot->bot);
-
-      if (!entry || !entry[0]) {
-        for (i = 0; i < cfg_count; i++) {
-          if (describe && (cfg[i]->flags & CFGF_LOCAL) && (cfg[i]->describe)) {
-	    k = (struct xtra_key *) get_user(&USERENTRY_CONFIG, u2);
-            while (k && strcmp(k->key, cfg[i]->name))
-              k = k->next;
-            if (k)
-              dprintf(idx, "  %s: %s\n", k->key, k->data);
-            else
-              dprintf(idx, "  %s: (not set)\n", cfg[i]->name);
-          }
-        }
-        continue;
-      }
-
-      cfgent = NULL;
-      if (describe) {
-        for (i = 0; !cfgent && (i < cfg_count); i++)
-          if (!strcmp(cfg[i]->name, entry) && (cfg[i]->flags & CFGF_LOCAL) && (cfg[i]->describe))
-            cfgent = cfg[i];
-      }
-      if (!cfgent) {
-        dprintf(idx, "No such configuration value\n");
-        return;
-      }
-      if (par[0]) {
-        char tmp[100] = "";
-
-        set_cfg_str(u2->handle, cfgent->name, (strcmp(par, "-")) ? par : NULL);
-        simple_snprintf(tmp, sizeof tmp, "%s %s", cfgent->name, par);
-        update_mod(u2->handle, dcc[idx].nick, "botconfig", tmp);
-        dprintf(idx, "Now: ");
-        write_userfile(idx);
-      } else {
-        if (describe && cfgent->describe && !described) {
-          described++;
-          cfgent->describe(cfgent, idx);
-        }
-      }
-      k = (struct xtra_key *) get_user(&USERENTRY_CONFIG, u2);
-      while (k && strcmp(k->key, cfgent->name))
-        k = k->next;
-      if (k)
-        dprintf(idx, "  %s: %s\n", k->key, k->data);
-      else
-        dprintf(idx, "  %s: (not set)\n", cfgent->name);
-    }
-  }
+  
+  cmd_set_real(botnick, idx, par);
+  return;
+}
 
 
-  if (!found)
-    dprintf(idx, "No bot matching '%s' linked\n", botm);
+static void cmd_set(int idx, char *par)
+{
+//  if (!par[0]) {
+//    dprintf(idx, "Usage: set [<+/->list] <var> [data]\n");
+//    return;
+//  }
+  cmd_set_real(NULL, idx, par);
+  return;
 }
 }
 
 
 static void cmd_cmdpass(int idx, char *par)
 static void cmd_cmdpass(int idx, char *par)
@@ -497,7 +339,7 @@ static void cmd_motd(int idx, char *par)
     s = (char *) my_calloc(1, size); /* +2: ' 'x2 */
     s = (char *) my_calloc(1, size); /* +2: ' 'x2 */
 
 
     egg_snprintf(s, size, "%s %li %s", dcc[idx].nick, now, par);
     egg_snprintf(s, size, "%s %li %s", dcc[idx].nick, now, par);
-    set_cfg_str(NULL, "motd", s);
+    var_set_by_name(NULL, "motd", s);
     free(s);
     free(s);
     dprintf(idx, "Motd set\n");
     dprintf(idx, "Motd set\n");
     if (conf.bot->hub)
     if (conf.bot->hub)
@@ -4284,7 +4126,6 @@ cmd_t C_dcc[] =
   {"back",		"",	(Function) cmd_back,		NULL, 0},
   {"back",		"",	(Function) cmd_back,		NULL, 0},
   {"backup",		"m|m",	(Function) cmd_backup,		NULL, HUB},
   {"backup",		"m|m",	(Function) cmd_backup,		NULL, HUB},
   {"boot",		"m",	(Function) cmd_boot,		NULL, HUB},
   {"boot",		"m",	(Function) cmd_boot,		NULL, HUB},
-  {"botconfig",		"n",	(Function) cmd_botconfig,	NULL, HUB},
   {"bots",		"m",	(Function) cmd_bots,		NULL, HUB},
   {"bots",		"m",	(Function) cmd_bots,		NULL, HUB},
   {"downbots",		"m",	(Function) cmd_downbots,	NULL, HUB},
   {"downbots",		"m",	(Function) cmd_downbots,	NULL, HUB},
   {"bottree",		"n",	(Function) cmd_bottree,		NULL, HUB},
   {"bottree",		"n",	(Function) cmd_bottree,		NULL, HUB},
@@ -4298,7 +4139,8 @@ cmd_t C_dcc[] =
   {"cmdpass",           "a",    (Function) cmd_cmdpass,         NULL, HUB},
   {"cmdpass",           "a",    (Function) cmd_cmdpass,         NULL, HUB},
   {"color",		"",     (Function) cmd_color,           NULL, 0},
   {"color",		"",     (Function) cmd_color,           NULL, 0},
   {"comment",		"m|m",	(Function) cmd_comment,		NULL, 0},
   {"comment",		"m|m",	(Function) cmd_comment,		NULL, 0},
-  {"config",		"n",	(Function) cmd_config,		NULL, HUB},
+  {"set",		"n",	(Function) cmd_set,		NULL, HUB},
+  {"botset",		"n",	(Function) cmd_botset,		NULL, HUB},
   {"console",		"-|-",	(Function) cmd_console,		NULL, 0},
   {"console",		"-|-",	(Function) cmd_console,		NULL, 0},
   {"date",		"",	(Function) cmd_date,		NULL, AUTH},
   {"date",		"",	(Function) cmd_date,		NULL, AUTH},
   {"dccstat",		"a",	(Function) cmd_dccstat,		NULL, 0},
   {"dccstat",		"a",	(Function) cmd_dccstat,		NULL, 0},

+ 1 - 1
src/core_binds.c

@@ -16,7 +16,7 @@
 #include "users.h"
 #include "users.h"
 #include "misc.h"
 #include "misc.h"
 #include "tclhash.h"
 #include "tclhash.h"
-#include "cfg.h"
+#include "dcc.h"
 
 
 extern cmd_t 		C_dcc[];
 extern cmd_t 		C_dcc[];
 
 

+ 1 - 0
src/dcc.c

@@ -41,6 +41,7 @@
 #include "core_binds.h"
 #include "core_binds.h"
 
 
 
 
+struct cmd_pass *cmdpass = NULL;
 struct dcc_t *dcc = NULL;       /* DCC list                                */
 struct dcc_t *dcc = NULL;       /* DCC list                                */
 time_t timesync = 0;
 time_t timesync = 0;
 int dcc_total = 0;              /* size of dcc table                             */
 int dcc_total = 0;              /* size of dcc table                             */

+ 1 - 0
src/dcc.h

@@ -221,6 +221,7 @@ extern int 			dcc_total, dccn, uplink_idx;
 extern time_t			timesync;
 extern time_t			timesync;
 extern char			network[];
 extern char			network[];
 extern bool			protect_telnet;
 extern bool			protect_telnet;
+extern struct cmd_pass          *cmdpass;
 extern struct dcc_table DCC_CHAT, DCC_BOT, DCC_BOT_NEW,
 extern struct dcc_table DCC_CHAT, DCC_BOT, DCC_BOT_NEW,
  DCC_RELAY, DCC_RELAYING, DCC_FORK_RELAY, DCC_PRE_RELAY, DCC_CHAT_PASS,
  DCC_RELAY, DCC_RELAYING, DCC_FORK_RELAY, DCC_PRE_RELAY, DCC_CHAT_PASS,
  DCC_FORK_BOT, DCC_SOCKET, DCC_TELNET_ID, DCC_TELNET_NEW, DCC_TELNET_PW,
  DCC_FORK_BOT, DCC_SOCKET, DCC_TELNET_ID, DCC_TELNET_NEW, DCC_TELNET_PW,

+ 69 - 0
src/dccutil.c

@@ -964,3 +964,72 @@ valid_idx(int idx)
   return 1;
   return 1;
 }
 }
 
 
+int check_cmd_pass(const char *cmd, char *pass)
+{
+  if (check_master_hash(NULL, pass))
+    return 1;
+
+  struct cmd_pass *cp = NULL;
+
+  for (cp = cmdpass; cp; cp = cp->next)
+    if (!egg_strcasecmp(cmd, cp->name)) {
+      char tmp[32] = "";
+
+      encrypt_pass(pass, tmp);
+      if (!strcmp(tmp, cp->pass))
+        return 1;
+      return 0;
+    }
+  return 0;
+}
+
+int has_cmd_pass(const char *cmd)
+{
+  struct cmd_pass *cp = NULL;
+
+  for (cp = cmdpass; cp; cp = cp->next)
+    if (!egg_strcasecmp(cmd, cp->name))
+      return 1;
+  return 0;
+}
+void set_cmd_pass(char *ln, int shareit)
+{
+  struct cmd_pass *cp = NULL;
+  char *cmd = NULL;
+
+  cmd = newsplit(&ln);
+  for (cp = cmdpass; cp; cp = cp->next)
+    if (!strcmp(cmd, cp->name))
+      break;
+  if (cp)
+    if (ln[0]) {
+      /* change */
+      strcpy(cp->pass, ln);
+      if (shareit)
+        botnet_send_cmdpass(-1, cp->name, cp->pass);
+    } else {
+      if (cp == cmdpass)
+        cmdpass = cp->next;
+      else {
+        struct cmd_pass *cp2;
+
+        cp2 = cmdpass;
+        while (cp2->next != cp)
+          cp2 = cp2->next;
+        cp2->next = cp->next;
+      }
+      if (shareit)
+        botnet_send_cmdpass(-1, cp->name, "");
+      free(cp->name);
+      free(cp);
+  } else if (ln[0]) {
+    /* create */
+    cp = (struct cmd_pass *) my_calloc(1, sizeof(struct cmd_pass));
+    cp->next = cmdpass;
+    cmdpass = cp;
+    cp->name = strdup(cmd);
+    strcpy(cp->pass, ln);
+    if (shareit)
+      botnet_send_cmdpass(-1, cp->name, cp->pass);
+  }
+}

+ 4 - 0
src/dccutil.h

@@ -28,6 +28,7 @@ struct portmap {
 #define DP_DUMP		0x8000
 #define DP_DUMP		0x8000
 
 
 
 
+
 void init_dcc(void);
 void init_dcc(void);
 void dumplots(int, const char *, char *);
 void dumplots(int, const char *, char *);
 void dprintf(int, const char *, ...) __attribute__((format(printf, 2, 3)));
 void dprintf(int, const char *, ...) __attribute__((format(printf, 2, 3)));
@@ -55,6 +56,9 @@ port_t listen_all(port_t, bool);
 bool valid_idx(int);
 bool valid_idx(int);
 int dcc_read(FILE *);
 int dcc_read(FILE *);
 void dcc_write(FILE *, int);
 void dcc_write(FILE *, int);
+int check_cmd_pass(const char *, char *);
+int has_cmd_pass(const char *);
+void set_cmd_pass(char *, int);
 
 
 extern int		max_dcc;
 extern int		max_dcc;
 extern time_t		connect_timeout;
 extern time_t		connect_timeout;

+ 86 - 0
src/flags.c

@@ -562,3 +562,89 @@ whois_access(struct userrec *user, struct userrec *whois_user)
     return 0;
     return 0;
   return 1;
   return 1;
 }
 }
+
+int deflag_translate(const char *buf)
+{
+  int num = atoi(buf);
+
+  if (egg_isdigit(num))
+    return num;
+
+  if (!egg_strcasecmp(buf, "ignore"))
+    return P_IGNORE;
+  else if (!egg_strcasecmp(buf, "deop"))
+    return P_DEOP;
+  else if (!egg_strcasecmp(buf, "kick"))
+    return P_KICK;
+  else if (!egg_strcasecmp(buf, "delete") || !egg_strcasecmp(buf, "remove"))
+    return P_DELETE;
+  return P_IGNORE;
+}
+void deflag_user(struct userrec *u, int why, char *msg, struct chanset_t *chan)
+{
+  if (!u)
+    return;
+
+  char tmp[256] = "", tmp2[1024] = "";
+  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
+  int which = 0;
+
+  switch (why) {
+  case DEFLAG_BADCOOKIE:
+    strcpy(tmp, "Bad op cookie");
+    which = chan->bad_cookie;
+    break;
+  case DEFLAG_MANUALOP:
+    strcpy(tmp, STR("Manual op in -manop channel"));
+    which = chan->manop;
+    break;
+#ifdef G_MEAN
+  case DEFLAG_MEAN_DEOP:
+    strcpy(tmp, STR("Deopped bot in +mean channel"));
+    ent = &CFG_MEANDEOP;
+    break;
+  case DEFLAG_MEAN_KICK:
+    strcpy(tmp, STR("Kicked bot in +mean channel"));
+    ent = &CFG_MEANDEOP;
+    break;
+  case DEFLAG_MEAN_BAN:
+    strcpy(tmp, STR("Banned bot in +mean channel"));
+    ent = &CFG_MEANDEOP;
+    break;
+#endif /* G_MEAN */
+  case DEFLAG_MDOP:
+    strcpy(tmp, "Mass deop");
+    which = chan->mdop;
+    break;
+  case DEFLAG_MOP:
+    strcpy(tmp, "Mass op");
+    which = chan->mop;
+    break;
+  default:
+    simple_sprintf(tmp, "Reason #%i", why);
+  }
+  if (which == P_DEOP) {
+    putlog(LOG_WARN, "*",  "Setting %s +d (%s): %s", u->handle, tmp, msg);
+    simple_sprintf(tmp2, "+d: %s (%s)", tmp, msg);
+    set_user(&USERENTRY_COMMENT, u, tmp2);
+    get_user_flagrec(u, &fr, chan->dname);
+    fr.global = USER_DEOP;
+    fr.chan = USER_DEOP;
+    set_user_flagrec(u, &fr, chan->dname);
+  } else if (which == P_KICK) {
+    putlog(LOG_WARN, "*",  "Setting %s +dk (%s): %s", u->handle, tmp, msg);
+    simple_sprintf(tmp2, "+dk: %s (%s)", tmp, msg);
+    set_user(&USERENTRY_COMMENT, u, tmp2);
+    get_user_flagrec(u, &fr, chan->dname);
+    fr.global = USER_DEOP | USER_KICK;
+    fr.chan = USER_DEOP | USER_KICK;
+    set_user_flagrec(u, &fr, chan->dname);
+  } else if (which == P_DELETE) {
+    putlog(LOG_WARN, "*",  "Deleting %s (%s): %s", u->handle, tmp, msg);
+    deluser(u->handle);
+  } else {
+    putlog(LOG_WARN, "*",  "No user flag effects for %s (%s): %s", u->handle, tmp, msg);
+    simple_sprintf(tmp2, "Warning: %s (%s)", tmp, msg);
+    set_user(&USERENTRY_COMMENT, u, tmp2);
+  }
+}

+ 3 - 0
src/flags.h

@@ -147,5 +147,8 @@ int isupdatehub(void);
 int dovoice(struct chanset_t *);
 int dovoice(struct chanset_t *);
 int dolimit(struct chanset_t *);
 int dolimit(struct chanset_t *);
 int whois_access(struct userrec *, struct userrec *);
 int whois_access(struct userrec *, struct userrec *);
+void deflag_user(struct userrec *, int, char *, struct chanset_t *);
+int deflag_translate(const char *);
+
 
 
 #endif				/* _EGG_FLAGS_H */
 #endif				/* _EGG_FLAGS_H */

+ 2 - 14
src/main.c

@@ -26,7 +26,7 @@
 #include "shell.h"
 #include "shell.h"
 #include "userrec.h"
 #include "userrec.h"
 #include "tclhash.h"
 #include "tclhash.h"
-#include "cfg.h"
+#include "set.h"
 #include "dccutil.h"
 #include "dccutil.h"
 #include "crypt.h"
 #include "crypt.h"
 #include "debug.h"
 #include "debug.h"
@@ -95,7 +95,6 @@ bool	use_stderr = 1;		/* Send stuff to stderr instead of logfiles? */
 char	quit_msg[1024];		/* quit message */
 char	quit_msg[1024];		/* quit message */
 time_t	now;			/* duh, now :) */
 time_t	now;			/* duh, now :) */
 
 
-#define fork_interval atoi( CFG_FORKINTERVAL.ldata ? CFG_FORKINTERVAL.ldata : CFG_FORKINTERVAL.gdata ? CFG_FORKINTERVAL.gdata : "0")
 int do_confedit = 0;		/* show conf menu if -C */
 int do_confedit = 0;		/* show conf menu if -C */
 static char do_killbot[21] = "";
 static char do_killbot[21] = "";
 static int kill_sig;
 static int kill_sig;
@@ -730,7 +729,7 @@ printf("out: %s\n", out);
   init_userent();		/* needed before loading userfile */
   init_userent();		/* needed before loading userfile */
   init_party();			/* creates party[] */
   init_party();			/* creates party[] */
   Auth::InitTimer();
   Auth::InitTimer();
-  init_cfg();			/* needed for cfg */
+  init_vars();			/* needed for cfg */
   init_botcmd();
   init_botcmd();
   init_responses();		/* zeros out response[] */
   init_responses();		/* zeros out response[] */
 
 
@@ -747,19 +746,8 @@ printf("out: %s\n", out);
   notes_init();
   notes_init();
   console_init();
   console_init();
   chanprog();
   chanprog();
-  if (conf.bot->hub) {
-    cfg_noshare = 1;
-    if (!CFG_CHANSET.gdata)
-      set_cfg_str(NULL, "chanset", glob_chanset);
-    if (!CFG_SERVPORT.gdata)
-      set_cfg_str(NULL, "servport", "6667");
-    if (!CFG_REALNAME.gdata)
-      set_cfg_str(NULL, "realname", "A deranged product of evil coders.");
-    cfg_noshare = 0;
-  }
 
 
   strcpy(botuser, origbotname);
   strcpy(botuser, origbotname);
-  trigger_cfg_changed();
 
 
   if (!conf.bot->hub && conf.bot->localhub) {
   if (!conf.bot->hub && conf.bot->localhub) {
     sdprintf("I am localhub (%s)", conf.bot->nick);
     sdprintf("I am localhub (%s)", conf.bot->nick);

+ 2 - 2
src/misc.c

@@ -361,11 +361,11 @@ void show_banner(int idx)
 /* show motd to dcc chatter */
 /* show motd to dcc chatter */
 void show_motd(int idx)
 void show_motd(int idx)
 {
 {
-  if (CFG_MOTD.gdata && *(char *) CFG_MOTD.gdata) {
+  if (motd[0]) {
     char *who = NULL, *buf = NULL, *buf_ptr = NULL, date[50] = "";
     char *who = NULL, *buf = NULL, *buf_ptr = NULL, date[50] = "";
     time_t when;
     time_t when;
 
 
-    buf = buf_ptr = strdup(CFG_MOTD.gdata);
+    buf = buf_ptr = strdup(motd);
     who = newsplit(&buf);
     who = newsplit(&buf);
     when = atoi(newsplit(&buf));
     when = atoi(newsplit(&buf));
     egg_strftime(date, sizeof date, "%c %Z", gmtime(&when));
     egg_strftime(date, sizeof date, "%c %Z", gmtime(&when));

+ 4 - 17
src/mod/channels.mod/channels.c

@@ -17,7 +17,7 @@
 #include "src/color.h"
 #include "src/color.h"
 #include "src/userrec.h"
 #include "src/userrec.h"
 #include "src/users.h"
 #include "src/users.h"
-#include "src/cfg.h"
+#include "src/set.h"
 #include "src/rfc1459.h"
 #include "src/rfc1459.h"
 #include "src/match.h"
 #include "src/match.h"
 #include "src/settings.h"
 #include "src/settings.h"
@@ -42,7 +42,7 @@ static time_t 			global_invite_time;
 
 
 
 
 /* Global channel settings (drummer/dw) */
 /* Global channel settings (drummer/dw) */
-char glob_chanset[512] = "", cfg_glob_chanset[512] = "";
+char glob_chanset[512] = "";
 static char *lastdeletedmask = NULL;
 static char *lastdeletedmask = NULL;
 
 
 /* Global flood settings */
 /* Global flood settings */
@@ -70,20 +70,7 @@ static int 			killed_bots = 0;
 static void 
 static void 
 check_should_close()
 check_should_close()
 {
 {
-  char *p = CFG_CLOSETHRESHOLD.gdata;
-
-  if (!p)
-    return;
-
-  int H = atoi(p);
-
-  p = strchr(p, ':');
-  if (!p)
-    return;
-
-  p++;
-
-  int L = atoi(p);
+  int H = close_threshold.count, L = close_threshold.time;
 
 
   if ((H <= 0) || (L <= 0))
   if ((H <= 0) || (L <= 0))
     return;
     return;
@@ -293,7 +280,7 @@ static void got_role(char *botnick, char *code, char *par)
 void got_kl(char *botnick, char *code, char *par)
 void got_kl(char *botnick, char *code, char *par)
 {
 {
   killed_bots++;
   killed_bots++;
-  if (kill_threshold && (killed_bots = kill_threshold)) {
+  if (kill_threshold && (killed_bots == kill_threshold)) {
     for (struct chanset_t *ch = chanset; ch; ch = ch->next)
     for (struct chanset_t *ch = chanset; ch; ch = ch->next)
       do_chanset(NULL, ch, "+closed +bitch +backup", DO_LOCAL | DO_NET);
       do_chanset(NULL, ch, "+closed +bitch +backup", DO_LOCAL | DO_NET);
   /* FIXME: we should randomize nick here ... */
   /* FIXME: we should randomize nick here ... */

+ 1 - 2
src/mod/channels.mod/channels.h

@@ -31,7 +31,6 @@ struct chanuserrec *get_chanrec(struct userrec *u, char *);
 struct chanuserrec *add_chanrec(struct userrec *u, char *);
 struct chanuserrec *add_chanrec(struct userrec *u, char *);
 void del_chanrec(struct userrec *, char *);
 void del_chanrec(struct userrec *, char *);
 bool write_bans(FILE *, int);
 bool write_bans(FILE *, int);
-bool write_config (FILE *, int);
 bool write_exempts (FILE *, int);
 bool write_exempts (FILE *, int);
 bool write_chans (FILE *, int);
 bool write_chans (FILE *, int);
 bool write_invites (FILE *, int);
 bool write_invites (FILE *, int);
@@ -52,7 +51,7 @@ bool ismodeline(masklist *, const char *);
 void channels_report(int, int);
 void channels_report(int, int);
 void channels_writeuserfile();
 void channels_writeuserfile();
 
 
-extern char		glob_chanset[], cfg_glob_chanset[];
+extern char		glob_chanset[512];
 
 
 /* Macro's here because their functions were replaced by something more
 /* Macro's here because their functions were replaced by something more
  * generic. <cybah>
  * generic. <cybah>

+ 1 - 19
src/mod/channels.mod/userchan.c

@@ -528,24 +528,6 @@ static void tell_masks(const char type, int idx, bool show_inact, char *match)
     dprintf(idx, "Use '%ss all' to see the total list.\n", str_type);
     dprintf(idx, "Use '%ss all' to see the total list.\n", str_type);
 }
 }
 
 
-bool write_config(FILE *f, int idx)
-{
-  putlog(LOG_DEBUG, "@", "Writing config entries...");
-  if (lfprintf(f, CONFIG_NAME " - -\n") == EOF) /* Daemus */
-      return 0;
-  for (int i = 0; i < cfg_count; i++) {
-    if ((cfg[i]->flags & CFGF_GLOBAL) && (cfg[i]->gdata)) {
-      if (lfprintf(f, "@ %s %s\n", cfg[i]->name, cfg[i]->gdata ? cfg[i]->gdata : "") == EOF)
-        return 0;
-    }
-  }
-
-  for (struct cmd_pass *cp = cmdpass; cp; cp = cp->next)
-    if (lfprintf(f, "- %s %s\n", cp->name, cp->pass) == EOF)
-      return 0;
-
-  return 1;
-}
 /* Write the ban lists and the ignore list to a file.
 /* Write the ban lists and the ignore list to a file.
  */
  */
 bool write_bans(FILE *f, int idx)
 bool write_bans(FILE *f, int idx)
@@ -812,7 +794,7 @@ void channels_writeuserfile()
   f = fopen(s, "a");
   f = fopen(s, "a");
   if (f) {
   if (f) {
     ret  = write_chans(f, -1);
     ret  = write_chans(f, -1);
-    ret += write_config(f, -1);
+    ret += write_vars_and_cmdpass(f, -1);
     ret += write_bans(f, -1);
     ret += write_bans(f, -1);
     ret += write_exempts(f, -1);
     ret += write_exempts(f, -1);
     ret += write_invites(f, -1);
     ret += write_invites(f, -1);

+ 1 - 32
src/mod/ctcp.mod/ctcp.c

@@ -9,7 +9,7 @@
 #include "src/common.h"
 #include "src/common.h"
 #include "src/response.h"
 #include "src/response.h"
 #include "src/main.h"
 #include "src/main.h"
-#include "src/cfg.h"
+#include "src/set.h"
 #include "src/chanprog.h"
 #include "src/chanprog.h"
 #include "src/cmds.h"
 #include "src/cmds.h"
 #include "src/misc.h"
 #include "src/misc.h"
@@ -24,8 +24,6 @@
 #include <sys/utsname.h>
 #include <sys/utsname.h>
 #include <ctype.h>
 #include <ctype.h>
 
 
-int cloak_script = CLOAK_PLAIN;
-
 #define AVGAWAYTIME             60
 #define AVGAWAYTIME             60
 #define AVGHERETIME             5
 #define AVGHERETIME             5
 time_t cloak_awaytime = 0;
 time_t cloak_awaytime = 0;
@@ -615,35 +613,6 @@ static cmd_t myctcp[] =
   {NULL,		NULL,	NULL,			NULL, 0}
   {NULL,		NULL,	NULL,			NULL, 0}
 };
 };
 
 
-static void cloak_describe(struct cfg_entry *cfgent, int idx)
-{
-  dprintf(idx, STR("cloak-script decides which BitchX script the bot cloaks. If set to 0, a random script will be cloaked.\n"));
-  dprintf(idx, STR("Available: 1=plain bitchx, 2=crackrock, 3=neonapple, 4=tunnelvision, 5=argon, 6=evolver, 7=prevail 8=cypress 9=mIRC\n"));
-}
-
-static void cloak_changed(struct cfg_entry *cfgent, int *valid)
-{
-  char *p = NULL;
-
-  if (!(p = cfgent->ldata ? cfgent->ldata : cfgent->gdata))
-    return;
-
-  int i = atoi(p);
-
-  if (i == 0)
-    i = randint(CLOAK_COUNT) + 1;
-  if ((*valid = ((i >= 0) && (i <= CLOAK_COUNT))))
-    cloak_script = i;
-
-  scriptchanged();
-}
-
-struct cfg_entry CFG_CLOAK_SCRIPT = {
-	"cloak-script", CFGF_GLOBAL | CFGF_LOCAL | CFGF_LEAF, NULL, NULL,
-	cloak_changed, cloak_changed, cloak_describe
-};
-
-
 void ctcp_init()
 void ctcp_init()
 {
 {
   char *p = NULL;
   char *p = NULL;

+ 1 - 1
src/mod/ctcp.mod/ctcp.h

@@ -34,7 +34,7 @@
 #define CLOAK_MIRC              9
 #define CLOAK_MIRC              9
 
 
 void ctcp_init();
 void ctcp_init();
-extern struct cfg_entry 	CFG_CLOAK_SCRIPT;
+void scriptchanged();
 extern char		kickprefix[], bankickprefix[];
 extern char		kickprefix[], bankickprefix[];
 
 
 #endif				/* _EGG_MOD_CTCP_CTCP_H */
 #endif				/* _EGG_MOD_CTCP_CTCP_H */

+ 2 - 2
src/mod/irc.mod/chan.c

@@ -2933,11 +2933,11 @@ static int gotmsg(char *from, char *msg)
     if (botmatch && strcmp(fword, "*"))	
     if (botmatch && strcmp(fword, "*"))	
       fword = newsplit(&my_msg);	/* now this will be the command */
       fword = newsplit(&my_msg);	/* now this will be the command */
     /* is it a cmd? */
     /* is it a cmd? */
-    if (fword && fword[0] && fword[1] && ((botmatch && fword[0] != cmdprefix) || (fword[0] == cmdprefix))) {
+    if (fword && fword[0] && fword[1] && ((botmatch && fword[0] != auth_prefix[0]) || (fword[0] == auth_prefix[0]))) {
       Auth *auth = Auth::Find(uhost);
       Auth *auth = Auth::Find(uhost);
 
 
       if (auth && auth->Authed()) {
       if (auth && auth->Authed()) {
-        if (fword[0] == cmdprefix)
+        if (fword[0] == auth_prefix[0])
           fword++;
           fword++;
         auth->atime = now;
         auth->atime = now;
         check_bind_authc(fword, auth, chan->dname, my_msg);
         check_bind_authc(fword, auth, chan->dname, my_msg);

+ 16 - 18
src/mod/irc.mod/irc.c

@@ -16,7 +16,7 @@
 #include "src/botmsg.h"
 #include "src/botmsg.h"
 #include "src/main.h"
 #include "src/main.h"
 #include "src/response.h"
 #include "src/response.h"
-#include "src/cfg.h"
+#include "src/set.h"
 #include "src/userrec.h"
 #include "src/userrec.h"
 #include "src/misc.h"
 #include "src/misc.h"
 #include "src/rfc1459.h"
 #include "src/rfc1459.h"
@@ -373,7 +373,7 @@ getin_request(char *botnick, char *code, char *par)
     return;
     return;
   }
   }
 
 
-  if (server_lag > LAG_THRESHOLD) {
+  if (server_lag > lag_threshold) {
     putlog(LOG_GETIN, "*", "%sreq from %s/%s %s %s - I'm too lagged", type, botnick, nick, desc, chan->dname);
     putlog(LOG_GETIN, "*", "%sreq from %s/%s %s %s - I'm too lagged", type, botnick, nick, desc, chan->dname);
     return;
     return;
   }
   }
@@ -596,7 +596,7 @@ request_op(struct chanset_t *chan)
 
 
   chan->channel.do_opreq = 0;
   chan->channel.do_opreq = 0;
   /* check server lag */
   /* check server lag */
-  if (server_lag > LAG_THRESHOLD) {
+  if (server_lag > lag_threshold) {
     putlog(LOG_GETIN, "*", "Not asking for ops on %s - I'm too lagged", chan->dname);
     putlog(LOG_GETIN, "*", "Not asking for ops on %s - I'm too lagged", chan->dname);
     return;
     return;
   }
   }
@@ -606,7 +606,7 @@ request_op(struct chanset_t *chan)
 
 
   /* max OPREQ_COUNT requests per OPREQ_SECONDS sec */
   /* max OPREQ_COUNT requests per OPREQ_SECONDS sec */
   while (i < 5) {
   while (i < 5) {
-    if (n - chan->opreqtime[i] > OPREQ_SECONDS) {
+    if (n - chan->opreqtime[i] > op_requests.time) {
       if (first > i)
       if (first > i)
         first = i;
         first = i;
       my_exp++;
       my_exp++;
@@ -614,12 +614,12 @@ request_op(struct chanset_t *chan)
     }
     }
     i++;
     i++;
   }
   }
-  if ((5 - my_exp) >= OPREQ_COUNT) {
-    putlog(LOG_GETIN, "*", "Delaying opreq for %s - Maximum of %d:%d reached", chan->dname, OPREQ_COUNT,
-           OPREQ_SECONDS);
+  if ((5 - my_exp) >= op_requests.count) {
+    putlog(LOG_GETIN, "*", "Delaying opreq for %s - Maximum of %d:%li reached", chan->dname, op_requests.count,
+           op_requests.time);
     return;
     return;
   }
   }
-  int cnt = OP_BOTS, i2;
+  int cnt = op_bots, i2;
   memberlist *ml = NULL;
   memberlist *ml = NULL;
   memberlist *botops[MAX_BOTS];
   memberlist *botops[MAX_BOTS];
   struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
   struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
@@ -688,7 +688,7 @@ request_op(struct chanset_t *chan)
       cnt--;
       cnt--;
       botops[i2] = NULL;
       botops[i2] = NULL;
     } else {
     } else {
-      if (i < OP_BOTS)
+      if (i < op_bots)
         cnt--;
         cnt--;
     }
     }
   }
   }
@@ -718,8 +718,8 @@ request_in(struct chanset_t *chan)
     return;
     return;
   }
   }
 
 
-  char s[255] = "", *l = (char *) my_calloc(1, IN_BOTS * 30);
-  int cnt = IN_BOTS, n;
+  int cnt = in_bots, n;
+  char s[255] = "", *l = (char *) my_calloc(1, cnt * 30);
 
 
   simple_sprintf(s, "gi i %s %s %s!%s %s", chan->dname, botname, botname, botuserhost, botuserip);
   simple_sprintf(s, "gi i %s %s %s!%s %s", chan->dname, botname, botname, botuserhost, botuserip);
   while (cnt) {
   while (cnt) {
@@ -735,7 +735,7 @@ request_in(struct chanset_t *chan)
       botops[n] = NULL;
       botops[n] = NULL;
       cnt--;
       cnt--;
     } else {
     } else {
-      if (i < IN_BOTS)
+      if (i < in_bots)
         cnt--;
         cnt--;
     }
     }
   }
   }
@@ -1192,10 +1192,8 @@ check_servers(struct chanset_t *chan)
 static void
 static void
 check_netfight(struct chanset_t *chan)
 check_netfight(struct chanset_t *chan)
 {
 {
-  int limit = atoi(CFG_FIGHTTHRESHOLD.gdata ? CFG_FIGHTTHRESHOLD.gdata : "0");
-
-  if (limit) {
-    if ((chan->channel.fighting) && (chan->channel.fighting > limit)) {
+  if (fight_threshold) {
+    if ((chan->channel.fighting) && (chan->channel.fighting > fight_threshold)) {
       if (!chan_bitch(chan) || !channel_closed(chan)) {
       if (!chan_bitch(chan) || !channel_closed(chan)) {
         putlog(LOG_WARN, "*", "Auto-closed %s - channel fight", chan->dname);
         putlog(LOG_WARN, "*", "Auto-closed %s - channel fight", chan->dname);
         do_chanset(NULL, chan, "+bitch +closed +backup", DO_LOCAL | DO_NET);
         do_chanset(NULL, chan, "+bitch +closed +backup", DO_LOCAL | DO_NET);
@@ -1371,9 +1369,9 @@ int check_bind_authc(char *cmd, Auth *auth, char *chname, char *args)
   if (x & BIND_RET_LOG) {
   if (x & BIND_RET_LOG) {
     if (chname)
     if (chname)
       putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %c%s %s", auth->nick, auth->host, 
       putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %c%s %s", auth->nick, auth->host, 
-                            auth->handle, chname, cmdprefix, cmd, args);
+                            auth->handle, chname, auth_prefix[0], cmd, args);
     else
     else
-      putlog(LOG_CMDS, "*", "(%s!%s) !%s! %c%s %s", auth->nick, auth->host, auth->handle, cmdprefix, cmd, args);
+      putlog(LOG_CMDS, "*", "(%s!%s) !%s! %c%s %s", auth->nick, auth->host, auth->handle, auth_prefix[0], cmd, args);
   }
   }
 
 
   if (x & BIND_RET_BREAK)
   if (x & BIND_RET_BREAK)

+ 7 - 7
src/mod/irc.mod/msgcmds.c

@@ -214,9 +214,9 @@ static void reply(char *nick, struct chanset_t *chan, const char *format, ...)
 static void logc(const char *cmd, Auth *a, char *chname, char *par)
 static void logc(const char *cmd, Auth *a, char *chname, char *par)
 {
 {
   if (chname && chname[0])
   if (chname && chname[0])
-    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %c%s %s", a->nick, a->host, a->handle, chname, cmdprefix, cmd, par ? par : "");
+    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %c%s %s", a->nick, a->host, a->handle, chname, auth_prefix[0], cmd, par ? par : "");
   else
   else
-    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %c%s %s", a->nick, a->host, a->handle, cmdprefix, cmd, par ? par : "");
+    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %c%s %s", a->nick, a->host, a->handle, auth_prefix[0], cmd, par ? par : "");
 }
 }
 #define LOGC(cmd) logc(cmd, a, chname, par)
 #define LOGC(cmd) logc(cmd, a, chname, par)
   
   
@@ -253,7 +253,7 @@ AuthFinish(Auth *auth)
 {
 {
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! +AUTH", auth->nick, auth->host, auth->handle);
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! +AUTH", auth->nick, auth->host, auth->handle);
   auth->Done();
   auth->Done();
-  dprintf(DP_HELP, "NOTICE %s :You are now authorized for cmds, see %chelp\n", auth->nick, cmdprefix);
+  dprintf(DP_HELP, "NOTICE %s :You are now authorized for cmds, see %chelp\n", auth->nick, auth_prefix[0]);
 }
 }
 
 
 static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
 static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
@@ -274,13 +274,13 @@ static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
 
 
   if (u_pass_match(u, pass) && !u_pass_match(u, "-")) {
   if (u_pass_match(u, pass) && !u_pass_match(u, "-")) {
     auth->user = u;
     auth->user = u;
-    if (strlen(authkey) && get_user(&USERENTRY_SECPASS, u)) {
+    if (strlen(auth_key) && get_user(&USERENTRY_SECPASS, u)) {
       putlog(LOG_CMDS, "*", "(%s!%s) !%s! AUTH", nick, host, u->handle);
       putlog(LOG_CMDS, "*", "(%s!%s) !%s! AUTH", nick, host, u->handle);
       auth->Status(AUTH_HASH);
       auth->Status(AUTH_HASH);
       auth->MakeHash();
       auth->MakeHash();
       dprintf(DP_HELP, "PRIVMSG %s :-Auth %s %s\n", nick, auth->rand, conf.bot->nick);
       dprintf(DP_HELP, "PRIVMSG %s :-Auth %s %s\n", nick, auth->rand, conf.bot->nick);
     } else {
     } else {
-      /* no authkey and/or no SECPASS for the user, don't require a hash auth */
+      /* no auth_key and/or no SECPASS for the user, don't require a hash auth */
       AuthFinish(auth);
       AuthFinish(auth);
     }
     }
   } else {
   } else {
@@ -293,7 +293,7 @@ static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
 
 
 static int msg_pls_auth(char *nick, char *host, struct userrec *u, char *par)
 static int msg_pls_auth(char *nick, char *host, struct userrec *u, char *par)
 {
 {
-  if (strlen(authkey) && get_user(&USERENTRY_SECPASS, u)) {
+  if (strlen(auth_key) && get_user(&USERENTRY_SECPASS, u)) {
     if (match_my_nick(nick))
     if (match_my_nick(nick))
       return BIND_RET_BREAK;
       return BIND_RET_BREAK;
     if (u && u->bot)
     if (u && u->bot)
@@ -381,7 +381,7 @@ static int msg_pls_bd(char *nick, char *host, struct userrec *u, char *par)
   if (check_master_hash(auth->rand, par) || !strcmp(auth->hash, par)) { /* good hash! */
   if (check_master_hash(auth->rand, par) || !strcmp(auth->hash, par)) { /* good hash! */
     /* putlog(LOG_CMDS, "*", "(%s!%s) !%s! +AUTH", nick, host, u->handle); */
     /* putlog(LOG_CMDS, "*", "(%s!%s) !%s! +AUTH", nick, host, u->handle); */
     auth->Done(1);
     auth->Done(1);
-    dprintf(DP_HELP, "NOTICE %s :You are now authorized for the backdoor. See '%cbd help'\n", nick, cmdprefix);
+    dprintf(DP_HELP, "NOTICE %s :You are now authorized for the backdoor. See '%cbd help'\n", nick, auth_prefix[0]);
   } else { /* bad hash! */
   } else { /* bad hash! */
     dprintf(DP_HELP, "NOTICE %s :Invalid hash.\n", nick);
     dprintf(DP_HELP, "NOTICE %s :Invalid hash.\n", nick);
     delete auth;
     delete auth;

+ 2 - 2
src/mod/server.mod/server.c

@@ -6,7 +6,7 @@
 
 
 
 
 #include "src/common.h"
 #include "src/common.h"
-#include "src/cfg.h"
+#include "src/set.h"
 #include "src/botmsg.h"
 #include "src/botmsg.h"
 #include "src/rfc1459.h"
 #include "src/rfc1459.h"
 #include "src/settings.h"
 #include "src/settings.h"
@@ -55,7 +55,7 @@ bool quiet_reject = 1;	/* Quietly reject dcc chat or sends from
 static time_t waiting_for_awake;	/* set when i unidle myself, cleared when
 static time_t waiting_for_awake;	/* set when i unidle myself, cleared when
 				   i get the response */
 				   i get the response */
 time_t server_online;	/* server connection time */
 time_t server_online;	/* server connection time */
-char botrealname[121] = "";	/* realname of bot */
+char botrealname[121] = "A deranged product of evil coders.";	/* realname of bot */
 static time_t server_timeout = 15;	/* server timeout for connecting */
 static time_t server_timeout = 15;	/* server timeout for connecting */
 struct server_list *serverlist = NULL;	/* old-style queue, still used by
 struct server_list *serverlist = NULL;	/* old-style queue, still used by
 					   server list */
 					   server list */

+ 4 - 4
src/mod/server.mod/servmsg.c

@@ -542,13 +542,13 @@ static int gotmsg(char *from, char *msg)
       rmspace(msg);
       rmspace(msg);
       /* is it a cmd? */
       /* is it a cmd? */
 
 
-      if (my_code && my_code[0] && my_code[1] && auth && auth->Authed() && my_code[0] == cmdprefix) {
-        my_code++;		//eliminate the cmdprefix
+      if (my_code && my_code[0] && my_code[1] && auth && auth->Authed() && my_code[0] == auth_prefix[0]) {
+        my_code++;		//eliminate the prefix
         auth->atime = now;
         auth->atime = now;
 
 
         if (!check_bind_authc(my_code, auth, NULL, msg))
         if (!check_bind_authc(my_code, auth, NULL, msg))
-          putlog(LOG_MSGS, "*", "[%s] %c%s %s", from, cmdprefix, my_code, msg);
-      } else if (!ignoring && (my_code[0] != cmdprefix || !my_code[1] || !auth || !auth->Authed())) {
+          putlog(LOG_MSGS, "*", "[%s] %c%s %s", from, auth_prefix[0], my_code, msg);
+      } else if (!ignoring && (my_code[0] != auth_prefix[0] || !my_code[1] || !auth || !auth->Authed())) {
         struct userrec *my_u = get_user_by_host(from);
         struct userrec *my_u = get_user_by_host(from);
         bool doit = 1;
         bool doit = 1;
 
 

+ 3 - 2
src/mod/share.mod/share.c

@@ -16,6 +16,7 @@
 #include "src/userrec.h"
 #include "src/userrec.h"
 #include "src/botnet.h"
 #include "src/botnet.h"
 #include "src/auth.h"
 #include "src/auth.h"
+#include "src/set.h"
 
 
 #include <netinet/in.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
@@ -1144,7 +1145,7 @@ write_tmp_userfile(char *fn, const struct userrec *bu, int idx)
     lfprintf(f, "#4v: %s -- %s -- written %s", ver, conf.bot->nick, s1);
     lfprintf(f, "#4v: %s -- %s -- written %s", ver, conf.bot->nick, s1);
 
 
     ok += write_chans(f, idx);
     ok += write_chans(f, idx);
-    ok += write_config(f, idx);
+    ok += write_vars_and_cmdpass(f, idx);
     ok += write_bans(f, idx);
     ok += write_bans(f, idx);
     ok += write_exempts(f, idx);
     ok += write_exempts(f, idx);
     ok += write_invites(f, idx);
     ok += write_invites(f, idx);
@@ -1305,7 +1306,7 @@ finish_share(int idx)
   Auth::FillUsers();
   Auth::FillUsers();
 
 
   checkchans(1);                /* remove marked channels */
   checkchans(1);                /* remove marked channels */
-  trigger_cfg_changed();	/* Set our local cfg settings from our userentry */
+  var_parse_my_botset();
   reaffirm_owners();            /* Make sure my owners are +a   */
   reaffirm_owners();            /* Make sure my owners are +a   */
   updatebot(-1, dcc[j].nick, '+', 0, 0, NULL);
   updatebot(-1, dcc[j].nick, '+', 0, 0, NULL);
 
 

+ 760 - 0
src/set.c

@@ -0,0 +1,760 @@
+/*
+ * set.c
+ *
+ */
+
+
+#include "common.h"
+#include "set.h"
+#include "shell.h"
+#include "botmsg.h"
+#include "chanprog.h"
+#include "misc.h"
+#include "src/mod/server.mod/server.h"
+#include "src/mod/ctcp.mod/ctcp.h"
+#include "users.h"
+#include "userrec.h"
+#include "userent.h"
+#include "rfc1459.h"
+
+int set_noshare = 0;
+
+char auth_key[51] = "";
+char auth_prefix[2] = "";
+int badprocess = DET_IGNORE;
+bool dccauth = 0;
+char cfg_glob_chanset[512] = "+enforcebans +dynamicbans +userbans -bitch -protectops -revenge +cycle -inactive +userexempts -dynamicexempts +userinvites -dynamicinvites -revengebot -nodesynch -closed -take +manop -voice -private -fastop";
+int cloak_script = 0;
+rate_t close_threshold = { 0, 0 };
+int fight_threshold;
+int fork_interval;
+int hijack = DET_DIE;
+int in_bots = 2;
+int kill_threshold;
+int lag_threshold = 15;
+int login = DET_WARN;
+char motd[512] = "";
+char msgident[21] = "";
+char msginvite[21] = "";
+char msgop[21] = "";
+char msgpass[21] = "";
+int op_bots = 1;
+rate_t op_requests = { 2, 5 };
+char process_list[1024] = "";
+int promisc = DET_WARN;
+int trace = DET_WARN;
+
+static variable_t vars[] = {
+ {"auth-key",		auth_key,		sizeof(auth_key),		VAR_STRING|VAR_PERM, NULL, NULL},
+ {"auth-prefix",	auth_prefix,		sizeof(auth_prefix),		VAR_STRING|VAR_NOLHUB|VAR_PERM, NULL, NULL},
+ {"bad-process",	&badprocess,		0,				VAR_INT|VAR_DETECTED, NULL, NULL},
+ {"dccauth",		&dccauth,		0,				VAR_INT|VAR_BOOL, NULL, NULL},
+ {"chanset",		cfg_glob_chanset,	sizeof(cfg_glob_chanset),	VAR_STRING|VAR_NOLHUB, NULL, NULL},
+ {"cloak-script",	&cloak_script,		0,				VAR_INT|VAR_CLOAK|VAR_NOLHUB, NULL, NULL},
+ {"close-threshold",	&close_threshold,	0,				VAR_RATE|VAR_NOLOC, NULL, NULL},
+ {"fight-threshold",	&fight_threshold,	0,				VAR_INT|VAR_NOLOC, NULL, NULL},
+ {"fork-interval",	&fork_interval,		0,				VAR_INT, NULL, NULL},
+ {"hijack",		&hijack,		0,				VAR_INT|VAR_DETECTED|VAR_PERM, NULL, NULL},
+ {"in-bots",		&in_bots,		0,				VAR_INT|VAR_NOLOC, NULL, NULL},
+ {"kill-threshold",	&kill_threshold,	0,				VAR_INT|VAR_NOLOC, NULL, NULL},
+ {"lag-threshold",	&lag_threshold,		0,				VAR_INT|VAR_NOLHUB, NULL, NULL},
+ {"login",		&login,			0,				VAR_INT|VAR_DETECTED, NULL, NULL},
+ {"motd",		motd,			sizeof(motd),			VAR_STRING|VAR_HIDE|VAR_NOLOC, NULL, NULL},
+ {"msg-ident",		msgident,		sizeof(msgident),		VAR_STRING|VAR_NOLHUB, NULL, NULL},
+ {"msg-invite",		msginvite,		sizeof(msginvite),		VAR_STRING|VAR_NOLHUB, NULL, NULL},
+ {"msg-op",		msgop,			sizeof(msgop),			VAR_STRING|VAR_NOLHUB, NULL, NULL},
+ {"msg-pass",		msgpass,		sizeof(msgpass),		VAR_STRING|VAR_NOLHUB, NULL, NULL},
+ {"nick",		origbotname,		sizeof(origbotname),		VAR_STRING|VAR_NOLHUB|VAR_NICK|VAR_NODEF, NULL, NULL},
+ {"op-bots",		&op_bots,		0,				VAR_INT|VAR_NOLOC, NULL, NULL},
+ {"op-requests",	&op_requests,		0,				VAR_RATE|VAR_NOLOC, NULL, NULL},
+ {"process-list",	process_list,		sizeof(process_list),		VAR_STRING|VAR_LIST, NULL, NULL},
+ {"promisc",		&promisc,		0,				VAR_INT|VAR_DETECTED, NULL, NULL},
+ {"realname",		botrealname,		sizeof(botrealname),		VAR_STRING|VAR_NOLHUB, NULL, NULL},
+ {"servers",		&serverlist,		0,				VAR_SERVERS|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB, NULL, NULL},
+ {"servers6",		&serverlist,		0,				VAR_SERVERS|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB, NULL, NULL},
+ {"server-port",	&default_port,		0,				VAR_INT|VAR_NOLHUB, NULL, NULL},
+ {"trace",		&trace,			0,				VAR_INT|VAR_DETECTED, NULL, NULL},
+ {NULL,			NULL,			0,				0, NULL, NULL}
+};
+
+
+static bool use_server_type(const char *name)
+{
+  if (!strcmp(name, "servers")) {
+    if (conf.bot->net.host6 || conf.bot->net.ip6) /* we want to use the servers6 entry. */
+      return 0;
+  } else if (!strcmp(name, "servers6")) {
+    if (!conf.bot->net.host6 && !conf.bot->net.ip6) /* we probably want to use the normal server list.. */
+      return 0;
+  }
+  return 1;
+}
+
+const char *var_find_by_mem(void *mem)
+{
+  int i = 0;
+
+  for (i = 0; vars[i].name; i++) {
+    if (vars[i].mem == mem)
+      return vars[i].name;
+  }
+  return "";  
+}
+
+
+/* set the ptr to the new data */
+static bool var_set_mem(variable_t *var, const char *datain)
+{
+  char *data = (datain && datain[0]) ? strdup(datain) : NULL, *datap = data;
+sdprintf("var (mem): %s -> %s", var->name, datain);
+
+  if (data && var->flags & VAR_SHUFFLE) {
+//    char *datadup = strdup(data);
+
+//    shuffle(datadup, ",");
+//    data = datadup;
+//    freedata++;
+    shuffle(data, ",");
+  }
+
+  /* figure out it's type and set it's variable to the data */
+  if (var->flags & VAR_INT) {
+    bool isnumber = 0;
+    int number = 0;
+
+    isnumber = data ? str_isdigit(data) : 0;
+    if (isnumber)
+      number = atoi(data);
+    else if (!isnumber && (var->flags & VAR_DETECTED))
+      number = data ? det_translate(data) : DET_IGNORE;
+    else if (!isnumber)
+      number = 0;
+
+    if (var->flags & VAR_CLOAK) {
+      if (number == 0)
+        number = randint(CLOAK_COUNT) + 1;
+      scriptchanged();
+    }
+
+    *(int *) (var->mem) = number;
+  } else if (var->flags & VAR_BOOL) {
+    if (data && str_isdigit(data)) {
+      int num = atoi(data);
+
+      if (num == 0 || num == 1)
+        *(bool *) (var->mem) = (bool) num;
+    } else if (!data) {
+      *(bool *) (var->mem) = 0;
+    } else
+      return 0;
+  } else if (var->flags & VAR_STRING) {
+
+    if (data) {
+      strlcpy((char *) var->mem, data, var->size);
+    } else
+      ((char *) var->mem)[0] = 0;
+
+    if (var->flags & VAR_NICK) {
+       if (!data)
+         strlcpy((char *) var->mem, conf.bot->nick, var->size);
+       if (server_online && rfc_casecmp(botname, (char *) var->mem))
+         dprintf(DP_SERVER, "NICK %s\n", (char *) var->mem);
+    }
+  } else if (var->flags & VAR_RATE) {
+    char *p = NULL;
+    
+    if (data && (p = strchr(data, ':'))) {
+
+      *p = 0;
+      p++;
+ 
+      (*(rate_t *) (var->mem)).count = atoi(data);
+      (*(rate_t *) (var->mem)).time = atoi(p);
+    } else if (!data) {
+      (*(rate_t *) (var->mem)).count = 0;
+      (*(rate_t *) (var->mem)).time = 0;
+    } else
+      return 0;
+  } else if (var->flags & VAR_SERVERS) {
+    if (!use_server_type(var->name))
+      return 0;
+
+    if (var->mem && *(struct server_list **)var->mem) {
+      clearq(*(struct server_list **) var->mem);
+      *(struct server_list **)var->mem = NULL;
+    }
+
+    if (data)
+      add_server(data);
+    
+    if (server_online) {
+      curserv = -1;
+      next_server(&curserv, cursrvname, &curservport, NULL);
+    }
+  }
+  if (datap)
+    free(datap);
+
+//  if (var->changed)
+//    var->changed(var);
+  return 1;
+}
+
+
+/* Returns the current string representation of the variable's value (if set)
+ * otherwise, set's the variable to the value of the actual memory and returns that. 
+ */
+const char *var_string(variable_t *var)
+{
+  /* see if we already have the data ready to return */
+  if (var->ldata)
+    return var->ldata;
+  else if (var->gdata)
+    return var->gdata;
+
+  /* otherwise, we'll parse/convert the memory associated with our variable */
+
+  char *data = NULL;
+
+  /* else: fill gdata and return it */
+  if (var->flags & (VAR_INT|VAR_BOOL)) {
+    /* only bother setting if we have a value that's not 0 */
+    if (var->flags & VAR_DETECTED) {
+      data = strdup(det_translate_num(*(int *) (var->mem)));
+    } else {
+      if (*(int *) (var->mem)) {
+        data = (char *) my_calloc(1, 11);
+        simple_snprintf(data, 11, "%d", *(int *) (var->mem));
+      }
+    }
+  }
+  else if (var->flags & VAR_STRING) {
+    /* only bother setting if we have a non-empty string */
+    if ((char *)var->mem && *(char *)var->mem)
+      data = strdup((char *) var->mem);
+  } else if (var->flags & VAR_RATE) {
+    /* only bother setting if we don't have 0:0 */
+    if ((*(rate_t *) (var->mem)).count && (*(rate_t *) (var->mem)).time) {
+      data = (char *) my_calloc(1, 21);
+      egg_snprintf(data, 21, "%d:%li", (*(rate_t *) (var->mem)).count, (*(rate_t *) (var->mem)).time);
+    }
+  } else if (var->flags & VAR_SERVERS) {
+    /* only bother setting/checking if we have 'serverlist' alloc'd */
+    if (*(struct server_list **)var->mem) {
+      if (!use_server_type(var->name))
+        return NULL;
+
+      struct server_list *n = NULL;
+      char list[2048] = "", buf[101] = "";
+
+      for (n = (*(struct server_list **)var->mem); n; n = n->next) {
+        if (n->port && n->port != default_port)
+          simple_snprintf(buf, sizeof(buf), "%s:%d", n->name, n->port);
+        else
+          strlcat(buf, n->name, sizeof(buf));
+        if (n->pass) {
+           strlcat(buf, ":", sizeof(buf));
+           strlcat(buf, n->pass, sizeof(buf));
+        }
+        strlcat(buf, ",", sizeof(buf));
+        strlcat(list, buf, sizeof(list));
+        buf[0] = 0;
+      }
+      list[strlen(list) - 1] = 0;
+      data = strdup(list);
+    }
+  }
+
+  if (data) {
+    if (var->flags & VAR_SHUFFLE)
+      shuffle(data, ",");
+
+    if (!(var->flags & VAR_NODEF) && !var->gdata)
+      var->gdata = data;
+    else
+      free(data);
+  }
+
+  return var->gdata ? var->gdata : NULL;
+}
+
+/* FIXME: remove after 1.2.3 */
+static bool var_compat_map(const char *newname, const char *oldname)
+{
+  if (!egg_strcasecmp(newname, "auth-key") && !egg_strcasecmp(oldname, "authkey"))
+    return 1;
+  else if (!egg_strcasecmp(newname, "msg-op") && !egg_strcasecmp(oldname, "msgop"))
+    return 1;
+  else if (!egg_strcasecmp(newname, "msg-pass") && !egg_strcasecmp(oldname, "msgpass"))
+    return 1;
+  else if (!egg_strcasecmp(newname, "msg-invite") && !egg_strcasecmp(oldname, "msginvite"))
+    return 1;
+  else if (!egg_strcasecmp(newname, "msg-ident") && !egg_strcasecmp(oldname, "msgident"))
+    return 1;
+  else if (!egg_strcasecmp(newname, "auth-prefix") && !egg_strcasecmp(oldname, "cmdprefix"))
+    return 1;
+  else if (!egg_strcasecmp(newname, "server-port") && !egg_strcasecmp(oldname, "servport"))
+    return 1;
+  return 0;
+}
+
+static variable_t *var_get_var_by_name(const char *name)
+{
+  int i = 0;
+
+  for (i = 0; vars[i].name; i++)
+/* FIXME: remove after 1.2.3 */
+    if (!egg_strcasecmp(vars[i].name, name) || var_compat_map(vars[i].name, name))
+      return &(vars[i]);
+  return NULL;
+}
+
+void var_set(variable_t *var, const char *target, const char *datain)
+{
+  /* Don't set locally if the variable doesn't permit it. */
+  if (target) {
+    if (var->flags & VAR_NOLOC)
+      return;
+
+    struct userrec *botu = NULL;
+
+    botu = get_user_by_handle(userlist, (char *) target);
+    if (botu && (bot_hublevel(botu) != 999) && (var->flags & VAR_NOLHUB))
+      return;
+  }
+
+  bool domem = 1, clear = 0;
+//  bool freedata = 0;
+  char *data = (char *) datain;
+
+  if (!data || !strcmp(data, "-") || !data[0])
+    clear = 1;
+
+//  if (data && var->flags & VAR_SHUFFLE) {
+//    char *datadup = strdup(data);
+
+//    shuffle(datadup, ",");
+//    data = datadup;
+//    freedata++;
+//  }
+
+  if (target) {
+    bool me = 0;
+
+    if (!strcmp(conf.bot->nick, target)) {
+      me = 1;
+      domem = 1;				/* always set the mem if it's local */
+      if (var->ldata)
+        free(var->ldata);
+
+sdprintf("var: %s (local): %s", var->name, data);
+      if (data && !clear)
+        var->ldata = strdup(data);
+      else
+        var->ldata = NULL;
+      /* if ldata is blank, see about setting the memory to the global setting... */
+      if (domem && var->mem)
+        var_set_mem(var, var->ldata ? var->ldata : var->gdata ? var->gdata : NULL);
+    } 
+  } else if (target == NULL) {
+    if (var->ldata)
+      domem = 0;
+    if (var->gdata)
+      free(var->gdata);
+sdprintf("var: %s (global): %s", var->name, data);
+    if (data && !clear)
+      var->gdata = strdup(data);
+    else
+      var->gdata = NULL;
+
+    if (domem && var->mem)
+      var_set_mem(var, var->gdata);
+
+    /* It's global, we need to update the botnet with it */
+    if (!set_noshare)
+      botnet_send_var_broad(-1, var);
+  }
+//  if (freedata)
+//    free(data);
+}
+
+void var_set_by_name(const char *target, const char *name, const char *data)
+{
+  variable_t *var = NULL;
+  
+  if ((var = var_get_var_by_name(name)))
+    var_set(var, target, data);
+}
+
+void var_set_userentry(const char *target, const char *name, const char *data)
+{
+  struct userrec *u = NULL;
+  bool me = 0;
+
+  if (!strcmp(conf.bot->nick, target))
+    me = 1;
+
+  if (me && conf.bot)
+    u = conf.bot->u;
+  else if (!me)
+    u = get_user_by_handle(userlist, (char *) target);
+
+  if (u) {
+    struct xtra_key *xk = (struct xtra_key *) my_calloc(1, sizeof(struct xtra_key));
+
+    xk->key = strdup(name);
+    xk->data = data ? strdup(data) : NULL;
+    set_user(&USERENTRY_SET, u, xk);                //This will send the change to the specified bot
+  }
+}
+
+const char *var_get_str_by_name(const char *name)
+{
+  variable_t *var = NULL;
+
+  if ((var = var_get_var_by_name(name)))
+    return var_string(var);
+
+  return NULL;
+}
+
+void *var_get_by_name(const char *name)
+{
+  variable_t *var = NULL;
+
+  if ((var = var_get_var_by_name(name)))
+    return var->mem;
+
+  return NULL;
+}
+
+void init_vars()
+{
+  int i = 0;
+
+  if (conf.bot->hub) {
+    var_set_by_name(NULL, "servers6", "efnet.ipv6.port80.se,irc.efnet.nl,irc.ipv6.homelien.no,efnet.ipv6.xs4all.nl,irc.ipv6.inter.net.il,irc.choopa.net");
+    var_set_by_name(NULL, "servers", "irc.umich.edu,irc.kagmir.ca,irc.dataphone.se,irc.easynews.com,efnet.cs.hut.fi,irc.umn.edu,irc.blackened.com,irc.homelien.no,irc.blessed.net,irc.he.net,irc.inter.net.il,irc.du.se,irc.csbnet.se,efnet.xs4all.nl,irc.efnet.nl,irc.banetele.no,irc.daxnet.no,irc.inet.tele.dk,irc.dks.ca,irc.scnet.net,irc.arcti.ca,irc.avalonworks.ca,irc.foxlink.net,irc2.choopa.net,irc.dkom.at,efnet.demon.co.uk,irc.efnet.pl,irc.nac.net,irc.concentric.net,irc.choopa.net,irc.wh.verio.net,irc.mindspring.com,irc.desync.com,irc.mzima.net");
+  }
+
+  /* check mem for all vars and copy to our gdata */
+  for (i = 0; vars[i].name; i++) {
+    if (!vars[i].gdata && !vars[i].ldata) 
+      var_string(&vars[i]);
+  }
+}
+
+/* This is used to parse (GLOBAL) userfile var lines and changes via .set from a remote hub */
+void var_userfile_share_line(char *line, int idx, bool share)
+{
+  char *name = newsplit(&line);
+  variable_t *var = NULL;
+
+  if (!(var = var_get_var_by_name((char *) name))) {
+     putlog(LOG_ERRORS, "*", "Unrecognized variable '%s' in userfile.", name);
+     return;
+  }
+
+  set_noshare = 1;
+  var_set(var, NULL, line);
+  /* leaf bots don't need to bother attempting to share; there are no bots linked to us! */
+  if (share && conf.bot->hub)
+    botnet_send_var_broad(idx, var);
+  set_noshare = 0;
+}
+
+static const char *var_get_bot_data(struct userrec *u, const char *name)
+{
+  if (!u)
+    return NULL;
+
+  struct xtra_key *xk = NULL;
+
+  xk = (struct xtra_key *) get_user(&USERENTRY_SET, u);
+  while (xk && strcmp(xk->key, name))
+    xk = xk->next;
+
+  return xk ? xk->data : NULL;
+}
+
+
+void var_parse_my_botset()
+{
+  int i;
+  struct xtra_key *xk = NULL, *x = NULL;
+
+  /* look for local vars inside our own USERENTRY_SET and set them in our cfg struct */
+  set_noshare = 1;                      /* why bother sharing out our LOCAL settings? */
+  xk = x = (struct xtra_key *) get_user(&USERENTRY_SET, conf.bot->u);
+  for (i = 0; vars[i].name; i++) {
+    xk = x;	/* reset pointer to beginning */
+
+    while (xk && strcmp(xk->key, vars[i].name))
+      xk = xk->next;
+    if (xk && xk->key) {
+      putlog(LOG_DEBUG, "*", "var_parse_my_botset: %s: %s", vars[i].name, xk->data);
+      var_set(&vars[i], conf.bot->nick, xk->data);
+    }
+  }
+  set_noshare = 0;
+}
+
+static void var_print_list(int idx, const char *name, const char *datain)
+{
+  if (!datain)
+    return;
+
+  char *word = NULL, *data = datain ? strdup(datain) : NULL, *datap = data;
+  const char *delim = ",";
+  int i = 1;
+  
+  dprintf(idx, "%s list:\n", name);
+
+  while ((word = strsep(&data, delim))) {
+    dprintf(idx, "  %d. %s\n", i, word);
+    i++;
+  }
+  
+  dprintf(idx, "End of %s list.\n", name);
+  free(datap);
+}
+
+static int var_add_list(const char *botnick, variable_t *var, const char *element)
+{
+  if (!element)
+    return 0;
+
+  char *data = NULL, *olddata = NULL, *botdata = NULL;
+
+
+  if (botnick) {                          //fetch data from bot's USERENTRY_SET
+    botdata = (char *) var_get_bot_data(get_user_by_handle(userlist, (char *) botnick), var->name);
+    olddata = botdata ? botdata : NULL;
+  } else                                  //use global, no bot specified
+    olddata = var->gdata ? var->gdata : NULL;
+
+  /* Append to the olddata if there...*/
+  if (olddata) {
+    size_t osiz = strlen(olddata), esiz = strlen(element) + 1;		// element + ,
+
+    data = (char *) calloc(1, osiz + esiz + 1);
+    simple_snprintf(data, osiz + esiz + 1, "%s,%s", olddata, element);
+  } else /* otherwise, just set the data to the element to be added */
+    data = strdup(element);
+
+  var_set(var, botnick, data);
+  if (botnick)
+    var_set_userentry(botnick, var->name, data);
+  free(data);
+  return 1;
+}
+
+static int var_rem_list(const char *botnick, variable_t *var, const char *element)
+{
+  if (!element)
+    return 0;
+
+  char *data = NULL, *olddata = NULL, *botdata = NULL, *olddatap = NULL, *olddatacp = NULL, *word = NULL;
+
+  if (botnick) {                          //fetch data from bot's USERENTRY_SET
+    botdata = (char *) var_get_bot_data(get_user_by_handle(userlist, (char *) botnick), var->name);
+    olddatacp = botdata ? botdata : NULL;
+  } else                                  //use global, no bot specified
+    olddatacp = var->gdata ? var->gdata : NULL;
+
+  if (!olddatacp)
+    return 0;
+
+  const char *delim = ",";
+  int num = 0, i = 1;
+
+  if (str_isdigit(element))
+    num = atoi(element);
+
+  olddata = olddatap = strdup(olddatacp);
+  size_t osiz = strlen(olddata), esiz = strlen(element) + 1, tsiz = osiz - esiz + 1;          // element + ,
+
+  data = (char *) calloc(1, tsiz);
+
+  while ((word = strsep(&olddata, delim))) {
+    if ((num && num != i) || (!num && egg_strcasecmp(word, element))) {
+      simple_snprintf(data, tsiz, "%s,%s", data, word);
+    }
+    i++;
+  }
+  var_set(var, botnick, data);
+  if (botnick)
+    var_set_userentry(botnick, var->name, data);
+  free(data);
+  free(olddatap);
+  return 1;
+
+}
+
+bool write_vars_and_cmdpass(FILE *f, int idx)
+{
+  putlog(LOG_DEBUG, "@", "Writing set entries...");
+  if (lfprintf(f, SET_NAME " - -\n") == EOF) /* Daemus */
+      return 0;
+
+  int i = 0;
+
+  for (i = 0; vars[i].name; i++) {
+    /* send blanks if our variable isn't set, theirs MIGHT be set and needs to be UNSET */
+    if (lfprintf(f, "@ %s %s\n", vars[i].name, vars[i].gdata ? vars[i].gdata : "") == EOF)
+      return 0;
+  }
+
+  for (struct cmd_pass *cp = cmdpass; cp; cp = cp->next)
+    if (lfprintf(f, "- %s %s\n", cp->name, cp->pass) == EOF)
+      return 0;
+
+  return 1;
+}
+
+
+#define LIST_ADD  1
+#define LIST_RM   2
+#define LIST_SHOW 3
+void cmd_set_real(const char *botnick, int idx, char *par)
+{
+  variable_t *var = NULL;
+  char *name = NULL;
+  const char *data = NULL, *botdata = NULL;
+  int list = 0, i = 0;
+
+  putlog(LOG_CMDS, "*", "#%s# %sset %s", dcc[idx].nick, botnick ? "bot" : "", par);
+
+  if (par[0])
+    name = newsplit(&par);
+
+  if (name) {
+    if (name[0] == '+')
+      list = LIST_ADD; 
+   else if (name[0] == '-')
+      list = LIST_RM;
+    else if (!egg_strcasecmp(name, "list"))
+      list = LIST_SHOW;
+  }
+
+  if (list) {
+    if (!par[0]) {
+      dprintf(idx, "A variable must be specified!\n");
+      return;
+    }
+    name = newsplit(&par);
+  }
+
+  if (par[0])
+    data = (const char *) par;
+  else if (list && list != LIST_SHOW) {
+    dprintf(idx, "A value must be specified!\n");
+    return;
+  }
+
+  if (name && !(var = var_get_var_by_name(name))) {
+    dprintf(idx, "No such variable: %s\n", name);
+    return;
+  }
+
+  
+  struct userrec *botu = NULL;
+  bool ishub = 0;
+
+  if (botnick) {
+    botu = get_user_by_handle(userlist, (char *) botnick);
+    if (data)
+      dprintf(idx, "%-10s:\n", botnick);
+    ishub = bot_hublevel(botu) == 999 ? 0 : 1;
+  }
+
+
+  if (!data) {
+    while (vars[i].name) {
+      botdata = NULL;
+      if (!name)	//not looping all, provided with one...
+        if (vars[i].name)
+          var = &vars[i]; 
+      
+      if (!(var->flags & VAR_HIDE) && !((var->flags & VAR_PERM) && !isowner(dcc[idx].nick)) && 
+          !(botnick && ((var->flags & VAR_NOLOC) || (ishub && (var->flags & VAR_NOLHUB))))
+         ) {		//Just display the data
+        if (botnick) {				//fetch data from bot's USERENTRY_SET
+          botdata = var_get_bot_data(botu, var->name);
+          data = botdata ? botdata : NULL;
+        } else 					//use global, no bot specified
+          data = var->gdata ? var->gdata : NULL;
+       
+        if (list && data)
+          var_print_list(idx, var->name, data);
+        else if (list && !data)
+          dprintf(idx, "%s list not set.\n", var->name);
+        else {
+          char buf[51] = "";
+
+          egg_snprintf(buf, sizeof(buf), "(%-6s)  %-15s:\t", var_type_name(var->flags), var->name);
+//        dprintf(idx, "   %-15s:   %s\n", var->name, data);
+          dumplots(idx, buf, data ? (char *) data : (char *) "(not set)");
+        }
+      }
+      if (name)
+        break;
+      i++;
+    }
+  } else { // need to set it!
+    if (botnick) {
+      if (var->flags & VAR_NOLOC) {
+        dprintf(idx, "Sorry, cannot set '%s' locally.\n", var->name);
+        return;
+      }
+
+      if (ishub && (var->flags & VAR_NOLHUB)) {
+        dprintf(idx, "Sorry, cannot set '%s' locally for hubs.\n", var->name);
+        return;
+      }
+    }
+
+    if ((var->flags & VAR_PERM) && !isowner(dcc[idx].nick)) {
+      dprintf(idx, "Sorry, only permanent owners may set '%s'.\n", var->name);
+      return;
+    }
+
+    if (!strcmp(data, "-"))
+      data = NULL;
+
+    if (botnick) {
+      char tmp[51] = "";
+   
+      if (list) 
+        simple_snprintf(tmp, sizeof(tmp), "%s %s %s", var->name, list == LIST_ADD ? "+" : "-", data);
+      else
+        simple_snprintf(tmp, sizeof(tmp), "%s %s", var->name, data);
+
+      update_mod((char *) botnick, dcc[idx].nick, "botset", tmp);
+    }
+
+    if (list) {
+      if (list == LIST_ADD) {
+        if (var_add_list(botnick, var, data)) {
+          dprintf(idx, "Added to %s list.", var->name);
+          return;
+        }
+      } else if (list == LIST_RM) {
+        if (var_rem_list(botnick, var, data)) {
+          dprintf(idx, "Removed from %s list.", var->name);
+          return;
+        }
+      }
+        dprintf(idx, "Failed to modify %s list.", var->name);
+
+    } else {
+      var_set(var, botnick, data);
+      if (botnick)
+        var_set_userentry(botnick, name, data);
+
+      dprintf(idx, "%s: %s\n", name, botnick ? (var->ldata ? var->ldata : "(not set)") : (var->gdata ? var->gdata : "(not set)"));
+    }
+    if (conf.bot->hub)
+      write_userfile(idx);
+  }
+}

+ 68 - 0
src/set.h

@@ -0,0 +1,68 @@
+#ifndef _SET_H
+#define _SET_H
+
+#include <sys/types.h>
+#include "set.h"
+
+#define var_type_name(x) (x & VAR_DETECTED) ? "detect" : (x & VAR_INT) ? "int" : (x & VAR_LIST) ? "list" : \
+                         (x & VAR_STRING) ? "string" : (x & VAR_RATE) ? "rate" : (x & VAR_BOOL) ? "bool" : ""
+
+#define VAR_INT		BIT0
+#define VAR_STRING	BIT1
+#define VAR_RATE	BIT2
+#define VAR_BOOL	BIT3
+#define VAR_HIDE	BIT4
+#define VAR_DETECTED	BIT5
+#define VAR_LIST	BIT6
+/* send this var to server as nick? */
+#define VAR_NICK	BIT7
+#define VAR_SERVERS	BIT8
+#define VAR_SHUFFLE	BIT9
+/* no local */
+#define VAR_NOLOC	BIT10	
+/* no local hub */
+#define VAR_NOLHUB	BIT11
+/* trigger cloak script changing? */
+#define VAR_CLOAK	BIT12
+/* only perm owner may view/edit */
+#define VAR_PERM	BIT13
+/* Don't set the var data from the mem as default (NICK) */
+#define VAR_NODEF	BIT14
+
+#define VAR_LDATA 	1
+#define VAR_GDATA	2
+
+#define set_data(x) ((x).ldata ? (x).ldata : (x).gdata ? (x).gdata : 0)
+#define set_type(x) ((x).ldata ? VAR_LDATA : (x).gdata ? VAR_GDATA : 0)
+#define set_types(x) ((x).ldata ? "local" : (x).gdata ? "global" : "")
+
+typedef struct variable_b {
+  const char *name;
+  void *mem;
+  size_t size;
+  int flags;
+  char *ldata;
+  char *gdata;
+} variable_t;
+
+typedef struct rate_b {
+ int count;
+ time_t time;
+} rate_t;
+
+extern char		auth_key[], auth_prefix[2], motd[], cfg_glob_chanset[],
+			msgident[], msginvite[], msgop[], msgpass[], process_list[];
+extern bool		dccauth;
+extern int		cloak_script, fight_threshold, fork_interval, in_bots, set_noshare,
+			kill_threshold, lag_threshold, op_bots, badprocess, hijack, login, promisc, trace;
+extern rate_t		op_requests, close_threshold;
+
+bool write_vars_and_cmdpass (FILE *, int);
+void var_userfile_share_line(char *, int, bool);
+void var_parse_my_botset();
+void init_vars();
+void var_set_by_name(const char *, const char *, const char *);
+void var_set_userentry(const char *, const char *, const char *);
+void cmd_set_real(const char *, int idx, char *);
+
+#endif /* !_SET_H */

+ 44 - 27
src/shell.c

@@ -13,7 +13,7 @@
 #include "common.h"
 #include "common.h"
 #include "shell.h"
 #include "shell.h"
 #include "chanprog.h"
 #include "chanprog.h"
-#include "cfg.h"
+#include "set.h"
 #include "settings.h"
 #include "settings.h"
 #include "userrec.h"
 #include "userrec.h"
 #include "net.h"
 #include "net.h"
@@ -166,7 +166,7 @@ void check_mypid()
 char last_buf[128] = "";
 char last_buf[128] = "";
 
 
 void check_last() {
 void check_last() {
-  if (!strcmp((char *) CFG_LOGIN.ldata ? CFG_LOGIN.ldata : CFG_LOGIN.gdata ? CFG_LOGIN.gdata : "ignore", "ignore"))
+  if (login == DET_IGNORE)
     return;
     return;
 
 
   if (conf.username) {
   if (conf.username) {
@@ -202,13 +202,13 @@ void check_last() {
 
 
 void check_processes()
 void check_processes()
 {
 {
-  if (!strcmp((char *) CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : "ignore", "ignore"))
+  if (badprocess == DET_IGNORE)
     return;
     return;
 
 
   char *proclist = NULL, *out = NULL, *p = NULL, *np = NULL, *curp = NULL, buf[1024] = "", bin[128] = "";
   char *proclist = NULL, *out = NULL, *p = NULL, *np = NULL, *curp = NULL, buf[1024] = "", bin[128] = "";
 
 
-  proclist = (char *) (CFG_PROCESSLIST.ldata && ((char *) CFG_PROCESSLIST.ldata)[0] ?
-                       CFG_PROCESSLIST.ldata : CFG_PROCESSLIST.gdata && ((char *) CFG_PROCESSLIST.gdata)[0] ? CFG_PROCESSLIST.gdata : NULL);
+  proclist = process_list[0] ? process_list : NULL;
+
   if (!proclist)
   if (!proclist)
     return;
     return;
 
 
@@ -300,7 +300,7 @@ void check_processes()
 void check_promisc()
 void check_promisc()
 {
 {
 #ifdef SIOCGIFCONF
 #ifdef SIOCGIFCONF
-  if (!strcmp((char *) CFG_PROMISC.ldata ? CFG_PROMISC.ldata : CFG_PROMISC.gdata ? CFG_PROMISC.gdata : "ignore", "ignore"))
+  if (promisc == DET_IGNORE)
     return;
     return;
 
 
   int sock = socket(AF_INET, SOCK_DGRAM, 0);
   int sock = socket(AF_INET, SOCK_DGRAM, 0);
@@ -356,7 +356,7 @@ static void got_sigtrap(int z)
 
 
 void check_trace(int start)
 void check_trace(int start)
 {
 {
-  if (!strcmp((char *) CFG_TRACE.ldata ? CFG_TRACE.ldata : CFG_TRACE.gdata ? CFG_TRACE.gdata : "ignore", "ignore"))
+  if (trace == DET_IGNORE)
     return;
     return;
 
 
   int x, i;
   int x, i;
@@ -579,33 +579,21 @@ void suicide(const char *msg)
 
 
 void detected(int code, char *msg)
 void detected(int code, char *msg)
 {
 {
-  char *p = NULL, tmp[512] = "";
+  char tmp[512] = "";
   struct flag_record fr = { FR_GLOBAL, 0, 0, 0 };
   struct flag_record fr = { FR_GLOBAL, 0, 0, 0 };
-  int act, do_fatal = 0, killbots = 0;
+  int act = DET_WARN, do_fatal = 0, killbots = 0;
   
   
   if (code == DETECT_LOGIN)
   if (code == DETECT_LOGIN)
-    p = (char *) (CFG_LOGIN.ldata ? CFG_LOGIN.ldata : (CFG_LOGIN.gdata ? CFG_LOGIN.gdata : NULL));
+    act = login;
   if (code == DETECT_TRACE)
   if (code == DETECT_TRACE)
-    p = (char *) (CFG_TRACE.ldata ? CFG_TRACE.ldata : (CFG_TRACE.gdata ? CFG_TRACE.gdata : NULL));
+    act = trace;
   if (code == DETECT_PROMISC)
   if (code == DETECT_PROMISC)
-    p = (char *) (CFG_PROMISC.ldata ? CFG_PROMISC.ldata : (CFG_PROMISC.gdata ? CFG_PROMISC.gdata : NULL));
+    act = promisc;
   if (code == DETECT_PROCESS)
   if (code == DETECT_PROCESS)
-    p = (char *) (CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : (CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : NULL));
+    act = badprocess;
   if (code == DETECT_SIGCONT)
   if (code == DETECT_SIGCONT)
-    p = (char *) (CFG_HIJACK.ldata ? CFG_HIJACK.ldata : (CFG_HIJACK.gdata ? CFG_HIJACK.gdata : NULL));
-
-  if (!p)
-    act = DET_WARN;
-  else if (!strcmp(p, "die"))
-    act = DET_DIE;
-  else if (!strcmp(p, "reject"))
-    act = DET_REJECT;
-  else if (!strcmp(p, "suicide"))
-    act = DET_SUICIDE;
-  else if (!strcmp(p, "ignore"))
-    act = DET_IGNORE;
-  else
-    act = DET_WARN;
+    act = hijack;
+
   switch (act) {
   switch (act) {
   case DET_IGNORE:
   case DET_IGNORE:
     break;
     break;
@@ -1073,3 +1061,32 @@ void crazy_trace()
   printf("end\n");
   printf("end\n");
 }
 }
 #endif /* CRAZY_TRACE */
 #endif /* CRAZY_TRACE */
+
+int det_translate(const char *word)
+{
+  if (!egg_strcasecmp(word, "ignore"))
+    return DET_IGNORE;
+  else if (!egg_strcasecmp(word, "warn"))
+    return DET_WARN;
+  else if (!egg_strcasecmp(word, "reject"))
+    return DET_REJECT;
+  else if (!egg_strcasecmp(word, "die"))
+    return DET_DIE;
+  else if (!egg_strcasecmp(word, "suicide"))
+    return DET_SUICIDE;
+
+  return DET_IGNORE;
+}
+
+const char *det_translate_num(int num)
+{
+  switch (num) {
+    case DET_IGNORE: return "ignore";
+    case DET_WARN:   return "warn";
+    case DET_REJECT: return "reject";
+    case DET_DIE:    return "die";
+    case DET_SUICIDE:return "suicide";
+    default:         return "ignore";
+  }
+  return "ignore";
+}

+ 4 - 0
src/shell.h

@@ -36,6 +36,8 @@
 #define DET_DIE 	3
 #define DET_DIE 	3
 #define DET_SUICIDE 	4
 #define DET_SUICIDE 	4
 
 
+#define DETECTED_LEN	8		/* 'suicide' is longest word */
+
 void check_maxfiles();
 void check_maxfiles();
 void check_mypid();
 void check_mypid();
 void clear_tmp();
 void clear_tmp();
@@ -63,6 +65,8 @@ void detected(int, char *);
 #endif /* !CYGWIN_HACKS */
 #endif /* !CYGWIN_HACKS */
 void werr(int) __attribute__((noreturn));
 void werr(int) __attribute__((noreturn));
 char *werr_tostr(int);
 char *werr_tostr(int);
+int det_translate(const char *);
+const char *det_translate_num(int);
 
 
 extern bool		clear_tmpdir;
 extern bool		clear_tmpdir;
 
 

+ 92 - 91
src/userent.c

@@ -36,7 +36,7 @@ void init_userent()
   add_entry_type(&USERENTRY_STATS);
   add_entry_type(&USERENTRY_STATS);
   add_entry_type(&USERENTRY_ADDED);
   add_entry_type(&USERENTRY_ADDED);
   add_entry_type(&USERENTRY_MODIFIED);
   add_entry_type(&USERENTRY_MODIFIED);
-  add_entry_type(&USERENTRY_CONFIG);
+  add_entry_type(&USERENTRY_SET);
 }
 }
 
 
 void list_type_kill(struct list_type *t)
 void list_type_kill(struct list_type *t)
@@ -218,167 +218,165 @@ struct user_entry_type USERENTRY_ADDED = {
   "ADDED"
   "ADDED"
 };
 };
 
 
-static bool config_set(struct userrec *u, struct user_entry *e, void *buf)
+
+static bool set_set(struct userrec *u, struct user_entry *e, void *buf)
 {
 {
-  struct xtra_key *curr = NULL, *old = NULL, *mynew = (struct xtra_key *) buf;
+  struct xtra_key *curr = (struct xtra_key *) e->u.extra, 
+                  *newxk = (struct xtra_key *) buf, *old = NULL;
 
 
-  for (curr = (struct xtra_key *) e->u.extra; curr; curr = curr->next) {
-    if (curr->key && !egg_strcasecmp(curr->key, mynew->key)) {
+  /* find the curr key if it exists */
+  for (; curr; curr = curr->next) {
+    if (curr->key && !egg_strcasecmp(curr->key, newxk->key)) {
       old = curr;
       old = curr;
       break;
       break;
     }
     }
   }
   }
-  if (!old && (!mynew->data || !mynew->data[0])) {
-    /* delete non-existant entry */
-    free(mynew->key);
-    if (mynew->data)
-      free(mynew->data);
-    free(mynew);
+  
+  /* unset and bail out if the new data is empty and the old doesn't exist, why'd we even get this change? */
+  if (!old && (!newxk->data || !newxk->data[0])) {
+    /* or simply ... delete non-existant entry */
+    free(newxk->key);
+    if (newxk->data)
+      free(newxk->data);
+    free(newxk);
     return 1;
     return 1;
   }
   }
 
 
-  /* we will possibly free new below, so let's send the information
-   * to the botnet now */
-  if (!noshare && !cfg_noshare)
-    shareout_prot(u, "c CONFIG %s %s %s\n", u->handle, mynew->key, mynew->data ? mynew->data : "");
-  if ((old && old != mynew) || !mynew->data || !mynew->data[0]) {
+  /* we will possibly free new below, so let's send the information to the botnet now */
+  if (!noshare && !set_noshare)
+    /* only share to pertinent bots */
+    shareout_prot(u, "c %s %s %s %s\n", e->type->name, u->handle, newxk->key, newxk->data ? newxk->data : "");
+
+  /* if we have a new entry and an old entry.. or our new entry is empty -> clear out the old entry */
+  if ((old && old != newxk) || !newxk->data || !newxk->data[0]) {
     list_delete((struct list_type **) (&e->u.extra), (struct list_type *) old);
     list_delete((struct list_type **) (&e->u.extra), (struct list_type *) old);
 
 
     free(old->key);
     free(old->key);
     free(old->data);
     free(old->data);
     free(old);
     free(old);
   }
   }
-  if (old != mynew && mynew->data) {
-    if (mynew->data[0]) {
-      list_insert((struct xtra_key **) (&e->u.extra), mynew);
+
+  /* add the new entry if it's not empty */
+  if (old != newxk && newxk->data) {
+    if (newxk->data[0]) {
+      list_insert((struct xtra_key **) (&e->u.extra), newxk);
     } else {
     } else {
-      if (mynew->data)
-        free(mynew->data);
-      free(mynew->key);
-      free(mynew);
+      if (newxk->data)
+        free(newxk->data);
+      free(newxk->key);
+      free(newxk);
     }
     }
   }
   }
   return 1;
   return 1;
 }
 }
 
 
-static bool config_unpack(struct userrec *u, struct user_entry *e)
+static bool set_unpack(struct userrec *u, struct user_entry *e)
 {
 {
   struct list_type *curr = NULL, *head = NULL;
   struct list_type *curr = NULL, *head = NULL;
-  struct xtra_key *t = NULL;
-  char *key = NULL, *data = NULL;
 
 
   head = curr = e->u.list;
   head = curr = e->u.list;
   e->u.extra = NULL;
   e->u.extra = NULL;
-  while (curr) {
-    t = (struct xtra_key *) my_calloc(1, sizeof(struct xtra_key));
-
-    data = curr->extra;
-    key = newsplit(&data);
-    if (data[0]) {
-      t->key = strdup(key);
-      t->data = strdup(data);
-      list_insert((struct xtra_key **) (&e->u.extra), t);
+
+  if (conf.bot->hub || !egg_strcasecmp(conf.bot->nick, u->handle)) {
+    struct xtra_key *t = NULL;
+    char *key = NULL, *data = NULL;
+
+    while (curr) {
+      t = (struct xtra_key *) my_calloc(1, sizeof(struct xtra_key));
+      data = curr->extra;
+      key = newsplit(&data);
+      if (data[0]) {
+        t->key = strdup(key);
+        t->data = strdup(data);
+        list_insert((struct xtra_key **) (&e->u.extra), t);
+      } else
+        free(t);
+      curr = curr->next;
     }
     }
-    curr = curr->next;
-  }
+  } 
+
   list_type_kill(head);
   list_type_kill(head);
   return 1;
   return 1;
 }
 }
 
 
-static void config_display(int idx, struct user_entry *e, struct userrec *u)
+static void set_display(int idx, struct user_entry *e, struct userrec *u)
 {
 {
   if (conf.bot->hub) {
   if (conf.bot->hub) {
-    struct xtra_key *xk = NULL;
+    struct xtra_key *xk = (struct xtra_key *) e->u.extra;
     struct flag_record fr = {FR_GLOBAL, 0, 0, 0 };
     struct flag_record fr = {FR_GLOBAL, 0, 0, 0 };
 
 
     get_user_flagrec(dcc[idx].user, &fr, NULL);
     get_user_flagrec(dcc[idx].user, &fr, NULL);
     /* scan thru xtra field, searching for matches */
     /* scan thru xtra field, searching for matches */
-    for (xk = (struct xtra_key *) e->u.extra; xk; xk = xk->next) {
+    for (; xk; xk = xk->next) {
       /* ok, it's a valid xtra field entry */
       /* ok, it's a valid xtra field entry */
       if (glob_owner(fr))
       if (glob_owner(fr))
-        dprintf(idx, "  %s: %s\n", xk->key, xk->data);
+        dprintf(idx, "  %s: %s\n", xk->key, xk->data ? xk->data : "");
     }
     }
   }
   }
 }
 }
 
 
-static bool config_gotshare(struct userrec *u, struct user_entry *e, char *buf, int idx)
+static bool set_gotshare(struct userrec *u, struct user_entry *e, char *buf, int idx)
 {
 {
-  char *arg = newsplit(&buf);
+  char *name = newsplit(&buf);
 
 
-  if (!arg[0])
+  if (!name || !name[0])
     return 1;
     return 1;
-  if (!strcmp(u->handle, conf.bot->nick)) {
-    struct cfg_entry *cfgent = NULL;
-    int i;
-
-    cfg_noshare = 1;
-    for (i = 0; !cfgent && (i < cfg_count); i++)
-      if (!strcmp(arg, cfg[i]->name) && (cfg[i]->flags & CFGF_LOCAL))
-	cfgent = cfg[i];
-    if (cfgent) {
-      set_cfg_str(conf.bot->nick, cfgent->name, (buf && buf[0]) ? buf : NULL);
-    }
-    cfg_noshare = 0;
-    return 1;
-  }
-
-  size_t l = strlen(arg);
-  struct xtra_key *xk = (struct xtra_key *) my_calloc(1, sizeof(struct xtra_key));
 
 
-  if (l > 1500)
-    l = 1500;
-  xk->key = (char *) my_calloc(1, l + 1);
-  strncpy(xk->key, arg, l + 1);
-
-  if (buf && buf[0]) {
-    size_t k = strlen(buf);
+  if (!egg_strcasecmp(u->handle, conf.bot->nick)) {
+    set_noshare = 1;
+    var_set_by_name(conf.bot->nick, name, buf);
+    set_noshare = 0;
+  /* var_set_by_name() called set_user(), no need to do it again... */
+  } 
+  /* not else if as the hub might have gotten a botset for itself */
+  if (conf.bot->hub) {
+  /* only hubs need to bother saving this stuff, leaf bots just store it in vars[] */
+    struct xtra_key *xk = (struct xtra_key *) my_calloc(1, sizeof(struct xtra_key));
 
 
-    if (k > 1500 - l)
-      k = 1500 - l;
-    xk->data = (char *) my_calloc(1, k + 1);
-    strncpy(xk->data, buf, k + 1);
+    xk->key = strdup(name);
+    xk->data = (buf && buf[0]) ? strdup(buf) : NULL;
+    set_set(u, e, xk);	/* set the USERENTRY */
   }
   }
-  config_set(u, e, xk);
-
   return 1;
   return 1;
 }
 }
 
 
-static bool config_write_userfile(FILE *f, struct userrec *u, struct user_entry *e, int idx)
+static bool set_write_userfile(FILE *f, struct userrec *u, struct user_entry *e, int idx)
 {
 {
   /* only write if saving local, or if sending to hub, or if sending to same user as entry */
   /* only write if saving local, or if sending to hub, or if sending to same user as entry */
   if (idx == -1 || dcc[idx].hub || dcc[idx].user == u) {
   if (idx == -1 || dcc[idx].hub || dcc[idx].user == u) {
-    struct xtra_key *x = NULL;
+    struct xtra_key *x = (struct xtra_key *) e->u.extra;
 
 
-    for (x = (struct xtra_key *) e->u.extra; x; x = x->next)
-      if (lfprintf(f, "--CONFIG %s %s\n", x->key, x->data) == EOF)
+    for (; x; x = x->next)
+      if (lfprintf(f, "--%s %s %s\n", e->type->name, x->key, x->data ? x->data : "") == EOF)
         return 0;
         return 0;
   }
   }
   return 1;
   return 1;
 }
 }
 
 
-static bool config_kill(struct user_entry *e)
+static bool set_kill(struct user_entry *e)
 {
 {
-  struct xtra_key *x = NULL, *y = NULL;
+  struct xtra_key *x = (struct xtra_key *) e->u.extra, *y = NULL;
 
 
-  for (x = (struct xtra_key *) e->u.extra; x; x = y) {
+  for (; x; x = y) {
     y = x->next;
     y = x->next;
     free(x->key);
     free(x->key);
-    free(x->data);
+    if (x->data)
+      free(x->data);
     free(x);
     free(x);
   }
   }
   free(e);
   free(e);
   return 1;
   return 1;
 }
 }
 
 
-struct user_entry_type USERENTRY_CONFIG = {
+struct user_entry_type USERENTRY_SET = {
   0,
   0,
-  config_gotshare,
-  config_unpack,
-  config_write_userfile,
-  config_kill,
+  set_gotshare,
+  set_unpack,
+  set_write_userfile,
+  set_kill,
   def_get,
   def_get,
-  config_set,
-  config_display,
+  set_set,
+  set_display,
   "CONFIG"
   "CONFIG"
 };
 };
 
 
@@ -1028,7 +1026,8 @@ struct user_entry_type *find_entry_type(char *name)
   struct user_entry_type *p = NULL;
   struct user_entry_type *p = NULL;
 
 
   for (p = entry_type_list; p; p = p->next) {
   for (p = entry_type_list; p; p = p->next) {
-    if (!egg_strcasecmp(name, p->name))
+/* FIXME: remove after 1.2.3 */
+    if (!egg_strcasecmp(name, p->name) || (!egg_strcasecmp(name, "CONFIG") && !egg_strcasecmp(p->name, "SET")))
       return p;
       return p;
   }
   }
   return NULL;
   return NULL;
@@ -1039,8 +1038,10 @@ struct user_entry *find_user_entry(struct user_entry_type *et, struct userrec *u
   struct user_entry **e = NULL, *t = NULL;
   struct user_entry **e = NULL, *t = NULL;
 
 
   for (e = &(u->entries); *e; e = &((*e)->next)) {
   for (e = &(u->entries); *e; e = &((*e)->next)) {
+/* FIXME: remove after 1.2.3 */
     if (((*e)->type == et) ||
     if (((*e)->type == et) ||
-	((*e)->name && !egg_strcasecmp((*e)->name, et->name))) {
+	((*e)->name && (!egg_strcasecmp((*e)->name, et->name) ||
+        (!egg_strcasecmp((*e)->name, "CONFIG") && !egg_strcasecmp(et->name, "SET"))))) {
       t = *e;
       t = *e;
       *e = t->next;
       *e = t->next;
       t->next = u->entries;
       t->next = u->entries;

+ 17 - 9
src/users.c

@@ -21,7 +21,7 @@
 #include "settings.h"
 #include "settings.h"
 #include "userrec.h"
 #include "userrec.h"
 #include "misc.h"
 #include "misc.h"
-#include "cfg.h"
+#include "set.h"
 #include "match.h"
 #include "match.h"
 #include "main.h"
 #include "main.h"
 #include "chanprog.h"
 #include "chanprog.h"
@@ -626,7 +626,8 @@ int readuserfile(const char *file, struct userrec **ret)
 	    else if (lasthand[0] == '*') {
 	    else if (lasthand[0] == '*') {
 	      if (lasthand[1] == IGNORE_NAME[1])
 	      if (lasthand[1] == IGNORE_NAME[1])
 		restore_ignore(s);
 		restore_ignore(s);
-              else if (lasthand[1] == CONFIG_NAME[1]) {
+/* FIXME: remove after 1.2.3 */
+              else if (lasthand[1] == SET_NAME[1] || lasthand[1] == 'C') {
                 set_cmd_pass(s, 0);		/* no need to share here, if we have a new userfile
                 set_cmd_pass(s, 0);		/* no need to share here, if we have a new userfile
 						 * then leaf bots under us also get the new userfile */
 						 * then leaf bots under us also get the new userfile */
               }
               }
@@ -654,8 +655,9 @@ int readuserfile(const char *file, struct userrec **ret)
 	    } else if (lasthand[0] == '*') {
 	    } else if (lasthand[0] == '*') {
 	      if (lasthand[1] == INVITE_NAME[1]) {
 	      if (lasthand[1] == INVITE_NAME[1]) {
                 restore_chanmask('I', NULL, s);
                 restore_chanmask('I', NULL, s);
-              } else if (lasthand[1] == CONFIG_NAME[1]) {
-                userfile_cfg_line(s);
+/* FIXME: Remove after 1.2.3 */
+              } else if (lasthand[1] == SET_NAME[1] || lasthand[1] == 'C') {
+                var_userfile_share_line(s, -1, 0);
               }
               }
             }
             }
 	  }
 	  }
@@ -780,7 +782,9 @@ int readuserfile(const char *file, struct userrec **ret)
 	    int ok = 0;
 	    int ok = 0;
 
 
 	    for (ue = u->entries; ue && !ok; ue = ue->next)
 	    for (ue = u->entries; ue && !ok; ue = ue->next)
-	      if (ue->name && !egg_strcasecmp(code + 2, ue->name)) {
+/* FIXME: remove after 1.2.3 */
+	      if (ue->name && (!egg_strcasecmp(code + 2, ue->name) ||
+                (!egg_strcasecmp(code + 2, "CONFIG") && !egg_strcasecmp(ue->name, "SET")))) {
 		struct list_type *list = NULL;
 		struct list_type *list = NULL;
 
 
 		list = (struct list_type *) my_calloc(1, sizeof(struct list_type));
 		list = (struct list_type *) my_calloc(1, sizeof(struct list_type));
@@ -790,12 +794,14 @@ int readuserfile(const char *file, struct userrec **ret)
 		list_append((&ue->u.list), list);
 		list_append((&ue->u.list), list);
 		ok = 1;
 		ok = 1;
 	      }
 	      }
+            /* if we don't have the entry, make it?? */
 	    if (!ok) {
 	    if (!ok) {
 	      ue = (struct user_entry *) my_calloc(1, sizeof(struct user_entry));
 	      ue = (struct user_entry *) my_calloc(1, sizeof(struct user_entry));
 
 
-	      ue->name = (char *) my_calloc(1, strlen(code + 1));
+//	      ue->name = (char *) my_calloc(1, strlen(code + 1));
+              ue->name = strdup(code + 2);
 	      ue->type = NULL;
 	      ue->type = NULL;
-	      strcpy(ue->name, code + 2);
+//	      strcpy(ue->name, code + 2);
 	      ue->u.list = (struct list_type *) my_calloc(1, sizeof(struct list_type));
 	      ue->u.list = (struct list_type *) my_calloc(1, sizeof(struct list_type));
 
 
 	      ue->u.list->next = NULL;
 	      ue->u.list->next = NULL;
@@ -818,7 +824,8 @@ int readuserfile(const char *file, struct userrec **ret)
         } else if (!rfc_casecmp(code, CHANS_NAME)) {
         } else if (!rfc_casecmp(code, CHANS_NAME)) {
           strcpy(lasthand, code);
           strcpy(lasthand, code);
           u = NULL;
           u = NULL;
-        } else if (!rfc_casecmp(code, CONFIG_NAME)) {
+/* FIXME: remove after 1.2.3 */
+        } else if (!rfc_casecmp(code, SET_NAME) || !rfc_casecmp(code, "*Config")) {
           strcpy(lasthand, code);
           strcpy(lasthand, code);
           u = NULL;  
           u = NULL;  
 	} else if (code[0] == '*') {
 	} else if (code[0] == '*') {
@@ -899,7 +906,8 @@ int readuserfile(const char *file, struct userrec **ret)
 	  uet->unpack(u, e);
 	  uet->unpack(u, e);
 	  free(e->name);
 	  free(e->name);
 	  e->name = NULL;
 	  e->name = NULL;
-	}
+	} else
+          sdprintf("FAILED TO UNPACK '%s'", e->name);
       }
       }
   }
   }
   /* process the user data *now* */
   /* process the user data *now* */

+ 2 - 2
src/users.h

@@ -46,7 +46,7 @@ struct user_entry_type {
 extern struct user_entry_type USERENTRY_COMMENT, USERENTRY_LASTON,
 extern struct user_entry_type USERENTRY_COMMENT, USERENTRY_LASTON,
  USERENTRY_INFO, USERENTRY_BOTADDR, USERENTRY_HOSTS,
  USERENTRY_INFO, USERENTRY_BOTADDR, USERENTRY_HOSTS,
  USERENTRY_PASS, USERENTRY_STATS, USERENTRY_ADDED, USERENTRY_MODIFIED,
  USERENTRY_PASS, USERENTRY_STATS, USERENTRY_ADDED, USERENTRY_MODIFIED,
- USERENTRY_CONFIG, USERENTRY_SECPASS, USERENTRY_USERNAME, USERENTRY_NODENAME, USERENTRY_OS,
+ USERENTRY_SET, USERENTRY_SECPASS, USERENTRY_USERNAME, USERENTRY_NODENAME, USERENTRY_OS,
  USERENTRY_TMPPASS;
  USERENTRY_TMPPASS;
 
 
 struct laston_info {
 struct laston_info {
@@ -104,7 +104,7 @@ bool set_user(struct user_entry_type *, struct userrec *, void *);
 #define EXEMPT_NAME "*exempt"
 #define EXEMPT_NAME "*exempt"
 #define INVITE_NAME "*Invite"
 #define INVITE_NAME "*Invite"
 #define CHANS_NAME  "*channels"
 #define CHANS_NAME  "*channels"
-#define CONFIG_NAME "*Config"
+#define SET_NAME "*Set"
 
 
 /* Channel-specific info
 /* Channel-specific info
  */
  */