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