Coverage Report

Created: 2023-03-26 06:28

/src/httpd/srclib/apr/misc/unix/errorcodes.c
Line
Count
Source (jump to first uncovered line)
1
/* Licensed to the Apache Software Foundation (ASF) under one or more
2
 * contributor license agreements.  See the NOTICE file distributed with
3
 * this work for additional information regarding copyright ownership.
4
 * The ASF licenses this file to You under the Apache License, Version 2.0
5
 * (the "License"); you may not use this file except in compliance with
6
 * the License.  You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#include "apr_arch_misc.h"
18
#include "apr_strings.h"
19
#include "apr_lib.h"
20
#include "apr_dso.h"
21
22
#include "apu_errno.h"
23
24
#if APR_HAVE_NETDB_H
25
#include <netdb.h>
26
#endif
27
#ifdef HAVE_DLFCN_H
28
#include <dlfcn.h>
29
#endif
30
31
/*
32
 * stuffbuffer - like apr_cpystrn() but returns the address of the
33
 * dest buffer instead of the address of the terminating '\0'
34
 */
35
static char *stuffbuffer(char *buf, apr_size_t bufsize, const char *s)
36
0
{
37
0
    apr_cpystrn(buf,s,bufsize);
38
0
    return buf;
39
0
}
40
41
static char *apr_error_string(apr_status_t statcode)
42
0
{
43
0
    switch (statcode) {
44
0
    case APR_ENOSTAT:
45
0
        return "Could not perform a stat on the file.";
46
0
    case APR_ENOPOOL:
47
0
        return "A new pool could not be created.";
48
0
    case APR_EBADDATE:
49
0
        return "An invalid date has been provided";
50
0
    case APR_EINVALSOCK:
51
0
        return "An invalid socket was returned";
52
0
    case APR_ENOPROC:
53
0
        return "No process was provided and one was required.";
54
0
    case APR_ENOTIME:
55
0
        return "No time was provided and one was required.";
56
0
    case APR_ENODIR:
57
0
        return "No directory was provided and one was required.";
58
0
    case APR_ENOLOCK:
59
0
        return "No lock was provided and one was required.";
60
0
    case APR_ENOPOLL:
61
0
        return "No poll structure was provided and one was required.";
62
0
    case APR_ENOSOCKET:
63
0
        return "No socket was provided and one was required.";
64
0
    case APR_ENOTHREAD:
65
0
        return "No thread was provided and one was required.";
66
0
    case APR_ENOTHDKEY:
67
0
        return "No thread key structure was provided and one was required.";
68
0
    case APR_ENOSHMAVAIL:
69
0
        return "No shared memory is currently available";
70
0
    case APR_EDSOOPEN:
71
#if APR_HAS_DSO && defined(HAVE_LIBDL)
72
        return dlerror();
73
#else
74
0
        return "DSO load failed";
75
0
#endif /* HAVE_LIBDL */
76
0
    case APR_EBADIP:
77
0
        return "The specified IP address is invalid.";
78
0
    case APR_EBADMASK:
79
0
        return "The specified network mask is invalid.";
80
0
    case APR_ESYMNOTFOUND:
81
0
        return "Could not find the requested symbol.";
82
0
    case APR_ENOTENOUGHENTROPY:
83
0
        return "Not enough entropy to continue.";
84
0
    case APR_INCHILD:
85
0
        return
86
0
      "Your code just forked, and you are currently executing in the "
87
0
      "child process";
88
0
    case APR_INPARENT:
89
0
        return
90
0
      "Your code just forked, and you are currently executing in the "
91
0
      "parent process";
92
0
    case APR_DETACH:
93
0
        return "The specified thread is detached";
94
0
    case APR_NOTDETACH:
95
0
        return "The specified thread is not detached";
96
0
    case APR_CHILD_DONE:
97
0
        return "The specified child process is done executing";
98
0
    case APR_CHILD_NOTDONE:
99
0
        return "The specified child process is not done executing";
100
0
    case APR_TIMEUP:
101
0
        return "The timeout specified has expired";
102
0
    case APR_INCOMPLETE:
103
0
        return "Partial results are valid but processing is incomplete";
104
0
    case APR_BADCH:
105
0
        return "Bad character specified on command line";
106
0
    case APR_BADARG:
107
0
        return "Missing parameter for the specified command line option";
108
0
    case APR_EOF:
109
0
        return "End of file found";
110
0
    case APR_NOTFOUND:
111
0
        return "Could not find specified socket in poll list.";
112
0
    case APR_ANONYMOUS:
113
0
        return "Shared memory is implemented anonymously";
114
0
    case APR_FILEBASED:
115
0
        return "Shared memory is implemented using files";
116
0
    case APR_KEYBASED:
117
0
        return "Shared memory is implemented using a key system";
118
0
    case APR_EINIT:
119
0
        return
120
0
      "There is no error, this value signifies an initialized "
121
0
      "error code";
122
0
    case APR_ENOTIMPL:
123
0
        return "This function has not been implemented on this platform";
124
0
    case APR_EMISMATCH:
125
0
        return "passwords do not match";
126
0
    case APR_EABSOLUTE:
127
0
        return "The given path is absolute";
128
0
    case APR_ERELATIVE:
129
0
        return "The given path is relative";
130
0
    case APR_EINCOMPLETE:
131
0
        return "The given path is incomplete";
132
0
    case APR_EABOVEROOT:
133
0
        return "The given path was above the root path";
134
0
    case APR_EBADPATH:
135
0
        return "The given path is misformatted or contained invalid characters";
136
0
    case APR_EPATHWILD:
137
0
        return "The given path contained wildcard characters";
138
0
    case APR_EBUSY:
139
0
        return "The given lock was busy.";
140
0
    case APR_EPROC_UNKNOWN:
141
0
        return "The process is not recognized.";
142
0
    case APR_EALREADY:
143
0
        return "Operation already in progress";
144
0
    case APR_EGENERAL:
145
0
        return "Internal error (specific information not available)";
146
147
/* APR Util error codes */
148
0
    case APR_ECRYPT:
149
0
        return "Internal error in the crypto subsystem (specific information not available)";
150
0
    case APR_ENOENGINE:
151
0
        return "No engine found for crypto subsystem";
152
0
    case APR_EINITENGINE:
153
0
        return "Failed to init engine for crypto subsystem";
154
155
0
    default:
156
0
        return "Error string not specified yet";
157
0
    }
158
0
}
159
160
161
#ifdef OS2
162
#include <ctype.h>
163
164
int apr_canonical_error(apr_status_t err);
165
166
static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err)
167
{
168
  char result[200];
169
  unsigned char message[HUGE_STRING_LEN];
170
  ULONG len;
171
  char *pos;
172
  int c;
173
174
  if (err >= 10000 && err < 12000) {  /* socket error codes */
175
      return stuffbuffer(buf, bufsize,
176
                         strerror(apr_canonical_error(err+APR_OS_START_SYSERR)));
177
  }
178
  else if (DosGetMessage(NULL, 0, message, HUGE_STRING_LEN, err,
179
       "OSO001.MSG", &len) == 0) {
180
      len--;
181
      message[len] = 0;
182
      pos = result;
183
184
      if (len >= sizeof(result))
185
        len = sizeof(result) - 1;
186
187
      for (c=0; c<len; c++) {
188
    /* skip multiple whitespace */
189
          while (apr_isspace(message[c]) && apr_isspace(message[c+1]))
190
              c++;
191
          *(pos++) = apr_isspace(message[c]) ? ' ' : message[c];
192
      }
193
194
      *pos = 0;
195
  }
196
  else {
197
      sprintf(result, "OS/2 error %d", err);
198
  }
199
200
  /* Stuff the string into the caller supplied buffer, then return
201
   * a pointer to it.
202
   */
203
  return stuffbuffer(buf, bufsize, result);
204
}
205
206
#elif defined(WIN32) || (defined(NETWARE) && defined(USE_WINSOCK))
207
208
static const struct {
209
    apr_status_t code;
210
    const char *msg;
211
} gaErrorList[] = {
212
    {WSAEINTR,           "Interrupted system call"},
213
    {WSAEBADF,           "Bad file number"},
214
    {WSAEACCES,          "Permission denied"},
215
    {WSAEFAULT,          "Bad address"},
216
    {WSAEINVAL,          "Invalid argument"},
217
    {WSAEMFILE,          "Too many open sockets"},
218
    {WSAEWOULDBLOCK,     "Operation would block"},
219
    {WSAEINPROGRESS,     "Operation now in progress"},
220
    {WSAEALREADY,        "Operation already in progress"},
221
    {WSAENOTSOCK,        "Socket operation on non-socket"},
222
    {WSAEDESTADDRREQ,    "Destination address required"},
223
    {WSAEMSGSIZE,        "Message too long"},
224
    {WSAEPROTOTYPE,      "Protocol wrong type for socket"},
225
    {WSAENOPROTOOPT,     "Bad protocol option"},
226
    {WSAEPROTONOSUPPORT, "Protocol not supported"},
227
    {WSAESOCKTNOSUPPORT, "Socket type not supported"},
228
    {WSAEOPNOTSUPP,      "Operation not supported on socket"},
229
    {WSAEPFNOSUPPORT,    "Protocol family not supported"},
230
    {WSAEAFNOSUPPORT,    "Address family not supported"},
231
    {WSAEADDRINUSE,      "Address already in use"},
232
    {WSAEADDRNOTAVAIL,   "Can't assign requested address"},
233
    {WSAENETDOWN,        "Network is down"},
234
    {WSAENETUNREACH,     "Network is unreachable"},
235
    {WSAENETRESET,       "Net connection reset"},
236
    {WSAECONNABORTED,    "Software caused connection abort"},
237
    {WSAECONNRESET,      "Connection reset by peer"},
238
    {WSAENOBUFS,         "No buffer space available"},
239
    {WSAEISCONN,         "Socket is already connected"},
240
    {WSAENOTCONN,        "Socket is not connected"},
241
    {WSAESHUTDOWN,       "Can't send after socket shutdown"},
242
    {WSAETOOMANYREFS,    "Too many references, can't splice"},
243
    {WSAETIMEDOUT,       "Connection timed out"},
244
    {WSAECONNREFUSED,    "Connection refused"},
245
    {WSAELOOP,           "Too many levels of symbolic links"},
246
    {WSAENAMETOOLONG,    "File name too long"},
247
    {WSAEHOSTDOWN,       "Host is down"},
248
    {WSAEHOSTUNREACH,    "No route to host"},
249
    {WSAENOTEMPTY,       "Directory not empty"},
250
    {WSAEPROCLIM,        "Too many processes"},
251
    {WSAEUSERS,          "Too many users"},
252
    {WSAEDQUOT,          "Disc quota exceeded"},
253
    {WSAESTALE,          "Stale NFS file handle"},
254
    {WSAEREMOTE,         "Too many levels of remote in path"},
255
    {WSASYSNOTREADY,     "Network system is unavailable"},
256
    {WSAVERNOTSUPPORTED, "Winsock version out of range"},
257
    {WSANOTINITIALISED,  "WSAStartup not yet called"},
258
    {WSAEDISCON,         "Graceful shutdown in progress"},
259
    {WSAHOST_NOT_FOUND,  "Host not found"},
260
    {WSANO_DATA,         "No host data of that type was found"},
261
    {0,                  NULL}
262
};
263
264
265
static char *apr_os_strerror(char *buf, apr_size_t bufsize, apr_status_t errcode)
266
{
267
    apr_size_t len=0, i;
268
269
#ifndef NETWARE
270
    len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
271
                      | FORMAT_MESSAGE_IGNORE_INSERTS,
272
                        NULL,
273
                        errcode,
274
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
275
                        buf,
276
                        (DWORD)bufsize,
277
                        NULL);
