]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bind9/lib/isc/result.c
This commit was generated by cvs2svn to compensate for changes in r153758,
[FreeBSD/FreeBSD.git] / contrib / bind9 / lib / isc / result.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
4  *
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.
8  *
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.
16  */
17
18 /* $Id: result.c,v 1.56.2.2.8.7 2004/06/11 00:31:01 marka Exp $ */
19
20 #include <config.h>
21
22 #include <stdlib.h>
23
24 #include <isc/lib.h>
25 #include <isc/msgs.h>
26 #include <isc/mutex.h>
27 #include <isc/once.h>
28 #include <isc/resultclass.h>
29 #include <isc/util.h>
30
31 typedef struct resulttable {
32         unsigned int                            base;
33         unsigned int                            last;
34         const char **                           text;
35         isc_msgcat_t *                          msgcat;
36         int                                     set;
37         ISC_LINK(struct resulttable)            link;
38 } resulttable;
39
40 static const char *text[ISC_R_NRESULTS] = {
41         "success",                              /*  0 */
42         "out of memory",                        /*  1 */
43         "timed out",                            /*  2 */
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 */
52         "host down",                            /* 11 */
53         "connection refused",                   /* 12 */
54         "not enough free resources",            /* 13 */
55         "end of file",                          /* 14 */
56         "socket already bound",                 /* 15 */
57         "reload",                               /* 16 */
58         "lock busy",                            /* 17 */
59         "already exists",                       /* 18 */
60         "ran out of space",                     /* 19 */
61         "operation canceled",                   /* 20 */
62         "socket is not bound",                  /* 21 */
63         "shutting down",                        /* 22 */
64         "not found",                            /* 23 */
65         "unexpected end of input",              /* 24 */
66         "failure",                              /* 25 */
67         "I/O error",                            /* 26 */
68         "not implemented",                      /* 27 */
69         "unbalanced parentheses",               /* 28 */
70         "no more",                              /* 29 */
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 */
77         "ignore",                               /* 36 */
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 */
98         "disabled",                             /* 57 */
99         "max size",                             /* 58 */
100         "invalid address format"                /* 59 */
101 };
102
103 #define ISC_RESULT_RESULTSET                    2
104 #define ISC_RESULT_UNAVAILABLESET               3
105
106 static isc_once_t                               once = ISC_ONCE_INIT;
107 static ISC_LIST(resulttable)                    tables;
108 static isc_mutex_t                              lock;
109
110 static isc_result_t
111 register_table(unsigned int base, unsigned int nresults, const char **text,
112                isc_msgcat_t *msgcat, int set)
113 {
114         resulttable *table;
115
116         REQUIRE(base % ISC_RESULTCLASS_SIZE == 0);
117         REQUIRE(nresults <= ISC_RESULTCLASS_SIZE);
118         REQUIRE(text != NULL);
119
120         /*
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.
123          */
124         table = malloc(sizeof(*table));
125         if (table == NULL)
126                 return (ISC_R_NOMEMORY);
127         table->base = base;
128         table->last = base + nresults - 1;
129         table->text = text;
130         table->msgcat = msgcat;
131         table->set = set;
132         ISC_LINK_INIT(table, link);
133
134         LOCK(&lock);
135
136         ISC_LIST_APPEND(tables, table, link);
137
138         UNLOCK(&lock);
139
140         return (ISC_R_SUCCESS);
141 }
142
143 static void
144 initialize_action(void) {
145         isc_result_t result;
146
147         RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
148         ISC_LIST_INIT(tables);
149
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"),
157                                  result);
158 }
159
160 static void
161 initialize(void) {
162         isc_lib_initmsgcat();
163         RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
164 }
165
166 const char *
167 isc_result_totext(isc_result_t result) {
168         resulttable *table;
169         const char *text, *default_text;
170         int index;
171
172         initialize();
173
174         LOCK(&lock);
175
176         text = NULL;
177         for (table = ISC_LIST_HEAD(tables);
178              table != NULL;
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];
183                         /*
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.
187                          */
188                         text = isc_msgcat_get(table->msgcat, table->set,
189                                               index + 1, default_text);
190                         break;
191                 }
192         }
193         if (text == NULL)
194                 text = isc_msgcat_get(isc_msgcat, ISC_RESULT_UNAVAILABLESET,
195                                       1, "(result code text not available)");
196
197         UNLOCK(&lock);
198
199         return (text);
200 }
201
202 isc_result_t
203 isc_result_register(unsigned int base, unsigned int nresults,
204                     const char **text, isc_msgcat_t *msgcat, int set)
205 {
206         initialize();
207
208         return (register_table(base, nresults, text, msgcat, set));
209 }