150764Smarkm/*
2233294Sstas * Copyright (c) 1997 - 2002 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
550764Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
950764Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1250764Smarkm *
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.
1650764Smarkm *
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.
2050764Smarkm *
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.
3250764Smarkm */
3350764Smarkm
34233294Sstas
3550764Smarkm#include <stdio.h>
3650764Smarkm#include <stdlib.h>
3750764Smarkm#include <string.h>
3850764Smarkm#include "com_err.h"
3950764Smarkm
40127807Snectarstruct et_list *_et_list = NULL;
4150764Smarkm
4250764Smarkm
43233294SstasKRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
4450764Smarkmerror_message (long code)
4550764Smarkm{
4650764Smarkm    static char msg[128];
4750764Smarkm    const char *p = com_right(_et_list, code);
48127807Snectar    if (p == NULL) {
49127807Snectar	if (code < 0)
50178846Sdfr	    snprintf(msg, sizeof(msg), "Unknown error %ld", code);
51127807Snectar	else
52127807Snectar	    p = strerror(code);
53127807Snectar    }
5450764Smarkm    if (p != NULL && *p != '\0') {
55178846Sdfr	strlcpy(msg, p, sizeof(msg));
56233294Sstas    } else
57178846Sdfr	snprintf(msg, sizeof(msg), "Unknown error %ld", code);
5850764Smarkm    return msg;
5950764Smarkm}
6050764Smarkm
61233294SstasKRB5_LIB_FUNCTION int KRB5_LIB_CALL
6250764Smarkminit_error_table(const char **msgs, long base, int count)
6350764Smarkm{
6450764Smarkm    initialize_error_table_r(&_et_list, msgs, count, base);
6550764Smarkm    return 0;
6650764Smarkm}
6750764Smarkm
68233294Sstasstatic void KRB5_CALLCONV
6950764Smarkmdefault_proc (const char *whoami, long code, const char *fmt, va_list args)
70127807Snectar    __attribute__((__format__(__printf__, 3, 0)));
71233294Sstas
72233294Sstasstatic void KRB5_CALLCONV
73127807Snectardefault_proc (const char *whoami, long code, const char *fmt, va_list args)
7450764Smarkm{
7550764Smarkm    if (whoami)
7650764Smarkm      fprintf(stderr, "%s: ", whoami);
7750764Smarkm    if (code)
7850764Smarkm      fprintf(stderr, "%s ", error_message(code));
7950764Smarkm    if (fmt)
8050764Smarkm      vfprintf(stderr, fmt, args);
8150764Smarkm    fprintf(stderr, "\r\n");	/* ??? */
8250764Smarkm}
8350764Smarkm
8450764Smarkmstatic errf com_err_hook = default_proc;
8550764Smarkm
86233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL
87233294Sstascom_err_va (const char *whoami,
88233294Sstas	    long code,
89233294Sstas	    const char *fmt,
9050764Smarkm	    va_list args)
9150764Smarkm{
9250764Smarkm    (*com_err_hook) (whoami, code, fmt, args);
9350764Smarkm}
9450764Smarkm
95233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL
9650764Smarkmcom_err (const char *whoami,
9750764Smarkm	 long code,
98233294Sstas	 const char *fmt,
9950764Smarkm	 ...)
10050764Smarkm{
10150764Smarkm    va_list ap;
10250764Smarkm    va_start(ap, fmt);
10350764Smarkm    com_err_va (whoami, code, fmt, ap);
10450764Smarkm    va_end(ap);
10550764Smarkm}
10650764Smarkm
107233294SstasKRB5_LIB_FUNCTION errf KRB5_LIB_CALL
10850764Smarkmset_com_err_hook (errf new)
10950764Smarkm{
11050764Smarkm    errf old = com_err_hook;
11150764Smarkm
11250764Smarkm    if (new)
11350764Smarkm	com_err_hook = new;
11450764Smarkm    else
11550764Smarkm	com_err_hook = default_proc;
116233294Sstas
11750764Smarkm    return old;
11850764Smarkm}
11950764Smarkm
120233294SstasKRB5_LIB_FUNCTION errf KRB5_LIB_CALL
121233294Sstasreset_com_err_hook (void)
12250764Smarkm{
12350764Smarkm    return set_com_err_hook(NULL);
12450764Smarkm}
12550764Smarkm
12650764Smarkm#define ERRCODE_RANGE   8       /* # of bits to shift table number */
12750764Smarkm#define BITS_PER_CHAR   6       /* # bits to shift per character in name */
12850764Smarkm
12950764Smarkmstatic const char char_set[] =
13050764Smarkm        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
13150764Smarkm
13250764Smarkmstatic char buf[6];
13350764Smarkm
134233294SstasKRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
13550764Smarkmerror_table_name(int num)
13650764Smarkm{
13750764Smarkm    int ch;
13850764Smarkm    int i;
13950764Smarkm    char *p;
14050764Smarkm
14150764Smarkm    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
14250764Smarkm    p = buf;
14350764Smarkm    num >>= ERRCODE_RANGE;
14450764Smarkm    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
14550764Smarkm    num &= 077777777;
14650764Smarkm    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
14750764Smarkm    for (i = 4; i >= 0; i--) {
14850764Smarkm        ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
14950764Smarkm        if (ch != 0)
15050764Smarkm            *p++ = char_set[ch-1];
15150764Smarkm    }
15250764Smarkm    *p = '\0';
15350764Smarkm    return(buf);
15450764Smarkm}
155127807Snectar
156233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL
157127807Snectaradd_to_error_table(struct et_list *new_table)
158127807Snectar{
159127807Snectar    struct et_list *et;
160127807Snectar
161127807Snectar    for (et = _et_list; et; et = et->next) {
162127807Snectar	if (et->table->base == new_table->table->base)
163127807Snectar	    return;
164127807Snectar    }
165127807Snectar
166127807Snectar    new_table->next = _et_list;
167127807Snectar    _et_list = new_table;
168127807Snectar}
169