xref: /freebsd/contrib/com_err/com_err.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1847a7462SMark Murray /*
2*ae771770SStanislav Sedov  * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
3847a7462SMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4847a7462SMark Murray  * All rights reserved.
5847a7462SMark Murray  *
6847a7462SMark Murray  * Redistribution and use in source and binary forms, with or without
7847a7462SMark Murray  * modification, are permitted provided that the following conditions
8847a7462SMark Murray  * are met:
9847a7462SMark Murray  *
10847a7462SMark Murray  * 1. Redistributions of source code must retain the above copyright
11847a7462SMark Murray  *    notice, this list of conditions and the following disclaimer.
12847a7462SMark Murray  *
13847a7462SMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14847a7462SMark Murray  *    notice, this list of conditions and the following disclaimer in the
15847a7462SMark Murray  *    documentation and/or other materials provided with the distribution.
16847a7462SMark Murray  *
172b2b3720SJacques Vidrine  * 3. Neither the name of the Institute nor the names of its contributors
18847a7462SMark Murray  *    may be used to endorse or promote products derived from this software
19847a7462SMark Murray  *    without specific prior written permission.
20847a7462SMark Murray  *
21847a7462SMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22847a7462SMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23847a7462SMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24847a7462SMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25847a7462SMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26847a7462SMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27847a7462SMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28847a7462SMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29847a7462SMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30847a7462SMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31847a7462SMark Murray  * SUCH DAMAGE.
32847a7462SMark Murray  */
33847a7462SMark Murray 
34*ae771770SStanislav Sedov 
35847a7462SMark Murray #include <stdio.h>
36847a7462SMark Murray #include <stdlib.h>
37847a7462SMark Murray #include <string.h>
38847a7462SMark Murray #include "com_err.h"
39847a7462SMark Murray 
402b2b3720SJacques Vidrine struct et_list *_et_list = NULL;
41847a7462SMark Murray 
42847a7462SMark Murray 
43*ae771770SStanislav Sedov KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
error_message(long code)44847a7462SMark Murray error_message (long code)
45847a7462SMark Murray {
46847a7462SMark Murray     static char msg[128];
47847a7462SMark Murray     const char *p = com_right(_et_list, code);
482b2b3720SJacques Vidrine     if (p == NULL) {
492b2b3720SJacques Vidrine 	if (code < 0)
5057680329SDoug Rabson 	    snprintf(msg, sizeof(msg), "Unknown error %ld", code);
512b2b3720SJacques Vidrine 	else
52847a7462SMark Murray 	    p = strerror(code);
532b2b3720SJacques Vidrine     }
54847a7462SMark Murray     if (p != NULL && *p != '\0') {
5557680329SDoug Rabson 	strlcpy(msg, p, sizeof(msg));
56847a7462SMark Murray     } else
5757680329SDoug Rabson 	snprintf(msg, sizeof(msg), "Unknown error %ld", code);
58847a7462SMark Murray     return msg;
59847a7462SMark Murray }
60847a7462SMark Murray 
61*ae771770SStanislav Sedov KRB5_LIB_FUNCTION int KRB5_LIB_CALL
init_error_table(const char ** msgs,long base,int count)62847a7462SMark Murray init_error_table(const char **msgs, long base, int count)
63847a7462SMark Murray {
64847a7462SMark Murray     initialize_error_table_r(&_et_list, msgs, count, base);
65847a7462SMark Murray     return 0;
66847a7462SMark Murray }
67847a7462SMark Murray 
68*ae771770SStanislav Sedov static void KRB5_CALLCONV
69847a7462SMark Murray default_proc (const char *whoami, long code, const char *fmt, va_list args)
702b2b3720SJacques Vidrine     __attribute__((__format__(__printf__, 3, 0)));
712b2b3720SJacques Vidrine 
72*ae771770SStanislav Sedov static void KRB5_CALLCONV
default_proc(const char * whoami,long code,const char * fmt,va_list args)732b2b3720SJacques Vidrine default_proc (const char *whoami, long code, const char *fmt, va_list args)
74847a7462SMark Murray {
75847a7462SMark Murray     if (whoami)
76847a7462SMark Murray       fprintf(stderr, "%s: ", whoami);
77847a7462SMark Murray     if (code)
78847a7462SMark Murray       fprintf(stderr, "%s ", error_message(code));
79847a7462SMark Murray     if (fmt)
80847a7462SMark Murray       vfprintf(stderr, fmt, args);
81847a7462SMark Murray     fprintf(stderr, "\r\n");	/* ??? */
82847a7462SMark Murray }
83847a7462SMark Murray 
84847a7462SMark Murray static errf com_err_hook = default_proc;
85847a7462SMark Murray 
86*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
com_err_va(const char * whoami,long code,const char * fmt,va_list args)87847a7462SMark Murray com_err_va (const char *whoami,
88847a7462SMark Murray 	    long code,
89847a7462SMark Murray 	    const char *fmt,
90847a7462SMark Murray 	    va_list args)
91847a7462SMark Murray {
92847a7462SMark Murray     (*com_err_hook) (whoami, code, fmt, args);
93847a7462SMark Murray }
94847a7462SMark Murray 
95*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
com_err(const char * whoami,long code,const char * fmt,...)96847a7462SMark Murray com_err (const char *whoami,
97847a7462SMark Murray 	 long code,
98847a7462SMark Murray 	 const char *fmt,
99847a7462SMark Murray 	 ...)
100847a7462SMark Murray {
101847a7462SMark Murray     va_list ap;
102847a7462SMark Murray     va_start(ap, fmt);
103847a7462SMark Murray     com_err_va (whoami, code, fmt, ap);
104847a7462SMark Murray     va_end(ap);
105847a7462SMark Murray }
106847a7462SMark Murray 
107*ae771770SStanislav Sedov KRB5_LIB_FUNCTION errf KRB5_LIB_CALL
set_com_err_hook(errf new)108847a7462SMark Murray set_com_err_hook (errf new)
109847a7462SMark Murray {
110847a7462SMark Murray     errf old = com_err_hook;
111847a7462SMark Murray 
112847a7462SMark Murray     if (new)
113847a7462SMark Murray 	com_err_hook = new;
114847a7462SMark Murray     else
115847a7462SMark Murray 	com_err_hook = default_proc;
116847a7462SMark Murray 
117847a7462SMark Murray     return old;
118847a7462SMark Murray }
119847a7462SMark Murray 
120*ae771770SStanislav Sedov KRB5_LIB_FUNCTION errf KRB5_LIB_CALL
reset_com_err_hook(void)121847a7462SMark Murray reset_com_err_hook (void)
122847a7462SMark Murray {
123847a7462SMark Murray     return set_com_err_hook(NULL);
124847a7462SMark Murray }
125847a7462SMark Murray 
126847a7462SMark Murray #define ERRCODE_RANGE   8       /* # of bits to shift table number */
127847a7462SMark Murray #define BITS_PER_CHAR   6       /* # bits to shift per character in name */
128847a7462SMark Murray 
129847a7462SMark Murray static const char char_set[] =
130847a7462SMark Murray         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
131847a7462SMark Murray 
132847a7462SMark Murray static char buf[6];
133847a7462SMark Murray 
134*ae771770SStanislav Sedov KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
error_table_name(int num)135847a7462SMark Murray error_table_name(int num)
136847a7462SMark Murray {
137847a7462SMark Murray     int ch;
138847a7462SMark Murray     int i;
139847a7462SMark Murray     char *p;
140847a7462SMark Murray 
141847a7462SMark Murray     /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
142847a7462SMark Murray     p = buf;
143847a7462SMark Murray     num >>= ERRCODE_RANGE;
144847a7462SMark Murray     /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
145847a7462SMark Murray     num &= 077777777;
146847a7462SMark Murray     /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
147847a7462SMark Murray     for (i = 4; i >= 0; i--) {
148847a7462SMark Murray         ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
149847a7462SMark Murray         if (ch != 0)
150847a7462SMark Murray             *p++ = char_set[ch-1];
151847a7462SMark Murray     }
152847a7462SMark Murray     *p = '\0';
153847a7462SMark Murray     return(buf);
154847a7462SMark Murray }
1552b2b3720SJacques Vidrine 
156*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
add_to_error_table(struct et_list * new_table)1572b2b3720SJacques Vidrine add_to_error_table(struct et_list *new_table)
1582b2b3720SJacques Vidrine {
1592b2b3720SJacques Vidrine     struct et_list *et;
1602b2b3720SJacques Vidrine 
1612b2b3720SJacques Vidrine     for (et = _et_list; et; et = et->next) {
1622b2b3720SJacques Vidrine 	if (et->table->base == new_table->table->base)
1632b2b3720SJacques Vidrine 	    return;
1642b2b3720SJacques Vidrine     }
1652b2b3720SJacques Vidrine 
1662b2b3720SJacques Vidrine     new_table->next = _et_list;
1672b2b3720SJacques Vidrine     _et_list = new_table;
1682b2b3720SJacques Vidrine }
169