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