1 |
|
2 #include "error.h" |
|
3 |
|
4 // for the error_desc tables |
|
5 #include "sock.h" |
|
6 #include "ssl_internal.h" |
|
7 #include "module.h" |
|
8 |
|
9 #include <string.h> |
|
10 #include <stdio.h> |
|
11 |
|
12 struct error_desc _core_error_desc[] = { |
|
13 { ERR_CALLOC, "calloc", ERR_EXTRA_NONE }, |
|
14 { ERR_STRDUP, "strdup", ERR_EXTRA_NONE }, |
|
15 { ERR_SIGACTION, "sigaction", ERR_EXTRA_ERRNO }, |
|
16 { ERR_ACCESS_READ, "access(R_OK)", ERR_EXTRA_ERRNO }, |
|
17 { ERR_GETADDRINFO, "getaddrinfo", ERR_EXTRA_GAI }, |
|
18 { ERR_GETADDRINFO_EMPTY, "getaddrinfo: no results", ERR_EXTRA_NONE }, |
|
19 { ERR_EVENT_NEW, "event_new", ERR_EXTRA_NONE }, |
|
20 { ERR_EVENT_ADD, "event_add", ERR_EXTRA_NONE }, |
|
21 { ERR_EVSQL_NEW_PQ, "evsql_new_pq", ERR_EXTRA_NONE }, |
|
22 { ERR_EVSQL_QUERY_EXEC, "evsql_query_exec", ERR_EXTRA_NONE }, |
|
23 { ERR_CMD_OPT, "argv", ERR_EXTRA_STR }, |
|
24 { _ERR_INVALID, NULL, 0 } |
|
25 |
|
26 }, _sock_error_desc[] = { |
|
27 { ERR_SOCKET, "socket", ERR_EXTRA_ERRNO }, |
|
28 { ERR_CONNECT, "connect", ERR_EXTRA_ERRNO }, |
|
29 { ERR_READ, "read", ERR_EXTRA_ERRNO }, |
|
30 { ERR_WRITE, "write", ERR_EXTRA_ERRNO }, |
|
31 { ERR_WRITE_EOF, "write: EOF", ERR_EXTRA_NONE }, |
|
32 { ERR_FCNTL, "fcntl", ERR_EXTRA_ERRNO }, |
|
33 { ERR_CLOSE, "close", ERR_EXTRA_ERRNO }, |
|
34 { ERR_GETSOCKOPT, "getsockopt", ERR_EXTRA_ERRNO }, |
|
35 { ERR_OPEN, "open", ERR_EXTRA_ERRNO }, |
|
36 { ERR_ACCEPT, "accept", ERR_EXTRA_ERRNO }, |
|
37 { ERR_BIND, "bind", ERR_EXTRA_ERRNO }, |
|
38 { ERR_LISTEN, "listen", ERR_EXTRA_ERRNO }, |
|
39 { _ERR_INVALID, NULL, 0 } |
|
40 |
|
41 }, _sock_gnutls_error_desc[] = { |
|
42 { ERR_GNUTLS_CERT_ALLOC_CRED, "gnutls_certificate_allocate_credentials", ERR_EXTRA_GNUTLS }, |
|
43 { ERR_GNUTLS_GLOBAL_INIT, "gnutls_global_init", ERR_EXTRA_GNUTLS }, |
|
44 { ERR_GNUTLS_SET_DEFAULT_PRIORITY, "gnutls_set_default_priority", ERR_EXTRA_GNUTLS }, |
|
45 { ERR_GNUTLS_CRED_SET, "gnutls_credentials_set", ERR_EXTRA_GNUTLS }, |
|
46 { ERR_GNUTLS_HANDSHAKE, "gnutls_handshake", ERR_EXTRA_GNUTLS }, |
|
47 { ERR_GNUTLS_RECORD_SEND, "gnutls_record_send", ERR_EXTRA_GNUTLS }, |
|
48 { ERR_GNUTLS_RECORD_RECV, "gnutls_record_recv", ERR_EXTRA_GNUTLS }, |
|
49 { ERR_GNUTLS_RECORD_GET_DIRECTION, "gnutls_record_get_direction", ERR_EXTRA_GNUTLS }, |
|
50 { ERR_GNUTLS_CERT_VERIFY_PEERS2, "gnutls_certificate_verify_peers2", ERR_EXTRA_GNUTLS }, |
|
51 { ERR_GNUTLS_CERT_VERIFY, "X.509 Certificate verification failed", ERR_EXTRA_STR }, |
|
52 { ERR_GNUTLS_CERT_SET_X509_TRUST_FILE,"gnutls_certificate_set_x509_trust_file", ERR_EXTRA_GNUTLS }, |
|
53 { ERR_GNUTLS_CERT_SET_X509_KEY_FILE, "gnutls_certificate_set_x509_key_file", ERR_EXTRA_GNUTLS }, |
|
54 { _ERR_INVALID, NULL, 0 } |
|
55 |
|
56 }, _irc_error_desc[] = { |
|
57 { ERR_LINE_TOO_LONG, "IRC line is too long", ERR_EXTRA_NONE }, |
|
58 { ERR_LINE_INVALID_TOKEN, "Illegal token value for IRC line", ERR_EXTRA_NONE }, |
|
59 { ERR_INVALID_NM, "Invalid nickmask", ERR_EXTRA_NONE }, |
|
60 { ERR_INVALID_NICK_LENGTH, "Nickname is too long", ERR_EXTRA_NONE }, |
|
61 |
|
62 // extra: the name of the invalid field |
|
63 { ERR_IRC_NET_INFO, "invalid irc_net_info", ERR_EXTRA_STR }, |
|
64 { ERR_IRC_NET_STATE, "invalid irc_net state for operation", ERR_EXTRA_NONE }, |
|
65 { ERR_IRC_CHAN_STATE, "invalid irc_chan state for operation", ERR_EXTRA_NONE }, |
|
66 |
|
67 { _ERR_INVALID, NULL, 0 } |
|
68 |
|
69 }, _config_error_desc[] = { |
|
70 { ERR_CONFIG_NAME, "unknown config option", ERR_EXTRA_STR }, |
|
71 { ERR_CONFIG_TYPE, "invalid config type", ERR_EXTRA_NONE }, |
|
72 { ERR_CONFIG_REQUIRED, "missing required value", ERR_EXTRA_STR }, |
|
73 { ERR_CONFIG_VALUE, "invalid value", ERR_EXTRA_STR }, |
|
74 { ERR_CONFIG_PARAMS, "invalid number of paramters", ERR_EXTRA_NONE }, |
|
75 |
|
76 { _ERR_INVALID, NULL, 0 } |
|
77 |
|
78 }, _module_error_desc[] = { |
|
79 { ERR_MODULE_NAME, "invalid module name", ERR_EXTRA_NONE }, |
|
80 { ERR_MODULE_DUP, "module already loaded", ERR_EXTRA_NONE }, |
|
81 { ERR_MODULE_PATH, "invalid module path", ERR_EXTRA_STR }, |
|
82 { ERR_MODULE_OPEN, "module dlopen() failed", ERR_EXTRA_STR }, |
|
83 { ERR_MODULE_SYM, "module dlsym() failed", ERR_EXTRA_STR }, |
|
84 { ERR_MODULE_INIT_FUNC, "invalid module init func", ERR_EXTRA_STR }, |
|
85 { ERR_MODULE_CONF, "module_conf", ERR_EXTRA_STR }, |
|
86 { _ERR_INVALID, NULL, 0 } |
|
87 |
|
88 }, _lua_error_desc[] = { |
|
89 { ERR_LUA_MEM, "lua: out of memory", ERR_EXTRA_STR }, |
|
90 { ERR_LUA_SYNTAX, "lua: syntax error", ERR_EXTRA_STR }, |
|
91 { ERR_LUA_RUN, "lua: runtime error", ERR_EXTRA_STR }, |
|
92 { ERR_LUA_ERR, "lua: error handling error", ERR_EXTRA_STR }, |
|
93 { ERR_LUA_FILE, "lua: error loading file", ERR_EXTRA_STR }, |
|
94 { _ERR_INVALID, NULL, 0 } |
|
95 |
|
96 }, _pcre_error_desc[] = { |
|
97 { ERR_PCRE_COMPILE, "pcre_compile", ERR_EXTRA_STR }, |
|
98 { ERR_PCRE_EXEC, "pcre_exec", ERR_EXTRA_STR }, |
|
99 { _ERR_INVALID, NULL, 0 } |
|
100 }, _general_error_desc[] = { |
|
101 { ERR_MISC, "miscellaneous error", ERR_EXTRA_STR }, |
|
102 { ERR_CMD_OPT, "invalid command line option", ERR_EXTRA_STR }, |
|
103 { ERR_DUP_NAME, "duplicate name", ERR_EXTRA_STR }, |
|
104 { ERR_EOF, "EOF", ERR_EXTRA_NONE }, |
|
105 { ERR_MEM, "memory allocation error", ERR_EXTRA_NONE }, |
|
106 { ERR_NOT_IMPLEMENTED, "function not implemented", ERR_EXTRA_NONE }, |
|
107 { _ERR_INVALID, NULL, 0 } |
|
108 }; |
|
109 |
|
110 /** |
|
111 * Array of error_desc tables |
|
112 */ |
|
113 static struct error_desc* _desc_tables[] = { |
|
114 _core_error_desc, |
|
115 _sock_error_desc, |
|
116 _sock_gnutls_error_desc, |
|
117 _irc_error_desc, |
|
118 _config_error_desc, |
|
119 _module_error_desc, |
|
120 _lua_error_desc, |
|
121 _pcre_error_desc, |
|
122 _general_error_desc, |
|
123 NULL |
|
124 }; |
|
125 |
|
126 const struct error_desc* error_lookup (err_t code) |
|
127 { |
|
128 struct error_desc **desc_table, *desc = NULL; |
|
129 |
|
130 // iterate over each defined error_desc array |
|
131 for (desc_table = _desc_tables; *desc_table; desc_table++) { |
|
132 for (desc = *desc_table; desc->code && desc->name; desc++) { |
|
133 // compare code |
|
134 if (desc->code == code) |
|
135 // found |
|
136 return desc; |
|
137 } |
|
138 } |
|
139 |
|
140 // not found |
|
141 return NULL; |
|
142 } |
|
143 |
|
144 const char *error_name (err_t code) |
|
145 { |
|
146 const struct error_desc *desc; |
|
147 |
|
148 if (!code) |
|
149 // no error... |
|
150 return "success"; |
|
151 |
|
152 else if ((desc = error_lookup(code))) |
|
153 // found an error_desc for it |
|
154 return desc->name; |
|
155 |
|
156 else |
|
157 // unknown |
|
158 return "[unknown]"; |
|
159 } |
|
160 |
|
161 const char *error_msg (const struct error_info *err) |
|
162 { |
|
163 static char msg[ERROR_MSG_MAXLEN]; |
|
164 const struct error_desc *desc; |
|
165 |
|
166 // do we have an error_desc for it? |
|
167 if ((desc = error_lookup(err->code)) == NULL) |
|
168 // ??? |
|
169 snprintf(msg, ERROR_MSG_MAXLEN, "[%#.8x]: %#.8x", err->code, err->extra); |
|
170 |
|
171 else |
|
172 // intrepret .extra |
|
173 switch (desc->extra_type) { |
|
174 case ERR_EXTRA_NONE: |
|
175 // no additional info |
|
176 snprintf(msg, ERROR_MSG_MAXLEN, "%s", desc->name); |
|
177 break; |
|
178 |
|
179 case ERR_EXTRA_ERRNO: |
|
180 // strerror |
|
181 snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, strerror(err->extra)); |
|
182 break; |
|
183 |
|
184 case ERR_EXTRA_GAI: |
|
185 // gai_strerror |
|
186 snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gai_strerror(err->extra)); |
|
187 break; |
|
188 |
|
189 case ERR_EXTRA_GNUTLS: |
|
190 // gnutls_strerror |
|
191 snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gnutls_strerror(err->extra)); |
|
192 break; |
|
193 |
|
194 case ERR_EXTRA_STR: |
|
195 // static error message string |
|
196 snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, err->extra_str); |
|
197 break; |
|
198 |
|
199 default: |
|
200 // ??? |
|
201 snprintf(msg, ERROR_MSG_MAXLEN, "%s: %#.8x", desc->name, err->extra); |
|
202 break; |
|
203 } |
|
204 |
|
205 // return static pointer |
|
206 return msg; |
|
207 } |
|
208 |
|
209 bool error_cmp_eq (const error_t *a, const error_t *b) |
|
210 { |
|
211 const struct error_desc *desc; |
|
212 |
|
213 // compare the top-level code |
|
214 if (a->code != b->code) |
|
215 return false; |
|
216 |
|
217 // lookup the extra type |
|
218 if ((desc = error_lookup(a->code)) == NULL) |
|
219 // not good... |
|
220 return false; |
|
221 |
|
222 // compare by type |
|
223 switch (desc->extra_type) { |
|
224 case ERR_EXTRA_NONE: |
|
225 return true; |
|
226 |
|
227 case ERR_EXTRA_ERRNO: |
|
228 case ERR_EXTRA_GAI: |
|
229 case ERR_EXTRA_GNUTLS: |
|
230 // integer comparison |
|
231 return (a->extra == b->extra); |
|
232 |
|
233 case ERR_EXTRA_STR: |
|
234 // string comparison |
|
235 return a->extra_str && b->extra_str && (strcmp(a->extra_str, b->extra_str) == 0); |
|
236 |
|
237 default: |
|
238 // ??? |
|
239 return false; |
|
240 } |
|
241 } |
|
242 |
|