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