summaryrefslogtreecommitdiffstats
path: root/src/global/trace.c
blob: d451b4f457b89e44433b3163dcd038c6ee6713c2 (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
/*++
/* NAME
/*	trace 3
/* SUMMARY
/*	user requested delivery tracing
/* SYNOPSIS
/*	#include <trace.h>
/*
/*	int	trace_append(flags, id, stats, rcpt, relay, dsn)
/*	int	flags;
/*	const char *id;
/*	MSG_STATS *stats;
/*	RECIPIENT *rcpt;
/*	const char *relay;
/*	DSN	*dsn;
/*
/*	int     trace_flush(flags, queue, id, encoding, sender,
/*				dsn_envid, dsn_ret)
/*	int     flags;
/*	const char *queue;
/*	const char *id;
/*	const char *encoding;
/*	const char *sender;
/*	const char *dsn_envid;
/*	int	dsn_ret;
/* DESCRIPTION
/*	trace_append() updates the message delivery record that is
/*	mailed back to the originator. In case of a trace-only
/*	message, the recipient status is also written to the
/*	mailer logfile.
/*
/*	trace_flush() returns the specified message to the specified
/*	sender, including the message delivery record log that was built
/*	with vtrace_append().
/*
/*	Arguments:
/* .IP flags
/*	The bitwise OR of zero or more of the following (specify
/*	BOUNCE_FLAG_NONE to request no special processing):
/* .RS
/* .IP BOUNCE_FLAG_CLEAN
/*	Delete the logfile in case of an error (as in: pretend
/*	that we never even tried to deliver this message).
/* .RE
/* .IP queue
/*	The message queue name of the original message file.
/* .IP id
/*	The message queue id.
/* .IP encoding
/*	The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
/* .IP sender
/*	The sender envelope address.
/* .IP dsn_envid
/*	Optional DSN envelope ID.
/* .IP dsn_ret
/*	Optional DSN return full/headers option.
/* .IP stats
/*	Time stamps from different message delivery stages
/*	and session reuse count.
/* .IP rcpt
/*	Recipient information. See recipient_list(3).
/* .IP relay
/*	The host we sent the mail to.
/* .IP dsn
/*	Delivery status information. See dsn(3).
/* DIAGNOSTICS
/*	A non-zero result means the operation failed.
/*
/*	Fatal: out of memory.
/* BUGS
/*	Should be replaced by routines with an attribute-value based
/*	interface instead of an interface that uses a rigid argument list.
/* 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 <stdio.h>
#include <string.h>

/* Utility library. */

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

/* Global library. */

#include <mail_params.h>
#include <mail_proto.h>
#include <log_adhoc.h>
#include <rcpt_print.h>
#include <dsn_print.h>
#include <trace.h>

/* trace_append - append to message delivery record */

int     trace_append(int flags, const char *id, MSG_STATS *stats,
		             RECIPIENT *rcpt, const char *relay,
		             DSN *dsn)
{
    VSTRING *why = vstring_alloc(100);
    DSN     my_dsn = *dsn;
    int     req_stat;

    /*
     * User-requested address verification, verbose delivery, or DSN SUCCESS
     * notification.
     */
    if (strcmp(relay, NO_RELAY_AGENT) != 0)
	vstring_sprintf(why, "delivery via %s: ", relay);
    vstring_strcat(why, my_dsn.reason);
    my_dsn.reason = vstring_str(why);

    if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
			    SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
			    SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
			    SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
			    SEND_ATTR_FUNC(rcpt_print, (void *) rcpt),
			    SEND_ATTR_FUNC(dsn_print, (void *) &my_dsn),
			    ATTR_TYPE_END) != 0) {
	msg_warn("%s: %s service failure", id, var_trace_service);
	req_stat = -1;
    } else {
	if (flags & DEL_REQ_FLAG_USR_VRFY)
	    log_adhoc(id, stats, rcpt, relay, dsn, my_dsn.action);
	req_stat = 0;
    }
    vstring_free(why);
    return (req_stat);
}

/* trace_flush - deliver delivery record to the sender */

int     trace_flush(int flags, const char *queue, const char *id,
		            const char *encoding, const char *sender,
		            const char *dsn_envid, int dsn_ret)
{
    if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
			    SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_TRACE),
			    SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
			    SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
			    SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
			    SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
			    SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
			    SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
			    SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
			    ATTR_TYPE_END) == 0) {
	return (0);
    } else {
	return (-1);
    }
}