1 /* file convert.c */
2 /***************************************************************************
3 *  Copyright 2003 -   Steven Shipway <steve@cheshire.demon.co.uk>          *
4 *                     Put "nospam" in subject to avoid spam filter         *
5 *                                                                          *
6 *  This program is free software; you can redistribute it and/or modify    *
7 *  it under the terms of the GNU General Public License as published by    *
8 *  the Free Software Foundation; either version 2 of the License, or       *
9 *  (at your option) any later version.                                     *
10 *                                                                          *
11 *  This program is distributed in the hope that it will be useful,         *
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
14 *  GNU General Public License for more details.                            *
15 *                                                                          *
16 *  You should have received a copy of the GNU General Public License       *
17 *  along with this program; if not, write to the Free Software             *
18 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA               *
19 *  02111-1307, USA.                                                        *
20 ***************************************************************************/
21 
22 /*************************************************************************
23 *         Since it is not likly that anyone will have V2 files avail     *
24 *         I will not attempt to change this file unless asked.           *
25 *               - Marina Brown       marina@surferz.net (12/2002)        *
26 **************************************************************************/
27 
28 #include "wand_head.h"
29 #include <errno.h>
30 
31 /*
32     This program converts V2.* save files into V3.* save files.
33 
34     It can do this for compressed/ uncompressed files, and defaults
35     to the def in wand_head.h
36 
37     Usage:
38 
39         convert [ -v ] [ -C | -N ] [ -c | -n ] oldfile newfile
40 
41     -v:  verbose
42     -C etc : force encryption / no encryption on OLDFILE or newfile.
43 
44 */
45 
46 /**********************************************
47 *          variable declarations              *
48 ***********************************************/
49 char screen[NOOFROWS][ROWLEN+1];
50 char screen_name[ROWLEN+1];
51 char *infile, *outfile;
52 
53 struct saved_game
54 {
55     short   num;
56     long    score;
57     short   bell;
58     short   maxmoves;
59     short   num_monsters;
60 };
61 
62 struct    save_vars    zz;
63 struct  old_save_vars   yy;
64 
65 int num, bell, maxmoves;
66 long score;
67 struct mon_rec  *last_of_list, *start_of_list, *tail_of_list;
68 
69 int o_enc, n_enc;
70 int verbose;
71 
72 /************************************************
73 *                function crypt_file            *
74 *************************************************/
crypt_file(name)75 crypt_file(name)
76 char *name;
77 {
78     char buffer[1024];
79     int fd,length,loop;
80 
81     if((fd = open(name,O_RDONLY)) == -1)
82     {
83         sprintf(buffer,"Wanderer: cannot open %s",name);
84         perror(buffer);
85         exit(1);
86     }
87     if((length = read(fd,buffer,1024)) < 1) {
88         sprintf(buffer,"Wanderer: read error on %s",name);
89         perror(buffer);
90         exit(1);
91     }
92     close(fd);
93 
94     /* Right, got it in here, now to encrypt the stuff */
95 
96     srand(BLURFL);
97     for(loop=0;loop<length;loop++)
98         buffer[loop]^=rand();
99 
100     if((fd = open(name,O_WRONLY|O_TRUNC))== -1) {
101         sprintf(buffer,"Wanderer: cannot write to %s",name);
102         perror(buffer);
103         exit(1);
104     }
105     if(write(fd,buffer,length)!=length) {
106         sprintf(buffer,"Wanderer: write error on %s",name);
107         perror(buffer);
108         exit(1);
109     }
110     close(fd);
111 
112     /* ok, file now contains encrypted/decrypted game. */
113     /* lets go back home...                            */
114 }
115 
116 /*****************************************************
117 *               function make_monster                *
118 ******************************************************/
make_monster(x,y)119 struct mon_rec *make_monster(x,y)
120 int x,y;
121 {
122     char *malloc();
123 #define MALLOC (struct mon_rec *)malloc(sizeof(struct mon_rec))
124     struct mon_rec *monster;
125     if(tail_of_list->next == NULL)
126     {
127         if((last_of_list = MALLOC) == NULL)
128         return NULL;
129         tail_of_list->next = last_of_list;
130         last_of_list->prev = tail_of_list;
131         last_of_list->next = NULL;
132     }
133     monster = tail_of_list = tail_of_list->next;
134     monster->x = x;
135     monster->y = y;
136     monster->mx = 1;      /* always start moving RIGHT. (fix later)  */
137     monster->my = 0;
138     monster->under = ' ';
139     return monster;
140 }
141 
142 /*************************************************
143 *               function save_game               *
144 **************************************************/
save_game()145 void save_game()
146 {
147     char    fname[128], buf[70], *fp;
148     FILE    *fo;
149     struct    saved_game    s;
150     extern    char    *getenv();
151     struct    mon_rec    *mp;
152 
153     fp = outfile;
154 
155     if ((FILE *)NULL == (fo = fopen(outfile, W_BIN))) {
156         perror(fp);
157         exit(1);
158     }
159 
160     s.num = num;
161     s.score = score;
162     s.bell = bell;
163     s.maxmoves = maxmoves;
164     s.num_monsters = 0;
165 
166     mp = start_of_list;        /* first entry is dummy    */
167     while (mp != tail_of_list) {
168         mp = mp->next;
169         s.num_monsters++;    /* count them monsters    */
170     }
171 
172     if ( (1 != fwrite((char *)&s, sizeof(s), 1, fo)) ||
173          (1 != fwrite((char *)screen, sizeof(screen), 1, fo)) ||
174          (1 != fwrite((char *)&zz, sizeof(zz), 1, fo)) )
175     {
176         printf("Write error on '%s'\n", fname);
177         fclose(fo);
178         unlink(fname);
179         exit(1);
180     }
181 
182     mp = start_of_list;
183     while (mp != tail_of_list) {
184         /* save them monsters    */
185         mp = mp->next;
186         if (1 != fwrite((char *)mp, sizeof(struct mon_rec), 1, fo)) {
187             printf("Write error on '%s'\n", fname);
188             fclose(fo);
189             unlink(fname);
190             exit(1);
191         }
192     }
193     fwrite(screen_name,sizeof(char),strlen(screen_name),fo);
194     fclose(fo);
195     if( n_enc )
196         crypt_file(outfile,0);   /* encrpyt the saved game */
197     printf("Game saved.\n\nWanderer Copyright (C) 1988 S Shipway\n\n");
198 }
199 
200 /*******************************************************
201 *                function restore_game                 *
202 ********************************************************/
restore_game()203 void restore_game()
204 {
205     FILE    *fi;
206     struct    saved_game    s;
207     struct    mon_rec    *mp, *tmp, tmp_monst;
208     char    fname[128], *fp;
209     FILE    *fo;
210     extern    char    *getenv();
211 
212     fp = infile;
213 
214     if( o_enc )
215          crypt_file(infile,1);   /* decrypt it */
216     if ((FILE *)NULL == (fi = fopen(infile, R_BIN))) {
217         printf("Open error on '%s'\n", fp);
218         printf("Cannot restore game --- sorry.\n");
219         exit(1);
220     }
221     if ( (1 != fread((char *)&s, sizeof(s), 1, fi)) ||
222          (1 != fread((char *)screen, sizeof(screen), 1, fi)) ||
223          (1 != fread((char *)&yy, sizeof(yy), 1, fi)) ) {
224         printf("Read error on '%s'\n", fp);
225         printf("Cannot restore game --- sorry.\n");
226         fclose(fi);
227         exit(1);
228     }
229 
230     num = s.num;
231     score = s.score;
232     bell = s.bell;
233     maxmoves = s.maxmoves;
234 
235     /* free any monsters already on chain, to start clean */
236     mp = start_of_list->next;
237     while ((mp != NULL) && (mp != start_of_list)) {
238         /* free them monsters    */
239         tmp = mp;
240         mp = mp->next;
241         free(tmp);
242     }
243 
244     /* re-initialize the monster list    */
245     /* *start_of_list = {0,0,0,0,0,NULL,NULL}; */
246     start_of_list->x = 0;
247     start_of_list->y = 0;
248     start_of_list->mx = 0;
249     start_of_list->my = 0;
250     start_of_list->under = 0;
251     start_of_list->next = (struct mon_rec *)NULL;
252     start_of_list->prev = (struct mon_rec *)NULL;
253 
254     tail_of_list = start_of_list;
255 
256     while (s.num_monsters--) {
257         /* use make_monster to allocate the monster structures    */
258         /* to get all the linking right without even trying    */
259         if ((struct mon_rec *)NULL == (mp = make_monster(0, 0))) {
260             printf("Monster alloc error on '%s'\n", fp);
261             printf("Try again - it might work.\nBut then,pigs might fly...\n");
262             fclose(fi);
263             exit(1);
264         }
265         if (1 != fread((char *)&tmp_monst, sizeof(struct mon_rec), 1, fi)) {
266             printf("Monster read error on '%s'\n", fp);
267             printf("Cannot restore game --- sorry.\n");
268             fclose(fi);
269             exit(1);
270         }
271         /* copy info without trashing links    */
272         mp->x     = tmp_monst.x;
273         mp->y     = tmp_monst.y;
274         mp->mx    = tmp_monst.mx;
275         mp->my    = tmp_monst.my;
276         mp->under = tmp_monst.under;
277     }
278     fclose(fi);
279 }
280 
281 /*************************************************************
282 *         external globals - move to top  Marina             *
283 **************************************************************/
284 extern int opterr,optind;
285 extern char *optarg;
286 
287 /**************************************************************
288 *                         main program                        *
289 ***************************************************************/
main(argc,argv)290 main(argc,argv)
291 int argc;
292 char **argv;
293 {
294     char c;
295     struct mon_rec mlist;
296 
297     start_of_list = &mlist;
298 
299     verbose = 0;
300 #ifdef NO_ENCRYPTION
301     o_enc = n_enc = 0;
302 #else
303     o_enc = n_enc = 1;
304 #endif
305 
306     while( ( c = getopt(argc,argv,"CNcnv") ) != -1 )
307     switch ( c )
308     {
309         case 'C': o_enc = 1; break;
310         case 'c': n_enc = 1; break;
311         case 'N': o_enc = 0; break;
312         case 'n': n_enc = 0; break;
313         case 'v': verbose = 1; break;
314         default : printf("Usage: %s [ -v ] [ -C | -c ] [ -N | -n ] oldfile newfile\n",argv[0]);
315             printf("-v : verbose\n");
316             printf("-C : file is encrypted\n -N : file not encrypted\n");
317             printf("Upper case -- old file, lower case -- new file\n");
318             exit(1);
319     }
320 
321     if( (argc - optind) < 2 )
322     {
323         printf("Usage: %s [ -v ] [ -C | -c ] [ -N | -n ] oldfile newfile\n",argv[0]);
324         printf("-v : verbose\n");
325         printf("-C : file is encrypted\n -N : file not encrypted\n");
326         printf("Upper case -- old file, lower case -- new file\n");
327         exit(1);
328     }
329 
330 
331     infile = argv[optind++]; outfile = argv[optind];
332     if(verbose) printf("Converting %s to %s.\n",infile,outfile);
333 
334     if(verbose )
335     {
336         printf( "Reading in file %s. ", infile);
337         if( o_enc ) printf("(encrypted)");
338         printf("\n");
339     }
340 
341     restore_game();
342 
343     if( verbose ) printf("Giving screen name.\n");
344 
345     sprintf(screen_name,"------ Wanderer version %s ------",VERSION);
346 
347     if( verbose ) printf(" Copying struct variables... \n");
348 
349     zz.z_x = yy.z_x;
350     zz.z_y = yy.z_y;
351     zz.z_tx = yy.z_tx;
352     zz.z_ty = yy.z_ty;
353     zz.z_mx = yy.z_mx;
354     zz.z_my = yy.z_my;
355     zz.z_sx = yy.z_sx;
356     zz.z_sy = yy.z_sy;
357     zz.z_diamonds = yy.z_diamonds;
358     zz.z_nf = yy.z_nf;
359 
360     if(verbose)
361     {
362         printf( "Saving to file %s. ", outfile);
363         if( n_enc ) printf("(encrypted)");
364         printf("\n");
365     }
366 
367     save_game();
368 
369     printf("Done.\n");
370 }
371