summaryrefslogtreecommitdiff
path: root/praliases/praliases.c
diff options
context:
space:
mode:
Diffstat (limited to 'praliases/praliases.c')
-rw-r--r--praliases/praliases.c374
1 files changed, 303 insertions, 71 deletions
diff --git a/praliases/praliases.c b/praliases/praliases.c
index 361edac..3935191 100644
--- a/praliases/praliases.c
+++ b/praliases/praliases.c
@@ -1,35 +1,13 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
+ * Copyright (c) 1983 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
*/
#ifndef lint
@@ -39,14 +17,43 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)praliases.c 8.5 (Berkeley) 5/28/97";
+static char sccsid[] = "@(#)praliases.c 8.21 (Berkeley) 12/27/1998";
#endif /* not lint */
-#include <ndbm.h>
-#define NOT_SENDMAIL
+#if !defined(NDBM) && !defined(NEWDB)
+ ERROR README: You must define one of NDBM or NEWDB in order to compile
+ ERROR README: praliases.
+#endif
+
+#ifdef NDBM
+# include <ndbm.h>
+#endif
+#ifndef NOT_SENDMAIL
+# define NOT_SENDMAIL
+#endif
#include <sendmail.h>
+#include <pathnames.h>
#ifdef NEWDB
-#include <db.h>
+# include <db.h>
+# ifndef DB_VERSION_MAJOR
+# define DB_VERSION_MAJOR 1
+# endif
+#endif
+
+#if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) || \
+ defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__)
+# ifndef HASSTRERROR
+# define HASSTRERROR 1 /* has strerror(3) */
+# endif
+#endif
+
+#if !HASSTRERROR
+extern char *strerror __P((int));
+#endif
+
+static void praliases __P((char *, int, char **));
+#ifdef NDBM
+static void praliases_dbm __P((char *, int, char **));
#endif
int
@@ -56,30 +63,148 @@ main(argc, argv)
{
extern char *optarg;
extern int optind;
- DBM *dbp;
- datum content, key;
- char *filename;
- int ch;
-#ifdef NEWDB
- const DB *db;
- DBT newdbkey, newdbcontent;
- char buf[MAXNAME];
+ char *cfile;
+#if _FFR_GRAB_ALIASFILE_OPTION
+ char *filename = NULL;
+#else
+ char *filename = "/etc/aliases";
#endif
+ FILE *cfp;
+ int ch;
+ char afilebuf[MAXLINE];
+ char buf[MAXLINE];
- filename = "/etc/aliases";
+ cfile = _PATH_SENDMAILCF;
+#if _FFR_GRAB_ALIASFILE_OPTION
+ while ((ch = getopt(argc, argv, "C:f:")) != EOF)
+#else
while ((ch = getopt(argc, argv, "f:")) != EOF)
- switch((char)ch) {
+#endif
+ {
+ switch ((char)ch) {
+ case 'C':
+ cfile = optarg;
+ break;
case 'f':
filename = optarg;
break;
case '?':
default:
- (void)fprintf(stderr, "usage: praliases [-f file]\n");
+ (void)fprintf(stderr,
+#if _FFR_GRAB_ALIASFILE_OPTION
+ "usage: praliases [-C cffile] [-f aliasfile]\n");
+#else
+ "usage: praliases [-f aliasfile]\n");
+#endif
exit(EX_USAGE);
}
+ }
argc -= optind;
argv += optind;
+ if (filename != NULL)
+ {
+ praliases(filename, argc, argv);
+ exit(EX_OK);
+ }
+
+ if ((cfp = fopen(cfile, "r")) == NULL)
+ {
+ fprintf(stderr, "praliases: ");
+ perror(cfile);
+ exit(EX_NOINPUT);
+ }
+
+ while (fgets(buf, sizeof(buf), cfp) != NULL)
+ {
+ register char *b, *p;
+
+ b = buf;
+ switch (*b++)
+ {
+ case 'O': /* option -- see if alias file */
+ if (strncasecmp(b, " AliasFile", 10) == 0 &&
+ !(isascii(b[10]) && isalnum(b[10])))
+ {
+ /* new form -- find value */
+ b = strchr(b, '=');
+ if (b == NULL)
+ continue;
+ while (isascii(*++b) && isspace(*b))
+ continue;
+ }
+ else if (*b++ != 'A')
+ {
+ /* something else boring */
+ continue;
+ }
+
+ /* this is the A or AliasFile option -- save it */
+ if (strlen(b) >= sizeof afilebuf)
+ {
+ fprintf(stderr,
+ "AliasFile filename too long: %.30s...\n",
+ b);
+ (void) fclose(cfp);
+ exit(EX_CONFIG);
+ }
+ strcpy(afilebuf, b);
+ b = afilebuf;
+
+ for (p = b; p != NULL; )
+ {
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ b = p;
+
+ p = strpbrk(p, " ,/");
+ /* find end of spec */
+ if (p != NULL)
+ p = strpbrk(p, ",\n");
+ if (p != NULL)
+ *p++ = '\0';
+
+ praliases(b, argc, argv);
+ }
+
+ default:
+ continue;
+ }
+ }
+ (void) fclose(cfp);
+ exit(EX_OK);
+}
+
+static void
+praliases(filename, argc, argv)
+ char *filename;
+ int argc;
+ char **argv;
+{
+#ifdef NEWDB
+ DB *db;
+ DBT newdbkey, newdbcontent;
+ char buf[MAXNAME];
+#endif
+ char *class;
+
+ class = strchr(filename, ':');
+ if (class != NULL)
+ {
+ if (strncasecmp(filename, "dbm:", 4) == 0)
+ {
+#ifdef NDBM
+ praliases_dbm(class + 1, argc, argv);
+ return;
+#else
+ fprintf(stderr, "class dbm not available\n");
+ exit(EX_DATAERR);
+#endif
+ }
+ filename = class + 1;
+ }
#ifdef NEWDB
if (strlen(filename) + 4 >= sizeof buf)
{
@@ -88,51 +213,158 @@ main(argc, argv)
}
(void) strcpy(buf, filename);
(void) strcat(buf, ".db");
- if (db = dbopen(buf, O_RDONLY, 0444 , DB_HASH, NULL)) {
- if (!argc) {
+# if DB_VERSION_MAJOR < 2
+ db = dbopen(buf, O_RDONLY, 0444, DB_HASH, NULL);
+# else
+ db = NULL;
+ errno = db_open(buf, DB_HASH, DB_RDONLY, 0444, NULL, NULL, &db);
+# endif
+ if (db != NULL)
+ {
+ if (!argc)
+ {
+# if DB_VERSION_MAJOR > 1
+ DBC *dbc;
+# endif
+ bzero(&newdbkey, sizeof newdbkey);
+ bzero(&newdbcontent, sizeof newdbcontent);
+
+# if DB_VERSION_MAJOR < 2
while(!db->seq(db, &newdbkey, &newdbcontent, R_NEXT))
+# else
+# if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >=6
+ if ((errno = db->cursor(db, NULL, &dbc, 0)) == 0)
+# else
+ if ((errno = db->cursor(db, NULL, &dbc)) == 0)
+# endif
+ {
+ while ((errno = dbc->c_get(dbc, &newdbkey,
+ &newdbcontent,
+ DB_NEXT)) == 0)
+# endif
printf("%.*s:%.*s\n",
- newdbkey.size, newdbkey.data,
- newdbcontent.size, newdbcontent.data);
+ (int) newdbkey.size,
+ (char *) newdbkey.data,
+ (int) newdbcontent.size,
+ (char *) newdbcontent.data);
+# if DB_VERSION_MAJOR > 1
+ (void) dbc->c_close(dbc);
+ }
+ else
+ {
+ fprintf(stderr,
+ "praliases: %s: Could not set cursor: %s\n",
+ buf, strerror(errno));
+ errno = db->close(db, 0);
+ exit(EX_DATAERR);
+ }
+# endif
}
- else for (; *argv; ++argv) {
+ else for (; *argv; ++argv)
+ {
+ bzero(&newdbkey, sizeof newdbkey);
+ bzero(&newdbcontent, sizeof newdbcontent);
newdbkey.data = *argv;
newdbkey.size = strlen(*argv) + 1;
+# if DB_VERSION_MAJOR < 2
if (!db->get(db, &newdbkey, &newdbcontent, 0))
- printf("%s:%.*s\n", newdbkey.data,
- newdbcontent.size, newdbcontent.data);
+# else
+ if ((errno = db->get(db, NULL, &newdbkey,
+ &newdbcontent, 0)) == 0)
+# endif
+ printf("%s:%.*s\n", (char *) newdbkey.data,
+ (int) newdbcontent.size,
+ (char *) newdbcontent.data);
else
printf("%s: No such key\n",
- newdbkey.data);
+ (char *) newdbkey.data);
}
+# if DB_VERSION_MAJOR < 2
+ (void)db->close(db);
+# else
+ errno = db->close(db, 0);
+# endif
}
- else {
+ else
+ {
#endif
- if ((dbp = dbm_open(filename, O_RDONLY, 0)) == NULL) {
- (void)fprintf(stderr,
- "praliases: %s: %s\n", filename, strerror(errno));
- exit(EX_OSFILE);
+#ifdef NDBM
+ praliases_dbm(filename, argc, argv);
+#endif
+#ifdef NEWDB
+ }
+#endif
+}
+
+#ifdef NDBM
+static void
+praliases_dbm(filename, argc, argv)
+ char *filename;
+ int argc;
+ char **argv;
+{
+ DBM *dbp;
+ datum content, key;
+
+ if ((dbp = dbm_open(filename, O_RDONLY, 0)) == NULL)
+ {
+ (void)fprintf(stderr,
+ "praliases: %s: %s\n", filename, strerror(errno));
+ exit(EX_OSFILE);
+ }
+ if (!argc)
+ {
+ for (key = dbm_firstkey(dbp);
+ key.dptr != NULL; key = dbm_nextkey(dbp))
+ {
+ content = dbm_fetch(dbp, key);
+ (void)printf("%.*s:%.*s\n",
+ (int) key.dsize, key.dptr,
+ (int) content.dsize, content.dptr);
}
- if (!argc)
- for (key = dbm_firstkey(dbp);
- key.dptr != NULL; key = dbm_nextkey(dbp)) {
- content = dbm_fetch(dbp, key);
- (void)printf("%.*s:%.*s\n",
- key.dsize, key.dptr,
- content.dsize, content.dptr);
- }
- else for (; *argv; ++argv) {
+ }
+ else
+ {
+ for (; *argv; ++argv)
+ {
+ /*
+ ** Use the sendmail adaptive algorithm of trying
+ ** the key first without, then if needed with,
+ ** the terminating NULL byte.
+ */
key.dptr = *argv;
- key.dsize = strlen(*argv) + 1;
+ key.dsize = strlen(*argv);
content = dbm_fetch(dbp, key);
- if (!content.dptr)
- (void)printf("%s: No such key\n", key.dptr);
- else
+ if (content.dptr == NULL)
+ {
+ key.dsize++;
+ content = dbm_fetch(dbp, key);
+ }
+ if (content.dptr != NULL)
(void)printf("%s:%.*s\n", key.dptr,
- content.dsize, content.dptr);
+ (int) content.dsize, content.dptr);
+ else
+ (void)printf("%s: No such key\n", key.dptr);
}
-#ifdef NEWDB
}
+ dbm_close(dbp);
+}
#endif
- exit(EX_OK);
+
+#if !HASSTRERROR
+
+char *
+strerror(eno)
+ int eno;
+{
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+ static char ebuf[60];
+
+ if (eno >= 0 && eno < sys_nerr)
+ return sys_errlist[eno];
+ (void) sprintf(ebuf, "Error %d", eno);
+ return ebuf;
}
+
+#endif /* !HASSTRERROR */