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
+7 -1
View File
@@ -696,7 +696,7 @@ E void FDECL(commit_bonesfile, (d_level *));
E int FDECL(open_bonesfile, (d_level*,char **)); E int FDECL(open_bonesfile, (d_level*,char **));
E int FDECL(delete_bonesfile, (d_level*)); E int FDECL(delete_bonesfile, (d_level*));
E void NDECL(compress_bonesfile); E void NDECL(compress_bonesfile);
E void NDECL(set_savefile_name); E void FDECL(set_savefile_name, (BOOLEAN_P));
#ifdef INSURANCE #ifdef INSURANCE
E void FDECL(save_savefile_name, (int)); E void FDECL(save_savefile_name, (int));
#endif #endif
@@ -726,6 +726,9 @@ E int FDECL(sym_val, (const char *));
#endif #endif
E void FDECL(paniclog, (const char *, const char *)); E void FDECL(paniclog, (const char *, const char *));
E int FDECL(validate_prefix_locations, (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 char** NDECL(get_saved_games);
E void FDECL(free_saved_games, (char**)); E void FDECL(free_saved_games, (char**));
#ifdef SELF_RECOVER #ifdef SELF_RECOVER
@@ -2437,6 +2440,9 @@ E int FDECL(vms_doshell, (const char *,BOOLEAN_P));
# ifdef SUSPEND # ifdef SUSPEND
E int NDECL(dosuspend); E int NDECL(dosuspend);
# endif # endif
# ifdef SELECTSAVED
E int FDECL(vms_get_saved_games, (const char *,char ***));
# endif
#endif /* VMS */ #endif /* VMS */
+6
View File
@@ -74,6 +74,12 @@
*/ */
#define DLB /* use data librarian code */ #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 * You may define TEXTCOLOR if your system has any terminals that recognize
* ANSI color sequences of the form ``<ESCAPE>[#;#m'', where the first # is * ANSI color sequences of the form ``<ESCAPE>[#;#m'', where the first # is
+42 -26
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. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* 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, /* set savefile name in OS-dependent manner from pre-existing plname,
* avoiding troublesome characters */ * avoiding troublesome characters */
void void
set_savefile_name() set_savefile_name(regularize_it)
boolean regularize_it;
{ {
#if defined(WIN32)
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
#endif
#ifdef VMS #ifdef VMS
Sprintf(SAVEF, "[.save]%d%s", getuid(), plname); Sprintf(SAVEF, "[.save]%d%s", getuid(), plname);
regularize(SAVEF+7); if (regularize_it) regularize(SAVEF+7);
Strcat(SAVEF, ";1"); Strcat(SAVEF, ";1");
#else #else
# if defined(MICRO) # if defined(MICRO)
@@ -854,20 +852,27 @@ set_savefile_name()
# else # else
(void)strncat(SAVEF, plname, 8); (void)strncat(SAVEF, plname, 8);
# endif # endif
regularize(SAVEF+i); if (regularize_it) regularize(SAVEF+i);
} }
Strcat(SAVEF, SAVE_EXTENSION); Strcat(SAVEF, SAVE_EXTENSION);
# else # else
# if defined(WIN32) # 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 /* Obtain the name of the logged on user and incorporate
* it into the name. */ * it into the name. */
Sprintf(fnamebuf, "%s-%s", get_username(0), plname); Sprintf(fnamebuf, "%s-%s", get_username(0), plname);
(void)fname_encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", if (regularize_it) ++legal; /* skip '*' wildcard character */
'%', fnamebuf, encodedfnamebuf, BUFSZ); (void)fname_encode(legal, '%', fnamebuf, encodedfnamebuf, BUFSZ);
Sprintf(SAVEF, "%s%s", encodedfnamebuf,SAVE_EXTENSION); Sprintf(SAVEF, "%s%s", encodedfnamebuf,SAVE_EXTENSION);
# else }
# else /* not VMS or MICRO or WIN32 */
Sprintf(SAVEF, "save/%d%s", (int)getuid(), plname); 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 /* WIN32 */
# endif /* MICRO */ # endif /* MICRO */
#endif /* VMS */ #endif /* VMS */
@@ -971,7 +976,7 @@ restore_saved_game()
int fd; int fd;
reset_restpref(); reset_restpref();
set_savefile_name(); set_savefile_name(TRUE);
#ifdef MFLOPPY #ifdef MFLOPPY
if (!saveDiskPrompt(1)) if (!saveDiskPrompt(1))
return -1; return -1;
@@ -989,8 +994,7 @@ restore_saved_game()
} }
#if defined(SELECTSAVED) #if defined(SELECTSAVED)
/*ARGSUSED*/ char *
static char*
plname_from_file(filename) plname_from_file(filename)
const char* filename; const char* filename;
{ {
@@ -1048,17 +1052,15 @@ char**
get_saved_games() get_saved_games()
{ {
#if defined(SELECTSAVED) #if defined(SELECTSAVED)
int n, j; int n, j = 0;
char **result; char **result = 0;
# ifdef WIN32CON # ifdef WIN32CON
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ]; {
char *foundfile; char *foundfile;
const char *fq_save; const char *fq_save;
Sprintf(fnamebuf, "%s-", get_username(0)); Strcpy(plname, "*");
(void)fname_encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", set_savefile_name(FALSE);
'%', fnamebuf, encodedfnamebuf, BUFSZ);
Sprintf(SAVEF, "%s*%s", encodedfnamebuf, SAVE_EXTENSION);
#if defined(ZLIB_COMP) #if defined(ZLIB_COMP)
Strcat(SAVEF, COMPRESS_EXTENSION); Strcat(SAVEF, COMPRESS_EXTENSION);
#endif #endif
@@ -1082,11 +1084,15 @@ get_saved_games()
result[j++] = r; result[j++] = r;
++n; ++n;
} while (findnext()); } while (findnext());
}
}
}
# endif # endif
# if defined(UNIX) && defined(QT_GRAPHICS) # if defined(UNIX) && defined(QT_GRAPHICS)
/* posixly correct version */ /* posixly correct version */
int myuid=getuid(); int myuid=getuid();
DIR *dir; DIR *dir;
if((dir=opendir(fqname("save", SAVEPREFIX, 0)))) { if((dir=opendir(fqname("save", SAVEPREFIX, 0)))) {
for(n=0; readdir(dir); n++) for(n=0; readdir(dir); n++)
; ;
@@ -1114,12 +1120,22 @@ get_saved_games()
} }
} }
closedir(dir); 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 */ #endif /* SELECTSAVED */
return 0; return 0;
} }
@@ -2962,7 +2978,7 @@ recover_savefile()
* (non-level-based) game state * (non-level-based) game state
* other levels * other levels
*/ */
set_savefile_name(); set_savefile_name(TRUE);
sfd = create_savefile(); sfd = create_savefile();
if (sfd < 0) { if (sfd < 0) {
raw_printf("\nCannot recover savefile %s.\n", SAVEF); raw_printf("\nCannot recover savefile %s.\n", SAVEF);