2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/scramble/scramble.cpp $
15 * Module for file scrambler
18 * Revision 1.3 2003/01/30 20:05:01 relnev
19 * ported (Taylor Richards)
21 * Revision 1.2 2002/06/09 04:41:25 relnev
22 * added copyright header
24 * Revision 1.1.1.1 2002/05/03 03:28:10 root
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.
32 * 2 10/24/98 11:41p Dave
34 * 1 10/24/98 11:31p Dave
36 * 7 8/09/98 4:44p Lawrance
37 * support alternate encryption scheme (doesn't pack chars into 7 bits)
39 * 6 4/14/98 4:14p Lawrance
40 * fix bug with ships and weapons tbl preprocessing
42 * 5 4/14/98 1:39p Lawrance
43 * Add command line switches to preprocess ship and weapon tables
45 * 4 3/31/98 1:14a Lawrance
46 * Get .tbl and mission file encryption working.
48 * 3 3/30/98 5:57p Lawrance
51 * 2 3/30/98 5:51p Lawrance
52 * file encryption and decryption
67 #define SDL_MAIN_HANDLED
78 #define strncasecmp strnicmp
79 #define strcasecmp stricmp
81 int _filelength (int fd)
84 if (fstat (fd, &buf) == -1)
91 #define MAX_LINE_LEN 512
93 //static int Use_8bit = 0; // set to 1 to disable 7bit character packing
94 static int Use_8bit = 1;
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)
100 char line[MAX_LINE_LEN+1];
101 char token_line[MAX_LINE_LEN+1];
103 int line_len, discard_line = 1, keep_all_lines = 0, post_discard = 0;
104 char seps[] = " ,\t\n";
107 *text_len = _filelength(fileno(fp));
112 *text = (char*)malloc(*text_len+1);
116 while ( fgets(line, MAX_LINE_LEN, fp) != NULL ) {
118 line_len = strlen(line);
119 memcpy(token_line, line, line_len+1);
121 if ( !keep_all_lines ) {
122 token = strtok( token_line, seps );
125 if ( !strncasecmp("#End", token, 4) ) {
127 } else if ( !strncasecmp("#Ship", token, 5) ) {
130 } else if ( !strncasecmp("$Name:", token, 6) ) {
131 token = strtok( NULL, seps );
133 if ( token[0] == '@' ) {
143 if ( !discard_line || keep_all_lines ) {
144 memcpy(dest, line, line_len);
148 if ( post_discard ) {
154 *text_len = dest - *text;
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)
160 char line[MAX_LINE_LEN+1];
161 char token_line[MAX_LINE_LEN+1];
163 int line_len, discard_line = 1, keep_all_lines = 0, post_discard = 0;
164 char seps[] = " ,\t\n";
167 *text_len = _filelength(fileno(fp));
168 *text = (char*)malloc(*text_len+1);
172 while ( fgets(line, MAX_LINE_LEN, fp) != NULL ) {
174 line_len = strlen(line);
175 memcpy(token_line, line, line_len+1);
177 if ( !keep_all_lines ) {
178 token = strtok( token_line, seps );
181 if ( !strncasecmp("#Countermeasures", token, 16) ) {
183 } else if ( !strncasecmp("#End", token, 4) || !strncasecmp("#Beam", token, 5) || !strncasecmp("#Primary", token, 8) || !strncasecmp("#Secondary", token, 10) ) {
186 } else if ( !strncasecmp("$Name:", token, 6) ) {
188 token = strtok( NULL, seps );
190 if ( token[0] == '@' ) {
198 if ( token && (token[0] != ';') && (!discard_line || keep_all_lines) ) {
199 memcpy(dest, line, line_len);
203 if ( post_discard ) {
209 *text_len = dest - *text;
212 void scramble_read_default(char **text, int *text_len, FILE *fp)
214 *text_len = _filelength(fileno(fp));
219 *text = (char*)malloc(*text_len+1);
221 if ( !fread(*text, *text_len, 1, fp) ) {
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)
235 int text_len, scramble_len;
236 char *text, *scramble_text;
238 fp = fopen(src_filename, "rb");
243 // read in data, maybe preprocess
245 case PREPROCESS_SHIPS_TBL:
246 scramble_read_ships_tbl(&text, &text_len, fp);
248 case PREPROCESS_WEAPONS_TBL:
249 scramble_read_weapons_tbl(&text, &text_len, fp);
252 // read in the raw data
253 scramble_read_default(&text, &text_len, fp);
263 // open up file for writing scrambled text
264 if ( dest_filename ) {
265 fp = fopen(dest_filename, "wb");
267 fp = fopen(src_filename, "wb");
275 scramble_text = (char*)malloc(text_len+32);
277 encrypt(text, text_len, scramble_text, &scramble_len, Use_8bit);
279 // write out scrambled data
280 fwrite( scramble_text, scramble_len, 1, fp );
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)
294 int scramble_len, text_len;
295 char *text, *scramble_text;
297 fp = fopen(src_filename, "rb");
302 // read in the scrambled data
303 scramble_len = _filelength(fileno(fp));
305 if (scramble_len <= 0) {
310 scramble_text = (char*)malloc(scramble_len+1);
312 if ( !fread(scramble_text, scramble_len, 1, fp) ) {
320 // open up file for writing unscrambled text
321 if ( dest_filename ) {
322 fp = fopen(dest_filename, "wb");
324 fp = fopen(src_filename, "wb");
330 // assume original text no larger than double scrambled size
331 text = (char*)malloc(scramble_len*2);
333 unencrypt(scramble_text, scramble_len, text, &text_len);
335 // write out unscrambled data
336 fwrite( text, text_len, 1, fp );
343 void print_instructions()
345 printf("Encrypt: scramble [-st] [-wt] <filename_in> [filename_out] \n");
346 printf("Decrypt: scramble -u <filename_in> [filename_out] \n");
349 int main(int argc, char *argv[])
354 scramble_file(argv[1]);
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);
365 scramble_file(argv[1], argv[2]);
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);
377 print_instructions();
381 print_instructions();