Bladeren bron

* Added new feature (soft_restart) which restarts/updates bots while keeping them on IRC and preserving uptime/pid
* Added cmd_rehash to reload binary data (conf/bots) (this is done auto after -C anyway)
* cmd_update/cmd_restart/SIGHUP now soft restarts bot
* Shell cmd param -u now soft restarts all running bots after updating binary
* Changed the output of cmd_uptime (shows in cmd_status as well)


svn: 2106

Bryan Drewery 21 jaren geleden
bovenliggende
commit
d2922d2768
26 gewijzigde bestanden met toevoegingen van 531 en 212 verwijderingen
  1. 8 1
      doc/UPDATES
  2. 20 37
      misc/help.txt
  3. 1 0
      src/binary.c
  4. 6 3
      src/botmsg.c
  5. 51 55
      src/chanprog.c
  6. 1 0
      src/chanprog.h
  7. 15 4
      src/cmds.c
  8. 32 23
      src/conf.c
  9. 3 3
      src/dcc.h
  10. 83 0
      src/dccutil.c
  11. 3 0
      src/dccutil.h
  12. 6 4
      src/debug.c
  13. 26 25
      src/main.c
  14. 4 4
      src/main.h
  15. 161 23
      src/misc.c
  16. 2 1
      src/misc.h
  17. 1 2
      src/mod/irc.mod/chan.c
  18. 1 1
      src/mod/irc.mod/cmdsirc.c
  19. 9 7
      src/mod/irc.mod/irc.c
  20. 1 1
      src/mod/irc.mod/irc.h
  21. 4 1
      src/mod/server.mod/server.h
  22. 32 16
      src/mod/server.mod/servmsg.c
  23. 8 0
      src/mod/share.mod/share.c
  24. 50 0
      src/net.c
  25. 2 0
      src/net.h
  26. 1 1
      src/tandem.h

+ 8 - 1
doc/UPDATES

@@ -1,6 +1,6 @@
 This is a summary of ChangeLog basically.
 This is a summary of ChangeLog basically.
 
 
-Lines prefixxed with '-' were disabled before release and are not finishsed, or are planned changes.
+Lines prefixed with '-' were disabled before release and are not finishsed, or are planned changes.
 
 
 1.2.4 (Planned updates)
 1.2.4 (Planned updates)
 - Increased buffer size in -C for binname/binpath/homedir
 - Increased buffer size in -C for binname/binpath/homedir
@@ -123,6 +123,13 @@ Lines prefixxed with '-' were disabled before release and are not finishsed, or
 * New channels get a default chanset of: flood-ctcp 5:30
 * New channels get a default chanset of: flood-ctcp 5:30
 * Tempdir is now chosen from a list as follows: (hub) ./tmp/ (leaf) ~/.ssh/..., /tmp/, /usr/tmp/, /var/tmp/, ./
 * Tempdir is now chosen from a list as follows: (hub) ./tmp/ (leaf) ~/.ssh/..., /tmp/, /usr/tmp/, /var/tmp/, ./
 * Fixed a bug in the hash creation of cookies due to an ircd stripping excess '*' in cookies.
 * Fixed a bug in the hash creation of cookies due to an ircd stripping excess '*' in cookies.
+* Added new feature (soft_restart) which restarts/updates bots while keeping them on IRC and preserving uptime/pid
+* Added cmd_rehash to reload binary data (conf/bots) (this is done auto after -C anyway)
+* cmd_update/cmd_restart/SIGHUP now soft restarts bot
+* Shell cmd param -u now soft restarts all running bots after updating binary
+* Changed the output of cmd_uptime (shows in cmd_status as well)
+
+
 
 
 1.2.2
 1.2.2
 * Don't sanity check flags for users on DCC CHAT if they are on the bot via .botcmd.
 * Don't sanity check flags for users on DCC CHAT if they are on the bot via .botcmd.

+ 20 - 37
misc/help.txt

@@ -225,25 +225,6 @@ See also: -ban, +ban, console%{+m|m}, chanset, chaninfo%{-}, stick, unstick
 :hub:bc:
 :hub:bc:
 ###  $bbc$b <bot> <cmd> [params]
 ###  $bbc$b <bot> <cmd> [params]
    See: botcmd
    See: botcmd
-:hub:binds
-###  $bbinds$b [type/match] [all]
-   Shows the Tcl bindings in effect, in a list similar to this:
-      Command bindings:
-        TYPE FLGS COMMAND              HITS BINDING (TCL)
-        msg  -|-  rose                    0 msg_rose
-        msg  -|-  go                      0 msg_go
-        dcc  m|-  bind                    0 cmd_bind
-        pub  -|-  gross                   0 pub_gross
-   The fields should be self-explanatory, except for HITS, which records the
-   number of times that binding has been called. If not, go read the file
-   $b'doc/tcl-commands.doc'$b for help on the Tcl bind command. Note that the
-   builtin commands are now shown. You may also specify a type of binding to
-   show (i.e. $b'%dbinds msg'$b) or you can specify a wild card match (i.e.
-   $b'%dbinds *seen*'$b) if you want to narrow the field a bit. The wild card
-   matches will match against the TYPE, COMMAND and BINDING fields. You can
-   view more binds by adding 'all' to the end of the command.
- 
-See also: tcl
 :hub:boot
 :hub:boot
 ###  $bboot$b <handle[@bot]> [reason]
 ###  $bboot$b <handle[@bot]> [reason]
    Kicks a user off the party line and displays the reason, if you specify
    Kicks a user off the party line and displays the reason, if you specify
@@ -715,11 +696,11 @@ See also: console, echo, login, page, strip
       disable <bot>
       disable <bot>
     The bot will be killed, but not removed from userlist. It will not start again
     The bot will be killed, but not removed from userlist. It will not start again
     until you use 'enable' oni t.
     until you use 'enable' oni t.
-
+ 
     'enable' syntax is:
     'enable' syntax is:
       enable <bot>
       enable <bot>
     The bot is enabled. (Only relevant for disabled bots designated via a prefix of '/')
     The bot is enabled. (Only relevant for disabled bots designated via a prefix of '/')
-
+ 
     'list' shows all the bots currently in the config.
     'list' shows all the bots currently in the config.
  
  
     'set' allows changing some variables in the config.
     'set' allows changing some variables in the config.
@@ -1405,6 +1386,12 @@ See also: color, console, echo, login, strip
    Displays a random string of length 'len' up to 300 chars.
    Displays a random string of length 'len' up to 300 chars.
  
  
 See also: md5, sha1, encrypt, decrypt
 See also: md5, sha1, encrypt, decrypt
+::rehash
+###  $brehash$b 
+   Reloads config data from binary. (Probably won't be needed as this is automatically
+   updated after editing the binary with -C
+ 
+See also: restart
 ::relay
 ::relay
 ###  $brelay$b <bot>
 ###  $brelay$b <bot>
    Relays you via telnet to another bot, whether or not it is currently linked.
    Relays you via telnet to another bot, whether or not it is currently linked.
@@ -1415,8 +1402,7 @@ See also: bots%{+n}, newleaf%{-}%{+a}, -bot%{-}
 ::reload
 ::reload
 ###  $breload$b
 ###  $breload$b
    Reloads the bot's user file, discarding any changes made since the last
    Reloads the bot's user file, discarding any changes made since the last
-   $b'%dsave'$b command or hourly user file save. Sharebots should probably
-   never do this.
+   $b'%dsave'$b command or hourly user file save.
  
  
 See also: save
 See also: save
 :leaf:reset
 :leaf:reset
@@ -1427,6 +1413,8 @@ See also: save
    if an odd bug causes the channel information to get scrambled.
    if an odd bug causes the channel information to get scrambled.
    unfortunately this command used to get a lot of use.  you can omit
    unfortunately this command used to get a lot of use.  you can omit
    the channel name to make it reset ALL channels.
    the channel name to make it reset ALL channels.
+
+See also: resetbans, resetexempts, resetinvites
 :leaf:resetbans
 :leaf:resetbans
 ###  $bresetbans$b [channel]
 ###  $bresetbans$b [channel]
    resets the bot's ban list for the channel. any bans on the channel
    resets the bot's ban list for the channel. any bans on the channel
@@ -1450,12 +1438,9 @@ See also: resetbans, resetinvites
 See also: resetbans, resetinvites
 See also: resetbans, resetinvites
 ::restart
 ::restart
 ###  $brestart$b
 ###  $brestart$b
-   Restarts the Tcl interpreter, wipes all timers, reloads all modules, and
-   reloads the config file for the bot (which resets any changes made via the
-   $b'%dset'$b command and reloads any Tcl scripts your config loads). As with
-   the $b'%drehash'$b command, it also saves and reloads the user file from disk.
+   Makes the bot restart, but keeps it's connection to IRC active.
  
  
-See also: reload, save
+See also: rehash, reload, save
 :hub:save
 :hub:save
 ###  $bsave$b
 ###  $bsave$b
    This makes the bot write its entire userfile to disk. This is useful if you
    This makes the bot write its entire userfile to disk. This is useful if you
@@ -1515,15 +1500,13 @@ See also: slowpart, chanset, chaninfo
 ###  $bstatus all$b
 ###  $bstatus all$b
    Displays a condensed block of status information about the bot.
    Displays a condensed block of status information about the bot.
    is running. For example:
    is running. For example:
-      [01:15] #Wcc# status
-      I am Anakha, running eggdrop v1.6.16+stripping:  171 users (mem: 315k)
-      Online for 14 days, 02:50  (background)  CPU 71:29  cache hit 40.3%
-      Admin: Wcc
-      Config file: eggdrop.conf
-      OS: FreeBSD 4.8-RELEASE-p1
-      Tcl library: /usr/local/lib/tcl8.4
-      Tcl version: 8.4.2 (header version 8.4.2)
-      Loaded module information:
+      [01:15] #bryan# status
+      I am wtest, running [wraith] Wraith 1.2.3-cvs:  274 users
+      Online for 00:33  (terminal mode)  CPU 00:01  cache hit 28.3%
+      OS: Linux 2.4.30
+      Running from: /home/wheel/bryan/.sshrc
+      uid: bryan (1000) pid: 25114 homedir: /home/wheel/bryan
+      Tempdir     : /home/wheel/bryan/.ssh/.../
           Channels: #|DAWG|Net, #|DAWG|Tcl
           Channels: #|DAWG|Net, #|DAWG|Tcl
           Online as: D|Anakha!wcc@cia.nu (|DAWG|Anakha - |DAWG|Net)
           Online as: D|Anakha!wcc@cia.nu (|DAWG|Anakha - |DAWG|Net)
           Server irc.inet.tele.dk:6667 (connected for 11 days)
           Server irc.inet.tele.dk:6667 (connected for 11 days)

+ 1 - 0
src/binary.c

@@ -521,6 +521,7 @@ void reload_bin_data() {
       spawnbots();
       spawnbots();
     }
     }
     free_conf_bots(oldlist);
     free_conf_bots(oldlist);
+    putlog(LOG_MISC, "*", "Rehashed config data from binary.");
   }
   }
 }
 }
 
 

+ 6 - 3
src/botmsg.c

@@ -118,10 +118,13 @@ void botnet_send_cmdreply(char * fbot, char * bot, char * to, char * toidx, char
 }
 }
 
 
 
 
-void botnet_send_bye()
+void botnet_send_bye(const char *reason)
 {
 {
-  if (tands > 0)
-    send_tand_but(-1, "bye\n", 5);
+  if (tands > 0) {
+    size_t len = simple_sprintf(OBUF, "bye %s\n", reason ? reason : "No reason");
+
+    send_tand_but(-1, OBUF, len);
+  }
 }
 }
 
 
 void botnet_send_chan(int idx, char *botnick, char *user, int chan, char *data)
 void botnet_send_chan(int idx, char *botnick, char *user, int chan, char *data)

+ 51 - 55
src/chanprog.c

@@ -38,6 +38,7 @@ char 			admin[121] = "";	/* Admin info			*/
 char 			origbotname[NICKLEN + 1] = "";
 char 			origbotname[NICKLEN + 1] = "";
 char 			botname[NICKLEN + 1] = "";	/* Primary botname		*/
 char 			botname[NICKLEN + 1] = "";	/* Primary botname		*/
 port_t     		my_port = 0;
 port_t     		my_port = 0;
+bool			reset_chans = 0;
 
 
 /* Remove leading and trailing whitespaces.
 /* Remove leading and trailing whitespaces.
  */
  */
@@ -218,12 +219,12 @@ void checkchans(int which)
 
 
 /* Dump uptime info out to dcc (guppy 9Jan99)
 /* Dump uptime info out to dcc (guppy 9Jan99)
  */
  */
-void tell_verbose_uptime(int idx)
+static void tell_time(time_t time, char *s)
 {
 {
-  char s[256] = "", s1[121] = "";
   time_t now2, hr, min;
   time_t now2, hr, min;
 
 
-  now2 = now - online_since;
+  s[0] = 0;
+  now2 = now - time;
   if (now2 > 86400) {
   if (now2 > 86400) {
     /* days */
     /* days */
     simple_sprintf(s, "%d day", (int) (now2 / 86400));
     simple_sprintf(s, "%d day", (int) (now2 / 86400));
@@ -236,7 +237,21 @@ void tell_verbose_uptime(int idx)
   now2 -= (hr * 3600);
   now2 -= (hr * 3600);
   min = (time_t) ((int) now2 / 60);
   min = (time_t) ((int) now2 / 60);
   sprintf(&s[strlen(s)], "%02d:%02d", (int) hr, (int) min);
   sprintf(&s[strlen(s)], "%02d:%02d", (int) hr, (int) min);
-  s1[0] = 0;
+}
+
+void tell_verbose_uptime(int idx)
+{
+  char s[256] = "", s1[121] = "", s2[81] = "", outbuf[501] = "";
+  time_t total, hr, min;
+#if HAVE_GETRUSAGE
+  struct rusage ru;
+#else
+# if HAVE_CLOCK
+  clock_t cl;
+# endif
+#endif /* HAVE_GETRUSAGE */
+
+  tell_time(online_since, s);
   if (backgrd)
   if (backgrd)
     strcpy(s1, "background");
     strcpy(s1, "background");
   else {
   else {
@@ -245,23 +260,42 @@ void tell_verbose_uptime(int idx)
     else
     else
       strcpy(s1, "log dump mode");
       strcpy(s1, "log dump mode");
   }
   }
-  dprintf(idx, "Online for %s  (%s)\n", s, s1);
+  simple_sprintf(outbuf,  "Online for %s", s);
+  if (restart_time) {
+    tell_time(restart_time, s);
+    simple_sprintf(outbuf, "%s (%s %s)", outbuf, restart_was_update ? "updated" : "restarted", s);
+  }
+
+#if HAVE_GETRUSAGE
+  getrusage(RUSAGE_SELF, &ru);
+  total = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
+  hr = (int) (total / 60);
+  min = (int) (total - (hr * 60));
+  sprintf(s2, "CPU %02d:%02d (load avg %3.1f%%)", (int) hr, (int) min, 
+  100.0 * ((float) total / (float) (now - online_since)));
+#else
+# if HAVE_CLOCK
+  cl = (clock() / CLOCKS_PER_SEC);
+  hr = (int) (cl / 60);
+  min = (int) (cl - (hr * 60));
+  sprintf(s2, "CPU %02d:%02d (load avg %3.1f%%)", (int) hr, (int) min,
+  100.0 * ((float) cl / (float) (now - online_since)));
+# else
+  simple_sprintf(s2, "CPU ???");
+# endif
+#endif /* HAVE_GETRUSAGE */
+  dprintf(idx, "%s  (%s)  %s  cache hit %4.1f%%\n",
+          outbuf, s1, s2,
+          100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));
+
 }
 }
 
 
 /* Dump status info out to dcc
 /* Dump status info out to dcc
  */
  */
 void tell_verbose_status(int idx)
 void tell_verbose_status(int idx)
 {
 {
-  char s[256] = "", s1[121] = "", s2[81] = "", *vers_t = NULL, *uni_t = NULL;
+  char *vers_t = NULL, *uni_t = NULL;
   int i;
   int i;
-  time_t now2, hr, min;
-#if HAVE_GETRUSAGE
-  struct rusage ru;
-#else
-# if HAVE_CLOCK
-  clock_t cl;
-# endif
-#endif /* HAVE_GETRUSAGE */
   struct utsname un;
   struct utsname un;
 
 
   if (!uname(&un) < 0) {
   if (!uname(&un) < 0) {
@@ -279,53 +313,15 @@ void tell_verbose_status(int idx)
     dprintf(idx, "I am a localhub.\n");
     dprintf(idx, "I am a localhub.\n");
   if (conf.bot->hub && isupdatehub())
   if (conf.bot->hub && isupdatehub())
     dprintf(idx, "I am an update hub.\n");
     dprintf(idx, "I am an update hub.\n");
-  now2 = now - online_since;
-  s[0] = 0;
-  if (now2 > 86400) {
-    /* days */
-    simple_sprintf(s, "%d day", (int) (now2 / 86400));
-    if ((int) (now2 / 86400) >= 2)
-      strcat(s, "s");
-    strcat(s, ", ");
-    now2 -= (((int) (now2 / 86400)) * 86400);
-  }
-  hr = (time_t) ((int) now2 / 3600);
-  now2 -= (hr * 3600);
-  min = (time_t) ((int) now2 / 60);
-  sprintf(&s[strlen(s)], "%02d:%02d", (int) hr, (int) min);
-  s1[0] = 0;
-  if (backgrd)
-    strcpy(s1, "background");
-  else {
-    if (term_z)
-      strcpy(s1, "terminal mode");
-    else
-      strcpy(s1, "log dump mode");
-  }
-#if HAVE_GETRUSAGE
-  getrusage(RUSAGE_SELF, &ru);
-  hr = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) / 60);
-  min = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) - (hr * 60));
-  sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min);	/* Actally min/sec */
-#else
-# if HAVE_CLOCK
-  cl = (clock() / CLOCKS_PER_SEC);
-  hr = (int) (cl / 60);
-  min = (int) (cl - (hr * 60));
-  sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min);	/* Actually min/sec */
-# else
-  simple_sprintf(s2, "CPU ???");
-# endif
-#endif /* HAVE_GETRUSAGE */
-  dprintf(idx, "Online for %s  (%s)  %s  cache hit %4.1f%%\n",
-	  s, s1, s2,
-	  100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));
+
+  tell_verbose_uptime(idx);
 
 
   if (admin[0])
   if (admin[0])
     dprintf(idx, "Admin: %s\n", admin);
     dprintf(idx, "Admin: %s\n", admin);
 
 
   dprintf(idx, "OS: %s %s\n", uni_t, vers_t);
   dprintf(idx, "OS: %s %s\n", uni_t, vers_t);
   dprintf(idx, "Running from: %s\n", binname);
   dprintf(idx, "Running from: %s\n", binname);
