172445Sassar/*
2233294Sstas * Copyright (c) 1997 - 2002 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
572445Sassar *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
972445Sassar *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1272445Sassar *
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.
1672445Sassar *
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.
2072445Sassar *
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.
3272445Sassar */
3372445Sassar
34233294Sstas
3572445Sassar#include <config.h>
36233294Sstas
3772445Sassar#include <stdio.h>
3872445Sassar#include <stdlib.h>
3972445Sassar#include <string.h>
4072445Sassar#include <roken.h>
4172445Sassar#include "com_err.h"
4272445Sassar
4372445Sassarstruct et_list *_et_list = NULL;
4472445Sassar
4572445Sassar
46233294SstasKRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
4772445Sassarerror_message (long code)
4872445Sassar{
4972445Sassar    static char msg[128];
5072445Sassar    const char *p = com_right(_et_list, code);
51102644Snectar    if (p == NULL) {
52102644Snectar	if (code < 0)
53178825Sdfr	    snprintf(msg, sizeof(msg), "Unknown error %ld", code);
54102644Snectar	else
55102644Snectar	    p = strerror(code);
56102644Snectar    }
5772445Sassar    if (p != NULL && *p != '\0') {
58178825Sdfr	strlcpy(msg, p, sizeof(msg));
59233294Sstas    } else
60178825Sdfr	snprintf(msg, sizeof(msg), "Unknown error %ld", code);
6172445Sassar    return msg;
6272445Sassar}
6372445Sassar
64233294SstasKRB5_LIB_FUNCTION int KRB5_LIB_CALL
6572445Sassarinit_error_table(const char **msgs, long base, int count)
6672445Sassar{
6772445Sassar    initialize_error_table_r(&_et_list, msgs, count, base);
6872445Sassar    return 0;
6972445Sassar}
7072445Sassar
71233294Sstasstatic void KRB5_CALLCONV
7272445Sassardefault_proc (const char *whoami, long code, const char *fmt, va_list args)
7378527Sassar    __attribute__((__format__(__printf__, 3, 0)));
74233294Sstas
75233294Sstasstatic void KRB5_CALLCONV
7678527Sassardefault_proc (const char *whoami, long code, const char *fmt, va_list args)
7772445Sassar{
7872445Sassar    if (whoami)
7972445Sassar      fprintf(stderr, "%s: ", whoami);
8072445Sassar    if (code)
8172445Sassar      fprintf(stderr, "%s ", error_message(code));
8272445Sassar    if (fmt)
8372445Sassar      vfprintf(stderr, fmt, args);
8472445Sassar    fprintf(stderr, "\r\n");	/* ??? */
8572445Sassar}
8672445Sassar
8772445Sassarstatic errf com_err_hook = default_proc;
8872445Sassar
89233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL
90233294Sstascom_err_va (const char *whoami,
91233294Sstas	    long code,
92233294Sstas	    const char *fmt,
9372445Sassar	    va_list args)
9472445Sassar{
9572445Sassar    (*com_err_hook) (whoami, code, fmt, args);
9672445Sassar}
9772445Sassar
98233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL
9972445Sassarcom_err (const char *whoami,
10072445Sassar	 long code,
101233294Sstas	 const char *fmt,
10272445Sassar	 ...)
10372445Sassar{
10472445Sassar    va_list ap;
10572445Sassar    va_start(ap, fmt);
10672445Sassar    com_err_va (whoami, code, fmt, ap);
10772445Sassar    va_end(ap);
10872445Sassar}
10972445Sassar
110233294SstasKRB5_LIB_FUNCTION errf KRB5_LIB_CALL
11172445Sassarset_com_err_hook (errf new)
11272445Sassar{
11372445Sassar    errf old = com_err_hook;
11472445Sassar
11572445Sassar    if (new)
11672445Sassar	com_err_hook = new;
11772445Sassar    else
11872445Sassar	com_err_hook = default_proc;
119233294Sstas
12072445Sassar    return old;
12172445Sassar}
12272445Sassar
123233294SstasKRB5_LIB_FUNCTION errf KRB5_LIB_CALL
124233294Sstasreset_com_err_hook (void)
12572445Sassar{
12672445Sassar    return set_com_err_hook(NULL);
12772445Sassar}
12872445Sassar
12972445Sassar#define ERRCODE_RANGE   8       /* # of bits to shift table number */
13072445Sassar#define BITS_PER_CHAR   6       /* # bits to shift per character in name */
13172445Sassar
13272445Sassarstatic const char char_set[] =
13372445Sassar        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
13472445Sassar
13572445Sassarstatic char buf[6];
13672445Sassar
137233294SstasKRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
13872445Sassarerror_table_name(int num)
13972445Sassar{
14072445Sassar    int ch;
14172445Sassar    int i;
14272445Sassar    char *p;
14372445Sassar
14472445Sassar    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
14572445Sassar    p = buf;
14672445Sassar    num >>= ERRCODE_RANGE;
14772445Sassar    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
14872445Sassar    num &= 077777777;
14972445Sassar    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
15072445Sassar    for (i = 4; i >= 0; i--) {
15172445Sassar        ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
15272445Sassar        if (ch != 0)
15372445Sassar            *p++ = char_set[ch-1];
15472445Sassar    }
15572445Sassar    *p = '\0';
15672445Sassar    return(buf);
15772445Sassar}
15878527Sassar
159233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL
16078527Sassaradd_to_error_table(struct et_list *new_table)
16178527Sassar{
16278527Sassar    struct et_list *et;
16378527Sassar
16478527Sassar    for (et = _et_list; et; et = et->next) {
16578527Sassar	if (et->table->base == new_table->table->base)
16678527Sassar	    return;
16778527Sassar    }
16878527Sassar
16978527Sassar    new_table->next = _et_list;
17078527Sassar    _et_list = new_table;
17178527Sassar}
172