Пример #1
0
static void qmqpd_open_file(QMQPD_STATE *state)
{
    int     cleanup_flags;

    /*
     * Connect to the cleanup server. Log client name/address with queue ID.
     */
    cleanup_flags = input_transp_cleanup(CLEANUP_FLAG_MASK_EXTERNAL,
					 qmqpd_input_transp_mask);
    state->dest = mail_stream_service(MAIL_CLASS_PUBLIC, var_cleanup_service);
    if (state->dest == 0
	|| attr_print(state->dest->stream, ATTR_FLAG_NONE,
		      ATTR_TYPE_INT, MAIL_ATTR_FLAGS, cleanup_flags,
		      ATTR_TYPE_END) != 0)
	msg_fatal("unable to connect to the %s %s service",
		  MAIL_CLASS_PUBLIC, var_cleanup_service);
    state->cleanup = state->dest->stream;
    state->queue_id = mystrdup(state->dest->id);
    msg_info("%s: client=%s", state->queue_id, state->namaddr);

    /*
     * Record the time of arrival. Optionally, enable content filtering (not
     * bloody likely, but present for the sake of consistency with all other
     * Postfix points of entrance).
     */
    rec_fprintf(state->cleanup, REC_TYPE_TIME, REC_TYPE_TIME_FORMAT,
		REC_TYPE_TIME_ARG(state->arrival_time));
    if (*var_filter_xport)
	rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
}
Пример #2
0
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);
}