VSTREAM *post_mail_fopen(const char *sender, const char *recipient, int filter_class, int trace_flags, VSTRING *queue_id) { VSTREAM *stream; stream = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service); post_mail_init(stream, sender, recipient, filter_class, trace_flags, queue_id); return (stream); }
static int pickup_file(PICKUP_INFO *info) { VSTRING *buf = vstring_alloc(100); int status; VSTREAM *qfile; VSTREAM *cleanup; int cleanup_flags; /* * Open the submitted file. If we cannot open it, and we're not having a * file descriptor leak problem, delete the submitted file, so that we * won't keep complaining about the same file again and again. XXX * Perhaps we should save "bad" files elsewhere for further inspection. * XXX How can we delete a file when open() fails with ENOENT? */ qfile = safe_open(info->path, O_RDONLY | O_NONBLOCK, 0, (struct stat *) 0, -1, -1, buf); if (qfile == 0) { if (errno != ENOENT) msg_warn("open input file %s: %s", info->path, vstring_str(buf)); vstring_free(buf); if (errno == EACCES) msg_warn("if this file was created by Postfix < 1.1, then you may have to chmod a+r %s/%s", var_queue_dir, info->path); return (errno == EACCES ? KEEP_MESSAGE_FILE : REMOVE_MESSAGE_FILE); } /* * Contact the cleanup service and read the queue ID that it has * allocated. In case of trouble, request that the cleanup service * bounces its copy of the message. because the original input file is * not readable by the bounce service. * * If mail is re-injected with "postsuper -r", disable Milter applications. * If they were run before the mail was queued then there is no need to * run them again. Moreover, the queue file does not contain enough * information to reproduce the exact same SMTP events and Sendmail * macros that Milters received when the mail originally arrived in * Postfix. * * The actual message copying code is in a separate routine, so that it is * easier to implement the many possible error exits without forgetting * to close files, or to release memory. */ cleanup_flags = input_transp_cleanup(CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_MASK_EXTERNAL, pickup_input_transp_mask); /* As documented in postsuper(1). */ if (MAIL_IS_REQUEUED(info)) cleanup_flags &= ~CLEANUP_FLAG_MILTER; else cleanup_flags |= smtputf8_autodetect(MAIL_SRC_MASK_SENDMAIL); cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service); if (attr_scan(cleanup, ATTR_FLAG_STRICT, RECV_ATTR_STR(MAIL_ATTR_QUEUEID, buf), ATTR_TYPE_END) != 1 || attr_print(cleanup, ATTR_FLAG_NONE, SEND_ATTR_INT(MAIL_ATTR_FLAGS, cleanup_flags), ATTR_TYPE_END) != 0) { status = KEEP_MESSAGE_FILE; } else { info->id = mystrdup(vstring_str(buf)); status = pickup_copy(qfile, cleanup, info, buf); } vstream_fclose(qfile); vstream_fclose(cleanup); vstring_free(buf); return (status); }