Eine aufbereitete Darstellung der Quelle

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

Benutzer

SSL mail_addr_map.c   Sprache: C

 

/*++
/* NAME
/* mail_addr_map 3
/* SUMMARY
/* generic address mapping
/* SYNOPSIS
/* #include <mail_addr_map.h>
/*
/* ARGV *mail_addr_map_internal(path, address, propagate)
/* MAPS *path;
/* const char *address;
/* int propagate;
/*
/* ARGV *mail_addr_map_opt(path, address, propagate, in_form,
/* query_form, out_form)
/* MAPS *path;
/* const char *address;
/* int propagate;
/* int in_form;
/* int query_form;
/* int out_form;
/* DESCRIPTION
/* mail_addr_map_*() returns the translation for the named address,
/* or a null pointer if none is found.
/*
/* With mail_addr_map_internal(), the search address and results
/* are in internal (unquoted) form.
/*
/* mail_addr_map_opt() gives more control, at the cost of additional
/* conversions between internal and external forms.
/*
/* When the \fBpropagate\fR argument is non-zero,
/* address extensions that aren't explicitly matched in the lookup
/* table are propagated to the result addresses. The caller is
/* expected to pass the lookup result to argv_free().
/*
/* Lookups are performed by mail_addr_find_*(). When the result has the
/* form \fI@otherdomain\fR, the result is the original user in
/* \fIotherdomain\fR.
/*
/* Arguments:
/* .IP path
/* Dictionary search path (see maps(3)).
/* .IP address
/* The address to be looked up in external (quoted) form, or
/* in the form specified with the in_form argument.
/* .IP query_form
/* Database query address forms, either MA_FORM_INTERNAL (unquoted
/* form), MA_FORM_EXTERNAL (quoted form), MA_FORM_EXTERNAL_FIRST
/* (external, then internal if the forms differ), or
/* MA_FORM_INTERNAL_FIRST (internal, then external if the forms
/* differ).
/* .IP in_form
/* .IP out_form
/* Input and output address forms, either MA_FORM_INTERNAL (unquoted
/* form) or MA_FORM_EXTERNAL (quoted form).
/* DIAGNOSTICS
/* Warnings: map lookup returns a non-address result.
/*
/* The path->error value is non-zero when the lookup
/* failed with a non-permanent error.
/* SEE ALSO
/* mail_addr_find(3), mail address matching
/* mail_addr_crunch(3), mail address parsing and rewriting
/* 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
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/


/* System library. */

#include <sys_defs.h>
#include <string.h>

/* Utility library. */

#include <msg.h>
#include <vstring.h>
#include <dict.h>
#include <argv.h>
#include <mymalloc.h>

/* Global library. */

#include <quote_822_local.h>
#include <mail_addr_find.h>
#include <mail_addr_crunch.h>
#include <mail_addr_map.h>

/* Application-specific. */

#define STR vstring_str
#define LEN VSTRING_LEN

/* mail_addr_map - map a canonical address */

