saved-games menu for vms (1 of 2) (trunk only)

First cut at implementing SELECTSAVED for VMS.  Unfortunately, it only
works by default if the player is using a [probably] shared account called
"games" or "nethack", and displaying a menu of games available to restore
will likely have the side-effect of encouraging other players sharing that
account to steal each others saved games.  To use it with a normal account,
the player has to include "-ugames" or "-unethack" on the command line
(or OPTIONS=name:games in config file) to force the program to reach the
"Who are you?" stage.

     I've added a flag argument to set_savefile_name() so regularization
can be suppressed, allowing it to be used to construct a wildcarded file
specification.  I'm using that for VMS and have attempted to put in place
for WIN32CON, but the latter is not tested.

     The current WIN32CON and UNIX+QT_GRAPHICS methods of collecting save
file names is bug-prone if used on a shared playground directory.  Counting
matching file names first, then allocating memory and retraversing the
directory to copy those names into the allocated memory has a window of
vulnerability where the number of matching files could increase between the
counting and the copying.
This commit is contained in:
nethack.rankin
2006-12-10 04:46:57 +00:00
parent a00a69ba26
commit a654734476
3 changed files with 55 additions and 27 deletions

View File

@@ -696,7 +696,7 @@ E void FDECL(commit_bonesfile, (d_level *));
E int FDECL(open_bonesfile, (d_level*,char **));
E int FDECL(delete_bonesfile, (d_level*));
E void NDECL(compress_bonesfile);
E void NDECL(set_savefile_name);
E void FDECL(set_savefile_name, (BOOLEAN_P));
#ifdef INSURANCE
E void FDECL(save_savefile_name, (int));
#endif
@@ -726,6 +726,9 @@ E int FDECL(sym_val, (const char *));
#endif
E void FDECL(paniclog, (const char *, const char *));
E int FDECL(validate_prefix_locations, (char *));
#ifdef SELECTSAVED
E void FDECL(get_plname_from_file, (int, char *));
#endif
E char** NDECL(get_saved_games);
E void FDECL(free_saved_games, (char**));
#ifdef SELF_RECOVER
@@ -2437,6 +2440,9 @@ E int FDECL(vms_doshell, (const char *,BOOLEAN_P));
# ifdef SUSPEND
E int NDECL(dosuspend);
# endif
# ifdef SELECTSAVED
E int FDECL(vms_get_saved_games, (const char *,char ***));
# endif
#endif /* VMS */

View File

@@ -74,6 +74,12 @@
*/
#define DLB /* use data librarian code */
/*
* Provide menu of saved games to choose from at start.
* [Player needs to use ``nethack "-ugames"'' for this to work.]
*/
#define SELECTSAVED
/*
* You may define TEXTCOLOR if your system has any terminals that recognize
* ANSI color sequences of the form ``<ESCAPE>[#;#m'', where the first # is

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)files.c 3.5 2005/01/04 */
/* SCCS Id: @(#)files.c 3.5 2006/12/09 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -831,14 +831,12 @@ compress_bonesfile()
/* set savefile name in OS-dependent manner from pre-existing plname,
* avoiding troublesome characters */
void
set_savefile_name()
set_savefile_name(regularize_it)
boolean regularize_it;
{
#if defined(WIN32)
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
#endif
#ifdef VMS
Sprintf(SAVEF, "[.save]%d%s", getuid(), plname);
regularize(SAVEF+7);
if (regularize_it) regularize(SAVEF+7);
Strcat(SAVEF, ";1");
#else
# if defined(MICRO)
@@ -854,20 +852,27 @@ set_savefile_name()
# else
(void)strncat(SAVEF, plname, 8);
# endif
regularize(SAVEF+i);
if (regularize_it) regularize(SAVEF+i);
}
Strcat(SAVEF, SAVE_EXTENSION);
# else
# if defined(WIN32)
{
static const char okchars[] =
"*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.";
const char *legal = okchars;
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
/* Obtain the name of the logged on user and incorporate
* it into the name. */
Sprintf(fnamebuf, "%s-%s", get_username(0), plname);
(void)fname_encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.",
'%', fnamebuf, encodedfnamebuf, BUFSZ);
if (regularize_it) ++legal; /* skip '*' wildcard character */
(void)fname_encode(legal, '%', fnamebuf, encodedfnamebuf, BUFSZ);
Sprintf(SAVEF, "%s%s", encodedfnamebuf,SAVE_EXTENSION);
# else
}
# else /* not VMS or MICRO or WIN32 */
Sprintf(SAVEF, "save/%d%s", (int)getuid(), plname);
regularize(SAVEF+5); /* avoid . or / in name */
if (regularize_it) regularize(SAVEF+5); /* avoid . or / in name */
# endif /* WIN32 */
# endif /* MICRO */
#endif /* VMS */
@@ -971,7 +976,7 @@ restore_saved_game()
int fd;
reset_restpref();
set_savefile_name();
set_savefile_name(TRUE);
#ifdef MFLOPPY
if (!saveDiskPrompt(1))
return -1;
@@ -989,8 +994,7 @@ restore_saved_game()
}
#if defined(SELECTSAVED)
/*ARGSUSED*/
static char*
char *
plname_from_file(filename)
const char* filename;
{
@@ -1048,17 +1052,15 @@ char**
get_saved_games()
{
#if defined(SELECTSAVED)
int n, j;
char **result;
int n, j = 0;
char **result = 0;
# ifdef WIN32CON
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
{
char *foundfile;
const char *fq_save;
Sprintf(fnamebuf, "%s-", get_username(0));
(void)fname_encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.",
'%', fnamebuf, encodedfnamebuf, BUFSZ);
Sprintf(SAVEF, "%s*%s", encodedfnamebuf, SAVE_EXTENSION);
Strcpy(plname, "*");
set_savefile_name(FALSE);
#if defined(ZLIB_COMP)
Strcat(SAVEF, COMPRESS_EXTENSION);
#endif
@@ -1082,11 +1084,15 @@ get_saved_games()
result[j++] = r;
++n;
} while (findnext());
}
}
}
# endif
# if defined(UNIX) && defined(QT_GRAPHICS)
/* posixly correct version */
int myuid=getuid();
DIR *dir;
if((dir=opendir(fqname("save", SAVEPREFIX, 0)))) {
for(n=0; readdir(dir); n++)
;
@@ -1114,12 +1120,22 @@ get_saved_games()
}
}
closedir(dir);
# endif
qsort(result, j, sizeof(char *), strcmp_wrap);
result[j++] = 0;
return result;
}
}
# endif
# ifdef VMS
Strcpy(plname, "*");
set_savefile_name(FALSE);
j = vms_get_saved_games(SAVEF, &result);
# endif /* VMS */
if (j > 0) {
if (j > 1) qsort(result, j, sizeof (char *), strcmp_wrap);
result[j] = 0;
return result;
} else if (result) { /* could happen if save files are obsolete */
free_saved_games(result);
}
#endif /* SELECTSAVED */
return 0;
}
@@ -2962,7 +2978,7 @@ recover_savefile()
* (non-level-based) game state
* other levels
*/
set_savefile_name();
set_savefile_name(TRUE);
sfd = create_savefile();
if (sfd < 0) {
raw_printf("\nCannot recover savefile %s.\n", SAVEF);