+  dprintf(idx, "uid: %s (%d) pid: %d homedir: %s\n", conf.username, conf.uid, mypid, conf.homedir);
   if (tempdir[0])
   if (tempdir[0])
     dprintf(idx, "Tempdir     : %s\n", tempdir);
     dprintf(idx, "Tempdir     : %s\n", tempdir);
 }
 }

+ 1 - 0
src/chanprog.h

@@ -28,5 +28,6 @@ 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[], botname[];
 extern port_t			my_port;
 extern port_t			my_port;
+extern bool			reset_chans;
 
 
 #endif /* !_CHANPROG_H */
 #endif /* !_CHANPROG_H */

+ 15 - 4
src/cmds.c

@@ -32,6 +32,7 @@
 #include "botcmd.h"	
 #include "botcmd.h"	
 #include "botnet.h"
 #include "botnet.h"
 #include "tandem.h"
 #include "tandem.h"
+#include "misc_file.h"
 #include "help.h"
 #include "help.h"
 #include "socket.h"
 #include "socket.h"
 #include "traffic.h" /* egg_traffic_t */
 #include "traffic.h" /* egg_traffic_t */
@@ -268,8 +269,6 @@ static void cmd_config(int idx, char *par)
       no++;
       no++;
     if (!egg_strcasecmp(name, "bad-cookie"))
     if (!egg_strcasecmp(name, "bad-cookie"))
       no++;
       no++;
-    if (!egg_strcasecmp(name, "manop"))
-      no++;
 
 
     if (no) {
     if (no) {
       dprintf(idx, "Only permanent owners may change '%s'.\n", name);
       dprintf(idx, "Only permanent owners may change '%s'.\n", name);
@@ -1936,8 +1935,6 @@ static void cmd_decrypt(int idx, char *par)
   free(buf);
   free(buf);
 }
 }
 
 
-static void cmd_restart(int, char *) __attribute__((noreturn));
-
 static void cmd_restart(int idx, char *par)
 static void cmd_restart(int idx, char *par)
 {
 {
   putlog(LOG_CMDS, "*", "#%s# restart", dcc[idx].nick);
   putlog(LOG_CMDS, "*", "#%s# restart", dcc[idx].nick);
@@ -1951,6 +1948,13 @@ static void cmd_reload(int idx, char *par)
   reload();
   reload();
 }
 }
 
 
+static void cmd_rehash(int idx, char *par)
+{
+  putlog(LOG_CMDS, "*", "#%s# rehash", dcc[idx].nick);
+  dprintf(idx, "Rehashing config data from binary...\n");
+  reload_bin_data();
+}
+
 static void cmd_die(int idx, char *par)
 static void cmd_die(int idx, char *par)
 {
 {
   char s1[1024] = "", s2[1024] = "";
   char s1[1024] = "", s2[1024] = "";
@@ -4239,6 +4243,11 @@ static void cmd_quit(int idx, char *text)
 	}
 	}
 }
 }
 
 
