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)
{
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)
{
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)
{
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;
}
|