Skip to content

Commit b7cdf70

Browse files
committed
fix score file format, use of whoami and fruit buffers
Corrected use of the global `whoami[]` and `fruit[]` buffers. Fixed how user id's are converted into usernames when processing the rogue score file. Fixed critical bugs in how the score file is formatted. In some cases a `SCORE` value was improperly initialized. Now, the function `init_score_value(SCORE *scp)` will properly initialize a `SCORE` value. If the rogue score file is missing, or zero length, then the `open_score()` functional will initialize it. Fixed cases where the code assumed that the score file was exactly 10 entries. Now the `NUMSCORES` value (which defaults to 10), as set in `config.h`, is used to determine the number of top scores. The global `numscores` value is initialized to `NUMSCORES`. If someone defines `NUMSCORES` to a value other than 10, the code will work. Changed the array name `top_ten` to `top_scores` to reflect the fact that someone can compile `NUMSCORES` value isn't 10. The `MAXNAME` value is now `MAX_USERNAME`. Added `MAX_OTHER_SCORE` to indicate the maximum length the score line apart from the username. The `MAXSCORELINE` value is now the sum of MAX_USERNAME` and `MAX_OTHER_SCORE`. Removed use of `NUMNAME` and instead print the number of top scores. This is because of someone defines the `NUMSCORES` value in `define.h` to a value other than 10, we don't have to try an convert the `NUMSCORES` value into a string that is the English name of that value. IMPORTANT NOTE: Due to serious flaws how the score file was formatted in older rogue versions, you make have to remove your existing score file and let the code re-initialize it. NOTE: The rogue score file is NOT portable across machines. For one thing, the user id and username stored in the score file is host dependent. For another thing, the values in the rogue score file are machine and OS dependent. NOTE: If you change the value of the `NUMSCORES` value, you will need to remove your existing rogue score file and set the rogue program re-initialize it. NOTE: If you really want to restore your rogue scores after the removal and re-initialization, the use the `scedit` tool to to restore your score scores. If the `rd_score()` function fails to properly parse the rogue score file, then code will print a ERROR indicating that rogue score file format is too old and/or has been corrupted, and suggest that you should remove the rogue score file which will allow the rogue program to properly initialize it. To determine if you need to re-initialize your rogue score file, run the command: > ./rogue -s If the above command issues the above mentioned ERROR/WARNING, and exits non-zero, then you need to remove the rogue score file and let the rogue program to re-initialize your rogue score file.
1 parent c670fe2 commit b7cdf70

File tree

11 files changed

+216
-100
lines changed

11 files changed

+216
-100
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,10 @@ This repo improves on the above mentioned repo in several important aspects:
181181
* Added extensive SPOILER section notes in the lower part of this `README.md` file
182182
* Fixed several buffer overflow bugs and memory leak conditions
183183
* Fixed bugs related to the reading and writing of the score file
184-
* Detects if the rogue score file is old and/or corrept and issues warnings along with a removal recommendation
184+
* Detects if the rogue score file is an old incompible format and/or corrept
185+
* If the rogue score file is empty or missing, the code will automatically re-initialize it
185186
* The top scores are recorded in the rogue score file, regardless of if the game was won or not
187+
* You may change the `NUMSCORES` value in `config.h` to a value other than 10
186188
* etc.
187189

188190

config.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,18 @@
204204
/* word for the number of scores to store in scoreboard */
205205
#define NUMNAME "Ten"
206206

207-
/* number of scores to store in scoreboard */
207+
/*
208+
* number of scores to store in scoreboard
209+
*
210+
* IMPORTANT NOTE: If you change NUMSCORES, then a existing rogue score file
211+
* will appear to be corrupted. If that happens, simply remove
212+
* your existing rogue score file, and run "rogue -s" to
213+
* re-initialize it.
214+
*
215+
* If you really want to restore your rogue scores after the
216+
* removal and re-initialization, the use the `scedit` tool
217+
* to restore your score scores.
218+
*/
208219
#define NUMSCORES 10
209220

210221
/* Define to the address where bug reports for this package should be sent. */

extern.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,16 @@ char file_name[MAXSTR+1] = {'\0'}; /* Save file path */
5757
char score_path[MAXSTR+1] = {'\0'}; /* score file path */
5858
char huh[MAXSTR]; /* The last message printed */
5959
const char *p_colors[MAXPOTIONS]; /* Colors of the potions */
60-
char prbuf[PFBUF_LEN+1]; /* buffer for snprintfs, +1 for paranoia */
60+
char prbuf[PFBUF_LEN+1] = {'\0'}; /* buffer for snprintfs, +1 for paranoia */
6161
const char *r_stones[MAXRINGS]; /* Stone settings of the rings */
6262
int runch; /* Direction player is running */
6363
char *s_names[MAXSCROLLS]; /* Names of the scrolls */
6464
int take; /* Thing she is taking */
65-
char whoami[MAXSTR]; /* Name of player */
65+
char whoami[MAXSTR+1] = {'\0'}; /* Name of player, +1 for paranoia */
6666
const char *ws_made[MAXSTICKS]; /* What sticks are made of */
6767
char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */
6868
int orig_dsusp; /* Original dsusp char */
69-
char fruit[MAXSTR] = /* Favorite fruit */
69+
char fruit[MAXSTR+1] = /* Favorite fruit, +1 for paranoia */
7070
{ 's', 'l', 'i', 'm', 'e', '-', 'm', 'o', 'l', 'd', '\0' };
7171
char home[MAXSTR+1] = { '\0' }; /* User's home directory */
7272
const char *inv_t_name[] = {
@@ -394,7 +394,7 @@ const struct h_list helpstr[] = {
394394
{'v', " print version number", TRUE},
395395
{0, NULL }
396396
};
397-
int numscores;
397+
int numscores = NUMSCORES;
398398
char *Numname;
399399
int allscore;
400400
int between;

extern.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ typedef unsigned int pid_t;
125125
#define PFBUF_LEN (2*MAXSTR)
126126
extern int got_ltc, in_shell;
127127
extern int wizard;
128-
extern char fruit[], prbuf[PFBUF_LEN+1], whoami[];
128+
extern char fruit[MAXSTR+1], prbuf[PFBUF_LEN+1], whoami[MAXSTR+1];
129129
extern int orig_dsusp;
130130
extern FILE *scoreboard;
131131
extern int numscores;

mach_dep.c

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
* people will be playing; otherwise the score file
2121
* gets hogged by just a few people.
2222
* NUMSCORES Number of scores in the score file (default 10).
23-
* NUMNAME String version of NUMSCORES (first character
24-
* should be capitalized) (default "Ten").
2523
* MAXLOAD What (if any) the maximum load average should be
2624
* when people are playing. Since it is divided
2725
* by 10, to specify a load limit of 4.0, MAXLOAD
@@ -48,15 +46,11 @@
4846
#include <errno.h>
4947
#include <time.h>
5048
#include <ncurses.h>
49+
#include "score.h"
5150
#include "extern.h"
5251

5352
#define NOOP(x) (x += 0)
5453

55-
# ifndef NUMSCORES
56-
# define NUMSCORES 10
57-
# define NUMNAME "Ten"
58-
# endif
59-
6054
#ifdef CHECKTIME
6155
static int num_checks = 0; /* times we've gone over in checkout() */
6256
#endif /* CHECKTIME */
@@ -91,8 +85,8 @@ init_check(void)
9185
void
9286
open_score(void)
9387
{
88+
struct stat buf; /* score file status */
9489
numscores = NUMSCORES;
95-
Numname = NUMNAME;
9690

9791
#ifdef ALLSCORES
9892
allscore = TRUE;
@@ -112,16 +106,64 @@ open_score(void)
112106

113107
scoreboard = fopen(score_path, "r+");
114108

115-
if ((scoreboard == NULL) && (errno == ENOENT))
116-
{
117-
scoreboard = fopen(score_path, "w+");
118-
md_chmod(score_path, 0664);
109+
/*
110+
* If we opened a score file, verify that the score file size is correct
111+
*
112+
* If the score file as empty, close the score file and let the next section
113+
* initialize the score file.
114+
*/
115+
if (scoreboard != NULL) {
116+
117+
/*
118+
* determine size of the opened score file
119+
*/
120+
if (fstat(fileno(scoreboard), &buf) < 0) {
121+
/* stat filed, close down and treat as if the previous open failed */
122+
fclose(scoreboard);
123+
scoreboard = NULL;
124+
125+
/*
126+
* if score file is empty
127+
*/
128+
} else if (buf.st_size == 0) {
129+
/* close score file, and let the next section initialize the score file */
130+
fclose(scoreboard);
131+
scoreboard = NULL;
132+
}
119133
}
120134

135+
/*
136+
* initialize the score file if the score file is not open
137+
*/
121138
if (scoreboard == NULL) {
122-
fprintf(stderr, "Could not open %s for writing: %s\n", score_path, strerror(errno));
123-
fflush(stderr);
139+
SCORE top_scores[NUMSCORES+1]; /* scores from the score file, +1 for paranoia */
140+
int i;
141+
142+
/*
143+
* create and truncate a writable score file
144+
*/
145+
scoreboard = fopen(score_path, "w+");
146+
if (scoreboard == NULL) {
147+
fprintf(stderr, "Could not open %s for writing: %s\n", score_path, strerror(errno));
148+
fflush(stderr);
149+
exit(1);
150+
}
151+
md_chmod(score_path, 0664);
152+
153+
/*
154+
* initialize all scores
155+
*/
156+
memset(top_scores, 0, sizeof(top_scores)); /* paranoia */
157+
for (i=0; i < NUMSCORES; ++i) {
158+
init_score_value(&top_scores[i]);
159+
}
160+
161+
/*
162+
* write the score file with initialized scores, and then rewind it
163+
*/
164+
wr_score(top_scores);
124165
}
166+
125167
}
126168

127169
/*

main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ main(int argc, char **argv)
7676
memset(score_path, 0, sizeof(score_path)); /* paranoia */
7777
snprintf(score_path, MAXSTR, "%s%s", home, SCORENAME);
7878

79+
memset(whoami, 0, sizeof(whoami)); /* paranoia */
7980
if ((env = getenv("ROGUEOPTS")) != NULL)
8081
parse_opts(env);
8182
if (env == NULL || whoami[0] == '\0')
@@ -106,6 +107,11 @@ main(int argc, char **argv)
106107
#endif
107108
seed = dnum;
108109

110+
/*
111+
* we use the random(3) facility, seeded, to generate random data for init_score()
112+
*/
113+
srandom((unsigned)seed);
114+
109115
open_score();
110116

111117
/*

mdport.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#include <sys/stat.h>
100100
#include <signal.h>
101101
#include "extern.h"
102+
#include "score.h"
102103

103104
#if !defined(PATH_MAX) && defined(_MAX_PATH)
104105
#define PATH_MAX _MAX_PATH
@@ -115,8 +116,6 @@
115116
#undef HAVE_SETRESUID
116117
#endif
117118

118-
#define MAX_USERNAME 32 /* MAX_USERNAME */
119-
120119
void
121120
md_init(void)
122121
{
@@ -627,7 +626,7 @@ directory_exists(char *dirname)
627626
char *
628627
md_getrealname(uid_t uid)
629628
{
630-
static char uidstr[MAX_USERNAME+1]; /* +1 for paranoia */
629+
static char uidstr[MAX_USERNAME+1]; /* +1 for paranoia */
631630

632631
memset(uidstr, 0, sizeof(uidstr)); /* paranoia */
633632
#if !defined(_WIN32) && !defined(DJGPP)
@@ -641,8 +640,8 @@ md_getrealname(uid_t uid)
641640
else
642641
return(pp->pw_name);
643642
#else
644-
snprintf(uidstr, MAX_USERNAME, "%ld", uid);
645-
return(uidstr);
643+
snprintf(uidstr, MAX_USERNAME, "%ld", uid);
644+
return(uidstr);
646645
#endif
647646
}
648647

0 commit comments

Comments
 (0)