1 // Attempt to convert your database from 32-bit to 64-bit.
2 // Don't run this. It doesn't work and if you try to run it you will immediately die.
4 // Copyright (c) 2023 by the citadel.org team
6 // This program is open source software. Use, duplication, or disclosure
7 // is subject to the terms of the GNU General Public License, version 3.
14 #include <sys/types.h>
15 #include <sys/socket.h>
23 #include <libcitadel.h>
26 #include "../server/sysdep.h"
27 #include "../server/citadel_defs.h"
28 #include "../server/server.h"
29 #include "../server/citadel_dirs.h"
30 #include "ctdl3264_structs.h"
32 static DB_ENV *dbenv; // The DB environment (global)
34 // Open the various databases we'll be using. Any database which
35 // does not exist should be created. Note that we don't need a
36 // critical section here, because there aren't any active threads
37 // manipulating the database yet.
38 void open_databases(void) {
42 int dbversion_major, dbversion_minor, dbversion_patch;
44 printf( "db: open_databases() starting\n"
45 "db: Linked zlib: %s\n"
46 "db: Compiled libdb: %s\n"
47 "db: Linked libdb: %s\n",
50 db_version(&dbversion_major, &dbversion_minor, &dbversion_patch)
53 // Create synthetic integer version numbers and compare them.
54 // Never allow citserver to run with a libdb older then the one with which it was compiled.
55 int compiled_db_version = ( (DB_VERSION_MAJOR * 1000000) + (DB_VERSION_MINOR * 1000) + (DB_VERSION_PATCH) );
56 int linked_db_version = ( (dbversion_major * 1000000) + (dbversion_minor * 1000) + (dbversion_patch) );
57 if (compiled_db_version > linked_db_version) {
58 printf( "db: citserver is running with a version of libdb older than the one with which it was compiled.\n"
59 "db: This is an invalid configuration. citserver will now exit to prevent data loss.");
63 printf("db: Setting up DB environment\n");
64 ret = db_env_create(&dbenv, 0);
66 printf("db: db_env_create: %s\n", db_strerror(ret));
67 printf("db: exit code %d\n", ret);
71 // We want to specify the shared memory buffer pool cachesize, but everything else is the default.
72 ret = dbenv->set_cachesize(dbenv, 0, 64 * 1024, 0);
74 printf("db: set_cachesize: %s\n", db_strerror(ret));
75 dbenv->close(dbenv, 0);
76 printf("db: exit code %d\n", ret);
80 if ((ret = dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT))) {
81 printf("db: set_lk_detect: %s\n", db_strerror(ret));
82 dbenv->close(dbenv, 0);
83 printf("db: exit code %d\n", ret);
87 flags = DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_INIT_TXN | DB_INIT_LOCK | DB_THREAD | DB_INIT_LOG;
88 printf("db: dbenv->open(dbenv, %s, %d, 0)\n", ctdl_db_dir, flags);
89 ret = dbenv->open(dbenv, ctdl_db_dir, flags, 0); // try opening the database cleanly
90 if (ret == DB_RUNRECOVERY) {
91 printf("db: dbenv->open: %s\n", db_strerror(ret));
92 printf("db: attempting recovery...\n");
94 ret = dbenv->open(dbenv, ctdl_db_dir, flags, 0); // try recovery
96 if (ret == DB_RUNRECOVERY) {
97 printf("db: dbenv->open: %s\n", db_strerror(ret));
98 printf("db: attempting catastrophic recovery...\n");
100 flags |= DB_RECOVER_FATAL;
101 ret = dbenv->open(dbenv, ctdl_db_dir, flags, 0); // try catastrophic recovery
104 printf("db: dbenv->open: %s\n", db_strerror(ret));
105 dbenv->close(dbenv, 0);
106 printf("db: exit code %d\n", ret);
115 // Close all of the db database files we've opened. This can be done in a loop, since it's just a bunch of closes.
116 void close_databases(void) {
120 //syslog(LOG_INFO, "db: performing final checkpoint");
121 //if ((ret = dbenv->txn_checkpoint(dbenv, 0, 0, 0))) {
122 //syslog(LOG_ERR, "db: txn_checkpoint: %s", db_strerror(ret));
126 ret = dbenv->close(dbenv, 0);
128 printf("db: DBENV->close: %s\n", db_strerror(ret));
133 void null_function(void) {
134 printf("FIXME null_function() called which means we have more work to do!\n");
138 void (*convert_functions[])(void) = {
139 null_function, // CDB_MSGMAIN
140 null_function, // CDB_USERS
141 null_function, // CDB_ROOMS
142 null_function, // CDB_FLOORTAB
143 null_function, // CDB_MSGLISTS
144 null_function, // CDB_VISIT
145 null_function, // CDB_DIRECTORY
146 null_function, // CDB_USETABLE
147 null_function, // CDB_BIGMSGS
148 null_function, // CDB_FULLTEXT
149 null_function, // CDB_EUIDINDEX
150 null_function, // CDB_USERSBYNUMBER
151 null_function, // CDB_EXTAUTH
152 null_function // CDB_CONFIG
156 void convert_table(int which_cdb) {
160 printf("Converting table %d\n", which_cdb);
162 // Begin by opening the database (table)
164 DB *dbp; // One DB handle for one Citadel database
165 printf("\033[33m\033[1mdb: opening database %02x\033[0m\n", which_cdb);
166 ret = db_create(&dbp, dbenv, 0); // Create a database handle
168 printf("db: db_create: %s\n", db_strerror(ret));
169 printf("db: exit code %d\n", ret);
173 snprintf(dbfilename, sizeof dbfilename, "cdb.%02x", which_cdb); // table names by number
174 ret = dbp->open(dbp, NULL, dbfilename, NULL, DB_BTREE, DB_AUTO_COMMIT, 0600);
176 printf("db: db_open[%02x]: %s\n", which_cdb, db_strerror(ret));
178 printf("db: You may need to tune your database; please check http://www.citadel.org for more information.\n");
180 printf("db: exit code %d\n", ret);
184 // Call the convert function (this will need some parameters later)
185 convert_functions[which_cdb]();
188 printf("\033[33m\033[1mdb: flushing the database logs\033[0m\n");
189 if ((ret = dbenv->log_flush(dbenv, NULL))) {
190 printf("db: log_flush: %s\n", db_strerror(ret));
193 // ...and close the database (table)
194 printf("\033[33m\033[1mdb: closing database %02x\033[0m\n", which_cdb);
195 ret = dbp->close(dbp, 0);
197 printf("db: db_close: %s\n", db_strerror(ret));
203 int main(int argc, char **argv) {
204 char ctdldir[PATH_MAX]=CTDLDIR;
206 // Check to make sure we're running on the target 64-bit system
207 if (sizeof(void *) != 8) {
208 fprintf(stderr, "%s: this is a %ld-bit system.\n", argv[0], sizeof(void *)*8);
209 fprintf(stderr, "%s: you must run this on a 64-bit system, onto which a 32-bit database has been copied.\n", argv[0]);
213 // Parse command line
215 while ((a = getopt(argc, argv, "h:")) != EOF) {
218 strncpy(ctdldir, optarg, sizeof ctdldir);
221 fprintf(stderr, "%s: usage: %s [-h server_dir]\n", argv[0], argv[0]);
227 for (int i = 0; i < MAXCDB; ++i) {