X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/0cc804c87799fb5902e66d5bd537a762f786dc2a..a7e6ad0ba38cf088e841c321042f81966d846b4b:/src/src/exim_dbutil.c diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c index 1d87cec17..4d213773b 100644 --- a/src/src/exim_dbutil.c +++ b/src/src/exim_dbutil.c @@ -2,9 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2023 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This single source file is used to compile three utility programs for @@ -47,6 +48,7 @@ whose inclusion is controlled by -D on the compilation command. */ uschar *spool_directory; +BOOL keyonly = FALSE; BOOL utc = FALSE; @@ -59,6 +61,9 @@ uschar * readconf_printtime(int t) { return NULL; } gstring * +string_catn(gstring * g, const uschar * s, int count) +{ return NULL; } +gstring * string_vformat_trc(gstring * g, const uschar * func, unsigned line, unsigned size_limit, unsigned flags, const char *format, va_list ap) { return NULL; } @@ -125,30 +130,32 @@ check_args(int argc, uschar **argv, uschar *name, uschar *options) uschar * aname = argv[optind + 1]; if (argc - optind == 2) { - if (Ustrcmp(aname, "retry") == 0) return type_retry; - if (Ustrcmp(aname, "misc") == 0) return type_misc; + if (Ustrcmp(aname, "retry") == 0) return type_retry; + if (Ustrcmp(aname, "misc") == 0) return type_misc; if (Ustrncmp(aname, "wait-", 5) == 0) return type_wait; - if (Ustrcmp(aname, "callout") == 0) return type_callout; + if (Ustrcmp(aname, "callout") == 0) return type_callout; if (Ustrcmp(aname, "ratelimit") == 0) return type_ratelimit; - if (Ustrcmp(aname, "tls") == 0) return type_tls; - if (Ustrcmp(aname, "seen") == 0) return type_seen; + if (Ustrcmp(aname, "tls") == 0) return type_tls; + if (Ustrcmp(aname, "seen") == 0) return type_seen; } usage(name, options); return -1; /* Never obeyed */ } +FUNC_MAYBE_UNUSED static void -options(int argc, uschar * argv[], uschar * name) +options(int argc, uschar * argv[], uschar * name, const uschar * opts) { int opt; opterr = 0; -while ((opt = getopt(argc, (char * const *)argv, "z")) != -1) +while ((opt = getopt(argc, (char * const *)argv, CCS opts)) != -1) switch (opt) { + case 'k': keyonly = TRUE; break; case 'z': utc = TRUE; break; - default: usage(name, US" [-z]"); + default: usage(name, US" [-z] [-k]"); } } @@ -400,12 +407,13 @@ Returns: a pointer to the retrieved record, or */ void * -dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length) +dbfn_read_with_length(open_db * dbblock, const uschar * key, int * length) { -void *yield; +void * yield; EXIM_DATUM key_datum, result_datum; int klen = Ustrlen(key) + 1; uschar * key_copy = store_get(klen, key); +unsigned dlen; memcpy(key_copy, key, klen); @@ -419,9 +427,10 @@ if (!exim_dbget(dbblock->dbptr, &key_datum, &result_datum)) return NULL; /* Assume for now that anything stored could have been tainted. Properly we should store the taint status along with the data. */ -yield = store_get(exim_datum_size_get(&result_datum), GET_TAINTED); -memcpy(yield, exim_datum_data_get(&result_datum), exim_datum_size_get(&result_datum)); -if (length) *length = exim_datum_size_get(&result_datum); +dlen = exim_datum_size_get(&result_datum); +yield = store_get(dlen, GET_TAINTED); +memcpy(yield, exim_datum_data_get(&result_datum), dlen); +if (length) *length = dlen; exim_datum_free(&result_datum); /* Some DBM libs require freeing */ return yield; @@ -557,11 +566,11 @@ uschar **argv = USS cargv; uschar keybuffer[1024]; store_init(); -options(argc, argv, US"dumpdb"); +options(argc, argv, US"dumpdb", US"kz"); /* Check the arguments, and open the database */ -dbdata_type = check_args(argc, argv, US"dumpdb", US" [-z]"); +dbdata_type = check_args(argc, argv, US"dumpdb", US" [-z] [-k]"); argc -= optind; argv += optind; spool_directory = argv[0]; @@ -600,12 +609,13 @@ for (uschar * key = dbfn_scan(dbm, TRUE, &cursor); } Ustrcpy(keybuffer, key); - if (!(value = dbfn_read_with_length(dbm, keybuffer, &length))) + if (keyonly) + printf(" %s\n", keybuffer); + else if (!(value = dbfn_read_with_length(dbm, keybuffer, &length))) fprintf(stderr, "**** Entry \"%s\" was in the key scan, but the record " "was not found in the file - something is wrong!\n", CS keybuffer); else - { /* Note: don't use print_time more than once in one statement, since it uses a single buffer. */ @@ -728,7 +738,6 @@ for (uschar * key = dbfn_scan(dbm, TRUE, &cursor); printf("%s\t%s\n", keybuffer, print_time(seen->time_stamp)); break; } - } store_reset(reset_point); } @@ -784,7 +793,7 @@ rmark reset_point; uschar * aname; store_init(); -options(argc, argv, US"fixdb"); +options(argc, argv, US"fixdb", US"z"); name[0] = 0; /* No name set */ /* Sort out the database type, verify what we are working on and then process