1: #!/usr/bin/perl -w
   2: 
   3: #############################################################
   4: # Usage... | mailtosql <dbname> <dbusername> <dbpass>       #
   5: # Pipe mail to this script and it will stick it in a mysql  #
   6: # table called Email. This is usefull for writing web       #
   7: # interfaces to email :) or other stuff.                    #
   8: #############################################################
   9: 
  10: use DBI;
  11: use Mail::Internet;
  12: use strict;
  13: use vars qw/$line $header @header @dats @fields $dbh $mail @arr $sth $statement $body $col @cols @body/;
  14: 
  15: $dbh = DBI->connect("DBI:mysql:$ARGV[0]",$ARGV[1],$ARGV[2],{
  16:         'RaiseError' => 0,
  17:         'PrintError' => 1
  18: });
  19: 
  20: $mail = new Mail::Internet \*STDIN;
  21: $header = $mail->head();
  22: 
  23: if (!($dbh->do("desc Email"))) {
  24:         $statement = "CREATE TABLE Email \(ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,ETo varchar\(150\),EFrom varchar\(150\),ESender varchar\(150\),ECc varchar\(150\),EDate varchar\(150\),ESubject varchar\(150\),EHeader text,EBody text\);";
  25:         $dbh->do($statement) || die "Could not create table \"Email\" on DB \"$ARGV[0]\"\n";
  26: }
  27: 
  28: die "Bad mail file\n" unless(defined($mail));
  29: 
  30: 
  31: # get fields 
  32: $sth = $dbh->prepare("desc Email");
  33: $sth->execute;
  34: while(@arr = $sth->fetchrow_array) {
  35:         push(@cols,$arr[0]);
  36: }
  37: 
  38: map {
  39:         chomp($line = $header->get($_));
  40:         $line = $dbh->quote($line);
  41:         $_ = "E".$_;
  42:         foreach $col(@cols) {
  43:                 if ($_ eq $col) {
  44:                         push(@fields,$_);
  45:                         push(@dats,$line);
  46:                 }
  47:         }
  48: } $header->tags;
  49: 
  50: map {
  51:         push(@header,$dbh->quote("$_: ".$header->get($_)));
  52: } $header->tags;
  53: push(@fields,"EHeader");
  54: push(@dats,"@header");
  55: 
  56: push(@fields,"EBody");
  57: @body = map {$dbh->quote($_)} @{$mail->body};
  58: push(@dats,"@body");
  59: 
  60: $statement = "INSERT INTO Email (".join(',',@fields).") VALUES(".join(',',@dats).");";
  61: $sth = $dbh->prepare($statement);
  62: $sth->execute;

Replies are listed 'Best First'.
RE: mailtosql.pl
by le (Friar) on Jul 21, 2000 at 16:31 UTC
    Sorry I had to vote -- on this one. The mail-to-database problem is one I had to fiddle with two months ago.
    1. Your script doesn't do anything with attachments, they will just be saved encoded into the body text column.
    2. Usually you know into which database you want to insert mail, so dynamically selecting it isn't necessary.
    3. Passing passwords on the command line isn't a good idea, they can be found in the shell's history (if it has one).
    4. Traversing over the header in a while loop should be faster than mapping (but this is untested).
    5. I prefer using placeholders to insert values, so I don't have to fiddle with correct quoting.
    These are just my 2 cents.
      1. Hmm forgot to handle attachments, Ill take care of that later today
      2. dynamiclly selecting isnt hurting anything :)
      3. Its not really meant to be used from command line, its more meant to
      be used from procmail or aliases etc etc.
      4. I think map is nifty :P~
      5. Iam weird.
      6. Thanks for the input :)



      lindex
      /****************************/ jason@gost.net, wh@ckz.org http://jason.gost.net /*****************************/
        If you need a script that can parse emails and put it into a database (with all attachments and stuff), email me. (Or should I put it here??)