summaryrefslogtreecommitdiff
path: root/Build/source/libs/zziplib/zziplib-0.13.58/zzip/stat.c
blob: 1c9428357b115d301515c33301bf117ccc760276 (plain)
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
120
121
122
123
124
125
126
127
128
129
130
131
132

/*
 * 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 (! hdr)
    {
        dir->errcode = ZZIP_ENOENT;
        return -1;
    }

    if (flags & ZZIP_IGNOREPATH)
    {
        char *n = strrchr(name, '/');
        if (n)
            name = n + 1;
    }

    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:
 */