#! /usr/local/bin/perl
################################################################
###
###			       immknmz
###	     "mew-nmz-mknmz-all-folders" (in mew-nmz.el)
###
### Author:  Shuichi Kitaguchi <kit@Mew.org>
###	Internet Message Group <img@mew.org>
### Created: Sep 23, 1999
### Revised: Mar 22, 2003
###

BEGIN {
    use lib '/usr/local/lib';
};

my $VERSION = "immknmz version 20030322(IM144)";

$Prog = 'immknmz';

###
### Modify these variables if you need.
###
my $nmzdir        = "Namazu";	# "~/$nmzdir"
my $mknmz_include = "mknmz-inc.pl";	# mknmz -I <file>
my @ignorefolders = ("draft", "trash", "schedule", "queue",);


# Code:

use IM::Config;
use IM::Util;
use IM::Folder;
use IO::File;
use strict;
use vars qw($Prog $EXPLANATION @OptConfig $opt_help $opt_gcnmz $opt_verbose $opt_timestamp);

$EXPLANATION = "$VERSION
make namazu index for mail/news folders

Usage: $Prog [OPTIONS]
";

@OptConfig = (
	      'gcnmz;b;;'   => "Use gcnmz after mknmz (Garbage Collection for Namazu index).",
	      'verbose;b;;' => "With verbose messages.",
	      'timestamp;b;;' => "Use checking time stamp.",
	      'help;b;;'    => "Show this message.",
	      );

init_opt(\@OptConfig);
read_cfg();
read_opt(\@ARGV);
help($EXPLANATION) && exit $EXIT_SUCCESS if $opt_help;

sub get_mtime {
    my($path) = @_;
    my($dev,$ino,$mode,$nlink,$uid,$gid,
       $rdev,$size,$atime,$mtime,$ctime,
       $blksize,$blocks) = stat($path) or return -1;
    return $mtime;
}

my $lockdir = namazu_lock_path();
if ($lockdir) {
    unless (mkdir($lockdir, 0700)) {
	print STDERR "$Prog: can not create lock directory: $lockdir.\n";
	exit $EXIT_ERROR;
    }
}
sub unlock_exit($) {
    my($status) = @_;
    rmdir $lockdir if $lockdir;
    exit $status;
}

my $mailpath = mail_path()."/";
my $namazupath = home_dir()."/$nmzdir/".mail_dir()."/";
my $mknmz_args = "-q";

my $incfile = home_dir()."/$nmzdir/$mknmz_include";
if (! -f $incfile) {
    $incfile = "";
}
my $folderspath = $mailpath."/.folders";
my $msgfolder;
my $msgdir;
my $flag;
my $nmzfolder;
my $gcnmztgt;
my $ret;
my @filelist;
my $tempdir;
my $tempfile;
my $timestamp;

$tempdir = $ENV{TMPDIR} || $ENV{TEMP} || $ENV{TMP} || '/tmp';
$tempdir =~ s:\\:/:g;
$tempdir =~ s/\/+$//;
$tempdir = sprintf("%s/immknmz-%d-%d", $tempdir, $$, time());
rmdir $tempdir;
unless (mkdir($tempdir, 0700)) {
    print STDERR "$Prog: can not create directory: $tempdir.\n";
    unlock_exit($EXIT_ERROR);
}
$tempfile = "$tempdir/tempfile";

$mknmz_args = "" if $opt_verbose;

