]> icculus.org git repositories - taylor/freespace2.git/blob - src/scramble/scramble.cpp
deal with static analyzer warnings
[taylor/freespace2.git] / src / scramble / scramble.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/scramble/scramble.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Module for file scrambler
16  *
17  * $Log$
18  * Revision 1.3  2003/01/30 20:05:01  relnev
19  * ported (Taylor Richards)
20  *
21  * Revision 1.2  2002/06/09 04:41:25  relnev
22  * added copyright header
23  *
24  * Revision 1.1.1.1  2002/05/03 03:28:10  root
25  * Initial import.
26  *
27  * 
28  * 3     3/25/99 11:26a Dave
29  * Beefed up encryption scheme so that even someone viewing the
30  * disassembly would have a hard time cracking it.
31  * 
32  * 2     10/24/98 11:41p Dave
33  * 
34  * 1     10/24/98 11:31p Dave
35  * 
36  * 7     8/09/98 4:44p Lawrance
37  * support alternate encryption scheme (doesn't pack chars into 7 bits)
38  * 
39  * 6     4/14/98 4:14p Lawrance
40  * fix bug with ships and weapons tbl preprocessing
41  * 
42  * 5     4/14/98 1:39p Lawrance
43  * Add command line switches to preprocess ship and weapon tables
44  * 
45  * 4     3/31/98 1:14a Lawrance
46  * Get .tbl and mission file encryption working.
47  * 
48  * 3     3/30/98 5:57p Lawrance
49  * add some comments
50  * 
51  * 2     3/30/98 5:51p Lawrance
52  * file encryption and decryption
53  *
54  * $NoKeywords: $
55  *
56 */
57
58 #include <stdlib.h>
59 #include <stdio.h>
60 #ifndef PLAT_UNIX
61 #include <io.h>
62 #else
63 #include <sys/stat.h>
64 #endif
65 #include <string.h>
66
67 #define SDL_MAIN_HANDLED
68
69 #include "pstypes.h"
70 #include "encrypt.h"
71 #include "scramble.h"
72
73 #undef malloc
74 #undef free
75 #undef strdup
76
77 #ifndef PLAT_UNIX
78 #define strncasecmp strnicmp
79 #define strcasecmp stricmp
80 #else
81 int _filelength (int fd)
82 {
83         struct stat buf;
84         if (fstat (fd, &buf) == -1)
85                 return -1;
86
87         return buf.st_size;
88 }
89 #endif
90
91 #define MAX_LINE_LEN    512
92
93 //static int Use_8bit = 0;      // set to 1 to disable 7bit character packing
94 static int Use_8bit = 1;
95
96
97 // strip out any ships tbl data not used in demo (ie entries without @ preceding name)
98 void scramble_read_ships_tbl(char **text, int *text_len, FILE *fp)
99 {
100         char    line[MAX_LINE_LEN+1];
101         char    token_line[MAX_LINE_LEN+1];
102         char    *dest;
103         int     line_len, discard_line = 1, keep_all_lines = 0, post_discard = 0;
104         char    seps[]   = " ,\t\n";
105         char    *token;
106
107         *text_len = _filelength(fileno(fp));
108
109         if (*text_len <= 0)
110                 return;
111
112         *text = (char*)malloc(*text_len+1);
113
114         dest = *text;
115
116         while ( fgets(line, MAX_LINE_LEN, fp) != NULL ) {
117
118                 line_len = strlen(line);
119                 memcpy(token_line, line, line_len+1);
120
121                 if ( !keep_all_lines ) {
122                         token = strtok( token_line, seps );
123
124                         if ( token ) {
125                                 if ( !strncasecmp("#End", token, 4) ) {
126                                         keep_all_lines = 1;
127                                 } else if ( !strncasecmp("#Ship", token, 5) ) {
128                                         discard_line = 0;
129                                         post_discard = 1;
130                                 } else if ( !strncasecmp("$Name:", token, 6) ) {
131                                         token = strtok( NULL, seps );
132                                         if ( token ) {
133                                                 if ( token[0] == '@' ) {
134                                                         discard_line = 0;
135                                                 } else {
136                                                         discard_line = 1;
137                                                 }
138                                         }
139                                 }
140                         }
141                 }
142
143                 if ( !discard_line || keep_all_lines ) {
144                         memcpy(dest, line, line_len);
145                         dest += line_len;
146                 }
147
148                 if ( post_discard ) {
149                         discard_line = 1;
150                         post_discard = 0;
151                 } 
152         }
153
154         *text_len = dest - *text;
155 }
156
157 // strip out any weapons tbl data not used in demo (ie entries without @ preceding name)
158 void scramble_read_weapons_tbl(char **text, int *text_len, FILE *fp)
159 {
160         char    line[MAX_LINE_LEN+1];
161         char    token_line[MAX_LINE_LEN+1];
162         char    *dest;
163         int     line_len, discard_line = 1, keep_all_lines = 0, post_discard = 0;
164         char    seps[]   = " ,\t\n";
165         char    *token = NULL;
166
167         *text_len = _filelength(fileno(fp));
168         *text = (char*)malloc(*text_len+1);
169
170         dest = *text;
171
172         while ( fgets(line, MAX_LINE_LEN, fp) != NULL ) {
173
174                 line_len = strlen(line);
175                 memcpy(token_line, line, line_len+1);
176
177                 if ( !keep_all_lines ) {
178                         token = strtok( token_line, seps );
179
180                         if ( token ) {
181                                 if ( !strncasecmp("#Countermeasures", token, 16) ) {
182                                         keep_all_lines = 1;
183                                 } else if ( !strncasecmp("#End", token, 4) || !strncasecmp("#Beam", token, 5) || !strncasecmp("#Primary", token, 8) || !strncasecmp("#Secondary", token, 10) ) {
184                                         discard_line = 0;
185                                         post_discard = 1;
186                                 } else if ( !strncasecmp("$Name:", token, 6) ) {
187                                         discard_line = 1;
188                                         token = strtok( NULL, seps );
189                                         if ( token ) {
190                                                 if ( token[0] == '@' ) {
191                                                         discard_line = 0;
192                                                 }
193                                         }
194                                 }
195                         }
196                 }
197
198                 if ( token && (token[0] != ';') && (!discard_line || keep_all_lines) ) {
199                         memcpy(dest, line, line_len);
200                         dest += line_len;
201                 }
202
203                 if ( post_discard ) {
204                         discard_line = 1;
205                         post_discard = 0;
206                 } 
207         }
208
209         *text_len = dest - *text;
210 }
211
212 void scramble_read_default(char **text, int *text_len, FILE *fp)
213 {
214         *text_len = _filelength(fileno(fp));
215
216         if (*text_len <= 0)
217                 return;
218
219         *text = (char*)malloc(*text_len+1);
220
221         if ( !fread(*text, *text_len, 1, fp) ) {
222                 free(*text);
223                 *text = NULL;
224                 *text_len = 0;
225         }
226 }
227
228 // scramble a file
229 //
230 // input:       src_filename    =>      filename of text to scramble
231 //                              dest_filename   =>      optional, this is the filename scrambled data will get stored to
232 void scramble_file(char *src_filename, char *dest_filename, int preprocess)
233 {
234         FILE    *fp;
235         int     text_len, scramble_len;
236         char    *text, *scramble_text;
237
238         fp = fopen(src_filename, "rb");
239         if ( !fp ) {
240                 return;
241         }
242
243         // read in data, maybe preprocess
244         switch(preprocess) {
245         case PREPROCESS_SHIPS_TBL:
246                 scramble_read_ships_tbl(&text, &text_len, fp);
247                 break;
248         case PREPROCESS_WEAPONS_TBL:
249                 scramble_read_weapons_tbl(&text, &text_len, fp);
250                 break;
251         default:
252                 // read in the raw data
253                 scramble_read_default(&text, &text_len, fp);
254                 break;
255         }
256
257         fclose(fp);
258
259         if (text == NULL) {
260                 return;
261         }
262
263         // open up file for writing scrambled text
264         if ( dest_filename ) {
265                 fp = fopen(dest_filename, "wb");
266         } else {
267                 fp = fopen(src_filename, "wb");
268         }
269
270         if ( !fp ) {
271                 free(text);
272                 return;
273         }
274
275         scramble_text = (char*)malloc(text_len+32);
276
277         encrypt(text, text_len, scramble_text, &scramble_len, Use_8bit);
278         
279         // write out scrambled data
280         fwrite( scramble_text, scramble_len, 1, fp );
281
282         free(text);
283         free(scramble_text);
284         fclose(fp);
285 }
286
287 // unscramble a file
288 //
289 // input:       src_filename    =>      filename of scrambled text
290 //                              dest_filename   =>      optional, this is the filename unscrambled text data will get stored to
291 void unscramble_file(char *src_filename, char *dest_filename)
292 {
293         FILE    *fp;
294         int     scramble_len, text_len;
295         char    *text, *scramble_text;
296
297         fp = fopen(src_filename, "rb");
298         if ( !fp ) {
299                 return;
300         }
301
302         // read in the scrambled data
303         scramble_len = _filelength(fileno(fp));
304
305         if (scramble_len <= 0) {
306                 fclose(fp);
307                 return;
308         }
309
310         scramble_text = (char*)malloc(scramble_len+1);
311
312         if ( !fread(scramble_text, scramble_len, 1, fp) ) {
313                 fclose(fp);
314                 free(scramble_text);
315                 return;
316         }
317
318         fclose(fp);
319
320         // open up file for writing unscrambled text
321         if ( dest_filename ) {
322                 fp = fopen(dest_filename, "wb");
323         } else {
324                 fp = fopen(src_filename, "wb");
325         }
326         if ( !fp ) {
327                 return;
328         }
329
330         // assume original text no larger than double scrambled size
331         text = (char*)malloc(scramble_len*2);
332
333         unencrypt(scramble_text, scramble_len, text, &text_len);
334
335         // write out unscrambled data
336         fwrite( text, text_len, 1, fp );
337
338         free(text);
339         free(scramble_text);
340         fclose(fp);
341 }
342
343 void print_instructions()
344 {
345         printf("Encrypt: scramble [-st] [-wt] <filename_in> [filename_out] \n");
346         printf("Decrypt: scramble -u <filename_in> [filename_out] \n");
347 }
348
349 int main(int argc, char *argv[])
350 {
351         switch (argc) {
352         case 2:
353                 encrypt_init();
354                 scramble_file(argv[1]);
355                 break;
356         case 3:
357                 encrypt_init();
358                 if ( !strcasecmp("-u", argv[1]) ) {
359                         unscramble_file(argv[2]);
360                 } else if ( !strcasecmp("-st", argv[1]) ) {
361                         scramble_file(argv[2], argv[2], PREPROCESS_SHIPS_TBL);
362                 } else if ( !strcasecmp("-wt", argv[1]) ) {
363                         scramble_file(argv[2], argv[2], PREPROCESS_WEAPONS_TBL);
364                 } else {
365                         scramble_file(argv[1], argv[2]);
366                 }
367                 break;
368         case 4:
369                 encrypt_init();
370                 if ( !strcasecmp("-u", argv[1]) ) {
371                         unscramble_file(argv[2], argv[3]);
372                 } else if ( !strcasecmp("-st", argv[1]) ) {
373                         scramble_file(argv[2], argv[3], PREPROCESS_SHIPS_TBL);
374                 } else if ( !strcasecmp("-wt", argv[1]) ) {
375                         scramble_file(argv[2], argv[3], PREPROCESS_WEAPONS_TBL);
376                 } else {
377                         print_instructions();
378                 }
379                 break;
380         default:
381                 print_instructions();
382                 break;
383         }
384
385         return 0;
386 }
387