Awesome sauce, read description below for details.
[citadel.git] / citadel / utils / ctdlload.c
index 352b468da56c95eebf9e6388eb3764809b7d4278..7eb285a38f80cf09019c92f4f9e7665c4379068b 100644 (file)
@@ -1,6 +1,6 @@
 // Load (restore) the Citadel database from a flat file created by ctdldump
 //
-// Copyright (c) 2024 by Art Cancro citadel.org
+// Copyright (c) 2023-2024 by Art Cancro citadel.org
 //
 // This program is open source software.  Use, duplication, or disclosure
 // is subject to the terms of the GNU General Public License, version 3.
@@ -71,8 +71,13 @@ int import_msgtext(char *line, struct cdbkeyval *kv) {
 // Convert a "msgmeta" record to a message metadata record on disk.  NOT THREADSAFE
 int import_msgmeta(char *line, struct cdbkeyval *kv) {
        char *token;
-       struct MetaData *m = malloc(sizeof(struct MetaData));
+       struct MetaData *m;
 
+       m = malloc(sizeof(struct MetaData));
+       if (!m) {
+               fprintf(stderr, "import_msgmeta: malloc: %s\n", strerror(errno));
+               return(0);
+       }
        memset(m, 0, sizeof(struct MetaData));
        char *p = line;
 
@@ -112,8 +117,13 @@ int import_msgmeta(char *line, struct cdbkeyval *kv) {
 int import_user(char *line, struct cdbkeyval *kv) {
        char userkey[USERNAME_SIZE];
        char *token;
-       struct ctdluser *u = malloc(sizeof(struct ctdluser));
+       struct ctdluser *u;
 
+       u = malloc(sizeof(struct ctdluser));
+       if (!u) {
+               fprintf(stderr, "malloc failed\n");
+               return(0);
+       }
        memset(u, 0, sizeof(struct ctdluser));
        char *p = line;
 
@@ -126,7 +136,7 @@ int import_user(char *line, struct cdbkeyval *kv) {
                                u->uid = atoi(token);
                                break;
                        case 3:
-                               strncpy(u->password, token, sizeof(u->password));
+                               safestrncpy(u->password, token, sizeof(u->password));
                                break;
                        case 4:
                                u->flags = atoi(token);
@@ -144,7 +154,7 @@ int import_user(char *line, struct cdbkeyval *kv) {
                                u->USuserpurge = atoi(token);
                                break;
                        case 9:
-                               strncpy(u->fullname, token, sizeof(u->fullname));
+                               safestrncpy(u->fullname, token, sizeof(u->fullname));
                                break;
                        case 10:
                                u->msgnum_bio = atol(token);
@@ -153,7 +163,8 @@ int import_user(char *line, struct cdbkeyval *kv) {
                                u->msgnum_pic = atol(token);
                                break;
                        case 12:
-                               CtdlDecodeBase64(u->emailaddrs, token, strlen(token));
+                               CtdlDecodeBase64(token, token, strlen(token));
+                               safestrncpy(u->emailaddrs, token, sizeof(u->emailaddrs));
                                break;
                        case 13:
                                u->msgnum_inboxrules = atol(token);
@@ -163,7 +174,14 @@ int import_user(char *line, struct cdbkeyval *kv) {
                                break;
                }
        }
+
+       // reject any user records without names
+       if (strlen(u->fullname) == 0) {
+               free(u);
+               return(0);
+       }
        
+       // ok, good to go
        makeuserkey(userkey, u->fullname);
        kv->key.len = strlen(userkey);
        kv->key.ptr = strdup(userkey);
@@ -176,8 +194,13 @@ int import_user(char *line, struct cdbkeyval *kv) {
 // Convert a "room" record to a record on disk.  (Source string is unusable after this function is called.)
 int import_room(char *line, struct cdbkeyval *kv) {
        char *token;
-       struct ctdlroom *r = malloc(sizeof(struct ctdlroom));
+       struct ctdlroom *r;
 
+       r = malloc(sizeof(struct ctdlroom));
+       if (!r) {
+               fprintf(stderr, "import_room: malloc: %s\n", strerror(errno));
+               return(0);
+       }
        memset(r, 0, sizeof(struct ctdlroom));
        char *p = line;
 
@@ -254,9 +277,14 @@ int import_room(char *line, struct cdbkeyval *kv) {
 // Convert a floor record to a record on disk.
 int import_floor(char *line, struct cdbkeyval *kv) {
        char *token;
-       struct floor *f = malloc(sizeof(struct floor));
+       struct floor *f;
        int floor_num;
 
+       f = malloc(sizeof(struct floor));
+       if (!f) {
+               fprintf(stderr, "import_floor: malloc: %s\n", strerror(errno));
+               return(0);
+       }
        memset(f, 0, sizeof(struct floor));
        char *p = line;
 
@@ -332,8 +360,13 @@ int import_msglist(char *line, struct cdbkeyval *kv) {
 // Convert a "visit" record to a record on disk.
 int import_visit(char *line, struct cdbkeyval *kv) {
        char *token;
-       struct visit *v = malloc(sizeof(struct visit));
+       struct visit *v;
 
+       v = malloc(sizeof(struct visit));
+       if (!v) {
+               fprintf(stderr, "import_visit: malloc: %s\n", strerror(errno));
+               return(0);
+       }
        memset(v, 0, sizeof(struct visit));
        char *p = line;
 
@@ -409,8 +442,13 @@ int import_dir(char *line, struct cdbkeyval *kv) {
 // Convert a "usetable" record to a record on disk.
 int import_usetable(char *line, struct cdbkeyval *kv) {
        char *token;
-       struct UseTable *u = malloc(sizeof(struct UseTable));
+       struct UseTable *u;
 
+       u = malloc(sizeof(struct UseTable));
+       if (!u) {
+               fprintf(stderr, "import_usetable: malloc: %s\n", strerror(errno));
+               return(0);
+       }
        memset(u, 0, sizeof(struct UseTable));
        char *p = line;
 
@@ -579,7 +617,6 @@ void ingest_one(char *line, struct cdbkeyval *kv) {
        static int current_cdb = -1 ;
        char record_type[32];
        int row_was_good;
-       static time_t last_diag = 0;
 
        // Clear out our record buffer
        memset(kv, 0, sizeof(struct cdbkeyval));
@@ -656,11 +693,9 @@ void ingest_one(char *line, struct cdbkeyval *kv) {
        else {
                ++bad_rows;
        }
-       if (time(NULL) > last_diag) {
-               fprintf(stderr, "   \033[32m%9d\033[0m / \033[31m%8d\033[0m\r", good_rows, bad_rows);
-               fflush(stderr);
-               last_diag = time(NULL);
-       }
+
+       fprintf(stderr, "\r   \033[32m%9d\033[0m / \033[31m%8d\033[0m ", good_rows, bad_rows);
+       fflush(stderr);
 
 }
 
@@ -726,13 +761,13 @@ int main(int argc, char **argv) {
        char *ctdldir = CTDLDIR;
 
        // display the greeting
-       fprintf(stderr, "\033[44m\033[1m"
-               "╔════════════════════════════════════════════════════════════════════════╗\n"
-               "║ DB Load utility for Citadel                                            ║\n"
-               "║ Copyright (c) 2023-2024 by citadel.org et al.                          ║\n"
-               "║ This program is open source software.  Use, duplication, or disclosure ║\n"
-               "║ is subject to the terms of the GNU General Public license v3.          ║\n"
-               "╚════════════════════════════════════════════════════════════════════════╝\033[0m\n"
+       fprintf(stderr,
+               "\033[44m\033[1m╔════════════════════════════════════════════════════════════════════════╗\033[0m\n"
+               "\033[44m\033[1m║ DB Load utility for Citadel                                            ║\033[0m\n"
+               "\033[44m\033[1m║ Copyright (c) 2023-2024 by citadel.org et al.                          ║\033[0m\n"
+               "\033[44m\033[1m║ This program is open source software.  Use, duplication, or disclosure ║\033[0m\n"
+               "\033[44m\033[1m║ is subject to the terms of the GNU General Public license v3.          ║\033[0m\n"
+               "\033[44m\033[1m╚════════════════════════════════════════════════════════════════════════╝\033[0m\n"
        );
 
        // Parse command line
@@ -777,6 +812,7 @@ int main(int argc, char **argv) {
        cdb_init_backends();
        cdb_open_databases();
 
+       // Load rows from the input source
        ingest();
 
        // close databases