1 /* util/scores/delete.c: standalone program to delete record from scorefile
2
3 Copyright (c) 1991 James E. Wilson
4
5 This software may be copied and distributed for educational, research, and
6 not for profit purposes provided that this copyright and statement are
7 included in all such copies. */
8
9 #include <stdio.h>
10
11 #include "../../source/config.h"
12 #include "../../source/constant.h"
13 #include "../../source/types.h"
14 #include "../../source/externs.h"
15
16 #if defined(USG) || defined(VMS)
17 #ifndef L_SET
18 #define L_SET 0
19 #endif
20 #ifndef L_INCR
21 #define L_INCR 1
22 #endif
23 #endif
24
25 #undef fopen
26
27 #ifndef USG
28 /* only needed for Berkeley UNIX */
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/file.h>
32 #endif
33
34 extern race_type race[MAX_RACES];
35 extern class_type class[MAX_CLASS];
36
37 FILE *highscore_fp;
38 FILE *fileptr;
39 int8u xor_byte;
40
41 void set_fileptr();
42
main(argc,argv)43 main(argc, argv)
44 int argc;
45 char *argv[];
46 {
47 register int i, rank;
48 high_scores score;
49 int8u version_maj, version_min, patch_level;
50 int delete_number;
51
52 if (argc != 3)
53 {
54 printf ("Usage: delete scorefile index > newscore\n");
55 exit (-2);
56 }
57
58 if ((highscore_fp = fopen (argv[1], "r")) == NULL)
59 {
60 printf ("Error opening score file \"%s\"\n", MORIA_TOP);
61 exit (-1);
62 }
63
64 if ((delete_number = atoi (argv[2])) <= 0)
65 {
66 printf ("Index must be a positive number.\n");
67 printf ("Usage: delete scorefile index\n");
68 exit (-2);
69 }
70
71 #ifdef MSDOS
72 (void) setmode (fileno(highscore_fp), O_BINARY);
73 #endif
74
75 #ifndef BSD4_3
76 (void) fseek(highscore_fp, (long)0, L_SET);
77 #else
78 (void) fseek(highscore_fp, (off_t)0, L_SET);
79 #endif
80
81 /* Read version numbers from the score file, and check for validity. */
82 version_maj = getc (highscore_fp);
83 version_min = getc (highscore_fp);
84 patch_level = getc (highscore_fp);
85 /* Support score files from 5.2.2 to present. */
86 if (feof (highscore_fp))
87 {
88 printf ("The scorefile is empty.\n");
89 exit (-1);
90 }
91 else if ((version_maj != CUR_VERSION_MAJ)
92 || (version_min > CUR_VERSION_MIN)
93 || (version_min == CUR_VERSION_MIN && patch_level > PATCH_LEVEL)
94 || (version_min == 2 && patch_level < 2)
95 || (version_min < 2))
96 {
97 printf("Sorry. This scorefile is from a different version of umoria.\n");
98 exit (-1);
99 }
100
101 (void) putc (version_maj, stdout);
102 (void) putc (version_min, stdout);
103 (void) putc (patch_level, stdout);
104
105 /* set the static fileptr in save.c to the highscore file pointer */
106 set_fileptr(highscore_fp);
107
108 rank = 1;
109 rd_highscore(&score);
110 while (!feof(highscore_fp))
111 {
112 i = 1;
113 /* Put twenty scores on each page, on lines 2 through 21. */
114 while (!feof(highscore_fp) && i < 21)
115 {
116 if (rank != delete_number)
117 {
118 set_fileptr (stdout);
119 wr_highscore (&score);
120 set_fileptr (highscore_fp);
121 }
122 rank++;
123 rd_highscore(&score);
124 }
125 }
126
127 /* Success. */
128 exit (0);
129 }
130
wr_byte(c)131 static void wr_byte(c)
132 int8u c;
133 {
134 xor_byte ^= c;
135 (void) putc((int)xor_byte, fileptr);
136 }
137
wr_short(s)138 static void wr_short(s)
139 int16u s;
140 {
141 xor_byte ^= (s & 0xFF);
142 (void) putc((int)xor_byte, fileptr);
143 xor_byte ^= ((s >> 8) & 0xFF);
144 (void) putc((int)xor_byte, fileptr);
145 }
146
wr_long(l)147 static void wr_long(l)
148 register int32u l;
149 {
150 xor_byte ^= (l & 0xFF);
151 (void) putc((int)xor_byte, fileptr);
152 xor_byte ^= ((l >> 8) & 0xFF);
153 (void) putc((int)xor_byte, fileptr);
154 xor_byte ^= ((l >> 16) & 0xFF);
155 (void) putc((int)xor_byte, fileptr);
156 xor_byte ^= ((l >> 24) & 0xFF);
157 (void) putc((int)xor_byte, fileptr);
158 }
159
wr_bytes(c,count)160 static void wr_bytes(c, count)
161 int8u *c;
162 register int count;
163 {
164 register int i;
165 register int8u *ptr;
166
167 ptr = c;
168 for (i = 0; i < count; i++)
169 {
170 xor_byte ^= *ptr++;
171 (void) putc((int)xor_byte, fileptr);
172 }
173 }
174
rd_byte(ptr)175 static void rd_byte(ptr)
176 int8u *ptr;
177 {
178 int8u c;
179
180 c = getc(fileptr) & 0xFF;
181 *ptr = c ^ xor_byte;
182 xor_byte = c;
183 }
184
rd_short(ptr)185 static void rd_short(ptr)
186 int16u *ptr;
187 {
188 int8u c;
189 int16u s;
190
191 c = (getc(fileptr) & 0xFF);
192 s = c ^ xor_byte;
193 xor_byte = (getc(fileptr) & 0xFF);
194 s |= (int16u)(c ^ xor_byte) << 8;
195 *ptr = s;
196 }
197
rd_long(ptr)198 static void rd_long(ptr)
199 int32u *ptr;
200 {
201 register int32u l;
202 register int8u c;
203
204 c = (getc(fileptr) & 0xFF);
205 l = c ^ xor_byte;
206 xor_byte = (getc(fileptr) & 0xFF);
207 l |= (int32u)(c ^ xor_byte) << 8;
208 c = (getc(fileptr) & 0xFF);
209 l |= (int32u)(c ^ xor_byte) << 16;
210 xor_byte = (getc(fileptr) & 0xFF);
211 l |= (int32u)(c ^ xor_byte) << 24;
212 *ptr = l;
213 }
214
rd_bytes(ch_ptr,count)215 static void rd_bytes(ch_ptr, count)
216 int8u *ch_ptr;
217 register int count;
218 {
219 register int i;
220 register int8u *ptr;
221 register int8u c;
222
223 ptr = ch_ptr;
224 for (i = 0; i < count; i++)
225 {
226 c = (getc(fileptr) & 0xFF);
227 *ptr++ = c ^ xor_byte;
228 xor_byte = c;
229 }
230 }
231
232 /* set the local fileptr to the scorefile fileptr */
set_fileptr(file)233 void set_fileptr(file)
234 FILE *file;
235 {
236 fileptr = file;
237 }
238
wr_highscore(score)239 void wr_highscore(score)
240 high_scores *score;
241 {
242 /* Save the encryption byte for robustness. */
243 wr_byte(xor_byte);
244
245 wr_long((int32u) score->points);
246 wr_long((int32u) score->birth_date);
247 wr_short((int16u) score->uid);
248 wr_short((int16u) score->mhp);
249 wr_short((int16u) score->chp);
250 wr_byte(score->dun_level);
251 wr_byte(score->lev);
252 wr_byte(score->max_dlv);
253 wr_byte(score->sex);
254 wr_byte(score->race);
255 wr_byte(score->class);
256 wr_bytes((int8u *)score->name, PLAYER_NAME_SIZE);
257 wr_bytes((int8u *)score->died_from, 25);
258 }
259
rd_highscore(score)260 void rd_highscore(score)
261 high_scores *score;
262 {
263 /* Read the encryption byte. */
264 rd_byte (&xor_byte);
265
266 rd_long((int32u *)&score->points);
267 rd_long((int32u *)&score->birth_date);
268 rd_short((int16u *)&score->uid);
269 rd_short((int16u *)&score->mhp);
270 rd_short((int16u *)&score->chp);
271 rd_byte(&score->dun_level);
272 rd_byte(&score->lev);
273 rd_byte(&score->max_dlv);
274 rd_byte(&score->sex);
275 rd_byte(&score->race);
276 rd_byte(&score->class);
277 rd_bytes((int8u *)score->name, PLAYER_NAME_SIZE);
278 rd_bytes((int8u *)score->died_from, 25);
279 }
280