]> icculus.org git repositories - taylor/freespace2.git/blob - src/cfilearchiver/cfilearchiver.cpp
added copyright header
[taylor/freespace2.git] / src / cfilearchiver / cfilearchiver.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/Cfilearchiver/CfileArchiver.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Program to create an archive file for use with cfile stuff
16  *
17  * $Log$
18  * Revision 1.3  2002/06/09 04:41:15  relnev
19  * added copyright header
20  *
21  * Revision 1.2  2002/05/07 03:16:43  theoddone33
22  * The Great Newline Fix
23  *
24  * Revision 1.1.1.1  2002/05/03 03:28:08  root
25  * Initial import.
26  *
27  * 
28  * 2     10/23/98 6:15p Dave
29  *
30  * $NoKeywords: $
31  */
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <direct.h>
36 #include <io.h>
37 #include <string.h>
38 #include <conio.h>
39
40 unsigned int Total_size=16; // Start with size of header
41 unsigned int Num_files =0;
42 FILE * fp_out = NULL;
43 FILE * fp_out_hdr = NULL;
44
45 typedef struct vp_header {
46         char id[4];
47         int version;
48         int index_offset;
49         int num_files;
50 } vp_header;
51
52 //vp_header Vp_header;
53
54 char archive_dat[1024];
55 char archive_hdr[1024];
56
57 #define BLOCK_SIZE (1024*1024)
58 #define VERSION_NUMBER 2;
59
60 char tmp_data[BLOCK_SIZE];              // 1 MB
61
62 void write_header()
63 {
64         fseek(fp_out, 0, SEEK_SET);
65         fwrite("VPVP", 1, 4, fp_out);
66         int ver = VERSION_NUMBER;
67         fwrite(&ver, 1, 4, fp_out);
68         fwrite(&Total_size, 1, 4, fp_out);
69         fwrite(&Num_files, 1, 4, fp_out);
70 }
71
72 int write_index(char *hf, char *df)
73 {
74         FILE *h = fopen(hf, "rb");
75         if (!h) return 0;
76         FILE *d = fopen(df, "a+b");
77         if (!d) return 0;
78         for (unsigned int i=0;i<Num_files;i++) {
79                 fread(tmp_data, 32+4+4+4, 1, h);
80                 fwrite(tmp_data, 32+4+4+4, 1, d);
81         }
82         fclose(h);
83         fclose(d);
84         return 1;
85 }
86
87 void pack_file( char *filespec, char *filename, int filesize, time_t time_write )
88 {
89         char path[1024];
90
91         if ( strstr( filename, ".vp" )) {
92                 // Don't pack yourself!!
93                 return;
94         }
95
96         if ( strstr( filename, ".hdr" ))        {
97                 // Don't pack yourself!!
98                 return;
99         }
100
101         if ( filesize == 0 ) {
102                 // Don't pack 0 length files, screws up directory structure!
103                 return;
104         }
105
106         memset( path, 0, sizeof(path));
107         strcpy( path, filename );
108         if ( strlen(filename)>31 )      {
109                 printf( "Filename '%s' too long\n", filename );
110                 exit(1);
111         }
112         fwrite( &Total_size, 1, 4, fp_out_hdr );
113         fwrite( &filesize, 1, 4, fp_out_hdr );
114         fwrite( &path, 1, 32, fp_out_hdr );
115         fwrite( &time_write, 1, sizeof(time_t), fp_out_hdr);
116
117         Total_size += filesize;
118         Num_files++;
119         printf( "Packing %s\\%s...", filespec, filename );
120
121         sprintf( path, "%s\\%s", filespec, filename );
122
123         FILE *fp = fopen( path, "rb" );
124         
125         if ( fp == NULL )       {
126                 printf( "Error opening '%s'\n", path );
127                 exit(1);
128         }
129
130         int nbytes, nbytes_read=0;
131
132         do      {
133                 nbytes = fread( tmp_data, 1, BLOCK_SIZE, fp );
134                 if ( nbytes > 0 )       {
135                         fwrite( tmp_data, 1, nbytes, fp_out );
136                         nbytes_read += nbytes;
137
138                 }
139         } while( nbytes > 0 );
140
141         fclose(fp);
142
143         printf( " %d bytes\n", nbytes_read );
144 }
145
146 // This function adds a directory marker to the header file
147 void add_directory( char * dirname)
148 {
149         char path[256];
150         char *pathptr = path;
151         char *tmpptr;
152
153         strcpy(path, dirname);
154         fwrite(&Total_size, 1, 4, fp_out_hdr);
155         int i = 0;
156         fwrite(&i, 1, 4, fp_out_hdr);
157         // strip out any directories that this dir is a subdir of
158         while ((tmpptr = strchr(pathptr, '\\')) != NULL) {
159                 pathptr = tmpptr+1;
160         }
161         fwrite(pathptr, 1, 32, fp_out_hdr);
162         fwrite(&i, 1, 4, fp_out_hdr); // timestamp = 0
163         Num_files++;
164 }
165
166 void pack_directory( char * filespec)
167 {
168         int find_handle;
169         _finddata_t find;
170         char tmp[512];
171         char tmp1[512];
172
173 /*
174         char dir_name[512];
175         char *last_slash;
176
177         last_slash = strrchr(filespec, '\\');
178         if ( last_slash ) {
179                 strcpy(dir_name, last_slash+1);
180         } else {
181                 strcpy(dir_name, filespec);
182         }
183
184         if ( !stricmp(dir_name, "voice") ) {
185                 return;
186         }
187 */
188
189         strcpy( tmp1, filespec );
190         add_directory(filespec);
191         strcat( tmp1, "\\*.*" );
192         
193         printf( "In dir '%s'\n", tmp1 );
194
195         find_handle = _findfirst( tmp1, &find );
196         if( find_handle != -1 ) {
197                 if ( find.attrib & _A_SUBDIR )  {
198                         if (strcmp( "..", find.name) && strcmp( ".", find.name))        {
199                                 strcpy( tmp, filespec );
200                                 strcat( tmp, "\\" );
201                                 strcat( tmp, find.name );
202                                 pack_directory(tmp);
203                         }
204                 } else {
205                         pack_file( filespec, find.name, find.size, find.time_write );
206                 }
207
208                 while( !_findnext( find_handle, &find ) )       {
209                         if ( find.attrib & _A_SUBDIR )  {
210                                 if (strcmp( "..", find.name) && strcmp( ".", find.name))        {
211                                         strcpy( tmp, filespec );
212                                         strcat( tmp, "\\" );
213                                         strcat( tmp, find.name );
214                                         pack_directory(tmp);
215
216                                 }
217                         } else {
218                                 pack_file( filespec, find.name, find.size, find.time_write );
219                         }
220                 }
221         }
222         add_directory("..");
223 }
224
225
226
227 int main(int argc, char *argv[] )
228 {
229         char archive[1024];
230         char *p;
231
232         if ( argc < 3 ) {
233                 printf( "Usage: %s archive_name src_dir\n", argv[0] );
234                 printf( "Example: %s freespace c:\\freespace\\data\n", argv[0] );
235                 printf( "Creates an archive named freespace out of the\nfreespace data tree\n" );
236                 printf( "Press any key to exit...\n" );
237                 getch();
238                 return 1;
239         }
240
241         strcpy( archive, argv[1] );
242         p = strchr( archive, '.' );
243         if (p) *p = 0;          // remove extension     
244
245         strcpy( archive_dat, archive );
246         strcat( archive_dat, ".vp" );
247
248         strcpy( archive_hdr, archive );
249         strcat( archive_hdr, ".hdr" );
250
251         fp_out = fopen( archive_dat, "wb" );
252         if ( !fp_out )  {
253                 printf( "Couldn't open '%s'!\n", archive_dat );
254                 printf( "Press any key to exit...\n" );
255                 getch();
256                 return 1;
257         }
258
259         fp_out_hdr = fopen( archive_hdr, "wb" );
260         if ( !fp_out_hdr )      {
261                 printf( "Couldn't open '%s'!\n", archive_hdr );
262                 printf( "Press any key to exit...\n" );
263                 getch();
264                 return 1;
265         }
266
267         write_header();
268
269         pack_directory( argv[2] );
270
271         write_header();
272
273         fclose(fp_out);
274         fclose(fp_out_hdr);
275
276         printf( "Data files written, appending index...\n" );
277
278         if (!write_index(archive_hdr, archive_dat)) {
279                 printf("Error appending index!\n");
280                 printf("Press any key to exit...\n");
281                 getch();
282                 return 1;
283         }
284         
285         printf( "%d total KB.\n", Total_size/1024 );
286         return 0;
287 }
288