Whamcloud - gitweb
Change compile_et to generate header files that use <et/com_err.h>
[tools/e2fsprogs.git] / lib / et / error_message.c
1 /*
2  * $Header$
3  * $Source$
4  * $Locker$
5  *
6  * Copyright 1987 by the Student Information Processing Board
7  * of the Massachusetts Institute of Technology
8  *
9  * Permission to use, copy, modify, and distribute this software and
10  * its documentation for any purpose is hereby granted, provided that
11  * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
12  * advertising or publicity pertaining to distribution of the software
13  * without specific, written prior permission.  M.I.T. and the
14  * M.I.T. S.I.P.B. make no representations about the suitability of
15  * this software for any purpose.  It is provided "as is" without
16  * express or implied warranty.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23 #include "com_err.h"
24 #include "error_table.h"
25 #include "internal.h"
26
27 static char buffer[25];
28
29 struct et_list * _et_list = (struct et_list *) NULL;
30
31
32 const char * error_message (errcode_t code)
33 {
34     int offset;
35     struct et_list *et;
36     errcode_t table_num;
37     int started = 0;
38     char *cp;
39
40     offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
41     table_num = code - offset;
42     if (!table_num) {
43 #ifdef HAS_SYS_ERRLIST
44         if (offset < sys_nerr)
45             return(sys_errlist[offset]);
46         else
47             goto oops;
48 #else
49         cp = strerror(offset);
50         if (cp)
51             return(cp);
52         else
53             goto oops;
54 #endif
55     }
56     for (et = _et_list; et; et = et->next) {
57         if (et->table->base == table_num) {
58             /* This is the right table */
59             if (et->table->n_msgs <= offset)
60                 goto oops;
61             return(et->table->msgs[offset]);
62         }
63     }
64 oops:
65     strcpy (buffer, "Unknown code ");
66     if (table_num) {
67         strcat (buffer, error_table_name (table_num));
68         strcat (buffer, " ");
69     }
70     for (cp = buffer; *cp; cp++)
71         ;
72     if (offset >= 100) {
73         *cp++ = '0' + offset / 100;
74         offset %= 100;
75         started++;
76     }
77     if (started || offset >= 10) {
78         *cp++ = '0' + offset / 10;
79         offset %= 10;
80     }
81     *cp++ = '0' + offset;
82     *cp = '\0';
83     return(buffer);
84 }
85
86 /*
87  * New interface provided by krb5's com_err library
88  */
89 errcode_t add_error_table(const struct error_table * et)
90 {
91         struct et_list *el = _et_list;
92
93         while (el) {
94                 if (el->table->base == et->base)
95                         return EEXIST;
96                 el = el->next;
97         }
98
99         if (!(el = (struct et_list *) malloc(sizeof(struct et_list))))
100                 return ENOMEM;
101
102         el->table = et;
103         el->next = _et_list;
104         _et_list = el;
105
106         return 0;
107 }
108
109 /*
110  * New interface provided by krb5's com_err library
111  */
112 errcode_t remove_error_table(const struct error_table * et)
113 {
114         struct et_list *el = _et_list;
115         struct et_list *el2 = 0;
116
117         while (el) {
118                 if (el->table->base == et->base) {
119                         if (el2)        /* Not the beginning of the list */
120                                 el2->next = el->next;
121                         else
122                                 _et_list = el->next;
123                         (void) free(el);
124                         return 0;
125                 }
126                 el2 = el;
127                 el = el->next;
128         }
129         return ENOENT;
130 }
131
132 /*
133  * Variant of the interface provided by Heimdal's com_err library
134  */
135 void
136 add_to_error_table(struct et_list *new_table)
137 {
138         add_error_table(new_table->table);
139 }