im_open(\*FILE, "<$folderspath");
while (<FILE>) {
    s/\r$// if &win95p() || &os2p();
    chomp;
    $msgfolder = $_;
    $flag = 0;
    foreach (@ignorefolders) {
	if ($msgfolder !~ /^\+/) {  # ! local folder
	    $flag=1;
	    last;
	} elsif ($msgfolder =~ /^\+$_/) {  # == @ignorefolders
	    $flag=1;
	    last;
	}
    }
    if ($flag != 0) {
	print "skipping $msgfolder...\n";
	flush('STDOUT');
    } else {
	$nmzfolder = $msgfolder;
	$msgfolder =~ s/^\+/$mailpath/g;
	$msgdir = $msgfolder;
	$nmzfolder =~ s/^\+/$namazupath/g;

        $timestamp = "$nmzfolder/NMZ.stamp";
        if ($opt_timestamp) {
	    my $foldermtime;
	    if (&usetouchfile() && -r $msgfolder . "/" . &touchfile()) {
		$foldermtime = get_mtime($msgfolder . "/" . &touchfile());
	    } else {
		$foldermtime = get_mtime("$msgfolder");
	    }
            if ($foldermtime < get_mtime("$timestamp")) {
                print "index of $msgfolder may be up to date.\n" if $opt_verbose;
		flush('STDOUT');
                next;
            }
        }
        im_open(\*STAMP,">$timestamp.new");
        print STAMP "touched by IM.";
        close(STAMP);

	opendir(DIR,$msgfolder);
	@filelist = grep(/^[0-9]*$/ && -f "$msgfolder/$_",readdir(DIR));
	closedir(DIR);

	if ((&win95p() || &os2p()) && !&namazuv2()) {
	    $msgfolder =~ s:/:\\:g;
	}

	if (scalar(@filelist) > 0) {
	    unless (sysopen(\*TEMPFILE, "$tempfile",
			    O_RDWR()|O_CREAT()|O_EXCL(), 0600)) {
		print STDERR "$Prog: can not create file: $tempfile.\n";
		unlock_exit($EXIT_ERROR);
	    }
	    binmode(\*TEMPFILE);
	    foreach (@filelist) {
		if (! -d "$msgdir/$_") {
		    if ((&win95p() || &os2p()) && !&namazuv2()) {
			print TEMPFILE "$msgfolder\\$_\n";
		    } else {
			print TEMPFILE "$msgfolder/$_\n";
		    }
		}
	    }
	    close(TEMPFILE);

	    create_folder($nmzfolder);
	    $gcnmztgt = "$nmzfolder" . "/NMZ";
	    
	    print "$Prog: processing $msgfolder ...\n";
            flush('STDOUT');
	    if ($incfile eq "") {
		$ret = system "mknmz -Uh $mknmz_args -O $nmzfolder -F $tempfile";
	    } else {
		$ret = system "mknmz -Uh $mknmz_args -O $nmzfolder -F $tempfile -I $incfile";
	    }
	    unlink $tempfile;
	    if ($ret == 2) {
		print "$Prog: abort.\n";
		flush('STDOUT');
		last;
	    } elsif ($opt_gcnmz) {
		print "$Prog: gcnmz $msgfolder ...\n" if $opt_verbose;
		flush('STDOUT');
		if (&namazuv2()) {
		    system "gcnmz --no-backup --quiet $gcnmztgt";
		} else {
		    system "gcnmz $gcnmztgt";
		    opendir(DIR,$nmzfolder);
		    @filelist = grep(/^.*.BAK$/ && -f "$nmzfolder/$_",readdir(DIR));
		    closedir(DIR);
		    if (scalar(@filelist) > 0) {
			foreach (@filelist) {
			    unlink "$nmzfolder" . "/$_";
			}
		    }
		}
	    }
	}
        rename("$timestamp.new", "$timestamp");
    }
}
close(FILE);
rmdir $tempdir;
unlock_exit($EXIT_SUCCESS);

__END__

=head1 NAME

immknmz - make namazu index for mail/news folders

=head1 SYNOPSIS

B<immknmz> [OPTIONS]

=head1 DESCRIPTION

The I<immknmz> command makes namazu index for mail/news folders.

This command is provided by IM (Internet Message).

=head1 OPTIONS

=over 5

=item I<-g, --gcnmz={on,off}>

Use gcnmz after mknmz (Garbage Collection for Namazu index).

=item I<-v, --verbose={on,off}>

Print verbose messages when running.

=item I<-t, --timestamp={on,off}>

Use checking time stamp.

=item I<-h, --help>

Display help message and exit.

=back

=head1 COPYRIGHT

IM (Internet Message) is copyrighted by IM developing team.
You can redistribute it and/or modify it under the modified BSD
license.  See the copyright file for more details.

=cut

### Copyright (C) 1997, 1998, 1999 IM developing team
### All rights reserved.
### 
### Redistribution and use in source and binary forms, with or without
### modification, are permitted provided that the following conditions
### are met:
### 
### 1. Redistributions of source code must retain the above copyright
###    notice, this list of conditions and the following disclaimer.
### 2. Redistributions in binary form must reproduce the above copyright
###    notice, this list of conditions and the following disclaimer in the
###    documentation and/or other materials provided with the distribution.
### 3. Neither the name of the team nor the names of its contributors
###    may be used to endorse or promote products derived from this software
###    without specific prior written permission.
### 
### THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND
### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
### PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE
### LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
### CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
### SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
### BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
### WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
### OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
### IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

### Local Variables:
### mode: perl
### End:
