1/*	$NetBSD$	*/
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  */
84static MSG_CLEANUP_FN bounce_cleanup_func;	/* saved callback */
85VSTRING *bounce_cleanup_path;		/* saved path name */
86
87/* bounce_cleanup_callback - run-time callback to cleanup logfile */
88
89static 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
107void    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
126static 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
139void    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
161void    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