]> skyeroc.xyz Git - dgamelaunch/commitdiff
Add possibility to backup the savefile before starting nethack.
authorJilles Tjoelker <jilles@stack.nl>
Wed, 17 Mar 2004 14:04:31 +0000 (14:04 +0000)
committerJilles Tjoelker <jilles@stack.nl>
Wed, 17 Mar 2004 14:04:31 +0000 (14:04 +0000)
git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@282 db0b04b0-f4d1-0310-9a6d-de3e77497b0e

Changelog
config.l
config.y
dgamelaunch.8
dgamelaunch.c
dgamelaunch.conf
dgamelaunch.h
dgl-common.c

index e788ba18e98873c169375f8698f9e918fc6a0279..9edc0009610dd0ac558ced05c2dbed38d5171145 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,9 @@
 1.4.5 (????/??/??)
        * Reset offset if necessary to show at least one game  to avoid things
          like "(15-14 of 14)".
+       * Backup the savefile before starting nethack to help prevent more
+         lost games. Note this must be explicitly configured in the
+         configuration file.
 
 1.4.4 (2004/03/07)
        * Show total number of games in progress below the list, useful if
index fedf2bb53727c9e831b0435c761b7b6d758a70b8..241a34f2e715bf29d7d8e5fd0ad9ad5364cb3c5a 100644 (file)
--- a/config.l
+++ b/config.l
@@ -65,6 +65,7 @@ COMMENT               ^#.*
 "rc_template"  { return TYPE_PATH_CANNED; }
 "passwd"       { return TYPE_PATH_PASSWD; }
 "lockfile"     { return TYPE_PATH_LOCKFILE; }
+"savefilefmt"  { return TYPE_PATH_SAVEFILEFMT; }
 
 \n             { line++; col = 0; }
 
index ead0bb93e0fd11b537d744bde22e5848d1376fa3..250ec747e89c8b8c9c531bdd65027f39bea76569 100644 (file)
--- a/config.y
+++ b/config.y
@@ -28,7 +28,8 @@ static const char* lookup_token (int t);
 %token TYPE_SUSER TYPE_SGROUP TYPE_SGID TYPE_SUID TYPE_MAX
 %token TYPE_PATH_NETHACK TYPE_PATH_DGLDIR TYPE_PATH_SPOOL
 %token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT
-%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_MALSTRING
+%token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_PATH_SAVEFILEFMT
+%token TYPE_MALSTRING
 %token <s> TYPE_VALUE
 %token <i> TYPE_NUMBER
 %type  <kt> KeyType
