Coverage Report

Created: 2023-05-19 06:16

/src/ntp-dev/lib/isc/result.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2004, 2005, 2007, 2008, 2012  Internet Systems Consortium, Inc. ("ISC")
3
 * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
4
 *
5
 * Permission to use, copy, modify, and/or 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$ */
19
20
/*! \file */
21
22
#include <config.h>
23
24
#include <stddef.h>
25
#include <stdlib.h>
26
27
#include <isc/lib.h>
28
#include <isc/msgs.h>
29
#include <isc/mutex.h>
30
#include <isc/once.h>
31
#include <isc/resultclass.h>
32
#include <isc/util.h>
33
34
typedef struct resulttable {
35
  unsigned int        base;
36
  unsigned int        last;
37
  const char **       text;
38
  isc_msgcat_t *        msgcat;
39
  int         set;
40
  ISC_LINK(struct resulttable)    link;
41
} resulttable;
42
43
static const char *text[ISC_R_NRESULTS] = {
44
  "success",        /*%< 0 */
45
  "out of memory",      /*%< 1 */
46
  "timed out",        /*%< 2 */
47
  "no available threads",     /*%< 3 */
48
  "address not available",    /*%< 4 */
49
  "address in use",     /*%< 5 */
50
  "permission denied",      /*%< 6 */
51
  "no pending connections",   /*%< 7 */
52
  "network unreachable",      /*%< 8 */
53
  "host unreachable",     /*%< 9 */
54
  "network down",       /*%< 10 */
55
  "host down",        /*%< 11 */
56
  "connection refused",     /*%< 12 */
57
  "not enough free resources",    /*%< 13 */
58
  "end of file",        /*%< 14 */
59
  "socket already bound",     /*%< 15 */
60
  "reload",       /*%< 16 */
61
  "lock busy",        /*%< 17 */
62
  "already exists",     /*%< 18 */
63
  "ran out of space",     /*%< 19 */
64
  "operation canceled",     /*%< 20 */
65
  "socket is not bound",      /*%< 21 */
66
  "shutting down",      /*%< 22 */
67
  "not found",        /*%< 23 */
68
  "unexpected end of input",    /*%< 24 */
69
  "failure",        /*%< 25 */
70
  "I/O error",        /*%< 26 */
71
  "not implemented",      /*%< 27 */
72
  "unbalanced parentheses",   /*%< 28 */
73
  "no more",        /*%< 29 */
74
  "invalid file",       /*%< 30 */
75
  "bad base64 encoding",      /*%< 31 */
76
  "unexpected token",     /*%< 32 */
77
  "quota reached",      /*%< 33 */
78
  "unexpected error",     /*%< 34 */
79
  "already running",      /*%< 35 */
80
  "ignore",       /*%< 36 */
81
  "address mask not contiguous",    /*%< 37 */
82
  "file not found",     /*%< 38 */
83
  "file already exists",      /*%< 39 */
84
  "socket is not connected",    /*%< 40 */
85
  "out of range",       /*%< 41 */
86
  "out of entropy",     /*%< 42 */
87
  "invalid use of multicast address", /*%< 43 */
88
  "not a file",       /*%< 44 */
89
  "not a directory",      /*%< 45 */
90
  "queue is full",      /*%< 46 */
91
  "address family mismatch",    /*%< 47 */
92
  "address family not supported",   /*%< 48 */
93
  "bad hex encoding",     /*%< 49 */
94
  "too many open files",      /*%< 50 */
95
  "not blocking",       /*%< 51 */
96
  "unbalanced quotes",      /*%< 52 */
97
  "operation in progress",    /*%< 53 */
98
  "connection reset",     /*%< 54 */
99
  "soft quota reached",     /*%< 55 */
100
  "not a valid number",     /*%< 56 */
101
  "disabled",       /*%< 57 */
102
  "max size",       /*%< 58 */
103
  "invalid address format",   /*%< 59 */
104
  "bad base32 encoding",      /*%< 60 */
105
  "unset",        /*%< 61 */
106
};
107
108
0
#define ISC_RESULT_RESULTSET      2
109
0
#define ISC_RESULT_UNAVAILABLESET   3
110
111
static isc_once_t         once = ISC_ONCE_INIT;
112
static ISC_LIST(resulttable)      tables;
113
static isc_mutex_t        lock;
114
115
static isc_result_t
116
register_table(unsigned int base, unsigned int nresults, const char **txt,
117
         isc_msgcat_t *msgcat, int set)
