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:
parent
c87eb3df1d
commit
eeb6f9edaa
|
@ -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
|
||||||
|
|
1
config.l
1
config.l
|
@ -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; }
|
||||||
|
|
||||||
|
|
9
config.y
9
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_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; }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -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.
|
||||||
|
|
100
dgamelaunch.c
100
dgamelaunch.c
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue