This is a modification to uni-one-converter which process a single mailbox using the database hooks directly, rather than via dbmail-smtp.
Usage: ./mbox2dbmail-fast /path/to/mboxfile useexisting|create The "mboxfile" will be the value it references against column 'userid' in the database. Useexisting bails if it can't find the user, create does the same as uni-one-converter and adds a new user with passwd 'default' [not tested btw]. Has a bit of a bug which means you can't just call as "mbox2dbmail-fast mboxfile useexisting" : I'm not a c programmer, but the path resolve function kills the first character when returning the username. Workaround "mbox2-dbmail-fast ./mboxfile useexisting" /Mark
mbox2dbmail-fast.c
Description: application/applefile
/* * this program traverses a directory tree and executes * dbmail conversion on each file. */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <dirent.h> #include <time.h> #include <unistd.h> #include "db.h" #include "auth.h" #include "dbmailtypes.h" #include "debug.h" #include <regex.h> #define MAX_LINESIZE 1024 #define UID_SIZE 70 const char *mbox_delimiter_pattern = "^From .* "; char blk[READ_BLOCK_SIZE + MAX_LINESIZE + 1]; /* syslog */ #define PNAME "dbmail/mbox2dbmail-fast" char *getusername (char *path); int processmbox (char *path, char *flags); int process_mboxfile(char *file, u64_t userid); int main (int argc, char* argv[]) { int result; if (argc < 3) { printf ("Usage: mbox2dbmail-fast <userid> [create|useexisting] \n"); return -1; } openlog(PNAME, LOG_PID, LOG_MAIL); /* open connection to syslog */ configure_debug(TRACE_ERROR, 1, 0); /* open dbase connections */ if (db_connect() != 0 || auth_connect() != 0) { printf("Error opening dbase connections\n"); return -1; } result = processmbox(argv[1], argv[2]); return result; } int processmbox (char *path, char *flags) { char *username; int n; u64_t userid; printf ("file %s\n",path); username = getusername(path); printf ("username %s\n", username); if ( strcmp(flags, "create") == 0) { printf("creating user..."); userid = auth_adduser(username, "default", "", "0", "10M"); } else { printf("looking up existing user"); userid = auth_user_exists(username); } if (userid != -1 && userid != 0) { printf("Ok id [%llu]\n", userid); fflush(stdout); n = process_mboxfile(path, userid); if (n != 0) printf("Warning: error converting mailbox\n"); else printf ("\ndone :)\n"); } else { printf("user already exists (create) or user not found (useexisting). Skipping\n"); } return 0; } char *getusername (char *path) { int i; char *tmp; i = strlen (path); tmp = path+i; while ( (tmp!=path) && (*tmp!='/')) tmp--; return tmp+1; } int process_mboxfile(char *file, u64_t userid) { regex_t preg; int result; FILE *infile; int in_msg, header_passed=0; char newunique[UID_SIZE]; unsigned cnt,len,newlines; u64_t msgid=0, size; char saved; int msgcount = 0; if ((result = regcomp(&preg, mbox_delimiter_pattern, REG_NOSUB)) != 0) { trace(TRACE_ERROR,"Regex compilation failed."); return -1; } if ( (infile = fopen(file, "r")) == 0) { trace(TRACE_ERROR,"Could not open file [%s]", infile); return -1; } in_msg = 0; cnt = 0; size = 0; newlines = 0; while (!feof(infile) && !ferror(infile)) { if (fgets(&blk[cnt], MAX_LINESIZE, infile) == 0) break; /* check if this is an mbox delimiter */ if (regexec(&preg, &blk[cnt], 0, NULL, 0) == 0) { if (!in_msg) in_msg = 1; /* ok start of a new msg */ else { /* update & end message */ msgcount++; printf("\rConverting mailbox :: %d", msgcount); db_insert_message_block(blk, cnt, msgid); snprintf(newunique, UID_SIZE, "%lluA%lu", userid, time(NULL)); db_update_message(msgid, newunique, size+cnt, size+cnt+newlines); trace(TRACE_ERROR, "message [%llu] inserted, [%u] bytes", msgid, size+cnt); } /* start new message */ msgid = db_insert_message(userid, 0, 0); header_passed = 0; cnt = 0; size = 0; newlines = 0; } else { newlines++; if (header_passed == 0) { /* we're still reading the header */ len = strlen(&blk[cnt]); if (strcmp(&blk[cnt], "\n") == 0) { db_insert_message_block(blk, cnt+len, msgid); header_passed = 1; size += (cnt+len); cnt = 0; } else cnt += len; } else { /* this is body data */ len = strlen(&blk[cnt]); cnt += len; if (cnt >= READ_BLOCK_SIZE) { /* write block */ saved = blk[READ_BLOCK_SIZE]; blk[READ_BLOCK_SIZE] = '\0'; db_insert_message_block(blk, READ_BLOCK_SIZE, msgid); blk[READ_BLOCK_SIZE] = saved; memmove(blk, &blk[READ_BLOCK_SIZE], cnt - (READ_BLOCK_SIZE)); size += READ_BLOCK_SIZE; cnt -= READ_BLOCK_SIZE; } } } } /* update & end message */ if (msgid > 0) { db_insert_message_block(blk, cnt, msgid); snprintf(newunique, UID_SIZE, "%lluA%lu", userid, time(NULL)); db_update_message(msgid, newunique, size+cnt, size+cnt+newlines); trace(TRACE_ERROR, "message [%llu] inserted, [%u] bytes", msgid, size+cnt); } fclose(infile); return 0; }