2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: result.c,v 1.56.2.2.8.7 2004/06/11 00:31:01 marka Exp $ */
26 #include <isc/mutex.h>
28 #include <isc/resultclass.h>
31 typedef struct resulttable {
35 isc_msgcat_t * msgcat;
37 ISC_LINK(struct resulttable) link;
40 static const char *text[ISC_R_NRESULTS] = {
42 "out of memory", /* 1 */
44 "no available threads", /* 3 */
45 "address not available", /* 4 */
46 "address in use", /* 5 */
47 "permission denied", /* 6 */
48 "no pending connections", /* 7 */
49 "network unreachable", /* 8 */
50 "host unreachable", /* 9 */
51 "network down", /* 10 */
53 "connection refused", /* 12 */
54 "not enough free resources", /* 13 */
55 "end of file", /* 14 */
56 "socket already bound", /* 15 */
59 "already exists", /* 18 */
60 "ran out of space", /* 19 */
61 "operation canceled", /* 20 */
62 "socket is not bound", /* 21 */
63 "shutting down", /* 22 */
65 "unexpected end of input", /* 24 */
68 "not implemented", /* 27 */
69 "unbalanced parentheses", /* 28 */
71 "invalid file", /* 30 */
72 "bad base64 encoding", /* 31 */
73 "unexpected token", /* 32 */
74 "quota reached", /* 33 */
75 "unexpected error", /* 34 */
76 "already running", /* 35 */
78 "address mask not contiguous", /* 37 */
79 "file not found", /* 38 */
80 "file already exists", /* 39 */
81 "socket is not connected", /* 40 */
82 "out of range", /* 41 */
83 "out of entropy", /* 42 */
84 "invalid use of multicast address", /* 43 */
85 "not a file", /* 44 */
86 "not a directory", /* 45 */
87 "queue is full", /* 46 */
88 "address family mismatch", /* 47 */
89 "address family not supported", /* 48 */
90 "bad hex encoding", /* 49 */
91 "too many open files", /* 50 */
92 "not blocking", /* 51 */
93 "unbalanced quotes", /* 52 */
94 "operation in progress", /* 53 */
95 "connection reset", /* 54 */
96 "soft quota reached", /* 55 */
97 "not a valid number", /* 56 */
100 "invalid address format" /* 59 */
103 #define ISC_RESULT_RESULTSET 2
104 #define ISC_RESULT_UNAVAILABLESET 3
106 static isc_once_t once = ISC_ONCE_INIT;
107 static ISC_LIST(resulttable) tables;
108 static isc_mutex_t lock;
111 register_table(unsigned int base, unsigned int nresults, const char **text,
112 isc_msgcat_t *msgcat, int set)
116 REQUIRE(base % ISC_RESULTCLASS_SIZE == 0);
117 REQUIRE(nresults <= ISC_RESULTCLASS_SIZE);
118 REQUIRE(text != NULL);
121 * We use malloc() here because we we want to be able to use
122 * isc_result_totext() even if there is no memory context.
124 table = malloc(sizeof(*table));
126 return (ISC_R_NOMEMORY);
128 table->last = base + nresults - 1;
130 table->msgcat = msgcat;
132 ISC_LINK_INIT(table, link);
136 ISC_LIST_APPEND(tables, table, link);
140 return (ISC_R_SUCCESS);
144 initialize_action(void) {
147 RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
148 ISC_LIST_INIT(tables);
150 result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, text,
151 isc_msgcat, ISC_RESULT_RESULTSET);
152 if (result != ISC_R_SUCCESS)
153 UNEXPECTED_ERROR(__FILE__, __LINE__,
154 "register_table() %s: %u",
155 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
156 ISC_MSG_FAILED, "failed"),
162 isc_lib_initmsgcat();
163 RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
167 isc_result_totext(isc_result_t result) {
169 const char *text, *default_text;
177 for (table = ISC_LIST_HEAD(tables);
179 table = ISC_LIST_NEXT(table, link)) {
180 if (result >= table->base && result <= table->last) {
181 index = (int)(result - table->base);
182 default_text = table->text[index];
184 * Note: we use 'index + 1' as the message number
185 * instead of index because isc_msgcat_get() requires
186 * the message number to be > 0.
188 text = isc_msgcat_get(table->msgcat, table->set,
189 index + 1, default_text);
194 text = isc_msgcat_get(isc_msgcat, ISC_RESULT_UNAVAILABLESET,
195 1, "(result code text not available)");
203 isc_result_register(unsigned int base, unsigned int nresults,
204 const char **text, isc_msgcat_t *msgcat, int set)
208 return (register_table(base, nresults, text, msgcat, set));