1 /**
2  * @file libcomprex/archive.c Archive API
3  *
4  * $Id: archive.c,v 1.33 2003/01/02 02:49:38 chipx86 Exp $
5  *
6  * @Copyright (C) 2001-2003 The GNUpdate Project.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA  02111-1307, USA.
22  */
23 #include <libcomprex/internal.h>
24 #include <libcomprex/archive.h>
25 #include <libcomprex/utils.h>
26 #include <comprex.h>
27 
28 CxArchive *
cxNewArchive(void)29 cxNewArchive(void)
30 {
31 	CxArchive *archive;
32 
33 	MEM_CHECK(archive = (CxArchive*)malloc(sizeof(CxArchive)));
34 	memset(archive, 0, sizeof(CxArchive));
35 
36 	cxSetArchiveType(archive,       CX_ARCHIVE_UNKNOWN);
37 	cxSetArchiveAccessMode(archive, CX_MODE_READ_WRITE);
38 
39 	archive->root = cxNewDirectory();
40 	cxSetDirArchive(archive->root, archive);
41 
42 #if 0
43 	cxSetDirName(archive->root, "/");
44 	cxSetDirPath(archive->root, "/");
45 #endif
46 
47 	CX_LINK(archive);
48 
49 	return archive;
50 }
51 
52 void
cxDestroyArchive(CxArchive * archive)53 cxDestroyArchive(CxArchive *archive)
54 {
55 	CxArchive *parent;
56 	CxFP *fp;
57 
58 	if (archive == NULL || archive->refCount == 0)
59 		return;
60 
61 	CX_UNLINK(archive);
62 
63 	if (archive->refCount > 0)
64 		return;
65 
66 	parent = archive->parent;
67 	fp     = archive->fp;
68 
69 	if (archive->module != NULL &&
70 		archive->module->ops.archive->closeArchive != NULL)
71 	{
72 		archive->module->ops.archive->closeArchive(archive);
73 	}
74 
75 	if (!cxIsArchiveLocal(archive) &&
76 	     cxGetArchivePhysicalPath(archive) != NULL)
77 	{
78 		unlink(cxGetArchivePhysicalPath(archive));
79 	}
80 
81 	if (archive->name     != NULL) free(archive->name);
82 	if (archive->path     != NULL) free(archive->path);
83 	if (archive->physPath != NULL) free(archive->physPath);
84 
85 	/* XXX This shouldn't be NULL, but check anyway. */
86 	if (archive->moduleData != NULL)
87 		free(archive->moduleData);
88 
89 	/* Close the associated file pointer. */
90 	cxClose(fp);
91 
92 	cxDestroyDirectory(archive->root);
93 
94 	free(archive);
95 
96 	/* Destroy the parent, if it's not in use. */
97 	if (parent != NULL)
98 		cxDestroyArchive(parent);
99 }
100 
101 void
cxSetArchiveModule(CxArchive * archive,CxModule * module)102 cxSetArchiveModule(CxArchive *archive, CxModule *module)
103 {
104 	if (archive == NULL)
105 		return;
106 
107 	archive->module = module;
108 }
109 
110 void
cxSetArchiveType(CxArchive * archive,CxArchiveType type)111 cxSetArchiveType(CxArchive *archive, CxArchiveType type)
112 {
113 	if (archive == NULL)
114 		return;
115 
116 	archive->type = type;
117 }
118 
119 void
cxSetArchiveAccessMode(CxArchive * archive,CxAccessMode mode)120 cxSetArchiveAccessMode(CxArchive *archive, CxAccessMode mode)
121 {
122 	if (archive == NULL)
123 		return;
124 
125 	archive->accessMode = mode;
126 }
127 
128 void
cxSetArchiveFileName(CxArchive * archive,const char * filename)129 cxSetArchiveFileName(CxArchive *archive, const char *filename)
130 {
131 	if (archive == NULL)
132 		return;
133 
134 	if (archive->name != NULL)
135 		free(archive->name);
136 
137 	archive->name = (filename == NULL ? NULL : strdup(filename));
138 }
139 
140 void
cxSetArchivePath(CxArchive * archive,const char * path)141 cxSetArchivePath(CxArchive *archive, const char *path)
142 {
143 	if (archive == NULL)
144 		return;
145 
146 	if (archive->path != NULL)
147 		free(archive->path);
148 
149 	archive->path = (path == NULL ? NULL : strdup(path));
150 }
151 
152 void
cxSetArchivePhysicalPath(CxArchive * archive,const char * path)153 cxSetArchivePhysicalPath(CxArchive *archive, const char *path)
154 {
155 	if (archive == NULL)
156 		return;
157 
158 	if (archive->physPath != NULL)
159 		free(archive->physPath);
160 
161 	archive->physPath = (path == NULL ? NULL : strdup(path));
162 }
163 
164 void
cxSetArchiveFileSize(CxArchive * archive,unsigned int fileSize)165 cxSetArchiveFileSize(CxArchive *archive, unsigned int fileSize)
166 {
167 	if (archive == NULL)
168 		return;
169 
170 	archive->fileSize = fileSize;
171 }
172 
173 void
cxSetArchiveSize(CxArchive * archive,unsigned int archiveSize)174 cxSetArchiveSize(CxArchive *archive, unsigned int archiveSize)
175 {
176 	if (archive == NULL)
177 		return;
178 
179 	archive->archiveSize = archiveSize;
180 }
181 
182 void
cxSetArchiveLocal(CxArchive * archive,char isLocal)183 cxSetArchiveLocal(CxArchive *archive, char isLocal)
184 {
185 	if (archive == NULL)
186 		return;
187 
188 	archive->isLocal = (isLocal == 0 ? 0 : 1);
189 }
190 
191 void
cxSetArchiveExtractCallback(CxArchive * archive,void (* callback)(CxArchive *,CxFile *,size_t,size_t))192 cxSetArchiveExtractCallback(CxArchive *archive,
193 							void (*callback) (CxArchive *, CxFile *,
194 											  size_t, size_t))
195 {
196 	if (archive == NULL)
197 		return;
198 
199 	archive->ex_callback = callback;
200 }
201 
202 CxModule *
cxGetArchiveModule(CxArchive * archive)203 cxGetArchiveModule(CxArchive *archive)
204 {
205 	if (archive == NULL)
206 		return NULL;
207 
208 	return archive->module;
209 }
210 
211 CxArchiveType
cxGetArchiveType(CxArchive * archive)212 cxGetArchiveType(CxArchive *archive)
213 {
214 	if (archive == NULL)
215 		return CX_ARCHIVE_UNKNOWN;
216 
217 	return archive->type;
218 }
219 
220 CxAccessMode
cxGetArchiveAccessMode(CxArchive * archive)221 cxGetArchiveAccessMode(CxArchive *archive)
222 {
223 	if (archive == NULL)
224 		return CX_MODE_ERROR;
225 
226 	return archive->accessMode;
227 }
228 
229 const char *
cxGetArchiveFileName(CxArchive * archive)230 cxGetArchiveFileName(CxArchive *archive)
231 {
232 	if (archive == NULL)
233 		return NULL;
234 
235 	return archive->name;
236 }
237 
238 const char *
cxGetArchivePath(CxArchive * archive)239 cxGetArchivePath(CxArchive *archive)
240 {
241 	if (archive == NULL)
242 		return NULL;
243 
244 	return archive->path;
245 }
246 
247 const char *
cxGetArchivePhysicalPath(CxArchive * archive)248 cxGetArchivePhysicalPath(CxArchive *archive)
249 {
250 	if (archive == NULL)
251 		return 0;
252 
253 	return archive->physPath;
254 }
255 
256 size_t
cxGetArchiveFileCount(CxArchive * archive)257 cxGetArchiveFileCount(CxArchive *archive)
258 {
259 	if (archive == NULL)
260 		return 0;
261 
262 	return archive->fileCount;
263 }
264 
265 unsigned int
cxGetArchiveFileSize(CxArchive * archive)266 cxGetArchiveFileSize(CxArchive *archive)
267 {
268 	if (archive == NULL)
269 		return 0;
270 
271 	return archive->fileSize;
272 }
273 
274 unsigned int
cxGetArchiveSize(CxArchive * archive)275 cxGetArchiveSize(CxArchive *archive)
276 {
277 	if (archive == NULL)
278 		return 0;
279 
280 	return archive->archiveSize;
281 }
282 
283 char
cxIsArchiveLocal(CxArchive * archive)284 cxIsArchiveLocal(CxArchive *archive)
285 {
286 	if (archive == NULL)
287 		return 0;
288 
289 	return archive->isLocal;
290 }
291 
292 CxDirectory *
cxGetArchiveRoot(CxArchive * archive)293 cxGetArchiveRoot(CxArchive *archive)
294 {
295 	if (archive == NULL)
296 		return NULL;
297 
298 	return archive->root;
299 }
300 
301