]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/pak.cpp
Use time_t to store time data.
[quix0rs-blobwars.git] / src / pak.cpp
1 /*
2 Copyright (C) 2005 Parallel Realities
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21 #include "pak.h"
22
23 FILE *pak;
24 int dirs = 0, files = 0;
25 int totalFiles = 0;
26 Bytef *buffer;
27 Bytef *output;
28
29 FileData *fileData = NULL;
30
31 void cleanup()
32 {
33         delete[] buffer;
34         delete[] output;
35 }
36
37 void countFiles(const char *dirName)
38 {
39         DIR *dirp, *dirp2;
40         dirent *dfile;
41         dirp = opendir(dirName);
42         char filename[1024];
43
44         while ((dfile = readdir(dirp)))
45         {
46                 if (dfile->d_name[0] == '.')
47                 {
48                         continue;
49                 }
50
51                 snprintf(filename, sizeof filename, "%s/%s", dirName, dfile->d_name);
52                 
53                 if (strlen(filename) > PAK_MAX_FILENAME - 1)
54                 {
55                         printf("\nERROR - '%s' exceeds maximum defined file length of %d\n", filename, PAK_MAX_FILENAME);
56                         exit(1);
57                 }
58
59                 dirp2 = opendir(filename);
60
61                 if (dirp2)
62                 {
63                         closedir(dirp2);
64                         countFiles(filename);
65                 }
66                 else
67                 {
68                         totalFiles++;
69                 }
70         }
71
72         closedir(dirp);
73         
74         fileData = new FileData[totalFiles];
75 }
76
77 void recurseDirectory(const char *dirName)
78 {
79         DIR *dirp, *dirp2;
80         dirent *dfile;
81         gzFile fp;
82         FILE *infile;
83         char filename[1024];
84
85         uLongf cSize = 0;
86         uLongf fSize = 0;
87
88         dirp = opendir(dirName);
89
90         if (dirp == NULL)
91         {
92                 printf("%s: Directory does not exist or is not accessable\n", dirName);
93                 return;
94         }
95         
96         float percentage;
97         long filesize;
98
99         while ((dfile = readdir(dirp)))
100         {
101                 if (dfile->d_name[0] == '.')
102                 {
103                         continue;
104                 }
105
106                 snprintf(filename, sizeof filename, "%s/%s", dirName, dfile->d_name);
107
108                 dirp2 = opendir(filename);
109
110                 if (dirp2)
111                 {
112                         closedir(dirp2);
113                         recurseDirectory(filename);
114                 }
115                 else
116                 {
117                         infile = fopen(filename, "rb");
118                         if (!infile)
119                         {
120                                 printf("Couldn't open %s for reading!\n", filename);
121                                 closedir(dirp);
122                                 fclose(pak);
123                                 exit(1);
124                         }
125                         
126                         fseek(infile, SEEK_SET, SEEK_END);
127                         
128                         filesize = ftell(infile);
129                         
130                         fclose(infile);
131                         
132                         delete[] buffer;
133                         buffer = new unsigned char[filesize];
134                         
135                         delete[] output;
136                         output = new unsigned char[(int)(filesize * 1.01) + 12];
137                         
138                         fp = gzopen(filename, "rb");
139
140                         if (!fp)
141                         {
142                                 printf("Couldn't open %s for reading!\n", filename);
143                                 closedir(dirp);
144                                 fclose(pak);
145                                 exit(1);
146                         }
147                         else
148                         {
149                                 fSize = gzread(fp, buffer, filesize);
150                                 gzclose(fp);
151
152                                 cSize = (uLongf)((fSize * 1.01) + 12);
153                                 compress2(output, &cSize, buffer, fSize, 9);
154                                 
155                                 fileData[files].set(filename, fSize, cSize, ftell(pak));
156
157                                 if (fwrite(output, 1, cSize, pak) != cSize)
158                                 {
159                                         fprintf(stderr, "Error writing to pakfile: %s\n", strerror(errno));
160                                         fclose(pak);
161                                         exit(1);
162                                 }
163
164                                 files++;
165                                 
166                                 percentage = files;
167                                 percentage /= totalFiles;
168                                 percentage *= 100;
169
170                                 printf("\b\b\b\b%3.0f%%", percentage);
171                                 fflush(stdout);
172                         }
173                 }
174         }
175
176         closedir(dirp);
177
178         dirs++;
179 }
180
181 int main(int argc, char *argv[])
182 {
183         if (argc < 3)
184         {
185                 printf("Usage   : pak <directory names> <outputname>\n");
186                 printf("Example : pak data music gfx sound data.pak\n");
187                 exit(1);
188         }
189
190         pak = fopen(argv[argc - 1], "wb");
191         if (!pak)
192         {
193                 fprintf(stderr, "Error opening %s: %s\n", argv[argc - 1], strerror(errno));
194                 return 1;
195         }
196         
197         for (int i = 1 ; i < (argc - 1) ; i++)
198         {
199                 countFiles(argv[i]);
200         }
201                 
202         printf("Paking...000%%");
203         fflush(stdout);
204         
205         output = NULL;
206         buffer = NULL;
207         
208         atexit(cleanup);
209
210         for (int i = 1 ; i < (argc - 1) ; i++)
211         {
212                 recurseDirectory(argv[i]);
213         }
214
215         unsigned int pos = ftell(pak);
216
217         for (int i = 0 ; i < files ; i++)
218         {
219                 if (fileData[i].fSize == 0)
220                 {
221                         break;
222                 }
223
224                 if (fwrite(&fileData[i], sizeof(FileData), 1, pak) != 1)
225                 {
226                         fprintf(stderr, "Error writing to %s: %s\n", argv[argc - 1], strerror(errno));
227                         fclose(pak);
228                         return 1;
229                 }
230         }
231         
232         unsigned int numberOfFiles = totalFiles;
233
234         if (fwrite(&pos, sizeof(unsigned int), 1, pak) != 1)
235         {
236                 fprintf(stderr, "Error writing to %s: %s\n", argv[argc - 1], strerror(errno));
237                 fclose(pak);
238                 return 1;
239         }
240         if (fwrite(&numberOfFiles, sizeof(unsigned int), 1, pak) != 1)
241         {
242                 fprintf(stderr, "Error writing to %s: %s\n", argv[argc - 1], strerror(errno));
243                 fclose(pak);
244                 return 1;
245         }
246
247         fclose(pak);
248
249         printf("\nPak: All Done. Added %d files\n", numberOfFiles);
250
251         return 0;
252 }