1#!/usr/bin/perl
2# convert_mbox.pl
3# perl script to convert mbox file to files in a new MH directory
4# aka another mbox -> MH conversion tool
5# 29 April 2003
6# Fred Marton <Fred.Marton@uni-bayreuth.de>
7#
8# Fixed (hopefully) to account for From lines
9# that are of various length and that might have
10# time zone info at the end
11# 20 January 2004
12#
13# Note: Running this with the -w flag generates the following warnings:
14# Scalar value @word[1] better written as $word[1] at /path/to/convert_mbox.pl line 54
15# Scalar value @word[0] better written as $word[1] at /path/to/convert_mbox.pl line 56
16# Making these changes requires further changes in the script
17# that results in much longer run-times.
18#
19# Copyright (c) 2003 Fred Marton
20# Copyright (c) 2009 Ricardo Mones, based on the bash script
21#                    by Daniel Dickinson [1]
22#
23# This program is free software; you can redistribute it and/or
24# modify it under the terms of the GNU General Public License
25# as published by the Free Software Foundation; either version 3
26# of the License, or (at your option) any later version.
27#
28# This program is distributed in the hope that it will be useful,
29# but WITHOUT ANY WARRANTY; without even the implied warranty of
30# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31# GNU General Public License for more details.
32#
33# You should have received a copy of the GNU General Public License
34# along with this program; if not, write to the Free Software
35# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
36# 02111-1307, USA.
37#
38# [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=15;filename=convert_mbox.sh;att=1;bug=461435
39
40use File::Path;
41use File::Basename;
42
43# check for arguments
44&usage if ($#ARGV < 1);
45if ($ARGV[0] eq "-R") {
46  # recursive, need more args
47  &usage if ($#ARGV < 2);
48  &usage unless (-d $ARGV[1]);
49  &usage unless (-d $ARGV[2]);
50  &convert_all ($ARGV[1], $ARGV[2]);
51}
52else {
53  # default behaviour
54  &convert_mbox ($ARGV[0], $$ARGV[1]);
55}
56
57sub strip_sbd {
58  # raw translation of bash, probably doable in real Perl better
59  $dirname = shift;
60  $nosbddir = "";
61  $dirleft = $dirname;
62  while ($dirleft ne "." and $dirleft ne "") {
63    $enddir = &basename ($dirleft, ['.sbd']);
64    if ($nosbddir ne "") {
65      $nosbddir = "$enddir/$nosbddir";
66    }
67    else {
68      $nosbddir = $enddir;
69    }
70    $dirleft = &dirname ($dirleft);
71  }
72  print "$nosbddir\n";
73}
74
75sub convert_all {
76  ($mboxdir, $targetdir) = @_;
77  $tmpbase = '/tmp/frommbox';
78  $tmplist = '/tmp/.convert_mbox.filelist';
79  $curdir = qx/pwd/;
80  chdir ($mboxdir);
81  qx/find * -type -d -a ! -name '*.*'i | sort > $tmplist/;
82  open (FLH, "<$tmplist") or die "cannot open $tmplist: $!\n";
83  while (<FLH>) {
84    chomp;
85    &convert_one ($_, $targetdir, $tmpbase);
86  }
87  close (FLH);
88  unlink ($tmplist);
89  chdir ($curdir);
90}
91
92sub convert_one {
93  # targetdir isn't used in the original bash script, maybe a bug?
94  ($file, $targetdir, $tmpbase) = @_;
95  $dirname = &dirname ($file);
96  $filename = &basename ($file);
97  if ($dirname eq $filename) {
98    $dirname = "";
99  }
100  $dirname = &strip_sbd ($dirname);
101  if ($dirname ne "") {
102    $dirname = "/$dirname";
103  }
104  &mkpath ($tmpbase . $dirname);
105  $basefile = &basename ($file);
106  $base1 = &basename ($file, ['.cmeta']);
107  $base2 = &basename ($base1, ['.ibex.index']);
108  $base3 = &basename ($base2, ['.ibex.index.data']);
109  $base5 = &basename ($base3, ['.ev-summary']);
110  $base4 = &basename ($base5, ['.ev-summary-meta']);
111  $subdir = &basename ($dirname);
112  $basedir = "/" . &dirname ($dirname);
113  if ( $basedir eq '/.' or $basedir eq '/' ) {
114    $basedir = $dirname;
115    $subdir = "";
116  }
117  $basedir = $tmpbase . $basedir;
118  &mkpath ($basedir);
119  $dirisfile = 0;
120  if ( -f "$basedir/$subdir" ) {
121    $dirisfile = 1;
122    qx/mv \"$basedir\/$subdir\" \"$basedir\/$subdir.tmp\"/;
123    &mkpath ("$basedir/$subdir");
124  }
125  if ( ! -d "$basedir/$subdir/$base4" ) {
126    print "$basedir/$subdir/$base4\n";
127    &convert_mbox ($file, "$basedir/$subdir/$base4", 'quiet');
128    if ($dirisfile == 1) {
129      qx/mv \"$basedir\/$subdir.tmp\/*\" \"$basedir\/$subdir\/\"/;
130    }
131  }
132}
133
134
135sub convert_mbox {
136  ($mbox, $mh, $quiet) = @_;
137  # check to make sure there isn't something named MH already
138  if (-e $mh) {
139     die (" The directory \"$mh\" already exists.  Exiting.\n");
140  }
141  else {
142     mkdir $mh;
143  }
144  # start numbering
145  $i = 0;
146  # open the mbox file
147  open (IN, $mbox);
148  while ($line = <IN>) {
149    # check for the beginning of an e-mail
150    @word = split(/ +/m,$line);
151    # some lines might start with "From ", so check
152    # to see if the [second-to-]last word is a year
153    @word2 = split(/:/,$line);
154    chomp($word2[$#word2]);
155    @word3 = split(/ /,$word2[2]);
156    $year = @word3[1];
157    # ignore the MAILER-DAEMON message from pine
158    if (@word[1] ne "MAILER-DAEMON") {
159      # start a new file, assuming $year is > 1970
160      if (@word[0] eq "From" && $year > 1970) {
161        $i++;
162        close (OUT);
163        open (OUT, ">$mh/$i");
164        print OUT $line;
165      }
166      else {
167        # continue the file
168        print OUT $line;
169      }
170    }
171  }
172  close (OUT);
173  close (IN);
174  # and we're done
175  if (! defined($quiet)) {
176    print "\n If it isn't there already, please move the directory \"$mh\"\n"
177          . " into your MH directory and rebuild your folder tree.\n\n";
178  }
179}
180
181sub usage {
182   die ("Usage: convert_mbox.pl MBOX MH_DIR\n"
183        . "       convert_mbox.pl -R MBOXDIR MH_DIR\n"
184        . "Where: \n"
185        . "  -R  Converts recursively a directory of mboxes\n");
186}
187
188
189