Imported Upstream version 2.5.1
[debian/amanda] / common-src / error.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author: James da Silva, Systems Design and Analysis Group
24  *                         Computer Science Department
25  *                         University of Maryland at College Park
26  */
27 /*
28  * $Id: error.c,v 1.19 2006/05/25 01:47:11 johnfranks Exp $
29  *
30  * error handling common to Amanda programs
31  */
32 #include "amanda.h"
33 #include "arglist.h"
34
35 #define MAXFUNCS 8
36
37 typedef void (*voidfunc)(void);
38 static voidfunc onerr[MAXFUNCS] = 
39     { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
40
41 int erroutput_type = ERR_INTERACTIVE;
42
43 static char *pname = "unknown";
44
45 static void output_error_message(char *msg);
46
47 static void (*logerror)(char *) = NULL;
48
49 void
50 set_pname(
51     char *      p)
52 {
53     pname = p;
54 }
55
56 char *
57 get_pname(void)
58 {
59     return pname;
60 }
61
62 void
63 set_logerror(
64     void (*f)(char *))
65 {
66     logerror = f;
67 }
68
69
70 static void
71 output_error_message(
72     char *      msg)
73 {
74     /* print and/or log message */
75
76     if((erroutput_type & ERR_AMANDALOG) != 0 && logerror != NULL) {
77         (*logerror)(msg);
78     }
79
80     if(erroutput_type & ERR_SYSLOG) {
81 #ifdef LOG_AUTH
82         openlog(get_pname(), LOG_PID, LOG_AUTH);
83 #else
84         openlog(get_pname(), LOG_PID, 0);
85 #endif
86         syslog(LOG_NOTICE, "%s", msg);
87         closelog();
88     }
89
90     if(erroutput_type & ERR_INTERACTIVE) {
91         fprintf(stderr, "%s: %s\n", get_pname(), msg);
92         fflush(stderr);
93     }
94
95     if(dbfp() != NULL) {
96         dbprintf(("%s: %s\n", debug_prefix_time(NULL), msg));
97         dbclose();
98     }
99 }
100
101
102 /*
103  * Prints an error message, calls the functions installed via onerror(),
104  * then exits.
105  */
106 printf_arglist_function(void error, const char *, format)
107 {
108     va_list argp;
109     int i;
110     char linebuf[STR_SIZE];
111
112
113     /* format and output the error message */
114
115     arglist_start(argp, format);
116     vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
117     arglist_end(argp);
118     output_error_message(linebuf);
119
120     /* traverse function list, calling in reverse order */
121
122     for(i=MAXFUNCS-1; i >= 0; i--) {
123         if(onerr[i] != NULL) (*onerr[i])();
124     }
125
126     /* terminate */
127     exit(1);
128 }
129
130
131 /*
132  * Prints an error message, calls the functions installed via onerror(),
133  * then calls abort() to drop core.
134  */
135 printf_arglist_function(void errordump, const char *, format)
136 {
137     va_list argp;
138     int i;
139     char linebuf[STR_SIZE];
140
141     /* format error message */
142
143     arglist_start(argp, format);
144     vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
145     arglist_end(argp);
146     output_error_message(linebuf);
147
148     /* traverse function list, calling in reverse order */
149
150     for(i=MAXFUNCS-1; i >= 0; i--) {
151         if(onerr[i] != NULL) (*onerr[i])();
152     }
153
154     /* terminate and drop core */
155     abort();
156 }
157
158
159 /*
160  * Register function to be called when error is called.  Up to MAXFUNCS
161  * functions can be registered.  If there isn't room in the table, onerror
162  * returns -1, otherwise it returns 0.
163  *
164  * The resemblance to atexit() is on purpose.  I wouldn't need onerror()
165  * if everyone had atexit().  Bummer.
166  */
167
168 int
169 onerror(
170     void        (*errf)(void))
171 {
172     int i;
173
174     for(i=0; i < MAXFUNCS; i++)         /* find empty slot */
175         if(onerr[i] == NULL) {
176             onerr[i] = errf;
177             return 0;
178         }
179
180     return -1;                          /* full table */
181 }