ARGV   *mail_addr_map_opt(MAPS *path, const char *address, int propagate,
             int in_form, int query_form, int out_form)
{
    VSTRING *buffer = 0;
    const char *myname = "mail_addr_map";
    const char *string;
    char   *ratsign;
    char   *extension = 0;
    ARGV   *argv = 0;
    int     i;
    VSTRING *int_address = 0;
    VSTRING *ext_address = 0;
    const char *int_addr;

    /*
     * Optionally convert input from external form. We prefer internal-form
     * input to avoid unnecessary input conversion in mail_addr_find_opt().
     */

    if (in_form == MA_FORM_EXTERNAL) {
 int_address = vstring_alloc(100);
 unquote_822_local(int_address, address);
 int_addr = STR(int_address);
 in_form = MA_FORM_INTERNAL;
    } else {
 int_addr = address;
    }

    /*
     * Look up the full address; if no match is found, look up the address
     * with the extension stripped off, and remember the unmatched extension.
     */

    if ((string = mail_addr_find_opt(path, int_addr, &extension,
         in_form, query_form,
         MA_FORM_EXTERNAL,
         MA_FIND_DEFAULT)) != 0) {

 /*
  * Prepend the original user to @otherdomain, but do not propagate
  * the unmatched address extension. Convert the address to external
  * form just like the mail_addr_find_opt() output.
 */

 if (*string == '@') {
     buffer = vstring_alloc(100);
     if ((ratsign = strrchr(int_addr, '@')) != 0)
  vstring_strncpy(buffer, int_addr, ratsign - int_addr);
     else
  vstring_strcpy(buffer, int_addr);
     if (extension)
  vstring_truncate(buffer, LEN(buffer) - strlen(extension));
     vstring_strcat(buffer, string);
     ext_address = vstring_alloc(2 * LEN(buffer));
     quote_822_local(ext_address, STR(buffer));
     string = STR(ext_address);
 }

 /*
  * Canonicalize the result, and propagate the unmatched extension to
  * each address found.
 */

 argv = mail_addr_crunch_opt(string, propagate ? extension : 0,
        MA_FORM_EXTERNAL, out_form);
 if (buffer)
     vstring_free(buffer);
 if (ext_address)
     vstring_free(ext_address);
 if (msg_verbose)
     for (i = 0; i < argv->argc; i++)
  msg_info("%s: %s -> %d: %s", myname, address, i, argv->argv[i]);
 if (argv->argc == 0) {
     msg_warn("%s lookup of %s returns non-address result \"%s\"",
       path->title, address, string);
     argv = argv_free(argv);
     path->error = DICT_ERR_RETRY;
 }
    }

    /*
     * No match found.
     */

    else {
 if (msg_verbose)
     msg_info("%s: %s -> %s", myname, address,
       path->error ? "(try again)" : "(not found)");
    }

    /*
     * Cleanup.
     */

    if (extension)
 myfree(extension);
    if (int_address)
 vstring_free(int_address);

    return (argv);
}

#ifdef TEST

/*
 * SYNOPSIS
 * mail_addr_map pass_tests | fail_tests
 * DESCRIPTION
 * mail_addr_map performs the specified set of built-in
 * unit tests. With 'pass_tests', all tests must pass, and
 * with 'fail_tests' all tests must fail.
 * DIAGNOSTICS
 * When a unit test fails, the program prints details of the
 * failed test.
 *
 * The program terminates with a non-zero exit status when at
 * least one test does not pass with 'pass_tests', or when at
 * least one test does not fail with 'fail_tests'.
 */


/* System library. */

#include <sys_defs.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Utility library. */

#include <argv.h>
#include <msg.h>
#include <mymalloc.h>
#include <vstring.h>

/* Global library. */

#include <canon_addr.h>
#include <mail_addr_map.h>
#include <mail_params.h>

/* Application-specific. */

#define STR vstring_str

typedef struct {
    const char *testname;
    const char *database;
    int     propagate;
    const char *delimiter;
    int     in_form;
    int     query_form;
    int     out_form;
    const char *address;
    const char *expect_argv[2];
    int     expect_argc;
} MAIL_ADDR_MAP_TEST;

#define DONT_PROPAGATE_UNMATCHED_EXTENSION 0
#define DO_PROPAGATE_UNMATCHED_EXTENSION 1
#define NO_RECIPIENT_DELIMITER   ""
#define PLUS_RECIPIENT_DELIMITER  "+"
#define DOT_RECIPIENT_DELIMITER   "."

 /*
  * All these tests must pass, so that we know that mail_addr_map_opt() works
  * as intended. mail_addr_map() has always been used for maps that expect
  * external-form queries, so there are no tests here for internal-form
  * queries.
  */

