Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postfix/src/global/   (Postfix Mailserver Version 3.11©)  Datei vom 10.8.2025 mit Größe 7 kB image not shown  

Quelle  deliver_pass.c

  Sprache: C
 

/*++
/* NAME
/* deliver_pass 3
/* SUMMARY
/* deliver request pass_through
/* SYNOPSIS
/* #include <deliver_request.h>
/*
/* int deliver_pass(class, service, request, recipient)
/* const char *class;
/* const char *service;
/* DELIVER_REQUEST *request;
/* RECIPIENT *recipient;
/*
/* int deliver_pass_all(class, service, request)
/* const char *class;
/* const char *service;
/* DELIVER_REQUEST *request;
/* DESCRIPTION
/* This module implements the client side of the `queue manager
/* to delivery agent' protocol, passing one recipient on from
/* one delivery agent to another.
/*
/* deliver_pass() delegates delivery of the named recipient.
/*
/* deliver_pass_all() delegates an entire delivery request.
/*
/* Arguments:
/* .IP class
/* Destination delivery agent service class
/* .IP service
/* String of the form \fItransport\fR:\fInexthop\fR. Either transport
/* or nexthop are optional. For details see the transport map manual page.
/* .IP request
/* Delivery request with queue file information.
/* .IP recipient
/* Recipient information. See recipient_list(3).
/* DIAGNOSTICS
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* BUGS
/* One recipient at a time; this is OK for mailbox deliveries.
/*
/* Hop status information cannot be passed back.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/


/* System library. */

#include <sys_defs.h>

/* Utility library. */

#include <msg.h>
#include <vstring.h>
#include <vstream.h>
#include <split_at.h>
#include <mymalloc.h>

/* Global library. */

#include <mail_params.h>
#include <deliver_pass.h>
#include <dsb_scan.h>
#include <defer.h>
#include <rcpt_print.h>
#include <info_log_addr_form.h>

#define DELIVER_PASS_DEFER 1
#define DELIVER_PASS_UNKNOWN 2

/* deliver_pass_initial_reply - retrieve initial delivery process response */

static int deliver_pass_initial_reply(VSTREAM *stream)
{
    if (attr_scan(stream, ATTR_FLAG_STRICT,
    RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
    ATTR_TYPE_END) != 0) {
 msg_warn("%s: malformed response", VSTREAM_PATH(stream));
 return (-1);
    }
    return (0);
}

/* deliver_pass_send_request - send delivery request to delivery process */

static int deliver_pass_send_request(VSTREAM *stream, DELIVER_REQUEST *request,
                 const char *nexthop,
                 RECIPIENT *rcpt)
{
    int     stat;

    attr_print(stream, ATTR_FLAG_NONE,
        SEND_ATTR_INT(MAIL_ATTR_FLAGS, request->flags),
        SEND_ATTR_STR(MAIL_ATTR_QUEUE, request->queue_name),
        SEND_ATTR_STR(MAIL_ATTR_QUEUEID, request->queue_id),
        SEND_ATTR_LONG(MAIL_ATTR_OFFSET, request->data_offset),
        SEND_ATTR_LONG(MAIL_ATTR_SIZE, request->data_size),
        SEND_ATTR_STR(MAIL_ATTR_NEXTHOP, nexthop),
        SEND_ATTR_STR(MAIL_ATTR_ENCODING, request->encoding),
        SEND_ATTR_INT(MAIL_ATTR_SENDOPTS, request->sendopts),
        SEND_ATTR_STR(MAIL_ATTR_SENDER, request->sender),
        SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, request->dsn_envid),
        SEND_ATTR_INT(MAIL_ATTR_DSN_RET, request->dsn_ret),
 SEND_ATTR_FUNC(msg_stats_print, (const void *) &request->msg_stats),
    /* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
      SEND_ATTR_STR(MAIL_ATTR_LOG_CLIENT_NAME, request->client_name),
      SEND_ATTR_STR(MAIL_ATTR_LOG_CLIENT_ADDR, request->client_addr),
      SEND_ATTR_STR(MAIL_ATTR_LOG_CLIENT_PORT, request->client_port),
      SEND_ATTR_STR(MAIL_ATTR_LOG_PROTO_NAME, request->client_proto),
        SEND_ATTR_STR(MAIL_ATTR_LOG_HELO_NAME, request->client_helo),
    /* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
        SEND_ATTR_STR(MAIL_ATTR_SASL_METHOD, request->sasl_method),
      SEND_ATTR_STR(MAIL_ATTR_SASL_USERNAME, request->sasl_username),
        SEND_ATTR_STR(MAIL_ATTR_SASL_SENDER, request->sasl_sender),
    /* XXX Ditto if we want to pass TLS certificate info. */
        SEND_ATTR_STR(MAIL_ATTR_LOG_IDENT, request->log_ident),
      SEND_ATTR_STR(MAIL_ATTR_RWR_CONTEXT, request->rewrite_context),
        SEND_ATTR_INT(MAIL_ATTR_RCPT_COUNT, 1),
        ATTR_TYPE_END);
    attr_print(stream, ATTR_FLAG_NONE,
        SEND_ATTR_FUNC(rcpt_print, (const void *) rcpt),
        ATTR_TYPE_END);

    if (vstream_fflush(stream)) {
 msg_warn("%s: bad write: %m", VSTREAM_PATH(stream));
 stat = -1;
    } else {
 stat = 0;
    }
    return (stat);
}

