src/error.c
branchnew-lib-errors
changeset 216 a10ba529ae39
parent 215 85863b89e38b
child 217 7728d6ec3abf
equal deleted inserted replaced
215:85863b89e38b 216:a10ba529ae39
     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