~ubuntu-branches/ubuntu/saucy/jzip/saucy

« back to all changes in this revision

Viewing changes to .pc/compiler-warnings/jzexe.c

  • Committer: Package Import Robot
  • Author(s): Niko Tyni
  • Date: 2012-03-25 22:42:35 UTC
  • Revision ID: package-import@ubuntu.com-20120325224235-aq5xki4sm298evr3
Tags: 210r20001005d-2
Adapt to zlib gzFile changes. (Closes: #664931)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* $Id: jzexe.c,v 1.1.1.1 2000/05/10 14:21:34 jholder Exp $   
 
3
 * --------------------------------------------------------------------
 
4
 * see doc/License.txt for License Information   
 
5
 * --------------------------------------------------------------------
 
6
 * 
 
7
 * File name: $Id: jzexe.c,v 1.1.1.1 2000/05/10 14:21:34 jholder Exp $  
 
8
 *   
 
9
 * Description:    
 
10
 *    
 
11
 * Modification history:      
 
12
 * $Log: jzexe.c,v $
 
13
 * Revision 1.1.1.1  2000/05/10 14:21:34  jholder
 
14
 *
 
15
 * imported
 
16
 *
 
17
 *
 
18
 * --------------------------------------------------------------------
 
19
 */
 
20
 
 
21
/*
 
22
 * jzexe.c  version 1.1
 
23
 * 
 
24
 * This program creates standalone game executables from Infocom
 
25
 * format story files. It does so by concatenating the JZip executable
 
26
 * with the story file and then patching the excutable to start reading
 
27
 * the story from the correct file position.
 
28
 *
 
29
 * Written by Magnus Olsson (mol@df.lth.se), 20 November, 1995,
 
30
 * as part of the JZip distribution. 
 
31
 * You may use this code in any way you like as long as it is
 
32
 * attributed to its author.
 
33
 *
 
34
 */
 
35
 
 
36
#include <stdlib.h>
 
37
#include <stdio.h>
 
38
#include <string.h>
 
39
 
 
40
#include "jzexe.h"
 
41
 
 
42
#ifndef TRUE
 
43
#define TRUE 1
 
44
#define FALSE 0
 
45
#endif
 
46
 
 
47
#ifndef SEEK_SET
 
48
#define SEEK_SET 0
 
49
#endif
 
50
 
 
51
/* The size of the buffer used when copying files */
 
52
#define BUFSIZE 16384
 
53
 
 
54
static unsigned char *buf;
 
55
static unsigned char *jzipmagic = ( unsigned char * ) MAGIC_STRING;
 
56
 
 
57
#if defined(MSDOS) || defined(__MSDOS__)
 
58
#define READ_MODE "rb"
 
59
#define WRITE_MODE "wb"
 
60
#else
 
61
#define READ_MODE "r"
 
62
#define WRITE_MODE "w"
 
63
#endif
 
64
 
 
65
#define NAME_LENGTH 200
 
66
static char in_name[NAME_LENGTH + 1];
 
67
static char out_name[NAME_LENGTH + 1];
 
68
 
 
69
/* The name of the JZip executable */
 
70
#define JZIP_NAME "jzip.exe"
 
71
 
 
72
void abort_program( int exit_code )
 
73
{
 
74
   fprintf( stderr, "\nProgram aborted.\n" );
 
75
   /* Remove output file; it's probably corrupted. */
 
76
   remove( out_name );
 
77
   exit( exit_code );
 
78
}
 
79
 
 
80
FILE *open_file( char *name, int input )
 
81
{
 
82
   char *mode;
 
83
   FILE *f;
 
84
 
 
85
   if ( input )
 
86
   {
 
87
      strncpy( in_name, name, NAME_LENGTH );
 
88
      /* If name is too long, in_name won't be null terminated: fix this,
 
89
       * just in case */
 
90
      in_name[NAME_LENGTH] = 0;
 
91
      mode = READ_MODE;
 
92
   }
 
93
   else
 
94
   {
 
95
      strncpy( out_name, name, NAME_LENGTH );
 
96
      out_name[NAME_LENGTH] = 0;
 
97
      mode = WRITE_MODE;
 
98
   }
 
99
   f = fopen( name, mode );
 
100
   if ( !f )
 
101
   {
 
102
      fprintf( stderr, "Error opening file %s\n", name );
 
103
      abort_program( 1 );
 
104
   }
 
105
   return f;
 
106
}
 
107
 
 
108
/* 
 
109
 * Search through the file f for the magic string. If found, return
 
110
 * the offset stored in the patch area, otherwise abort the program.
 
111
 */
 
112
long search( FILE * f )
 
113
{
 
114
   int c, i;
 
115
 
 
116
   i = 0;
 
117
   while ( ( c = getc( f ) ) > -1 )
 
118
   {
 
119
      if ( ( unsigned char ) c != jzipmagic[i] )
 
120
      {                         
 
121
         if ( ( unsigned char ) c == jzipmagic[0] ) 
 
122
            i = 1;
 
123
         else
 
124
            i = 0;
 
125
      }
 
126
      else if ( ++i == MAGIC_END )
 
127
      {
 
128
         /* Found magic string. */
 
129
         long offset;
 
130
 
 
131
         /* Next byte must be zero. */
 
132
         if ( getc( f ) != 0 )
 
133
         {
 
134
            fprintf( stderr, "Error: standalone flag != 0\n" );
 
135
            abort_program( 1 );
 
136
         }
 
137
         offset = getc( f );
 
138
         offset += 256L * getc( f );
 
139
         offset += 65536L * getc( f );
 
140
         return offset;
 
141
      }
 
142
   }
 
143
   fprintf( stderr, "Couldn't find magic string." );
 
144
   abort_program( 1 );
 
145
}
 
146
 
 
147
/*
 
148
 * Copy the file in to the file out. Set length to the length in bytes
 
149
 * of the input file, and set magic_pos to the offset of the first
 
150
 * occurrence of MAGIC_STRING. 
 
151
 */
 
152
void copy_and_search( FILE * in, FILE * out, long *length, long *magic_pos )
 
153
{
 
154
   int c, magic_idx;            
 
155
   size_t buf_idx, buf_end;     
 
156
   long pos;
 
157
 
 
158
   pos = 0;
 
159
   buf_idx = buf_end = 0;
 
160
   magic_idx = 0;
 
161
   *magic_pos = 0;
 
162
 
 
163
   for ( ;; )
 
164
   {                            
 
165
      if ( buf_idx >= buf_end )
 
166
      {
 
167
         /* Reached end of input buffer; read in a new chunk */
 
168
         buf_end = fread( buf, 1, BUFSIZE, in );
 
169
         if ( buf_end < 1 )
 
170
         {
 
171
            /* Reached end of input file. 
 
172
             * pos is now the number of bytes read. */
 
173
            *length = pos;
 
174
            return;
 
175
         }
 
176
         if ( fwrite( buf, 1, buf_end, out ) != buf_end )
 
177
         {
 
178
            fprintf( stderr, "Write error on file %s\n", out_name );
 
179
            fclose( in );
 
180
            fclose( out );
 
181
            abort_program( 1 );
 
182
         }
 
183
         buf_idx = 0;
 
184
      }
 
185
 
 
186
      c = buf[buf_idx++];       /* Get current character */
 
187
      ++pos;                    /* Offset of next byte */
 
188
 
 
189
      /* The following search algorithm utilizes the fact that the
 
190
       * first character of the magic string is unique. */
 
191
      if ( ( unsigned char ) c != jzipmagic[magic_idx] ) 
 
192
         if ( ( unsigned char ) c == jzipmagic[0] ) 
 
193
            magic_idx = 1;
 
194
         else
 
195
            magic_idx = 0;
 
196
      else if ( ++magic_idx == MAGIC_END )
 
197
      {
 
198
         /* Matched the entire magic string */
 
199
         if ( *magic_pos > 0 )
 
200
         {
 
201
            /* If this condition occurs, the magic string isn't unique,
 
202
             * with potentially bad consequences. Re-compile with a
 
203
             * different magic string. */
 
204
            fprintf( stderr, "Found more than one instance of the magic string.\n" );
 
205
            fclose( in );
 
206
            fclose( out );
 
207
            abort_program( 1 );
 
208
         }
 
209
         *magic_pos = pos;
 
210
      }
 
211
   }
 
212
}
 
213
 
 
214
/*
 
215
 * Copy the input file to the output file.
 
216
 */
 
217
void copy( FILE * in, FILE * out )
 
218
{
 
219
   unsigned bytes_read;
 
220
   long total = 0;
 
221
 
 
222
   do
 
223
   {
 
224
      bytes_read = fread( buf, 1, BUFSIZE, in );
 
225
      if ( bytes_read > 0 )
 
226
         if ( fwrite( buf, 1, bytes_read, out ) != bytes_read )
 
227
         {
 
228
            fprintf( stderr, "Write error on file %s\n", out_name );
 
229
            fclose( in );
 
230
            fclose( out );
 
231
            abort_program( 1 );
 
232
         }
 
233
      total += bytes_read;
 
234
   }
 
235
   while ( bytes_read > 0 );
 
236
 
 
237
   if ( total == 0 )
 
238
      fprintf( stderr, "Nothing read from file %s - probably an error.\n", in_name );
 
239
}
 
240
 
 
241
/*
 
242
 * Patch the output file so it will read Z code from the correct position.
 
243
 */
 
244
void patch( FILE * f, long pos, long value )
 
245
{
 
246
   int i;
 
247
 
 
248
   fflush( f );
 
249
   if ( fseek( f, pos, SEEK_SET ) )
 
250
   {
 
251
      fprintf( stderr, "Seek error on file %s\n", out_name );
 
252
      fclose( f );
 
253
      abort_program( 1 );
 
254
   }
 
255
   /* Set STANDALONE_FLAG to FALSE */
 
256
   fputc( FALSE, f );
 
257
   /* Write the length of the JZip interpreter to the file as a
 
258
    * little-endian, 24-bit number. */
 
259
   for ( i = 0; i < 3; ++i )
 
260
   {
 
261
      fputc( ( int ) ( value & 0xff ), f );
 
262
      value >>= 8;
 
263
   }
 
264
}
 
265
 
 
266
void create_executable( char *story, char *jzip )
 
267
{
 
268
   FILE *in, *out;
 
269
   long p, length, pos;
 
270
   char fn[NAME_LENGTH + 4];
 
271
   char *ext;
 
272
   int ok;
 
273
 
 
274
   strcpy( in_name, "" );
 
275
   strcpy( out_name, "" );
 
276
 
 
277
   if ( strlen( story ) > NAME_LENGTH || strlen( jzip ) > NAME_LENGTH )
 
278
   {
 
279
      fprintf( stderr, "Filename too long.\n" );
 
280
      abort_program( 1 );
 
281
   }
 
282
   strcpy( fn, story );
 
283
   ext = strrchr( fn, '.' );
 
284
   if ( ext )
 
285
      *ext = '\0';
 
286
   strcat( fn, ".exe" );
 
287
 
 
288
   printf( "Creating standalone story %s\n", fn );
 
289
   out = open_file( fn, FALSE );
 
290
 
 
291
   printf( "Copying JZip interpreter (%s).\n", jzip );
 
292
   in = open_file( jzip, TRUE );
 
293
 
 
294
   copy_and_search( in, out, &length, &pos );
 
295
   fclose( in );
 
296
   if ( pos == 0 )
 
297
   {
 
298
      fprintf( stderr, "Error: couldn't find magic string.\n" );
 
299
      fprintf( stderr, "Check that you have the right version of JZip.\n" );
 
300
      abort_program( 1 );
 
301
   }
 
302
 
 
303
   printf( "Copying story file %s.\n", story );
 
304
   in = open_file( story, TRUE );
 
305
   copy( in, out );
 
306
   fclose( in );
 
307
 
 
308
   printf( "Patching interpreter.\n" );
 
309
   patch( out, pos, length );
 
310
   fclose( out );
 
311
 
 
312
   printf( "Done!\n" );
 
313
}
 
314
 
 
315
void extract_zcode( char *filename )
 
316
{
 
317
   FILE *in, *out;
 
318
   long offset;
 
319
   char fn[NAME_LENGTH + 4];
 
320
   char *ext;
 
321
   int z_version;
 
322
 
 
323
   strcpy( in_name, "" );
 
324
   strcpy( out_name, "" );
 
325
 
 
326
   if ( strlen( filename ) > NAME_LENGTH )
 
327
   {
 
328
      fprintf( stderr, "Filename too long.\n" );
 
329
      abort_program( 1 );
 
330
   }
 
331
 
 
332
   in = open_file( filename, TRUE );
 
333
   offset = search( in );
 
334
 
 
335
   fseek( in, offset, SEEK_SET );
 
336
   z_version = fgetc( in );
 
337
   if ( z_version < 1 || z_version > 8 )
 
338
   {
 
339
      fprintf( stderr, "Unsupported Z code version: %d\n", z_version );
 
340
      abort_program( 1 );
 
341
   }
 
342
   strcpy( fn, filename );
 
343
   ext = strrchr( fn, '.' );
 
344
   if ( ext == 0 )
 
345
      ext = fn + strlen( fn );
 
346
   sprintf( ext, ".z%d", z_version );
 
347
 
 
348
   printf( "Extracting Z code to story file %s\n", fn );
 
349
   out = open_file( fn, FALSE );
 
350
 
 
351
   fputc( z_version, out );
 
352
   copy( in, out );
 
353
   fclose( in );
 
354
   fclose( out );
 
355
}
 
356
 
 
357
#define USAGE "JZexe Ver. 1.1 - creates standalone Infocom-format games for MS-DOS and Linux.\n\
 
358
(c) 1995 by Magnus Olsson (mol@df.lth.se)\n\n\
 
359
Usage: jzexe story_file\n\
 
360
       jzexe story_file jzip_file\n\n\
 
361
These two commands create a standalone game from an Infocom story file.\n\
 
362
In the first case, it is assumed that the JZip interpreter is called jzip.exe\n\
 
363
and resides in the current directory.\n\n\
 
364
       jzexe -x game.exe\n\n\
 
365
This command extracts the Z code from a standalone executable and creates\n\
 
366
a story file that can be played with JZip or any other interpreter.\n\
 
367
Note that the extension '.exe' of the game file must be given.\n"
 
368
 
 
369
void main( int argc, char **argv )
 
370
{
 
371
   buf = ( unsigned char * ) malloc( BUFSIZE * sizeof ( unsigned char ) );
 
372
 
 
373
   if ( argc == 3 && strcmp( argv[1], "-x" ) == 0 )
 
374
      extract_zcode( argv[2] );
 
375
   else if ( argc == 2 )
 
376
      create_executable( argv[1], JZIP_NAME );
 
377
   else if ( argc == 3 )
 
378
      create_executable( argv[1], argv[2] );
 
379
   else
 
380
      fprintf( stderr, USAGE );
 
381
 
 
382
   exit( 0 );
 
383
}