summaryrefslogtreecommitdiff
path: root/gnu/dist/postfix/src/postalias
diff options
context:
space:
mode:
authorperry <perry@NetBSD.org>2002-02-02 23:10:24 +0000
committerperry <perry@NetBSD.org>2002-02-02 23:10:24 +0000
commit6f59dc7aebbf705da79e61ef3fd24b48ed99d327 (patch)
treec6e9fd356c8aac78b966a9dd53f5d0d14d5e62cd /gnu/dist/postfix/src/postalias
parentecf43984517b4cfb837e78958769cc8207ea5288 (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.in31
-rw-r--r--gnu/dist/postfix/src/postalias/map-ABC1.ref1
-rw-r--r--gnu/dist/postfix/src/postalias/map-ABC2.ref1
-rw-r--r--gnu/dist/postfix/src/postalias/map-abc1.ref1
-rw-r--r--gnu/dist/postfix/src/postalias/map-abc2.ref1
-rw-r--r--gnu/dist/postfix/src/postalias/map-ghi1.ref1
-rw-r--r--gnu/dist/postfix/src/postalias/map-ghi2.ref1
-rw-r--r--gnu/dist/postfix/src/postalias/map.in2
-rw-r--r--gnu/dist/postfix/src/postalias/postalias.c168
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);