// Load (restore) the Citadel database from a flat file created by ctdldump
//
-// Copyright (c) 2023 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.
// 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;
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;
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);
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);
u->msgnum_pic = atol(token);
break;
case 12:
- CtdlDecodeBase64(u->emailaddrs, token, strlen(token));
+ CtdlDecodeBase64(token, token, strlen(token)); // Decode in place
+ safestrncpy(u->emailaddrs, token, sizeof(u->emailaddrs));
break;
case 13:
u->msgnum_inboxrules = atol(token);
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);
// 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;
// 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;
// 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;
// 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;
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));
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);
}
char *ctdldir = CTDLDIR;
// display the greeting
- fprintf(stderr, "\033[44m\033[33m\033[1m \033[K\033[0m\n"
- "\033[44m\033[33m\033[1m DB Load utility for Citadel \033[K\033[0m\n"
- "\033[44m\033[33m\033[1m Copyright (c) 2023 by citadel.org et al. \033[K\033[0m\n"
- "\033[44m\033[33m\033[1m This program is open source software. Use, duplication, or disclosure \033[K\033[0m\n"
- "\033[44m\033[33m\033[1m is subject to the terms of the GNU General Public license v3. \033[K\033[0m\n"
- "\033[44m\033[33m\033[1m \033[K\033[0m\n");
+ fprintf(stderr,
+ "\033[44m\033[1m╔════════════════════════════════════════════════════════════════════════╗\033[0m\n"
+ "\033[44m\033[1m║ DB Load utility for Citadel version %-4d ║\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",
+ REV_LEVEL
+ );
// Parse command line
int a;
}
else {
fprintf(stderr, "ctdlload: usage: ctdlload -y -h[citadel_dir] <[dump_file]\n");
- fprintf(stderr, " [citadel_dir] is your server directory, usually /usr/local/citadel\n");
+ fprintf(stderr, " -y : yes, I know this program can do damage and I want to run it anyway.\n");
+ fprintf(stderr, " -h : [citadel_dir] is your server directory, usually /usr/local/citadel\n");
fprintf(stderr, " Please read [ https://www.citadel.org/dump-and-load.html ] to learn how to proceed.\n");
exit(1);
}
cdb_init_backends();
cdb_open_databases();
+ // Load rows from the input source
ingest();
// close databases