/* deliver_pass_final_reply - retrieve final delivery status response */

static int deliver_pass_final_reply(VSTREAM *stream, DSN_BUF *dsb)
{
    int     stat;

    if (attr_scan(stream, ATTR_FLAG_STRICT,
    RECV_ATTR_FUNC(dsb_scan, (void *) dsb),
    RECV_ATTR_INT(MAIL_ATTR_STATUS, &stat),
    ATTR_TYPE_END) != 2) {
 msg_warn("%s: malformed response", VSTREAM_PATH(stream));
 return (DELIVER_PASS_UNKNOWN);
    } else {
 return (stat ? DELIVER_PASS_DEFER : 0);
    }
}

/* deliver_pass - deliver one per-site queue entry */

int     deliver_pass(const char *classconst char *service,
               DELIVER_REQUEST *request,
               RECIPIENT *rcpt)
{
    VSTREAM *stream;
    DSN_BUF *dsb;
    DSN     dsn;
    int     status;
    char   *saved_service;
    char   *transport;
    char   *nexthop;

    /*
     * Parse service into transport:nexthop form, and allow for omission of
     * optional fields
     */

    transport = saved_service = mystrdup(service);
    if ((nexthop = split_at(saved_service, ':')) == 0 || *nexthop == 0)
 nexthop = request->nexthop;
    if (*transport == 0)
 msg_fatal("missing transport name in \"%s\"", service);

    /*
     * Initialize.
     */

    msg_info("%s: passing <%s> to transport=%s",
      request->queue_id, info_log_addr_form_recipient(rcpt->address),
      transport);
    stream = mail_connect_wait(class, transport);
    dsb = dsb_create();

    /*
     * Get the delivery process initial response. Send the queue file info
     * and recipient info to the delivery process. Retrieve the delivery
     * agent status report. The numerical status code indicates if delivery
     * should be tried again. The reason text is sent only when a destination
     * should be avoided for a while, so that the queue manager can log why
     * it does not even try to schedule delivery to the affected recipients.
     * XXX Can't pass back hop status info because the problem is with a
     * different transport.
     */

    if (deliver_pass_initial_reply(stream) != 0
 || deliver_pass_send_request(stream, request, nexthop, rcpt) != 0) {
 (void) DSN_SIMPLE(&dsn, "4.3.0""mail transport unavailable");
 status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
         request->queue_id, &request->msg_stats,
         rcpt, "none", NO_TLS_STATS, &dsn);
    } else if ((status = deliver_pass_final_reply(stream, dsb))
        == DELIVER_PASS_UNKNOWN) {
 (void) DSN_SIMPLE(&dsn, "4.3.0""unknown mail transport error");
 status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
         request->queue_id, &request->msg_stats,
         rcpt, "none", NO_TLS_STATS, &dsn);
    }

    /*
     * Clean up.
     */

    vstream_fclose(stream);
    dsb_free(dsb);
    myfree(saved_service);

    return (status);
}

/* deliver_pass_all - pass entire delivery request */

int     deliver_pass_all(const char *classconst char *service,
            DELIVER_REQUEST *request)
{
    RECIPIENT_LIST *list;
    RECIPIENT *rcpt;
    int     status = 0;

    /*
     * XXX We should find out if the target transport can handle
     * multi-recipient requests. Unfortunately such code is hard to test,
     * rarely used, and therefore will be buggy.
     */

    list = &request->rcpt_list;
    for (rcpt = list->info; rcpt < list->info + list->len; rcpt++)
 status |= deliver_pass(class, service, request, rcpt);
    return (status);
}

Messung V0.5 in Prozent
C=75 H=96 G=86

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.