/*++ /* NAME /* dict 3 /* SUMMARY /* dictionary manager /* SYNOPSIS /* #include <dict.h> /* /* void dict_register(dict_name, dict_info) /* const char *dict_name; /* DICT *dict_info; /* /* DICT *dict_handle(dict_name) /* const char *dict_name; /* /* void dict_unregister(dict_name) /* const char *dict_name; /* /* int dict_update(dict_name, member, value) /* const char *dict_name; /* const char *member; /* const char *value; /* /* const char *dict_lookup(dict_name, member) /* const char *dict_name; /* const char *member; /* /* int dict_delete(dict_name, member) /* const char *dict_name; /* const char *member; /* /* int dict_sequence(dict_name, func, member, value) /* const char *dict_name; /* int func; /* const char **member; /* const char **value; /* /* const char *dict_eval(dict_name, string, int recursive) /* const char *dict_name; /* const char *string; /* int recursive; /* /* int dict_walk(action, context) /* void (*action)(dict_name, dict_handle, context) /* void *context; /* /* int dict_error(dict_name) /* const char *dict_name; /* /* const char *dict_changed_name() /* /* void DICT_OWNER_AGGREGATE_INIT(aggregate) /* DICT_OWNER aggregate; /* /* void DICT_OWNER_AGGREGATE_UPDATE(aggregate, source) /* DICT_OWNER aggregate; /* DICT_OWNER source; /* AUXILIARY FUNCTIONS /* int dict_load_file_xt(dict_name, path) /* const char *dict_name; /* const char *path; /* /* void dict_load_fp(dict_name, fp) /* const char *dict_name; /* VSTREAM *fp; /* /* const char *dict_flags_str(dict_flags) /* int dict_flags; /* /* int dict_flags_mask(names) /* const char *names; /* /* char *dict_make_registered_name( /* VSTRING *out, /* const char *type_name, /* int open_flags, /* int dict_flags) /* /* char *dict_make_registered_name4( /* VSTRING *out, /* const char *type, /* const char *name, /* int open_flags, /* int dict_flags) /* DESCRIPTION /* This module maintains a collection of name-value dictionaries. /* Each dictionary has its own name and has its own methods to read /* or update members. Examples of dictionaries that can be accessed /* in this manner are the global UNIX-style process environment, /* hash tables, NIS maps, DBM files, and so on. Dictionary values /* are not limited to strings but can be arbitrary objects as long /* as they can be represented by character pointers. /* FEATURES /* .fi /* .ad /* Notable features of this module are: /* .IP "macro expansion (string-valued dictionaries only)" /* Macros of the form $\fIname\fR can be expanded to the current /* value of \fIname\fR. The forms $(\fIname\fR) and ${\fIname\fR} are /* also supported. /* .IP "unknown names" /* An update request for an unknown dictionary name will trigger /* the instantiation of an in-memory dictionary with that name. /* A lookup request (including delete and sequence) for an /* unknown dictionary will result in a "not found" and "no /* error" result. /* .PP /* dict_register() adds a new dictionary, including access methods, /* to the list of known dictionaries, or increments the reference /* count for an existing (name, dictionary) pair. Otherwise, it is /* an error to pass an existing name (this would cause a memory leak). /* /* dict_handle() returns the generic dictionary handle of the /* named dictionary, or a null pointer when the named dictionary /* is not found. /* /* dict_unregister() decrements the reference count of the named /* dictionary. When the reference count reaches zero, dict_unregister() /* breaks the (name, dictionary) association and executes the /* dictionary's optional \fIremove\fR method. /* /* dict_update() updates the value of the named dictionary member. /* The dictionary member and the named dictionary are instantiated /* on the fly. The result value is zero (DICT_STAT_SUCCESS) /* when the update was made. /* /* dict_lookup() returns the value of the named member (i.e. without /* expanding macros in the member value). The \fIdict_name\fR argument /* specifies the dictionary to search. The result is a null pointer /* when no value is found, otherwise the result is owned by the /* underlying dictionary method. Make a copy if the result is to be /* modified, or if the result is to survive multiple dict_lookup() calls. /* /* dict_delete() removes the named member from the named dictionary. /* The result value is zero (DICT_STAT_SUCCESS) when the member /* was found. /* /* dict_sequence() steps through the named dictionary and returns /* keys and values in some implementation-defined order. The func /* argument is DICT_SEQ_FUN_FIRST to set the cursor to the first /* entry or DICT_SEQ_FUN_NEXT to select the next entry. The result /* is owned by the underlying dictionary method. Make a copy if the /* result is to be modified, or if the result is to survive multiple /* dict_sequence() calls. The result value is zero (DICT_STAT_SUCCESS) /* when a member was found. /* /* dict_eval() expands macro references in the specified string. /* The result is owned by the dictionary manager. Make a copy if the /* result is to survive multiple dict_eval() calls. When the /* \fIrecursive\fR argument is non-zero, macro references in macro /* lookup results are expanded recursively. /* /* dict_walk() iterates over all registered dictionaries in some /* arbitrary order, and invokes the specified action routine with /* as arguments: /* .IP "const char *dict_name" /* Dictionary name. /* .IP "DICT *dict_handle" /* Generic dictionary handle. /* .IP "char *context" /* Application context from the caller. /* .PP /* dict_changed_name() returns non-zero when any dictionary is /* opened read-only and has changed, or because it was unlinked. /* A non-zero result is the name of a changed dictionary. /* /* dict_load_file_xt() reads name-value entries from the named file. /* Lines that begin with whitespace are concatenated to the preceding /* line (the newline is deleted). /* Each entry is stored in the dictionary named by \fIdict_name\fR. /* The result is zero if the file could not be opened. /* /* dict_load_fp() reads name-value entries from an open stream. /* It has the same semantics as the dict_load_file_xt() function. /* /* dict_flags_str() returns a printable representation of the /* specified dictionary flags. The result is overwritten upon /* each call. /* /* dict_flags_mask() returns the bitmask for the specified /* comma/space-separated dictionary flag names. /* /* dict_make_registered_name*() format a dictionary type, name, /* and (initial) flag values for use in dict_register() calls. /* This encourages consistent sharing of dictionary instances that /* have the exact same type:name and (initial) flags. The result /* value is the string value of the \fIout\fR VSTRING buffer. /* TRUST AND PROVENANCE /* .ad /* .fi /* Each dictionary has an owner attribute that contains (status, /* uid) information about the owner of a dictionary. The /* status is one of the following: /* .IP DICT_OWNER_TRUSTED /* The dictionary is owned by a trusted user. The uid is zero, /* and specifies a UNIX user ID. /* .IP DICT_OWNER_UNTRUSTED /* The dictionary is owned by an untrusted user. The uid is /* non-zero, and specifies a UNIX user ID. /* .IP DICT_OWNER_UNKNOWN /* The dictionary is owned by an unspecified user. For example, /* the origin is unauthenticated, or different parts of a /* dictionary aggregate (see below) are owned by different /* untrusted users. The uid is non-zero and does not specify /* a UNIX user ID. /* .PP /* Note that dictionary ownership does not necessarily imply /* ownership of lookup results. For example, a PCRE table may /* be owned by the trusted root user, but the result of $number /* expansion can contain data from an arbitrary remote SMTP /* client. See dict_open(3) for how to disallow $number /* expansions with security-sensitive operations. /* /* Two macros are available to help determine the provenance /* and trustworthiness of a dictionary aggregate. The macros /* are unsafe because they may evaluate arguments more than /* once. /* /* DICT_OWNER_AGGREGATE_INIT() initialize aggregate owner /* attributes to the highest trust level. /* /* DICT_OWNER_AGGREGATE_UPDATE() updates the aggregate owner /* attributes with the attributes of the specified source, and /* reduces the aggregate trust level as appropriate. /* SEE ALSO /* htable(3) /* BUGS /* DIAGNOSTICS /* Fatal errors: out of memory, malformed macro name. /* /* The lookup routine returns non-null when the request is /* satisfied. The update, delete and sequence routines return /* zero (DICT_STAT_SUCCESS) when the request is satisfied. /* The dict_error() function returns non-zero only when the /* last operation was not satisfied due to a dictionary access /* error. The result can have the following values: /* .IP DICT_ERR_NONE(zero) /* There was no dictionary access error. For example, the /* request was satisfied, the requested information did not /* exist in the dictionary, or the information already existed /* when it should not exist (collision). /* .IP DICT_ERR_RETRY(<0) /* The dictionary was temporarily unavailable. This can happen /* with network-based services. /* .IP DICT_ERR_CONFIG(<0) /* The dictionary was unavailable due to a configuration error. /* .PP /* Generally, a program is expected to test the function result /* value for "success" first. If the operation was not successful, /* a program is expected to test for a non-zero dict->error /* status to distinguish between a data notfound/collision /* condition or a dictionary access error. /* 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
/*--*/
/* *Enforcereferentialintegrity.
*/ if (dict_info->reg_name && strcmp(dict_name, dict_info->reg_name) != 0)
msg_panic("%s: '%s:%s' is already registered under '%s' and cannot " "also be registered under '%s'", myname, dict_info->type,
dict_info->name, dict_info->reg_name, dict_name);
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.