terom@6: terom@6: #include "error.h" terom@6: terom@30: // for the error_desc tables terom@30: #include "sock.h" terom@30: #include "sock_gnutls.h" terom@30: terom@7: #include terom@7: #include terom@7: terom@30: struct error_desc _core_error_desc[] = { terom@31: { ERR_CALLOC, "calloc", ERR_EXTRA_NONE }, terom@37: { ERR_STRDUP, "strdup", ERR_EXTRA_NONE }, terom@31: { ERR_GETADDRINFO, "getaddrinfo", ERR_EXTRA_GAI }, terom@31: { ERR_GETADDRINFO_EMPTY, "getaddrinfo: no results", ERR_EXTRA_NONE }, terom@31: { ERR_EVENT_NEW, "event_new", ERR_EXTRA_NONE }, terom@31: { ERR_EVENT_ADD, "event_add", ERR_EXTRA_NONE }, terom@31: { ERR_EVSQL_NEW_PQ, "evsql_new_pq", ERR_EXTRA_NONE }, terom@31: { _ERR_INVALID, NULL, 0 } terom@7: terom@31: }, _sock_error_desc[] = { terom@31: { ERR_SOCKET, "socket", ERR_EXTRA_ERRNO }, terom@31: { ERR_CONNECT, "connect", ERR_EXTRA_ERRNO }, terom@31: { ERR_READ, "read", ERR_EXTRA_ERRNO }, terom@31: { ERR_READ_EOF, "read: EOF", ERR_EXTRA_NONE }, terom@31: { ERR_WRITE, "write", ERR_EXTRA_ERRNO }, terom@31: { ERR_WRITE_EOF, "write: EOF", ERR_EXTRA_NONE }, terom@31: { ERR_FCNTL, "fcntl", ERR_EXTRA_ERRNO }, terom@31: { ERR_CLOSE, "close", ERR_EXTRA_ERRNO }, terom@31: { _ERR_INVALID, NULL, 0 } terom@30: terom@31: }, _sock_gnutls_error_desc[] = { terom@31: { ERR_GNUTLS_CERT_ALLOC_CRED, "gnutls_certificate_allocate_credentials", ERR_EXTRA_GNUTLS }, terom@31: { ERR_GNUTLS_GLOBAL_INIT, "gnutls_global_init", ERR_EXTRA_GNUTLS }, terom@31: { ERR_GNUTLS_SET_DEFAULT_PRIORITY, "gnutls_set_default_priority", ERR_EXTRA_GNUTLS }, terom@31: { ERR_GNUTLS_CRED_SET, "gnutls_credentials_set", ERR_EXTRA_GNUTLS }, terom@31: { ERR_GNUTLS_HANDSHAKE, "gnutls_handshake", ERR_EXTRA_GNUTLS }, terom@31: { ERR_GNUTLS_RECORD_SEND, "gnutls_record_send", ERR_EXTRA_GNUTLS }, terom@31: { ERR_GNUTLS_RECORD_RECV, "gnutls_record_recv", ERR_EXTRA_GNUTLS }, terom@31: { ERR_GNUTLS_RECORD_GET_DIRECTION, "gnutls_record_get_direction", ERR_EXTRA_GNUTLS }, terom@31: { _ERR_INVALID, NULL, 0 } terom@31: terom@37: }, _irc_proto_error_desc[] = { terom@37: { ERR_LINE_TOO_LONG, "IRC line is too long", ERR_EXTRA_NONE }, terom@37: { ERR_LINE_INVALID_TOKEN, "Illegal token value for IRC line", ERR_EXTRA_NONE }, terom@37: { ERR_INVALID_NM, "Invalid nickmask", ERR_EXTRA_NONE }, terom@37: { ERR_INVALID_NICK_LENGTH, "Nickname is too long", ERR_EXTRA_NONE }, terom@37: { _ERR_INVALID, NULL, 0 } terom@30: }; terom@30: terom@30: /** terom@30: * Array of error_desc tables terom@6: */ terom@30: static struct error_desc* _desc_tables[] = { terom@30: _core_error_desc, terom@30: _sock_error_desc, terom@30: _sock_gnutls_error_desc, terom@37: _irc_proto_error_desc, terom@30: NULL terom@30: }; terom@30: terom@30: /** terom@30: * Look up the error_desc for the given error code terom@30: */ terom@30: static const struct error_desc* error_lookup_desc (err_t code) terom@30: { terom@30: struct error_desc **desc_table, *desc = NULL; terom@30: terom@30: // iterate over each defined error_desc array terom@30: for (desc_table = _desc_tables; desc_table; desc_table++) { terom@30: for (desc = *desc_table; desc->code && desc->name; desc++) { terom@30: // compare code terom@30: if (desc->code == code) terom@30: // found terom@30: return desc; terom@30: } terom@30: } terom@30: terom@30: // not found terom@30: return NULL; terom@30: } terom@6: terom@6: const char *error_name (err_t code) terom@6: { terom@30: const struct error_desc *desc; terom@30: terom@30: // do we have an error_desc for it? terom@30: if ((desc = error_lookup_desc(code))) terom@30: return desc->name; terom@30: else terom@30: // unknown terom@30: return "[unknown]"; terom@6: } terom@6: terom@8: const char *error_msg (const struct error_info *err) terom@7: { terom@7: static char msg[ERROR_MSG_MAXLEN]; terom@30: const struct error_desc *desc; terom@30: terom@30: // do we have an error_desc for it? terom@30: if ((desc = error_lookup_desc(err->code)) == NULL) terom@30: // ??? terom@30: snprintf(msg, ERROR_MSG_MAXLEN, "[%#.8x]: %#.8x", err->code, err->extra); terom@30: terom@30: else terom@30: // intrepret .extra terom@30: switch (desc->extra_type) { terom@30: case ERR_EXTRA_NONE: terom@30: // no additional info terom@30: snprintf(msg, ERROR_MSG_MAXLEN, "%s", desc->name); terom@30: break; terom@30: terom@30: case ERR_EXTRA_ERRNO: terom@30: // strerror terom@30: snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, strerror(err->extra)); terom@30: break; terom@30: terom@30: case ERR_EXTRA_GAI: terom@30: // gai_strerror terom@30: snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gai_strerror(err->extra)); terom@30: break; terom@30: terom@30: case ERR_EXTRA_GNUTLS: terom@30: // gnutls_strerror terom@30: snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gnutls_strerror(err->extra)); terom@30: break; terom@30: terom@30: default: terom@30: // ??? terom@30: snprintf(msg, ERROR_MSG_MAXLEN, "%s: %#.8x", desc->name, err->extra); terom@30: break; terom@30: } terom@7: terom@7: // return static pointer terom@7: return msg; terom@7: } terom@7: