Whamcloud - gitweb
error_message.c, init_et.c: Segregate error tables registered
[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 struct et_list * _et_dynamic_list = (struct et_list *) NULL;
31
32
33 const char * error_message (errcode_t code)
34 {
35     int offset;
36     struct et_list *et;
37     errcode_t table_num;
38     int started = 0;
39     char *cp;
40
41     offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
42     table_num = code - offset;
43     if (!table_num) {
44 #ifdef HAS_SYS_ERRLIST
45         if (offset < sys_nerr)
46             return(sys_errlist[offset]);
47         else
48             goto oops;
49 #else
50         cp = strerror(offset);
51         if (cp)
52             return(cp);
53         else
54             goto oops;
55 #endif
56     }
57     for (et = _et_list; et; et = et->next) {
58         if (et->table->base == table_num) {
59             /* This is the right table */
60             if (et->table->n_msgs <= offset)
61                 goto oops;
62             return(et->table->msgs[offset]);
63         }
64     }
65     for (et = _et_dynamic_list; et; et = et->next) {
66         if (et->table->base == table_num) {
67             /* This is the right table */
68             if (et->table->n_msgs <= offset)
69                 goto oops;
70             return(et->table->msgs[offset]);
71         }
72     }
73 oops:
74     strcpy (buffer, "Unknown code ");
75     if (table_num) {
76         strcat (buffer, error_table_name (table_num));
77         strcat (buffer, " ");
78     }
79     for (cp = buffer; *cp; cp++)
80         ;
81     if (offset >= 100) {
82         *cp++ = '0' + offset / 100;
83         offset %= 100;
84         started++;
85     }
86     if (started || offset >= 10) {
87         *cp++ = '0' + offset / 10;
88         offset %= 10;
89     }
90     *cp++ = '0' + offset;
91     *cp = '\0';
92     return(buffer);
93 }
94
95 /*
96  * New interface provided by krb5's com_err library
97  */
98 errcode_t add_error_table(const struct error_table * et)
99 {
100         struct et_list *el;
101
102         if (!(el = (struct et_list *) malloc(sizeof(struct et_list))))
103                 return ENOMEM;
104
105         el->table = et;
106         el->next = _et_dynamic_list;
107         _et_dynamic_list = el;
108
109         return 0;
110 }
111
112 /*
113  * New interface provided by krb5's com_err library
114  */
115 errcode_t remove_error_table(const struct error_table * et)
116 {
117         struct et_list *el = _et_dynamic_list;
118         struct et_list *el2 = 0;
119
120         while (el) {
121                 if (el->table->base == et->base) {
122                         if (el2)        /* Not the beginning of the list */
123                                 el2->next = el->next;
124                         else
125                                 _et_dynamic_list = el->next;
126                         (void) free(el);
127                         return 0;
128                 }
129                 el2 = el;
130                 el = el->next;
131         }
132         return ENOENT;
133 }
134
135 /*
136  * Variant of the interface provided by Heimdal's com_err library
137  */
138 void
139 add_to_error_table(struct et_list *new_table)
140 {
141         add_error_table(new_table->table);
142 }