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