Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  cleanup_bounce.c

  Sprache: C
 

/*++
/* NAME
/* cleanup_bounce 3
/* SUMMARY
/* bounce all recipients
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* void cleanup_bounce(state)
/* CLEANUP_STATE *state;
/* DESCRIPTION
/* cleanup_bounce() updates the bounce log on request by client
/* programs that cannot handle such problems themselves.
/*
/* Upon successful completion, all error flags are reset,
/* and the message is scheduled for deletion.
/* Otherwise, the CLEANUP_STAT_WRITE error flag is raised.
/*
/* Arguments:
/* .IP state
/* Queue file and message processing state. This state is
/* updated as records are processed and as errors happen.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/


/* System library. */

#include <sys_defs.h>

/* Utility library. */

#include <msg.h>
#include <stringops.h>
#include <stdlib.h>

/* Global library. */

#include <cleanup_user.h>
#include <mail_params.h>
#include <mail_proto.h>
#include <bounce.h>
#include <dsn_util.h>
#include <record.h>
#include <rec_type.h>
#include <dsn_mask.h>
#include <mail_queue.h>
#include <rec_attr_map.h>

/* Application-specific. */

#include "cleanup.h"

#define STR(x) vstring_str(x)

/* cleanup_bounce_append - update bounce logfile */

static void cleanup_bounce_append(CLEANUP_STATE *state, RECIPIENT *rcpt,
              DSN *dsn)
{
    MSG_STATS stats;

    /*
     * Don't log a spurious warning (for example, when soft_bounce is turned
     * on). bounce_append() already logs a record when the logfile can't be
     * updated. Set the write error flag, so that a maildrop queue file won't
     * be destroyed.
     */

    if (bounce_append(BOUNCE_FLAG_CLEAN, state->queue_id,
        CLEANUP_MSG_STATS(&stats, state),
        rcpt, "none", NO_TLS_STATS, dsn) != 0) {
 state->errs |= CLEANUP_STAT_WRITE;
    }
}

/* cleanup_bounce - bounce all recipients */