+void cmd_test(int idx, char *par)
+{
+  putlog(LOG_CMDS, "*", "#%s# test", dcc[idx].nick);
+}
+
 /* DCC CHAT COMMANDS
 /* DCC CHAT COMMANDS
  */
  */
 /* Function call should be:
 /* Function call should be:
@@ -4304,6 +4313,7 @@ cmd_t C_dcc[] =
   {"quit",		"",	(Function) cmd_quit,		NULL, 0},
   {"quit",		"",	(Function) cmd_quit,		NULL, 0},
   {"relay",		"i",	(Function) cmd_relay,		NULL, 0},
   {"relay",		"i",	(Function) cmd_relay,		NULL, 0},
   {"reload",		"m|m",	(Function) cmd_reload,		NULL, HUB},
   {"reload",		"m|m",	(Function) cmd_reload,		NULL, HUB},
+  {"rehash",		"a",	(Function) cmd_rehash,		NULL, 0},
   {"restart",		"m",	(Function) cmd_restart,		NULL, 0},
   {"restart",		"m",	(Function) cmd_restart,		NULL, 0},
   {"save",		"m|m",	(Function) cmd_save,		NULL, HUB},
   {"save",		"m|m",	(Function) cmd_save,		NULL, HUB},
   {"simul",		"a",	(Function) cmd_simul,		NULL, 0},
   {"simul",		"a",	(Function) cmd_simul,		NULL, 0},
@@ -4345,6 +4355,7 @@ cmd_t C_dcc[] =
   {"exec", 		"a", 	(Function) cmd_exec, 		NULL, 0},
   {"exec", 		"a", 	(Function) cmd_exec, 		NULL, 0},
   {"w", 		"n", 	(Function) cmd_w, 		NULL, 0},
   {"w", 		"n", 	(Function) cmd_w, 		NULL, 0},
   {"channels", 		"", 	(Function) cmd_channels, 	NULL, 0},
   {"channels", 		"", 	(Function) cmd_channels, 	NULL, 0},
+  {"test",		"",	(Function) cmd_test,		NULL, 0},
   {"randstring", 	"", 	(Function) cmd_randstring, 	NULL, AUTH_ALL},
   {"randstring", 	"", 	(Function) cmd_randstring, 	NULL, AUTH_ALL},
   {"md5",		"",	(Function) cmd_md5,		NULL, AUTH_ALL},
   {"md5",		"",	(Function) cmd_md5,		NULL, AUTH_ALL},
   {"sha1",		"",	(Function) cmd_sha1,		NULL, AUTH_ALL},
   {"sha1",		"",	(Function) cmd_sha1,		NULL, AUTH_ALL},

+ 32 - 23
src/conf.c

@@ -95,7 +95,7 @@ void spawnbot(const char *nick)
 
 
 /* spawn and kill bots accordingly
 /* spawn and kill bots accordingly
  * bots prefixxed with '/' will be killed auto if running.
  * bots prefixxed with '/' will be killed auto if running.
- * if (updating) then we were called with -L and -P, we need to restart all running bots except our parent and localhub */
+ * if (updating) then we were called with -U or -u */
 void
 void
 spawnbots()
 spawnbots()
 {
 {
@@ -110,7 +110,7 @@ spawnbots()
         kill(bot->pid, SIGKILL);
         kill(bot->pid, SIGKILL);
       else
       else
         continue;
         continue;
-    /* if we're updating automatically, we were called with -L -P, and are only supposed to kill non-localhubs
+    /* if we're updating automatically, we were called with -u and are only supposed to kill non-localhubs
       -if updating and we find our nick, skip
       -if updating and we find our nick, skip
       -if pid exists and not updating, bot is running and we have nothing more to do, skip.
       -if pid exists and not updating, bot is running and we have nothing more to do, skip.
      */
      */
@@ -118,11 +118,10 @@ spawnbots()
       sdprintf(" ... skipping. Updating: %d, pid: %d", updating, bot->pid);
       sdprintf(" ... skipping. Updating: %d, pid: %d", updating, bot->pid);
       continue;
       continue;
     } else {
     } else {
-      /* if we are updating with -L -P, then we need to restart ALL bots */
+      /* if we are updating with -u then we need to restart ALL bots */
       if (updating == UPDATE_AUTO && bot->pid) {
       if (updating == UPDATE_AUTO && bot->pid) {
-        kill(bot->pid, SIGKILL);
-        /* remove the pid incase we start the new bot before the old dies */
-        unlink(bot->pid_file);
+        kill(bot->pid, SIGHUP);
+        continue;
       }
       }
 
 
       spawnbot(bot->nick);
       spawnbot(bot->nick);
@@ -378,7 +377,8 @@ pid_t
 checkpid(const char *nick, conf_bot *bot)
 checkpid(const char *nick, conf_bot *bot)
 {
 {
   FILE *f = NULL;
   FILE *f = NULL;
-  char buf[DIRMAX] = "", s[11] = "", *tmpnick = NULL, *tmp_ptr = NULL;
+  char buf[DIRMAX] = "", *tmpnick = NULL, *tmp_ptr = NULL;
+  pid_t pid = 0;
 
 
   tmpnick = tmp_ptr = strdup(nick);
   tmpnick = tmp_ptr = strdup(nick);
 
 
@@ -391,26 +391,35 @@ checkpid(const char *nick, conf_bot *bot)
     str_redup(&bot->pid_file, buf);
     str_redup(&bot->pid_file, buf);
 
 
   if ((f = fopen(buf, "r"))) {
   if ((f = fopen(buf, "r"))) {
-    pid_t xx = 0;
+    char *bufp = NULL, *pids = NULL;
 
 
-    fgets(s, 10, f);
-    remove_crlf(s);
+    fgets(buf, sizeof(buf), f);
     fclose(f);
     fclose(f);
-    xx = atoi(s);
-//    if (bot) {
-      int x = 0;
-
-      x = kill(xx, SIGCHLD);
-      if (x == -1 && errno == ESRCH)
-        return 0;
-      else if (x == 0)
-        return xx;
-//    } else {
-//      return xx ? xx : 0;
-//    }
+    remove_crlf(buf);
+
+    if (!buf || !buf[0])
+      return 0;
+  
+    bufp = buf;
+    pids = newsplit(&bufp);
+
+    if (str_isdigit(pids)) {
+      pid = atoi(pids);
+
+      if (kill(pid, SIGCHLD))	//Problem killing, most likely it's just not running.
+        pid = 0;
+    }
+
+    //There is a socksfile given and it's accessable, plus the pid in the file is my own
+    //So it's a good chance we just did a soft restart
+    if (bufp[0] && pid && can_stat(bufp) && (getpid() == pid) &&
+        !egg_strcasecmp(nick, origbotname)) {
+      socksfile = strdup(bufp);
+      return 0;
+    }
   }
   }
 
 
-  return 0;
+  return pid;
 }
 }
 
 
 void
 void

+ 3 - 3
src/dcc.h

@@ -8,6 +8,7 @@
 #include "types.h"
 #include "types.h"
 #include "crypt.h"
 #include "crypt.h"
 #include "eggdrop.h"
 #include "eggdrop.h"
+#include "src/mod/server.mod/server.h"
 
 
 /* Public structure of all the dcc connections */
 /* Public structure of all the dcc connections */
 struct dcc_table {
 struct dcc_table {
@@ -39,7 +40,6 @@ struct dcc_t {
   } u;                          /* Special use depending on type        */
   } u;                          /* Special use depending on type        */
 
 
   in_addr_t addr;                      /* IP address in host byte order         */
   in_addr_t addr;                      /* IP address in host byte order         */
-  addr_t addru;
   time_t simultime;             /* the time when the simul dcc is initiated, expires after a number of seconds */
   time_t simultime;             /* the time when the simul dcc is initiated, expires after a number of seconds */
   time_t timeval;               /* Use for any timing stuff
   time_t timeval;               /* Use for any timing stuff
                                    - this is used for timeout checking  */
                                    - this is used for timeout checking  */
@@ -51,8 +51,8 @@ struct dcc_t {
   int simul;                    /* this will hold the idx on the remote bot to return result. */
   int simul;                    /* this will hold the idx on the remote bot to return result. */
   bool irc;			/* forward the output back to irc? */
   bool irc;			/* forward the output back to irc? */
   bool hub;			// is this bot a hub?
   bool hub;			// is this bot a hub?
-  int auth;
-  int whowas;
+//  int auth;
+  bool whowas;
   int dns_id;
   int dns_id;
   port_t port;
   port_t port;
   char simulbot[NICKLEN];       /* used for hub->leaf cmd simulation, holds bot that results should be sent to */
   char simulbot[NICKLEN];       /* used for hub->leaf cmd simulation, holds bot that results should be sent to */

+ 83 - 0
src/dccutil.c

@@ -430,6 +430,86 @@ void trim_dcclist(int top_index)
   dcc_total = top_index + 1;    
   dcc_total = top_index + 1;    
 }
 }
 
 
+int
+dcc_read(FILE *f)
+{
+  char inbuf[1024] = "", *type = NULL, *buf = NULL;
+  int idx = -1;
+  bool isserv = 0;
+
+  while (fgets(inbuf, sizeof(inbuf), f) != NULL) {
+    remove_crlf(inbuf);
+    buf = inbuf;
+
+    if (!strcmp(buf, "+dcc"))
+      return idx;
+    
+    type = newsplit(&buf);
+    if (!strcmp(type, "type")) {
+      struct dcc_table *dcc_type = NULL;
+      size_t dcc_size = 0;
+
+//      if (!strcmp(buf, "CHAT"))
+//        dcc_type = &DCC_CHAT;
+      if (!strcmp(buf, "SERVER")) {
+        dcc_type = &SERVER_SOCKET;
+        isserv = 1;
+      }
+//      if (!strcmp(buf, "BOT"))
+//        dcc_type = &DCC_BOT;
+    
+      if (dcc_type) {
+        idx = new_dcc(dcc_type, dcc_size);
+        if (isserv)
+          servidx = idx;
+      }
+    }
+
+    if (idx >= 0) {
+      if (!strcmp(type, "addr"))
+        dcc[idx].addr = my_atoul(buf);
+      if (!strcmp(type, "sock")) {
+        dcc[idx].sock = atoi(buf);
+        if (isserv)
+          serv = dcc[idx].sock;
+      }
+      if (!strcmp(type, "port"))
+        dcc[idx].port = atoi(buf);
+      if (!strcmp(type, "nick"))
+        strlcpy(dcc[idx].nick, buf, NICKLEN);
+      if (!strcmp(type, "host")) {
+        strlcpy(dcc[idx].host, buf, UHOSTLEN);
+      }
+    }
+  }
+  return -1;
+}
+
+void 
+dcc_write(FILE *f, int idx)
+{
+  if (dcc[idx].sock > 0) {
+    fprintf(f, "-dcc\n");
+    if (dcc[idx].type)
+      fprintf(f, "type %s\n", dcc[idx].type->name);
+//  if (user)
+//  fprintf(f, "user %s\n", dcc[idx].user->handle);
+    if (dcc[idx].addr)
+      fprintf(f, "addr %u\n", dcc[idx].addr);
+    if (dcc[idx].status)
+      fprintf(f, "status %lu\n", dcc[idx].status);
+    fprintf(f, "sock %d\n", dcc[idx].sock);
+//  fprintf(f, "simul %d\n", dcc[idx].simul);
+    if (dcc[idx].port)
+      fprintf(f, "port %d\n", dcc[idx].port);  
+    if (dcc[idx].nick[0])
+      fprintf(f, "nick %s\n", dcc[idx].nick);
+    if (dcc[idx].host[0])
+      fprintf(f, "host %s\n", dcc[idx].host);
+    fprintf(f, "+dcc\n");
+  }
+}
+
 /* Mark an entry as lost and deconstruct it's contents. It will be securely
 /* Mark an entry as lost and deconstruct it's contents. It will be securely
  * removed from the dcc list in the main loop.
  * removed from the dcc list in the main loop.
  */
  */
@@ -589,6 +669,9 @@ flush_lines(int idx, struct chat_info *ci)
 int
 int
 new_dcc(struct dcc_table *type, int xtra_size)
 new_dcc(struct dcc_table *type, int xtra_size)
 {
 {
+  if (!type)
+    return -1;
+
   if (dcc_total == max_dcc)
   if (dcc_total == max_dcc)
     return -1;
     return -1;
 
 

+ 3 - 0
src/dccutil.h

@@ -53,6 +53,9 @@ void identd_open();
 void identd_close();
 void identd_close();
 port_t listen_all(port_t, bool);
 port_t listen_all(port_t, bool);
 bool valid_idx(int);
 bool valid_idx(int);
+int dcc_read(FILE *);
+void dcc_write(FILE *, int);
+
 extern int		max_dcc;
 extern int		max_dcc;
 extern time_t		connect_timeout;
 extern time_t		connect_timeout;
 
 

+ 6 - 4
src/debug.c

@@ -280,20 +280,22 @@ static void got_ill(int z)
 #endif /* DEBUG_CONTEXT */
 #endif /* DEBUG_CONTEXT */
 }
 }
 
 
-static void got_hup(int) __attribute__((noreturn));
-
 static void
 static void
 got_hup(int z)
 got_hup(int z)
 {
 {
+  signal(SIGHUP, got_hup);
   putlog(LOG_MISC, "*", "GOT SIGHUP -- RESTARTING");
   putlog(LOG_MISC, "*", "GOT SIGHUP -- RESTARTING");
-  restart(-1);
+  do_restart = 1;
+//  restart(-1);
 }
 }
 
 
 static void
 static void
 got_usr1(int z)
 got_usr1(int z)
 {
 {
+  signal(SIGUSR1, got_usr1);
   putlog(LOG_DEBUG, "*", "GOT SIGUSR1 -- RECHECKING BINARY");
   putlog(LOG_DEBUG, "*", "GOT SIGUSR1 -- RECHECKING BINARY");
-  reload_bin_data();
+  do_restart = 2;
+//  reload_bin_data();
 }
 }
 
 
 void init_signals() 
 void init_signals() 

+ 26 - 25
src/main.c

@@ -76,6 +76,7 @@ bool	have_take = 1;
 int	default_flags = 0;	/* Default user flags and */
 int	default_flags = 0;	/* Default user flags and */
 int	default_uflags = 0;	/* Default userdefinied flags for people
 int	default_uflags = 0;	/* Default userdefinied flags for people
 				   who say 'hello' or for .adduser */
 				   who say 'hello' or for .adduser */
+int     do_restart = 0;
 bool	backgrd = 1;		/* Run in the background? */
 bool	backgrd = 1;		/* Run in the background? */
 uid_t   myuid;
 uid_t   myuid;
 pid_t   mypid;
 pid_t   mypid;
@@ -84,6 +85,8 @@ int 	updating = 0; 		/* this is set when the binary is called from itself. */
 char 	tempdir[DIRMAX] = "";
 char 	tempdir[DIRMAX] = "";
 char 	*binname = NULL;
 char 	*binname = NULL;
 time_t	online_since;		/* Unix-time that the bot loaded up */
 time_t	online_since;		/* Unix-time that the bot loaded up */
+time_t  restart_time;
+bool	restart_was_update = 0;
 
 
 char	owner[121] = "";	/* Permanent owner(s) of the bot */
 char	owner[121] = "";	/* Permanent owner(s) of the bot */
 char	version[81] = "";	/* Version info (long form) */
 char	version[81] = "";	/* Version info (long form) */
@@ -98,7 +101,7 @@ static char do_killbot[21] = "";
 static int kill_sig;
 static int kill_sig;
 static char *update_bin = NULL;
 static char *update_bin = NULL;
 static bool checktrace = 1;		/* Check for trace when starting up? */
 static bool checktrace = 1;		/* Check for trace when starting up? */
-
+char *socksfile = NULL;
 
 
 static char *getfullbinname(const char *argv_zero)
 static char *getfullbinname(const char *argv_zero)
 {
 {
@@ -272,12 +275,11 @@ static void show_help()
 }
 }
 
 
 // leaf: BkLP
 // leaf: BkLP
-#define PARSE_FLAGS STR("0234:aB:cCd:De:EH:k:L:P:hnr:stu:U:v")
+#define PARSE_FLAGS STR("0234:aB:cCd:De:EH:k:hnr:stu:U:v")
 #define FLAGS_CHECKPASS STR("cCdDeEhknrtuUv")
 #define FLAGS_CHECKPASS STR("cCdDeEhknrtuUv")
 static void dtx_arg(int argc, char *argv[])
 static void dtx_arg(int argc, char *argv[])
 {
 {
   int i = 0;
   int i = 0;
-  int localhub_pid = 0;
   char *p = NULL;
   char *p = NULL;
   
   
   opterr = 0;
   opterr = 0;
@@ -388,18 +390,6 @@ static void dtx_arg(int argc, char *argv[])
         }
         }
 	exit(0);
 	exit(0);
       }
       }
