com_err.c revision 50764
134355Sjb/*
234355Sjb * Copyright (c) 1997, 1998 Kungliga Tekniska H�gskolan
389985Sbde * (Royal Institute of Technology, Stockholm, Sweden).
4112902Sjeff * All rights reserved.
534355Sjb *
634355Sjb * Redistribution and use in source and binary forms, with or without
764002Speter * modification, are permitted provided that the following conditions
834355Sjb * are met:
934355Sjb *
1034355Sjb * 1. Redistributions of source code must retain the above copyright
1134355Sjb *    notice, this list of conditions and the following disclaimer.
1234355Sjb *
1334355Sjb * 2. Redistributions in binary form must reproduce the above copyright
1434355Sjb *    notice, this list of conditions and the following disclaimer in the
1534355Sjb *    documentation and/or other materials provided with the distribution.
1634355Sjb *
1734355Sjb * 3. All advertising materials mentioning features or use of this software
1834355Sjb *    must display the following acknowledgement:
1934355Sjb *      This product includes software developed by Kungliga Tekniska
2034355Sjb *      H�gskolan and its contributors.
2134355Sjb *
2234355Sjb * 4. Neither the name of the Institute nor the names of its contributors
2334355Sjb *    may be used to endorse or promote products derived from this software
2434355Sjb *    without specific prior written permission.
2534355Sjb *
2634355Sjb * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2734355Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2834355Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2934355Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
3034355Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3134355Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3234355Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3334355Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3434355Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3534355Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3634355Sjb * SUCH DAMAGE.
3734355Sjb */
3834355Sjb
3934355Sjb#ifdef HAVE_CONFIG_H
4034355Sjb#include <config.h>
4134355SjbRCSID("$Id: com_err.c,v 1.13 1999/03/12 15:17:08 bg Exp $");
4234355Sjb#endif
4334355Sjb#include <stdio.h>
4434355Sjb#include <stdlib.h>
4534355Sjb#include <string.h>
4634355Sjb#include <roken.h>
4734355Sjb#include "com_err.h"
4834355Sjb
4934355Sjbstruct et_list *_et_list;
5034355Sjb
5134355Sjb
5234355Sjbconst char *
5334355Sjberror_message (long code)
5434355Sjb{
5534355Sjb    static char msg[128];
5634355Sjb    const char *p = com_right(_et_list, code);
5734355Sjb    if (p == NULL)
5834355Sjb	p = strerror(code);
5934355Sjb    if (p != NULL && *p != '\0') {
6034355Sjb	strncpy(msg, p, sizeof(msg) - 1);
6134355Sjb	msg[sizeof(msg) - 1] = 0;
6234355Sjb    } else
6334355Sjb	sprintf(msg, "Unknown error %ld", code);
6434355Sjb    return msg;
6534355Sjb}
6634355Sjb
6734355Sjbint
6834355Sjbinit_error_table(const char **msgs, long base, int count)
6934355Sjb{
7034355Sjb    initialize_error_table_r(&_et_list, msgs, count, base);
7134355Sjb    return 0;
7234355Sjb}
7334355Sjb
7434355Sjbstatic void
7534355Sjbdefault_proc (const char *whoami, long code, const char *fmt, va_list args)
7634355Sjb{
7734355Sjb    if (whoami)
7834355Sjb      fprintf(stderr, "%s: ", whoami);
7934355Sjb    if (code)
8034355Sjb      fprintf(stderr, "%s ", error_message(code));
8134355Sjb    if (fmt)
8234355Sjb      vfprintf(stderr, fmt, args);
8334355Sjb    fprintf(stderr, "\r\n");	/* ??? */
8434355Sjb}
8534355Sjb
8634355Sjbstatic errf com_err_hook = default_proc;
8734355Sjb
8834355Sjbvoid
8934355Sjbcom_err_va (const char *whoami,
9034355Sjb	    long code,
9134355Sjb	    const char *fmt,
9234355Sjb	    va_list args)
9334355Sjb{
9434355Sjb    (*com_err_hook) (whoami, code, fmt, args);
9534355Sjb}
9634355Sjb
9734355Sjbvoid
9834355Sjbcom_err (const char *whoami,
9934355Sjb	 long code,
10034355Sjb	 const char *fmt,
10134355Sjb	 ...)
10234355Sjb{
10334355Sjb    va_list ap;
10434355Sjb    va_start(ap, fmt);
10534355Sjb    com_err_va (whoami, code, fmt, ap);
10634355Sjb    va_end(ap);
10734355Sjb}
10834355Sjb
10934355Sjberrf
11034355Sjbset_com_err_hook (errf new)
11134355Sjb{
11234355Sjb    errf old = com_err_hook;
11334355Sjb
11434355Sjb    if (new)
11534355Sjb	com_err_hook = new;
11634355Sjb    else
11734355Sjb	com_err_hook = default_proc;
11834355Sjb
11934355Sjb    return old;
12034355Sjb}
12134355Sjb
12245065Salcerrf
12345065Salcreset_com_err_hook (void)
12434355Sjb{
12534355Sjb    return set_com_err_hook(NULL);
12634355Sjb}
12734355Sjb
12834355Sjb#define ERRCODE_RANGE   8       /* # of bits to shift table number */
12934355Sjb#define BITS_PER_CHAR   6       /* # bits to shift per character in name */
13034355Sjb
13134355Sjbstatic const char char_set[] =
13234355Sjb        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
13334355Sjb
13434355Sjbstatic char buf[6];
13534355Sjb
13634355Sjbconst char *
13734355Sjberror_table_name(int num)
13834355Sjb{
13934355Sjb    int ch;
14034355Sjb    int i;
14134355Sjb    char *p;
14234355Sjb
14334355Sjb    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
14434355Sjb    p = buf;
14535938Sdyson    num >>= ERRCODE_RANGE;
14634355Sjb    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
14734355Sjb    num &= 077777777;
14834355Sjb    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
14934355Sjb    for (i = 4; i >= 0; i--) {
15034355Sjb        ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
15134355Sjb        if (ch != 0)
15234355Sjb            *p++ = char_set[ch-1];
15334355Sjb    }
15434355Sjb    *p = '\0';
15534355Sjb    return(buf);
15634355Sjb}
15734355Sjb