xref: /netbsd-src/external/ibm-public/postfix/dist/src/bounce/bounce_cleanup.c (revision 41fbaed053f8fbfdf9d2a4ee0a7386a3c83f8505)
1 /*	$NetBSD: bounce_cleanup.c,v 1.1.1.1 2009/06/23 10:08:42 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	bounce_cleanup 3
6 /* SUMMARY
7 /*	cleanup logfile upon error
8 /* SYNOPSIS
9 /*	#include "bounce_service.h"
10 /*
11 /*	int	bounce_cleanup_registered()
12 /*
13 /*	void	bounce_cleanup_register(queue_id)
14 /*	char	*queue_id;
15 /*
16 /*	void	bounce_cleanup_log(void)
17 /*
18 /*	void	bounce_cleanup_unregister(void)
19 /* DESCRIPTION
20 /*	This module implements support for deleting the current
21 /*	bounce logfile in case of errors, and upon the arrival
22 /*	of a SIGTERM signal (shutdown).
23 /*
24 /*	bounce_cleanup_register() registers a callback routine with the
25 /*	run-time error handler, for automatic logfile removal in case
26 /*	of a fatal run-time error.
27 /*
28 /*	bounce_cleanup_unregister() cleans up storage used by
29 /*	bounce_cleanup_register().
30 /*
31 /*	In-between bounce_cleanup_register() and bounce_cleanup_unregister()
32 /*	calls, a call of bounce_cleanup_log() will delete the registered
33 /*	bounce logfile.
34 /*
35 /*	bounce_cleanup_registered() returns non-zero when a cleanup
36 /*	trap has been set.
37 /* DIAGNOSTICS
38 /*	Fatal error: all file access errors. Panic: nested calls of
39 /*	bounce_cleanup_register(); any calls of bounce_cleanup_unregister()
40 /*	or bounce_cleanup_log() without preceding bounce_cleanup_register()
41 /*	call.
42 /* BUGS
43 /* SEE ALSO
44 /*	master(8) process manager
45 /* LICENSE
46 /* .ad
47 /* .fi
48 /*	The Secure Mailer license must be distributed with this software.
49 /* AUTHOR(S)
50 /*	Wietse Venema
51 /*	IBM T.J. Watson Research
52 /*	P.O. Box 704
53 /*	Yorktown Heights, NY 10598, USA
54 /*--*/
55 
56 /* System library. */
57 
58 #include <sys_defs.h>
59 #include <unistd.h>
60 #include <signal.h>
61 #include <stdlib.h>
62 
63 /* Utility library. */
64 
65 #include <msg.h>
66 #include <mymalloc.h>
67 #include <vstring.h>
68 
69 /* Global library. */
70 
71 #include <mail_queue.h>
72 
73 /* Application-specific. */
74 
75 #include "bounce_service.h"
76 
77  /*
78   * Support for removing a logfile when an update fails. In order to do this,
79   * we save a copy of the currently-open logfile name, and register a
80   * callback function pointer with the run-time error handler. The saved
81   * pathname is made global so that the application can see whether or not a
82   * trap was set up.
83   */
84 static MSG_CLEANUP_FN bounce_cleanup_func;	/* saved callback */
85 VSTRING *bounce_cleanup_path;		/* saved path name */
86 
87 /* bounce_cleanup_callback - run-time callback to cleanup logfile */
88 
bounce_cleanup_callback(void)89 static void bounce_cleanup_callback(void)
90 {
91 
92     /*
93      * Remove the logfile.
94      */
95     if (bounce_cleanup_path)
96 	bounce_cleanup_log();
97 
98     /*
99      * Execute the saved cleanup action.
100      */
101     if (bounce_cleanup_func)
102 	bounce_cleanup_func();
103 }
104 
105 /* bounce_cleanup_log - clean up the logfile */
106 
bounce_cleanup_log(void)107 void    bounce_cleanup_log(void)
108 {
109     const char *myname = "bounce_cleanup_log";
110 
111     /*
112      * Sanity checks.
113      */
114     if (bounce_cleanup_path == 0)
115 	msg_panic("%s: no cleanup context", myname);
116 
117     /*
118      * This function may be called before a logfile is created or after it
119      * has been deleted, so do not complain.
120      */
121     (void) unlink(vstring_str(bounce_cleanup_path));
122 }
123 
124 /* bounce_cleanup_sig - signal handler */
125 
bounce_cleanup_sig(int sig)126 static void bounce_cleanup_sig(int sig)
127 {
128 
129     /*
130      * Running as a signal handler - don't do complicated stuff.
131      */
132     if (bounce_cleanup_path)
133 	(void) unlink(vstring_str(bounce_cleanup_path));
134     _exit(sig);
135 }
136 
137 /* bounce_cleanup_register - register logfile to clean up */
138 
bounce_cleanup_register(char * service,char * queue_id)139 void    bounce_cleanup_register(char *service, char *queue_id)
140 {
141     const char *myname = "bounce_cleanup_register";
142 
143     /*
144      * Sanity checks.
145      */
146     if (bounce_cleanup_path)
147 	msg_panic("%s: nested call", myname);
148 
149     /*
150      * Save a copy of the logfile path, and of the last callback function
151      * pointer registered with the run-time error handler.
152      */
153     bounce_cleanup_path = vstring_alloc(10);
154     (void) mail_queue_path(bounce_cleanup_path, service, queue_id);
155     bounce_cleanup_func = msg_cleanup(bounce_cleanup_callback);
156     signal(SIGTERM, bounce_cleanup_sig);
157 }
158 
159 /* bounce_cleanup_unregister - unregister logfile to clean up */
160 
bounce_cleanup_unregister(void)161 void    bounce_cleanup_unregister(void)
162 {
163     const char *myname = "bounce_cleanup_unregister";
164 
165     /*
166      * Sanity checks.
167      */
168     if (bounce_cleanup_path == 0)
169 	msg_panic("%s: no cleanup context", myname);
170 
171     /*
172      * Restore the saved callback function pointer, and release storage for
173      * the saved logfile pathname.
174      */
175     signal(SIGTERM, SIG_DFL);
176     (void) msg_cleanup(bounce_cleanup_func);
177     vstring_free(bounce_cleanup_path);
178     bounce_cleanup_path = 0;
179 }
180