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(¶ms, '\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, ¶ms); 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