static MAIL_ADDR_MAP_TEST pass_tests[] = {
    {
 "1 external -external-> external, no extension",
 "inline:{ aa@example.com=bb@example.com }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "aa@example.com",
 {"bb@example.com"}, 1,
    },
    {
 "2 external -external-> external, extension, propagation",
 "inline:{ aa@example.com=bb@example.com }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "aa+ext@example.com",
 {"bb+ext@example.com"}, 1,
    },
    {
 "3 external -external-> external, extension, no propagation, no match",
 "inline:{ aa@example.com=bb@example.com }",
 DONT_PROPAGATE_UNMATCHED_EXTENSION, NO_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "aa+ext@example.com",
 {0}, 0,
    },
    {
 "4 external -external-> external, extension, full match",
 "inline:{{cc+ext@example.com=dd@example.com,ee@example.com}}",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "cc+ext@example.com",
 {"dd@example.com", "ee@example.com"}, 2,
    },
    {
 "5 external -external-> external, no extension, quoted",
 "inline:{ {\"a a\"@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "\"a a\"@example.com",
 {"\"b b\"@example.com"}, 1,
    },
    {
 "6 external -external-> external, extension, propagation, quoted",
 "inline:{ {\"a a\"@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "\"a a+ext\"@example.com",
 {"\"b b+ext\"@example.com"}, 1,
    },
    {
 "7 internal -external-> internal, no extension, propagation, embedded space",
 "inline:{ {\"a a\"@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_INTERNAL, MA_FORM_EXTERNAL, MA_FORM_INTERNAL,
 "a a@example.com",
 {"b b@example.com"}, 1,
    },
    {
 "8 internal -external-> internal, extension, propagation, embedded space",
 "inline:{ {\"a a\"@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_INTERNAL, MA_FORM_EXTERNAL, MA_FORM_INTERNAL,
 "a a+ext@example.com",
 {"b b+ext@example.com"}, 1,
    },
    {
 "9 internal -external-> internal, no extension, propagation, embedded space",
 "inline:{ {a_a@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_INTERNAL, MA_FORM_EXTERNAL, MA_FORM_INTERNAL,
 "a_a@example.com",
 {"b b@example.com"}, 1,
    },
    {
 "10 internal -external-> internal, extension, propagation, embedded space",
 "inline:{ {a_a@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_INTERNAL, MA_FORM_EXTERNAL, MA_FORM_INTERNAL,
 "a_a+ext@example.com",
 {"b b+ext@example.com"}, 1,
    },
    {
 "11 internal -external-> internal, no extension, @domain",
 "inline:{ {@example.com=@example.net} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_INTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "a@a@example.com",
 {"\"a@a\"@example.net"}, 1,
    },
    {
 "12 external -external-> external, extension, propagation",
 "inline:{ aa@example.com=bb@example.com }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, DOT_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "aa.ext@example.com",
 {"bb.ext@example.com"}, 1,
    },
    0,
};

 /*
  * All these tests must fail, so that we know that the tests work.
  */

static MAIL_ADDR_MAP_TEST fail_tests[] = {
    {
 "selftest 1 external -external-> external, no extension, quoted",
 "inline:{ {\"a a\"@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "\"a a\"@example.com",
 {"\"bXb\"@example.com"}, 1,
    },
    {
 "selftest 2 external -external-> external, no extension, quoted",
 "inline:{ {\"a a\"@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "\"aXa\"@example.com",
 {"\"b b\"@example.com"}, 1,
    },
    {
 "selftest 3 external -external-> external, no extension, quoted",
 "inline:{ {\"a a\"@example.com=\"b b\"@example.com} }",
 DO_PROPAGATE_UNMATCHED_EXTENSION, PLUS_RECIPIENT_DELIMITER,
 MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
 "\"a a\"@example.com",
 {0}, 0,
    },
    0,
};

/* canon_addr_external - surrogate to avoid trivial-rewrite dependency */

VSTRING *canon_addr_external(VSTRING *result, const char *addr)
{
    return (vstring_strcpy(result, addr));
}