118
0
{
119
0
  resulttable *table;
120
121
0
  REQUIRE(base % ISC_RESULTCLASS_SIZE == 0);
122
0
  REQUIRE(nresults <= ISC_RESULTCLASS_SIZE);
123
0
  REQUIRE(txt != NULL);
124
125
  /*
126
   * We use malloc() here because we we want to be able to use
127
   * isc_result_totext() even if there is no memory context.
128
   */
129
0
  table = malloc(sizeof(*table));
130
0
  if (table == NULL)
131
0
    return (ISC_R_NOMEMORY);
132
0
  table->base = base;
133
0
  table->last = base + nresults - 1;
134
0
  table->text = txt;
135
0
  table->msgcat = msgcat;
136
0
  table->set = set;
137
0
  ISC_LINK_INIT(table, link);
138
139
0
  LOCK(&lock);
140
141
0
  ISC_LIST_APPEND(tables, table, link);
142
143
0
  UNLOCK(&lock);
144
145
0
  return (ISC_R_SUCCESS);
146
0
}
147
148
static void
149
0
initialize_action(void) {
150
0
  isc_result_t result;
151
152
0
  RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
153
0
  ISC_LIST_INIT(tables);
154
155
0
  result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, text,
156
0
        isc_msgcat, ISC_RESULT_RESULTSET);
157
0
  if (result != ISC_R_SUCCESS)
158
0
    UNEXPECTED_ERROR(__FILE__, __LINE__,
159
0
         "register_table() %s: %u",
160
0
         isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
161
0
            ISC_MSG_FAILED, "failed"),
162
0
         result);
163
0
}
164
165
static void
166
0
initialize(void) {
167
0
  isc_lib_initmsgcat();
168
0
  RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
169
0
}
170
171
const char *
172
0
isc_result_totext(isc_result_t result) {
173
0
  resulttable *table;
174
0
  const char *txt, *default_text;
175
0
  int idx;
176
177
0
  initialize();
178
179
0
  LOCK(&lock);
180
181
0
  txt = NULL;
182
0
  for (table = ISC_LIST_HEAD(tables);
183
0
       table != NULL;
184
0
       table = ISC_LIST_NEXT(table, link)) {
185
0
    if (result >= table->base && result <= table->last) {
186
0
      idx = (int)(result - table->base);
187
0
      default_text = table->text[idx];
188
      /*
189
       * Note: we use 'idx + 1' as the message number
190
       * instead of idx because isc_msgcat_get() requires
191
       * the message number to be > 0.
192
       */
193
0
      txt = isc_msgcat_get(table->msgcat, table->set,
194
0
               idx + 1, default_text);
195
0
      break;
196
0
    }
197
0
  }
198
0
  if (txt == NULL)
199
0
    txt = isc_msgcat_get(isc_msgcat, ISC_RESULT_UNAVAILABLESET,
200
0
             1, "(result code text not available)");
201
202
0
  UNLOCK(&lock);
203
204
0
  return (txt);
205
0
}
206
207
isc_result_t
208
isc_result_register(unsigned int base, unsigned int nresults,
209
        const char **txt, isc_msgcat_t *msgcat, int set)
210
0
{
211
0
  initialize();
212
213
0
  return (register_table(base, nresults, txt, msgcat, set));
214
0
}