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

Quelle  scache.c

  Sprache: C
 

/*++
/* NAME
/* scache 3
/* SUMMARY
/* generic session cache API
/* SYNOPSIS
/* #include <scache.h>
/* DESCRIPTION
/* typedef struct {
/* .in +4
/* int dest_count;
/* int endp_count;
/* int sess_count;
/* .in -4
/* } SCACHE_SIZE;
/*
/* unsigned scache_size(scache, size)
/* SCACHE *scache;
/* SCACHE_SIZE *size;
/*
/* void scache_free(scache)
/* SCACHE *scache;
/*
/* void    scache_save_endp(scache, endp_ttl, endp_label, endp_prop, fd)
/* SCACHE *scache;
/* int endp_ttl;
/* const char *endp_label;
/* const char *endp_prop;
/* int fd;
/*
/* int     scache_find_endp(scache, endp_label, endp_prop)
/* SCACHE *scache;
/* const char *endp_label;
/* VSTRING *endp_prop;
/*
/* void scache_save_dest(scache, dest_ttl, dest_label,
/* dest_prop, endp_label)
/* SCACHE *scache;
/* int dest_ttl;
/* const char *dest_label;
/* const char *dest_prop;
/* const char *endp_label;
/*
/* int scache_find_dest(dest_label, dest_prop, endp_prop)
/* SCACHE *scache;
/* const char *dest_label;
/* VSTRING *dest_prop;
/* VSTRING *endp_prop;
/* DESCRIPTION
/* This module implements a generic session cache interface.
/* Specific cache types are described in scache_single(3),
/* scache_clnt(3) and scache_multi(3). These documents also
/* describe now to instantiate a specific session cache type.
/*
/* The code maintains two types of association: a) physical
/* endpoint to file descriptor, and b) logical endpoint
/* to physical endpoint. Physical endpoints are stored and
/* looked up under their low-level session details such as
/* numerical addresses, while logical endpoints are stored
/* and looked up by the domain name that humans use. One logical
/* endpoint can refer to multiple physical endpoints, one
/* physical endpoint may be referenced by multiple logical
/* endpoints, and one physical endpoint may have multiple
/* sessions.
/*
/* scache_size() returns the number of logical destination
/* names, physical endpoint addresses, and cached sessions.
/*
/* scache_free() destroys the specified session cache.
/*
/* scache_save_endp() stores an open session under the specified
/* physical endpoint name.
/*
/* scache_find_endp() looks up a saved session under the
/* specified physical endpoint name.
/*
/* scache_save_dest() associates the specified physical endpoint
/* with the specified logical endpoint name.
/*
/* scache_find_dest() looks up a saved session under the
/* specified physical endpoint name.
/*
/* Arguments:
/* .IP endp_ttl
/* How long the session should be cached.  When information
/* expires it is purged automatically.
/* .IP endp_label
/* The transport name and the physical endpoint name under
/* which the session is stored and looked up.
/*
/* In the case of SMTP, the physical endpoint includes the numerical
/* IP address, address family information, and the numerical TCP port.
/* .IP endp_prop
/* Application-specific data with endpoint attributes.  It is up to
/* the application to passivate (flatten) and re-activate this content
/* upon storage and retrieval, respectively.
/* .sp
/* In the case of SMTP, the endpoint attributes specify the
/* server hostname, IP address, numerical TCP port, as well
/* as ESMTP features advertised by the server, and when information
/* expires. All this in some application-specific format that is easy
/* to unravel when re-activating a cached session.
/* .IP dest_ttl
/* How long the destination-to-endpoint binding should be
/* cached. When information expires it is purged automatically.
/* .IP dest_label
/* The transport name and the logical destination under which the
/* destination-to-endpoint binding is stored and looked up.
/*
/* In the case of SMTP, the logical destination is the DNS
/* host or domain name with or without [], plus the numerical TCP port.
/* .IP dest_prop
/* Application-specific attributes that describe features of
/* this logical to physical binding. It is up to the application
/* to passivate (flatten) and re-activate this content.
/* upon storage and retrieval, respectively
/* .sp
/* In case the of an SMTP logical destination to physical
/* endpoint binding, the attributes specify the logical
/* destination name, numerical port, whether the physical
/* endpoint is best mx host with respect to a logical or
/* fall-back destination, and when information expires.
/* .IP fd
/* File descriptor with session to be cached.
/* DIAGNOSTICS
/* scache_find_endp() and scache_find_dest() return -1 when
/* the lookup fails, and a file descriptor upon success.
/*
/* Other diagnostics: fatal error: memory allocation problem;
/* panic: internal consistency failure.
/* SEE ALSO
/* scache_single(3), single-session, in-memory cache
/* scache_clnt(3), session cache client
/* scache_multi(3), multi-session, in-memory cache
/* 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 <unistd.h>
#include <string.h>

/* Utility library. */

