1b6f9478a02e663daa1a2699d1cd6226b3aee251
[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.18 2003/04/27 01:17:19 martinea 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) P((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 (*logerror) P((char *)) = NULL;
46
47 void set_pname(p)
48 char *p;
49 {
50     pname = p;
51 }
52
53 char *get_pname()
54 {
55     return pname;
56 }
57
58 void set_logerror(f)
59 void (*f) P((char *));
60 {
61     logerror = f;
62 }
63
64
65 static void output_error_message(msg)
66 char *msg;
67 {
68     /* print and/or log message */
69
70     if((erroutput_type & ERR_AMANDALOG) != 0 && logerror != NULL) {
71         (*logerror)(msg);
72     }
73
74     if(erroutput_type & ERR_SYSLOG) {
75 #ifdef LOG_AUTH
76         openlog(get_pname(), LOG_PID, LOG_AUTH);
77 #else
78         openlog(get_pname(), LOG_PID);
79 #endif
80         syslog(LOG_NOTICE, "%s", msg);
81         closelog();
82     }
83
84     if(erroutput_type & ERR_INTERACTIVE) {
85         fprintf(stderr, "%s: %s\n", get_pname(), msg);
86         fflush(stderr);
87     }
88
89     if(dbfp() != NULL) {
90         dbprintf(("%s: %s\n", debug_prefix_time(NULL), msg));
91         dbclose();
92     }
93 }
94
95
96 /*
97  * Prints an error message, calls the functions installed via onerror(),
98  * then exits.
99  */
100 printf_arglist_function(void error, const char *, format)
101 {
102     va_list argp;
103     int i;
104     char linebuf[STR_SIZE];
105
106
107     /* format and output the error message */
108
109     arglist_start(argp, format);
110     vsnprintf(linebuf, sizeof(linebuf), format, argp);
111     arglist_end(argp);
112     output_error_message(linebuf);
113
114     /* traverse function list, calling in reverse order */
115
116     for(i=MAXFUNCS-1; i >= 0; i--) {
117         if(onerr[i] != NULL) (*onerr[i])();
118     }
119
120     /* terminate */
121     exit(1);
122 }
123
124
125 /*
126  * Prints an error message, calls the functions installed via onerror(),
127  * then calls abort() to drop core.
128  */
129 printf_arglist_function(void errordump, const char *, format)
130 {
131     va_list argp;
132     int i;
133     char linebuf[STR_SIZE];
134
135     /* format error message */
136
137     arglist_start(argp, format);
138     vsnprintf(linebuf, sizeof(linebuf), format, argp);
139     arglist_end(argp);
140     output_error_message(linebuf);
141
142     /* traverse function list, calling in reverse order */
143
144     for(i=MAXFUNCS-1; i >= 0; i--) {
145         if(onerr[i] != NULL) (*onerr[i])();
146     }
147
148     /* terminate and drop core */
149     abort();
150 }
151
152
153 int onerror(errf)
154 void (*errf) P((void));
155 /*
156  * Register function to be called when error is called.  Up to MAXFUNCS
157  * functions can be registered.  If there isn't room in the table, onerror
158  * returns -1, otherwise it returns 0.
159  *
160  * The resemblance to atexit() is on purpose.  I wouldn't need onerror()
161  * if everyone had atexit().  Bummer.
162  */
163 {
164     int i;
165
166     for(i=0; i < MAXFUNCS; i++)         /* find empty slot */
167         if(onerr[i] == NULL) {
168             onerr[i] = errf;
169             return 0;
170         }
171
172     return -1;                          /* full table */
173 }