error.c revision 178825
1109998Smarkm/* 2280304Sjkim * Copyright (c) 2006 - 2007 Kungliga Tekniska H�gskolan 3280304Sjkim * (Royal Institute of Technology, Stockholm, Sweden). 4280304Sjkim * All rights reserved. 5109998Smarkm * 6109998Smarkm * Redistribution and use in source and binary forms, with or without 7160814Ssimon * modification, are permitted provided that the following conditions 8109998Smarkm * are met: 9109998Smarkm * 10109998Smarkm * 1. Redistributions of source code must retain the above copyright 11109998Smarkm * notice, this list of conditions and the following disclaimer. 12109998Smarkm * 13109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 14280304Sjkim * notice, this list of conditions and the following disclaimer in the 15109998Smarkm * documentation and/or other materials provided with the distribution. 16109998Smarkm * 17109998Smarkm * 3. Neither the name of the Institute nor the names of its contributors 18109998Smarkm * may be used to endorse or promote products derived from this software 19109998Smarkm * without specific prior written permission. 20109998Smarkm * 21109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22109998Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24109998Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25109998Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26109998Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27109998Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29109998Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30109998Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31109998Smarkm * SUCH DAMAGE. 32109998Smarkm */ 33109998Smarkm 34109998Smarkm#include "hx_locl.h" 35109998SmarkmRCSID("$Id: error.c 22332 2007-12-17 01:03:22Z lha $"); 36109998Smarkm 37109998Smarkm/** 38109998Smarkm * @page page_error Hx509 error reporting functions 39109998Smarkm * 40109998Smarkm * See the library functions here: @ref hx509_error 41109998Smarkm */ 42109998Smarkm 43109998Smarkmstruct hx509_error_data { 44109998Smarkm hx509_error next; 45109998Smarkm int code; 46109998Smarkm char *msg; 47109998Smarkm}; 48109998Smarkm 49109998Smarkmstatic void 50109998Smarkmfree_error_string(hx509_error msg) 51109998Smarkm{ 52109998Smarkm while(msg) { 53109998Smarkm hx509_error m2 = msg->next; 54109998Smarkm free(msg->msg); 55109998Smarkm free(msg); 56109998Smarkm msg = m2; 57109998Smarkm } 58109998Smarkm} 59160814Ssimon 60160814Ssimon/** 61280304Sjkim * Resets the error strings the hx509 context. 62160814Ssimon * 63160814Ssimon * @param context A hx509 context. 64109998Smarkm * 65109998Smarkm * @ingroup hx509_error 66280304Sjkim */ 67109998Smarkm 68280304Sjkimvoid 69111147Snectarhx509_clear_error_string(hx509_context context) 70280304Sjkim{ 71280304Sjkim free_error_string(context->error); 72280304Sjkim context->error = NULL; 73111147Snectar} 74280304Sjkim 75280304Sjkim/** 76280304Sjkim * Add an error message to the hx509 context. 77280304Sjkim * 78280304Sjkim * @param context A hx509 context. 79280304Sjkim * @param flags 80280304Sjkim * - HX509_ERROR_APPEND appends the error string to the old messages 81280304Sjkim (code is updated). 82280304Sjkim * @param code error code related to error message 83280304Sjkim * @param fmt error message format 84280304Sjkim * @param ap arguments to error message format 85280304Sjkim * 86280304Sjkim * @ingroup hx509_error 87280304Sjkim */ 88280304Sjkim 89280304Sjkimvoid 90280304Sjkimhx509_set_error_stringv(hx509_context context, int flags, int code, 91280304Sjkim const char *fmt, va_list ap) 92280304Sjkim{ 93280304Sjkim hx509_error msg; 94280304Sjkim 95109998Smarkm msg = calloc(1, sizeof(*msg)); 96280304Sjkim if (msg == NULL) { 97280304Sjkim hx509_clear_error_string(context); 98160814Ssimon return; 99280304Sjkim } 100238405Sjkim 101109998Smarkm if (vasprintf(&msg->msg, fmt, ap) == -1) { 102109998Smarkm hx509_clear_error_string(context); 103109998Smarkm free(msg); 104109998Smarkm return; 105280304Sjkim } 106280304Sjkim msg->code = code; 107280304Sjkim 108280304Sjkim if (flags & HX509_ERROR_APPEND) { 109280304Sjkim msg->next = context->error; 110280304Sjkim context->error = msg; 111280304Sjkim } else { 112280304Sjkim free_error_string(context->error); 113280304Sjkim context->error = msg; 114280304Sjkim } 115280304Sjkim} 116280304Sjkim 117280304Sjkim/** 118280304Sjkim * See hx509_set_error_stringv(). 119280304Sjkim * 120109998Smarkm * @param context A hx509 context. 121280304Sjkim * @param flags 122280304Sjkim * - HX509_ERROR_APPEND appends the error string to the old messages 123109998Smarkm (code is updated). 124280304Sjkim * @param code error code related to error message 125280304Sjkim * @param fmt error message format 126280304Sjkim * @param ... arguments to error message format 127280304Sjkim * 128280304Sjkim * @ingroup hx509_error 129280304Sjkim */ 130280304Sjkim 131109998Smarkmvoid 132109998Smarkmhx509_set_error_string(hx509_context context, int flags, int code, 133280304Sjkim const char *fmt, ...) 134280304Sjkim{ 135109998Smarkm va_list ap; 136280304Sjkim 137280304Sjkim va_start(ap, fmt); 138280304Sjkim hx509_set_error_stringv(context, flags, code, fmt, ap); 139280304Sjkim va_end(ap); 140280304Sjkim} 141280304Sjkim 142280304Sjkim/** 143109998Smarkm * Get an error string from context associated with error_code. 144280304Sjkim * 145280304Sjkim * @param context A hx509 context. 146280304Sjkim * @param error_code Get error message for this error code. 147280304Sjkim * 148280304Sjkim * @return error string, free with hx509_free_error_string(). 149280304Sjkim * 150280304Sjkim * @ingroup hx509_error 151280304Sjkim */ 152280304Sjkim 153280304Sjkimchar * 154280304Sjkimhx509_get_error_string(hx509_context context, int error_code) 155109998Smarkm{ 156280304Sjkim struct rk_strpool *p = NULL; 157280304Sjkim hx509_error msg = context->error; 158280304Sjkim 159280304Sjkim if (msg == NULL || msg->code != error_code) { 160238405Sjkim const char *cstr; 161238405Sjkim char *str; 162280304Sjkim 163238405Sjkim cstr = com_right(context->et_list, error_code); 164280304Sjkim if (cstr) 165280304Sjkim return strdup(cstr); 166280304Sjkim cstr = strerror(error_code); 167280304Sjkim if (cstr) 168280304Sjkim return strdup(cstr); 169280304Sjkim if (asprintf(&str, "<unknown error: %d>", error_code) == -1) 170280304Sjkim return NULL; 171280304Sjkim return str; 172280304Sjkim } 173280304Sjkim 174280304Sjkim for (msg = context->error; msg; msg = msg->next) 175109998Smarkm p = rk_strpoolprintf(p, "%s%s", msg->msg, 176109998Smarkm msg->next != NULL ? "; " : ""); 177280304Sjkim 178280304Sjkim return rk_strpoolcollect(p); 179280304Sjkim} 180280304Sjkim 181280304Sjkim/** 182280304Sjkim * Free error string returned by hx509_get_error_string(). 183280304Sjkim * 184280304Sjkim * @param str error string to free. 185280304Sjkim * 186280304Sjkim * @ingroup hx509_error 187280304Sjkim */ 188280304Sjkim 189280304Sjkimvoid 190109998Smarkmhx509_free_error_string(char *str) 191280304Sjkim{ 192280304Sjkim free(str); 193280304Sjkim} 194109998Smarkm 195280304Sjkim/** 196280304Sjkim * Print error message and fatally exit from error code 197280304Sjkim * 198280304Sjkim * @param context A hx509 context. 199280304Sjkim * @param exit_code exit() code from process. 200280304Sjkim * @param error_code Error code for the reason to exit. 201280304Sjkim * @param fmt format string with the exit message. 202280304Sjkim * @param ... argument to format string. 203280304Sjkim * 204280304Sjkim * @ingroup hx509_error 205109998Smarkm */ 206280304Sjkim 207280304Sjkimvoid 208280304Sjkimhx509_err(hx509_context context, int exit_code, 209280304Sjkim int error_code, const char *fmt, ...) 210280304Sjkim{ 211280304Sjkim va_list ap; 212280304Sjkim const char *msg; 213280304Sjkim char *str; 214280304Sjkim 215280304Sjkim va_start(ap, fmt); 216280304Sjkim vasprintf(&str, fmt, ap); 217280304Sjkim va_end(ap); 218280304Sjkim msg = hx509_get_error_string(context, error_code); 219280304Sjkim if (msg == NULL) 220280304Sjkim msg = "no error"; 221280304Sjkim 222280304Sjkim errx(exit_code, "%s: %s", str, msg); 223280304Sjkim} 224280304Sjkim