int     cleanup_bounce(CLEANUP_STATE *state)
{
    const char *myname = "cleanup_bounce";
    VSTRING *buf = vstring_alloc(100);
    const CLEANUP_STAT_DETAIL *detail;
    DSN_SPLIT dp;
    const char *dsn_status;
    const char *dsn_text;
    char   *rcpt = 0;
    RECIPIENT recipient;
    DSN     dsn;
    char   *attr_name;
    char   *attr_value;
    char   *dsn_orcpt = 0;
    int     dsn_notify = 0;
    char   *orig_rcpt = 0;
    char   *start;
    int     rec_type;
    int     junk;
    long    curr_offset;
    const char *encoding;
    const char *dsn_envid;
    int     dsn_ret;
    int     bounce_err;

    /*
     * Parse the failure reason if one was given, otherwise use a generic
     * mapping from cleanup-internal error code to (DSN + text).
     */

    if (state->reason) {
 dsn_split(&dp, "5.0.0", state->reason);
 dsn_status = DSN_STATUS(dp.dsn);
 dsn_text = dp.text;
    } else {
 detail = cleanup_stat_detail(state->errs);
 dsn_status = detail->dsn;
 dsn_text = detail->text;
    }

    /*
     * Create a bounce logfile with one entry for each final recipient.
     * Degrade gracefully in case of no recipients or no queue file.
     * 
     * Victor Duchovni observes that the number of recipients in the queue file
     * can potentially be very large due to virtual alias expansion. This can
     * expand the recipient count by virtual_alias_expansion_limit (default:
     * 1000) times.
     * 
     * After a queue file write error, purge any unwritten data (so that
     * vstream_fseek() won't fail while trying to flush it) and reset the
     * stream error flags to avoid false alarms.
     */

    if (vstream_ferror(state->dst) || vstream_fflush(state->dst)) {
 (void) vstream_fpurge(state->dst, VSTREAM_PURGE_BOTH);
 vstream_clearerr(state->dst);
    }
    if (vstream_fseek(state->dst, 0L, SEEK_SET) < 0)
 msg_fatal("%s: seek %s: %m", myname, cleanup_path);

    while ((state->errs & CLEANUP_STAT_WRITE) == 0) {
 if ((curr_offset = vstream_ftell(state->dst)) < 0)
     msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path);
 if ((rec_type = rec_get(state->dst, buf, 0)) <= 0
     || rec_type == REC_TYPE_END)
     break;
 start = STR(buf);
 if (rec_type == REC_TYPE_ATTR) {
     if (split_nameval(STR(buf), &attr_name, &attr_value) != 0
  || *attr_value == 0)
  continue;
     /* Map attribute names to pseudo record type. */
     if ((junk = rec_attr_map(attr_name)) != 0) {
  start = attr_value;
  rec_type = junk;
     }
 }
 switch (rec_type) {
 case REC_TYPE_DSN_ORCPT:  /* RCPT TO ORCPT parameter */
     if (dsn_orcpt != 0)   /* can't happen */
  myfree(dsn_orcpt);
     dsn_orcpt = mystrdup(start);
     break;
 case REC_TYPE_DSN_NOTIFY:  /* RCPT TO NOTIFY parameter */
     if (alldig(start) && (junk = atoi(start)) > 0
  && DSN_NOTIFY_OK(junk))
  dsn_notify = junk;
     else
  dsn_notify = 0;
     break;
 case REC_TYPE_ORCP:   /* unmodified RCPT TO address */
     if (orig_rcpt != 0)   /* can't happen */
  myfree(orig_rcpt);
     orig_rcpt = mystrdup(start);
     break;
 case REC_TYPE_RCPT:   /* rewritten RCPT TO address */
     rcpt = start;
     RECIPIENT_ASSIGN(&recipient, curr_offset,
        dsn_orcpt ? dsn_orcpt : "", dsn_notify,
        orig_rcpt ? orig_rcpt : rcpt, rcpt);
     (void) DSN_SIMPLE(&dsn, dsn_status, dsn_text);
     cleanup_bounce_append(state, &recipient, &dsn);
     /* FALLTHROUGH */
 case REC_TYPE_DRCP:   /* canceled recipient */
 case REC_TYPE_DONE:   /* can't happen */
     if (orig_rcpt != 0) {
  myfree(orig_rcpt);
  orig_rcpt = 0;
     }
     if (dsn_orcpt != 0) {
  myfree(dsn_orcpt);
  dsn_orcpt = 0;
     }
     dsn_notify = 0;
     break;
 }
    }
    if (orig_rcpt != 0)    /* can't happen */
 myfree(orig_rcpt);
    if (dsn_orcpt != 0)    /* can't happen */
 myfree(dsn_orcpt);

    /*
     * No recipients. Yes, this can happen.
     */

    if ((state->errs & CLEANUP_STAT_WRITE) == 0 && rcpt == 0) {
 RECIPIENT_ASSIGN(&recipient, 0""0"""unknown");
 (void) DSN_SIMPLE(&dsn, dsn_status, dsn_text);
 cleanup_bounce_append(state, &recipient, &dsn);
    }
    vstring_free(buf);

    /*
     * Flush the bounce logfile to the sender. See also qmgr_active.c.
     */

    if ((state->errs & CLEANUP_STAT_WRITE) == 0) {
 if ((encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) == 0)
     encoding = MAIL_ATTR_ENC_NONE;
 dsn_envid = state->dsn_envid ?
     state->dsn_envid : "";
 /* Do not send unfiltered (body) content. */
 dsn_ret = (state->errs & (CLEANUP_STAT_CONT | CLEANUP_STAT_SIZE)) ?
     DSN_RET_HDRS : state->dsn_ret;

 if (state->verp_delims == 0 || var_verp_bounce_off) {
     bounce_err =
  bounce_flush(BOUNCE_FLAG_CLEAN,
        state->queue_name, state->queue_id,
        encoding, state->sendopts, state->sender,
        dsn_envid, dsn_ret);
 } else {
     bounce_err =
  bounce_flush_verp(BOUNCE_FLAG_CLEAN,
      state->queue_name, state->queue_id,
      encoding, state->sendopts, state->sender,
      dsn_envid, dsn_ret, state->verp_delims);
 }
 if (bounce_err != 0) {
     msg_warn("%s: bounce message failure", state->queue_id);
     state->errs |= CLEANUP_STAT_WRITE;
 }
    }

    /*
     * Schedule this message (and trace logfile) for deletion when all is
     * well. When all is not well these files would be deleted too, but the
     * client would get a different completion status so we have to carefully
     * maintain the bits anyway.
     */

    if ((state->errs &= CLEANUP_STAT_WRITE) == 0)
 state->flags |= CLEANUP_FLAG_DISCARD;

    return (state->errs);
}

Messung V0.5 in Prozent
C=76 H=94 G=85

¤ 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142