278
#endif
279
280
    if (!len) {
281
        for (i = 0; gaErrorList[i].msg; ++i) {
282
            if (gaErrorList[i].code == errcode) {
283
                apr_cpystrn(buf, gaErrorList[i].msg, bufsize);
284
                len = strlen(buf);
285
                break;
286
            }
287
        }
288
    }
289
290
    if (len) {
291
        /* FormatMessage put the message in the buffer, but it may
292
         * have embedded a newline (\r\n), and possible more than one.
293
         * Remove the newlines replacing them with a space. This is not
294
         * as visually perfect as moving all the remaining message over,
295
         * but more efficient.
296
         */
297
        i = len;
298
        while (i) {
299
            i--;
300
            if ((buf[i] == '\r') || (buf[i] == '\n'))
301
                buf[i] = ' ';
302
        }
303
    }
304
    else {
305
        /* Windows didn't provide us with a message.  Even stuff like                    * WSAECONNREFUSED won't get a message.
306
         */
307
        apr_snprintf(buf, bufsize, "Unrecognized Win32 error code %d", errcode);
308
    }
309
310
    return buf;
311
}
312
313
#else
314
/* On Unix, apr_os_strerror() handles error codes from the resolver
315
 * (h_errno).
316
 */
317
static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err)
318
0
{
319
#ifdef HAVE_HSTRERROR
320
    return stuffbuffer(buf, bufsize, hstrerror(err));
321
#else /* HAVE_HSTRERROR */
322
0
    const char *msg;
323
324
0
    switch(err) {
325
0
    case HOST_NOT_FOUND:
326
0
        msg = "Unknown host";
327
0
        break;
328
0
#if defined(NO_DATA)
329
0
    case NO_DATA:
330
#if defined(NO_ADDRESS) && (NO_DATA != NO_ADDRESS)
331
    case NO_ADDRESS:
332
#endif
333
0
        msg = "No address for host";
334
0
        break;
335
#elif defined(NO_ADDRESS)
336
    case NO_ADDRESS:
337
        msg = "No address for host";
338
        break;
339
#endif /* NO_DATA */
340
0
    default:
341
0
        msg = "Unrecognized resolver error";
342
0
    }
343
0
    return stuffbuffer(buf, bufsize, msg);
344
0
#endif /* HAVE_STRERROR */
345
0
}
346
#endif
347
348
#if defined(HAVE_STRERROR_R) && defined(STRERROR_R_RC_INT) && !defined(BEOS)
349
/* AIX and Tru64 style */
350
static char *native_strerror(apr_status_t statcode, char *buf,
351
                             apr_size_t bufsize)
