diff options
Diffstat (limited to 'maildir/sharedindexsplit.in')
| -rw-r--r-- | maildir/sharedindexsplit.in | 151 | 
1 files changed, 151 insertions, 0 deletions
| diff --git a/maildir/sharedindexsplit.in b/maildir/sharedindexsplit.in new file mode 100644 index 0000000..5c0c10a --- /dev/null +++ b/maildir/sharedindexsplit.in @@ -0,0 +1,151 @@ +#! @PERL@ +# +# Copyright 2004 Double Precision, Inc. +# +# See COPYING for distribution information. +# +# Split the shared index into multiple files.  The entire shared index is +# piped on stdin. There are two modes of operation: +# - if nletters is specified and is greater than 0, then +#   split based on the first n characters of the username +# - if nletters is omitted or zero, then split based on the 'sharedgroup' +#   account option. This requires the options to be given as column 6 of +#   the input. +# +# Assume that account names use only the Latin alphabet. + +use IO::File; + +my $hasEncode=0; + +eval 'use Encode; $hasEncode=1;'; + +if ($hasEncode) +{ +    $hasEncode=0; + +    grep {$hasEncode=1 if $_ eq "UTF-32BE"; } Encode->encodings(":all"); + +} + +my $mult=1; + +$mult=4 if $hasEncode; + +my $outputdir=shift @ARGV; +my $nletters=shift @ARGV; + +die "Usage: $0 outputdir [ letters ]\n" unless -d $outputdir; + +print "*** WARNING - Encode not found, you should upgrade to Perl 5.8.0\n" +    unless $hasEncode; + +$nletters=0 unless defined($nletters); + +my %FILES;  # All opened files +my @MRU;    # Recycle using most-recently-used mechanism. + +sub indexfile { +    my $filename=shift @_; + +    Encode::from_to($filename, "UTF-32BE", "UTF-8") if $hasEncode; + +    return "$filename"; +} + +while (defined($_=<STDIN>)) +{ +    chomp; +    s/\#.*//; + +    my @fields=split /\t/; + + +    next unless $#fields>2;   # Comments, etc... + +    my $key; + +    if ($nletters > 0) +    { +	$key=$fields[0]; +	Encode::from_to($key, "UTF-8", "UTF-32BE") if $hasEncode; +	$key=substr($key, 0, $nletters * $mult); +    } +    elsif ($fields[5] =~ /(^|,)sharedgroup=([^,]+)/) +    { +        $key = $2; +	Encode::from_to($key, "UTF-8", "UTF-32BE") if $hasEncode; +    } +    else +    { +	$key = ""; +    } + +    while (length($key) < $nletters * $mult) +    { +	my $u="_"; + +	$u=Encode::encode("UTF-32BE", $u) if $hasEncode; + +	$key .= $u; +    } + +    if (defined $FILES{$key}) +    { +	@MRU=grep {$_ ne $key} @MRU; +	push @MRU, $key; + +    } +    else +    { +	unless ($#MRU < 3) +	{ +	    my $oldest=shift @MRU; + +	    close($FILES{$oldest}); +	    $FILES{$oldest}=undef; +	} + +	push @MRU, $key; + +	open( ($FILES{$key}=new IO::File), ">>$outputdir/index" +	      . indexfile($key) . "\n") +	    || die "$outputdir/index" . indexfile($key) . ": $!\n"; +    } + +    my $fh=$FILES{$key}; +    splice(@fields,5,1);  # hide options +    (print $fh (join("\t", @fields) . "\n")) || exit 1; +} + +grep { ( close($FILES{$_}) || exit(1)) if defined $FILES{$_}} keys %FILES; + +while ($nletters > 0) +{ +    my %NEWKEYS; +    my %NEWFILES; + +    --$nletters; + +    foreach (keys %FILES) +    { +	$NEWKEYS{substr($_, 0, $nletters * $mult)}=1; + +	push @{$NEWFILES{substr($_, 0, $nletters * $mult)}}, $_; +    } + +    foreach (keys %NEWFILES) +    { +	my $fn=indexfile($_); + +	open(FH, ">$outputdir/index$fn") || die "$outputdir/index$fn: $!\n"; + +	grep { my $x=indexfile($_);print FH "$x\t*\tindex$x\n" +		   || exit 1; } @{$NEWFILES{$_}}; +	close(FH) || exit 1; +    } + +    %FILES=%NEWKEYS; +} + + | 
