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