1 
2 /*
3  * Author:
4  *      Guido Draheim <guidod@gmx.de>
5  *      Tomi Ollila <Tomi.Ollila@iki.fi>
6  *
7  *      Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
8  *          All rights reserved,
9  *          use under the restrictions of the
10  *          Lesser GNU General Public License
11  *          or alternatively the restrictions
12  *          of the Mozilla Public License 1.1
13  */
14 
15 #define _CRT_SECURE_NO_WARNINGS
16 
17 #include <zzip/lib.h>           /* exported... */
18 #include <zlib.h>
19 
20 #include <string.h>
21 #include <errno.h>
22 
23 #include <zzip/file.h>
24 
25 /* *INDENT-OFF* */
26 static struct errlistentry { int code; const char* mesg; }
27 errlist[] =
28 {
29     { ZZIP_NO_ERROR,        "No error" },
30     { ZZIP_OUTOFMEM,
31       "could not get temporary memory for internal structures" },
32     { ZZIP_DIR_OPEN,        "Failed to open zip-file %s" },
33     { ZZIP_DIR_STAT,        "Failed to fstat zip-file %s" },
34     { ZZIP_DIR_SEEK,        "Failed to lseek zip-file %s" },
35     { ZZIP_DIR_READ,        "Failed to read zip-file %s"},
36     { ZZIP_DIR_TOO_SHORT,   "zip-file %s too short" },
37     { ZZIP_DIR_EDH_MISSING, "zip-file central directory not found" },
38     { ZZIP_DIRSIZE,         "Directory size too big..." },
39     { ZZIP_ENOENT,          "No such file found in zip-file %s" },
40     { ZZIP_UNSUPP_COMPR,    "Unsupported compression format" },
41     { ZZIP_CORRUPTED,       "Zipfile corrupted" },
42     { ZZIP_UNDEF,           "Some undefined error occurred" },
43     { ZZIP_DIR_LARGEFILE,   "Directory is largefile variant" },
44     { 0, 0 },
45 };
46 /* *INDENT-ON* */
47 
48 
49 #define errlistSIZE (sizeof(errlist)/sizeof(*errlist))
50 
51 /**
52  * returns the static string for the given error code. The
53  * error code can be either a normal system error (a
54  * positive error code will flag this), it can be => libz
55  * error code (a small negative error code will flag this)
56  * or it can be an error code from => libzzip, which is an
57  * negative value lower than => ZZIP_ERROR
58  */
59 zzip_char_t *
zzip_strerror(int errcode)60 zzip_strerror(int errcode)
61 {
62     if (errcode < ZZIP_ERROR && errcode > ZZIP_ERROR - 32)
63     {
64         struct errlistentry *err = errlist;
65 
66         for (; err->mesg; err++)
67         {
68             if (err->code == errcode)
69                 return err->mesg;
70         }
71         errcode = EINVAL;
72     }
73 
74     if (errcode < 0)
75     {
76         if (errcode == -1)
77             return strerror(errcode);
78         else
79             return zError(errcode);
80     }
81 
82     return strerror(errcode);
83 }
84 
85 /** => zzip_strerror
86  * This function fetches the errorcode from the => DIR-handle and
87  * runs it through => zzip_strerror to obtain the static string
88  * describing the error.
89  */
90 zzip_char_t *
zzip_strerror_of(ZZIP_DIR * dir)91 zzip_strerror_of(ZZIP_DIR * dir)
92 {
93     if (! dir)
94         return strerror(errno);
95     return zzip_strerror(dir->errcode);
96 }
97 
98 /* *INDENT-OFF* */
99 static struct errnolistentry { int code; int e_no; }
100 errnolist[] =
101 {
102     { Z_STREAM_ERROR, EPIPE },
103     { Z_DATA_ERROR, ESPIPE },
104     { Z_MEM_ERROR, ENOMEM },
105     { Z_BUF_ERROR, EMFILE },
106     { Z_VERSION_ERROR, ENOEXEC },
107 
108     { ZZIP_DIR_OPEN, ENOTDIR },
109     { ZZIP_DIR_STAT, EREMOTE },
110     { ZZIP_DIR_SEEK, ESPIPE },
111 #  ifdef ESTRPIPE
112     { ZZIP_DIR_READ, ESTRPIPE},
113 #  else
114     { ZZIP_DIR_READ, EPIPE},
115 #  endif
116     { ZZIP_DIR_TOO_SHORT, ENOEXEC },
117 #  ifdef ENOMEDIUM
118     { ZZIP_DIR_EDH_MISSING, ENOMEDIUM },
119 #  else
120     { ZZIP_DIR_EDH_MISSING, EIO },
121 #  endif
122     { ZZIP_DIRSIZE, EFBIG },
123     { ZZIP_OUTOFMEM, ENOMEM },
124     { ZZIP_ENOENT, ENOENT },
125 #  ifdef EPFNOSUPPORT
126     { ZZIP_UNSUPP_COMPR, EPFNOSUPPORT },
127 #  else
128     { ZZIP_UNSUPP_COMPR, EACCES },
129 #  endif
130 # ifdef EILSEQ
131     { ZZIP_CORRUPTED, EILSEQ },
132 # else
133     { ZZIP_CORRUPTED, ELOOP },
134 # endif
135     { ZZIP_UNDEF, EINVAL },
136     { 0, 0 },
137 };
138 /* *INDENT-ON* */
139 
140 /**
141  * map the error code to a system error code. This is used
142  * for the drop-in replacement functions to return a value
143  * that can be interpreted correctly by code sections that
144  * are unaware of the fact they their => open(2) call had been
145  * diverted to a file inside a zip-archive.
146  */
147 int
zzip_errno(int errcode)148 zzip_errno(int errcode)
149 {
150     if (errcode >= -1)
151     {
152         return errno;
153     } else
154     {
155         struct errnolistentry *err = errnolist;
156 
157         for (; err->code; err++)
158         {
159             if (err->code == errcode)
160                 return err->e_no;
161         }
162         return EINVAL;
163     }
164 }
165 
166 /*
167  * Local variables:
168  * c-file-style: "stroustrup"
169  * End:
170  */
171