1 #include "dzip.h"
2 
3 FILE *pakfile;
4 pakentry_t *pakdir;
5 int paknum, pakptr;
6 char flag[5];
7 
initpakfile(direntry_t * de)8 void initpakfile (direntry_t *de)
9 {
10 	if (flag[SW_VERIFY])
11 		{ paknum = 0; pakfile = NULL; return; }
12 	pakdir = malloc(de->pak * sizeof(pakentry_t));
13 	paknum = *(int*)"PACK";
14 	if (pakfile) safe_fwrite(&paknum,4,pakfile);
15 	if (pakfile) safe_fwrite(&paknum,4,pakfile);
16 	if (pakfile) safe_fwrite(&paknum,4,pakfile);
17 	paknum = 0; pakptr = 12;
18 }
19 
closepakfile(direntry_t * de)20 void closepakfile (direntry_t *de)
21 {
22 	int tmp;
23 
24 	if (!pakfile) { free(pakdir); return; }
25 
26 	safe_fwrite(pakdir,paknum*sizeof(pakentry_t),pakfile);
27 	fseek(pakfile,4,SEEK_SET);
28 	tmp = cnvlong(pakptr);
29 	safe_fwrite(&tmp,4,pakfile);
30 	paknum *= 64;
31 	tmp = cnvlong(paknum);
32 	safe_fwrite(&tmp,4,pakfile);
33 	free(pakdir);
34 	fclose(pakfile);
35 	if (maj_ver != 1)
36 #ifdef _WIN32
37 	setfiledate(de[-paknum/64].name,de->date);
38 #endif
39 	pakfile = NULL;
40 }
41 
init_zlib_decompression()42 void init_zlib_decompression ()
43 {
44 	zip_stream.zalloc = (alloc_func)0;
45 	zip_stream.zfree = (free_func)0;
46 	zip_stream.opaque = (voidpf)0;
47 
48 	zip_err = inflateInit(&zip_stream);
49 	zip_stream.avail_in = p_blocksize + 1;
50 	check_dzip_err("inflateinit");
51 }
52 
end_zlib_decompression()53 void end_zlib_decompression ()
54 {
55 	inflateEnd(&zip_stream);
56 }
57 
check_filetype(int type)58 int check_filetype (int type)
59 {
60         if (type >= TYPE_LAST) Sys_Error("unknown type of file");
61 	return (type == TYPE_DEM || type == TYPE_DEMV1
62 		|| type == TYPE_NEHAHRA);
63 }
64 
uncompress_file(FILE * handle,char * src,char * outname)65 void uncompress_file (FILE *handle, char *src, char *outname)
66 {
67 	int i, inlen, ptr, readptr, eofptr, blocksize;
68 	char demomode;
69 	direntry_t *de;
70         char *action = "extracting";
71 
72         OpenDZFile(handle, src);
73 //        de->type = TYPE_NEHAHRA;
74 
75 	printf("%s created using v%u.%u\n", src, maj_ver, min_ver);
76 //        maj_ver = 1;
77 
78 	inlen = 0;
79 	if (maj_ver == 1)
80 	{
81 		ptr = directory[numfiles-1].ptr + directory[numfiles-1].size;
82 		readptr = totalsize = 12;
83 		init_zlib_decompression();
84 	}
85 
86 	for (i = 0; i < numfiles; i++)
87 	{
88 		de = directory + i;
89 		crcval = INITCRC;
90 		if (!de->pak)
91 			printf("%s %s",action,de->name);
92 		fflush(stdout);
93 		if (de->type == TYPE_PAK)
94 		{
95 			printf("%s %s:",action,de->name);
96 			if (flag[SW_VERIFY])
97 				pakfile = NULL;
98 			else
99 			{
100 			#ifdef GUI
101 				pakfile = GuiGetUncompressOutfile(de);
102 				if (!pakfile && GuiAbort) return;
103 			#else
104                                 pakfile = open_create(outname);
105 			#endif
106 			}
107 			if (pakfile || flag[SW_VERIFY]) printf("\n");
108                         initpakfile(de);
109 			i++; de++;
110 			outfile = pakfile;
111 		}
112 		demomode = check_filetype(de->type);
113                 outfile = open_create(outname);
114                 if (demomode) dem_uncompress_init(TYPE_NEHAHRA);
115 
116 		if (maj_ver > 1)
117 		{
118 			init_zlib_decompression();
119 			readptr = totalsize = 0;
120 			ptr = eofptr = de->inter;
121 			ztotal = de->size;
122 		}
123 		else
124 			eofptr = de->ptr + de->size;
125 
126 		while (readptr < eofptr)
127 		{
128                         read_file(handle,&inlen,ptr);
129 
130 			if (demomode)
131 				blocksize = dem_uncompress();
132 			else
133 			{
134 				blocksize = totalsize - readptr;
135 				if (totalsize >= eofptr)
136 					blocksize = eofptr - readptr;
137 				write_output(inblk,blocksize);
138 			}
139 			if (blocksize != p_blocksize)
140 				memcpy(inblk,inblk+blocksize,p_blocksize-blocksize);
141 			readptr += blocksize;
142 			inlen -= blocksize;
143 		}
144 
145 		if (!de->pak && outfile)
146 		{
147                         fclose(outfile);
148 //                        if (maj_ver > 1) setfiledate(de->name,de->date);
149 		}
150 //                demotime =de->date;
151 
152 		if (pakfile && (i+1 == numfiles || !directory[i+1].pak
153 			|| directory[i+1].type == TYPE_PAK))
154 			closepakfile(de);
155 
156 //                if (crcval != de->crc)
157 //                        if (flag[SW_CRC])
158 //                                fprintf(stderr,": warning: CRC error!\n");
159 //                        else
160 //                                Sys_Error("CRC checksum error! Archive is broken!");
161 
162 		if (flag[SW_VERIFY]) printf(": ok\n");
163 		else printf("\n");
164 
165 		if (maj_ver > 1) end_zlib_decompression();
166 	}
167 	if (maj_ver == 1) end_zlib_decompression();
168 
169 	for (i = 0; i < numfiles; free(directory[i++].name));
170 	free(directory);
171         fclose(handle);
172 }
173