ctdlload: import room records
authorArt Cancro <ajc@citadel.org>
Mon, 17 Jul 2023 03:01:53 +0000 (18:01 -0900)
committerArt Cancro <ajc@citadel.org>
Mon, 17 Jul 2023 03:01:53 +0000 (18:01 -0900)
citadel/utils/ctdlload.c

index 6ddf69c22a5752978b115f40a759e1727f56c6cb..e4b67762714197b0f059ce8af19b4b96fdb19ca6 100644 (file)
@@ -49,14 +49,21 @@ DB_ENV *open_dbenv(char *dirname) {
        int i;
        u_int32_t flags = 0;
        int dbversion_major, dbversion_minor, dbversion_patch;
+       db_version(&dbversion_major, &dbversion_minor, &dbversion_patch);
 
        // Create synthetic integer version numbers and compare them.
-       // Never run with a libdb older than the one with which it was compiled.
+       // Never run with a libdb other than the one with which it was compiled.
        int compiled_db_version = ( (DB_VERSION_MAJOR * 1000000) + (DB_VERSION_MINOR * 1000) + (DB_VERSION_PATCH) );
        int linked_db_version = ( (dbversion_major * 1000000) + (dbversion_minor * 1000) + (dbversion_patch) );
-       if (compiled_db_version > linked_db_version) {
-               fprintf(stderr, "db: ctdlload is running with a version of libdb older than the one with which it was compiled.\n"
-                       "db: This is an invalid configuration.  ctdlload will now exit to prevent data loss.");
+       if (compiled_db_version != linked_db_version) {
+               fprintf(stderr,
+                       "db: ctdlload is running with a version of libdb other than the one with which it was compiled.\n"
+                       "db: compiled: %d\n"
+                       "db:   linked: %d\n"
+                       "db: This is an invalid configuration.  ctdlload will now exit to prevent data loss.",
+                       compiled_db_version,
+                       linked_db_version
+               );
                exit(CTDLEXIT_DB);
        }
 
@@ -160,7 +167,7 @@ int convert_msgmeta(char *line, DBT *out_key, DBT *out_data) {
 }
 
 
-// Convert a "user" record to a record on disk.  NOT THREADSAFE
+// Convert a "user" record to a record on disk.  (Source string is unusable after this function is called.)
 int convert_user(char *line, DBT *out_key, DBT *out_data) {
        char userkey[USERNAME_SIZE];
        char *token;
@@ -225,6 +232,107 @@ int convert_user(char *line, DBT *out_key, DBT *out_data) {
 }
 
 
+// Convert a "room" record to a record on disk.  (Source string is unusable after this function is called.)
+int convert_room(char *line, DBT *out_key, DBT *out_data) {
+       char *token;
+       struct ctdlroom *r = malloc(sizeof(struct ctdlroom));
+
+       memset(r, 0, sizeof(struct ctdlroom));
+       char *p = line;
+
+       for (int i=0; (token = strsep(&p, "|")); ++i) {
+               switch(i) {
+                       case 1:
+                               strncpy(r->QRname, token, sizeof(r->QRname));
+                               break;
+                       case 2:
+                               strncpy(r->QRpasswd, token, sizeof (r->QRpasswd));
+                               break;
+                       case 3:
+                               r->QRroomaide = atol(token);
+                               break;
+                       case 4:
+                               r->QRhighest = atol(token);
+                               break;
+                       case 5:
+                               r->QRgen = atol(token);
+                               break;
+                       case 6:
+                               r->QRflags = atoi(token);
+                               break;
+                       case 7:
+                               strncpy(r->QRdirname, token, sizeof(r->QRdirname));
+                               break;
+                       case 8:
+                               r->msgnum_info = atol(token);
+                               break;
+                       case 9:
+                               r->QRfloor = atoi(token);
+                               break;
+                       case 10:
+                               r->QRmtime = atol(token);
+                               break;
+                       case 11:
+                               r->QRep.expire_mode = atoi(token);
+                               break;
+                       case 12:
+                               r->QRep.expire_value = atoi(token);
+                               break;
+                       case 13:
+                               r->QRnumber = atol(token);
+                               break;
+                       case 14:
+                               r->QRorder = atoi(token);
+                               break;
+                       case 15:
+                               r->QRflags2 = atoi(token);
+                               break;
+                       case 16:
+                               r->QRdefaultview = atoi(token);
+                               break;
+                       case 17:
+                               r->msgnum_pic = atol(token);
+                               break;
+               }
+       }
+
+       // The key is the room name in all lower case
+       out_key->size = strlen(r->QRname);
+       out_key->data = strdup(r->QRname);
+       char *k = (char *)out_key->data;
+       for (int i=0; i<=out_key->size; ++i) {
+               k[i] = tolower(k[i]);
+       }
+
+       out_data->size = sizeof(struct ctdlroom);
+       out_data->data = r;
+       return(1);
+}
+
+
+#if 0
+// Convert a "foo" record to a record on disk.
+int convert_oom(char *line, DBT *out_key, DBT *out_data) {
+       char *token;
+       struct ctdloom *r = malloc(sizeof(struct ctdloom));
+
+       memset(r, 0, sizeof(struct ctdloom));
+       char *p = line;
+
+       for (int i=0; (token = strsep(&p, "|")); ++i) {
+               switch(i) {
+               }
+       }
+
+       out_key->size = strlen(r->QRname);
+       out_key->data = strdup(r->QRname);
+       out_data->size = sizeof(struct ctdloom);
+       out_data->data = r;
+       return(0);
+}
+#endif
+
+
 // Ingest one line of dump data.  NOT REENTRANT
 void ingest_one(char *line, DB_ENV *dst_dbenv) {
 
@@ -242,6 +350,11 @@ void ingest_one(char *line, DB_ENV *dst_dbenv) {
        // We are assuming that the lines of the dump file will generally be sorted by table.
        // By remembering the last table we worked with, we can do close/open if the table changes.
 
+       if (current_cdb >= 0) {
+               fprintf(stderr, "   \033[33m%02x \033[32m%9d \033[31m%8d\033[0m\r", current_cdb, good_rows, bad_rows);
+               fflush(stderr);
+       }
+
        // Identify the record type we are currently working with
        extract_token(record_type, line, 0, '|', sizeof record_type);
        if (!strcasecmp(record_type, "msgtext"))                current_cdb = CDB_MSGMAIN;
@@ -260,15 +373,15 @@ void ingest_one(char *line, DB_ENV *dst_dbenv) {
        else                                                    current_cdb = -1 ;
 
        if (current_cdb != previous_cdb) {
+               if (previous_cdb >= 0) {
+                       fprintf(stderr, "\n");
+               }
                if (previous_cdb >= 0) {
                        ret = dst_dbp->close(dst_dbp, 0);
                        if (ret) {
                                fprintf(stderr, "db: db_close: %s\n", db_strerror(ret));
                        }
                }
-               if (previous_cdb > 0) {
-                       fprintf(stderr, "\n");
-               }
 
                if (current_cdb >= 0) {
                        good_rows = 0;
@@ -302,7 +415,7 @@ void ingest_one(char *line, DB_ENV *dst_dbenv) {
        if      (!strcasecmp(record_type, "msgtext"))           row_was_good = convert_msgtext(line, &out_key, &out_data);
        else if (!strcasecmp(record_type, "msgmeta"))           row_was_good = convert_msgmeta(line, &out_key, &out_data);
        else if (!strcasecmp(record_type, "user"))              row_was_good = convert_user(line, &out_key, &out_data);
-       else if (!strcasecmp(record_type, "room"))              row_was_good = convert_foo(line, &out_key, &out_data);
+       else if (!strcasecmp(record_type, "room"))              row_was_good = convert_room(line, &out_key, &out_data);
        else if (!strcasecmp(record_type, "floor"))             row_was_good = convert_foo(line, &out_key, &out_data);
        else if (!strcasecmp(record_type, "msglist"))           row_was_good = convert_foo(line, &out_key, &out_data);
        else if (!strcasecmp(record_type, "visit"))             row_was_good = convert_foo(line, &out_key, &out_data);
@@ -328,11 +441,6 @@ void ingest_one(char *line, DB_ENV *dst_dbenv) {
 
        free(out_key.data);
        free(out_data.data);
-
-       if (current_cdb > 0) {
-               fprintf(stderr, "   %02x %9d %8d\r", current_cdb, good_rows, bad_rows);
-               fflush(stderr);
-       }
 }
 
 
@@ -343,8 +451,7 @@ void ingest(DB_ENV *dst_dbenv) {
        static size_t line_len = 0;
        char ch;
 
-       fprintf(stderr, "table good_rows bad_rows\n");
-       fprintf(stderr, "----- --------- --------\n");
+       fprintf(stderr, "\033[7mtable\033[0m \033[7mgood_rows\033[0m \033[7mbad_rows\033[0m\n");
        line = reallok(NULL, line_alloc);
 
        do {