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

Quelle  rewrite.c

  Sprache: C
 

/*++
/* NAME
/* rewrite 3
/* SUMMARY
/* mail address rewriter
/* SYNOPSIS
/* #include "trivial-rewrite.h"
/*
/* void rewrite_init(void)
/*
/* void rewrite_proto(stream)
/* VSTREAM *stream;
/*
/* void rewrite_addr(context, addr, result)
/* RWR_CONTEXT *context;
/* char *addr;
/* VSTRING *result;
/*
/* void rewrite_tree(context, tree)
/* RWR_CONTEXT *context;
/* TOK822 *tree;
/*
/* RWR_CONTEXT local_context;
/* RWR_CONTEXT remote_context;
/* DESCRIPTION
/* This module implements the trivial address rewriting engine.
/*
/* rewrite_init() initializes data structures that are private
/* to this module. It should be called once before using the
/* actual rewriting routines.
/*
/* rewrite_proto() implements the client-server protocol: read
/* one rule set name and one address in external (quoted) form,
/* reply with the rewritten address in external form.
/*
/* rewrite_addr() rewrites an address string to another string.
/* Both input and output are in external (quoted) form.
/*
/* rewrite_tree() rewrites a parse tree with a single address to
/* another tree.  A tree is a dummy node on top of a token list.
/*
/* local_context and remote_context provide domain names for
/* completing incomplete address forms.
/* STANDARDS
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8)
/* or \fBpostlogd\fR(8).
/* BUGS
/* SEE ALSO
/* 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>
#include <stdlib.h>
#include <string.h>

#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif

/* Utility library. */

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

/* Global library. */

#include <mail_params.h>
#include <mail_proto.h>
#include <resolve_local.h>
#include <tok822.h>
#include <mail_conf.h>

/* Application-specific. */

#include "trivial-rewrite.h"

RWR_CONTEXT local_context = {
    VAR_MYORIGIN, &var_myorigin,
    VAR_MYDOMAIN, &var_mydomain,
};

RWR_CONTEXT remote_context = {
    VAR_REM_RWR_DOMAIN, &var_remote_rwr_domain,
    VAR_REM_RWR_DOMAIN, &var_remote_rwr_domain,
};

static VSTRING *ruleset;
static VSTRING *address;
static VSTRING *result;

/* rewrite_tree - rewrite address according to rule set */