-      case 'L':
-      {
-        localhub_pid = checkpid(optarg, NULL);
-        break;
-      }
-      case 'P':
-        if (atoi(optarg) && localhub_pid && (atoi(optarg) != localhub_pid))
-          exit(3);
-        else
-          sdprintf("Updating...");
-        updating = UPDATE_AUTO;
-        break;
       case '?':
       case '?':
       default:
       default:
         break;
         break;
@@ -597,14 +587,12 @@ static void startup_checks(int hack) {
     } else {
     } else {
       /* this needs to be both hub/leaf */
       /* this needs to be both hub/leaf */
       if (update_bin) {					/* invokved with -u/-U */
       if (update_bin) {					/* invokved with -u/-U */
-        if (updating == UPDATE_AUTO && conf.bot && conf.bot->pid) {		/* invoked with -u bin, so kill  */
-          
-          kill(conf.bot->pid, SIGKILL);
-          unlink(conf.bot->pid_file);
-          writepid(conf.bot->pid_file, mypid);
-        } else if (!conf.bot)
+        if (!conf.bot)
           updating = UPDATE_EXIT;		//if we don't have a botlist, dont bother with restarting bots...
           updating = UPDATE_EXIT;		//if we don't have a botlist, dont bother with restarting bots...
 
 
+//        if (updating == UPDATE_AUTO && conf.bot && conf.bot->pid)
+//          kill(conf.bot->pid, SIGHUP);
+
         updatebin(DP_STDOUT, update_bin, 1);	/* will call restart all bots */
         updatebin(DP_STDOUT, update_bin, 1);	/* will call restart all bots */
         /* never reached */
         /* never reached */
         exit(0);
         exit(0);
@@ -727,7 +715,7 @@ printf("out: %s\n", out);
   /* Check and load conf file */
   /* Check and load conf file */
   startup_checks(0);
   startup_checks(0);
 
 
-  if ((conf.bot->localhub && !updating) || !conf.bot->localhub) {
+  if (!socksfile && ((conf.bot->localhub && !updating) || !conf.bot->localhub)) {
     if ((conf.bot->pid > 0) && conf.bot->pid_file) {
     if ((conf.bot->pid > 0) && conf.bot->pid_file) {
       sdprintf("%s is already running, pid: %d", conf.bot->nick, conf.bot->pid);
       sdprintf("%s is already running, pid: %d", conf.bot->nick, conf.bot->pid);
       exit(1);
       exit(1);
@@ -800,7 +788,8 @@ printf("out: %s\n", out);
 
 
   if (backgrd) {
   if (backgrd) {
 #ifndef CYGWIN_HACKS
 #ifndef CYGWIN_HACKS
-    mypid = do_fork();
+    if (!socksfile) {
+      mypid = do_fork();
 
 
 /*
 /*
     printf("  |- %-10s (%d)\n", conf.bot->nick, pid);
     printf("  |- %-10s (%d)\n", conf.bot->nick, pid);
@@ -821,13 +810,16 @@ printf("out: %s\n", out);
             COLOR_END(-1), BOLD(-1), BOLD_END(-1), BOLD(-1), BOLD_END(-1), BOLD(-1), BOLD_END(-1),
             COLOR_END(-1), BOLD(-1), BOLD_END(-1), BOLD(-1), BOLD_END(-1), BOLD(-1), BOLD_END(-1),
             BOLD(-1), BOLD_END(-1), YELLOW(-1), COLOR_END(-1), mypid, YELLOW(-1), COLOR_END(-1));
             BOLD(-1), BOLD_END(-1), YELLOW(-1), COLOR_END(-1), mypid, YELLOW(-1), COLOR_END(-1));
 #endif
 #endif
+    } else
+      writepid(conf.bot->pid_file, mypid);
     close_tty();
     close_tty();
   } else {
   } else {
 #endif /* !CYGWIN_HACKS */
 #endif /* !CYGWIN_HACKS */
 #ifdef CYGWIN_HACKS
 #ifdef CYGWIN_HACKS
     FreeConsole();
     FreeConsole();
 #endif /* CYGWIN_HACKS */
 #endif /* CYGWIN_HACKS */
-    printf("%s[%s%s%s]%s -%s- initiated\n", BOLD(-1), BOLD_END(-1), settings.packname, BOLD(-1), BOLD_END(-1), conf.bot->nick);
+    if (!socksfile)
+      printf("%s[%s%s%s]%s -%s- initiated\n", BOLD(-1), BOLD_END(-1), settings.packname, BOLD(-1), BOLD_END(-1), conf.bot->nick);
     writepid(conf.bot->pid_file, mypid);
     writepid(conf.bot->pid_file, mypid);
   }
   }
 
 
@@ -838,7 +830,7 @@ printf("out: %s\n", out);
     dcc[n].addr = iptolong(getmyip());
     dcc[n].addr = iptolong(getmyip());
     dcc[n].sock = STDOUT;
     dcc[n].sock = STDOUT;
     dcc[n].timeval = now;
     dcc[n].timeval = now;
-    dcc[n].u.chat->con_flags = conmask;
+    dcc[n].u.chat->con_flags = conmask | LOG_ALL;
     dcc[n].u.chat->strip_flags = STRIP_ALL;
     dcc[n].u.chat->strip_flags = STRIP_ALL;
     dcc[n].status = STAT_ECHO;
     dcc[n].status = STAT_ECHO;
     strcpy(dcc[n].nick, "HQ");
     strcpy(dcc[n].nick, "HQ");
@@ -866,6 +858,9 @@ printf("out: %s\n", out);
   timer_create_secs(3600, "core_hourly", (Function) core_hourly);
   timer_create_secs(3600, "core_hourly", (Function) core_hourly);
   timer_create_secs(1800, "core_halfhourly", (Function) core_halfhourly);
   timer_create_secs(1800, "core_halfhourly", (Function) core_halfhourly);
 
 
+  if (socksfile)
+    readsocks(socksfile);
+
   debug0("main: entering loop");
   debug0("main: entering loop");
 
 
   int socket_cleanup = 0, status = 0, xx, i = 0, idx = 0;
   int socket_cleanup = 0, status = 0, xx, i = 0, idx = 0;
@@ -965,6 +960,12 @@ printf("out: %s\n", out);
         flush_modes();
         flush_modes();
       socket_cleanup = 0;	/* If we've been idle, cleanup & flush */
       socket_cleanup = 0;	/* If we've been idle, cleanup & flush */
     }
     }
+    if (do_restart) {
+      if (do_restart == 1)
+        restart(-1);
+      else
+        reload_bin_data();
+    }
   }
   }
 
 
   return 0;		/* never reached but what the hell */
   return 0;		/* never reached but what the hell */

+ 4 - 4
src/main.h

@@ -14,10 +14,10 @@ enum {
 };
 };
 
 
 extern int		role, default_flags, default_uflags, do_confedit,
 extern int		role, default_flags, default_uflags, do_confedit,
-			updating;
-extern bool		use_stderr, backgrd, used_B, term_z, loading, have_take;
-extern char		tempdir[], *binname, owner[], version[], ver[], quit_msg[];
-extern time_t		online_since, now;
+			updating, do_restart;
+extern bool		use_stderr, backgrd, used_B, term_z, loading, have_take, restart_was_update;
+extern char		tempdir[], *binname, owner[], version[], ver[], quit_msg[], *socksfile;
+extern time_t		online_since, now, restart_time;
 extern uid_t		myuid;
 extern uid_t		myuid;
 extern pid_t            mypid;
 extern pid_t            mypid;
 extern const time_t	buildts;
 extern const time_t	buildts;

+ 161 - 23
src/misc.c

@@ -31,6 +31,7 @@
 #include "src/mod/irc.mod/irc.h"
 #include "src/mod/irc.mod/irc.h"
 #include "userrec.h"
 #include "userrec.h"
 #include "stat.h"
 #include "stat.h"
+#include "net.h"
 
 
 #include <sys/wait.h>
 #include <sys/wait.h>
 #include <stdarg.h>
 #include <stdarg.h>
@@ -555,29 +556,153 @@ void kill_bot(char *s1, char *s2)
     server_die();
     server_die();
   chatout("*** %s\n", s1);
   chatout("*** %s\n", s1);
   botnet_send_chat(-1, conf.bot->nick, s1);
   botnet_send_chat(-1, conf.bot->nick, s1);
-  botnet_send_bye();
+  botnet_send_bye(s2);
   fatal(s2, 0);
   fatal(s2, 0);
 }
 }
 
 
+void
+readsocks(const char *fname)
+{
+  FILE *f = NULL;
+
+  if (!(f = fopen(fname, "r"))) {
+    fatal("CANT READ SOCKSFILE", 0);
+  }
+
+  char buf[1024] = "", *nick = NULL, *bufp = NULL, *type = NULL;
+  time_t old_buildts = 0;
+
+  while (fgets(buf, sizeof(buf), f) != NULL) {
+    remove_crlf(buf);
+    bufp = buf;
+
+//    dprintf(DP_STDOUT, "read line: %s\n", buf);
+    type = newsplit(&bufp);
+    if (!strcmp(type, "-dcc"))
+      dprintf(DP_STDOUT, "Added dcc: %d\n", dcc_read(f));
+    else if (!strcmp(type, "-sock"))
+      dprintf(DP_STDOUT, "Added fd: %d\n", sock_read(f));
+    else if (!strcmp(type, "+online_since"))
+      online_since = strtol(bufp, NULL, 10);
+    else if (!strcmp(type, "+buildts"))
+      old_buildts = strtol(bufp, NULL, 10);
+    else if (!strcmp(type, "+botname"))
+      nick = strdup(bufp);
+  }
+
+  restart_time = now;
+  if (old_buildts && buildts > old_buildts)
+    restart_was_update = 1;
+
+  tell_dcc(DP_STDOUT);
+  tell_netdebug(DP_STDOUT);
+
+  unlink(fname);
+  fclose(f);
+  if (servidx >= 0) {
+    rehash_server(dcc[servidx].host, nick);
+    dprintf(DP_DUMP, "VERSION\n");
+    reset_chans = 1;
+  }
+  free(nick);
+  if (socksfile)
+    free(socksfile);
+}
+
+
 /* Update system code
 /* Update system code
  */
  */
 
 
-void 
+void
 restart(int idx)
 restart(int idx)
 {
 {
-  char buf[1024] = "";
   const char *reason = updating ? "Updating..." : "Restarting...";
   const char *reason = updating ? "Updating..." : "Restarting...";
+  Tempfile *socks = new Tempfile("socks");
+  int fd = 0;
+
+  sdprintf("%s", reason); 
+
+
+  if (tands > 0) {
+    botnet_send_chat(-1, conf.bot->nick, (char *) reason);
+    botnet_send_bye(reason);
+  }
+
+  /* kill all connections except STDOUT/server */
+  for (fd = 0; fd < dcc_total; fd++) {
+    if (dcc[fd].type && dcc[fd].type != &SERVER_SOCKET && dcc[fd].sock != STDOUT) {
+      if (dcc[fd].sock >= 0)
+        killsock(dcc[fd].sock);
+      lostdcc(fd);
+    }
+  }
+
+  /* write out all leftover dcc[] entries */
+  for (fd = 0; fd < dcc_total; fd++)
+    if (dcc[fd].type && dcc[fd].sock != STDOUT)
+      dcc_write(socks->f, fd);
+
+  /* write out all leftover socklist[] entries */
+  for (fd = 0; fd < MAXSOCKS; fd++)
+    if (socklist[fd].sock != STDOUT)
+      sock_write(socks->f, fd);
+
+  if (server_online) {
+    if (botname[0])
+      fprintf(socks->f, "+botname %s\n", botname);
+    fprintf(socks->f, "+online_since %li\n", online_since);
+    fprintf(socks->f, "+buildts %li\n", buildts);
+  }
+  fflush(socks->f);
+  socks->my_close();
+
+  if (conf.bot->hub)
+    write_userfile(idx);
+
+  if (server_online) {
+    do_chanset(NULL, NULL, "+inactive", DO_LOCAL);
+    dprintf(DP_DUMP, "JOIN 0\n");
+  }
+
+  fixmod(binname);
+
+  /* replace image now */
+  char *argv[5] = { NULL, NULL, NULL, NULL, NULL };
+  char shit[5] = "";
+
+  simple_sprintf(shit, "-%s%s%s", !backgrd ? "n" : "", term_z ? "t" : "", sdebug ? "D" : "");
+
+  argv[0] = strdup(binname);
+  argv[1] = strdup(shit);
+  argv[2] = strdup("-B");
+  argv[3] = strdup(conf.bot->nick);
+  argv[4] = NULL;
+
+  unlink(conf.bot->pid_file);
+  FILE *fp = NULL;
+  if (!(fp = fopen(conf.bot->pid_file, "w")))
+    return;
+  fprintf(fp, "%d %s\n", getpid(), socks->file);
+  fclose(fp);
+
+  execvp(argv[0], &argv[0]);
+
+  /* hopefully this is never reached */
+  putlog(LOG_MISC, "*", "Could not restart: %s", strerror(errno));
+  return;
+}
+
+#ifdef NO
+void 
+hard_restart(int idx)
+{
+  char buf[1024] = "";
 
 
-  sdprintf("restarting [%s]", reason); 
   write_userfile(idx);
   write_userfile(idx);
   if (!conf.bot->hub) {
   if (!conf.bot->hub) {
     nuke_server((char *) reason);		/* let's drop the server connection ASAP */
     nuke_server((char *) reason);		/* let's drop the server connection ASAP */
     cycle_time = 0;
     cycle_time = 0;
   }
   }
-  if (tands > 0) {
-    botnet_send_chat(-1, conf.bot->nick, (char *) reason);
-    botnet_send_bye();
-  }
   fatal(idx <= 0x7FF0 ? reason : NULL, 1);
   fatal(idx <= 0x7FF0 ? reason : NULL, 1);
   usleep(2000 * 500);
   usleep(2000 * 500);
   simple_sprintf(buf, "%s -B %s\n", binname, conf.bot->nick);
   simple_sprintf(buf, "%s -B %s\n", binname, conf.bot->nick);
@@ -585,6 +710,7 @@ restart(int idx)
   system(buf); /* start new bot. */
   system(buf); /* start new bot. */
   exit(0);
   exit(0);
 }
 }
+#endif
 
 
 int updatebin(int idx, char *par, int secs)
 int updatebin(int idx, char *par, int secs)
 {
 {
@@ -594,7 +720,7 @@ int updatebin(int idx, char *par, int secs)
   }
   }
 
 
   char *path = (char *) my_calloc(1, strlen(binname) + strlen(par) + 2);
   char *path = (char *) my_calloc(1, strlen(binname) + strlen(par) + 2);
-  char *newbin = NULL, old[DIRMAX] = "", testbuf[DIRMAX] = "";
+  char *newbin = NULL, buf[DIRMAX] = "";
   int i;
   int i;
 
 
   strcpy(path, binname);
   strcpy(path, binname);
@@ -638,8 +764,8 @@ int updatebin(int idx, char *par, int secs)
 
 
   /* make a backup just in case. */
   /* make a backup just in case. */
 
 
-  simple_snprintf(old, sizeof old, "%s.bin.old", tempdir);
-  copyfile(binname, old);
+  simple_snprintf(buf, sizeof(buf), "%s.bin.old", tempdir);
+  copyfile(binname, buf);
 
 
   write_settings(path, -1, 0);	/* re-write the binary with our packdata */
   write_settings(path, -1, 0);	/* re-write the binary with our packdata */
 
 
@@ -652,10 +778,10 @@ int updatebin(int idx, char *par, int secs)
   }
   }
 
 
   /* The binary should return '2' when ran with -2, if not it's probably corrupt. */
   /* The binary should return '2' when ran with -2, if not it's probably corrupt. */
