1 #include "dzip.h"
2
dzExtractFile(uInt filepos,int testing)3 void dzExtractFile (uInt filepos, int testing)
4 {
5 int inlen, blocksize;
6 uInt eofptr, readptr;
7 direntry_t *de = directory + filepos;
8 char demomode;
9 #ifdef GUI
10 char *action = testing ? "testing" : "extracting";
11 #else
12 char *action = testing ? "checking" : "extracting";
13 #endif
14
15 static pakentry_t *pakdir;
16 static uInt pakptr;
17
18 crcval = INITCRC;
19 dzFile_Seek(de->ptr);
20
21 if (de->type == TYPE_PAK)
22 {
23 struct {
24 int id;
25 uInt offset;
26 uInt size;
27 } pakheader;
28 int i;
29
30 printf("%s %s:\n", action, de->name);
31 pakdir = Dzip_malloc(de->pak * sizeof(pakentry_t));
32 memset(pakdir, 0, de->pak * sizeof(pakentry_t));
33 pakptr = 12;
34 /* write pak header */
35 pakheader.id = pakid;
36 pakheader.size = de->pak * sizeof(pakentry_t);
37 pakheader.offset = de->real - pakheader.size;
38 Outfile_Write(&pakheader, 12);
39 for (i = 0; i < de->pak; i++)
40 {
41 printf(" %s", de[i + 1].name);
42 dzExtractFile(filepos + i + 1, testing);
43 if (AbortOp)
44 {
45 pakptr = 0;
46 return;
47 }
48 }
49 Outfile_Write(pakdir, de->pak * sizeof(pakentry_t));
50 free(pakdir);
51 pakptr = 0;
52 return;
53 }
54
55 if (de->type >= TYPE_LAST)
56 {
57 error("%s is unknown type of file: %i", de->name, de->type);
58 return;
59 }
60 demomode = (de->type == TYPE_DEM || de->type == TYPE_NEHAHRA);
61
62 if (pakptr)
63 {
64 strcpy(pakdir[de->pak - 1].name, de->name);
65 pakdir[de->pak - 1].len = de->real;
66 pakdir[de->pak - 1].ptr = pakptr;
67 pakptr += de->real;
68 }
69
70 #ifdef GUI
71 if (pakptr || (testing && de->pak))
72 GuiProgressMsg("%s %s [%s]", action, de[-de->pak].name, de->name);
73 else
74 GuiProgressMsg("%s %s", action, de->name);
75 #endif
76
77 if (!de->pak)
78 printf("%s %s", action, de->name);
79
80 if (de->type == TYPE_STORE)
81 {
82 totalsize = de->real;
83 while (totalsize && !AbortOp)
84 {
85 blocksize = (totalsize > p_blocksize * 2) ? p_blocksize * 2 : totalsize;
86 dzFile_Read(inblk, blocksize);
87 Outfile_Write(inblk, blocksize);
88 totalsize -= blocksize;
89 }
90 }
91 else
92 {
93 inlen = readptr = totalsize = 0;
94 eofptr = de->inter;
95 ztotal = de->size;
96 inflateInit(&zs); /* cant possibly fail with my modified zlib */
97 zs.avail_in = 0;
98
99 if (demomode)
100 dem_uncompress_init(de->type);
101
102 while (readptr < eofptr && !AbortOp)
103 {
104 if (!dzRead(inlen))
105 break; /* corrupt compressed stream */
106
107 if (demomode)
108 {
109 blocksize = dem_uncompress(eofptr - readptr);
110 if (!blocksize)
111 break;
112 }
113 else
114 {
115 blocksize = totalsize - readptr;
116 if (totalsize >= eofptr)
117 blocksize = eofptr - readptr;
118 Outfile_Write(inblk, blocksize);
119 }
120 if (blocksize != p_blocksize)
121 memcpy(inblk, inblk + blocksize, p_blocksize - blocksize);
122 readptr += blocksize;
123 inlen = p_blocksize - blocksize;
124 }
125 inflateEnd(&zs);
126 }
127
128 if (!AbortOp && crcval != de->crc)
129 {
130 #ifdef GUI
131 error("CRC error in %s", de->name);
132 #else
133 error(": CRC checksum error! Archive is broken!");
134 #endif
135 } else if (testing) printf(": ok\n");
136 else printf("\n");
137 }
138
139 #ifndef GUI
140
141 #include "dzipcon.h"
142
setfiledate(char * filename,uInt date)143 void setfiledate (char *filename, uInt date)
144 {
145 #ifdef WIN32
146 FILETIME ft1, ft2;
147 HANDLE h = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
148 NULL, OPEN_EXISTING, 0, NULL);
149 DosDateTimeToFileTime(HIWORD(date + (1 << 21)), LOWORD(date), &ft1);
150 LocalFileTimeToFileTime(&ft1, &ft2);
151 SetFileTime(h, NULL, NULL, &ft2);
152 CloseHandle(h);
153 #else
154 struct tm timerec;
155 struct utimbuf tbuf;
156
157 timerec.tm_hour = (date >> 11) & 0x1f;
158 timerec.tm_min = (date >> 5) & 0x3f;
159 timerec.tm_sec = (date & 0x1f) << 1;
160 timerec.tm_mday = (date >> 16) & 0x1f;
161 timerec.tm_mon = (date >> 21) & 0x0f;
162 timerec.tm_year = ((date >> 25) & 0x7f) + 80;
163 timerec.tm_isdst = -1;
164 tbuf.actime = tbuf.modtime = mktime(&timerec);
165 utime(filename,&tbuf);
166 #endif
167 }
168
dzUncompress(char * src)169 void dzUncompress (char *src)
170 {
171 direntry_t *de;
172 int i;
173
174 if (!dzOpen(src, 0))
175 return;
176 printf("%s created using v%u.%u\n", src, maj_ver, min_ver);
177
178 if (maj_ver == 1)
179 dzUncompressV1(flag[SW_VERIFY]);
180 else
181 for (i = 0; i < numfiles; i += de->pak + 1)
182 {
183 de = directory + i;
184 if (de->type == TYPE_DIR)
185 {
186 if (!flag[SW_VERIFY])
187 {
188 printf("creating %s\n", de->name);
189 CreateDir(de);
190 }
191 continue;
192 }
193
194 if (flag[SW_VERIFY])
195 {
196 dzExtractFile(i, 1);
197 continue;
198 }
199
200 outfile = open_create(de->name);
201 if (!outfile)
202 continue;
203
204 dzExtractFile(i, 0);
205 fclose(outfile);
206 if (AbortOp)
207 { /* problem writing file */
208 remove(de->name);
209 break;
210 }
211
212 setfiledate(de->name, de->date);
213 }
214 printf("\n");
215 dzClose();
216 }
217 #endif