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