1c2aa98e2SPeter Wemm /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 1998-2001, 2008 Proofpoint, 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,
175dd76dd0SGregory Neil Shapiro "@(#) Copyright (c) 1998-2001 Proofpoint, 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 
234313cc83SGregory Neil Shapiro SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.98 2013-11-22 20:51:53 ca Exp $")
24c2aa98e2SPeter Wemm 
253299c2f1SGregory Neil Shapiro #include <sys/types.h>
263299c2f1SGregory Neil Shapiro #include <ctype.h>
273299c2f1SGregory Neil Shapiro #include <stdlib.h>
283299c2f1SGregory Neil Shapiro #include <unistd.h>
293299c2f1SGregory Neil Shapiro #ifdef EX_OK
303299c2f1SGregory Neil Shapiro # undef EX_OK		/* unistd.h may have another use for this */
315b0945b5SGregory Neil Shapiro #endif
323299c2f1SGregory Neil Shapiro #include <sysexits.h>
333299c2f1SGregory Neil Shapiro 
343299c2f1SGregory Neil Shapiro 
35c2aa98e2SPeter Wemm #ifndef NOT_SENDMAIL
36c2aa98e2SPeter Wemm # define NOT_SENDMAIL
375b0945b5SGregory Neil Shapiro #endif
383299c2f1SGregory Neil Shapiro #include <sendmail/sendmail.h>
393299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h>
403299c2f1SGregory Neil Shapiro #include <libsmdb/smdb.h>
41c2aa98e2SPeter Wemm 
4276b7bf71SPeter Wemm static void praliases __P((char *, int, char **));
433299c2f1SGregory Neil Shapiro 
443299c2f1SGregory Neil Shapiro uid_t	RealUid;
453299c2f1SGregory Neil Shapiro gid_t	RealGid;
463299c2f1SGregory Neil Shapiro char	*RealUserName;
473299c2f1SGregory Neil Shapiro uid_t	RunAsUid;
4841f3d2ceSGregory Neil Shapiro gid_t	RunAsGid;
493299c2f1SGregory Neil Shapiro char	*RunAsUserName;
503299c2f1SGregory Neil Shapiro int	Verbose = 2;
5112ed1c7cSGregory Neil Shapiro bool	DontInitGroups = false;
523299c2f1SGregory Neil Shapiro uid_t	TrustedUid = 0;
533299c2f1SGregory Neil Shapiro BITMAP256 DontBlameSendmail;
543299c2f1SGregory Neil Shapiro 
55c46d91b7SGregory Neil Shapiro # define DELIMITERS		" ,/"
56c46d91b7SGregory Neil Shapiro # define PATH_SEPARATOR		':'
5776b7bf71SPeter Wemm 
58c2aa98e2SPeter Wemm int
main(argc,argv)59c2aa98e2SPeter Wemm main(argc, argv)
60c2aa98e2SPeter Wemm 	int argc;
61c2aa98e2SPeter Wemm 	char **argv;
62c2aa98e2SPeter Wemm {
6376b7bf71SPeter Wemm 	char *cfile;
6476b7bf71SPeter Wemm 	char *filename = NULL;
6512ed1c7cSGregory Neil Shapiro 	SM_FILE_T *cfp;
66c2aa98e2SPeter Wemm 	int ch;
6776b7bf71SPeter Wemm 	char afilebuf[MAXLINE];
6876b7bf71SPeter Wemm 	char buf[MAXLINE];
693299c2f1SGregory Neil Shapiro 	struct passwd *pw;
703299c2f1SGregory Neil Shapiro 	static char rnamebuf[MAXNAME];
713299c2f1SGregory Neil Shapiro 	extern char *optarg;
723299c2f1SGregory Neil Shapiro 	extern int optind;
733299c2f1SGregory Neil Shapiro 
743299c2f1SGregory Neil Shapiro 	clrbitmap(DontBlameSendmail);
753299c2f1SGregory Neil Shapiro 	RunAsUid = RealUid = getuid();
763299c2f1SGregory Neil Shapiro 	RunAsGid = RealGid = getgid();
773299c2f1SGregory Neil Shapiro 	pw = getpwuid(RealUid);
783299c2f1SGregory Neil Shapiro 	if (pw != NULL)
793299c2f1SGregory Neil Shapiro 	{
803299c2f1SGregory Neil Shapiro 		if (strlen(pw->pw_name) > MAXNAME - 1)
813299c2f1SGregory Neil Shapiro 			pw->pw_name[MAXNAME] = 0;
8212ed1c7cSGregory Neil Shapiro 		sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
833299c2f1SGregory Neil Shapiro 	}
843299c2f1SGregory Neil Shapiro 	else
8512ed1c7cSGregory Neil Shapiro 		(void) sm_snprintf(rnamebuf, sizeof rnamebuf,
8612ed1c7cSGregory Neil Shapiro 		    "Unknown UID %d", (int) RealUid);
873299c2f1SGregory Neil Shapiro 	RunAsUserName = RealUserName = rnamebuf;
88c2aa98e2SPeter Wemm 
8912ed1c7cSGregory Neil Shapiro 	cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
902fb4f839SGregory Neil Shapiro 	while ((ch = getopt(argc, argv, "C:f:l")) != -1)
9176b7bf71SPeter Wemm 	{
92c2aa98e2SPeter Wemm 		switch ((char)ch) {
9376b7bf71SPeter Wemm 		case 'C':
9476b7bf71SPeter Wemm 			cfile = optarg;
9576b7bf71SPeter Wemm 			break;
96c2aa98e2SPeter Wemm 		case 'f':
97c2aa98e2SPeter Wemm 			filename = optarg;
98c2aa98e2SPeter Wemm 			break;
992fb4f839SGregory Neil Shapiro 
1002fb4f839SGregory Neil Shapiro 		case 'l':
1012fb4f839SGregory Neil Shapiro 			smdb_print_available_types(false);
1022fb4f839SGregory Neil Shapiro 			exit(EX_OK);
1032fb4f839SGregory Neil Shapiro 			break;
104c2aa98e2SPeter Wemm 		case '?':
105c2aa98e2SPeter Wemm 		default:
10612ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
1079bd497b8SGregory Neil Shapiro 			    "usage: praliases [-C cffile] [-f aliasfile]"
1089bd497b8SGregory Neil Shapiro 			    " [key ...]\n");
109c2aa98e2SPeter Wemm 			exit(EX_USAGE);
110c2aa98e2SPeter Wemm 		}
11176b7bf71SPeter Wemm 	}
112c2aa98e2SPeter Wemm 	argc -= optind;
113c2aa98e2SPeter Wemm 	argv += optind;
114c2aa98e2SPeter Wemm 
11576b7bf71SPeter Wemm 	if (filename != NULL)
11676b7bf71SPeter Wemm 	{
11776b7bf71SPeter Wemm 		praliases(filename, argc, argv);
11876b7bf71SPeter Wemm 		exit(EX_OK);
11976b7bf71SPeter Wemm 	}
12076b7bf71SPeter Wemm 
12112ed1c7cSGregory Neil Shapiro 	if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
12212ed1c7cSGregory Neil Shapiro 			      NULL)) == NULL)
12376b7bf71SPeter Wemm 	{
12412ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
12512ed1c7cSGregory Neil Shapiro 				     "praliases: %s: %s\n", cfile,
12612ed1c7cSGregory Neil Shapiro 				     sm_errstring(errno));
12776b7bf71SPeter Wemm 		exit(EX_NOINPUT);
12876b7bf71SPeter Wemm 	}
12976b7bf71SPeter Wemm 
130552d4955SGregory Neil Shapiro 	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
13176b7bf71SPeter Wemm 	{
13276b7bf71SPeter Wemm 		register char *b, *p;
13376b7bf71SPeter Wemm 
1343299c2f1SGregory Neil Shapiro 		b = strchr(buf, '\n');
1353299c2f1SGregory Neil Shapiro 		if (b != NULL)
1363299c2f1SGregory Neil Shapiro 			*b = '\0';
1373299c2f1SGregory Neil Shapiro 
13876b7bf71SPeter Wemm 		b = buf;
13976b7bf71SPeter Wemm 		switch (*b++)
14076b7bf71SPeter Wemm 		{
14176b7bf71SPeter Wemm 		  case 'O':		/* option -- see if alias file */
14212ed1c7cSGregory Neil Shapiro 			if (sm_strncasecmp(b, " AliasFile", 10) == 0 &&
14376b7bf71SPeter Wemm 			    !(isascii(b[10]) && isalnum(b[10])))
14476b7bf71SPeter Wemm 			{
14576b7bf71SPeter Wemm 				/* new form -- find value */
14676b7bf71SPeter Wemm 				b = strchr(b, '=');
14776b7bf71SPeter Wemm 				if (b == NULL)
14876b7bf71SPeter Wemm 					continue;
14976b7bf71SPeter Wemm 				while (isascii(*++b) && isspace(*b))
15076b7bf71SPeter Wemm 					continue;
15176b7bf71SPeter Wemm 			}
15276b7bf71SPeter Wemm 			else if (*b++ != 'A')
15376b7bf71SPeter Wemm 			{
15476b7bf71SPeter Wemm 				/* something else boring */
15576b7bf71SPeter Wemm 				continue;
15676b7bf71SPeter Wemm 			}
15776b7bf71SPeter Wemm 
15876b7bf71SPeter Wemm 			/* this is the A or AliasFile option -- save it */
15912ed1c7cSGregory Neil Shapiro 			if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >=
1603299c2f1SGregory Neil Shapiro 			    sizeof afilebuf)
16176b7bf71SPeter Wemm 			{
16212ed1c7cSGregory Neil Shapiro 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
1633299c2f1SGregory Neil Shapiro 				    "praliases: AliasFile filename too long: %.30s\n",
16476b7bf71SPeter Wemm 					b);
16512ed1c7cSGregory Neil Shapiro 				(void) sm_io_close(cfp, SM_TIME_DEFAULT);
16676b7bf71SPeter Wemm 				exit(EX_CONFIG);
16776b7bf71SPeter Wemm 			}
16876b7bf71SPeter Wemm 			b = afilebuf;
16976b7bf71SPeter Wemm 
17076b7bf71SPeter Wemm 			for (p = b; p != NULL; )
17176b7bf71SPeter Wemm 			{
17276b7bf71SPeter Wemm 				while (isascii(*p) && isspace(*p))
17376b7bf71SPeter Wemm 					p++;
17476b7bf71SPeter Wemm 				if (*p == '\0')
17576b7bf71SPeter Wemm 					break;
17676b7bf71SPeter Wemm 				b = p;
17776b7bf71SPeter Wemm 
178c46d91b7SGregory Neil Shapiro 				p = strpbrk(p, DELIMITERS);
1793299c2f1SGregory Neil Shapiro 
18076b7bf71SPeter Wemm 				/* find end of spec */
18176b7bf71SPeter Wemm 				if (p != NULL)
1823299c2f1SGregory Neil Shapiro 				{
18312ed1c7cSGregory Neil Shapiro 					bool quoted = false;
18476b7bf71SPeter Wemm 
1853299c2f1SGregory Neil Shapiro 					for (; *p != '\0'; p++)
1863299c2f1SGregory Neil Shapiro 					{
1873299c2f1SGregory Neil Shapiro 						/*
1883299c2f1SGregory Neil Shapiro 						**  Don't break into a quoted
1893299c2f1SGregory Neil Shapiro 						**  string.
1903299c2f1SGregory Neil Shapiro 						*/
1913299c2f1SGregory Neil Shapiro 
1923299c2f1SGregory Neil Shapiro 						if (*p == '"')
1933299c2f1SGregory Neil Shapiro 							quoted = !quoted;
1943299c2f1SGregory Neil Shapiro 						else if (*p == ',' && !quoted)
1953299c2f1SGregory Neil Shapiro 							break;
1963299c2f1SGregory Neil Shapiro 					}
1973299c2f1SGregory Neil Shapiro 
1983299c2f1SGregory Neil Shapiro 					/* No more alias specs follow */
1993299c2f1SGregory Neil Shapiro 					if (*p == '\0')
2003299c2f1SGregory Neil Shapiro 					{
2013299c2f1SGregory Neil Shapiro 						/* chop trailing whitespace */
2023299c2f1SGregory Neil Shapiro 						while (isascii(*p) &&
2033299c2f1SGregory Neil Shapiro 						       isspace(*p) &&
2043299c2f1SGregory Neil Shapiro 						       p > b)
2053299c2f1SGregory Neil Shapiro 							p--;
2063299c2f1SGregory Neil Shapiro 						*p = '\0';
2073299c2f1SGregory Neil Shapiro 						p = NULL;
2083299c2f1SGregory Neil Shapiro 					}
2093299c2f1SGregory Neil Shapiro 				}
2103299c2f1SGregory Neil Shapiro 
2113299c2f1SGregory Neil Shapiro 				if (p != NULL)
2123299c2f1SGregory Neil Shapiro 				{
2133299c2f1SGregory Neil Shapiro 					char *e = p - 1;
2143299c2f1SGregory Neil Shapiro 
2153299c2f1SGregory Neil Shapiro 					/* chop trailing whitespace */
2163299c2f1SGregory Neil Shapiro 					while (isascii(*e) &&
2173299c2f1SGregory Neil Shapiro 					       isspace(*e) &&
2183299c2f1SGregory Neil Shapiro 					       e > b)
2193299c2f1SGregory Neil Shapiro 						e--;
2203299c2f1SGregory Neil Shapiro 					*++e = '\0';
2213299c2f1SGregory Neil Shapiro 					*p++ = '\0';
2223299c2f1SGregory Neil Shapiro 				}
22376b7bf71SPeter Wemm 				praliases(b, argc, argv);
22476b7bf71SPeter Wemm 			}
22576b7bf71SPeter Wemm 
22676b7bf71SPeter Wemm 		  default:
22776b7bf71SPeter Wemm 			continue;
22876b7bf71SPeter Wemm 		}
22976b7bf71SPeter Wemm 	}
23012ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
23176b7bf71SPeter Wemm 	exit(EX_OK);
2323299c2f1SGregory Neil Shapiro 	/* NOTREACHED */
2333299c2f1SGregory Neil Shapiro 	return EX_OK;
23476b7bf71SPeter Wemm }
23576b7bf71SPeter Wemm 
23676b7bf71SPeter Wemm static void
praliases(filename,argc,argv)23776b7bf71SPeter Wemm praliases(filename, argc, argv)
23876b7bf71SPeter Wemm 	char *filename;
23976b7bf71SPeter Wemm 	int argc;
24076b7bf71SPeter Wemm 	char **argv;
24176b7bf71SPeter Wemm {
2423299c2f1SGregory Neil Shapiro 	int result;
2433299c2f1SGregory Neil Shapiro 	char *colon;
2443299c2f1SGregory Neil Shapiro 	char *db_name;
2453299c2f1SGregory Neil Shapiro 	char *db_type;
2463299c2f1SGregory Neil Shapiro 	SMDB_DATABASE *database = NULL;
2473299c2f1SGregory Neil Shapiro 	SMDB_CURSOR *cursor = NULL;
2483299c2f1SGregory Neil Shapiro 	SMDB_DBENT db_key, db_value;
2493299c2f1SGregory Neil Shapiro 	SMDB_DBPARAMS params;
2503299c2f1SGregory Neil Shapiro 	SMDB_USER_INFO user_info;
25176b7bf71SPeter Wemm 
252c46d91b7SGregory Neil Shapiro 	colon = strchr(filename, PATH_SEPARATOR);
2533299c2f1SGregory Neil Shapiro 	if (colon == NULL)
25476b7bf71SPeter Wemm 	{
2553299c2f1SGregory Neil Shapiro 		db_name = filename;
2563299c2f1SGregory Neil Shapiro 		db_type = SMDB_TYPE_DEFAULT;
257c2aa98e2SPeter Wemm 	}
258c2aa98e2SPeter Wemm 	else
259c2aa98e2SPeter Wemm 	{
2603299c2f1SGregory Neil Shapiro 		*colon = '\0';
2613299c2f1SGregory Neil Shapiro 		db_name = colon + 1;
2623299c2f1SGregory Neil Shapiro 		db_type = filename;
2633299c2f1SGregory Neil Shapiro 	}
2643299c2f1SGregory Neil Shapiro 
2653299c2f1SGregory Neil Shapiro 	/* clean off arguments */
2663299c2f1SGregory Neil Shapiro 	for (;;)
2673299c2f1SGregory Neil Shapiro 	{
2683299c2f1SGregory Neil Shapiro 		while (isascii(*db_name) && isspace(*db_name))
2693299c2f1SGregory Neil Shapiro 			db_name++;
270c46d91b7SGregory Neil Shapiro 
2713299c2f1SGregory Neil Shapiro 		if (*db_name != '-')
2723299c2f1SGregory Neil Shapiro 			break;
2733299c2f1SGregory Neil Shapiro 		while (*db_name != '\0' &&
2743299c2f1SGregory Neil Shapiro 		       !(isascii(*db_name) && isspace(*db_name)))
2753299c2f1SGregory Neil Shapiro 			db_name++;
2763299c2f1SGregory Neil Shapiro 	}
2773299c2f1SGregory Neil Shapiro 
278b4662009SGregory Neil Shapiro 	/* Skip non-file based DB types */
279b4662009SGregory Neil Shapiro 	if (db_type != NULL && *db_type != '\0')
280b4662009SGregory Neil Shapiro 	{
281b4662009SGregory Neil Shapiro 		if (db_type != SMDB_TYPE_DEFAULT &&
2825b0945b5SGregory Neil Shapiro 		    !smdb_is_db_type(db_type))
283b4662009SGregory Neil Shapiro 		{
28412ed1c7cSGregory Neil Shapiro 			sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
285b4662009SGregory Neil Shapiro 				      "praliases: Skipping non-file based alias type %s\n",
286b4662009SGregory Neil Shapiro 				db_type);
287b4662009SGregory Neil Shapiro 			return;
288b4662009SGregory Neil Shapiro 		}
289b4662009SGregory Neil Shapiro 	}
290b4662009SGregory Neil Shapiro 
2913299c2f1SGregory Neil Shapiro 	if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
2923299c2f1SGregory Neil Shapiro 	{
2933299c2f1SGregory Neil Shapiro 		if (colon != NULL)
2943299c2f1SGregory Neil Shapiro 			*colon = ':';
29512ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
29612ed1c7cSGregory Neil Shapiro 		    "praliases: illegal alias specification: %s\n", filename);
2973299c2f1SGregory Neil Shapiro 		goto fatal;
2983299c2f1SGregory Neil Shapiro 	}
2993299c2f1SGregory Neil Shapiro 
3003299c2f1SGregory Neil Shapiro 	memset(&params, '\0', sizeof params);
3013299c2f1SGregory Neil Shapiro 	params.smdbp_cache_size = 1024 * 1024;
3023299c2f1SGregory Neil Shapiro 
3033299c2f1SGregory Neil Shapiro 	user_info.smdbu_id = RunAsUid;
3043299c2f1SGregory Neil Shapiro 	user_info.smdbu_group_id = RunAsGid;
30512ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
30612ed1c7cSGregory Neil Shapiro 			  SMDB_MAX_USER_NAME_LEN);
3073299c2f1SGregory Neil Shapiro 
3083299c2f1SGregory Neil Shapiro 	result = smdb_open_database(&database, db_name, O_RDONLY, 0,
3093299c2f1SGregory Neil Shapiro 				    SFF_ROOTOK, db_type, &user_info, &params);
3103299c2f1SGregory Neil Shapiro 	if (result != SMDBE_OK)
3113299c2f1SGregory Neil Shapiro 	{
31212ed1c7cSGregory Neil Shapiro 		sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
31312ed1c7cSGregory Neil Shapiro 			      "praliases: %s: open: %s\n",
31412ed1c7cSGregory Neil Shapiro 			      db_name, sm_errstring(result));
3153299c2f1SGregory Neil Shapiro 		goto fatal;
3163299c2f1SGregory Neil Shapiro 	}
3173299c2f1SGregory Neil Shapiro 
3183299c2f1SGregory Neil Shapiro 	if (argc == 0)
3193299c2f1SGregory Neil Shapiro 	{
3203299c2f1SGregory Neil Shapiro 		memset(&db_key, '\0', sizeof db_key);
3213299c2f1SGregory Neil Shapiro 		memset(&db_value, '\0', sizeof db_value);
3223299c2f1SGregory Neil Shapiro 
3233299c2f1SGregory Neil Shapiro 		result = database->smdb_cursor(database, &cursor, 0);
3243299c2f1SGregory Neil Shapiro 		if (result != SMDBE_OK)
3253299c2f1SGregory Neil Shapiro 		{
32612ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
32712ed1c7cSGregory Neil Shapiro 			    "praliases: %s: set cursor: %s\n", db_name,
32812ed1c7cSGregory Neil Shapiro 			    sm_errstring(result));
3293299c2f1SGregory Neil Shapiro 			goto fatal;
3303299c2f1SGregory Neil Shapiro 		}
3313299c2f1SGregory Neil Shapiro 
3323299c2f1SGregory Neil Shapiro 		while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
3333299c2f1SGregory Neil Shapiro 						   SMDB_CURSOR_GET_NEXT)) ==
3343299c2f1SGregory Neil Shapiro 						   SMDBE_OK)
3353299c2f1SGregory Neil Shapiro 		{
3363299c2f1SGregory Neil Shapiro #if 0
3373299c2f1SGregory Neil Shapiro 			/* skip magic @:@ entry */
338c46d91b7SGregory Neil Shapiro 			if (db_key.size == 2 &&
339c46d91b7SGregory Neil Shapiro 			    db_key.data[0] == '@' &&
340c46d91b7SGregory Neil Shapiro 			    db_key.data[1] == '\0' &&
341c46d91b7SGregory Neil Shapiro 			    db_value.size == 2 &&
342c46d91b7SGregory Neil Shapiro 			    db_value.data[0] == '@' &&
343c46d91b7SGregory Neil Shapiro 			    db_value.data[1] == '\0')
3443299c2f1SGregory Neil Shapiro 				continue;
3453299c2f1SGregory Neil Shapiro #endif /* 0 */
3463299c2f1SGregory Neil Shapiro 
34712ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
34812ed1c7cSGregory Neil Shapiro 					     "%.*s:%.*s\n",
349c46d91b7SGregory Neil Shapiro 					     (int) db_key.size,
350c46d91b7SGregory Neil Shapiro 					     (char *) db_key.data,
351c46d91b7SGregory Neil Shapiro 					     (int) db_value.size,
352c46d91b7SGregory Neil Shapiro 					     (char *) db_value.data);
3533299c2f1SGregory Neil Shapiro 		}
3543299c2f1SGregory Neil Shapiro 
3553299c2f1SGregory Neil Shapiro 		if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
3563299c2f1SGregory Neil Shapiro 		{
35712ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
3583299c2f1SGregory Neil Shapiro 				"praliases: %s: get value at cursor: %s\n",
35912ed1c7cSGregory Neil Shapiro 				db_name, sm_errstring(result));
3603299c2f1SGregory Neil Shapiro 			goto fatal;
361c2aa98e2SPeter Wemm 		}
362c2aa98e2SPeter Wemm 	}
3633299c2f1SGregory Neil Shapiro 	else for (; *argv != NULL; ++argv)
36476b7bf71SPeter Wemm 	{
365c0c4794dSGregory Neil Shapiro 		int get_res;
366c0c4794dSGregory Neil Shapiro 
3673299c2f1SGregory Neil Shapiro 		memset(&db_key, '\0', sizeof db_key);
3683299c2f1SGregory Neil Shapiro 		memset(&db_value, '\0', sizeof db_value);
369c46d91b7SGregory Neil Shapiro 		db_key.data = *argv;
370c0c4794dSGregory Neil Shapiro 		db_key.size = strlen(*argv);
371c0c4794dSGregory Neil Shapiro 		get_res = database->smdb_get(database, &db_key, &db_value, 0);
372c0c4794dSGregory Neil Shapiro 		if (get_res == SMDBE_NOT_FOUND)
373c0c4794dSGregory Neil Shapiro 		{
374c0c4794dSGregory Neil Shapiro 			db_key.size++;
375c0c4794dSGregory Neil Shapiro 			get_res = database->smdb_get(database, &db_key,
376c0c4794dSGregory Neil Shapiro 						     &db_value, 0);
377c0c4794dSGregory Neil Shapiro 		}
378c0c4794dSGregory Neil Shapiro 		if (get_res == SMDBE_OK)
3793299c2f1SGregory Neil Shapiro 		{
38012ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
38112ed1c7cSGregory Neil Shapiro 					     "%.*s:%.*s\n",
382c46d91b7SGregory Neil Shapiro 					     (int) db_key.size,
383c46d91b7SGregory Neil Shapiro 					     (char *) db_key.data,
384c46d91b7SGregory Neil Shapiro 					     (int) db_value.size,
385c46d91b7SGregory Neil Shapiro 					     (char *) db_value.data);
386c2aa98e2SPeter Wemm 		}
38776b7bf71SPeter Wemm 		else
38812ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
38912ed1c7cSGregory Neil Shapiro 					     "%s: No such key\n",
39012ed1c7cSGregory Neil Shapiro 					     (char *)db_key.data);
39176b7bf71SPeter Wemm 	}
39276b7bf71SPeter Wemm 
3933299c2f1SGregory Neil Shapiro  fatal:
3943299c2f1SGregory Neil Shapiro 	if (cursor != NULL)
3953299c2f1SGregory Neil Shapiro 		(void) cursor->smdbc_close(cursor);
3963299c2f1SGregory Neil Shapiro 	if (database != NULL)
3973299c2f1SGregory Neil Shapiro 		(void) database->smdb_close(database);
3983299c2f1SGregory Neil Shapiro 	if (colon != NULL)
3993299c2f1SGregory Neil Shapiro 		*colon = ':';
4003299c2f1SGregory Neil Shapiro 	return;
401c2aa98e2SPeter Wemm }
402