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