Current File : //root/postfix-3.2.0/src/global/dsn.c |
/*++
/* 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);
}