diff options
Diffstat (limited to '')
-rw-r--r-- | src/global/dsn.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/src/global/dsn.c b/src/global/dsn.c new file mode 100644 index 0000000..32da936 --- /dev/null +++ b/src/global/dsn.c @@ -0,0 +1,189 @@ +/*++ +/* NAME +/* dsn +/* SUMMARY +/* RFC-compliant delivery status information +/* SYNOPSIS +/* #include <dsn.h> +/* +/* typedef struct { +/* .in +4 +/* const char *status; /* RFC 3463 status */ +/* const char *action; /* null or RFC 3464 action */ +/* const char *reason; /* human-readable text */ +/* const char *dtype; /* null or diagnostic type */ +/* const char *dtext; /* null or diagnostic code */ +/* const char *mtype; /* null or MTA type */ +/* const char *mname; /* null or remote MTA */ +/* .in -4 +/* } DSN; +/* +/* DSN *dsn_create(status, action, reason, dtype, dtext, mtype, mname) +/* const char *status; +/* const char *action; +/* const char *reason; +/* const char *dtype; +/* const char *dtext; +/* const char *mtype; +/* const char *mname; +/* +/* DSN *DSN_COPY(dsn) +/* DSN *dsn; +/* +/* void dsn_free(dsn) +/* DSN *dsn; +/* +/* DSN *DSN_ASSIGN(dsn, status, action, reason, dtype, dtext, +/* mtype, mname) +/* DSN *dsn; +/* const char *status; +/* const char *action; +/* const char *reason; +/* const char *dtype; +/* const char *dtext; +/* const char *mtype; +/* const char *mname; +/* +/* DSN *DSN_SIMPLE(dsn, status, action, reason) +/* DSN *dsn; +/* const char *status; +/* const char *action; +/* const char *reason; +/* DESCRIPTION +/* This module maintains delivery error information. For a +/* description of structure field members see "Arguments" +/* below. Function-like names spelled in upper case are macros. +/* These may evaluate some arguments more than once. +/* +/* dsn_create() creates a DSN structure and copies its arguments. +/* The DSN structure should be destroyed with dsn_free(). +/* +/* DSN_COPY() creates a deep copy of its argument. +/* +/* dsn_free() destroys a DSN structure and makes its storage +/* available for reuse. +/* +/* DSN_ASSIGN() updates a DSN structure and DOES NOT copy +/* arguments or free memory. The result DSN structure must +/* NOT be passed to dsn_free(). DSN_ASSIGN() is typically used +/* for stack-based short-lived storage. +/* +/* DSN_SIMPLE() takes the minimally required subset of all the +/* attributes and sets the rest to empty strings. +/* This is a wrapper around the DSN_ASSIGN() macro. +/* +/* Arguments: +/* .IP reason +/* Human-readable text, used for logging purposes, and for +/* updating the message-specific \fBbounce\fR or \fIdefer\fR +/* logfile. +/* .IP status +/* Enhanced status code as specified in RFC 3463. +/* .IP action +/* DSN_NO_ACTION, empty string, or action as defined in RFC 3464. +/* If no action is specified, a default action is chosen. +/* .IP dtype +/* DSN_NO_DTYPE, empty string, or diagnostic code type as +/* specified in RFC 3464. +/* .IP dtext +/* DSN_NO_DTEXT, empty string, or diagnostic code as specified +/* in RFC 3464. +/* .IP mtype +/* DSN_NO_MTYPE, empty string, DSN_MTYPE_DNS or DSN_MTYPE_UNIX. +/* .IP mname +/* DSN_NO_MNAME, empty string, or remote MTA as specified in +/* RFC 3464. +/* DIAGNOSTICS +/* Panic: null or empty status or reason. +/* Fatal: out of memory. +/* 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> + +/* Utility library. */ + +#include <msg.h> +#include <mymalloc.h> + +/* Global library. */ + +#include <dsn.h> + +/* dsn_create - create DSN structure */ + +DSN *dsn_create(const char *status, const char *action, const char *reason, + const char *dtype, const char *dtext, + const char *mtype, const char *mname) +{ + const char *myname = "dsn_create"; + DSN *dsn; + + dsn = (DSN *) mymalloc(sizeof(*dsn)); + + /* + * Status and reason must not be empty. Other members may be empty + * strings. + * + * Early implementations represented unavailable information with null + * pointers. This resulted in code that was difficult to maintain. We now + * use empty strings instead. For safety sake we keep the null pointer + * test for input, but we always convert to empty string on output. + */ +#define NULL_OR_EMPTY(s) ((s) == 0 || *(s) == 0) + + if (NULL_OR_EMPTY(status)) + msg_panic("%s: null dsn status", myname); + else + dsn->status = mystrdup(status); + + if (NULL_OR_EMPTY(action)) + dsn->action = mystrdup(""); + else + dsn->action = mystrdup(action); + + if (NULL_OR_EMPTY(reason)) + msg_panic("%s: null dsn reason", myname); + else + dsn->reason = mystrdup(reason); + + if (NULL_OR_EMPTY(dtype) || NULL_OR_EMPTY(dtext)) { + dsn->dtype = mystrdup(""); + dsn->dtext = mystrdup(""); + } else { + dsn->dtype = mystrdup(dtype); + dsn->dtext = mystrdup(dtext); + } + if (NULL_OR_EMPTY(mtype) || NULL_OR_EMPTY(mname)) { + dsn->mtype = mystrdup(""); + dsn->mname = mystrdup(""); + } else { + dsn->mtype = mystrdup(mtype); + dsn->mname = mystrdup(mname); + } + return (dsn); +} + +/* dsn_free - destroy DSN structure */ + +void dsn_free(DSN *dsn) +{ + myfree((void *) dsn->status); + myfree((void *) dsn->action); + myfree((void *) dsn->reason); + myfree((void *) dsn->dtype); + myfree((void *) dsn->dtext); + myfree((void *) dsn->mtype); + myfree((void *) dsn->mname); + myfree((void *) dsn); +} |