#include <msg.h>
#include <vstream.h>
#include <vstring.h>
#include <vstring_vstream.h>
#include <argv.h>
#include <events.h>

/* Global library. */

#include <scache.h>

#ifdef TEST

 /*
  * Driver program for cache regression tests. Although all variants are
  * relatively simple to verify by hand for single session storage, more
  * sophisticated instrumentation is needed to demonstrate that the
  * multi-session cache manager properly handles collisions in the time
  * domain and in all the name space domains.
  */

static SCACHE *scache;
static VSTRING *endp_prop;
static VSTRING *dest_prop;
static int verbose_level = 3;

 /*
  * Cache mode lookup table. We don't do the client-server variant because
  * that drags in a ton of configuration junk; the client-server protocol is
  * relatively easy to verify manually.
  */

struct cache_type {
    char   *mode;
    SCACHE *(*create) (void);
};

static struct cache_type cache_types[] = {
    "single", scache_single_create,
    "multi", scache_multi_create,
    0,
};

#define STR(x) vstring_str(x)

/* cache_type - select session cache type */

static void cache_type(ARGV *argv)
{
    struct cache_type *cp;

    if (argv->argc != 2) {
 msg_error("usage: %s mode", argv->argv[0]);
 return;
    }
    if (scache != 0)
 scache_free(scache);
    for (cp = cache_types; cp->mode != 0; cp++) {
 if (strcmp(cp->mode, argv->argv[1]) == 0) {
     scache = cp->create();
     return;
 }
    }
    msg_error("unknown cache type: %s", argv->argv[1]);
}

/* handle_events - handle events while time advances */

static void handle_events(ARGV *argv)
{
    int     delay;
    time_t  before;
    time_t  after;

    if (argv->argc != 2 || (delay = atoi(argv->argv[1])) <= 0) {
 msg_error("usage: %s time", argv->argv[0]);
 return;
    }
    before = event_time();
    event_drain(delay);
    after = event_time();
    if (after < before + delay)
 sleep(before + delay - after);
}

/* save_endp - save endpoint->session binding */

static void save_endp(ARGV *argv)
{
    int     ttl;
    int     fd;

    if (argv->argc != 5
 || (ttl = atoi(argv->argv[1])) <= 0
 || (fd = atoi(argv->argv[4])) <= 0) {
 msg_error("usage: save_endp ttl endpoint endp_props fd");
 return;
    }
    if (DUP2(0, fd) < 0)
 msg_fatal("dup2(0, %d): %m", fd);
    scache_save_endp(scache, ttl, argv->argv[2], argv->argv[3], fd);
}

/* find_endp - find endpoint->session binding */

static void find_endp(ARGV *argv)
{
    int     fd;

    if (argv->argc != 2) {
 msg_error("usage: find_endp endpoint");
 return;
    }
    if ((fd = scache_find_endp(scache, argv->argv[1], endp_prop)) >= 0)
 close(fd);
}

