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 

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

Reply via email to