source: trunk/third/sendmail/praliases/praliases.c @ 12554

Revision 12554, 7.3 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12553, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 1998 Sendmail, Inc.  All rights reserved.
3 * Copyright (c) 1983 Eric P. Allman.  All rights reserved.
4 * Copyright (c) 1988, 1993
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * By using this file, you agree to the terms and conditions set
8 * forth in the LICENSE file which can be found at the top level of
9 * the sendmail distribution.
10 *
11 */
12
13#ifndef lint
14static char copyright[] =
15"@(#) Copyright (c) 1988, 1993\n\
16        The Regents of the University of California.  All rights reserved.\n";
17#endif /* not lint */
18
19#ifndef lint
20static char sccsid[] = "@(#)praliases.c 8.21 (Berkeley) 12/27/1998";
21#endif /* not lint */
22
23#if !defined(NDBM) && !defined(NEWDB)
24  ERROR README: You must define one of NDBM or NEWDB in order to compile
25  ERROR README: praliases.
26#endif
27
28#ifdef NDBM
29# include <ndbm.h>
30#endif
31#ifndef NOT_SENDMAIL
32# define NOT_SENDMAIL
33#endif
34#include <sendmail.h>
35#include <pathnames.h>
36#ifdef NEWDB
37# include <db.h>
38# ifndef DB_VERSION_MAJOR
39#  define DB_VERSION_MAJOR 1
40# endif
41#endif
42
43#if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) || \
44    defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__)
45# ifndef HASSTRERROR
46#  define HASSTRERROR   1       /* has strerror(3) */
47# endif
48#endif
49
50#if !HASSTRERROR
51extern char     *strerror __P((int));
52#endif
53
54static void praliases __P((char *, int, char **));
55#ifdef NDBM
56static void praliases_dbm __P((char *, int, char **));
57#endif
58
59int
60main(argc, argv)
61        int argc;
62        char **argv;
63{
64        extern char *optarg;
65        extern int optind;
66        char *cfile;
67#if _FFR_GRAB_ALIASFILE_OPTION
68        char *filename = NULL;
69#else
70        char *filename = "/etc/aliases";
71#endif
72        FILE *cfp;
73        int ch;
74        char afilebuf[MAXLINE];
75        char buf[MAXLINE];
76
77        cfile = _PATH_SENDMAILCF;
78#if _FFR_GRAB_ALIASFILE_OPTION
79        while ((ch = getopt(argc, argv, "C:f:")) != EOF)
80#else
81        while ((ch = getopt(argc, argv, "f:")) != EOF)
82#endif
83        {
84                switch ((char)ch) {
85                case 'C':
86                        cfile = optarg;
87                        break;
88                case 'f':
89                        filename = optarg;
90                        break;
91                case '?':
92                default:
93                        (void)fprintf(stderr,
94#if _FFR_GRAB_ALIASFILE_OPTION
95                                "usage: praliases [-C cffile] [-f aliasfile]\n");
96#else
97                                "usage: praliases [-f aliasfile]\n");
98#endif
99                        exit(EX_USAGE);
100                }
101        }
102        argc -= optind;
103        argv += optind;
104
105        if (filename != NULL)
106        {
107                praliases(filename, argc, argv);
108                exit(EX_OK);
109        }
110
111        if ((cfp = fopen(cfile, "r")) == NULL)
112        {
113                fprintf(stderr, "praliases: ");
114                perror(cfile);
115                exit(EX_NOINPUT);
116        }
117
118        while (fgets(buf, sizeof(buf), cfp) != NULL)
119        {
120                register char *b, *p;
121
122                b = buf;
123                switch (*b++)
124                {
125                  case 'O':             /* option -- see if alias file */
126                        if (strncasecmp(b, " AliasFile", 10) == 0 &&
127                            !(isascii(b[10]) && isalnum(b[10])))
128                        {
129                                /* new form -- find value */
130                                b = strchr(b, '=');
131                                if (b == NULL)
132                                        continue;
133                                while (isascii(*++b) && isspace(*b))
134                                        continue;
135                        }
136                        else if (*b++ != 'A')
137                        {
138                                /* something else boring */
139                                continue;
140                        }
141
142                        /* this is the A or AliasFile option -- save it */
143                        if (strlen(b) >= sizeof afilebuf)
144                        {
145                                fprintf(stderr,
146                                        "AliasFile filename too long: %.30s...\n",
147                                        b);
148                                (void) fclose(cfp);
149                                exit(EX_CONFIG);
150                        }
151                        strcpy(afilebuf, b);
152                        b = afilebuf;
153
154                        for (p = b; p != NULL; )
155                        {
156                                while (isascii(*p) && isspace(*p))
157                                        p++;
158                                if (*p == '\0')
159                                        break;
160                                b = p;
161
162                                p = strpbrk(p, " ,/");
163                                /* find end of spec */
164                                if (p != NULL)
165                                        p = strpbrk(p, ",\n");
166                                if (p != NULL)
167                                        *p++ = '\0';
168
169                                praliases(b, argc, argv);
170                        }
171
172                  default:
173                        continue;
174                }
175        }
176        (void) fclose(cfp);
177        exit(EX_OK);
178}
179
180static void
181praliases(filename, argc, argv)
182        char *filename;
183        int  argc;
184        char **argv;
185{
186#ifdef NEWDB
187        DB *db;
188        DBT newdbkey, newdbcontent;
189        char buf[MAXNAME];
190#endif
191        char *class;
192
193        class = strchr(filename, ':');
194        if (class != NULL)
195        {
196                if (strncasecmp(filename, "dbm:", 4) == 0)
197                {
198#ifdef NDBM
199                        praliases_dbm(class + 1, argc, argv);
200                        return;
201#else
202                        fprintf(stderr, "class dbm not available\n");
203                        exit(EX_DATAERR);
204#endif
205                }
206                filename = class + 1;
207        }
208#ifdef NEWDB
209        if (strlen(filename) + 4 >= sizeof buf)
210        {
211                fprintf(stderr, "Alias filename too long: %.30s...\n", filename);
212                exit(EX_USAGE);
213        }
214        (void) strcpy(buf, filename);
215        (void) strcat(buf, ".db");
216# if DB_VERSION_MAJOR < 2
217        db = dbopen(buf, O_RDONLY, 0444, DB_HASH, NULL);
218# else
219        db = NULL;
220        errno = db_open(buf, DB_HASH, DB_RDONLY, 0444, NULL, NULL, &db);
221# endif
222        if (db != NULL)
223        {
224                if (!argc)
225                {
226# if DB_VERSION_MAJOR > 1
227                        DBC *dbc;
228# endif
229                        bzero(&newdbkey, sizeof newdbkey);
230                        bzero(&newdbcontent, sizeof newdbcontent);
231
232# if DB_VERSION_MAJOR < 2
233                        while(!db->seq(db, &newdbkey, &newdbcontent, R_NEXT))
234# else
235#  if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >=6
236                        if ((errno = db->cursor(db, NULL, &dbc, 0)) == 0)
237#  else
238                        if ((errno = db->cursor(db, NULL, &dbc)) == 0)
239#  endif
240                        {
241                                while ((errno = dbc->c_get(dbc, &newdbkey,
242                                                           &newdbcontent,
243                                                           DB_NEXT)) == 0)
244# endif
245                                printf("%.*s:%.*s\n",
246                                        (int) newdbkey.size,
247                                        (char *) newdbkey.data,
248                                        (int) newdbcontent.size,
249                                        (char *) newdbcontent.data);
250# if DB_VERSION_MAJOR > 1
251                                (void) dbc->c_close(dbc);
252                        }
253                        else
254                        {
255                                fprintf(stderr,
256                                        "praliases: %s: Could not set cursor: %s\n",
257                                        buf, strerror(errno));
258                                errno = db->close(db, 0);
259                                exit(EX_DATAERR);
260                        }
261# endif
262                }
263                else for (; *argv; ++argv)
264                {
265                        bzero(&newdbkey, sizeof newdbkey);
266                        bzero(&newdbcontent, sizeof newdbcontent);
267                        newdbkey.data = *argv;
268                        newdbkey.size = strlen(*argv) + 1;
269# if DB_VERSION_MAJOR < 2
270                        if (!db->get(db, &newdbkey, &newdbcontent, 0))
271# else
272                        if ((errno = db->get(db, NULL, &newdbkey,
273                                             &newdbcontent, 0)) == 0)
274# endif
275                                printf("%s:%.*s\n", (char *) newdbkey.data,
276                                        (int) newdbcontent.size,
277                                        (char *) newdbcontent.data);
278                        else
279                                printf("%s: No such key\n",
280                                        (char *) newdbkey.data);
281                }
282# if DB_VERSION_MAJOR < 2
283                (void)db->close(db);
284# else
285                errno = db->close(db, 0);
286# endif
287        }
288        else
289        {
290#endif
291#ifdef NDBM
292                praliases_dbm(filename, argc, argv);
293#endif
294#ifdef NEWDB
295        }
296#endif
297}
298
299#ifdef NDBM
300static void
301praliases_dbm(filename, argc, argv)
302        char *filename;
303        int  argc;
304        char **argv;
305{
306        DBM *dbp;
307        datum content, key;
308
309        if ((dbp = dbm_open(filename, O_RDONLY, 0)) == NULL)
310        {
311                (void)fprintf(stderr,
312                    "praliases: %s: %s\n", filename, strerror(errno));
313                exit(EX_OSFILE);
314        }
315        if (!argc)
316        {
317                for (key = dbm_firstkey(dbp);
318                    key.dptr != NULL; key = dbm_nextkey(dbp))
319                {
320                        content = dbm_fetch(dbp, key);
321                        (void)printf("%.*s:%.*s\n",
322                                (int) key.dsize, key.dptr,
323                                (int) content.dsize, content.dptr);
324                }
325        }
326        else
327        {
328                for (; *argv; ++argv)
329                {
330                        /*
331                        **  Use the sendmail adaptive algorithm of trying
332                        **  the key first without, then if needed with,
333                        **  the terminating NULL byte.
334                        */
335                        key.dptr = *argv;
336                        key.dsize = strlen(*argv);
337                        content = dbm_fetch(dbp, key);
338                        if (content.dptr == NULL)
339                        {
340                                key.dsize++;
341                                content = dbm_fetch(dbp, key);
342                        }
343                        if (content.dptr != NULL)
344                                (void)printf("%s:%.*s\n", key.dptr,
345                                        (int) content.dsize, content.dptr);
346                        else
347                                (void)printf("%s: No such key\n", key.dptr);
348                }
349        }
350        dbm_close(dbp);
351}
352#endif
353
354#if !HASSTRERROR
355
356char *
357strerror(eno)
358        int eno;
359{
360        extern int sys_nerr;
361        extern char *sys_errlist[];
362        static char ebuf[60];
363
364        if (eno >= 0 && eno < sys_nerr)
365                return sys_errlist[eno];
366        (void) sprintf(ebuf, "Error %d", eno);
367        return ebuf;
368}
369
370#endif /* !HASSTRERROR */
Note: See TracBrowser for help on using the repository browser.