~ubuntu-branches/ubuntu/vivid/postfix/vivid-proposed

« back to all changes in this revision

Viewing changes to src/bounce/bounce_append_service.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2005-02-27 09:33:07 UTC
  • Revision ID: james.westby@ubuntu.com-20050227093307-cn789t27ibnlh6tf
Tags: upstream-2.1.5
ImportĀ upstreamĀ versionĀ 2.1.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*++
 
2
/* NAME
 
3
/*      bounce_append_service 3
 
4
/* SUMMARY
 
5
/*      append record to bounce log, server side
 
6
/* SYNOPSIS
 
7
/*      #include "bounce_service.h"
 
8
/*
 
9
/*      int     bounce_append_service(flags, queue_id, orig_rcpt, recipient,
 
10
/*                                      status, action, why)
 
11
/*      int     flags;
 
12
/*      char    *queue_id;
 
13
/*      char    *orig_rcpt;
 
14
/*      char    *recipient;
 
15
/*      char    *status;
 
16
/*      char    *action;
 
17
/*      char    *why;
 
18
/* DESCRIPTION
 
19
/*      This module implements the server side of the bounce_append()
 
20
/*      (append bounce log) request. This routine either succeeds or
 
21
/*      it raises a fatal error.
 
22
/* DIAGNOSTICS
 
23
/*      Fatal errors: all file access errors; memory allocation errors.
 
24
/* BUGS
 
25
/* SEE ALSO
 
26
/*      bounce(3) basic bounce service client interface
 
27
/* LICENSE
 
28
/* .ad
 
29
/* .fi
 
30
/*      The Secure Mailer license must be distributed with this software.
 
31
/* AUTHOR(S)
 
32
/*      Wietse Venema
 
33
/*      IBM T.J. Watson Research
 
34
/*      P.O. Box 704
 
35
/*      Yorktown Heights, NY 10598, USA
 
36
/*--*/
 
37
 
 
38
/* System library. */
 
39
 
 
40
#include <sys_defs.h>
 
41
#include <unistd.h>
 
42
#include <fcntl.h>
 
43
#include <errno.h>
 
44
#include <ctype.h>
 
45
#include <string.h>
 
46
 
 
47
#ifdef STRCASECMP_IN_STRINGS_H
 
48
#include <strings.h>
 
49
#endif
 
50
 
 
51
/* Utility library. */
 
52
 
 
53
#include <msg.h>
 
54
#include <vstring.h>
 
55
#include <vstream.h>
 
56
#include <stringops.h>
 
57
 
 
58
/* Global library. */
 
59
 
 
60
#include <mail_params.h>
 
61
#include <mail_queue.h>
 
62
#include <quote_822_local.h>
 
63
#include <deliver_flock.h>
 
64
#include <mail_proto.h>
 
65
 
 
66
/* Application-specific. */
 
67
 
 
68
#include "bounce_service.h"
 
69
 
 
70
/* bounce_append_service - append bounce log */
 
71
 
 
72
int     bounce_append_service(int unused_flags, char *service, char *queue_id,
 
73
                                      char *orig_rcpt, char *recipient,
 
74
                                      long offset, char *status, char *action,
 
75
                                      char *why)
 
76
{
 
77
    VSTRING *in_buf = vstring_alloc(100);
 
78
    VSTRING *out_buf = vstring_alloc(100);
 
79
    VSTREAM *log;
 
80
    long    orig_length;
 
81
 
 
82
    /*
 
83
     * This code is paranoid for a good reason. Once the bounce service takes
 
84
     * responsibility, the mail system will make no further attempts to
 
85
     * deliver this recipient. Whenever file access fails, assume that the
 
86
     * system is under stress or that something has been mis-configured, and
 
87
     * force a backoff by raising a fatal run-time error.
 
88
     */
 
89
    log = mail_queue_open(service, queue_id,
 
90
                          O_WRONLY | O_APPEND | O_CREAT, 0600);
 
91
    if (log == 0)
 
92
        msg_fatal("open file %s %s: %m", service, queue_id);
 
93
 
 
94
    /*
 
95
     * Lock out other processes to avoid truncating someone else's data in
 
96
     * case of trouble.
 
97
     */
 
98
    if (deliver_flock(vstream_fileno(log), INTERNAL_LOCK, (VSTRING *) 0) < 0)
 
99
        msg_fatal("lock file %s %s: %m", service, queue_id);
 
100
 
 
101
    /*
 
102
     * Now, go for it. Append a record. Truncate the log to the original
 
103
     * length when the append operation fails. We use the plain stream-lf
 
104
     * file format because we do not need anything more complicated. As a
 
105
     * benefit, we can still recover some data when the file is a little
 
106
     * garbled.
 
107
     * 
 
108
     * XXX addresses in defer logfiles are in printable quoted form, while
 
109
     * addresses in message envelope records are in raw unquoted form. This
 
110
     * may change once we replace the present ad-hoc bounce/defer logfile
 
111
     * format by one that is transparent for control etc. characters. See
 
112
     * also: showq/showq.c.
 
113
     * 
 
114
     * While migrating from old format to new format, allow backwards
 
115
     * compatibility by writing an old-style record before the new-style
 
116
     * records.
 
117
     */
 
118
    if ((orig_length = vstream_fseek(log, 0L, SEEK_END)) < 0)
 
119
        msg_fatal("seek file %s %s: %m", service, queue_id);
 
120
 
 
121
    vstream_fputs("\n", log);
 
122
    if (var_oldlog_compat) {
 
123
        vstream_fprintf(log, "<%s>: %s\n", *recipient == 0 ? "" :
 
124
            printable(vstring_str(quote_822_local(in_buf, recipient)), '?'),
 
125
                        printable(why, '?'));
 
126
    }
 
127
    vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_RECIP, *recipient ?
 
128
           printable(vstring_str(quote_822_local(in_buf, recipient)), '?') :
 
129
                    "<>");
 
130
    if (*orig_rcpt && strcasecmp(recipient, orig_rcpt) != 0)
 
131
        vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_ORCPT,
 
132
           printable(vstring_str(quote_822_local(in_buf, orig_rcpt)), '?'));
 
133
    if (offset > 0)
 
134
        vstream_fprintf(log, "%s=%ld\n", MAIL_ATTR_OFFSET, offset);
 
135
    vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_STATUS, printable(status, '?'));
 
136
    vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_ACTION, printable(action, '?'));
 
137
    vstream_fprintf(log, "%s=%s\n", MAIL_ATTR_WHY, printable(why, '?'));
 
138
    vstream_fputs("\n", log);
 
139
 
 
140
    if (vstream_fflush(log) != 0 || fsync(vstream_fileno(log)) < 0) {
 
141
#ifndef NO_TRUNCATE
 
142
        if (ftruncate(vstream_fileno(log), (off_t) orig_length) < 0)
 
143
            msg_fatal("truncate file %s %s: %m", service, queue_id);
 
144
#endif
 
145
        msg_fatal("append file %s %s: %m", service, queue_id);
 
146
    }
 
147
 
 
148
    /*
 
149
     * Darn. If closing the log detects a problem, the only way to undo the
 
150
     * damage is to open the log once more, and to truncate the log to the
 
151
     * original length. But, this could happen only when the log is kept on a
 
152
     * remote file system, and that is not recommended practice anyway.
 
153
     */
 
154
    if (vstream_fclose(log) != 0)
 
155
        msg_warn("append file %s %s: %m", service, queue_id);
 
156
 
 
157
    vstring_free(in_buf);
 
158
    vstring_free(out_buf);
 
159
    return (0);
 
160
}