352
{
353
    if (strerror_r(statcode, buf, bufsize) < 0) {
354
        return stuffbuffer(buf, bufsize,
355
                           "APR does not understand this error code");
356
    }
357
    else {
358
        return buf;
359
    }
360
}
361
#elif defined(HAVE_STRERROR_R)
362
/* glibc style */
363
364
/* BeOS has the function available, but it doesn't provide
365
 * the prototype publicly (doh!), so to avoid a build warning
366
 * we add a suitable prototype here.
367
 */
368
#if defined(BEOS)
369
const char *strerror_r(apr_status_t, char *, apr_size_t);
370
#endif
371
372
static char *native_strerror(apr_status_t statcode, char *buf,
373
                             apr_size_t bufsize)
374
0
{
375
0
    const char *msg;
376
377
0
    buf[0] = '\0';
378
0
    msg = strerror_r(statcode, buf, bufsize);
379
0
    if (buf[0] == '\0') { /* libc didn't use our buffer */
380
0
        return stuffbuffer(buf, bufsize, msg);
381
0
    }
382
0
    else {
383
0
        return buf;
384
0
    }
385
0
}
386
#else
387
/* plain old strerror();
388
 * thread-safe on some platforms (e.g., Solaris, OS/390)
389
 */
390
static char *native_strerror(apr_status_t statcode, char *buf,
391
                             apr_size_t bufsize)
