1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/*
* Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <Tomi.Ollila@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* Description:
* although this file is defining a function called zzip_stat it
* will not need a real stat(2) exported by the Operating System.
* It will just try to fill the fields of the ZZIP_STAT structure
* of
*/
#include <zzip/lib.h> /* exported...*/
#include <zzip/file.h>
#include <string.h>
#include <sys/stat.h>
#define ZZIP_USE_INTERNAL
#include <zzip/info.h>
/**
* obtain information about a filename in an opened zip-archive without
* opening that file first. Mostly used to obtain the uncompressed
* size of a file inside a zip-archive. see => zzip_dir_open.
*/
int
zzip_dir_stat(ZZIP_DIR * dir, zzip_char_t* name, ZZIP_STAT * zs, int flags)
{
struct zzip_dir_hdr * hdr = dir->hdr0;
int (*cmp)(zzip_char_t*, zzip_char_t*);
cmp = (flags & ZZIP_CASEINSENSITIVE) ? strcasecmp : strcmp;
if (flags & ZZIP_IGNOREPATH)
{
char* n = strrchr(name, '/');
if (n) name = n + 1;
}
if (hdr)
while (1)
{
register char* hdr_name = hdr->d_name;
if (flags & ZZIP_IGNOREPATH)
{
register char* n = strrchr(hdr_name, '/');
if (n) hdr_name = n + 1;
}
if (! cmp(hdr_name, name))
break;
if (! hdr->d_reclen)
{
dir->errcode = ZZIP_ENOENT;
return -1;
}
hdr = (struct zzip_dir_hdr *) ((char *)hdr + hdr->d_reclen);
}
zs->d_compr = hdr->d_compr;
zs->d_csize = hdr->d_csize;
zs->st_size = hdr->d_usize;
zs->d_name = hdr->d_name;
return 0;
}
/** => zzip_dir_stat
* This function will obtain information about a opened file _within_ a
* zip-archive. The file is supposed to be open (otherwise -1 is returned).
* The st_size stat-member contains the uncompressed size. The optional
* d_name is never set here.
*/
int zzip_file_stat (ZZIP_FILE* file, ZZIP_STAT* zs)
{
if (! file) return -1;
zs->d_compr = file->method;
zs->d_csize = file->csize;
zs->st_size = file->usize;
zs->d_name = 0;
return 0;
}
/** => zzip_dir_stat
* This function will obtain information about a opened file which may be
* either real/zipped. The file is supposed to be open (otherwise -1 is
* returned). The st_size stat-member contains the uncompressed size.
* The optional d_name is never set here. For a real file, we do set the
* d_csize := st_size and d_compr := 0 for meaningful defaults.
*/
int zzip_fstat (ZZIP_FILE* file, ZZIP_STAT* zs)
{
if (ZZIP_file_real(file))
{
struct stat st;
if (fstat (file->fd, &st) < 0) return -1;
zs->st_size = st.st_size;
zs->d_csize = st.st_size;
zs->d_compr = 0;
return 0;
}else{
return zzip_file_stat (file, zs);
}
}
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/
|