Skip to content

Commit a32beff

Browse files
committed
improve rogue game save and restore
Clarified in `vers.c`, the purpose of the `release[]` string and the `version[]` strings. Write the `release[]` string, not the `version[]` string to the rogue save file. Changed some recently added `stderr` directed warning and error messages to `stdout` in order to match the rest of the warning and error messages. Added `fflush(stdout)` to force a flush of such warning and error messages. Detected when the rogue save file does not have a line that can be parsed. Zeroized data before restoring rogue save file into that data.
1 parent 9056dd1 commit a32beff

File tree

11 files changed

+138
-66
lines changed

11 files changed

+138
-66
lines changed

extern.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,24 @@ int tombstone = TRUE; /* Print out tombstone at end */
4545
#ifdef MASTER
4646
int wizard = FALSE; /* True if allows wizard commands */
4747
#endif
48-
int pack_used[26] = { /* Is the character used in the pack? */
48+
int pack_used[MAXPACK + 1] = { /* Is the character used in the pack? +1 for paranoia */
4949
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
5050
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
51-
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
51+
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
52+
FALSE, /* paranoia */
5253
};
5354

5455
int dir_ch; /* Direction from last get_dir() call */
55-
char home[MAXSTR+1] = {'\0'}; /* User's home directory plus a trailing /, +1 for paranoia */
56-
char file_name[2*MAXSTR+1] = {'\0'}; /* home plus / plus rogue save file path, +1 for paranoia */
57-
char lock_path[2*MAXSTR+1] = {'\0'}; /* home plus / plus rogue lock file path, +1 for paranoia */
58-
char score_path[2*MAXSTR+1] = {'\0'}; /* home plus / plus rogue score file path, +1 for paranoia */
59-
char huh[MAXSTR+1]; /* The last message printed */
60-
const char *p_colors[MAXPOTIONS]; /* Colors of the potions */
61-
char prbuf[PFBUF_LEN+1] = {'\0'}; /* buffer for snprintfs, +1 for paranoia */
62-
const char *r_stones[MAXRINGS]; /* Stone settings of the rings */
56+
char home[MAXSTR + 1] = {'\0'}; /* User's home directory plus a trailing /, +1 for paranoia */
57+
char file_name[(2*MAXSTR) + 1] = {'\0'}; /* home plus / plus rogue save file path, +1 for paranoia */
58+
char lock_path[(2*MAXSTR) + 1] = {'\0'}; /* home plus / plus rogue lock file path, +1 for paranoia */
59+
char score_path[(2*MAXSTR) + 1] = {'\0'}; /* home plus / plus rogue score file path, +1 for paranoia */
60+
char huh[MAXSTR+1]; /* The last message printed, +1 for paranoia */
61+
const char *p_colors[MAXPOTIONS + 1]; /* Colors of the potions, +1 for paranoia */
62+
char prbuf[PFBUF_LEN + 1] = {'\0'}; /* buffer for snprintfs, +1 for paranoia */
63+
const char *r_stones[MAXRINGS + 1]; /* Stone settings of the rings, +1 for paranoia */
6364
int runch; /* Direction player is running */
64-
char *s_names[MAXSCROLLS]; /* Names of the scrolls */
65+
char *s_names[MAXSCROLLS + 1]; /* Names of the scrolls, +1 for paranoia */
6566
int take; /* Thing she is taking */
6667
const char *ws_made[MAXSTICKS]; /* What sticks are made of */
6768
char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */
@@ -150,7 +151,7 @@ coord delta; /* Change indicated to get_dir() */
150151
coord oldpos; /* Position before last look() call */
151152
coord stairs; /* Location of staircase */
152153

153-
PLACE places[MAXLINES*MAXCOLS]; /* level map */
154+
PLACE places[(MAXLINES*MAXCOLS) + 1]; /* level map, +1 for paranoia */
154155

155156
THING *cur_armor; /* What he is wearing */
156157
THING *cur_ring[2]; /* Which rings are being worn */
@@ -169,8 +170,8 @@ WINDOW *hw = NULL; /* used as a scratch window */
169170
struct stats max_stats = INIT_STATS; /* The maximum for the player */
170171

171172
struct room *oldrp; /* Roomin(&oldpos) */
172-
struct room rooms[MAXROOMS]; /* One for each room -- A level */
173-
struct room passages[MAXPASS] = /* One for each passage */
173+
struct room rooms[MAXROOMS + 1]; /* One for each room -- A level, +1 for paranoia */
174+
struct room passages[MAXPASS + 1] = /* One for each passage, +1 for paranoia */
174175
{
175176
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
176177
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
@@ -184,12 +185,13 @@ struct room passages[MAXPASS] = /* One for each passage */
184185
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
185186
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
186187
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
187-
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} }
188+
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
189+
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} } /* paranoia */
188190
};
189191

