diff options
Diffstat (limited to 'src/bounce/bounce_cleanup.c')
-rw-r--r-- | src/bounce/bounce_cleanup.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/src/bounce/bounce_cleanup.c b/src/bounce/bounce_cleanup.c new file mode 100644 index 0000000..9fb900b --- /dev/null +++ b/src/bounce/bounce_cleanup.c @@ -0,0 +1,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; +} |