xref: /titanic_50/usr/src/cmd/sendmail/aux/praliases.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
3*7c478bd9Sstevel@tonic-gate  *	All rights reserved.
4*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1983 Eric P. Allman.  All rights reserved.
5*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1988, 1993
6*7c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
7*7c478bd9Sstevel@tonic-gate  *
8*7c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
9*7c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
10*7c478bd9Sstevel@tonic-gate  * the sendmail distribution.
11*7c478bd9Sstevel@tonic-gate  *
12*7c478bd9Sstevel@tonic-gate  */
13*7c478bd9Sstevel@tonic-gate 
14*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
15*7c478bd9Sstevel@tonic-gate 
16*7c478bd9Sstevel@tonic-gate #include <sm/gen.h>
17*7c478bd9Sstevel@tonic-gate 
18*7c478bd9Sstevel@tonic-gate SM_IDSTR(copyright,
19*7c478bd9Sstevel@tonic-gate "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
20*7c478bd9Sstevel@tonic-gate 	All rights reserved.\n\
21*7c478bd9Sstevel@tonic-gate      Copyright (c) 1983 Eric P. Allman.  All rights reserved.\n\
22*7c478bd9Sstevel@tonic-gate      Copyright (c) 1988, 1993\n\
23*7c478bd9Sstevel@tonic-gate 	The Regents of the University of California.  All rights reserved.\n")
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.91 2001/03/29 21:15:53 rodney Exp $")
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
28*7c478bd9Sstevel@tonic-gate #include <ctype.h>
29*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
30*7c478bd9Sstevel@tonic-gate #include <unistd.h>
31*7c478bd9Sstevel@tonic-gate #ifdef EX_OK
32*7c478bd9Sstevel@tonic-gate # undef EX_OK		/* unistd.h may have another use for this */
33*7c478bd9Sstevel@tonic-gate #endif /* EX_OK */
34*7c478bd9Sstevel@tonic-gate #include <sysexits.h>
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate #ifndef NOT_SENDMAIL
38*7c478bd9Sstevel@tonic-gate # define NOT_SENDMAIL
39*7c478bd9Sstevel@tonic-gate #endif /* ! NOT_SENDMAIL */
40*7c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h>
41*7c478bd9Sstevel@tonic-gate #include <sendmail/pathnames.h>
42*7c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h>
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate static void praliases __P((char *, int, char **));
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate uid_t	RealUid;
47*7c478bd9Sstevel@tonic-gate gid_t	RealGid;
48*7c478bd9Sstevel@tonic-gate char	*RealUserName;
49*7c478bd9Sstevel@tonic-gate uid_t	RunAsUid;
50*7c478bd9Sstevel@tonic-gate uid_t	RunAsGid;
51*7c478bd9Sstevel@tonic-gate char	*RunAsUserName;
52*7c478bd9Sstevel@tonic-gate int	Verbose = 2;
53*7c478bd9Sstevel@tonic-gate bool	DontInitGroups = false;
54*7c478bd9Sstevel@tonic-gate uid_t	TrustedUid = 0;
55*7c478bd9Sstevel@tonic-gate BITMAP256 DontBlameSendmail;
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate # define DELIMITERS		" ,/"
58*7c478bd9Sstevel@tonic-gate # define PATH_SEPARATOR		':'
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate int
61*7c478bd9Sstevel@tonic-gate main(argc, argv)
62*7c478bd9Sstevel@tonic-gate 	int argc;
63*7c478bd9Sstevel@tonic-gate 	char **argv;
64*7c478bd9Sstevel@tonic-gate {
65*7c478bd9Sstevel@tonic-gate 	char *cfile;
66*7c478bd9Sstevel@tonic-gate 	char *filename = NULL;
67*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *cfp;
68*7c478bd9Sstevel@tonic-gate 	int ch;
69*7c478bd9Sstevel@tonic-gate 	char afilebuf[MAXLINE];
70*7c478bd9Sstevel@tonic-gate 	char buf[MAXLINE];
71*7c478bd9Sstevel@tonic-gate 	struct passwd *pw;
72*7c478bd9Sstevel@tonic-gate 	static char rnamebuf[MAXNAME];
73*7c478bd9Sstevel@tonic-gate 	extern char *optarg;
74*7c478bd9Sstevel@tonic-gate 	extern int optind;
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate 	clrbitmap(DontBlameSendmail);
77*7c478bd9Sstevel@tonic-gate 	RunAsUid = RealUid = getuid();
78*7c478bd9Sstevel@tonic-gate 	RunAsGid = RealGid = getgid();
79*7c478bd9Sstevel@tonic-gate 	pw = getpwuid(RealUid);
80*7c478bd9Sstevel@tonic-gate 	if (pw != NULL)
81*7c478bd9Sstevel@tonic-gate 	{
82*7c478bd9Sstevel@tonic-gate 		if (strlen(pw->pw_name) > MAXNAME - 1)
83*7c478bd9Sstevel@tonic-gate 			pw->pw_name[MAXNAME] = 0;
84*7c478bd9Sstevel@tonic-gate 		sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
85*7c478bd9Sstevel@tonic-gate 	}
86*7c478bd9Sstevel@tonic-gate 	else
87*7c478bd9Sstevel@tonic-gate 		(void) sm_snprintf(rnamebuf, sizeof rnamebuf,
88*7c478bd9Sstevel@tonic-gate 		    "Unknown UID %d", (int) RealUid);
89*7c478bd9Sstevel@tonic-gate 	RunAsUserName = RealUserName = rnamebuf;
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate 	cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
92*7c478bd9Sstevel@tonic-gate 	while ((ch = getopt(argc, argv, "C:f:")) != -1)
93*7c478bd9Sstevel@tonic-gate 	{
94*7c478bd9Sstevel@tonic-gate 		switch ((char)ch) {
95*7c478bd9Sstevel@tonic-gate 		case 'C':
96*7c478bd9Sstevel@tonic-gate 			cfile = optarg;
97*7c478bd9Sstevel@tonic-gate 			break;
98*7c478bd9Sstevel@tonic-gate 		case 'f':
99*7c478bd9Sstevel@tonic-gate 			filename = optarg;
100*7c478bd9Sstevel@tonic-gate 			break;
101*7c478bd9Sstevel@tonic-gate 		case '?':
102*7c478bd9Sstevel@tonic-gate 		default:
103*7c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
104*7c478bd9Sstevel@tonic-gate 			    "usage: praliases [-C cffile] [-f aliasfile]\n");
105*7c478bd9Sstevel@tonic-gate 			exit(EX_USAGE);
106*7c478bd9Sstevel@tonic-gate 		}
107*7c478bd9Sstevel@tonic-gate 	}
108*7c478bd9Sstevel@tonic-gate 	argc -= optind;
109*7c478bd9Sstevel@tonic-gate 	argv += optind;
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate 	if (filename != NULL)
112*7c478bd9Sstevel@tonic-gate 	{
113*7c478bd9Sstevel@tonic-gate 		praliases(filename, argc, argv);
114*7c478bd9Sstevel@tonic-gate 		exit(EX_OK);
115*7c478bd9Sstevel@tonic-gate 	}
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate 	if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
118*7c478bd9Sstevel@tonic-gate 			      NULL)) == NULL)
119*7c478bd9Sstevel@tonic-gate 	{
120*7c478bd9Sstevel@tonic-gate 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
121*7c478bd9Sstevel@tonic-gate 				     "praliases: %s: %s\n", cfile,
122*7c478bd9Sstevel@tonic-gate 				     sm_errstring(errno));
123*7c478bd9Sstevel@tonic-gate 		exit(EX_NOINPUT);
124*7c478bd9Sstevel@tonic-gate 	}
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate 	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
127*7c478bd9Sstevel@tonic-gate 	{
128*7c478bd9Sstevel@tonic-gate 		register char *b, *p;
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 		b = strchr(buf, '\n');
131*7c478bd9Sstevel@tonic-gate 		if (b != NULL)
132*7c478bd9Sstevel@tonic-gate 			*b = '\0';
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 		b = buf;
135*7c478bd9Sstevel@tonic-gate 		switch (*b++)
136*7c478bd9Sstevel@tonic-gate 		{
137*7c478bd9Sstevel@tonic-gate 		  case 'O':		/* option -- see if alias file */
138*7c478bd9Sstevel@tonic-gate 			if (sm_strncasecmp(b, " AliasFile", 10) == 0 &&
139*7c478bd9Sstevel@tonic-gate 			    !(isascii(b[10]) && isalnum(b[10])))
140*7c478bd9Sstevel@tonic-gate 			{
141*7c478bd9Sstevel@tonic-gate 				/* new form -- find value */
142*7c478bd9Sstevel@tonic-gate 				b = strchr(b, '=');
143*7c478bd9Sstevel@tonic-gate 				if (b == NULL)
144*7c478bd9Sstevel@tonic-gate 					continue;
145*7c478bd9Sstevel@tonic-gate 				while (isascii(*++b) && isspace(*b))
146*7c478bd9Sstevel@tonic-gate 					continue;
147*7c478bd9Sstevel@tonic-gate 			}
148*7c478bd9Sstevel@tonic-gate 			else if (*b++ != 'A')
149*7c478bd9Sstevel@tonic-gate 			{
150*7c478bd9Sstevel@tonic-gate 				/* something else boring */
151*7c478bd9Sstevel@tonic-gate 				continue;
152*7c478bd9Sstevel@tonic-gate 			}
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 			/* this is the A or AliasFile option -- save it */
155*7c478bd9Sstevel@tonic-gate 			if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >=
156*7c478bd9Sstevel@tonic-gate 			    sizeof afilebuf)
157*7c478bd9Sstevel@tonic-gate 			{
158*7c478bd9Sstevel@tonic-gate 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
159*7c478bd9Sstevel@tonic-gate 				    "praliases: AliasFile filename too long: %.30s\n",
160*7c478bd9Sstevel@tonic-gate 					b);
161*7c478bd9Sstevel@tonic-gate 				(void) sm_io_close(cfp, SM_TIME_DEFAULT);
162*7c478bd9Sstevel@tonic-gate 				exit(EX_CONFIG);
163*7c478bd9Sstevel@tonic-gate 			}
164*7c478bd9Sstevel@tonic-gate 			b = afilebuf;
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate 			for (p = b; p != NULL; )
167*7c478bd9Sstevel@tonic-gate 			{
168*7c478bd9Sstevel@tonic-gate 				while (isascii(*p) && isspace(*p))
169*7c478bd9Sstevel@tonic-gate 					p++;
170*7c478bd9Sstevel@tonic-gate 				if (*p == '\0')
171*7c478bd9Sstevel@tonic-gate 					break;
172*7c478bd9Sstevel@tonic-gate 				b = p;
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate 				p = strpbrk(p, DELIMITERS);
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate 				/* find end of spec */
177*7c478bd9Sstevel@tonic-gate 				if (p != NULL)
178*7c478bd9Sstevel@tonic-gate 				{
179*7c478bd9Sstevel@tonic-gate 					bool quoted = false;
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate 					for (; *p != '\0'; p++)
182*7c478bd9Sstevel@tonic-gate 					{
183*7c478bd9Sstevel@tonic-gate 						/*
184*7c478bd9Sstevel@tonic-gate 						**  Don't break into a quoted
185*7c478bd9Sstevel@tonic-gate 						**  string.
186*7c478bd9Sstevel@tonic-gate 						*/
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 						if (*p == '"')
189*7c478bd9Sstevel@tonic-gate 							quoted = !quoted;
190*7c478bd9Sstevel@tonic-gate 						else if (*p == ',' && !quoted)
191*7c478bd9Sstevel@tonic-gate 							break;
192*7c478bd9Sstevel@tonic-gate 					}
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate 					/* No more alias specs follow */
195*7c478bd9Sstevel@tonic-gate 					if (*p == '\0')
196*7c478bd9Sstevel@tonic-gate 					{
197*7c478bd9Sstevel@tonic-gate 						/* chop trailing whitespace */
198*7c478bd9Sstevel@tonic-gate 						while (isascii(*p) &&
199*7c478bd9Sstevel@tonic-gate 						       isspace(*p) &&
200*7c478bd9Sstevel@tonic-gate 						       p > b)
201*7c478bd9Sstevel@tonic-gate 							p--;
202*7c478bd9Sstevel@tonic-gate 						*p = '\0';
203*7c478bd9Sstevel@tonic-gate 						p = NULL;
204*7c478bd9Sstevel@tonic-gate 					}
205*7c478bd9Sstevel@tonic-gate 				}
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 				if (p != NULL)
208*7c478bd9Sstevel@tonic-gate 				{
209*7c478bd9Sstevel@tonic-gate 					char *e = p - 1;
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 					/* chop trailing whitespace */
212*7c478bd9Sstevel@tonic-gate 					while (isascii(*e) &&
213*7c478bd9Sstevel@tonic-gate 					       isspace(*e) &&
214*7c478bd9Sstevel@tonic-gate 					       e > b)
215*7c478bd9Sstevel@tonic-gate 						e--;
216*7c478bd9Sstevel@tonic-gate 					*++e = '\0';
217*7c478bd9Sstevel@tonic-gate 					*p++ = '\0';
218*7c478bd9Sstevel@tonic-gate 				}
219*7c478bd9Sstevel@tonic-gate 				praliases(b, argc, argv);
220*7c478bd9Sstevel@tonic-gate 			}
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 		  default:
223*7c478bd9Sstevel@tonic-gate 			continue;
224*7c478bd9Sstevel@tonic-gate 		}
225*7c478bd9Sstevel@tonic-gate 	}
226*7c478bd9Sstevel@tonic-gate 	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
227*7c478bd9Sstevel@tonic-gate 	exit(EX_OK);
228*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
229*7c478bd9Sstevel@tonic-gate 	return EX_OK;
230*7c478bd9Sstevel@tonic-gate }
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate static void
233*7c478bd9Sstevel@tonic-gate praliases(filename, argc, argv)
234*7c478bd9Sstevel@tonic-gate 	char *filename;
235*7c478bd9Sstevel@tonic-gate 	int argc;
236*7c478bd9Sstevel@tonic-gate 	char **argv;
237*7c478bd9Sstevel@tonic-gate {
238*7c478bd9Sstevel@tonic-gate 	int result;
239*7c478bd9Sstevel@tonic-gate 	char *colon;
240*7c478bd9Sstevel@tonic-gate 	char *db_name;
241*7c478bd9Sstevel@tonic-gate 	char *db_type;
242*7c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database = NULL;
243*7c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor = NULL;
244*7c478bd9Sstevel@tonic-gate 	SMDB_DBENT db_key, db_value;
245*7c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS params;
246*7c478bd9Sstevel@tonic-gate 	SMDB_USER_INFO user_info;
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	colon = strchr(filename, PATH_SEPARATOR);
249*7c478bd9Sstevel@tonic-gate 	if (colon == NULL)
250*7c478bd9Sstevel@tonic-gate 	{
251*7c478bd9Sstevel@tonic-gate 		db_name = filename;
252*7c478bd9Sstevel@tonic-gate 		db_type = SMDB_TYPE_DEFAULT;
253*7c478bd9Sstevel@tonic-gate 	}
254*7c478bd9Sstevel@tonic-gate 	else
255*7c478bd9Sstevel@tonic-gate 	{
256*7c478bd9Sstevel@tonic-gate 		*colon = '\0';
257*7c478bd9Sstevel@tonic-gate 		db_name = colon + 1;
258*7c478bd9Sstevel@tonic-gate 		db_type = filename;
259*7c478bd9Sstevel@tonic-gate 	}
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate 	/* clean off arguments */
262*7c478bd9Sstevel@tonic-gate 	for (;;)
263*7c478bd9Sstevel@tonic-gate 	{
264*7c478bd9Sstevel@tonic-gate 		while (isascii(*db_name) && isspace(*db_name))
265*7c478bd9Sstevel@tonic-gate 			db_name++;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 		if (*db_name != '-')
268*7c478bd9Sstevel@tonic-gate 			break;
269*7c478bd9Sstevel@tonic-gate 		while (*db_name != '\0' &&
270*7c478bd9Sstevel@tonic-gate 		       !(isascii(*db_name) && isspace(*db_name)))
271*7c478bd9Sstevel@tonic-gate 			db_name++;
272*7c478bd9Sstevel@tonic-gate 	}
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate 	/* Skip non-file based DB types */
275*7c478bd9Sstevel@tonic-gate 	if (db_type != NULL && *db_type != '\0')
276*7c478bd9Sstevel@tonic-gate 	{
277*7c478bd9Sstevel@tonic-gate 		if (db_type != SMDB_TYPE_DEFAULT &&
278*7c478bd9Sstevel@tonic-gate 		    strcmp(db_type, "hash") != 0 &&
279*7c478bd9Sstevel@tonic-gate 		    strcmp(db_type, "btree") != 0 &&
280*7c478bd9Sstevel@tonic-gate 		    strcmp(db_type, "dbm") != 0)
281*7c478bd9Sstevel@tonic-gate 		{
282*7c478bd9Sstevel@tonic-gate 			sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
283*7c478bd9Sstevel@tonic-gate 				      "praliases: Skipping non-file based alias type %s\n",
284*7c478bd9Sstevel@tonic-gate 				db_type);
285*7c478bd9Sstevel@tonic-gate 			return;
286*7c478bd9Sstevel@tonic-gate 		}
287*7c478bd9Sstevel@tonic-gate 	}
288*7c478bd9Sstevel@tonic-gate 
289*7c478bd9Sstevel@tonic-gate 	if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
290*7c478bd9Sstevel@tonic-gate 	{
291*7c478bd9Sstevel@tonic-gate 		if (colon != NULL)
292*7c478bd9Sstevel@tonic-gate 			*colon = ':';
293*7c478bd9Sstevel@tonic-gate 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
294*7c478bd9Sstevel@tonic-gate 		    "praliases: illegal alias specification: %s\n", filename);
295*7c478bd9Sstevel@tonic-gate 		goto fatal;
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	memset(&params, '\0', sizeof params);
299*7c478bd9Sstevel@tonic-gate 	params.smdbp_cache_size = 1024 * 1024;
300*7c478bd9Sstevel@tonic-gate 
301*7c478bd9Sstevel@tonic-gate 	user_info.smdbu_id = RunAsUid;
302*7c478bd9Sstevel@tonic-gate 	user_info.smdbu_group_id = RunAsGid;
303*7c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
304*7c478bd9Sstevel@tonic-gate 			  SMDB_MAX_USER_NAME_LEN);
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 	result = smdb_open_database(&database, db_name, O_RDONLY, 0,
307*7c478bd9Sstevel@tonic-gate 				    SFF_ROOTOK, db_type, &user_info, &params);
308*7c478bd9Sstevel@tonic-gate 	if (result != SMDBE_OK)
309*7c478bd9Sstevel@tonic-gate 	{
310*7c478bd9Sstevel@tonic-gate 		sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
311*7c478bd9Sstevel@tonic-gate 			      "praliases: %s: open: %s\n",
312*7c478bd9Sstevel@tonic-gate 			      db_name, sm_errstring(result));
313*7c478bd9Sstevel@tonic-gate 		goto fatal;
314*7c478bd9Sstevel@tonic-gate 	}
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate 	if (argc == 0)
317*7c478bd9Sstevel@tonic-gate 	{
318*7c478bd9Sstevel@tonic-gate 		memset(&db_key, '\0', sizeof db_key);
319*7c478bd9Sstevel@tonic-gate 		memset(&db_value, '\0', sizeof db_value);
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 		result = database->smdb_cursor(database, &cursor, 0);
322*7c478bd9Sstevel@tonic-gate 		if (result != SMDBE_OK)
323*7c478bd9Sstevel@tonic-gate 		{
324*7c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
325*7c478bd9Sstevel@tonic-gate 			    "praliases: %s: set cursor: %s\n", db_name,
326*7c478bd9Sstevel@tonic-gate 			    sm_errstring(result));
327*7c478bd9Sstevel@tonic-gate 			goto fatal;
328*7c478bd9Sstevel@tonic-gate 		}
329*7c478bd9Sstevel@tonic-gate 
330*7c478bd9Sstevel@tonic-gate 		while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
331*7c478bd9Sstevel@tonic-gate 						   SMDB_CURSOR_GET_NEXT)) ==
332*7c478bd9Sstevel@tonic-gate 						   SMDBE_OK)
333*7c478bd9Sstevel@tonic-gate 		{
334*7c478bd9Sstevel@tonic-gate #if 0
335*7c478bd9Sstevel@tonic-gate 			/* skip magic @:@ entry */
336*7c478bd9Sstevel@tonic-gate 			if (db_key.size == 2 &&
337*7c478bd9Sstevel@tonic-gate 			    db_key.data[0] == '@' &&
338*7c478bd9Sstevel@tonic-gate 			    db_key.data[1] == '\0' &&
339*7c478bd9Sstevel@tonic-gate 			    db_value.size == 2 &&
340*7c478bd9Sstevel@tonic-gate 			    db_value.data[0] == '@' &&
341*7c478bd9Sstevel@tonic-gate 			    db_value.data[1] == '\0')
342*7c478bd9Sstevel@tonic-gate 				continue;
343*7c478bd9Sstevel@tonic-gate #endif /* 0 */
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
346*7c478bd9Sstevel@tonic-gate 					     "%.*s:%.*s\n",
347*7c478bd9Sstevel@tonic-gate 					     (int) db_key.size,
348*7c478bd9Sstevel@tonic-gate 					     (char *) db_key.data,
349*7c478bd9Sstevel@tonic-gate 					     (int) db_value.size,
350*7c478bd9Sstevel@tonic-gate 					     (char *) db_value.data);
351*7c478bd9Sstevel@tonic-gate 		}
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 		if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
354*7c478bd9Sstevel@tonic-gate 		{
355*7c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
356*7c478bd9Sstevel@tonic-gate 				"praliases: %s: get value at cursor: %s\n",
357*7c478bd9Sstevel@tonic-gate 				db_name, sm_errstring(result));
358*7c478bd9Sstevel@tonic-gate 			goto fatal;
359*7c478bd9Sstevel@tonic-gate 		}
360*7c478bd9Sstevel@tonic-gate 	}
361*7c478bd9Sstevel@tonic-gate 	else for (; *argv != NULL; ++argv)
362*7c478bd9Sstevel@tonic-gate 	{
363*7c478bd9Sstevel@tonic-gate 		int get_res;
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 		memset(&db_key, '\0', sizeof db_key);
366*7c478bd9Sstevel@tonic-gate 		memset(&db_value, '\0', sizeof db_value);
367*7c478bd9Sstevel@tonic-gate 		db_key.data = *argv;
368*7c478bd9Sstevel@tonic-gate 		db_key.size = strlen(*argv);
369*7c478bd9Sstevel@tonic-gate 		get_res = database->smdb_get(database, &db_key, &db_value, 0);
370*7c478bd9Sstevel@tonic-gate 		if (get_res == SMDBE_NOT_FOUND)
371*7c478bd9Sstevel@tonic-gate 		{
372*7c478bd9Sstevel@tonic-gate 			db_key.size++;
373*7c478bd9Sstevel@tonic-gate 			get_res = database->smdb_get(database, &db_key,
374*7c478bd9Sstevel@tonic-gate 						     &db_value, 0);
375*7c478bd9Sstevel@tonic-gate 		}
376*7c478bd9Sstevel@tonic-gate 		if (get_res == SMDBE_OK)
377*7c478bd9Sstevel@tonic-gate 		{
378*7c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
379*7c478bd9Sstevel@tonic-gate 					     "%.*s:%.*s\n",
380*7c478bd9Sstevel@tonic-gate 					     (int) db_key.size,
381*7c478bd9Sstevel@tonic-gate 					     (char *) db_key.data,
382*7c478bd9Sstevel@tonic-gate 					     (int) db_value.size,
383*7c478bd9Sstevel@tonic-gate 					     (char *) db_value.data);
384*7c478bd9Sstevel@tonic-gate 		}
385*7c478bd9Sstevel@tonic-gate 		else
386*7c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
387*7c478bd9Sstevel@tonic-gate 					     "%s: No such key\n",
388*7c478bd9Sstevel@tonic-gate 					     (char *)db_key.data);
389*7c478bd9Sstevel@tonic-gate 	}
390*7c478bd9Sstevel@tonic-gate 
391*7c478bd9Sstevel@tonic-gate  fatal:
392*7c478bd9Sstevel@tonic-gate 	if (cursor != NULL)
393*7c478bd9Sstevel@tonic-gate 		(void) cursor->smdbc_close(cursor);
394*7c478bd9Sstevel@tonic-gate 	if (database != NULL)
395*7c478bd9Sstevel@tonic-gate 		(void) database->smdb_close(database);
396*7c478bd9Sstevel@tonic-gate 	if (colon != NULL)
397*7c478bd9Sstevel@tonic-gate 		*colon = ':';
398*7c478bd9Sstevel@tonic-gate 	return;
399*7c478bd9Sstevel@tonic-gate }
400