190192
#define ___ 1
191193
#define XX 10
192-
struct monster monsters[26] =
194+
struct monster monsters[26 + 1] =
193195
{
194196
/* Name CARRY FLAG str, exp, lvl, amr, hpt, dmg */
195197
{ "aquator", 0, ISMEAN, { XX, 20, 5, 2, ___, "0x0/0x0" } },
@@ -219,22 +221,24 @@ struct monster monsters[26] =
219221
{ "wraith", 0, 0, { XX, 55, 5, 4, ___, "1x6" } },
220222
{ "xeroc", 30, 0, { XX,100, 7, 7, ___, "4x4" } },
221223
{ "yeti", 30, 0, { XX, 50, 4, 6, ___, "1x6/1x6" } },
222-
{ "zombie", 0, ISMEAN, { XX, 6, 2, 8, ___, "1x8" } }
224+
{ "zombie", 0, ISMEAN, { XX, 6, 2, 8, ___, "1x8" } },
225+
{ "", 0, 0, { 0, 0, 0, 0, 0, "" } }, /* paranoia */
223226
};
224227
#undef ___
225228
#undef XX
226229

227-
struct obj_info things[NUMTHINGS] = {
230+
struct obj_info things[NUMTHINGS + 1] = {
228231
{ 0, 26 }, /* potion */
229232
{ 0, 36 }, /* scroll */
230233
{ 0, 16 }, /* food */
231234
{ 0, 7 }, /* weapon */
232235
{ 0, 7 }, /* armor */
233236
{ 0, 4 }, /* ring */
234237
{ 0, 4 }, /* stick */
238+
{ 0, 0 }, /* paranoia */
235239
};
236240

237-
struct obj_info arm_info[MAXARMORS] = {
241+
struct obj_info arm_info[MAXARMORS + 1] = {
238242
{ "leather armor", 20, 20, NULL, FALSE },
239243
{ "ring mail", 15, 25, NULL, FALSE },
240244
{ "studded leather armor", 15, 20, NULL, FALSE },
@@ -243,8 +247,9 @@ struct obj_info arm_info[MAXARMORS] = {
243247
{ "splint mail", 10, 80, NULL, FALSE },
244248
{ "banded mail", 10, 90, NULL, FALSE },
245249
{ "plate mail", 5, 150, NULL, FALSE },
250+
{ NULL, 0, 0, NULL, FALSE }, /* paranoia */
246251
};
247-
struct obj_info pot_info[MAXPOTIONS] = {
252+
struct obj_info pot_info[MAXPOTIONS + 1] = {
248253
{ "confusion", 7, 5, NULL, FALSE },
249254
{ "hallucination", 8, 5, NULL, FALSE },
250255
{ "poison", 8, 5, NULL, FALSE },
@@ -259,8 +264,9 @@ struct obj_info pot_info[MAXPOTIONS] = {
259264
{ "restore strength", 13, 130, NULL, FALSE },
260265
{ "blindness", 5, 5, NULL, FALSE },
261266
{ "levitation", 6, 75, NULL, FALSE },
267+
{ NULL, 0, 0, NULL, FALSE }, /* paranoia */
262268
};
263-
struct obj_info ring_info[MAXRINGS] = {
269+
struct obj_info ring_info[MAXRINGS + 1] = {
264270
{ "protection", 9, 400, NULL, FALSE },
265271
{ "add strength", 9, 400, NULL, FALSE },
266272
{ "sustain strength", 5, 280, NULL, FALSE },
@@ -275,8 +281,9 @@ struct obj_info ring_info[MAXRINGS] = {
275281
{ "teleportation", 5, 30, NULL, FALSE },
276282
{ "stealth", 7, 470, NULL, FALSE },
277283
{ "maintain armor", 5, 380, NULL, FALSE },
284+
{ NULL, 0, 0, NULL, FALSE }, /* paranoia */
278285
};
279-
struct obj_info scr_info[MAXSCROLLS] = {
286+
struct obj_info scr_info[MAXSCROLLS + 1] = {
280287
{ "monster confusion", 7, 140, NULL, FALSE },
281288
{ "magic mapping", 4, 150, NULL, FALSE },
282289
{ "hold monster", 2, 180, NULL, FALSE },
@@ -295,8 +302,9 @@ struct obj_info scr_info[MAXSCROLLS] = {
295302
{ "remove curse", 7, 105, NULL, FALSE },
296303
{ "aggravate monsters", 3, 20, NULL, FALSE },
297304
{ "protect armor", 2, 250, NULL, FALSE },
305+
{ NULL, 0, 0, NULL, FALSE }, /* paranoia */
298306
};
299-
struct obj_info weap_info[MAXWEAPONS + 1] = {
307+
struct obj_info weap_info[MAXWEAPONS + 1 + 1] = {
300308
{ "mace", 11, 8, NULL, FALSE },
301309
{ "long sword", 11, 15, NULL, FALSE },
302310
{ "short bow", 12, 15, NULL, FALSE },
@@ -307,8 +315,9 @@ struct obj_info weap_info[MAXWEAPONS + 1] = {
307315
{ "shuriken", 12, 5, NULL, FALSE },
308316
{ "spear", 12, 5, NULL, FALSE },
309317
{ NULL, 0 }, /* DO NOT REMOVE: fake entry for dragon's breath */
318+
{ NULL, 0, 0, NULL, FALSE }, /* paranoia */
310319
};
311-
struct obj_info ws_info[MAXSTICKS] = {
320+
struct obj_info ws_info[MAXSTICKS + 1] = {
312321
{ "light", 12, 250, NULL, FALSE },
313322
{ "invisibility", 6, 5, NULL, FALSE },
314323
{ "lightning", 3, 330, NULL, FALSE },
@@ -323,6 +332,7 @@ struct obj_info ws_info[MAXSTICKS] = {
323332
{ "teleport away", 6, 340, NULL, FALSE },
324333
{ "teleport to", 6, 50, NULL, FALSE },
325334
{ "cancellation", 5, 280, NULL, FALSE },
335+
{ NULL, 0, 0, NULL, FALSE }, /* paranoia */
326336
};
327337

328338
const struct h_list helpstr[] = {

extern.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ typedef unsigned int pid_t;
131131
#define PFBUF_LEN (2*MAXSTR)
132132
extern int got_ltc, in_shell;
133133
extern int wizard;
134-
extern char fruit[MAXSTR+1], prbuf[PFBUF_LEN+1];
134+
extern char fruit[MAXSTR+1]; /* +1 for paranoia */
135+
extern char prbuf[PFBUF_LEN+1]; /* +1 for paranoia */
135136
extern int orig_dsusp;
136137
extern FILE *scoreboard;
137138
extern int numscores;

findpw.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
extern char *xcrypt(const char *, const char *);
2020

21-
char whoami[MAX_USERNAME] = {'\0'}; /* Name of player */
21+
char whoami[MAX_USERNAME+1] = {'\0'}; /* Name of player, +1 for paranoia */
2222

2323
int
2424
main(int argc, char *argv[])
@@ -30,5 +30,6 @@ main(int argc, char *argv[])
3030
(void) fgets(buf, MAX_PW_LEN+1, stdin);
3131
buf[strlen(buf) - 1] = '\0';
3232
printf("%s\n", xcrypt(buf, "mT"));
33+
fflush(stdout);
3334
return 0;
3435
}

init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ badcheck(const char *name, const struct obj_info *info, int bound)
428428

429429
if (info[bound - 1].oi_prob == 100)
430430
return;
431-
printf("\nBad percentages for %s (bound = %d):\n", name, bound);
431+
printf("Bad percentages for %s (bound = %d):\n", name, bound);
432432
for (end = &info[bound]; info < end; info++)
433433
printf("%3d%% %s\n", info->oi_prob, info->oi_name);
434434
printf("[hit RETURN to continue]");

mach_dep.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,13 @@ init_check(void)
7474
printf("Sorry, %s, but the system is too loaded now.\n", whoami);
7575
printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
7676
vowelstr(fruit), fruit);
77-
if (author())
77+
fflush(stdout);
78+
if (author()) {
7879
printf("However, since you're a good guy, it's up to you\n");
79-
else
80+
fflush(stdout);
81+
} else {
8082
exit(1);
83+
}
8184
}
8285
#endif
8386
}
@@ -149,8 +152,8 @@ open_score(void)
149152
*/
150153
scoreboard = fopen(score_path, "w+");
151154
if (scoreboard == NULL) {
152-
fprintf(stderr, "Could not open %s for writing: %s\n", score_path, strerror(errno));
153-
fflush(stderr);
155+
printf("Could not open %s for writing: %s\n", score_path, strerror(errno));
156+
fflush(stdout);
154157
exit(1);
155158
}
156159
md_chmod(score_path, 0664);
@@ -433,7 +436,8 @@ lock_sc(void)
433436
lock_fd = open(lock_path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); /* more 0644 */
434437
if (lock_fd < 0) {
435438
/* failed to open and/or create the lock file */
436-
fprintf(stderr, "\nERROR: failed to open lock file: %s\n", lock_path);
439+
printf("ERROR: failed to open lock file: %s\n", lock_path);
440+
fflush(stdout);
437441
return FALSE;
438442
}
439443
}
@@ -444,7 +448,8 @@ lock_sc(void)
444448
ret = flock(lock_fd, LOCK_EX);
445449
if (ret < 0) {
446450
/* failed to lock */
447-
fprintf(stderr, "\nERROR: failed to lock: %s\n", lock_path);
451+
printf("ERROR: failed to lock: %s\n", lock_path);
452+
fflush(stdout);
448453
return FALSE;
449454
}
450455

@@ -486,7 +491,8 @@ unlock_sc(void)
486491
ret = flock(lock_fd, LOCK_UN);
487492
if (ret < 0) {
488493
/* failed to lock */
489-
fprintf(stderr, "\nERROR: failed to unlock: %s\n", lock_path);
494+
printf("ERROR: failed to unlock: %s\n", lock_path);
495+
fflush(stdout);
490496
return;
491497
}
492498

main.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "rogue.h"
1818
#include "score.h"
1919

20-
char whoami[MAX_USERNAME] = {'\0'}; /* Name of player */
20+
char whoami[MAX_USERNAME+1] = {'\0'}; /* Name of player, +1 for paranoia */
2121

2222
/*
2323
* main:
@@ -143,14 +143,18 @@ main(int argc, char **argv)
143143
else if (strcmp(argv[1], "-V") == 0)
144144
{
145145
printf("version %s (chongo was here) %s\n", release, version);
146+
fflush(stdout);
146147
exit(0);
147148
}
148149
}
149150

150151
init_check(); /* check for legal startup */
151152
if (argc == 2)
152-
if (!restore(argv[1])) /* Note: restore will never return */
153-
my_exit(1);
153+
/* if restore works, it will never return */
154+
if (!restore(argv[1])) {
155+
fflush(stdout);
156+
exit(1);
157+
}
154158
#ifdef MASTER
155159
if (wizard)
156160
printf("Hello %s, welcome to dungeon #%u", whoami, dnum);
@@ -183,7 +187,8 @@ main(int argc, char **argv)
183187
memset (pidfilename, '\0', sizeof(pidfilename));
184188
snprintf (pidfilename, BUFSIZ-1, "roguepid.%d", pid);
185189
if ((pidfp = fopen (pidfilename, "w")) == NULL) {
186-
fprintf (stderr, "Can't open '%s'.\n", pidfilename);
190+
printf("Can't open '%s'.\n", pidfilename);
191+
fflush(stdout);
187192
exit(1);
188193
}
189194
}
@@ -202,8 +207,9 @@ main(int argc, char **argv)
202207
*/
203208
if (LINES < NUMLINES || COLS < NUMCOLS)
204209
{
205-
printf("\nSorry, the screen must be at least %dx%d\n", NUMLINES, NUMCOLS);
206210
endwin();
211+
printf("Sorry, the screen must be at least %dx%d\n", NUMLINES, NUMCOLS);
212+
fflush(stdout);
207213
my_exit(1);
208214
}
209215

rip.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ score(int amount, int flags, int monst)
129129
refresh();
130130
wgetnstr(stdscr,prbuf,80);
131131
endwin();
132-
printf("\n");
132+
putchar('\n');
133133
resetltchars();
134134
/*
135135
* free up space to "guarantee" there is space for the top_scores
@@ -222,6 +222,7 @@ score(int amount, int flags, int monst)
222222
putchar('\n');
223223
printf("Top %d %s:\n", NUMSCORES, allscore ? "Scores" : "Rogueists");
224224
printf(" Score Name\n");
225+
fflush(stdout);
225226
for (scp = top_scores; scp < endp; scp++)
226227
{
227228
if (scp->sc_score > 0) {
@@ -232,14 +233,15 @@ score(int amount, int flags, int monst)
232233
reason[scp->sc_flags], scp->sc_level);
233234
if (scp->sc_flags == 0 || scp->sc_flags == 3)
234235
printf(" by %s", killname(scp->sc_monster, TRUE));
236+
fflush(stdout);
235237
#ifdef MASTER
236238
if (prflags == 1)
237239
{
238240
printf(" (%s)", md_getrealname(scp->sc_uid));
239241
}
240242
else if (prflags == 2)
241243
{
242-
fflush(stdout);
244+
memset(prbuf, 0, sizeof(prbuf));
243245
(void) fgets(prbuf,10,stdin);
244246
if (prbuf[0] == 'd')
245247
{
@@ -253,13 +255,18 @@ score(int amount, int flags, int monst)
253255
else
254256
#endif /* MASTER */
255257
printf(".");
258+
fflush(stdout);
256259
if (sc2 == scp)
257260
md_raw_standend();
258261
putchar('\n');
259262
}
260263
else
264+
{
261265
break;
266+
}
267+
fflush(stdout);
262268
}
269+
263270
/*
264271
* Update the list file
265272
*/

0 commit comments

Comments
 (0)