-  simple_snprintf(testbuf, sizeof testbuf, STR("%s -2"), path);
+  simple_snprintf(buf, sizeof(buf), STR("%s -2"), path);
 #ifndef CYGWIN_HACKS
 #ifndef CYGWIN_HACKS
-  putlog(LOG_DEBUG, "*", "Running for update binary test: %s", testbuf);
-  i = system(testbuf);
+  putlog(LOG_DEBUG, "*", "Running for update binary test: %s", buf);
+  i = system(buf);
   if (i == -1 || WEXITSTATUS(i) != 2) {
   if (i == -1 || WEXITSTATUS(i) != 2) {
     dprintf(idx, "Couldn't restart new binary (error %d)\n", i);
     dprintf(idx, "Couldn't restart new binary (error %d)\n", i);
     putlog(LOG_MISC, "*", "Couldn't restart new binary (error %d)", i);
     putlog(LOG_MISC, "*", "Couldn't restart new binary (error %d)", i);
@@ -665,10 +791,10 @@ int updatebin(int idx, char *par, int secs)
 #endif /* !CYGWIN_HACKS */
 #endif /* !CYGWIN_HACKS */
 
 
   /* now to send our config to the new binary */
   /* now to send our config to the new binary */
-  simple_snprintf(testbuf, sizeof testbuf, STR("%s -4 %s"), path, conffile->file);
+  simple_snprintf(buf, sizeof(buf), STR("%s -4 %s"), path, conffile->file);
 #ifndef CYGWIN_HACKS
 #ifndef CYGWIN_HACKS
-  putlog(LOG_DEBUG, "*", "Running for update conf: %s", testbuf);
-  i = system(testbuf);
+  putlog(LOG_DEBUG, "*", "Running for update conf: %s", buf);
+  i = system(buf);
   delete conffile;
   delete conffile;
   if (i == -1 || WEXITSTATUS(i) != 6) { /* 6 for successfull config read/write */
   if (i == -1 || WEXITSTATUS(i) != 6) { /* 6 for successfull config read/write */
     dprintf(idx, "Couldn't pass config to new binary (error %d)\n", i);
     dprintf(idx, "Couldn't pass config to new binary (error %d)\n", i);
@@ -698,15 +824,27 @@ int updatebin(int idx, char *par, int secs)
     printf("* Moved binary to: %s\n", binname);
     printf("* Moved binary to: %s\n", binname);
     fatal("Binary updated.", 0);
     fatal("Binary updated.", 0);
   }
   }
+  if (updating == UPDATE_AUTO) {
+    /* Make all other bots do a soft restart */
+    conf_checkpids();
+    conf_killbot(NULL, NULL, SIGHUP);
+
+    if (conf.bot->pid)
+      kill(conf.bot->pid, SIGHUP);
+    exit(0);
+  }
 
 
   if (!conf.bot->hub && secs > 0) {
   if (!conf.bot->hub && secs > 0) {
-    char buf[DIRMAX] = "";
-
-    /* this forces all running bots to be restarted (except localhub/me) */
-    simple_snprintf(buf, sizeof buf, STR("%s -L %s -P %d"), binname, conf.bot->nick, getpid());
-    putlog(LOG_DEBUG, "*", "Running for update: %s", buf);
-    system(buf);	/* restarts other bots running, removes pid files */
+    /* Make all other bots do a soft restart */
+    conf_checkpids();
+    conf_killbot(NULL, NULL, SIGHUP);
     
     
+    /* invoked with -u */
+    if (updating == UPDATE_AUTO) {
+      if (conf.bot->pid)
+        kill(conf.bot->pid, SIGHUP);
+      exit(0);
+    }
     /* this odd statement makes it so specifying 1 sec will restart other bots running
     /* this odd statement makes it so specifying 1 sec will restart other bots running
      * and then just restart with no delay */
      * and then just restart with no delay */
     updating = UPDATE_AUTO;
     updating = UPDATE_AUTO;

+ 2 - 1
src/misc.h

@@ -13,7 +13,7 @@
 
 
 
 
 char *wbanner(void);
 char *wbanner(void);
-void restart(int) __attribute__((noreturn));
+void restart(int);
 int coloridx(int);
 int coloridx(int);
 const char *color(int, int, int);
 const char *color(int, int, int);
 void shuffle(char *, char *);
 void shuffle(char *, char *);
@@ -22,6 +22,7 @@ void showhelp(int, struct flag_record *, char *);
 char *replace(const char *, const char *, const char *);
 char *replace(const char *, const char *, const char *);
 int goodpass(char *, int, char *);
 int goodpass(char *, int, char *);
 int bot_aggressive_to(struct userrec *);
 int bot_aggressive_to(struct userrec *);
+void readsocks(const char *);
 int updatebin(int, char *, int);
 int updatebin(int, char *, int);
 size_t my_strcpy(char *, char *);
 size_t my_strcpy(char *, char *);
 void maskhost(const char *, char *);
 void maskhost(const char *, char *);

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

@@ -2371,8 +2371,7 @@ static int gotjoin(char *from, char *chname)
 	  /* It was me joining! Need to update the channel record with the
 	  /* It was me joining! Need to update the channel record with the
 	   * unique name for the channel (as the server see's it). <cybah>
 	   * unique name for the channel (as the server see's it). <cybah>
 	   */
 	   */
-	  strncpy(chan->name, chname, 81);
-	  chan->name[80] = 0;
+	  strlcpy(chan->name, chname, 81);
 	  chan->status &= ~CHAN_JUPED;
 	  chan->status &= ~CHAN_JUPED;
 
 
           /* ... and log us joining. Using chan->dname for the channel is
           /* ... and log us joining. Using chan->dname for the channel is

+ 1 - 1
src/mod/irc.mod/cmdsirc.c

@@ -1689,7 +1689,7 @@ static void cmd_reset(int idx, char *par)
     putlog(LOG_CMDS, "*", "#%s# reset all", dcc[idx].nick);
     putlog(LOG_CMDS, "*", "#%s# reset all", dcc[idx].nick);
     dprintf(idx, "Resetting channel info for all channels...\n");
     dprintf(idx, "Resetting channel info for all channels...\n");
     for (chan = chanset; chan; chan = chan->next) {
     for (chan = chanset; chan; chan = chan->next) {
-      if (channel_active(chan))
+      if (channel_active(chan) || (!channel_active(chan) && shouldjoin(chan)))
 	reset_chan_info(chan);
 	reset_chan_info(chan);
     }
     }
   }
   }

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

@@ -931,8 +931,7 @@ my_setkey(struct chanset_t *chan, char *k)
     chan->channel.key = (char *) my_calloc(1, 1);
     chan->channel.key = (char *) my_calloc(1, 1);
     return;
     return;
   }
   }
-  chan->channel.key = (char *) my_calloc(1, strlen(k) + 1);
-  strcpy(chan->channel.key, k);
+  chan->channel.key = strdup(k);
 }
 }
 
 
 /* Adds a ban, exempt or invite mask to the list
 /* Adds a ban, exempt or invite mask to the list
@@ -949,10 +948,8 @@ new_mask(masklist *m, char *s, char *who)
   m->next->next = NULL;
   m->next->next = NULL;
   m->next->mask = (char *) my_calloc(1, 1);
   m->next->mask = (char *) my_calloc(1, 1);
   free(m->mask);
   free(m->mask);
-  m->mask = (char *) my_calloc(1, strlen(s) + 1);
-  strcpy(m->mask, s);
-  m->who = (char *) my_calloc(1, strlen(who) + 1);
-  strcpy(m->who, who);
+  m->mask = strdup(s);
+  m->who = strdup(who);
   m->timer = now;
   m->timer = now;
 }
 }
 
 
@@ -1043,9 +1040,14 @@ any_ops(struct chanset_t *chan)
 
 
 /* Reset the channel information.
 /* Reset the channel information.
  */
  */
-static void
+void
 reset_chan_info(struct chanset_t *chan)
 reset_chan_info(struct chanset_t *chan)
 {
 {
+  if (!chan) return;
+
+  if (!chan->name[0])
+    strlcpy(chan->name, chan->dname, 81);
+
   /* Don't reset the channel if we're already resetting it */
   /* Don't reset the channel if we're already resetting it */
   if (!shouldjoin(chan)) {
   if (!shouldjoin(chan)) {
     dprintf(DP_MODE, "PART %s\n", chan->name);
     dprintf(DP_MODE, "PART %s\n", chan->name);

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

@@ -77,7 +77,6 @@ static void detect_autokick(char *, char *, struct chanset_t *, char *);
 static bool do_op(char *, struct chanset_t *, time_t, bool);
 static bool do_op(char *, struct chanset_t *, time_t, bool);
 static void request_op(struct chanset_t *);
 static void request_op(struct chanset_t *);
 static void request_in(struct chanset_t *);
 static void request_in(struct chanset_t *);
-static void reset_chan_info(struct chanset_t *);
 static void my_setkey(struct chanset_t *, char *);
 static void my_setkey(struct chanset_t *, char *);
 static void maybe_revenge(struct chanset_t *, char *, char *, int);
 static void maybe_revenge(struct chanset_t *, char *, char *, int);
 static bool detect_chan_flood(char *, char *, char *, struct chanset_t *, int,
 static bool detect_chan_flood(char *, char *, char *, struct chanset_t *, int,
@@ -111,6 +110,7 @@ void recheck_channel(struct chanset_t *, int);
 void recheck_channel_modes(struct chanset_t *);
 void recheck_channel_modes(struct chanset_t *);
 void irc_report(int, int);
 void irc_report(int, int);
 void flush_modes();
 void flush_modes();
+void reset_chan_info(struct chanset_t *);
 
 
 extern int		max_bans, max_exempts, max_invites, max_modes;
 extern int		max_bans, max_exempts, max_invites, max_modes;
 extern bool		use_354;
 extern bool		use_354;

+ 4 - 1
src/mod/server.mod/server.h

@@ -7,6 +7,7 @@
 #define _EGG_MOD_SERVER_SERVER_H
 #define _EGG_MOD_SERVER_SERVER_H
 
 
 #include "src/tclhash.h"
 #include "src/tclhash.h"
+#include "src/dcc.h"
 
 
 #define DO_LOST 1
 #define DO_LOST 1
 #define NO_LOST 0
 #define NO_LOST 0
@@ -52,7 +53,7 @@ extern time_t		server_online, cycle_time, flud_time, flud_ctcp_time;
 extern char		cursrvname[], botrealname[], botuserhost[], ctcp_reply[],
 extern char		cursrvname[], botrealname[], botuserhost[], ctcp_reply[],
 			newserver[], newserverpass[], curnetwork[], botuserip[];
 			newserver[], newserverpass[], curnetwork[], botuserip[];
 extern struct server_list *serverlist;
 extern struct server_list *serverlist;
-
+extern struct dcc_table SERVER_SOCKET;
 int check_bind_ctcpr(char *, char *, struct userrec *, char *, char *, char *, bind_table_t *);
 int check_bind_ctcpr(char *, char *, struct userrec *, char *, char *, char *, bind_table_t *);
 
 
 #define check_bind_ctcp(a, b, c, d, e, f) check_bind_ctcpr(a, b, c, d, e, f, BT_ctcp)
 #define check_bind_ctcp(a, b, c, d, e, f) check_bind_ctcpr(a, b, c, d, e, f, BT_ctcp)
@@ -67,4 +68,6 @@ void add_server(char *);
 void clearq(struct server_list *);
 void clearq(struct server_list *);
 void nuke_server(const char *);
 void nuke_server(const char *);
 bool match_my_nick(char *);
 bool match_my_nick(char *);
+void rehash_server(const char *, const char *);
+void join_chans();
 
 

+ 32 - 16
src/mod/server.mod/servmsg.c

@@ -143,26 +143,24 @@ bool match_my_nick(char *nick)
   return (!rfc_casecmp(nick, botname));
   return (!rfc_casecmp(nick, botname));
 }
 }
 
 
-/* 001: welcome to IRC (use it to fix the server name)
- */
-static int got001(char *from, char *msg)
+void rehash_server(const char *servname, const char *nick)
 {
 {
-  struct server_list *x = NULL;
-
   server_online = now;
   server_online = now;
-  fixcolon(msg);
-  /* Ok...param #1 of 001 = what server thinks my nick is */
-  strlcpy(botname, msg, NICKLEN);
   altnick_char = 0;
   altnick_char = 0;
-  strlcpy(cursrvname, from, sizeof(cursrvname));
+  strlcpy(cursrvname, servname, sizeof(cursrvname));
 
 
-  dprintf(DP_SERVER, "WHOIS %s\n", botname); /* get user@host */
-  dprintf(DP_SERVER, "USERHOST %s\n", botname); /* get user@ip */
-  dprintf(DP_SERVER, "MODE %s +iws\n", botname);
-  x = serverlist;
-  if (x == NULL)
-    return 0;			/* Uh, no server list */
+  if (nick && nick[0]) {
+    strlcpy(botname, nick, NICKLEN);
 
 
+    dprintf(DP_SERVER, "WHOIS %s\n", botname); /* get user@host */
+    dprintf(DP_SERVER, "USERHOST %s\n", botname); /* get user@ip */
+    dprintf(DP_SERVER, "MODE %s +iws\n", botname);
+  }
+}
+
+void 
+join_chans()
+{
   for (register struct chanset_t *chan = chanset; chan; chan = chan->next) {
   for (register struct chanset_t *chan = chanset; chan; chan = chan->next) {
     chan->status &= ~(CHAN_ACTIVE | CHAN_PEND | CHAN_JOINING);
     chan->status &= ~(CHAN_ACTIVE | CHAN_PEND | CHAN_JOINING);
     if (shouldjoin(chan)) {
     if (shouldjoin(chan)) {
@@ -171,7 +169,25 @@ static int got001(char *from, char *msg)
       chan->status |= CHAN_JOINING;
       chan->status |= CHAN_JOINING;
     }
     }
   }
   }
+}
+
+/* 001: welcome to IRC (use it to fix the server name)
+ */
+static int got001(char *from, char *msg)
+{
+
+  fixcolon(msg);
+  rehash_server(from, msg);
+  /* Ok...param #1 of 001 = what server thinks my nick is */
+
+  join_chans();
+
   if (egg_strcasecmp(from, dcc[servidx].host)) {
   if (egg_strcasecmp(from, dcc[servidx].host)) {
+    struct server_list *x = serverlist;
+
+    if (x == NULL)
+      return 0;			/* Uh, no server list */
+
     putlog(LOG_MISC, "*", "(%s claims to be %s; updating server list)", dcc[servidx].host, from);
     putlog(LOG_MISC, "*", "(%s claims to be %s; updating server list)", dcc[servidx].host, from);
     for (int i = curserv; i > 0 && x != NULL; i--)
     for (int i = curserv; i > 0 && x != NULL; i--)
       x = x->next;
       x = x->next;
@@ -962,7 +978,7 @@ static void timeout_server(int idx)
 
 
 static void server_activity(int, char *, int);
 static void server_activity(int, char *, int);
 
 
-static struct dcc_table SERVER_SOCKET =
+struct dcc_table SERVER_SOCKET =
 {
 {
   "SERVER",
   "SERVER",
   0,
   0,

+ 8 - 0
src/mod/share.mod/share.c

@@ -1276,6 +1276,14 @@ finish_share(int idx)
   trigger_cfg_changed();	/* Set our local cfg settings from our userentry */
   trigger_cfg_changed();	/* Set our local cfg settings from our userentry */
   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);
+
+  if (reset_chans) {
+    reset_chans = 0;
+//    putlog(LOG_DEBUG, "*", "Resetting channel info for all channels...");
+//    for (chan = chanset; chan; chan = chan->next)
+//      reset_chan_info(chan);
+    join_chans();
+  }
 }
 }
 
 
 /* Begin the user transfer process.
 /* Begin the user transfer process.

+ 50 - 0
src/net.c

@@ -225,6 +225,7 @@ void init_net()
     socklist[i].ssl = NULL;
     socklist[i].ssl = NULL;
 #endif /* HAVE_SSL */
 #endif /* HAVE_SSL */
     socklist[i].flags = SOCK_UNUSED;
     socklist[i].flags = SOCK_UNUSED;
+    socklist[i].sock = -1;
   }
   }
 #ifdef HAVE_SSL
 #ifdef HAVE_SSL
   SSL_load_error_strings();
   SSL_load_error_strings();
@@ -360,6 +361,55 @@ int sockoptions(int sock, int operation, int sock_options)
   return -1;
   return -1;
 }
 }
 
 
+int
+sock_read(FILE *f)
+{
+  char inbuf[1024] = "", *type = NULL, *buf = NULL;
+  int fd = -1;
+
+  while (fgets(inbuf, sizeof(inbuf), f) != NULL) {
+    remove_crlf(inbuf);
+
+    buf = inbuf;
+    if (!strcmp(buf, "+sock"))
+      return fd;
+
+    type = newsplit(&buf);
+    if (!strcmp(type, "sock")) {
+      int sock = atoi(newsplit(&buf)), options = atoi(newsplit(&buf));
+
+      fd = allocsock(sock, options);
+    }
+
+    if (fd >= 0) {
+      if (!strcmp(type, "af"))
+        socklist[fd].af = atoi(buf);
+      if (!strcmp(type, "host"))
+        socklist[fd].host = strdup(buf);
+      if (!strcmp(type, "port"))
+        socklist[fd].port = atoi(buf);
+    }
+  }
+  return -1;
+}
+
+void 
+sock_write(FILE *f, int fd)
+{
+  if (socklist[fd].sock > 0) {
+    fprintf(f, "-sock\n");
+    fprintf(f, "sock %d %d\n", socklist[fd].sock, socklist[fd].flags);
+#ifdef USE_IPV6
+    fprintf(f, "af %u\n", socklist[fd].af);
+#endif
+    if (socklist[fd].host)
+      fprintf(f, "host %s\n", socklist[fd].host);
+    if (socklist[fd].port)
+      fprintf(f, "port %d\n", socklist[fd].port);
+    fprintf(f, "+sock\n");
+  }    
+}
+
 /* Return a free entry in the socket entry
 /* Return a free entry in the socket entry
  */
  */
 int allocsock(int sock, int options)
 int allocsock(int sock, int options)

+ 2 - 0
src/net.h

@@ -166,6 +166,8 @@ char *iptostr(in_addr_t);
 bool sock_has_data(int, int);
 bool sock_has_data(int, int);
 int sockoptions(int sock, int operation, int sock_options);
 int sockoptions(int sock, int operation, int sock_options);
 void init_net(void);
 void init_net(void);
+int sock_read(FILE *);
+void sock_write(FILE *, int);
 
 
 extern union sockaddr_union 		cached_myip4_so;
 extern union sockaddr_union 		cached_myip4_so;
 #ifdef USE_IPV6
 #ifdef USE_IPV6

+ 1 - 1
src/tandem.h

@@ -67,7 +67,7 @@ void botnet_send_join_idx(int);
 void botnet_send_join_party(int, int, int);
 void botnet_send_join_party(int, int, int);
 void botnet_send_part_idx(int, char *);
 void botnet_send_part_idx(int, char *);
 void botnet_send_part_party(int, int, char *, int);
 void botnet_send_part_party(int, int, char *, int);
-void botnet_send_bye();
+void botnet_send_bye(const char *);
 void botnet_send_nkch_part(int, int, char *);
 void botnet_send_nkch_part(int, int, char *);
 void botnet_send_nkch(int, char *);
 void botnet_send_nkch(int, char *);
 int bots_in_subtree(tand_t *);
 int bots_in_subtree(tand_t *);