Add possibility to backup the savefile before starting nethack.

git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@282 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Jilles Tjoelker 2004-03-17 14:04:31 +00:00
parent c87eb3df1d
commit eeb6f9edaa
8 changed files with 134 additions and 4 deletions

View File

@ -1,6 +1,9 @@
1.4.5 (????/??/??) 1.4.5 (????/??/??)
* Reset offset if necessary to show at least one game to avoid things * Reset offset if necessary to show at least one game to avoid things
like "(15-14 of 14)". 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) 1.4.4 (2004/03/07)
* Show total number of games in progress below the list, useful if * Show total number of games in progress below the list, useful if

View File

@ -65,6 +65,7 @@ COMMENT ^#.*
"rc_template" { return TYPE_PATH_CANNED; } "rc_template" { return TYPE_PATH_CANNED; }
"passwd" { return TYPE_PATH_PASSWD; } "passwd" { return TYPE_PATH_PASSWD; }
"lockfile" { return TYPE_PATH_LOCKFILE; } "lockfile" { return TYPE_PATH_LOCKFILE; }
"savefilefmt" { return TYPE_PATH_SAVEFILEFMT; }
\n { line++; col = 0; } \n { line++; col = 0; }

View File

@ -28,7 +28,8 @@ static const char* lookup_token (int t);
%token TYPE_SUSER TYPE_SGROUP TYPE_SGID TYPE_SUID TYPE_MAX %token TYPE_SUSER TYPE_SGROUP TYPE_SGID TYPE_SUID TYPE_MAX
%token TYPE_PATH_NETHACK TYPE_PATH_DGLDIR TYPE_PATH_SPOOL %token TYPE_PATH_NETHACK TYPE_PATH_DGLDIR TYPE_PATH_SPOOL
%token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT %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 <s> TYPE_VALUE
%token <i> TYPE_NUMBER %token <i> TYPE_NUMBER
%type <kt> KeyType %type <kt> KeyType
@ -147,6 +148,11 @@ KeyPair: KeyType '=' TYPE_VALUE {
myconfig->passwd = strdup($3); myconfig->passwd = strdup($3);
break; break;
case TYPE_PATH_SAVEFILEFMT:
if (myconfig->savefilefmt) free(myconfig->savefilefmt);
myconfig->savefilefmt = strdup($3);
break;
default: default:
fprintf(stderr, "%s:%d: token %s does not take a string, bailing out\n", fprintf(stderr, "%s:%d: token %s does not take a string, bailing out\n",
config, line, lookup_token($1)); config, line, lookup_token($1));
@ -215,6 +221,7 @@ KeyType : TYPE_SUSER { $$ = TYPE_SUSER; }
| TYPE_PATH_CANNED { $$ = TYPE_PATH_CANNED; } | TYPE_PATH_CANNED { $$ = TYPE_PATH_CANNED; }
| TYPE_PATH_PASSWD { $$ = TYPE_PATH_PASSWD; } | TYPE_PATH_PASSWD { $$ = TYPE_PATH_PASSWD; }
| TYPE_PATH_LOCKFILE { $$ = TYPE_PATH_LOCKFILE; } | TYPE_PATH_LOCKFILE { $$ = TYPE_PATH_LOCKFILE; }
| TYPE_PATH_SAVEFILEFMT { $$ = TYPE_PATH_SAVEFILEFMT; }
; ;
%% %%

View File

@ -52,7 +52,7 @@ login(1)
Ignored; solely for compatibility with Ignored; solely for compatibility with
.B .B
login(1) login(1)
.SH CRASH RECOVERY .SH "CRASH RECOVERY"
.PP .PP
If a user somehow disconnects in an unclean way, If a user somehow disconnects in an unclean way,
.I .I
@ -69,7 +69,17 @@ nethack does not shut down within 10 seconds,
.I .I
dgamelaunch dgamelaunch
will ask the user for permission to send it the SIGTERM signal, which causes 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 .SH AUTHORS
.PP .PP
M. Drew Streib wrote the original version. M. Drew Streib wrote the original version.

View 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 /* 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. */ * as may be some code... don't think so though. Globalize it. */
int int
@ -1561,6 +1658,9 @@ main (int argc, char** argv)
endwin (); endwin ();
signal(SIGWINCH, SIG_DFL); signal(SIGWINCH, SIG_DFL);
if (!backup_savefile ())
graceful_exit (5);
/* environment */ /* environment */
snprintf (atrcfilename, 81, "@%s", rcfilename); snprintf (atrcfilename, 81, "@%s", rcfilename);

View File

@ -49,3 +49,9 @@ rc_template = "/dgl-default-rcfile"
passwd = "/dgl-login" passwd = "/dgl-login"
lockfile = "/dgl-lock" 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"

View File

@ -57,6 +57,7 @@ struct dg_config
uid_t shed_uid; uid_t shed_uid;
gid_t shed_gid; gid_t shed_gid;
unsigned long max; unsigned long max;
char* savefilefmt;
}; };
/* Global variables */ /* Global variables */

View File

@ -29,7 +29,8 @@ struct dg_config defconfig = {
/* shed_group = */ "games", /* shed_group = */ "games",
/* shed_uid = */ 5, /* shed_uid = */ 5,
/* shed_gid = */ 60, /* games:games in Debian */ /* shed_gid = */ 60, /* games:games in Debian */
/* max = */ 64000 /* max = */ 64000,
/* savefilefmt = */ "" /* don't do this by default */
}; };
char* config = NULL; char* config = NULL;
@ -237,4 +238,5 @@ create_config ()
if (!myconfig->spool) myconfig->spool = defconfig.spool; if (!myconfig->spool) myconfig->spool = defconfig.spool;
if (!myconfig->passwd) myconfig->passwd = defconfig.passwd; if (!myconfig->passwd) myconfig->passwd = defconfig.passwd;
if (!myconfig->lockfile) myconfig->lockfile = defconfig.lockfile; if (!myconfig->lockfile) myconfig->lockfile = defconfig.lockfile;
if (!myconfig->savefilefmt) myconfig->savefilefmt = defconfig.savefilefmt;
} }