void    rewrite_tree(RWR_CONTEXT *context, TOK822 *tree)
{
    TOK822 *colon;
    TOK822 *domain;
    TOK822 *bang;
    TOK822 *local;
    VSTRING *vstringval;

    /*
     * XXX If you change this module, quote_822_local.c, or tok822_parse.c,
     * be sure to re-run the tests under "make rewrite_clnt_test" and "make
     * resolve_clnt_test" in the global directory.
     */


    /*
     * Sanity check.
     */

    if (tree->head == 0)
 msg_panic("rewrite_tree: empty tree");

    /*
     * An empty address is a special case.
     */

    if (tree->head == tree->tail
 && tree->tail->type == TOK822_QSTRING
 && VSTRING_LEN(tree->tail->vstr) == 0)
 return;

    /*
     * Treat a lone @ as if it were an empty address.
     */

    if (tree->head == tree->tail
 && tree->tail->type == '@') {
 tok822_free_tree(tok822_sub_keep_before(tree, tree->tail));
 tok822_sub_append(tree, tok822_alloc(TOK822_QSTRING, ""));
 return;
    }

    /*
     * Strip source route.
     */

    if (tree->head->type == '@'
 && (colon = tok822_find_type(tree->head, ':')) != 0
 && colon != tree->tail)
 tok822_free_tree(tok822_sub_keep_after(tree, colon));

    /*
     * Optionally, transform address forms without @.
     */

    if ((domain = tok822_rfind_type(tree->tail, '@')) == 0) {

 /*
  * Swap domain!user to user@domain.
 */

 if (var_swap_bangpath != 0
     && (bang = tok822_find_type(tree->head, '!')) != 0) {
     tok822_sub_keep_before(tree, bang);
     local = tok822_cut_after(bang);
     tok822_free(bang);
     tok822_sub_prepend(tree, tok822_alloc('@', (char *) 0));
     if (local)
  tok822_sub_prepend(tree, local);
 }

 /*
  * Promote user%domain to user@domain.
 */

 else if (var_percent_hack != 0
   && (domain = tok822_rfind_type(tree->tail, '%')) != 0) {
     domain->type = '@';
 }

 /*
  * Append missing @origin
 */

 else if (var_append_at_myorigin != 0
   && REW_PARAM_VALUE(context->origin) != 0
   && REW_PARAM_VALUE(context->origin)[0] != 0) {
     domain = tok822_sub_append(tree, tok822_alloc('@', (char *) 0));
     tok822_sub_append(tree, tok822_scan(REW_PARAM_VALUE(context->origin),
      (TOK822 **) 0));
 }
    }

    /*
     * Append missing .domain, but leave broken forms ending in @ alone. This
     * merely makes diagnostics more accurate by leaving bogus addresses
     * alone.
     * 
     * Backwards-compatibility warning: warn for "user@localhost" when there is
     * no "localhost" in mydestination or in any other address class with an
     * explicit domain list.
     */

    if (var_append_dot_mydomain != 0
 && REW_PARAM_VALUE(context->domain) != 0
 && REW_PARAM_VALUE(context->domain)[0] != 0
 && (domain = tok822_rfind_type(tree->tail, '@')) != 0
 && domain != tree->tail
 && tok822_find_type(domain, TOK822_DOMLIT) == 0
 && tok822_find_type(domain, '.') == 0) {
 if (warn_compat_break_app_dot_mydomain
     && (vstringval = domain->next->vstr) != 0) {
     if (strcasecmp(vstring_str(vstringval), "localhost") != 0) {
  msg_info("using backwards-compatible default setting "
    VAR_APP_DOT_MYDOMAIN "=yes to rewrite \"%s\" to "
    "\"%s.%s\"", vstring_str(vstringval),
    vstring_str(vstringval), var_mydomain);
     } else if (resolve_class("localhost") == RESOLVE_CLASS_DEFAULT) {
  msg_info("using backwards-compatible default setting "
    VAR_APP_DOT_MYDOMAIN "=yes to rewrite \"%s\" to "
    "\"%s.%s\"; please add \"localhost\" to "
    "mydestination or other address class",
    vstring_str(vstringval), vstring_str(vstringval),
    var_mydomain);
     }
 }
 tok822_sub_append(tree, tok822_alloc('.', (char *) 0));
 tok822_sub_append(tree, tok822_scan(REW_PARAM_VALUE(context->domain),
         (TOK822 **) 0));
    }

    /*
     * Strip trailing dot at end of domain, but not dot-dot or @-dot. This
     * merely makes diagnostics more accurate by leaving bogus addresses
     * alone.
     */

    if (tree->tail->type == '.'
 && tree->tail->prev
 && tree->tail->prev->type != '.'
 && tree->tail->prev->type != '@')
 tok822_free_tree(tok822_sub_keep_before(tree, tree->tail));
}

/* rewrite_proto - read request and send reply */

int     rewrite_proto(VSTREAM *stream)
{
    RWR_CONTEXT *context;
    TOK822 *tree;

    if (attr_scan(stream, ATTR_FLAG_STRICT,
    RECV_ATTR_STR(MAIL_ATTR_RULE, ruleset),
    RECV_ATTR_STR(MAIL_ATTR_ADDR, address),
    ATTR_TYPE_END) != 2)
 return (-1);

    if (strcmp(vstring_str(ruleset), MAIL_ATTR_RWR_LOCAL) == 0)
 context = &local_context;
    else if (strcmp(vstring_str(ruleset), MAIL_ATTR_RWR_REMOTE) == 0)
 context = &remote_context;
    else {
 msg_warn("unknown context: %s", vstring_str(ruleset));
 return (-1);
    }

    /*
     * Sanity check. An address is supposed to be in externalized form.
     */

    if (*vstring_str(address) == 0) {
 msg_warn("rewrite_addr: null address");
 vstring_strcpy(result, vstring_str(address));
    }

    /*
     * Convert the address from externalized (quoted) form to token list,
     * rewrite it, and convert back.
     */

    else {
 tree = tok822_scan_addr(vstring_str(address));
 rewrite_tree(context, tree);
 tok822_externalize(result, tree, TOK822_STR_DEFL);
 tok822_free_tree(tree);
    }
    if (msg_verbose)
 msg_info("`%s' `%s' -> `%s'", vstring_str(ruleset),
   vstring_str(address), vstring_str(result));

    attr_print(stream, ATTR_FLAG_NONE,
        SEND_ATTR_INT(MAIL_ATTR_FLAGS, server_flags),
        SEND_ATTR_STR(MAIL_ATTR_ADDR, vstring_str(result)),
        ATTR_TYPE_END);

    if (vstream_fflush(stream) != 0) {
 msg_warn("write rewrite reply: %m");
 return (-1);
    }
    return (0);
}

/* rewrite_init - module initializations */

void    rewrite_init(void)
{
    ruleset = vstring_alloc(100);
    address = vstring_alloc(100);
    result = vstring_alloc(100);
}

Messung V0.5 in Prozent
C=82 H=94 G=88

¤ Dauer der Verarbeitung: 0.1 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.