diff options
author | hubertf <hubertf@NetBSD.org> | 1999-07-28 01:45:41 +0000 |
---|---|---|
committer | hubertf <hubertf@NetBSD.org> | 1999-07-28 01:45:41 +0000 |
commit | 932e74d4028472671e706b8d64965ef4a4293d0f (patch) | |
tree | 7155c281e751417d576084fd2feebae3a4e5159e /battlestar/save.c | |
parent | d0abda98e89948088de49cb3c2f192c15aa4518d (diff) | |
download | bsdgames-darwin-932e74d4028472671e706b8d64965ef4a4293d0f.tar.gz bsdgames-darwin-932e74d4028472671e706b8d64965ef4a4293d0f.tar.zst bsdgames-darwin-932e74d4028472671e706b8d64965ef4a4293d0f.zip |
This patch improves the handling of save files in battlestar(6), by
allowing the user to choose the name of the save file and specify it
on the command line when restoring. It also eliminates a buffer
overrun in determining the path to the save file, and any particular
arbitrary limit on the name length. In the name of a tidier home
directory, the default name is changed from "Bstar" to ".Bstar".
Patch supplied in PR 8085 by Joseph Myers <jsm28@cam.ac.uk>
Minor modification (s/startup/filename/ in initialize()) by me.
Diffstat (limited to 'battlestar/save.c')
-rw-r--r-- | battlestar/save.c | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/battlestar/save.c b/battlestar/save.c index fa24f407..d42793fc 100644 --- a/battlestar/save.c +++ b/battlestar/save.c @@ -1,4 +1,4 @@ -/* $NetBSD: save.c,v 1.8 1998/09/13 15:24:41 hubertf Exp $ */ +/* $NetBSD: save.c,v 1.9 1999/07/28 01:45:43 hubertf Exp $ */ /* * Copyright (c) 1983, 1993 @@ -38,27 +38,24 @@ #if 0 static char sccsid[] = "@(#)save.c 8.2 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: save.c,v 1.8 1998/09/13 15:24:41 hubertf Exp $"); +__RCSID("$NetBSD: save.c,v 1.9 1999/07/28 01:45:43 hubertf Exp $"); #endif #endif /* not lint */ #include "extern.h" void -restore() +restore(filename) + const char *filename; { - char *home; - char home1[100]; int n; int tmp; FILE *fp; - home = getenv("HOME"); - strcpy(home1, home); - strcat(home1, "/Bstar"); - if ((fp = fopen(home1, "r")) == 0) { - err(1, "fopen %s", home1); - return; + if (filename == NULL) + exit(1); /* Error determining save file name. */ + if ((fp = fopen(filename, "r")) == 0) { + err(1, "fopen %s", filename); } fread(&WEIGHT, sizeof WEIGHT, 1, fp); fread(&CUMBER, sizeof CUMBER, 1, fp); @@ -94,28 +91,27 @@ restore() fread(&loved, sizeof loved, 1, fp); fread(&pleasure, sizeof pleasure, 1, fp); fread(&power, sizeof power, 1, fp); + /* We must check the last read, to catch truncated save files */ if (fread(&ego, sizeof ego, 1, fp) < 1) - errx(1, "save file %s too short", home1); + errx(1, "save file %s too short", filename); fclose(fp); } void -save() +save(filename) + const char *filename; { - char *home; - char home1[100]; int n; int tmp; FILE *fp; - home = getenv("HOME"); - strcpy(home1, home); - strcat(home1, "/Bstar"); - if ((fp = fopen(home1, "w")) == 0) { - warn("fopen %s", home1); + if (filename == NULL) + return; /* Error determining save file name. */ + if ((fp = fopen(filename, "w")) == NULL) { + warn("fopen %s", filename); return; } - printf("Saved in %s.\n", home1); + printf("Saved in %s.\n", filename); fwrite(&WEIGHT, sizeof WEIGHT, 1, fp); fwrite(&CUMBER, sizeof CUMBER, 1, fp); fwrite(&ourclock, sizeof ourclock, 1, fp); @@ -153,6 +149,55 @@ save() fwrite(&ego, sizeof ego, 1, fp); fflush(fp); if (ferror(fp)) - warn("fwrite %s", home1); + warn("fwrite %s", filename); fclose(fp); } + +/* + * Given a save file name (possibly from fgetln, so without terminating NUL), + * determine the name of the file to be saved to by adding the HOME + * directory if the name does not contain a slash. Name will be allocated + * with malloc(3). + */ +char * +save_file_name(filename, len) + const char *filename; + size_t len; +{ + char *home; + char *newname; + size_t tmpl; + + if (memchr(filename, '/', len)) { + newname = malloc(len + 1); + if (newname == NULL) { + warnx("out of memory"); + return NULL; + } + memcpy(newname, filename, len); + newname[len] = 0; + } else { + home = getenv("HOME"); + if (home != NULL) { + tmpl = strlen(home); + newname = malloc(tmpl + len + 2); + if (newname == NULL) { + warnx("out of memory"); + return NULL; + } + memcpy(newname, home, tmpl); + newname[tmpl] = '/'; + memcpy(newname + tmpl + 1, filename, len); + newname[tmpl + len + 1] = 0; + } else { + newname = malloc(len + 1); + if (newname == NULL) { + warnx("out of memory"); + return NULL; + } + memcpy(newname, filename, len); + newname[len] = 0; + } + } + return newname; +} |