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;
}
