xref: /freebsd/contrib/sendmail/praliases/praliases.c (revision 12ed1c7c81a0777c53a89597f28b0ece402a6e0c)
1c2aa98e2SPeter Wemm /*
2b4662009SGregory Neil Shapiro  * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
33299c2f1SGregory Neil Shapiro  *	All rights reserved.
4c2aa98e2SPeter Wemm  * Copyright (c) 1983 Eric P. Allman.  All rights reserved.
5c2aa98e2SPeter Wemm  * Copyright (c) 1988, 1993
6c2aa98e2SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
7c2aa98e2SPeter Wemm  *
8c2aa98e2SPeter Wemm  * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm  * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm  * the sendmail distribution.
11c2aa98e2SPeter Wemm  *
12c2aa98e2SPeter Wemm  */
13c2aa98e2SPeter Wemm 
1412ed1c7cSGregory Neil Shapiro #include <sm/gen.h>
1512ed1c7cSGregory Neil Shapiro 
1612ed1c7cSGregory Neil Shapiro SM_IDSTR(copyright,
17b4662009SGregory Neil Shapiro "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
183299c2f1SGregory Neil Shapiro 	All rights reserved.\n\
193299c2f1SGregory Neil Shapiro      Copyright (c) 1983 Eric P. Allman.  All rights reserved.\n\
203299c2f1SGregory Neil Shapiro      Copyright (c) 1988, 1993\n\
2112ed1c7cSGregory Neil Shapiro 	The Regents of the University of California.  All rights reserved.\n")
22c2aa98e2SPeter Wemm 
2312ed1c7cSGregory Neil Shapiro SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.93 2001/09/11 04:05:07 gshapiro Exp $")
24c2aa98e2SPeter Wemm 
253299c2f1SGregory Neil Shapiro /* $FreeBSD$ */
26c2aa98e2SPeter Wemm 
273299c2f1SGregory Neil Shapiro #include <sys/types.h>
283299c2f1SGregory Neil Shapiro #include <ctype.h>
293299c2f1SGregory Neil Shapiro #include <stdlib.h>
303299c2f1SGregory Neil Shapiro #include <unistd.h>
313299c2f1SGregory Neil Shapiro #ifdef EX_OK
323299c2f1SGregory Neil Shapiro # undef EX_OK		/* unistd.h may have another use for this */
333299c2f1SGregory Neil Shapiro #endif /* EX_OK */
343299c2f1SGregory Neil Shapiro #include <sysexits.h>
353299c2f1SGregory Neil Shapiro 
363299c2f1SGregory Neil Shapiro 
37c2aa98e2SPeter Wemm #ifndef NOT_SENDMAIL
38c2aa98e2SPeter Wemm # define NOT_SENDMAIL
393299c2f1SGregory Neil Shapiro #endif /* ! NOT_SENDMAIL */
403299c2f1SGregory Neil Shapiro #include <sendmail/sendmail.h>
413299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h>
423299c2f1SGregory Neil Shapiro #include <libsmdb/smdb.h>
43c2aa98e2SPeter Wemm 
4476b7bf71SPeter Wemm static void praliases __P((char *, int, char **));
453299c2f1SGregory Neil Shapiro 
463299c2f1SGregory Neil Shapiro uid_t	RealUid;
473299c2f1SGregory Neil Shapiro gid_t	RealGid;
483299c2f1SGregory Neil Shapiro char	*RealUserName;
493299c2f1SGregory Neil Shapiro uid_t	RunAsUid;
503299c2f1SGregory Neil Shapiro uid_t	RunAsGid;
513299c2f1SGregory Neil Shapiro char	*RunAsUserName;
523299c2f1SGregory Neil Shapiro int	Verbose = 2;
5312ed1c7cSGregory Neil Shapiro bool	DontInitGroups = false;
543299c2f1SGregory Neil Shapiro uid_t	TrustedUid = 0;
553299c2f1SGregory Neil Shapiro BITMAP256 DontBlameSendmail;
563299c2f1SGregory Neil Shapiro 
57c46d91b7SGregory Neil Shapiro # define DELIMITERS		" ,/"
58c46d91b7SGregory Neil Shapiro # define PATH_SEPARATOR		':'
5976b7bf71SPeter Wemm 
60c2aa98e2SPeter Wemm int
61c2aa98e2SPeter Wemm main(argc, argv)
62c2aa98e2SPeter Wemm 	int argc;
63c2aa98e2SPeter Wemm 	char **argv;
64c2aa98e2SPeter Wemm {
6576b7bf71SPeter Wemm 	char *cfile;
6676b7bf71SPeter Wemm 	char *filename = NULL;
6712ed1c7cSGregory Neil Shapiro 	SM_FILE_T *cfp;
68c2aa98e2SPeter Wemm 	int ch;
6976b7bf71SPeter Wemm 	char afilebuf[MAXLINE];
7076b7bf71SPeter Wemm 	char buf[MAXLINE];
713299c2f1SGregory Neil Shapiro 	struct passwd *pw;
723299c2f1SGregory Neil Shapiro 	static char rnamebuf[MAXNAME];
733299c2f1SGregory Neil Shapiro 	extern char *optarg;
743299c2f1SGregory Neil Shapiro 	extern int optind;
753299c2f1SGregory Neil Shapiro 
763299c2f1SGregory Neil Shapiro 	clrbitmap(DontBlameSendmail);
773299c2f1SGregory Neil Shapiro 	RunAsUid = RealUid = getuid();
783299c2f1SGregory Neil Shapiro 	RunAsGid = RealGid = getgid();
793299c2f1SGregory Neil Shapiro 	pw = getpwuid(RealUid);
803299c2f1SGregory Neil Shapiro 	if (pw != NULL)
813299c2f1SGregory Neil Shapiro 	{
823299c2f1SGregory Neil Shapiro 		if (strlen(pw->pw_name) > MAXNAME - 1)
833299c2f1SGregory Neil Shapiro 			pw->pw_name[MAXNAME] = 0;
8412ed1c7cSGregory Neil Shapiro 		sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
853299c2f1SGregory Neil Shapiro 	}
863299c2f1SGregory Neil Shapiro 	else
8712ed1c7cSGregory Neil Shapiro 		(void) sm_snprintf(rnamebuf, sizeof rnamebuf,
8812ed1c7cSGregory Neil Shapiro 		    "Unknown UID %d", (int) RealUid);
893299c2f1SGregory Neil Shapiro 	RunAsUserName = RealUserName = rnamebuf;
90c2aa98e2SPeter Wemm 
9112ed1c7cSGregory Neil Shapiro 	cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
9276b7bf71SPeter Wemm 	while ((ch = getopt(argc, argv, "C:f:")) != -1)
9376b7bf71SPeter Wemm 	{
94c2aa98e2SPeter Wemm 		switch ((char)ch) {
9576b7bf71SPeter Wemm 		case 'C':
9676b7bf71SPeter Wemm 			cfile = optarg;
9776b7bf71SPeter Wemm 			break;
98c2aa98e2SPeter Wemm 		case 'f':
99c2aa98e2SPeter Wemm 			filename = optarg;
100c2aa98e2SPeter Wemm 			break;
101c2aa98e2SPeter Wemm 		case '?':
102c2aa98e2SPeter Wemm 		default:
10312ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
10476b7bf71SPeter Wemm 			    "usage: praliases [-C cffile] [-f aliasfile]\n");
105c2aa98e2SPeter Wemm 			exit(EX_USAGE);
106c2aa98e2SPeter Wemm 		}
10776b7bf71SPeter Wemm 	}
108c2aa98e2SPeter Wemm 	argc -= optind;
109c2aa98e2SPeter Wemm 	argv += optind;
110c2aa98e2SPeter Wemm 
11176b7bf71SPeter Wemm 	if (filename != NULL)
11276b7bf71SPeter Wemm 	{
11376b7bf71SPeter Wemm 		praliases(filename, argc, argv);
11476b7bf71SPeter Wemm 		exit(EX_OK);
11576b7bf71SPeter Wemm 	}
11676b7bf71SPeter Wemm 
11712ed1c7cSGregory Neil Shapiro 	if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
11812ed1c7cSGregory Neil Shapiro 			      NULL)) == NULL)
11976b7bf71SPeter Wemm 	{
12012ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
12112ed1c7cSGregory Neil Shapiro 				     "praliases: %s: %s\n", cfile,
12212ed1c7cSGregory Neil Shapiro 				     sm_errstring(errno));
12376b7bf71SPeter Wemm 		exit(EX_NOINPUT);
12476b7bf71SPeter Wemm 	}
12576b7bf71SPeter Wemm 
12612ed1c7cSGregory Neil Shapiro 	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
12776b7bf71SPeter Wemm 	{
12876b7bf71SPeter Wemm 		register char *b, *p;
12976b7bf71SPeter Wemm 
1303299c2f1SGregory Neil Shapiro 		b = strchr(buf, '\n');
1313299c2f1SGregory Neil Shapiro 		if (b != NULL)
1323299c2f1SGregory Neil Shapiro 			*b = '\0';
1333299c2f1SGregory Neil Shapiro 
13476b7bf71SPeter Wemm 		b = buf;
13576b7bf71SPeter Wemm 		switch (*b++)
13676b7bf71SPeter Wemm 		{
13776b7bf71SPeter Wemm 		  case 'O':		/* option -- see if alias file */
13812ed1c7cSGregory Neil Shapiro 			if (sm_strncasecmp(b, " AliasFile", 10) == 0 &&
13976b7bf71SPeter Wemm 			    !(isascii(b[10]) && isalnum(b[10])))
14076b7bf71SPeter Wemm 			{
14176b7bf71SPeter Wemm 				/* new form -- find value */
14276b7bf71SPeter Wemm 				b = strchr(b, '=');
14376b7bf71SPeter Wemm 				if (b == NULL)
14476b7bf71SPeter Wemm 					continue;
14576b7bf71SPeter Wemm 				while (isascii(*++b) && isspace(*b))
14676b7bf71SPeter Wemm 					continue;
14776b7bf71SPeter Wemm 			}
14876b7bf71SPeter Wemm 			else if (*b++ != 'A')
14976b7bf71SPeter Wemm 			{
15076b7bf71SPeter Wemm 				/* something else boring */
15176b7bf71SPeter Wemm 				continue;
15276b7bf71SPeter Wemm 			}
15376b7bf71SPeter Wemm 
15476b7bf71SPeter Wemm 			/* this is the A or AliasFile option -- save it */
15512ed1c7cSGregory Neil Shapiro 			if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >=
1563299c2f1SGregory Neil Shapiro 			    sizeof afilebuf)
15776b7bf71SPeter Wemm 			{
15812ed1c7cSGregory Neil Shapiro 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
1593299c2f1SGregory Neil Shapiro 				    "praliases: AliasFile filename too long: %.30s\n",
16076b7bf71SPeter Wemm 					b);
16112ed1c7cSGregory Neil Shapiro 				(void) sm_io_close(cfp, SM_TIME_DEFAULT);
16276b7bf71SPeter Wemm 				exit(EX_CONFIG);
16376b7bf71SPeter Wemm 			}
16476b7bf71SPeter Wemm 			b = afilebuf;
16576b7bf71SPeter Wemm 
16676b7bf71SPeter Wemm 			for (p = b; p != NULL; )
16776b7bf71SPeter Wemm 			{
16876b7bf71SPeter Wemm 				while (isascii(*p) && isspace(*p))
16976b7bf71SPeter Wemm 					p++;
17076b7bf71SPeter Wemm 				if (*p == '\0')
17176b7bf71SPeter Wemm 					break;
17276b7bf71SPeter Wemm 				b = p;
17376b7bf71SPeter Wemm 
174c46d91b7SGregory Neil Shapiro 				p = strpbrk(p, DELIMITERS);
1753299c2f1SGregory Neil Shapiro 
17676b7bf71SPeter Wemm 				/* find end of spec */
17776b7bf71SPeter Wemm 				if (p != NULL)
1783299c2f1SGregory Neil Shapiro 				{
17912ed1c7cSGregory Neil Shapiro 					bool quoted = false;
18076b7bf71SPeter Wemm 
1813299c2f1SGregory Neil Shapiro 					for (; *p != '\0'; p++)
1823299c2f1SGregory Neil Shapiro 					{
1833299c2f1SGregory Neil Shapiro 						/*
1843299c2f1SGregory Neil Shapiro 						**  Don't break into a quoted
1853299c2f1SGregory Neil Shapiro 						**  string.
1863299c2f1SGregory Neil Shapiro 						*/
1873299c2f1SGregory Neil Shapiro 
1883299c2f1SGregory Neil Shapiro 						if (*p == '"')
1893299c2f1SGregory Neil Shapiro 							quoted = !quoted;
1903299c2f1SGregory Neil Shapiro 						else if (*p == ',' && !quoted)
1913299c2f1SGregory Neil Shapiro 							break;
1923299c2f1SGregory Neil Shapiro 					}
1933299c2f1SGregory Neil Shapiro 
1943299c2f1SGregory Neil Shapiro 					/* No more alias specs follow */
1953299c2f1SGregory Neil Shapiro 					if (*p == '\0')
1963299c2f1SGregory Neil Shapiro 					{
1973299c2f1SGregory Neil Shapiro 						/* chop trailing whitespace */
1983299c2f1SGregory Neil Shapiro 						while (isascii(*p) &&
1993299c2f1SGregory Neil Shapiro 						       isspace(*p) &&
2003299c2f1SGregory Neil Shapiro 						       p > b)
2013299c2f1SGregory Neil Shapiro 							p--;
2023299c2f1SGregory Neil Shapiro 						*p = '\0';
2033299c2f1SGregory Neil Shapiro 						p = NULL;
2043299c2f1SGregory Neil Shapiro 					}
2053299c2f1SGregory Neil Shapiro 				}
2063299c2f1SGregory Neil Shapiro 
2073299c2f1SGregory Neil Shapiro 				if (p != NULL)
2083299c2f1SGregory Neil Shapiro 				{
2093299c2f1SGregory Neil Shapiro 					char *e = p - 1;
2103299c2f1SGregory Neil Shapiro 
2113299c2f1SGregory Neil Shapiro 					/* chop trailing whitespace */
2123299c2f1SGregory Neil Shapiro 					while (isascii(*e) &&
2133299c2f1SGregory Neil Shapiro 					       isspace(*e) &&
2143299c2f1SGregory Neil Shapiro 					       e > b)
2153299c2f1SGregory Neil Shapiro 						e--;
2163299c2f1SGregory Neil Shapiro 					*++e = '\0';
2173299c2f1SGregory Neil Shapiro 					*p++ = '\0';
2183299c2f1SGregory Neil Shapiro 				}
21976b7bf71SPeter Wemm 				praliases(b, argc, argv);
22076b7bf71SPeter Wemm 			}
22176b7bf71SPeter Wemm 
22276b7bf71SPeter Wemm 		  default:
22376b7bf71SPeter Wemm 			continue;
22476b7bf71SPeter Wemm 		}
22576b7bf71SPeter Wemm 	}
22612ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
22776b7bf71SPeter Wemm 	exit(EX_OK);
2283299c2f1SGregory Neil Shapiro 	/* NOTREACHED */
2293299c2f1SGregory Neil Shapiro 	return EX_OK;
23076b7bf71SPeter Wemm }
23176b7bf71SPeter Wemm 
23276b7bf71SPeter Wemm static void
23376b7bf71SPeter Wemm praliases(filename, argc, argv)
23476b7bf71SPeter Wemm 	char *filename;
23576b7bf71SPeter Wemm 	int argc;
23676b7bf71SPeter Wemm 	char **argv;
23776b7bf71SPeter Wemm {
2383299c2f1SGregory Neil Shapiro 	int result;
2393299c2f1SGregory Neil Shapiro 	char *colon;
2403299c2f1SGregory Neil Shapiro 	char *db_name;
2413299c2f1SGregory Neil Shapiro 	char *db_type;
2423299c2f1SGregory Neil Shapiro 	SMDB_DATABASE *database = NULL;
2433299c2f1SGregory Neil Shapiro 	SMDB_CURSOR *cursor = NULL;
2443299c2f1SGregory Neil Shapiro 	SMDB_DBENT db_key, db_value;
2453299c2f1SGregory Neil Shapiro 	SMDB_DBPARAMS params;
2463299c2f1SGregory Neil Shapiro 	SMDB_USER_INFO user_info;
24776b7bf71SPeter Wemm 
248c46d91b7SGregory Neil Shapiro 	colon = strchr(filename, PATH_SEPARATOR);
2493299c2f1SGregory Neil Shapiro 	if (colon == NULL)
25076b7bf71SPeter Wemm 	{
2513299c2f1SGregory Neil Shapiro 		db_name = filename;
2523299c2f1SGregory Neil Shapiro 		db_type = SMDB_TYPE_DEFAULT;
253c2aa98e2SPeter Wemm 	}
254c2aa98e2SPeter Wemm 	else
255c2aa98e2SPeter Wemm 	{
2563299c2f1SGregory Neil Shapiro 		*colon = '\0';
2573299c2f1SGregory Neil Shapiro 		db_name = colon + 1;
2583299c2f1SGregory Neil Shapiro 		db_type = filename;
2593299c2f1SGregory Neil Shapiro 	}
2603299c2f1SGregory Neil Shapiro 
2613299c2f1SGregory Neil Shapiro 	/* clean off arguments */
2623299c2f1SGregory Neil Shapiro 	for (;;)
2633299c2f1SGregory Neil Shapiro 	{
2643299c2f1SGregory Neil Shapiro 		while (isascii(*db_name) && isspace(*db_name))
2653299c2f1SGregory Neil Shapiro 			db_name++;
266c46d91b7SGregory Neil Shapiro 
2673299c2f1SGregory Neil Shapiro 		if (*db_name != '-')
2683299c2f1SGregory Neil Shapiro 			break;
2693299c2f1SGregory Neil Shapiro 		while (*db_name != '\0' &&
2703299c2f1SGregory Neil Shapiro 		       !(isascii(*db_name) && isspace(*db_name)))
2713299c2f1SGregory Neil Shapiro 			db_name++;
2723299c2f1SGregory Neil Shapiro 	}
2733299c2f1SGregory Neil Shapiro 
274b4662009SGregory Neil Shapiro 	/* Skip non-file based DB types */
275b4662009SGregory Neil Shapiro 	if (db_type != NULL && *db_type != '\0')
276b4662009SGregory Neil Shapiro 	{
277b4662009SGregory Neil Shapiro 		if (db_type != SMDB_TYPE_DEFAULT &&
278b4662009SGregory Neil Shapiro 		    strcmp(db_type, "hash") != 0 &&
279b4662009SGregory Neil Shapiro 		    strcmp(db_type, "btree") != 0 &&
280b4662009SGregory Neil Shapiro 		    strcmp(db_type, "dbm") != 0)
281b4662009SGregory Neil Shapiro 		{
28212ed1c7cSGregory Neil Shapiro 			sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
283b4662009SGregory Neil Shapiro 				      "praliases: Skipping non-file based alias type %s\n",
284b4662009SGregory Neil Shapiro 				db_type);
285b4662009SGregory Neil Shapiro 			return;
286b4662009SGregory Neil Shapiro 		}
287b4662009SGregory Neil Shapiro 	}
288b4662009SGregory Neil Shapiro 
2893299c2f1SGregory Neil Shapiro 	if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
2903299c2f1SGregory Neil Shapiro 	{
2913299c2f1SGregory Neil Shapiro 		if (colon != NULL)
2923299c2f1SGregory Neil Shapiro 			*colon = ':';
29312ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
29412ed1c7cSGregory Neil Shapiro 		    "praliases: illegal alias specification: %s\n", filename);
2953299c2f1SGregory Neil Shapiro 		goto fatal;
2963299c2f1SGregory Neil Shapiro 	}
2973299c2f1SGregory Neil Shapiro 
2983299c2f1SGregory Neil Shapiro 	memset(&params, '\0', sizeof params);
2993299c2f1SGregory Neil Shapiro 	params.smdbp_cache_size = 1024 * 1024;
3003299c2f1SGregory Neil Shapiro 
3013299c2f1SGregory Neil Shapiro 	user_info.smdbu_id = RunAsUid;
3023299c2f1SGregory Neil Shapiro 	user_info.smdbu_group_id = RunAsGid;
30312ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
30412ed1c7cSGregory Neil Shapiro 			  SMDB_MAX_USER_NAME_LEN);
3053299c2f1SGregory Neil Shapiro 
3063299c2f1SGregory Neil Shapiro 	result = smdb_open_database(&database, db_name, O_RDONLY, 0,
3073299c2f1SGregory Neil Shapiro 				    SFF_ROOTOK, db_type, &user_info, &params);
3083299c2f1SGregory Neil Shapiro 	if (result != SMDBE_OK)
3093299c2f1SGregory Neil Shapiro 	{
31012ed1c7cSGregory Neil Shapiro 		sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
31112ed1c7cSGregory Neil Shapiro 			      "praliases: %s: open: %s\n",
31212ed1c7cSGregory Neil Shapiro 			      db_name, sm_errstring(result));
3133299c2f1SGregory Neil Shapiro 		goto fatal;
3143299c2f1SGregory Neil Shapiro 	}
3153299c2f1SGregory Neil Shapiro 
3163299c2f1SGregory Neil Shapiro 	if (argc == 0)
3173299c2f1SGregory Neil Shapiro 	{
3183299c2f1SGregory Neil Shapiro 		memset(&db_key, '\0', sizeof db_key);
3193299c2f1SGregory Neil Shapiro 		memset(&db_value, '\0', sizeof db_value);
3203299c2f1SGregory Neil Shapiro 
3213299c2f1SGregory Neil Shapiro 		result = database->smdb_cursor(database, &cursor, 0);
3223299c2f1SGregory Neil Shapiro 		if (result != SMDBE_OK)
3233299c2f1SGregory Neil Shapiro 		{
32412ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
32512ed1c7cSGregory Neil Shapiro 			    "praliases: %s: set cursor: %s\n", db_name,
32612ed1c7cSGregory Neil Shapiro 			    sm_errstring(result));
3273299c2f1SGregory Neil Shapiro 			goto fatal;
3283299c2f1SGregory Neil Shapiro 		}
3293299c2f1SGregory Neil Shapiro 
3303299c2f1SGregory Neil Shapiro 		while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
3313299c2f1SGregory Neil Shapiro 						   SMDB_CURSOR_GET_NEXT)) ==
3323299c2f1SGregory Neil Shapiro 						   SMDBE_OK)
3333299c2f1SGregory Neil Shapiro 		{
3343299c2f1SGregory Neil Shapiro #if 0
3353299c2f1SGregory Neil Shapiro 			/* skip magic @:@ entry */
336c46d91b7SGregory Neil Shapiro 			if (db_key.size == 2 &&
337c46d91b7SGregory Neil Shapiro 			    db_key.data[0] == '@' &&
338c46d91b7SGregory Neil Shapiro 			    db_key.data[1] == '\0' &&
339c46d91b7SGregory Neil Shapiro 			    db_value.size == 2 &&
340c46d91b7SGregory Neil Shapiro 			    db_value.data[0] == '@' &&
341c46d91b7SGregory Neil Shapiro 			    db_value.data[1] == '\0')
3423299c2f1SGregory Neil Shapiro 				continue;
3433299c2f1SGregory Neil Shapiro #endif /* 0 */
3443299c2f1SGregory Neil Shapiro 
34512ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
34612ed1c7cSGregory Neil Shapiro 					     "%.*s:%.*s\n",
347c46d91b7SGregory Neil Shapiro 					     (int) db_key.size,
348c46d91b7SGregory Neil Shapiro 					     (char *) db_key.data,
349c46d91b7SGregory Neil Shapiro 					     (int) db_value.size,
350c46d91b7SGregory Neil Shapiro 					     (char *) db_value.data);
3513299c2f1SGregory Neil Shapiro 		}
3523299c2f1SGregory Neil Shapiro 
3533299c2f1SGregory Neil Shapiro 		if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
3543299c2f1SGregory Neil Shapiro 		{
35512ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
3563299c2f1SGregory Neil Shapiro 				"praliases: %s: get value at cursor: %s\n",
35712ed1c7cSGregory Neil Shapiro 				db_name, sm_errstring(result));
3583299c2f1SGregory Neil Shapiro 			goto fatal;
359c2aa98e2SPeter Wemm 		}
360c2aa98e2SPeter Wemm 	}
3613299c2f1SGregory Neil Shapiro 	else for (; *argv != NULL; ++argv)
36276b7bf71SPeter Wemm 	{
363c0c4794dSGregory Neil Shapiro 		int get_res;
364c0c4794dSGregory Neil Shapiro 
3653299c2f1SGregory Neil Shapiro 		memset(&db_key, '\0', sizeof db_key);
3663299c2f1SGregory Neil Shapiro 		memset(&db_value, '\0', sizeof db_value);
367c46d91b7SGregory Neil Shapiro 		db_key.data = *argv;
368c0c4794dSGregory Neil Shapiro 		db_key.size = strlen(*argv);
369c0c4794dSGregory Neil Shapiro 		get_res = database->smdb_get(database, &db_key, &db_value, 0);
370c0c4794dSGregory Neil Shapiro 		if (get_res == SMDBE_NOT_FOUND)
371c0c4794dSGregory Neil Shapiro 		{
372c0c4794dSGregory Neil Shapiro 			db_key.size++;
373c0c4794dSGregory Neil Shapiro 			get_res = database->smdb_get(database, &db_key,
374c0c4794dSGregory Neil Shapiro 						     &db_value, 0);
375c0c4794dSGregory Neil Shapiro 		}
376c0c4794dSGregory Neil Shapiro 		if (get_res == SMDBE_OK)
3773299c2f1SGregory Neil Shapiro 		{
37812ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
37912ed1c7cSGregory Neil Shapiro 					     "%.*s:%.*s\n",
380c46d91b7SGregory Neil Shapiro 					     (int) db_key.size,
381c46d91b7SGregory Neil Shapiro 					     (char *) db_key.data,
382c46d91b7SGregory Neil Shapiro 					     (int) db_value.size,
383c46d91b7SGregory Neil Shapiro 					     (char *) db_value.data);
384c2aa98e2SPeter Wemm 		}
38576b7bf71SPeter Wemm 		else
38612ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
38712ed1c7cSGregory Neil Shapiro 					     "%s: No such key\n",
38812ed1c7cSGregory Neil Shapiro 					     (char *)db_key.data);
38976b7bf71SPeter Wemm 	}
39076b7bf71SPeter Wemm 
3913299c2f1SGregory Neil Shapiro  fatal:
3923299c2f1SGregory Neil Shapiro 	if (cursor != NULL)
3933299c2f1SGregory Neil Shapiro 		(void) cursor->smdbc_close(cursor);
3943299c2f1SGregory Neil Shapiro 	if (database != NULL)
3953299c2f1SGregory Neil Shapiro 		(void) database->smdb_close(database);
3963299c2f1SGregory Neil Shapiro 	if (colon != NULL)
3973299c2f1SGregory Neil Shapiro 		*colon = ':';
3983299c2f1SGregory Neil Shapiro 	return;
399c2aa98e2SPeter Wemm }
400