summaryrefslogtreecommitdiffstats
path: root/src/bounce/bounce_cleanup.c
blob: 9fb900bb0abcbedf5c5b06286840dc7b55483661 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*++
/* NAME
/*	bounce_cleanup 3
/* SUMMARY
/*	cleanup logfile upon error
/* SYNOPSIS
/*	#include "bounce_service.h"
/*
/*	int	bounce_cleanup_registered()
/*
/*	void	bounce_cleanup_register(queue_id)
/*	char	*queue_id;
/*
/*	void	bounce_cleanup_log(void)
/*
/*	void	bounce_cleanup_unregister(void)
/* DESCRIPTION
/*	This module implements support for deleting the current
/*	bounce logfile in case of errors, and upon the arrival
/*	of a SIGTERM signal (shutdown).
/*
/*	bounce_cleanup_register() registers a callback routine with the
/*	run-time error handler, for automatic logfile removal in case
/*	of a fatal run-time error.
/*
/*	bounce_cleanup_unregister() cleans up storage used by
/*	bounce_cleanup_register().
/*
/*	In-between bounce_cleanup_register() and bounce_cleanup_unregister()
/*	calls, a call of bounce_cleanup_log() will delete the registered
/*	bounce logfile.
/*
/*	bounce_cleanup_registered() returns non-zero when a cleanup
/*	trap has been set.
/* DIAGNOSTICS
/*	Fatal error: all file access errors. Panic: nested calls of
/*	bounce_cleanup_register(); any calls of bounce_cleanup_unregister()
/*	or bounce_cleanup_log() without preceding bounce_cleanup_register()
/*	call.
/* BUGS
/* SEE ALSO
/*	master(8) process manager
/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*--*/

/* System library. */

#include <sys_defs.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

/* Utility library. */

#include <msg.h>
#include <mymalloc.h>
#include <vstring.h>

/* Global library. */

#include <mail_queue.h>

/* Application-specific. */

#include "bounce_service.h"

 /*
  * Support for removing a logfile when an update fails. In order to do this,
  * we save a copy of the currently-open logfile name, and register a
  * callback function pointer with the run-time error handler. The saved
  * pathname is made global so that the application can see whether or not a
  * trap was set up.
  */
static MSG_CLEANUP_FN bounce_cleanup_func;	/* saved callback */
VSTRING *bounce_cleanup_path;		/* saved path name */

/* bounce_cleanup_callback - run-time callback to cleanup logfile */

static void bounce_cleanup_callback(void)
{

    /*
     * Remove the logfile.
     */
    if (bounce_cleanup_path)
	bounce_cleanup_log();

    /*
     * Execute the saved cleanup action.
     */
    if (bounce_cleanup_func)
	bounce_cleanup_func();
}

/* bounce_cleanup_log - clean up the logfile */

void    bounce_cleanup_log(void)
{
    const char *myname = "bounce_cleanup_log";

    /*
     * Sanity checks.
     */
    if (bounce_cleanup_path == 0)
	msg_panic("%s: no cleanup context", myname);

    /*
     * This function may be called before a logfile is created or after it
     * has been deleted, so do not complain.
     */
    (void) unlink(vstring_str(bounce_cleanup_path));
}

/* bounce_cleanup_sig - signal handler */

static void bounce_cleanup_sig(int sig)
{

    /*
     * Running as a signal handler - don't do complicated stuff.
     */
    if (bounce_cleanup_path)
	(void) unlink(vstring_str(bounce_cleanup_path));
    _exit(sig);
}

/* bounce_cleanup_register - register logfile to clean up */

void    bounce_cleanup_register(char *service, char *queue_id)
{
    const char *myname = "bounce_cleanup_register";

    /*
     * Sanity checks.
     */
    if (bounce_cleanup_path)
	msg_panic("%s: nested call", myname);

    /*
     * Save a copy of the logfile path, and of the last callback function
     * pointer registered with the run-time error handler.
     */
    bounce_cleanup_path = vstring_alloc(10);
    (void) mail_queue_path(bounce_cleanup_path, service, queue_id);
    bounce_cleanup_func = msg_cleanup(bounce_cleanup_callback);
    signal(SIGTERM, bounce_cleanup_sig);
}

/* bounce_cleanup_unregister - unregister logfile to clean up */

void    bounce_cleanup_unregister(void)
{
    const char *myname = "bounce_cleanup_unregister";

    /*
     * Sanity checks.
     */
    if (bounce_cleanup_path == 0)
	msg_panic("%s: no cleanup context", myname);

    /*
     * Restore the saved callback function pointer, and release storage for
     * the saved logfile pathname.
     */
    signal(SIGTERM, SIG_DFL);
    (void) msg_cleanup(bounce_cleanup_func);
    vstring_free(bounce_cleanup_path);
    bounce_cleanup_path = 0;
}