]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/berrno.c
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / lib / berrno.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5    Copyright (C) 2004-2014 Free Software Foundation Europe e.V.
6
7    The original author of Bacula is Kern Sibbald, with contributions
8    from many others, a complete list can be found in the file AUTHORS.
9
10    You may use this file and others of this release according to the
11    license defined in the LICENSE file, which includes the Affero General
12    Public License, v3.0 ("AGPLv3") and some additional permissions and
13    terms pursuant to its AGPLv3 Section 7.
14
15    This notice must be preserved when any source code is 
16    conveyed and/or propagated.
17
18    Bacula(R) is a registered trademark of Kern Sibbald.
19 */
20 /*
21  *  Bacula errno handler
22  *
23  *    berrno is a simplistic errno handler that works for
24  *      Unix, Win32, and Bacula bpipes.
25  *
26  *    See berrno.h for how to use berrno.
27  *
28  *   Kern Sibbald, July MMIV
29  *
30  *
31  */
32
33 #include "bacula.h"
34
35 #ifndef HAVE_WIN32
36 extern const char *get_signal_name(int sig);
37 extern int num_execvp_errors;
38 extern int execvp_errors[];
39 #endif
40
41 const char *berrno::bstrerror()
42 {
43    *m_buf = 0;
44 #ifdef HAVE_WIN32
45    if (m_berrno & (b_errno_win32 | b_errno_WSA)) {
46       format_win32_message();
47       return (const char *)m_buf;
48    }
49 #else
50    int stat = 0;
51
52    if (m_berrno & b_errno_exit) {
53       stat = (m_berrno & ~b_errno_exit);       /* remove bit */
54       if (stat == 0) {
55          return _("Child exited normally.");    /* this really shouldn't happen */
56       } else {
57          /* Maybe an execvp failure */
58          if (stat >= 200) {
59             if (stat < 200 + num_execvp_errors) {
60                m_berrno = execvp_errors[stat - 200];
61             } else {
62                return _("Unknown error during program execvp");
63             }
64          } else {
65             Mmsg(m_buf, _("Child exited with code %d"), stat);
66             return m_buf;
67          }
68          /* If we drop out here, m_berrno is set to an execvp errno */
69       }
70    }
71    if (m_berrno & b_errno_signal) {
72       stat = (m_berrno & ~b_errno_signal);        /* remove bit */
73       Mmsg(m_buf, _("Child died from signal %d: %s"), stat, get_signal_name(stat));
74       return m_buf;
75    }
76 #endif
77    /* Normal errno */
78    if (b_strerror(m_berrno, m_buf, sizeof_pool_memory(m_buf)) < 0) {
79       return _("Invalid errno. No error message possible.");
80    }
81    return m_buf;
82 }
83
84 void berrno::format_win32_message()
85 {
86 #ifdef HAVE_WIN32
87    LPVOID msg;
88    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
89        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
90        NULL,
91        m_berrno & b_errno_WSA ? WSAGetLastError() : GetLastError(),
92        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
93        (LPTSTR)&msg,
94        0,
95        NULL);
96    pm_strcpy(&m_buf, (const char *)msg);
97    LocalFree(msg);
98 #endif
99 }
100
101 #ifdef TEST_PROGRAM
102
103 int main()
104 {
105 }
106 #endif