static int compare(const char *testname,
             const char **expect_argv, int expect_argc,
             char **result_argv, int result_argc)
{
    int     n;
    int     err = 0;

    if (expect_argc != 0 && result_argc != 0) {
 for (n = 0; n < expect_argc && n < result_argc; n++) {
     if (strcmp(expect_argv[n], result_argv[n]) != 0) {
  msg_warn("fail test %s: expect[%d]='%s', result[%d]='%s'",
    testname, n, expect_argv[n], n, result_argv[n]);
  err = 1;
     }
 }
    }
    if (expect_argc != result_argc) {
 msg_warn("fail test %s: expects %d results but there were %d",
   testname, expect_argc, result_argc);
 for (n = expect_argc; n < result_argc; n++)
     msg_info("no expect to match result[%d]='%s'", n, result_argv[n]);
 for (n = result_argc; n < expect_argc; n++)
     msg_info("no result to match expect[%d]='%s'", n, expect_argv[n]);
 err = 1;
    }
    return (err);
}

static char *progname;

static NORETURN usage(void)
{
    msg_fatal("usage: %s pass_test | fail_test", progname);
}

int     main(int argc, char **argv)
{
    MAIL_ADDR_MAP_TEST *test;
    MAIL_ADDR_MAP_TEST *tests;
    int     errs = 0;

#define UPDATE(dst, src) { if (dst) myfree(dst); dst = mystrdup(src); }

    /*
     * Parse JCL.
     */

    progname = argv[0];
    if (argc != 2) {
 usage();
    } else if (strcmp(argv[1], "pass_tests") == 0) {
 tests = pass_tests;
    } else if (strcmp(argv[1], "fail_tests") == 0) {
 tests = fail_tests;
    } else {
 usage();
    }

    /*
     * Initialize.
     */

    mail_params_init();

    /*
     * A read-eval-print loop, because specifying C strings with quotes and
     * backslashes is painful.
     */

    for (test = tests; test->testname; test++) {
 ARGV   *result;
 int     fail = 0;

 if (mail_addr_form_to_string(test->in_form) == 0) {
     msg_warn("test %s: bad in_form field: %d",
       test->testname, test->in_form);
     fail = 1;
     continue;
 }
 if (mail_addr_form_to_string(test->query_form) == 0) {
     msg_warn("test %s: bad query_form field: %d",
       test->testname, test->query_form);
     fail = 1;
     continue;
 }
 if (mail_addr_form_to_string(test->out_form) == 0) {
     msg_warn("test %s: bad out_form field: %d",
       test->testname, test->out_form);
     fail = 1;
     continue;
 }
 MAPS   *maps = maps_create("test", test->database, DICT_FLAG_LOCK
        | DICT_FLAG_FOLD_FIX | DICT_FLAG_UTF8_REQUEST);

 UPDATE(var_rcpt_delim, test->delimiter);
 result = mail_addr_map_opt(maps, test->address, test->propagate,
      test->in_form, test->query_form, test->out_form);
 if (compare(test->testname, test->expect_argv, test->expect_argc,
        result ? result->argv : 0, result ? result->argc : 0) != 0) {
     msg_info("database = %s", test->database);
     msg_info("propagate = %d", test->propagate);
     msg_info("delimiter = '%s'", var_rcpt_delim);
     msg_info("in_form = %s", mail_addr_form_to_string(test->in_form));
     msg_info("query_form = %s", mail_addr_form_to_string(test->query_form));
     msg_info("out_form = %s", mail_addr_form_to_string(test->out_form));
     msg_info("address = %s", test->address);
     fail = 1;
 }
 maps_free(maps);
 if (result)
     argv_free(result);

 /*
  * It is an error if a test does not pass or fail as intended.
 */

 errs += (tests == pass_tests ? fail : !fail);
    }
    return (errs != 0);
}

#endif

Messung V0.5 in Prozent
C=82 H=90 G=86

¤ Dauer der Verarbeitung: 0.29 Sekunden  (vorverarbeitet am  2026-09-28) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Dauer der Verarbeitung:

Sekunden

sprechenden Kalenders






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126438
#Domains=1867298