diff -p -up postfix-2.7.0/src/postmap/postmap.c.dbupgrade postfix-2.7.0/src/postmap/postmap.c --- postfix-2.7.0/src/postmap/postmap.c.dbupgrade 2009-04-17 20:04:00.000000000 +0000 +++ postfix-2.7.0/src/postmap/postmap.c 2010-02-20 11:10:32.040323376 +0000 @@ -5,7 +5,7 @@ /* Postfix lookup table management /* SYNOPSIS /* .fi -/* \fBpostmap\fR [\fB-Nbfhimnoprsvw\fR] [\fB-c \fIconfig_dir\fR] +/* \fBpostmap\fR [\fB-Nbfhimnoprsuvw\fR] [\fB-c \fIconfig_dir\fR] /* [\fB-d \fIkey\fR] [\fB-q \fIkey\fR] /* [\fIfile_type\fR:]\fIfile_name\fR ... /* DESCRIPTION @@ -151,6 +151,8 @@ /* .sp /* This feature is available in Postfix version 2.2 and later, /* and is not available for all database types. +/* .IP \fB-u\fR +/* Upgrade the database to the current version. /* .IP \fB-v\fR /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR /* options make the software increasingly verbose. @@ -723,11 +725,23 @@ static void postmap_seq(const char *map_ dict_close(dict); } +/* postmap_upgrade - upgrade a map */ + +static int postmap_upgrade(const char *map_type, const char *map_name) +{ + DICT *dict; + + dict = dict_open3(map_type, map_name, O_RDWR, + DICT_FLAG_LOCK|DICT_FLAG_UPGRADE); + dict_close(dict); + return (dict != 0); +} + /* usage - explain */ static NORETURN usage(char *myname) { - msg_fatal("usage: %s [-Nfinoprsvw] [-c config_dir] [-d key] [-q key] [map_type:]file...", + msg_fatal("usage: %s [-Nfhimnoprsuvw] [-c config_dir] [-d key] [-q key] [map_type:]file...", myname); } @@ -743,6 +757,7 @@ int main(int argc, char **argv) int postmap_flags = POSTMAP_FLAG_AS_OWNER | POSTMAP_FLAG_SAVE_PERM; int open_flags = O_RDWR | O_CREAT | O_TRUNC; int dict_flags = DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX; + int upgrade = 0; char *query = 0; char *delkey = 0; int sequence = 0; @@ -787,7 +802,7 @@ int main(int argc, char **argv) /* * Parse JCL. */ - while ((ch = GETOPT(argc, argv, "Nbc:d:fhimnopq:rsvw")) > 0) { + while ((ch = GETOPT(argc, argv, "Nbc:d:fhimnopq:rsuvw")) > 0) { switch (ch) { default: usage(argv[0]); @@ -804,8 +819,8 @@ int main(int argc, char **argv) msg_fatal("out of memory"); break; case 'd': - if (sequence || query || delkey) - msg_fatal("specify only one of -s -q or -d"); + if (sequence || query || delkey || upgrade) + msg_fatal("specify only one of -s -q -u or -d"); delkey = optarg; break; case 'f': @@ -831,8 +846,8 @@ int main(int argc, char **argv) postmap_flags &= ~POSTMAP_FLAG_SAVE_PERM; break; case 'q': - if (sequence || query || delkey) - msg_fatal("specify only one of -s -q or -d"); + if (sequence || query || delkey || upgrade) + msg_fatal("specify only one of -s -q -u or -d"); query = optarg; break; case 'r': @@ -840,10 +855,15 @@ int main(int argc, char **argv) dict_flags |= DICT_FLAG_DUP_REPLACE; break; case 's': - if (query || delkey) - msg_fatal("specify only one of -s or -q or -d"); + if (query || delkey || upgrade) + msg_fatal("specify only one of -s or -q -u or -d"); sequence = 1; break; + case 'u': + if (sequence || query || delkey || upgrade) + msg_fatal("specify only one of -s -q -u or -d"); + upgrade=1; + break; case 'v': msg_verbose++; break; @@ -914,6 +934,21 @@ int main(int argc, char **argv) exit(0); } exit(1); + } else if (upgrade) { /* Upgrade the map(s) */ + int success = 1; + if (optind + 1 > argc) + usage(argv[0]); + while (optind < argc) { + if ((path_name = split_at(argv[optind], ':')) != 0) { + success &= postmap_upgrade(argv[optind], path_name); + } else { + success &= postmap_upgrade(var_db_type, argv[optind]); + } + if (!success) + exit(1); + optind++; + } + exit(0); } else { /* create/update map(s) */ if (optind + 1 > argc) usage(argv[0]); diff -p -up postfix-2.7.0/src/util/dict.h.dbupgrade postfix-2.7.0/src/util/dict.h --- postfix-2.7.0/src/util/dict.h.dbupgrade 2007-12-03 19:42:26.000000000 +0000 +++ postfix-2.7.0/src/util/dict.h 2010-02-20 11:10:32.040323376 +0000 @@ -66,6 +66,7 @@ extern DICT *dict_debug(DICT *); #define DICT_FLAG_NO_UNAUTH (1<<13) /* disallow unauthenticated data */ #define DICT_FLAG_FOLD_FIX (1<<14) /* case-fold key with fixed-case map */ #define DICT_FLAG_FOLD_MUL (1<<15) /* case-fold key with multi-case map */ +#define DICT_FLAG_UPGRADE (1<<30) /* Upgrade the db */ #define DICT_FLAG_FOLD_ANY (DICT_FLAG_FOLD_FIX | DICT_FLAG_FOLD_MUL) /* IMPORTANT: Update the dict_mask[] table when the above changes */ diff -p -up postfix-2.7.0/src/util/dict_db.c.dbupgrade postfix-2.7.0/src/util/dict_db.c --- postfix-2.7.0/src/util/dict_db.c.dbupgrade 2010-01-02 22:28:08.000000000 +0100 +++ postfix-2.7.0/src/util/dict_db.c 2010-02-20 15:51:14.850299909 +0100 @@ -675,6 +675,12 @@ static DICT *dict_db_open(const char *cl msg_fatal("set DB cache size %d: %m", dict_db_cache_size); if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0) msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM); + if (dict_flags & DICT_FLAG_UPGRADE) { + if (msg_verbose) + msg_info("upgrading database %s",db_path); + if ((errno = db->upgrade(db,db_path,0)) != 0) + msg_fatal("upgrade of database %s: %m",db_path); + } #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0) if ((errno = db->open(db, 0, db_path, 0, type, db_flags, 0644)) != 0) msg_fatal("open database %s: %m", db_path); diff -p -up postfix-2.7.0/src/util/dict_dbm.c.dbupgrade postfix-2.7.0/src/util/dict_dbm.c --- postfix-2.7.0/src/util/dict_dbm.c.dbupgrade 2009-12-24 23:53:04.000000000 +0100 +++ postfix-2.7.0/src/util/dict_dbm.c 2010-02-20 15:51:14.850299909 +0100 @@ -409,6 +409,10 @@ DICT *dict_dbm_open(const char *path, char *dbm_path; int lock_fd; +#ifdef HAVE_GDBM + msg_fatal("%s: gdbm maps use locking that is incompatible with postfix. Use a hash map instead.", + path); +#endif /* * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in * the time domain) locking while accessing individual database records.