diff options
| author | perry <perry@NetBSD.org> | 2002-02-02 23:10:24 +0000 |
|---|---|---|
| committer | perry <perry@NetBSD.org> | 2002-02-02 23:10:24 +0000 |
| commit | 6f59dc7aebbf705da79e61ef3fd24b48ed99d327 (patch) | |
| tree | c6e9fd356c8aac78b966a9dd53f5d0d14d5e62cd /gnu/dist/postfix/src/postalias | |
| parent | ecf43984517b4cfb837e78958769cc8207ea5288 (diff) | |
Postfix 1.1.2
(Postfix releases are now numbered -- 1.1.2 means 1.1, patchlevel 2.)
Lots of new features, same great security.
Diffstat (limited to 'gnu/dist/postfix/src/postalias')
| -rw-r--r-- | gnu/dist/postfix/src/postalias/Makefile.in | 31 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/map-ABC1.ref | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/map-ABC2.ref | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/map-abc1.ref | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/map-abc2.ref | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/map-ghi1.ref | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/map-ghi2.ref | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/map.in | 2 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/postalias/postalias.c | 168 |
9 files changed, 173 insertions, 34 deletions
diff --git a/gnu/dist/postfix/src/postalias/Makefile.in b/gnu/dist/postfix/src/postalias/Makefile.in index 1fbc2a67d54..b18759656dd 100644 --- a/gnu/dist/postfix/src/postalias/Makefile.in +++ b/gnu/dist/postfix/src/postalias/Makefile.in @@ -21,10 +21,36 @@ $(PROG): $(OBJS) $(LIBS) Makefile: Makefile.in (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@ -test: $(TESTPROG) - update: ../../bin/$(PROG) +test: test1 test2 + +test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-ABC1.ref + ./$(PROG) map.in + for key in abc ghi; \ + do \ + ./$(PROG) -q $${key} map.in | diff map-$${key}1.ref -; \ + done + ./$(PROG) -f map.in + for key in ABC; \ + do \ + ./$(PROG) -fq $${key} map.in | diff map-$${key}1.ref -; \ + done + rm -f map.in.db + +test2: $(PROG) map.in map-abc2.ref map-ghi2.ref map-ABC2.ref + ./$(PROG) map.in + for key in abc ghi; \ + do \ + echo $${key} | ./$(PROG) -q - map.in | diff map-$${key}2.ref -; \ + done + ./$(PROG) -f map.in + for key in ABC; \ + do \ + echo $${key} | ./$(PROG) -fq - map.in | diff map-$${key}2.ref -; \ + done + rm -f map.in.db + ../../bin/$(PROG): $(PROG) cp $(PROG) ../../bin @@ -65,6 +91,7 @@ postalias.o: ../../include/readlline.h postalias.o: ../../include/stringops.h postalias.o: ../../include/split_at.h postalias.o: ../../include/get_hostname.h +postalias.o: ../../include/vstring_vstream.h postalias.o: ../../include/tok822.h postalias.o: ../../include/resolve_clnt.h postalias.o: ../../include/mail_conf.h diff --git a/gnu/dist/postfix/src/postalias/map-ABC1.ref b/gnu/dist/postfix/src/postalias/map-ABC1.ref new file mode 100644 index 00000000000..142195f36ae --- /dev/null +++ b/gnu/dist/postfix/src/postalias/map-ABC1.ref @@ -0,0 +1 @@ +DEF diff --git a/gnu/dist/postfix/src/postalias/map-ABC2.ref b/gnu/dist/postfix/src/postalias/map-ABC2.ref new file mode 100644 index 00000000000..929916bcb4d --- /dev/null +++ b/gnu/dist/postfix/src/postalias/map-ABC2.ref @@ -0,0 +1 @@ +ABC: DEF diff --git a/gnu/dist/postfix/src/postalias/map-abc1.ref b/gnu/dist/postfix/src/postalias/map-abc1.ref new file mode 100644 index 00000000000..142195f36ae --- /dev/null +++ b/gnu/dist/postfix/src/postalias/map-abc1.ref @@ -0,0 +1 @@ +DEF diff --git a/gnu/dist/postfix/src/postalias/map-abc2.ref b/gnu/dist/postfix/src/postalias/map-abc2.ref new file mode 100644 index 00000000000..dfbdab6f18e --- /dev/null +++ b/gnu/dist/postfix/src/postalias/map-abc2.ref @@ -0,0 +1 @@ +abc: DEF diff --git a/gnu/dist/postfix/src/postalias/map-ghi1.ref b/gnu/dist/postfix/src/postalias/map-ghi1.ref new file mode 100644 index 00000000000..7beb1db20dc --- /dev/null +++ b/gnu/dist/postfix/src/postalias/map-ghi1.ref @@ -0,0 +1 @@ +jkl diff --git a/gnu/dist/postfix/src/postalias/map-ghi2.ref b/gnu/dist/postfix/src/postalias/map-ghi2.ref new file mode 100644 index 00000000000..e2ca310ca9d --- /dev/null +++ b/gnu/dist/postfix/src/postalias/map-ghi2.ref @@ -0,0 +1 @@ +ghi: jkl diff --git a/gnu/dist/postfix/src/postalias/map.in b/gnu/dist/postfix/src/postalias/map.in new file mode 100644 index 00000000000..203fa0cd34a --- /dev/null +++ b/gnu/dist/postfix/src/postalias/map.in @@ -0,0 +1,2 @@ +ABC: DEF +ghi: jkl diff --git a/gnu/dist/postfix/src/postalias/postalias.c b/gnu/dist/postfix/src/postalias/postalias.c index 0fe46f910f5..6daf0fff6d4 100644 --- a/gnu/dist/postfix/src/postalias/postalias.c +++ b/gnu/dist/postfix/src/postalias/postalias.c @@ -5,7 +5,7 @@ /* Postfix alias database maintenance /* SYNOPSIS /* .fi -/* \fBpostalias\fR [\fB-Ninrvw\fR] [\fB-c \fIconfig_dir\fR] +/* \fBpostalias\fR [\fB-Nfinrvw\fR] [\fB-c \fIconfig_dir\fR] /* [\fB-d \fIkey\fR] [\fB-q \fIkey\fR] /* [\fIfile_type\fR:]\fIfile_name\fR ... /* DESCRIPTION @@ -29,7 +29,14 @@ /* instead of the default configuration directory. /* .IP "\fB-d \fIkey\fR" /* Search the specified maps for \fIkey\fR and remove one entry per map. -/* The exit status is non-zero if the requested information was not found. +/* The exit status is zero when the requested information was found. +/* +/* If a key value of \fB-\fR is specified, the program reads key +/* values from the standard input stream. The exit status is zero +/* when at least one of the requested keys was found. +/* .IP \fB-f\fR +/* Do not fold the lookup key to lower case while creating or querying +/* a map. /* .IP \fB-i\fR /* Incremental mode. Read entries from standard input and do not /* truncate an existing database. By default, \fBpostalias\fR creates @@ -40,8 +47,13 @@ /* the host operating system. /* .IP "\fB-q \fIkey\fR" /* Search the specified maps for \fIkey\fR and print the first value -/* found on the standard output stream. The exit status is non-zero -/* if the requested information was not found. +/* found on the standard output stream. The exit status is zero +/* when the requested information was found. +/* +/* If a key value of \fB-\fR is specified, the program reads key +/* values from the standard input stream and prints one line of +/* \fIkey: value\fR output for each key that was found. The exit +/* status is zero when at least one of the requested keys was found. /* .IP \fB-r\fR /* When updating a table, do not warn about duplicate entries; silently /* replace them. @@ -81,9 +93,6 @@ /* \fBpostalias\fR terminates with zero exit status in case of success /* (including successful \fBpostmap -q\fR lookup) and terminates /* with non-zero exit status in case of failure. -/* BUGS -/* The "delete key" support is limited to one delete operation -/* per command invocation. /* ENVIRONMENT /* .ad /* .fi @@ -137,6 +146,7 @@ #include <stringops.h> #include <split_at.h> #include <get_hostname.h> +#include <vstring_vstream.h> /* Global library. */ @@ -188,23 +198,7 @@ static void postalias(char *map_type, char *path_name, * Add records to the database. */ lineno = 0; - while (readlline(line_buffer, source_fp, &lineno, READLL_STRIPNL)) { - - /* - * Skip comments. - */ - if (*STR(line_buffer) == '#') - continue; - - /* - * Weird stuff. Normally, a line that begins with whitespace is a - * continuation of the previous line. - */ - if (ISSPACE(*STR(line_buffer))) { - msg_warn("%s, line %d: malformed line", - VSTREAM_PATH(source_fp), lineno); - continue; - } + while (readlline(line_buffer, source_fp, &lineno)) { /* * Tokenize the input, so that we do the right thing when a quoted @@ -263,7 +257,8 @@ static void postalias(char *map_type, char *path_name, /* * Store the value under a case-insensitive key. */ - lowercase(STR(key_buffer)); + if (dict_flags & DICT_FLAG_FOLD_KEY) + lowercase(STR(key_buffer)); mkmap_append(mkmap, STR(key_buffer), STR(value_buffer)); } @@ -306,6 +301,65 @@ static void postalias(char *map_type, char *path_name, vstream_fclose(source_fp); } +/* postalias_queries - apply multiple requests from stdin */ + +static int postalias_queries(VSTREAM *in, char **maps, const int map_count, + const int dict_flags) +{ + int found = 0; + VSTRING *keybuf = vstring_alloc(100); + DICT **dicts; + const char *map_name; + const char *value; + int n; + + /* + * Sanity check. + */ + if (map_count <= 0) + msg_panic("postalias_queries: bad map count"); + + /* + * Prepare to open maps lazily. + */ + dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count); + for (n = 0; n < map_count; n++) + dicts[n] = 0; + + /* + * Perform all queries. Open maps on the fly, to avoid opening unecessary + * maps. + */ + while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) { + if (dict_flags & DICT_FLAG_FOLD_KEY) + lowercase(STR(keybuf)); + for (n = 0; n < map_count; n++) { + if (dicts[n] == 0) + dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ? + dict_open3(maps[n], map_name, O_RDONLY, DICT_FLAG_LOCK) : + dict_open3(var_db_type, maps[n], O_RDONLY, DICT_FLAG_LOCK)); + if ((value = dict_get(dicts[n], STR(keybuf))) != 0) { + vstream_printf("%s: %s\n", STR(keybuf), value); + found = 1; + break; + } + } + } + if (found) + vstream_fflush(VSTREAM_OUT); + + /* + * Cleanup. + */ + for (n = 0; n < map_count; n++) + if (dicts[n]) + dict_close(dicts[n]); + myfree((char *) dicts); + vstring_free(keybuf); + + return (found); +} + /* postalias_query - query a map and print the result to stdout */ static int postalias_query(const char *map_type, const char *map_name, @@ -323,6 +377,50 @@ static int postalias_query(const char *map_type, const char *map_name, return (value != 0); } +/* postalias_deletes - apply multiple requests from stdin */ + +static int postalias_deletes(VSTREAM *in, char **maps, const int map_count) +{ + int found = 0; + VSTRING *keybuf = vstring_alloc(100); + DICT **dicts; + const char *map_name; + int n; + + /* + * Sanity check. + */ + if (map_count <= 0) + msg_panic("postalias_deletes: bad map count"); + + /* + * Open maps ahead of time. + */ + dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count); + for (n = 0; n < map_count; n++) + dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ? + dict_open3(maps[n], map_name, O_RDWR, DICT_FLAG_LOCK) : + dict_open3(var_db_type, maps[n], O_RDWR, DICT_FLAG_LOCK)); + + /* + * Perform all requests. + */ + while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) + for (n = 0; n < map_count; n++) + found |= (dict_del(dicts[n], STR(keybuf)) == 0); + + /* + * Cleanup. + */ + for (n = 0; n < map_count; n++) + if (dicts[n]) + dict_close(dicts[n]); + myfree((char *) dicts); + vstring_free(keybuf); + + return (found); +} + /* postalias_delete - delete a key value pair from a map */ static int postalias_delete(const char *map_type, const char *map_name, @@ -331,10 +429,6 @@ static int postalias_delete(const char *map_type, const char *map_name, DICT *dict; int status; - /* - * XXX This must be generalized to multi-key (read from stdin) and - * multi-map (given on command line) updates. - */ dict = dict_open3(map_type, map_name, O_RDWR, DICT_FLAG_LOCK); status = dict_del(dict, key); dict_close(dict); @@ -345,7 +439,7 @@ static int postalias_delete(const char *map_type, const char *map_name, static NORETURN usage(char *myname) { - msg_fatal("usage: %s [-Ninrvw] [-c config_dir] [-d key] [-q key] [map_type:]file...", + msg_fatal("usage: %s [-Nfinrvw] [-c config_dir] [-d key] [-q key] [map_type:]file...", myname); } @@ -357,7 +451,7 @@ int main(int argc, char **argv) char *slash; struct stat st; int open_flags = O_RDWR | O_CREAT | O_TRUNC; - int dict_flags = DICT_FLAG_DUP_WARN; + int dict_flags = DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_KEY; char *query = 0; char *delkey = 0; int found; @@ -395,7 +489,7 @@ int main(int argc, char **argv) /* * Parse JCL. */ - while ((ch = GETOPT(argc, argv, "Nc:d:inq:rvw")) > 0) { + while ((ch = GETOPT(argc, argv, "Nc:d:finq:rvw")) > 0) { switch (ch) { default: usage(argv[0]); @@ -413,6 +507,9 @@ int main(int argc, char **argv) msg_fatal("specify only one of -q or -d"); delkey = optarg; break; + case 'f': + dict_flags &= ~DICT_FLAG_FOLD_KEY; + break; case 'i': open_flags &= ~O_TRUNC; break; @@ -447,6 +544,8 @@ int main(int argc, char **argv) if (delkey) { /* remove entry */ if (optind + 1 > argc) usage(argv[0]); + if (strcmp(delkey, "-") == 0) + exit(postalias_deletes(VSTREAM_IN, argv + optind, argc - optind) == 0); found = 0; while (optind < argc) { if ((path_name = split_at(argv[optind], ':')) != 0) { @@ -460,6 +559,11 @@ int main(int argc, char **argv) } else if (query) { /* query map(s) */ if (optind + 1 > argc) usage(argv[0]); + if (strcmp(query, "-") == 0) + exit(postalias_queries(VSTREAM_IN, argv + optind, argc - optind, + dict_flags) == 0); + if (dict_flags & DICT_FLAG_FOLD_KEY) + lowercase(query); while (optind < argc) { if ((path_name = split_at(argv[optind], ':')) != 0) { found = postalias_query(argv[optind], path_name, query); |
