X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=lib%2Ferr.c;h=854a4a904c66e1ba3e4f81e7150166f3a154e46b;hb=a64a823a8759a7a7223d4ca1a0f0af0bb1d616fa;hp=66c5d94fb13153d8aec65b9b2d0e3af83b84d25f;hpb=aa354bb116fb38c9b049070dea4752afe9a3ea34;p=libradsec.git diff --git a/lib/err.c b/lib/err.c index 66c5d94..854a4a9 100644 --- a/lib/err.c +++ b/lib/err.c @@ -1,72 +1,214 @@ +/* Copyright 2010, 2011 NORDUnet A/S. All rights reserved. + See LICENSE for licensing information. */ + +#if defined HAVE_CONFIG_H +#include +#endif + +#include +#include +#include #include -#include "libradsec.h" -#include "libradsec-impl.h" - -const char *_errtxt[] = { - "SUCCESS", /* 0 RSE_OK */ - "NOMEM", /* 1 RSE_NOMEM */ - "NYI -- not yet implemented", /* 2 RSE_NOSYS */ - "invalid handle" /* 3 RSE_INVALID_CTX */ - "invalid connection" /* 4 RSE_INVALID_CONN */ - "ERR 5" /* RSE_ */ - "ERR 6" /* RSE_ */ - "ERR 7" /* RSE_ */ - "ERR 8" /* RSE_ */ - "ERR 9" /* RSE_ */ - "ERR 10" /* RSE_ */ - "ERR 11" /* RSE_ */ - "ERR 12" /* RSE_ */ - "ERR 13" /* RSE_ */ - "ERR " /* RSE_ */ - "ERR " /* RSE_ */ - "ERR " /* RSE_ */ - "ERR " /* RSE_ */ - "ERR " /* RSE_ */ - "ERR " /* RSE_ */ - "ERR " /* RSE_ */ - "some error" /* 21 RSE_SOME_ERROR */ +#include +#include + +static const char *_errtxt[] = { + "SUCCESS", /* 0 RSE_OK */ + "out of memory", /* 1 RSE_NOMEM */ + "not yet implemented", /* 2 RSE_NOSYS */ + "invalid handle", /* 3 RSE_INVALID_CTX */ + "invalid connection", /* 4 RSE_INVALID_CONN */ + "connection type mismatch", /* 5 RSE_CONN_TYPE_MISMATCH */ + "FreeRadius error", /* 6 RSE_FR */ + "bad hostname or port", /* 7 RSE_BADADDR */ + "no peer configured", /* 8 RSE_NOPEER */ + "libevent error", /* 9 RSE_EVENT */ + "socket error", /* 10 RSE_SOCKERR */ + "invalid configuration file", /* 11 RSE_CONFIG */ + "authentication failed", /* 12 RSE_BADAUTH */ + "internal error", /* 13 RSE_INTERNAL */ + "SSL error", /* 14 RSE_SSLERR */ + "invalid packet", /* 15 RSE_INVALID_PKT */ + "connect timeout", /* 16 RSE_TIMEOUT_CONN */ + "invalid argument", /* 17 RSE_INVAL */ + "I/O timeout", /* 18 RSE_TIMEOUT_IO */ + "timeout", /* 19 RSE_TIMEOUT */ + "peer disconnected", /* 20 RSE_DISCO */ + "resource is in use", /* 21 RSE_INUSE */ + "packet is too small", /* 22 RSE_PACKET_TOO_SMALL */ + "packet is too large", /* 23 RSE_PACKET_TOO_LARGE */ + "attribute overflows packet", /* 24 RSE_ATTR_OVERFLOW */ + "attribute is too small", /* 25 RSE_ATTR_TOO_SMALL */ + "attribute is too large", /* 26 RSE_ATTR_TOO_LARGE */ + "unknown attribute", /* 27 RSE_ATTR_UNKNOWN */ + "invalid name for attribute", /* 28 RSE_ATTR_BAD_NAME */ + "invalid value for attribute", /* 29 RSE_ATTR_VALUE_MALFORMED */ + "invalid attribute", /* 30 RSE_ATTR_INVALID */ + "too many attributes in the packet", /* 31 RSE_TOO_MANY_ATTRS */ + "attribute type unknown", /* 32 RSE_ATTR_TYPE_UNKNOWN */ + "invalid message authenticator", /* 33 RSE_MSG_AUTH_LEN */ + "incorrect message authenticator", /* 34 RSE_MSG_AUTH_WRONG */ + "request is required", /* 35 RSE_REQUEST_REQUIRED */ + "invalid request code", /* 36 RSE_REQUEST_CODE_INVALID */ + "incorrect request authenticator", /* 37 RSE_AUTH_VECTOR_WRONG */ + "response code is unsupported", /* 38 RSE_INVALID_RESPONSE_CODE */ + "response ID is invalid", /* 39 RSE_INVALID_RESPONSE_ID */ + "response from the wrong source address", /* 40 RSE_INVALID_RESPONSE_SRC */ + "no packet data", /* 41 RSE_NO_PACKET_DATA */ + "vendor is unknown", /* 42 RSE_VENDOR_UNKNOWN */ + "invalid credentials", /* 43 RSE_CRED */ + "certificate validation error", /* 44 RSE_CERT */ }; +#define ERRTXT_SIZE (sizeof(_errtxt) / sizeof(*_errtxt)) static struct rs_error * -_err_new (unsigned int code, const char *msg) +_err_vcreate (unsigned int code, const char *file, int line, const char *fmt, + va_list args) { - struct rs_error *err; + struct rs_error *err = NULL; - err = malloc (sizeof (struct rs_error)); + err = malloc (sizeof(struct rs_error)); if (err) { - memset (err, 0, sizeof (struct rs_error)); + int n; + memset (err, 0, sizeof(struct rs_error)); err->code = code; - snprintf (err->buf, sizeof (err->buf), "%s: %s", - code < sizeof (_errtxt) / sizeof (*_errtxt) ? - _errtxt[code] : "invalid error index", - msg); + if (fmt) + n = vsnprintf (err->buf, sizeof(err->buf), fmt, args); + else + { + strncpy (err->buf, + err->code < ERRTXT_SIZE ? _errtxt[err->code] : "", + sizeof(err->buf)); + n = strlen (err->buf); + } + if (n >= 0 && file) + { + char *sep = strrchr (file, '/'); + if (sep) + file = sep + 1; + snprintf (err->buf + n, sizeof(err->buf) - n, " (%s:%d)", file, + line); + } } return err; } +struct rs_error * +err_create (unsigned int code, + const char *file, + int line, + const char *fmt, + ...) +{ + struct rs_error *err = NULL; + + va_list args; + va_start (args, fmt); + err = _err_vcreate (code, file, line, fmt, args); + va_end (args); + + return err; +} + +static int +_ctx_err_vpush_fl (struct rs_context *ctx, int code, const char *file, + int line, const char *fmt, va_list args) +{ + struct rs_error *err = _err_vcreate (code, file, line, fmt, args); + + if (!err) + return RSE_NOMEM; + + /* TODO: Implement a stack. */ + if (ctx->err) + rs_err_free (ctx->err); + ctx->err = err; + + return err->code; +} + int -rs_ctx_err_push (struct rs_handle *ctx, int code, const char *msg) +rs_err_ctx_push (struct rs_context *ctx, int code, const char *fmt, ...) { - struct rs_error *err = _err_new (code, msg); + int r = 0; + va_list args; - if (err) - ctx->err = err; - return code; + va_start (args, fmt); + r = _ctx_err_vpush_fl (ctx, code, NULL, 0, fmt, args); + va_end (args); + + return r; } int -rs_conn_err_push (struct rs_connection *conn, int code, const char *msg) +rs_err_ctx_push_fl (struct rs_context *ctx, int code, const char *file, + int line, const char *fmt, ...) { - struct rs_error *err = _err_new (code, msg); + int r = 0; + va_list args; - if (err) - conn->err = err; - return code; + va_start (args, fmt); + r = _ctx_err_vpush_fl (ctx, code, file, line, fmt, args); + va_end (args); + + return r; +} + +int +err_conn_push_err (struct rs_connection *conn, struct rs_error *err) +{ + assert (conn); + assert (err); + + if (conn->err) + rs_err_free (conn->err); + conn->err = err; /* FIXME: use a stack */ + + return err->code; +} + +static int +_conn_err_vpush_fl (struct rs_connection *conn, int code, const char *file, + int line, const char *fmt, va_list args) +{ + struct rs_error *err = _err_vcreate (code, file, line, fmt, args); + + if (!err) + return RSE_NOMEM; + + return err_conn_push_err (conn, err); +} + +int +rs_err_conn_push (struct rs_connection *conn, int code, const char *fmt, ...) +{ + int r = 0; + + va_list args; + va_start (args, fmt); + r = _conn_err_vpush_fl (conn, code, NULL, 0, fmt, args); + va_end (args); + + return r; +} + +int +rs_err_conn_push_fl (struct rs_connection *conn, int code, const char *file, + int line, const char *fmt, ...) +{ + int r = 0; + + va_list args; + va_start (args, fmt); + r = _conn_err_vpush_fl (conn, code, file, line, fmt, args); + va_end (args); + + return r; } struct rs_error * -rs_ctx_err_pop (struct rs_handle *ctx) +rs_err_ctx_pop (struct rs_context *ctx) { struct rs_error *err; @@ -74,11 +216,12 @@ rs_ctx_err_pop (struct rs_handle *ctx) return NULL; /* FIXME: RSE_INVALID_CTX. */ err = ctx->err; ctx->err = NULL; + return err; } struct rs_error * -rs_conn_err_pop (struct rs_connection *conn) +rs_err_conn_pop (struct rs_connection *conn) { struct rs_error *err; @@ -86,36 +229,48 @@ rs_conn_err_pop (struct rs_connection *conn) return NULL; /* FIXME: RSE_INVALID_CONN */ err = conn->err; conn->err = NULL; + return err; } +int +rs_err_conn_peek_code (struct rs_connection *conn) +{ + if (!conn) + return -1; /* FIXME: RSE_INVALID_CONN */ + if (conn->err) + return conn->err->code; + + return RSE_OK; +} + void rs_err_free (struct rs_error *err) { assert (err); - if (err->msg) - free (err->msg); free (err); } char * rs_err_msg (struct rs_error *err) { - char *msg; - - if (err->msg) - msg = err->msg; - else - msg = strdup (err->buf); + if (!err) + return NULL; - rs_err_free (err); - return msg; + return err->buf; } int -rs_err_code (struct rs_error *err) +rs_err_code (struct rs_error *err, int dofree_flag) { - int code = err->code; - rs_err_free(err); + int code; + + if (!err) + return -1; + code = err->code; + + if (dofree_flag) + rs_err_free (err); + return code; }