00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <stddef.h>
00025 #include <stdlib.h>
00026
00027 #include <isc/lib.h>
00028 #include <isc/msgs.h>
00029 #include <isc/mutex.h>
00030 #include <isc/once.h>
00031 #include <isc/resultclass.h>
00032 #include <isc/util.h>
00033
00034 typedef struct resulttable {
00035 unsigned int base;
00036 unsigned int last;
00037 const char ** text;
00038 isc_msgcat_t * msgcat;
00039 int set;
00040 ISC_LINK(struct resulttable) link;
00041 } resulttable;
00042
00043 static const char *description[ISC_R_NRESULTS] = {
00044 "success",
00045 "out of memory",
00046 "timed out",
00047 "no available threads",
00048 "address not available",
00049 "address in use",
00050 "permission denied",
00051 "no pending connections",
00052 "network unreachable",
00053 "host unreachable",
00054 "network down",
00055 "host down",
00056 "connection refused",
00057 "not enough free resources",
00058 "end of file",
00059 "socket already bound",
00060 "reload",
00061 "lock busy",
00062 "already exists",
00063 "ran out of space",
00064 "operation canceled",
00065 "socket is not bound",
00066 "shutting down",
00067 "not found",
00068 "unexpected end of input",
00069 "failure",
00070 "I/O error",
00071 "not implemented",
00072 "unbalanced parentheses",
00073 "no more",
00074 "invalid file",
00075 "bad base64 encoding",
00076 "unexpected token",
00077 "quota reached",
00078 "unexpected error",
00079 "already running",
00080 "ignore",
00081 "address mask not contiguous",
00082 "file not found",
00083 "file already exists",
00084 "socket is not connected",
00085 "out of range",
00086 "out of entropy",
00087 "invalid use of multicast address",
00088 "not a file",
00089 "not a directory",
00090 "queue is full",
00091 "address family mismatch",
00092 "address family not supported",
00093 "bad hex encoding",
00094 "too many open files",
00095 "not blocking",
00096 "unbalanced quotes",
00097 "operation in progress",
00098 "connection reset",
00099 "soft quota reached",
00100 "not a valid number",
00101 "disabled",
00102 "max size",
00103 "invalid address format",
00104 "bad base32 encoding",
00105 "unset",
00106 "multiple",
00107 };
00108
00109 #define ISC_RESULT_RESULTSET 2
00110 #define ISC_RESULT_UNAVAILABLESET 3
00111
00112 static isc_once_t once = ISC_ONCE_INIT;
00113 static ISC_LIST(resulttable) tables;
00114 static isc_mutex_t lock;
00115
00116 static isc_result_t
00117 register_table(unsigned int base, unsigned int nresults, const char **text,
00118 isc_msgcat_t *msgcat, int set)
00119 {
00120 resulttable *table;
00121
00122 REQUIRE(base % ISC_RESULTCLASS_SIZE == 0);
00123 REQUIRE(nresults <= ISC_RESULTCLASS_SIZE);
00124 REQUIRE(text != NULL);
00125
00126
00127
00128
00129
00130 table = malloc(sizeof(*table));
00131 if (table == NULL)
00132 return (ISC_R_NOMEMORY);
00133 table->base = base;
00134 table->last = base + nresults - 1;
00135 table->text = text;
00136 table->msgcat = msgcat;
00137 table->set = set;
00138 ISC_LINK_INIT(table, link);
00139
00140 LOCK(&lock);
00141
00142 ISC_LIST_APPEND(tables, table, link);
00143
00144 UNLOCK(&lock);
00145
00146 return (ISC_R_SUCCESS);
00147 }
00148
00149 static void
00150 initialize_action(void) {
00151 isc_result_t result;
00152
00153 RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
00154 ISC_LIST_INIT(tables);
00155
00156 result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS,
00157 description, isc_msgcat, ISC_RESULT_RESULTSET);
00158 if (result != ISC_R_SUCCESS)
00159 UNEXPECTED_ERROR(__FILE__, __LINE__,
00160 "register_table() %s: %u",
00161 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
00162 ISC_MSG_FAILED, "failed"),
00163 result);
00164 }
00165
00166 static void
00167 initialize(void) {
00168 isc_lib_initmsgcat();
00169 RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
00170 }
00171
00172 const char *
00173 isc_result_totext(isc_result_t result) {
00174 resulttable *table;
00175 const char *text, *default_text;
00176 int index;
00177
00178 initialize();
00179
00180 LOCK(&lock);
00181
00182 text = NULL;
00183 for (table = ISC_LIST_HEAD(tables);
00184 table != NULL;
00185 table = ISC_LIST_NEXT(table, link)) {
00186 if (result >= table->base && result <= table->last) {
00187 index = (int)(result - table->base);
00188 default_text = table->text[index];
00189
00190
00191
00192
00193
00194 text = isc_msgcat_get(table->msgcat, table->set,
00195 index + 1, default_text);
00196 break;
00197 }
00198 }
00199 if (text == NULL)
00200 text = isc_msgcat_get(isc_msgcat, ISC_RESULT_UNAVAILABLESET,
00201 1, "(result code text not available)");
00202
00203 UNLOCK(&lock);
00204
00205 return (text);
00206 }
00207
00208 isc_result_t
00209 isc_result_register(unsigned int base, unsigned int nresults,
00210 const char **text, isc_msgcat_t *msgcat, int set)
00211 {
00212 initialize();
00213
00214 return (register_table(base, nresults, text, msgcat, set));
00215 }