172445Sassar/*
2102644Snectar * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan
372445Sassar * (Royal Institute of Technology, Stockholm, Sweden).
472445Sassar * All rights reserved.
572445Sassar *
672445Sassar * Redistribution and use in source and binary forms, with or without
772445Sassar * modification, are permitted provided that the following conditions
872445Sassar * are met:
972445Sassar *
1072445Sassar * 1. Redistributions of source code must retain the above copyright
1172445Sassar *    notice, this list of conditions and the following disclaimer.
1272445Sassar *
1372445Sassar * 2. Redistributions in binary form must reproduce the above copyright
1472445Sassar *    notice, this list of conditions and the following disclaimer in the
1572445Sassar *    documentation and/or other materials provided with the distribution.
1672445Sassar *
1772445Sassar * 3. Neither the name of the Institute nor the names of its contributors
1872445Sassar *    may be used to endorse or promote products derived from this software
1972445Sassar *    without specific prior written permission.
2072445Sassar *
2172445Sassar * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2272445Sassar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2372445Sassar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2472445Sassar * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2572445Sassar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2672445Sassar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2772445Sassar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2872445Sassar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2972445Sassar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3072445Sassar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3172445Sassar * SUCH DAMAGE.
3272445Sassar */
3372445Sassar
3472445Sassar#ifdef HAVE_CONFIG_H
3572445Sassar#include <config.h>
36178825SdfrRCSID("$Id: com_err.c 14930 2005-04-24 19:43:06Z lha $");
3772445Sassar#endif
3872445Sassar#include <stdio.h>
3972445Sassar#include <stdlib.h>
4072445Sassar#include <string.h>
4172445Sassar#include <roken.h>
4272445Sassar#include "com_err.h"
4372445Sassar
4472445Sassarstruct et_list *_et_list = NULL;
4572445Sassar
4672445Sassar
4772445Sassarconst char *
4872445Sassarerror_message (long code)
4972445Sassar{
5072445Sassar    static char msg[128];
5172445Sassar    const char *p = com_right(_et_list, code);
52102644Snectar    if (p == NULL) {
53102644Snectar	if (code < 0)
54178825Sdfr	    snprintf(msg, sizeof(msg), "Unknown error %ld", code);
55102644Snectar	else
56102644Snectar	    p = strerror(code);
57102644Snectar    }
5872445Sassar    if (p != NULL && *p != '\0') {
59178825Sdfr	strlcpy(msg, p, sizeof(msg));
6072445Sassar    } else
61178825Sdfr	snprintf(msg, sizeof(msg), "Unknown error %ld", code);
6272445Sassar    return msg;
6372445Sassar}
6472445Sassar
6572445Sassarint
6672445Sassarinit_error_table(const char **msgs, long base, int count)
6772445Sassar{
6872445Sassar    initialize_error_table_r(&_et_list, msgs, count, base);
6972445Sassar    return 0;
7072445Sassar}
7172445Sassar
7272445Sassarstatic void
7372445Sassardefault_proc (const char *whoami, long code, const char *fmt, va_list args)
7478527Sassar    __attribute__((__format__(__printf__, 3, 0)));
7578527Sassar
7678527Sassarstatic void
7778527Sassardefault_proc (const char *whoami, long code, const char *fmt, va_list args)
7872445Sassar{
7972445Sassar    if (whoami)
8072445Sassar      fprintf(stderr, "%s: ", whoami);
8172445Sassar    if (code)
8272445Sassar      fprintf(stderr, "%s ", error_message(code));
8372445Sassar    if (fmt)
8472445Sassar      vfprintf(stderr, fmt, args);
8572445Sassar    fprintf(stderr, "\r\n");	/* ??? */
8672445Sassar}
8772445Sassar
8872445Sassarstatic errf com_err_hook = default_proc;
8972445Sassar
9072445Sassarvoid
9172445Sassarcom_err_va (const char *whoami,
9272445Sassar	    long code,
9372445Sassar	    const char *fmt,
9472445Sassar	    va_list args)
9572445Sassar{
9672445Sassar    (*com_err_hook) (whoami, code, fmt, args);
9772445Sassar}
9872445Sassar
9972445Sassarvoid
10072445Sassarcom_err (const char *whoami,
10172445Sassar	 long code,
10272445Sassar	 const char *fmt,
10372445Sassar	 ...)
10472445Sassar{
10572445Sassar    va_list ap;
10672445Sassar    va_start(ap, fmt);
10772445Sassar    com_err_va (whoami, code, fmt, ap);
10872445Sassar    va_end(ap);
10972445Sassar}
11072445Sassar
11172445Sassarerrf
11272445Sassarset_com_err_hook (errf new)
11372445Sassar{
11472445Sassar    errf old = com_err_hook;
11572445Sassar
11672445Sassar    if (new)
11772445Sassar	com_err_hook = new;
11872445Sassar    else
11972445Sassar	com_err_hook = default_proc;
12072445Sassar
12172445Sassar    return old;
12272445Sassar}
12372445Sassar
12472445Sassarerrf
12572445Sassarreset_com_err_hook (void)
12672445Sassar{
12772445Sassar    return set_com_err_hook(NULL);
12872445Sassar}
12972445Sassar
13072445Sassar#define ERRCODE_RANGE   8       /* # of bits to shift table number */
13172445Sassar#define BITS_PER_CHAR   6       /* # bits to shift per character in name */
13272445Sassar
13372445Sassarstatic const char char_set[] =
13472445Sassar        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
13572445Sassar
13672445Sassarstatic char buf[6];
13772445Sassar
13872445Sassarconst char *
13972445Sassarerror_table_name(int num)
14072445Sassar{
14172445Sassar    int ch;
14272445Sassar    int i;
14372445Sassar    char *p;
14472445Sassar
14572445Sassar    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
14672445Sassar    p = buf;
14772445Sassar    num >>= ERRCODE_RANGE;
14872445Sassar    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
14972445Sassar    num &= 077777777;
15072445Sassar    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
15172445Sassar    for (i = 4; i >= 0; i--) {
15272445Sassar        ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
15372445Sassar        if (ch != 0)
15472445Sassar            *p++ = char_set[ch-1];
15572445Sassar    }
15672445Sassar    *p = '\0';
15772445Sassar    return(buf);
15872445Sassar}
15978527Sassar
16078527Sassarvoid
16178527Sassaradd_to_error_table(struct et_list *new_table)
16278527Sassar{
16378527Sassar    struct et_list *et;
16478527Sassar
16578527Sassar    for (et = _et_list; et; et = et->next) {
16678527Sassar	if (et->table->base == new_table->table->base)
16778527Sassar	    return;
16878527Sassar    }
16978527Sassar
17078527Sassar    new_table->next = _et_list;
17178527Sassar    _et_list = new_table;
17278527Sassar}
173