com_err.c revision 72445
118334Speter/* 290075Sobrien * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan 3132718Skan * (Royal Institute of Technology, Stockholm, Sweden). 418334Speter * All rights reserved. 590075Sobrien * 618334Speter * Redistribution and use in source and binary forms, with or without 790075Sobrien * modification, are permitted provided that the following conditions 890075Sobrien * are met: 990075Sobrien * 1090075Sobrien * 1. Redistributions of source code must retain the above copyright 1118334Speter * notice, this list of conditions and the following disclaimer. 1290075Sobrien * 1390075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1490075Sobrien * notice, this list of conditions and the following disclaimer in the 1590075Sobrien * documentation and/or other materials provided with the distribution. 1618334Speter * 1718334Speter * 3. Neither the name of the Institute nor the names of its contributors 1890075Sobrien * may be used to endorse or promote products derived from this software 1990075Sobrien * without specific prior written permission. 2090075Sobrien * 2118334Speter * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2218334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2318334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2418334Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2518334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2618334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2718334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2818334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2918334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3018334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3118334Speter * SUCH DAMAGE. 3218334Speter */ 3318334Speter 3450397Sobrien#ifdef HAVE_CONFIG_H 3550397Sobrien#include <config.h> 3618334SpeterRCSID("$Id: com_err.c,v 1.15 2000/04/04 22:04:55 assar Exp $"); 3718334Speter#endif 3818334Speter#include <stdio.h> 3918334Speter#include <stdlib.h> 4018334Speter#include <string.h> 4118334Speter#include <roken.h> 4218334Speter#include "com_err.h" 4318334Speter 4418334Speterstruct et_list *_et_list = NULL; 4518334Speter 4618334Speter 47117395Skanconst char * 48117395Skanerror_message (long code) 49117395Skan{ 5018334Speter static char msg[128]; 5118334Speter const char *p = com_right(_et_list, code); 5218334Speter if (p == NULL) 5350397Sobrien p = strerror(code); 54117395Skan if (p != NULL && *p != '\0') { 55117395Skan strncpy(msg, p, sizeof(msg) - 1); 56117395Skan msg[sizeof(msg) - 1] = 0; 57117395Skan } else 58117395Skan sprintf(msg, "Unknown error %ld", code); 59117395Skan return msg; 6018334Speter} 6152284Sobrien 6252284Sobrienint 6352284Sobrieninit_error_table(const char **msgs, long base, int count) 6452284Sobrien{ 6552284Sobrien initialize_error_table_r(&_et_list, msgs, count, base); 6652284Sobrien return 0; 6752284Sobrien} 6818334Speter 69132718Skanstatic void 70132718Skandefault_proc (const char *whoami, long code, const char *fmt, va_list args) 71132718Skan{ 72132718Skan if (whoami) 73132718Skan fprintf(stderr, "%s: ", whoami); 74132718Skan if (code) 75132718Skan fprintf(stderr, "%s ", error_message(code)); 76132718Skan if (fmt) 77132718Skan vfprintf(stderr, fmt, args); 78132718Skan fprintf(stderr, "\r\n"); /* ??? */ 79132718Skan} 80132718Skan 81132718Skanstatic errf com_err_hook = default_proc; 82132718Skan 83132718Skanvoid 84132718Skancom_err_va (const char *whoami, 85132718Skan long code, 86132718Skan const char *fmt, 87132718Skan va_list args) 88132718Skan{ 89132718Skan (*com_err_hook) (whoami, code, fmt, args); 90132718Skan} 91132718Skan 92132718Skanvoid 93132718Skancom_err (const char *whoami, 94132718Skan long code, 9518334Speter const char *fmt, 9690075Sobrien ...) 9790075Sobrien{ 9890075Sobrien va_list ap; 9918334Speter va_start(ap, fmt); 10018334Speter com_err_va (whoami, code, fmt, ap); 10118334Speter va_end(ap); 10250397Sobrien} 10318334Speter 10418334Spetererrf 10518334Speterset_com_err_hook (errf new) 106132718Skan{ 107132718Skan errf old = com_err_hook; 108132718Skan 109132718Skan if (new) 110132718Skan com_err_hook = new; 111132718Skan else 112132718Skan com_err_hook = default_proc; 113132718Skan 114132718Skan return old; 115132718Skan} 116132718Skan 117132718Skanerrf 118132718Skanreset_com_err_hook (void) 119132718Skan{ 120132718Skan return set_com_err_hook(NULL); 121132718Skan} 122132718Skan 123132718Skan#define ERRCODE_RANGE 8 /* # of bits to shift table number */ 124132718Skan#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ 125132718Skan 12618334Speterstatic const char char_set[] = 12718334Speter "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; 12896263Sobrien 12996263Sobrienstatic char buf[6]; 13096263Sobrien 13196263Sobrienconst char * 13296263Sobrienerror_table_name(int num) 13396263Sobrien{ 13496263Sobrien int ch; 13596263Sobrien int i; 13696263Sobrien char *p; 13796263Sobrien 13896263Sobrien /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ 13918334Speter p = buf; 14096263Sobrien num >>= ERRCODE_RANGE; 14196263Sobrien /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ 14296263Sobrien num &= 077777777; 14396263Sobrien /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ 14496263Sobrien for (i = 4; i >= 0; i--) { 14596263Sobrien ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); 14696263Sobrien if (ch != 0) 14796263Sobrien *p++ = char_set[ch-1]; 14896263Sobrien } 14996263Sobrien *p = '\0'; 15096263Sobrien return(buf); 15196263Sobrien} 15218334Speter