]> icculus.org git repositories - taylor/freespace2.git/blob - src/scramble/scramble.cpp
ported (Taylor Richards)
[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 #endif
63 #include <string.h>
64
65 #include "pstypes.h"
66 #include "encrypt.h"
67 #include "scramble.h"
68
69 #define MAX_LINE_LEN    512
70
71 //static int Use_8bit = 0;      // set to 1 to disable 7bit character packing
72 static int Use_8bit = 1;
73
74
75 // strip out any ships tbl data not used in demo (ie entries without @ preceding name)
76 void scramble_read_ships_tbl(char **text, int *text_len, FILE *fp)
77 {
78         char    line[MAX_LINE_LEN+1];
79         char    token_line[MAX_LINE_LEN+1];
80         char    *dest;
81         int     line_len, discard_line = 1, keep_all_lines = 0, post_discard = 0;
82         char    seps[]   = " ,\t\n";
83         char    *token;
84
85 #ifndef PLAT_UNIX
86         *text_len = _filelength(fileno(fp));
87 #else
88         *text_len = filelength(fileno(fp));
89 #endif
90         *text = (char*)malloc(*text_len+1);
91
92         dest = *text;
93
94         while ( fgets(line, MAX_LINE_LEN, fp) != NULL ) {
95
96                 line_len = strlen(line);
97                 memcpy(token_line, line, line_len+1);
98
99                 if ( !keep_all_lines ) {
100                         token = strtok( token_line, seps );
101
102                         if ( token ) {
103                                 if ( !strnicmp("#End", token, 4) ) {
104                                         keep_all_lines = 1;
105                                 } else if ( !strnicmp("#Ship", token, 5) ) {
106                                         discard_line = 0;
107                                         post_discard = 1;
108                                 } else if ( !strnicmp("$Name:", token, 6) ) {
109                                         token = strtok( NULL, seps );
110                                         if ( token ) {
111                                                 if ( token[0] == '@' ) {
112                                                         discard_line = 0;
113                                                 } else {
114                                                         discard_line = 1;
115                                                 }
116                                         }
117                                 }
118                         }
119                 }
120
121                 if ( !discard_line || keep_all_lines ) {
122                         memcpy(dest, line, line_len);
123                         dest += line_len;
124                 }
125
126                 if ( post_discard ) {
127                         discard_line = 1;
128                         post_discard = 0;
129                 } 
130         }
131
132         *text_len = dest - *text;
133 }
134
135 // strip out any weapons tbl data not used in demo (ie entries without @ preceding name)
136 void scramble_read_weapons_tbl(char **text, int *text_len, FILE *fp)
137 {
138         char    line[MAX_LINE_LEN+1];
139         char    token_line[MAX_LINE_LEN+1];
140         char    *dest;
141         int     line_len, discard_line = 1, keep_all_lines = 0, post_discard = 0;
142         char    seps[]   = " ,\t\n";
143         char    *token = NULL;
144
145 #ifndef PLAT_UNIX
146         *text_len = _filelength(fileno(fp));
147 #else
148         *text_len = filelength(fileno(fp));
149 #endif
150         *text = (char*)malloc(*text_len+1);
151
152         dest = *text;
153
154         while ( fgets(line, MAX_LINE_LEN, fp) != NULL ) {
155
156                 line_len = strlen(line);
157                 memcpy(token_line, line, line_len+1);
158
159                 if ( !keep_all_lines ) {
160                         token = strtok( token_line, seps );
161
162                         if ( token ) {
163                                 if ( !strnicmp("#Countermeasures", token, 16) ) {
164                                         keep_all_lines = 1;
165                                 } else if ( !strnicmp("#End", token, 4) || !strnicmp("#Beam", token, 5) || !strnicmp("#Primary", token, 8) || !strnicmp("#Secondary", token, 10) ) {
166                                         discard_line = 0;
167                                         post_discard = 1;
168                                 } else if ( !strnicmp("$Name:", token, 6) ) {
169                                         discard_line = 1;
170                                         token = strtok( NULL, seps );
171                                         if ( token ) {
172                                                 if ( token[0] == '@' ) {
173                                                         discard_line = 0;
174                                                 }
175                                         }
176                                 }
177                         }
178                 }
179
180                 if ( (token[0] != ';') && (!discard_line || keep_all_lines) ) {
181                         memcpy(dest, line, line_len);
182                         dest += line_len;
183                 }
184
185                 if ( post_discard ) {
186                         discard_line = 1;
187                         post_discard = 0;
188                 } 
189         }
190
191         *text_len = dest - *text;
192 }
193
194 void scramble_read_default(char **text, int *text_len, FILE *fp)
195 {
196 #ifndef PLAT_UNIX
197         *text_len = _filelength(fileno(fp));
198 #else
199         *text_len = filelength(fileno(fp));
200 #endif
201         *text = (char*)malloc(*text_len+1);
202         fread( *text, *text_len, 1, fp );
203 }
204
205 // scramble a file
206 //
207 // input:       src_filename    =>      filename of text to scramble
208 //                              dest_filename   =>      optional, this is the filename scrambled data will get stored to
209 void scramble_file(char *src_filename, char *dest_filename, int preprocess)
210 {
211         FILE    *fp;
212         int     text_len, scramble_len;
213         char    *text, *scramble_text;
214
215         fp = fopen(src_filename, "rb");
216         if ( !fp ) {
217                 return;
218         }
219
220         // read in data, maybe preprocess
221         switch(preprocess) {
222         case PREPROCESS_SHIPS_TBL:
223                 scramble_read_ships_tbl(&text, &text_len, fp);
224                 break;
225         case PREPROCESS_WEAPONS_TBL:
226                 scramble_read_weapons_tbl(&text, &text_len, fp);
227                 break;
228         default:
229                 // read in the raw data
230                 scramble_read_default(&text, &text_len, fp);
231                 break;
232         }
233
234         fclose(fp);
235
236         // open up file for writing scrambled text
237         if ( dest_filename ) {
238                 fp = fopen(dest_filename, "wb");
239         } else {
240                 fp = fopen(src_filename, "wb");
241         }
242
243         if ( !fp ) {
244                 return;
245         }
246
247         scramble_text = (char*)malloc(text_len+32);
248
249         encrypt(text, text_len, scramble_text, &scramble_len, Use_8bit);
250         
251         // write out scrambled data
252         fwrite( scramble_text, scramble_len, 1, fp );
253
254         free(text);
255         free(scramble_text);
256         fclose(fp);
257 }
258
259 // unscramble a file
260 //
261 // input:       src_filename    =>      filename of scrambled text
262 //                              dest_filename   =>      optional, this is the filename unscrambled text data will get stored to
263 void unscramble_file(char *src_filename, char *dest_filename)
264 {
265         FILE    *fp;
266         int     scramble_len, text_len;
267         char    *text, *scramble_text;
268
269         fp = fopen(src_filename, "rb");
270         if ( !fp ) {
271                 return;
272         }
273
274         // read in the scrambled data
275 #ifndef PLAT_UNIX
276         scramble_len = _filelength(fileno(fp));
277 #else
278         scramble_len = filelength(fileno(fp));
279 #endif
280         scramble_text = (char*)malloc(scramble_len+1);
281         fread( scramble_text, scramble_len, 1, fp );
282         fclose(fp);
283
284         // open up file for writing unscrambled text
285         if ( dest_filename ) {
286                 fp = fopen(dest_filename, "wb");
287         } else {
288                 fp = fopen(src_filename, "wb");
289         }
290         if ( !fp ) {
291                 return;
292         }
293
294         // assume original text no larger than double scrambled size
295         text = (char*)malloc(scramble_len*2);
296
297         unencrypt(scramble_text, scramble_len, text, &text_len);
298
299         // write out unscrambled data
300         fwrite( text, text_len, 1, fp );
301
302         free(text);
303         free(scramble_text);
304         fclose(fp);
305 }
306
307 void print_instructions()
308 {
309         printf("Encrypt: scramble [-st] [-wt] <filename_in> [filename_out] \n");
310         printf("Decrypt: scramble -u <filename_in> [filename_out] \n");
311 }
312
313 #ifndef PLAT_UNIX
314 void main(int argc, char *argv[])
315 #else
316 int main(int argc, char *argv[])
317 #endif
318 {
319         switch (argc) {
320         case 2:
321                 encrypt_init();
322                 scramble_file(argv[1]);
323                 break;
324         case 3:
325                 encrypt_init();
326                 if ( !stricmp("-u", argv[1]) ) {
327                         unscramble_file(argv[2]);
328                 } else if ( !stricmp("-st", argv[1]) ) {
329                         scramble_file(argv[2], argv[2], PREPROCESS_SHIPS_TBL);
330                 } else if ( !stricmp("-wt", argv[1]) ) {
331                         scramble_file(argv[2], argv[2], PREPROCESS_WEAPONS_TBL);
332                 } else {
333                         scramble_file(argv[1], argv[2]);
334                 }
335                 break;
336         case 4:
337                 encrypt_init();
338                 if ( !stricmp("-u", argv[1]) ) {
339                         unscramble_file(argv[2], argv[3]);
340                 } else if ( !stricmp("-st", argv[1]) ) {
341                         scramble_file(argv[2], argv[3], PREPROCESS_SHIPS_TBL);
342                 } else if ( !stricmp("-wt", argv[1]) ) {
343                         scramble_file(argv[2], argv[3], PREPROCESS_WEAPONS_TBL);
344                 } else {
345                         print_instructions();
346                 }
347                 break;
348         default:
349                 print_instructions();
350 #ifndef PLAT_UNIX
351                 return;
352 #else
353                 return 1;
354 #endif
355         }
356 }
357