#ifndef _DICT_H_INCLUDED_
#define _DICT_H_INCLUDED_
/*++
/* NAME
/* dict 3h
/* SUMMARY
/* dictionary manager
/* SYNOPSIS
/* #include <dict.h>
/* DESCRIPTION
/* .nf
/*
* System library .
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <setjmp.h>
#ifdef NO_SIGSETJMP
#define DICT_JMP_BUF jmp_buf
#else
#define DICT_JMP_BUF sigjmp_buf
#endif
/*
* Utility library .
*/
#include <vstream.h>
#include <argv.h>
#include <vstring.h>
#include <myflock.h>
/*
* Provenance information .
*/
typedef struct DICT_OWNER {
int status; /* see below */
uid_t uid; /* use only if status == UNTRUSTED */
} DICT_OWNER;
/*
* Note that trust levels are not in numerical order .
*/
#define DICT_OWNER_UNKNOWN (-1 ) /* ex: unauthenticated tcp, proxy */
#define DICT_OWNER_TRUSTED (!1 ) /* ex: root-owned config file */
#define DICT_OWNER_UNTRUSTED (!0 ) /* ex: non-root config file */
/*
* When combining tables with different provenance , we initialize to the
* highest trust level , and remember the lowest trust level that we find
* during aggregation . If we combine tables that are owned by different
* untrusted users , the resulting provenance is " unknown " .
*/
#define DICT_OWNER_AGGREGATE_INIT(dst) { \
(dst).status = DICT_OWNER_TRUSTED; \
(dst).uid = 0 ; \
} while (0 )
/*
* The following is derived from the 3 x3 transition matrix .
*/
#define DICT_OWNER_AGGREGATE_UPDATE(dst, src) do { \
if ((dst).status == DICT_OWNER_TRUSTED \
|| (src).status == DICT_OWNER_UNKNOWN) { \
(dst) = (src); \
} else if ((dst).status == (src).status \
&& (dst).uid != (src).uid) { \
(dst).status = DICT_OWNER_UNKNOWN; \
(dst).uid = ~0 ; \
} \
} while (0 )
/*
* Generic dictionary interface - in reality , a dictionary extends this
* structure with private members to maintain internal state .
*/
typedef struct DICT {
char *type; /* for diagnostics */
char *name; /* for diagnostics */
int flags; /* see below */
const char *(*lookup) (struct DICT *, const char *);
int (*update) (struct DICT *, const char *, const char *);
int (*delete ) (struct DICT *, const char *);
int (*sequence) (struct DICT *, int , const char **, const char **);
int (*lock) (struct DICT *, int );
void (*close) (struct DICT *);
int lock_type; /* for read/write lock */
int lock_fd; /* for read/write lock */
int stat_fd; /* change detection */
time_t mtime; /* mod time at open */
VSTRING *fold_buf; /* key folding buffer */
DICT_OWNER owner; /* provenance */
int error; /* last operation only */
DICT_JMP_BUF *jbuf; /* exception handling */
struct DICT_UTF8_BACKUP *utf8_backup; /* see below */
struct VSTRING *file_buf; /* dict_file_to_buf() */
struct VSTRING *file_b64; /* dict_file_to_b64() */
char *reg_name; /* managed by dict_register() */
void (*saved_close) (struct DICT *); /* managed by dict_register() */
} DICT;
extern DICT *dict_alloc(const char *, const char *, ssize_t);
extern void dict_free(DICT *);
/*
* See dict_open . c embedded manpage for flag definitions .
*/
#define DICT_FLAG_NONE (0 )
#define DICT_FLAG_DUP_WARN (1 <<0 ) /* warn about dups if not supported */
#define DICT_FLAG_DUP_IGNORE (1 <<1 ) /* ignore dups if not supported */
#define DICT_FLAG_TRY0NULL (1 <<2 ) /* do not append 0 to key/value */
#define DICT_FLAG_TRY1NULL (1 <<3 ) /* append 0 to key/value */
#define DICT_FLAG_FIXED (1 <<4 ) /* fixed key map */
#define DICT_FLAG_PATTERN (1 <<5 ) /* keys are patterns */
#define DICT_FLAG_LOCK (1 <<6 ) /* use temp lock before access */
#define DICT_FLAG_DUP_REPLACE (1 <<7 ) /* replace dups if supported */
#define DICT_FLAG_SYNC_UPDATE (1 <<8 ) /* sync updates if supported */
/*#define DICT_FLAG_DEBUG (1<<9) /* log access */
/*#define DICT_FLAG_FOLD_KEY (1<<10) /* lowercase the lookup key */
#define DICT_FLAG_NO_REGSUB (1 <<11 ) /* disallow regexp substitution */
#define DICT_FLAG_NO_PROXY (1 <<12 ) /* disallow proxy mapping */
#define DICT_FLAG_NO_UNAUTH (1 <<13 ) /* disallow unauthenticated data */
#define DICT_FLAG_FOLD_FIX (1 <<14 ) /* case-fold key with fixed-case map */
#define DICT_FLAG_FOLD_MUL (1 <<15 ) /* case-fold key with multi-case map */
#define DICT_FLAG_FOLD_ANY (DICT_FLAG_FOLD_FIX | DICT_FLAG_FOLD_MUL)
#define DICT_FLAG_OPEN_LOCK (1 <<16 ) /* perm lock if not multi-writer safe */
#define DICT_FLAG_BULK_UPDATE (1 <<17 ) /* optimize for bulk updates */
#define DICT_FLAG_MULTI_WRITER (1 <<18 ) /* multi-writer safe map */
#define DICT_FLAG_UTF8_REQUEST (1 <<19 ) /* activate UTF-8 if possible */
#define DICT_FLAG_UTF8_ACTIVE (1 <<20 ) /* UTF-8 proxy layer is present */
#define DICT_FLAG_SRC_RHS_IS_FILE \
(1 <<21 ) /* Map source RHS is a file */
#define DICT_FLAG_SURROGATE (1 <22 ) /* This is a surrogate dictionary */
#define DICT_FLAG_UTF8_MASK (DICT_FLAG_UTF8_REQUEST)
/* IMPORTANT: Update the dict_mask[] table when the above changes */
/*
* The subsets of flags that control how a map is used . These are relevant
* mainly for proxymap support . Note : some categories overlap .
*
* DICT_FLAG_PARANOID - requestor flags that forbid the use of insecure map
* types for security - sensitive operations . These flags are checked by the
* map implementation itself upon open , lookup etc . requests .
*/
#define DICT_FLAG_PARANOID \
(DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY | DICT_FLAG_NO_UNAUTH)
/*
* Feature tests .
*/
#define DICT_NEED_UTF8_ACTIVATION(enable, flags) \
((enable) && ((flags) & DICT_FLAG_UTF8_MASK))
/*
* dict - > error values . Errors must be negative ; smtpd_check depends on this .
*/
#define DICT_ERR_NONE 0 /* no error */
#define DICT_ERR_RETRY (-1 ) /* soft error */
#define DICT_ERR_CONFIG (-2 ) /* configuration error */
/*
* Result values for exposed functions except lookup . FAIL / ERROR are
* suggested values , not for use in comparisons for equality .
*/
#define DICT_STAT_FAIL 1 /* any value > 0: notfound, conflict */
#define DICT_STAT_SUCCESS 0 /* request satisfied */
#define DICT_STAT_ERROR (-1 ) /* any value < 0: database error */
/*
* Set an error code and return a result value .
*/
#define DICT_ERR_VAL_RETURN(dict, err, val) do { \
(dict)->error = (err); \
return (val); \
} while (0 )
/*
* Sequence function types .
*/
#define DICT_SEQ_FUN_FIRST 0 /* set cursor to first record */
#define DICT_SEQ_FUN_NEXT 1 /* set cursor to next record */
/*
* Interface for dictionary types .
*/
extern ARGV *dict_mapnames(void );
typedef void (*DICT_MAPNAMES_EXTEND_FN) (ARGV *);
extern DICT_MAPNAMES_EXTEND_FN dict_mapnames_extend(DICT_MAPNAMES_EXTEND_FN);
/*
* High - level interface , with logical dictionary names .
*/
extern void dict_register(const char *, DICT *);
extern DICT *dict_handle(const char *);
extern void dict_unregister(const char *);
extern int dict_update(const char *, const char *, const char *);
extern const char *dict_lookup(const char *, const char *);
extern int dict_delete(const char *, const char *);
extern int dict_sequence(const char *, const int , const char **, const char **);
extern int dict_load_file_xt(const char *, const char *);
extern void dict_load_fp(const char *, VSTREAM *);
extern const char *dict_eval(const char *, const char *, int );
extern int dict_error(const char *);
/*
* Low - level interface , with physical dictionary handles .
*/
typedef DICT *(*DICT_OPEN_FN) (const char *, int , int );
typedef struct {
const char *type;
DICT_OPEN_FN dict_fn;
struct MKMAP *(*mkmap_fn) (const char *);
} DICT_OPEN_INFO;
typedef const DICT_OPEN_INFO *(*DICT_OPEN_EXTEND_FN) (const char *);
extern DICT *dict_open(const char *, int , int );
extern DICT *dict_open3(const char *, const char *, int , int );
extern void dict_open_register(const DICT_OPEN_INFO *);
extern void dict_open_unregister(const char *);
extern const DICT_OPEN_INFO *dict_open_lookup(const char *);
extern DICT_OPEN_EXTEND_FN dict_open_extend(DICT_OPEN_EXTEND_FN);
#define dict_get(dp, key) ((const char *) (dp)->lookup((dp), (key)))
#define dict_put(dp, key, val) (dp)->update((dp), (key), (val))
#define dict_del(dp, key) (dp)->delete ((dp), (key))
#define dict_seq(dp, f, key, val) (dp)->sequence((dp), (f), (key), (val))
#define dict_close(dp) (dp)->close(dp)
typedef void (*DICT_WALK_ACTION) (const char *, DICT *, void *);
extern void dict_walk(DICT_WALK_ACTION, void *);
extern int dict_changed(void );
extern const char *dict_changed_name(void );
extern const char *dict_flags_str(int );
extern int dict_flags_mask(const char *);
extern void dict_type_override(DICT *, const char *);
/*
* Check and convert UTF - 8 keys and values .
*/
typedef struct DICT_UTF8_BACKUP {
const char *(*lookup) (struct DICT *, const char *);
int (*update) (struct DICT *, const char *, const char *);
int (*delete ) (struct DICT *, const char *);
} DICT_UTF8_BACKUP;
extern DICT *dict_utf8_activate(DICT *);
/*
* Driver for interactive or scripted tests .
*/
void dict_test(int , char **);
/*
* Behind - the - scenes support to continue execution with reduced
* functionality .
*/
extern int dict_allow_surrogate;
extern DICT *PRINTFLIKE(5 , 6 ) dict_surrogate(const char *, const char *, int , int , const char *,...);
/*
* Support for consistent sharing and collision avoidance when tables are
* registered with dict_register ( ) . Only share instances that have the same
* type , name , open_flags , and ( initial ) dict_flags .
*/
extern char *dict_make_registered_name(VSTRING *, const char *, int , int );
extern char *dict_make_registered_name4(VSTRING *, const char *, const char *, int , int );
/*
* This name is reserved for matchlist error handling .
*/
#define DICT_TYPE_NOFILE "non-existent"
#define DICT_TYPE_NOUTF8 "non-UTF-8"
/*
* Duplicated from vstream ( 3 ) . This should probably be abstracted out .
*
* Exception handling . We use pointer to jmp_buf to avoid a lot of unused
* baggage for streams that don ' t need this functionality .
*
* XXX sigsetjmp ( ) / siglongjmp ( ) save and restore the signal mask which can
* avoid surprises in code that manipulates signals , but unfortunately some
* systems have bugs in their implementation .
*/
#ifdef NO_SIGSETJMP
#define dict_setjmp(dict) setjmp((dict)->jbuf[0 ])
#define dict_longjmp(dict, val) longjmp((dict)->jbuf[0 ], (val))
#else
#define dict_setjmp(dict) sigsetjmp((dict)->jbuf[0 ], 1 )
#define dict_longjmp(dict, val) siglongjmp((dict)->jbuf[0 ], (val))
#endif
#define dict_isjmp(dict) ((dict)->jbuf != 0 )
/*
* Temporary API . If exception handling proves to be useful ,
* dict_jmp_alloc ( ) should be integrated into dict_alloc ( ) .
*/
extern void dict_jmp_alloc(DICT *);
/*
* dict_file ( 3 ) .
*/
extern struct VSTRING *dict_file_to_buf(DICT *, const char *);
extern struct VSTRING *dict_file_to_b64(DICT *, const char *);
extern struct VSTRING *dict_file_from_b64(DICT *, const char *);
extern char *dict_file_get_error(DICT *);
extern void dict_file_purge_buffers(DICT *);
extern const char *dict_file_lookup(DICT *dict, const char *);
/*
* dict_stream ( 3 )
*/
extern VSTREAM *dict_stream_open(const char *dict_type, const char *mapname,
int open_flags, int dict_flags, struct stat * st, VSTRING **why);
/* 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
/*--*/
#endif
Messung V0.5 in Prozent C=72 H=97 G=85
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-08-09)
¤
*© Formatika GbR, Deutschland