@@ -147,6 +148,11 @@ KeyPair: KeyType '=' TYPE_VALUE {
       myconfig->passwd = strdup($3);
       break;
 
+    case TYPE_PATH_SAVEFILEFMT:
+      if (myconfig->savefilefmt) free(myconfig->savefilefmt);
+      myconfig->savefilefmt = strdup($3);
+      break;
+
     default:
       fprintf(stderr, "%s:%d: token %s does not take a string, bailing out\n",
         config, line, lookup_token($1));
@@ -215,6 +221,7 @@ KeyType : TYPE_SUSER        { $$ = TYPE_SUSER; }
        | TYPE_PATH_CANNED      { $$ = TYPE_PATH_CANNED; }
        | TYPE_PATH_PASSWD      { $$ = TYPE_PATH_PASSWD; }
        | TYPE_PATH_LOCKFILE    { $$ = TYPE_PATH_LOCKFILE; }
+       | TYPE_PATH_SAVEFILEFMT { $$ = TYPE_PATH_SAVEFILEFMT; }
        ;
 
 %%
index 019322b16c285b70946ff90261fdb6a543ae2a4b..b1ad11a4d2e64d9553476517451e6bd18855a737 100644 (file)
@@ -52,7 +52,7 @@ login(1)
 Ignored; solely for compatibility with
 .B
 login(1)
-.SH CRASH RECOVERY
+.SH "CRASH RECOVERY"
 .PP
 If a user somehow disconnects in an unclean way,
 .I
@@ -69,7 +69,17 @@ nethack does not shut down within 10 seconds,
 .I
 dgamelaunch
 will ask the user for permission to send it the SIGTERM signal, which causes
-nethack to terminate quickly.
+nethack to terminate quickly (without leaving a savefile usually).
+.PP
+In some cases (e.g. at "Restoring save file...--More--") nethack doesn't leave
+a savefile if sent SIGHUP. To avoid loss of games,
+.I
+dgamelaunch
+can backup the savefile. A human must then restore the backup if necessary.
+This must be configured with the
+.B
+savefilefmt
+option in the configuration file.
 .SH AUTHORS
 .PP
 M. Drew Streib wrote the original version.
index c9c4b7b9b015121879506a56e3efa29986647bd4..c73357a0f3a999d02bb96f40866d3fe62e45269c 100644 (file)
@@ -1294,6 +1294,103 @@ writefile (int requirenew)
 /* ************************************************************* */
 /* ************************************************************* */
 
+/*
+ * Backup the savefile, if configured.
+ * Returns non-zero if successful, otherwise an error message has been
+ * given already.
+ */
+int
+backup_savefile (void)
+{
+  char buf[1024];
+  char *f, *p, *end;
+  int ispercent = 0, n;
+  int in, out;
+
+  f = myconfig->savefilefmt;
+
+  if (*f == '\0')
+    return 1;
+  if (me == NULL)
+    graceful_exit (147);
+
+  p = buf;
+  end = buf + sizeof(buf) - 10; /* make sure we can add .bak */
+  while (*f)
+    {
+      if (ispercent)
+        {
+          switch (*f)
+         {
+           case 'u':
+             snprintf (p, end + 1 - p, "%d", myconfig->shed_uid);
+             while (*p != '\0')
+               p++;
+             break;
+           case 'n':
+             snprintf (p, end + 1 - p, "%s", me->username);
+             while (*p != '\0')
+               p++;
+             break;
+           default:
+             *p = *f;
+             if (p < end)
+               p++;
+         }
+         ispercent = 0;
+       }
+      else
+        {
+         if (*f == '%')
+           ispercent = 1;
+         else
+           {
+             *p = *f;
+             if (p < end)
+               p++;
+           }
+       }
+      f++;
+    }
+  *p = '\0';
+
+  /*fprintf(stderr, "***\n[SAVEFILE=%s]\n***\n", buf);
+  sleep(3);*/
+  in = open (buf, O_RDONLY);
+  if (in == -1)
+    {
+      if (errno == ENOENT)
+        return 1; /* Nothing to back up */
+      else
+        {
+          fprintf (stderr, "Cannot open savefile '%s'\n", buf);
+         perror ("for input");
+          return 0;
+        }
+    }
+  strcpy (p, ".bak");
+  out = open (buf, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+  if (out == -1)
+    {
+      close (in);
+      fprintf (stderr, "Cannot open backup savefile '%s'\n", buf);
+      perror ("for output");
+      return 0;
+    }
+
+  while ((n = read (in, buf, sizeof(buf))) > 0)
+    {
+      n = write (out, buf, n);
+      if (n < 0)
+        break;
+    }
+  close (out);
+  close (in);
+  if (n < 0)
+    perror ("I/O error while backing up savefile");
+  return n >= 0;
+}
+
 /* TODO: Some of the messages here (sorry no nethack for you!) are nethack specific
  * as may be some code... don't think so though. Globalize it. */ 
 int
@@ -1561,6 +1658,9 @@ main (int argc, char** argv)
   endwin ();
   signal(SIGWINCH, SIG_DFL);
 
+  if (!backup_savefile ())
+    graceful_exit (5);
+
   /* environment */
   snprintf (atrcfilename, 81, "@%s", rcfilename);
 
index 09df739ee23a5a84b3d9ce6d030cae57cbbbc16f..4130f875c0d96edcc5d75af95b1c506bba7f571e 100644 (file)
@@ -49,3 +49,9 @@ rc_template = "/dgl-default-rcfile"
 
 passwd = "/dgl-login"
 lockfile = "/dgl-lock"
+
+# From inside the jail, the path to the savefile. %u is replaced by the
+# decimal representation of shed_uid, %n is replaced by the player's
+# user name. Before starting the game, this file is copied to its name
+# with ".bak" appended. Set to an empty string to disable this copying.
+savefilefmt = "/var/games/nethack/save/%u%n.gz"
index 799053142954e1a85c0b72c9fc0da2bbca1eb4ea..1c6b28218a1bd34c463d95a68b527130f43d691c 100644 (file)
@@ -57,6 +57,7 @@ struct dg_config
   uid_t shed_uid;
   gid_t shed_gid;
   unsigned long max;
+  char* savefilefmt;
 };
 
 /* Global variables */
index 95338c0cd5784addaa07260838761e34b5e87231..185a34eaf4910b7d28a1caaa774e2c33f67b93a5 100644 (file)
@@ -29,7 +29,8 @@ struct dg_config defconfig = {
   /* shed_group = */ "games",
   /* shed_uid = */ 5,
   /* shed_gid = */ 60, /* games:games in Debian */
-  /* max = */ 64000 
+  /* max = */ 64000,
+  /* savefilefmt = */ "" /* don't do this by default */
 };
 
 char* config = NULL;
@@ -237,4 +238,5 @@ create_config ()
   if (!myconfig->spool) myconfig->spool = defconfig.spool;
   if (!myconfig->passwd) myconfig->passwd = defconfig.passwd;
   if (!myconfig->lockfile) myconfig->lockfile = defconfig.lockfile;
+  if (!myconfig->savefilefmt) myconfig->savefilefmt = defconfig.savefilefmt;
 }