/* save_dest - save destination->endpoint binding */

static void save_dest(ARGV *argv)
{
    int     ttl;

    if (argv->argc != 5 || (ttl = atoi(argv->argv[1])) <= 0) {
 msg_error("usage: save_dest ttl destination dest_props endpoint");
 return;
    }
    scache_save_dest(scache, ttl, argv->argv[2], argv->argv[3], argv->argv[4]);
}

/* find_dest - find destination->endpoint->session binding */

static void find_dest(ARGV *argv)
{
    int     fd;

    if (argv->argc != 2) {
 msg_error("usage: find_dest destination");
 return;
    }
    if ((fd = scache_find_dest(scache, argv->argv[1], dest_prop, endp_prop)) >= 0)
 close(fd);
}

/* verbose - adjust noise level during cache manipulation */

static void verbose(ARGV *argv)
{
    int     level;

    if (argv->argc != 2 || (level = atoi(argv->argv[1])) < 0) {
 msg_error("usage: verbose level");
 return;
    }
    verbose_level = level;
}

 /*
  * The command lookup table.
  */

struct action {
    char   *command;
    void    (*action) (ARGV *);
    int     flags;
};

#define FLAG_NEED_CACHE (1<<0)

static void help(ARGV *);

static struct action actions[] = {
    "cache_type", cache_type, 0,
    "save_endp", save_endp, FLAG_NEED_CACHE,
    "find_endp", find_endp, FLAG_NEED_CACHE,
    "save_dest", save_dest, FLAG_NEED_CACHE,
    "find_dest", find_dest, FLAG_NEED_CACHE,
    "sleep", handle_events, 0,
    "verbose", verbose, 0,
    "?", help, 0,
    0,
};

/* help - list commands */

static void help(ARGV *argv)
{
    struct action *ap;

    vstream_printf("commands:");
    for (ap = actions; ap->command != 0; ap++)
 vstream_printf(" %s", ap->command);
    vstream_printf("\n");
    vstream_fflush(VSTREAM_OUT);
}

/* get_buffer - prompt for input or log input */

static int get_buffer(VSTRING *buf, VSTREAM *fp, int interactive)
{
    int     status;

    if (interactive) {
 vstream_printf("> ");
 vstream_fflush(VSTREAM_OUT);
    }
    if ((status = vstring_get_nonl(buf, fp)) != VSTREAM_EOF) {
 if (!interactive) {
     vstream_printf(">>> %s\n", STR(buf));
     vstream_fflush(VSTREAM_OUT);
 }
    }
    return (status);
}

/* at last, the main program */

int     main(int unused_argc, char **unused_argv)
{
    VSTRING *buf = vstring_alloc(1);
    ARGV   *argv;
    struct action *ap;
    int     interactive = isatty(0);

    endp_prop = vstring_alloc(1);
    dest_prop = vstring_alloc(1);

    vstream_fileno(VSTREAM_ERR) = 1;

    while (get_buffer(buf, VSTREAM_IN, interactive) != VSTREAM_EOF) {
 argv = argv_split(STR(buf), CHARS_SPACE);
 if (argv->argc > 0 && argv->argv[0][0] != '#') {
     msg_verbose = verbose_level;
     for (ap = actions; ap->command != 0; ap++) {
  if (strcmp(ap->command, argv->argv[0]) == 0) {
      if ((ap->flags & FLAG_NEED_CACHE) != 0 && scache == 0)
   msg_error("no session cache");
      else
   ap->action(argv);
      break;
  }
     }
     msg_verbose = 0;
     if (ap->command == 0)
  msg_error("bad command: %s", argv->argv[0]);
 }
 argv_free(argv);
    }
    scache_free(scache);
    vstring_free(endp_prop);
    vstring_free(dest_prop);
    vstring_free(buf);
    exit(0);
}

#endif

Messung V0.5 in Prozent
C=77 H=97 G=87

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

*© 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.