392
{
393
    const char *err = strerror(statcode);
394
    if (err) {
395
        return stuffbuffer(buf, bufsize, err);
396
    } else {
397
        return stuffbuffer(buf, bufsize,
398
                           "APR does not understand this error code");
399
    }
400
}
401
#endif
402
403
APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
404
                                 apr_size_t bufsize)
405
0
{
406
0
    if (statcode < APR_OS_START_ERROR) {
407
0
        return native_strerror(statcode, buf, bufsize);
408
0
    }
409
0
    else if (statcode < APR_OS_START_USERERR) {
410
0
        return stuffbuffer(buf, bufsize, apr_error_string(statcode));
411
0
    }
412
0
    else if (statcode < APR_OS_START_EAIERR) {
413
0
        return stuffbuffer(buf, bufsize, "APR does not understand this error code");
414
0
    }
415
0
    else if (statcode < APR_OS_START_SYSERR) {
416
0
#if defined(HAVE_GAI_STRERROR)
417
0
        statcode -= APR_OS_START_EAIERR;
418
0
#if defined(NEGATIVE_EAI)
419
0
        statcode = -statcode;
420
0
#endif
421
0
        return stuffbuffer(buf, bufsize, gai_strerror(statcode));
422
#else
423
        return stuffbuffer(buf, bufsize, "APR does not understand this error code");
424
#endif
425
0
    }
426
0
    else {
427
0
        return apr_os_strerror(buf, bufsize, statcode - APR_OS_START_SYSERR);
428
0
    }
429
0
}
430