1178825Sdfr/* 2233294Sstas * Copyright (c) 2006 - 2007 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34178825Sdfr#include "hx_locl.h" 35178825Sdfr 36178825Sdfr/** 37178825Sdfr * @page page_error Hx509 error reporting functions 38178825Sdfr * 39178825Sdfr * See the library functions here: @ref hx509_error 40178825Sdfr */ 41178825Sdfr 42178825Sdfrstruct hx509_error_data { 43178825Sdfr hx509_error next; 44178825Sdfr int code; 45178825Sdfr char *msg; 46178825Sdfr}; 47178825Sdfr 48178825Sdfrstatic void 49178825Sdfrfree_error_string(hx509_error msg) 50178825Sdfr{ 51178825Sdfr while(msg) { 52178825Sdfr hx509_error m2 = msg->next; 53178825Sdfr free(msg->msg); 54178825Sdfr free(msg); 55178825Sdfr msg = m2; 56178825Sdfr } 57178825Sdfr} 58178825Sdfr 59178825Sdfr/** 60178825Sdfr * Resets the error strings the hx509 context. 61178825Sdfr * 62178825Sdfr * @param context A hx509 context. 63178825Sdfr * 64178825Sdfr * @ingroup hx509_error 65178825Sdfr */ 66178825Sdfr 67178825Sdfrvoid 68178825Sdfrhx509_clear_error_string(hx509_context context) 69178825Sdfr{ 70233294Sstas if (context) { 71233294Sstas free_error_string(context->error); 72233294Sstas context->error = NULL; 73233294Sstas } 74178825Sdfr} 75178825Sdfr 76178825Sdfr/** 77178825Sdfr * Add an error message to the hx509 context. 78178825Sdfr * 79178825Sdfr * @param context A hx509 context. 80178825Sdfr * @param flags 81178825Sdfr * - HX509_ERROR_APPEND appends the error string to the old messages 82178825Sdfr (code is updated). 83178825Sdfr * @param code error code related to error message 84178825Sdfr * @param fmt error message format 85178825Sdfr * @param ap arguments to error message format 86178825Sdfr * 87178825Sdfr * @ingroup hx509_error 88178825Sdfr */ 89178825Sdfr 90178825Sdfrvoid 91233294Sstashx509_set_error_stringv(hx509_context context, int flags, int code, 92178825Sdfr const char *fmt, va_list ap) 93178825Sdfr{ 94178825Sdfr hx509_error msg; 95178825Sdfr 96233294Sstas if (context == NULL) 97233294Sstas return; 98233294Sstas 99178825Sdfr msg = calloc(1, sizeof(*msg)); 100178825Sdfr if (msg == NULL) { 101178825Sdfr hx509_clear_error_string(context); 102178825Sdfr return; 103178825Sdfr } 104178825Sdfr 105178825Sdfr if (vasprintf(&msg->msg, fmt, ap) == -1) { 106178825Sdfr hx509_clear_error_string(context); 107178825Sdfr free(msg); 108178825Sdfr return; 109178825Sdfr } 110178825Sdfr msg->code = code; 111178825Sdfr 112178825Sdfr if (flags & HX509_ERROR_APPEND) { 113178825Sdfr msg->next = context->error; 114178825Sdfr context->error = msg; 115178825Sdfr } else { 116178825Sdfr free_error_string(context->error); 117178825Sdfr context->error = msg; 118178825Sdfr } 119178825Sdfr} 120178825Sdfr 121178825Sdfr/** 122233294Sstas * See hx509_set_error_stringv(). 123178825Sdfr * 124178825Sdfr * @param context A hx509 context. 125178825Sdfr * @param flags 126178825Sdfr * - HX509_ERROR_APPEND appends the error string to the old messages 127178825Sdfr (code is updated). 128178825Sdfr * @param code error code related to error message 129178825Sdfr * @param fmt error message format 130178825Sdfr * @param ... arguments to error message format 131178825Sdfr * 132178825Sdfr * @ingroup hx509_error 133178825Sdfr */ 134178825Sdfr 135178825Sdfrvoid 136178825Sdfrhx509_set_error_string(hx509_context context, int flags, int code, 137178825Sdfr const char *fmt, ...) 138178825Sdfr{ 139178825Sdfr va_list ap; 140178825Sdfr 141178825Sdfr va_start(ap, fmt); 142178825Sdfr hx509_set_error_stringv(context, flags, code, fmt, ap); 143178825Sdfr va_end(ap); 144178825Sdfr} 145178825Sdfr 146178825Sdfr/** 147178825Sdfr * Get an error string from context associated with error_code. 148178825Sdfr * 149178825Sdfr * @param context A hx509 context. 150178825Sdfr * @param error_code Get error message for this error code. 151178825Sdfr * 152178825Sdfr * @return error string, free with hx509_free_error_string(). 153178825Sdfr * 154178825Sdfr * @ingroup hx509_error 155178825Sdfr */ 156178825Sdfr 157178825Sdfrchar * 158178825Sdfrhx509_get_error_string(hx509_context context, int error_code) 159178825Sdfr{ 160178825Sdfr struct rk_strpool *p = NULL; 161178825Sdfr hx509_error msg = context->error; 162178825Sdfr 163178825Sdfr if (msg == NULL || msg->code != error_code) { 164178825Sdfr const char *cstr; 165178825Sdfr char *str; 166178825Sdfr 167178825Sdfr cstr = com_right(context->et_list, error_code); 168178825Sdfr if (cstr) 169178825Sdfr return strdup(cstr); 170178825Sdfr cstr = strerror(error_code); 171178825Sdfr if (cstr) 172178825Sdfr return strdup(cstr); 173178825Sdfr if (asprintf(&str, "<unknown error: %d>", error_code) == -1) 174178825Sdfr return NULL; 175178825Sdfr return str; 176178825Sdfr } 177178825Sdfr 178178825Sdfr for (msg = context->error; msg; msg = msg->next) 179233294Sstas p = rk_strpoolprintf(p, "%s%s", msg->msg, 180178825Sdfr msg->next != NULL ? "; " : ""); 181178825Sdfr 182178825Sdfr return rk_strpoolcollect(p); 183178825Sdfr} 184178825Sdfr 185178825Sdfr/** 186178825Sdfr * Free error string returned by hx509_get_error_string(). 187178825Sdfr * 188178825Sdfr * @param str error string to free. 189178825Sdfr * 190178825Sdfr * @ingroup hx509_error 191178825Sdfr */ 192178825Sdfr 193178825Sdfrvoid 194178825Sdfrhx509_free_error_string(char *str) 195178825Sdfr{ 196178825Sdfr free(str); 197178825Sdfr} 198178825Sdfr 199178825Sdfr/** 200178825Sdfr * Print error message and fatally exit from error code 201178825Sdfr * 202178825Sdfr * @param context A hx509 context. 203178825Sdfr * @param exit_code exit() code from process. 204178825Sdfr * @param error_code Error code for the reason to exit. 205178825Sdfr * @param fmt format string with the exit message. 206178825Sdfr * @param ... argument to format string. 207178825Sdfr * 208178825Sdfr * @ingroup hx509_error 209178825Sdfr */ 210178825Sdfr 211178825Sdfrvoid 212233294Sstashx509_err(hx509_context context, int exit_code, 213178825Sdfr int error_code, const char *fmt, ...) 214178825Sdfr{ 215178825Sdfr va_list ap; 216178825Sdfr const char *msg; 217178825Sdfr char *str; 218178825Sdfr 219178825Sdfr va_start(ap, fmt); 220178825Sdfr vasprintf(&str, fmt, ap); 221178825Sdfr va_end(ap); 222178825Sdfr msg = hx509_get_error_string(context, error_code); 223178825Sdfr if (msg == NULL) 224178825Sdfr msg = "no error"; 225178825Sdfr 226178825Sdfr errx(exit_code, "%s: %s", str, msg); 227178825Sdfr} 228