Postfix3.3.1
pickup.c
[詳解]
1 /*++
2 /* NAME
3 /* pickup 8
4 /* SUMMARY
5 /* Postfix local mail pickup
6 /* SYNOPSIS
7 /* \fBpickup\fR [generic Postfix daemon options]
8 /* DESCRIPTION
9 /* The \fBpickup\fR(8) daemon waits for hints that new mail has been
10 /* dropped into the \fBmaildrop\fR directory, and feeds it into the
11 /* \fBcleanup\fR(8) daemon.
12 /* Ill-formatted files are deleted without notifying the originator.
13 /* This program expects to be run from the \fBmaster\fR(8) process
14 /* manager.
15 /* STANDARDS
16 /* .ad
17 /* .fi
18 /* None. The \fBpickup\fR(8) daemon does not interact with
19 /* the outside world.
20 /* SECURITY
21 /* .ad
22 /* .fi
23 /* The \fBpickup\fR(8) daemon is moderately security sensitive. It runs
24 /* with fixed low privilege and can run in a chrooted environment.
25 /* However, the program reads files from potentially hostile users.
26 /* The \fBpickup\fR(8) daemon opens no files for writing, is careful about
27 /* what files it opens for reading, and does not actually touch any data
28 /* that is sent to its public service endpoint.
29 /* DIAGNOSTICS
30 /* Problems and transactions are logged to \fBsyslogd\fR(8).
31 /* BUGS
32 /* The \fBpickup\fR(8) daemon copies mail from file to the \fBcleanup\fR(8)
33 /* daemon. It could avoid message copying overhead by sending a file
34 /* descriptor instead of file data, but then the already complex
35 /* \fBcleanup\fR(8) daemon would have to deal with unfiltered user data.
36 /* CONFIGURATION PARAMETERS
37 /* .ad
38 /* .fi
39 /* As the \fBpickup\fR(8) daemon is a relatively long-running process, up
40 /* to an hour may pass before a \fBmain.cf\fR change takes effect.
41 /* Use the command "\fBpostfix reload\fR" command to speed up a change.
42 /*
43 /* The text below provides only a parameter summary. See
44 /* \fBpostconf\fR(5) for more details including examples.
45 /* CONTENT INSPECTION CONTROLS
46 /* .ad
47 /* .fi
48 /* .IP "\fBcontent_filter (empty)\fR"
49 /* After the message is queued, send the entire message to the
50 /* specified \fItransport:destination\fR.
51 /* .IP "\fBreceive_override_options (empty)\fR"
52 /* Enable or disable recipient validation, built-in content
53 /* filtering, or address mapping.
54 /* MISCELLANEOUS CONTROLS
55 /* .ad
56 /* .fi
57 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
58 /* The default location of the Postfix main.cf and master.cf
59 /* configuration files.
60 /* .IP "\fBipc_timeout (3600s)\fR"
61 /* The time limit for sending or receiving information over an internal
62 /* communication channel.
63 /* .IP "\fBline_length_limit (2048)\fR"
64 /* Upon input, long lines are chopped up into pieces of at most
65 /* this length; upon delivery, long lines are reconstructed.
66 /* .IP "\fBmax_idle (100s)\fR"
67 /* The maximum amount of time that an idle Postfix daemon process waits
68 /* for an incoming connection before terminating voluntarily.
69 /* .IP "\fBmax_use (100)\fR"
70 /* The maximal number of incoming connections that a Postfix daemon
71 /* process will service before terminating voluntarily.
72 /* .IP "\fBprocess_id (read-only)\fR"
73 /* The process ID of a Postfix command or daemon process.
74 /* .IP "\fBprocess_name (read-only)\fR"
75 /* The process name of a Postfix command or daemon process.
76 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
77 /* The location of the Postfix top-level queue directory.
78 /* .IP "\fBsyslog_facility (mail)\fR"
79 /* The syslog facility of Postfix logging.
80 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
81 /* A prefix that is prepended to the process name in syslog
82 /* records, so that, for example, "smtpd" becomes "prefix/smtpd".
83 /* .PP
84 /* Available in Postfix 3.3 and later:
85 /* .IP "\fBservice_name (read-only)\fR"
86 /* The master.cf service name of a Postfix daemon process.
87 /* SEE ALSO
88 /* cleanup(8), message canonicalization
89 /* sendmail(1), Sendmail-compatible interface
90 /* postdrop(1), mail posting agent
91 /* postconf(5), configuration parameters
92 /* master(5), generic daemon options
93 /* master(8), process manager
94 /* syslogd(8), system logging
95 /* LICENSE
96 /* .ad
97 /* .fi
98 /* The Secure Mailer license must be distributed with this software.
99 /* AUTHOR(S)
100 /* Wietse Venema
101 /* IBM T.J. Watson Research
102 /* P.O. Box 704
103 /* Yorktown Heights, NY 10598, USA
104 /*
105 /* Wietse Venema
106 /* Google, Inc.
107 /* 111 8th Avenue
108 /* New York, NY 10011, USA
109 /*--*/
110 
111 /* System library. */
112 
113 #include <sys_defs.h>
114 #include <sys/stat.h>
115 #include <dirent.h>
116 #include <unistd.h>
117 #include <stdlib.h>
118 #include <time.h>
119 #include <string.h>
120 #include <fcntl.h>
121 #include <errno.h>
122 #include <ctype.h>
123 
124 /* Utility library. */
125 
126 #include <msg.h>
127 #include <scan_dir.h>
128 #include <vstring.h>
129 #include <vstream.h>
130 #include <set_ugid.h>
131 #include <safe_open.h>
132 #include <watchdog.h>
133 #include <stringops.h>
134 
135 /* Global library. */
136 
137 #include <mail_queue.h>
138 #include <mail_open_ok.h>
139 #include <mymalloc.h>
140 #include <mail_proto.h>
141 #include <cleanup_user.h>
142 #include <mail_date.h>
143 #include <mail_params.h>
144 #include <mail_conf.h>
145 #include <record.h>
146 #include <rec_type.h>
147 #include <lex_822.h>
148 #include <input_transp.h>
149 #include <rec_attr_map.h>
150 #include <mail_version.h>
151 #include <smtputf8.h>
152 
153 /* Single-threaded server skeleton. */
154 
155 #include <mail_server.h>
156 
157 /* Application-specific. */
158 
161 
162  /*
163  * Structure to bundle a bunch of information about a queue file.
164  */
165 typedef struct {
166  char *id; /* queue file basename */
167  struct stat st; /* queue file status */
168  char *path; /* name for open/remove */
169  char *sender; /* sender address */
170 } PICKUP_INFO;
171 
172  /*
173  * What action should be taken after attempting to deliver a message: remove
174  * the file from the maildrop, or leave it alone. The latter is also used
175  * for files that are still being written to.
176  */
177 #define REMOVE_MESSAGE_FILE 1
178 #define KEEP_MESSAGE_FILE 2
179 
180  /*
181  * Transparency: before mail is queued, do we allow address mapping,
182  * automatic bcc, header/body checks?
183  */
185 
186 /* file_read_error - handle error while reading queue file */
187 
188 static int file_read_error(PICKUP_INFO *info, int type)
189 {
190  msg_warn("uid=%ld: unexpected or malformed record type %d",
191  (long) info->st.st_uid, type);
192  return (REMOVE_MESSAGE_FILE);
193 }
194 
195 /* cleanup_service_error_reason - handle error writing to cleanup service. */
196 
197 static int cleanup_service_error_reason(PICKUP_INFO *info, int status,
198  const char *reason)
199 {
200 
201  /*
202  * XXX If the cleanup server gave a reason, then it was already logged.
203  * Don't bother logging it another time.
204  *
205  * XXX Discard a message without recipient. This can happen with "postsuper
206  * -r" when a message is already delivered (or bounced). The Postfix
207  * sendmail command rejects submissions without recipients.
208  */
209  if (reason == 0 || *reason == 0)
210  msg_warn("%s: error writing %s: %s",
211  info->path, info->id, cleanup_strerror(status));
212  return ((status & (CLEANUP_STAT_BAD | CLEANUP_STAT_RCPT)) ?
214 }
215 
216 #define cleanup_service_error(info, status) \
217  cleanup_service_error_reason((info), (status), (char *) 0)
218 
219 /* copy_segment - copy a record group */
220 
221 static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
222  VSTRING *buf, char *expected)
223 {
224  int type;
225  int check_first = (*expected == REC_TYPE_CONTENT[0]);
226  int time_seen = 0;
227  char *attr_name;
228  char *attr_value;
229  char *saved_attr;
230  int skip_attr;
231 
232  /*
233  * Limit the input record size. All front-end programs should protect the
234  * mail system against unreasonable inputs. This also requires that we
235  * limit the size of envelope records written by the local posting agent.
236  *
237  * Records with named attributes are filtered by postdrop(1).
238  *
239  * We must allow PTR records here because of "postsuper -r".
240  */
241  for (;;) {
242  if ((type = rec_get(qfile, buf, var_line_limit)) < 0
243  || strchr(expected, type) == 0)
244  return (file_read_error(info, type));
245  if (msg_verbose)
246  msg_info("%s: read %c %s", info->id, type, vstring_str(buf));
247  if (type == *expected)
248  break;
249  if (type == REC_TYPE_FROM) {
250  if (info->sender == 0)
251  info->sender = mystrdup(vstring_str(buf));
252  /* Compatibility with Postfix < 2.3. */
253  if (time_seen == 0)
254  rec_fprintf(cleanup, REC_TYPE_TIME, "%ld",
255  (long) info->st.st_mtime);
256  }
257  if (type == REC_TYPE_TIME)
258  time_seen = 1;
259 
260  /*
261  * XXX Workaround: REC_TYPE_FILT (used in envelopes) == REC_TYPE_CONT
262  * (used in message content).
263  *
264  * As documented in postsuper(1), ignore content filter record.
265  */
266  if (*expected != REC_TYPE_CONTENT[0]) {
267  if (type == REC_TYPE_FILT)
268  /* Discard FILTER record after "postsuper -r". */
269  continue;
270  if (type == REC_TYPE_RDR)
271  /* Discard REDIRECT record after "postsuper -r". */
272  continue;
273  }
274  if (*expected == REC_TYPE_EXTRACT[0]) {
275  if (type == REC_TYPE_RRTO)
276  /* Discard return-receipt record after "postsuper -r". */
277  continue;
278  if (type == REC_TYPE_ERTO)
279  /* Discard errors-to record after "postsuper -r". */
280  continue;
281  if (type == REC_TYPE_ATTR) {
282  saved_attr = mystrdup(vstring_str(buf));
283  skip_attr = (split_nameval(saved_attr,
284  &attr_name, &attr_value) == 0
285  && rec_attr_map(attr_name) == 0);
286  myfree(saved_attr);
287  /* Discard other/header/body action after "postsuper -r". */
288  if (skip_attr)
289  continue;
290  }
291  }
292 
293  /*
294  * XXX Force an empty record when the queue file content begins with
295  * whitespace, so that it won't be considered as being part of our
296  * own Received: header. What an ugly Kluge.
297  */
298  if (check_first
299  && (type == REC_TYPE_NORM || type == REC_TYPE_CONT)) {
300  check_first = 0;
301  if (VSTRING_LEN(buf) > 0 && IS_SPACE_TAB(vstring_str(buf)[0]))
302  rec_put(cleanup, REC_TYPE_NORM, "", 0);
303  }
304  if ((REC_PUT_BUF(cleanup, type, buf)) < 0)
306  }
307  return (0);
308 }
309 
310 /* pickup_copy - copy message to cleanup service */
311 
312 static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup,
313  PICKUP_INFO *info, VSTRING *buf)
314 {
315  time_t now = time((time_t *) 0);
316  int status;
317  char *name;
318 
319  /*
320  * Protect against time-warped time stamps. Warn about mail that has been
321  * queued for an excessive amount of time. Allow for some time drift with
322  * network clients that mount the maildrop remotely - especially clients
323  * that can't get their daylight savings offsets right.
324  */
325 #define DAY_SECONDS 86400
326 #define HOUR_SECONDS 3600
327 
328  if (info->st.st_mtime > now + 2 * HOUR_SECONDS) {
329  msg_warn("%s: message dated %ld seconds into the future",
330  info->id, (long) (info->st.st_mtime - now));
331  info->st.st_mtime = now;
332  } else if (info->st.st_mtime < now - DAY_SECONDS) {
333  msg_warn("%s: message has been queued for %d days",
334  info->id, (int) ((now - info->st.st_mtime) / DAY_SECONDS));
335  }
336 
337  /*
338  * Add content inspection transport. See also postsuper(1).
339  */
340  if (*var_filter_xport)
341  rec_fprintf(cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
342 
343  /*
344  * Copy the message envelope segment. Allow only those records that we
345  * expect to see in the envelope section. The envelope segment must
346  * contain an envelope sender address.
347  */
348  if ((status = copy_segment(qfile, cleanup, info, buf, REC_TYPE_ENVELOPE)) != 0)
349  return (status);
350  if (info->sender == 0) {
351  msg_warn("%s: uid=%ld: no envelope sender",
352  info->id, (long) info->st.st_uid);
353  return (REMOVE_MESSAGE_FILE);
354  }
355 
356  /*
357  * For messages belonging to $mail_owner also log the maildrop queue id.
358  * This supports message tracking for mail requeued via "postsuper -r".
359  */
360 #define MAIL_IS_REQUEUED(info) \
361  ((info)->st.st_uid == var_owner_uid && ((info)->st.st_mode & S_IROTH) == 0)
362 
363  if (MAIL_IS_REQUEUED(info)) {
364  msg_info("%s: uid=%d from=<%s> orig_id=%s", info->id,
365  (int) info->st.st_uid, info->sender,
366  ((name = strrchr(info->path, '/')) != 0 ?
367  name + 1 : info->path));
368  } else {
369  msg_info("%s: uid=%d from=<%s>", info->id,
370  (int) info->st.st_uid, info->sender);
371  }
372 
373  /*
374  * Message content segment. Send a dummy message length. Prepend a
375  * Received: header to the message contents. For tracing purposes,
376  * include the message file ownership, without revealing the login name.
377  */
378  rec_fputs(cleanup, REC_TYPE_MESG, "");
379  rec_fprintf(cleanup, REC_TYPE_NORM, "Received: by %s (%s, from userid %ld)",
380  var_myhostname, var_mail_name, (long) info->st.st_uid);
381  rec_fprintf(cleanup, REC_TYPE_NORM, "\tid %s; %s", info->id,
382  mail_date(info->st.st_mtime));
383 
384  /*
385  * Copy the message content segment. Allow only those records that we
386  * expect to see in the message content section.
387  */
388  if ((status = copy_segment(qfile, cleanup, info, buf, REC_TYPE_CONTENT)) != 0)
389  return (status);
390 
391  /*
392  * Send the segment with information extracted from message headers.
393  * Permit a non-empty extracted segment, so that list manager software
394  * can to output recipients after the message, and so that sysadmins can
395  * re-inject messages after a change of configuration.
396  */
397  rec_fputs(cleanup, REC_TYPE_XTRA, "");
398  if ((status = copy_segment(qfile, cleanup, info, buf, REC_TYPE_EXTRACT)) != 0)
399  return (status);
400 
401  /*
402  * There are no errors. Send the end-of-data marker, and get the cleanup
403  * service completion status. XXX Since the pickup service is unable to
404  * bounce, the cleanup service can report only soft errors here.
405  */
406  rec_fputs(cleanup, REC_TYPE_END, "");
407  if (attr_scan(cleanup, ATTR_FLAG_MISSING,
410  ATTR_TYPE_END) != 2)
412 
413  /*
414  * Depending on the cleanup service completion status, delete the message
415  * file, or try again later. Bounces are dealt with by the cleanup
416  * service itself. The master process wakes up the cleanup service every
417  * now and then.
418  */
419  if (status) {
420  return (cleanup_service_error_reason(info, status, vstring_str(buf)));
421  } else {
422  return (REMOVE_MESSAGE_FILE);
423  }
424 }
425 
426 /* pickup_file - initialize for file copy and cleanup */
427 
428 static int pickup_file(PICKUP_INFO *info)
429 {
430  VSTRING *buf = vstring_alloc(100);
431  int status;
432  VSTREAM *qfile;
433  VSTREAM *cleanup;
434  int cleanup_flags;
435 
436  /*
437  * Open the submitted file. If we cannot open it, and we're not having a
438  * file descriptor leak problem, delete the submitted file, so that we
439  * won't keep complaining about the same file again and again. XXX
440  * Perhaps we should save "bad" files elsewhere for further inspection.
441  * XXX How can we delete a file when open() fails with ENOENT?
442  */
443  qfile = safe_open(info->path, O_RDONLY | O_NONBLOCK, 0,
444  (struct stat *) 0, -1, -1, buf);
445  if (qfile == 0) {
446  if (errno != ENOENT)
447  msg_warn("open input file %s: %s", info->path, vstring_str(buf));
448  vstring_free(buf);
449  if (errno == EACCES)
450  msg_warn("if this file was created by Postfix < 1.1, then you may have to chmod a+r %s/%s",
451  var_queue_dir, info->path);
452  return (errno == EACCES ? KEEP_MESSAGE_FILE : REMOVE_MESSAGE_FILE);
453  }
454 
455  /*
456  * Contact the cleanup service and read the queue ID that it has
457  * allocated. In case of trouble, request that the cleanup service
458  * bounces its copy of the message. because the original input file is
459  * not readable by the bounce service.
460  *
461  * If mail is re-injected with "postsuper -r", disable Milter applications.
462  * If they were run before the mail was queued then there is no need to
463  * run them again. Moreover, the queue file does not contain enough
464  * information to reproduce the exact same SMTP events and Sendmail
465  * macros that Milters received when the mail originally arrived in
466  * Postfix.
467  *
468  * The actual message copying code is in a separate routine, so that it is
469  * easier to implement the many possible error exits without forgetting
470  * to close files, or to release memory.
471  */
472  cleanup_flags =
475  /* As documented in postsuper(1). */
476  if (MAIL_IS_REQUEUED(info))
477  cleanup_flags &= ~CLEANUP_FLAG_MILTER;
478  else
480 
482  if (attr_scan(cleanup, ATTR_FLAG_STRICT,
484  ATTR_TYPE_END) != 1
485  || attr_print(cleanup, ATTR_FLAG_NONE,
486  SEND_ATTR_INT(MAIL_ATTR_FLAGS, cleanup_flags),
487  ATTR_TYPE_END) != 0) {
488  status = KEEP_MESSAGE_FILE;
489  } else {
490  info->id = mystrdup(vstring_str(buf));
491  status = pickup_copy(qfile, cleanup, info, buf);
492  }
493  vstream_fclose(qfile);
494  vstream_fclose(cleanup);
495  vstring_free(buf);
496  return (status);
497 }
498 
499 /* pickup_init - init info structure */
500 
501 static void pickup_init(PICKUP_INFO *info)
502 {
503  info->id = 0;
504  info->path = 0;
505  info->sender = 0;
506 }
507 
508 /* pickup_free - wipe info structure */
509 
510 static void pickup_free(PICKUP_INFO *info)
511 {
512 #define SAFE_FREE(x) { if (x) myfree(x); }
513 
514  SAFE_FREE(info->id);
515  SAFE_FREE(info->path);
516  SAFE_FREE(info->sender);
517 }
518 
519 /* pickup_service - service client */
520 
521 static void pickup_service(char *unused_buf, ssize_t unused_len,
522  char *unused_service, char **argv)
523 {
524  SCAN_DIR *scan;
525  char *queue_name;
526  PICKUP_INFO info;
527  const char *path;
528  char *id;
529  int file_count;
530 
531  /*
532  * Sanity check. This service takes no command-line arguments.
533  */
534  if (argv[0])
535  msg_fatal("unexpected command-line argument: %s", argv[0]);
536 
537  /*
538  * Skip over things that we don't want to open, such as files that are
539  * still being written, or garbage. Leave it up to the sysadmin to remove
540  * garbage. Keep scanning the queue directory until we stop removing
541  * files from it.
542  *
543  * When we find a file, stroke the watchdog so that it will not bark while
544  * some application is keeping us busy by injecting lots of mail into the
545  * maildrop directory.
546  */
547  queue_name = MAIL_QUEUE_MAILDROP; /* XXX should be a list */
548  do {
549  file_count = 0;
550  scan = scan_dir_open(queue_name);
551  while ((id = scan_dir_next(scan)) != 0) {
552  if (mail_open_ok(queue_name, id, &info.st, &path) == MAIL_OPEN_YES) {
553  pickup_init(&info);
554  info.path = mystrdup(path);
555  watchdog_pat();
556  if (pickup_file(&info) == REMOVE_MESSAGE_FILE) {
557  if (REMOVE(info.path))
558  msg_warn("remove %s: %m", info.path);
559  else
560  file_count++;
561  }
562  pickup_free(&info);
563  }
564  }
565  scan_dir_close(scan);
566  } while (file_count);
567 }
568 
569 /* post_jail_init - drop privileges */
570 
571 static void post_jail_init(char *unused_name, char **unused_argv)
572 {
573 
574  /*
575  * In case master.cf was not updated for unprivileged service.
576  */
577  if (getuid() != var_owner_uid)
579 
580  /*
581  * Initialize the receive transparency options: do we want unknown
582  * recipient checks, do we want address mapping.
583  */
586 }
587 
589 
590 /* main - pass control to the multi-threaded server skeleton */
591 
592 int main(int argc, char **argv)
593 {
594  static const CONFIG_STR_TABLE str_table[] = {
597  0,
598  };
599 
600  /*
601  * Fingerprint executables and core dumps.
602  */
604 
605  /*
606  * Use the multi-threaded skeleton, because no-one else should be
607  * monitoring our service socket while this process runs.
608  *
609  * XXX The default watchdog timeout for trigger servers is 1000s, while the
610  * cleanup server watchdog timeout is $daemon_timeout (i.e. several
611  * hours). We override the default 1000s timeout to avoid problems with
612  * slow mail submission. The real problem is of course that the
613  * single-threaded pickup server is not a good solution for mail
614  * submissions.
615  */
616  trigger_server_main(argc, argv, pickup_service,
617  CA_MAIL_SERVER_STR_TABLE(str_table),
618  CA_MAIL_SERVER_POST_INIT(post_jail_init),
621  0);
622 }
int msg_verbose
Definition: msg.c:177
#define IS_SPACE_TAB(ch)
Definition: lex_822.h:17
#define REC_TYPE_FILT
Definition: rec_type.h:42
char * var_mail_name
Definition: mail_params.c:230
#define ATTR_FLAG_NONE
Definition: attr.h:98
#define MAIL_SRC_MASK_SENDMAIL
Definition: mail_proto.h:77
#define CA_MAIL_SERVER_WATCHDOG(v)
Definition: mail_server.h:73
void myfree(void *ptr)
Definition: mymalloc.c:207
VSTREAM * mail_connect_wait(const char *class, const char *name)
Definition: mail_connect.c:108
#define SAFE_FREE(x)
#define VAR_FILTER_XPORT
Definition: mail_params.h:2479
char * mystrdup(const char *str)
Definition: mymalloc.c:225
char * var_cleanup_service
Definition: mail_params.c:302
int smtputf8_autodetect(int class)
Definition: smtputf8.c:67
void watchdog_pat(void)
Definition: watchdog.c:278
#define DEF_FILTER_XPORT
Definition: mail_params.h:2480
const char * mail_date(time_t when)
Definition: mail_date.c:54
#define CA_MAIL_SERVER_STR_TABLE(v)
Definition: mail_server.h:57
#define VAR_INPUT_TRANSP
Definition: mail_params.h:3013
int input_transp_mask(const char *param_name, const char *pattern)
Definition: input_transp.c:70
#define vstring_str(vp)
Definition: vstring.h:71
#define MAIL_OPEN_YES
Definition: mail_open_ok.h:19
#define cleanup_service_error(info, status)
Definition: pickup.c:216
#define ATTR_FLAG_MISSING
Definition: attr.h:99
int REMOVE(const char *path)
Definition: remove.c:52
#define stat(p, s)
Definition: warn_stat.h:18
#define CLEANUP_FLAG_BOUNCE
Definition: cleanup_user.h:18
#define DAY_SECONDS
int pickup_input_transp_mask
Definition: pickup.c:184
#define CLEANUP_FLAG_MILTER
Definition: cleanup_user.h:24
#define RECV_ATTR_INT(name, val)
Definition: attr.h:71
#define ATTR_TYPE_END
Definition: attr.h:39
char * var_input_transp
Definition: pickup.c:160
#define REC_TYPE_FROM
Definition: rec_type.h:43
#define REC_TYPE_END
Definition: rec_type.h:77
NORETURN trigger_server_main(int, char **, TRIGGER_SERVER_FN,...)
#define VSTRING_LEN(vp)
Definition: vstring.h:72
const char * split_nameval(char *buf, char **name, char **value)
Definition: split_nameval.c:61
MAIL_VERSION_STAMP_DECLARE
Definition: pickup.c:588
SCAN_DIR * scan_dir_open(const char *path)
Definition: scan_dir.c:165
#define MAIL_CLASS_PUBLIC
Definition: mail_proto.h:95
#define CA_MAIL_SERVER_POST_INIT(v)
Definition: mail_server.h:65
#define REC_TYPE_RDR
Definition: rec_type.h:52
#define REC_PUT_BUF(v, t, b)
Definition: record.h:43
#define attr_print
Definition: attr.h:109
char * path
Definition: pickup.c:168
int main(int argc, char **argv)
Definition: pickup.c:592
gid_t var_owner_gid
Definition: mail_params.c:235
uid_t var_owner_uid
Definition: mail_params.c:234
#define REC_TYPE_CONT
Definition: rec_type.h:58
int vstream_fclose(VSTREAM *stream)
Definition: vstream.c:1268
#define DEF_INPUT_TRANSP
Definition: mail_params.h:3014
SCAN_DIR * scan_dir_close(SCAN_DIR *scan)
Definition: scan_dir.c:210
#define REC_TYPE_ERTO
Definition: rec_type.h:65
int rec_fputs(VSTREAM *stream, int type, const char *str)
Definition: record.c:404
#define REC_TYPE_MESG
Definition: rec_type.h:56
#define MAIL_ATTR_WHY
Definition: mail_proto.h:135
int mail_open_ok(const char *queue_name, const char *queue_id, struct stat *statp, const char **path)
Definition: mail_open_ok.c:77
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
int input_transp_cleanup(int cleanup_flags, int transp_mask)
Definition: input_transp.c:85
#define MAIL_VERSION_STAMP_ALLOCATE
Definition: mail_version.h:67
#define REC_TYPE_RRTO
Definition: rec_type.h:64
#define MAIL_ATTR_STATUS
Definition: mail_proto.h:126
#define SEND_ATTR_INT(name, val)
Definition: attr.h:63
int rec_attr_map(const char *attr_name)
Definition: rec_attr_map.c:39
#define MAIL_QUEUE_MAILDROP
Definition: mail_queue.h:28
int rec_put(VSTREAM *stream, int type, const char *data, ssize_t len)
Definition: record.c:194
int var_line_limit
Definition: mail_params.c:263
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
#define CLEANUP_FLAG_MASK_EXTERNAL
Definition: cleanup_user.h:33
#define CLEANUP_STAT_BAD
Definition: cleanup_user.h:57
struct stat st
Definition: pickup.c:167
#define REMOVE_MESSAGE_FILE
Definition: pickup.c:177
#define KEEP_MESSAGE_FILE
Definition: pickup.c:178
#define HOUR_SECONDS
void set_ugid(uid_t uid, gid_t gid)
Definition: set_ugid.c:45
#define CLEANUP_STAT_RCPT
Definition: cleanup_user.h:62
#define REC_TYPE_EXTRACT
Definition: rec_type.h:108
VSTREAM * safe_open(const char *path, int flags, mode_t mode, struct stat *st, uid_t user, gid_t group, VSTRING *why)
Definition: safe_open.c:243
#define REC_TYPE_XTRA
Definition: rec_type.h:62
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
char * var_queue_dir
Definition: mail_params.c:246
#define CA_MAIL_SERVER_SOLITARY
Definition: mail_server.h:69
#define REC_TYPE_ATTR
Definition: rec_type.h:49
int var_daemon_timeout
Definition: mail_params.c:284
char * sender
Definition: pickup.c:169
#define REC_TYPE_NORM
Definition: rec_type.h:59
#define REC_TYPE_TIME
Definition: rec_type.h:38
#define CLEANUP_STAT_WRITE
Definition: cleanup_user.h:58
const char * cleanup_strerror(unsigned status)
#define MAIL_ATTR_QUEUEID
Definition: mail_proto.h:130
char * var_myhostname
Definition: mail_params.c:223
#define rec_get(fp, buf, limit)
Definition: record.h:56
#define attr_scan
Definition: attr.h:111
int rec_fprintf(VSTREAM *stream, int type, const char *format,...)
Definition: record.c:391
#define MAIL_IS_REQUEUED(info)
char * id
Definition: pickup.c:166
#define MAIL_ATTR_FLAGS
Definition: mail_proto.h:128
#define REC_TYPE_CONTENT
Definition: rec_type.h:107
char * scan_dir_next(SCAN_DIR *scan)
Definition: scan_dir.c:177
#define RECV_ATTR_STR(name, val)
Definition: attr.h:72
#define ATTR_FLAG_STRICT
Definition: attr.h:103
void msg_info(const char *fmt,...)
Definition: msg.c:199
char * var_filter_xport
Definition: pickup.c:159
#define REC_TYPE_ENVELOPE
Definition: rec_type.h:106