#! @im_path_perl@ ################################################################ ### ### imhist ### ### Author: Internet Message Group ### Created: Jul 6, 1997 ### Revised: Apr 23, 2007 ### BEGIN { @im_my_siteperl@ @im_src_siteperl@ }; $Prog = 'imhist'; my $VERSION_DATE = "20161010"; my $VERSION_NUMBER = "153"; my $VERSION = "${Prog} version ${VERSION_DATE}(IM${VERSION_NUMBER})"; my $VERSION_INFORMATION = "${Prog} (IM ${VERSION_NUMBER}) ${VERSION_DATE} Copyright (C) 1999 IM developing team This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "; ## ## Require packages ## use IM::Config; use IM::Address; use IM::History; use IM::Message; use IM::Util; use integer; use strict; use vars qw($Prog $EXPLANATION @OptConfig @Hdr $opt_lookup $opt_remove $opt_msg $opt_dump $opt_add $opt_subfolders $opt_verbose $opt_debug $opt_help $opt_version); ## ## Environments ## $EXPLANATION = "$VERSION treat mail/news history database Usage: imhist [OPTIONS] "; @OptConfig = ( 'lookup;s;;' => 'Look up an entry for specified message-id', 'remove;s;;' => 'Remove whole information on specified message-id', 'msg;s;;' => 'Message to be deleted if multiple in database', 'dump;b;;' => 'Dump database just for debugging', 'add;f;;' => 'Add information of messages in a specified folder', 'subfolders;b;;' => 'Descend sub folders recursively (option for --add)', 'verbose;b;;' => 'With verbose messages', 'debug;d;;' => "With debug message", 'help;b;;' => "Display this help and exit", 'version,V;b;;' => "Output version information and exit", ); ## ## Profile and option processing ## init_opt(\@OptConfig); read_cfg(); read_opt(\@ARGV); # help? print("${VERSION_INFORMATION}") && exit $EXIT_SUCCESS if $opt_version; help($EXPLANATION) && exit $EXIT_SUCCESS if $opt_help; debug_option($opt_debug) if $opt_debug; ## ## Main ## if (msgdbfile() eq '') { im_die("MsgDBFile is not defined.\n"); } if ($opt_lookup ne '') { exit $EXIT_ERROR if (history_open(1) < 0); # unless ($opt_lookup =~ /^<.*>$/) { # im_warn("Message-ID should be surrounded by <>.\n"); # exit $EXIT_ERROR; # } my $msg = history_lookup($opt_lookup, LookUpMsg); if ($msg eq '') { im_info("no entry found for $opt_lookup\n"); exit $EXIT_ERROR; } else { print $msg . "\n"; } history_close(); } elsif ($opt_remove ne '') { exit $EXIT_ERROR if (history_open(1) < 0); # unless ($opt_lookup =~ /^<.*>$/) { # im_warn("Message-ID should be surrounded by <>.\n"); # exit $EXIT_ERROR; # } my $num = history_delete($opt_remove, $opt_msg); if ($num < 0) { im_warn("no entry found for $opt_remove\n"); exit $EXIT_ERROR; } if ($opt_msg ne '' && $num > 0) { im_info("message $opt_msg for $opt_remove deleted\n"); } else { im_info("entry for $opt_remove deleted\n"); } history_close(); } elsif ($opt_dump) { exit $EXIT_ERROR if (history_open(0) < 0); history_dump(); history_close(); } elsif ($opt_add ne '') { my $p = expand_path($opt_add); if (-f $p) { # single file if (history_open(1) < 0) { exit $EXIT_ERROR; } add_msg_info($p, $opt_add); history_close(); } elsif (-d $p) { # folder if (history_open(1) < 0) { exit $EXIT_ERROR; } add_folder_info($p, $opt_add); history_close(); } else { im_warn("no message found to add.\n"); exit $EXIT_ERROR; } } else { im_warn("no option specified.\n"); exit $EXIT_ERROR; } exit $EXIT_SUCCESS; sub add_msg_info($$) { my($path, $msg) = @_; local(@Hdr) = (); if (im_open(\*MSG, "<$path")) { &read_header(\*MSG, \@Hdr, 0); my $mid = &header_value(\@Hdr, 'Message-ID'); # my $dt = &header_value(\@Hdr, 'Date'); my $ver = &extract_addr(&header_value(\@Hdr, 'Mime-Version')); $ver =~ s/\s//g; my $master = ''; if ($ver eq '1.0') { my $ct = &header_value(\@Hdr, 'Content-Type') . ';'; $ct =~ s/\s//g; if ($ct =~ m|^Message/partial;(.*;)?id=([^;]+);|i) { $master = $2; $master =~ s/^"(.*)"$/$1/; } } if ($mid ne '') { history_store($mid, $msg); history_store("partial:$master", $mid) if ($master ne ''); } close (MSG); return 0; } return -1; } sub add_folder_info($$) { my($dir, $folder) = @_; $dir =~ s|/$||; im_info("Entering folder $dir\n"); chdir ($dir); unless (opendir(FOLDER, $dir)) { im_warn("can't read $dir\n"); return -1; } my @lower = (); my $f; foreach $f (readdir(FOLDER)) { if ($f eq '.' || $f eq '..') { } elsif ($f =~ /^\d+$/ && -f $f) { print(" $f\n"); add_msg_info($f, "$folder/$f"); } elsif (-d $f) { push(@lower, $f); } } closedir(FOLDER); if ($opt_subfolders eq '1') { my $l; foreach $l (@lower) { if ($folder eq '+') { add_folder_info("$dir/$l", "+$l"); } else { add_folder_info("$dir/$l", "$folder/$l"); } } } } __END__ =head1 NAME imhist - treat mail/news history database =head1 SYNOPSIS B [OPTIONS] =head1 DESCRIPTION The I command handles mail/news history database. This command is provided by IM (Internet Message). =head1 OPTIONS =over 5 =item I<-l, --lookup=STRING> Look up an entry for specified message-id. =item I<-r, --remove=STRING> Remove whole information on specified message-id. =item I<-m, --msg=STRING> Message to be deleted if multiple in database. =item I<-d, --dump={on,off}> Dump database just for debugging. =item I<-a, --add=FOLDER> Add information of messages in a specified folder. =item I<-s, --subfolders={on,off}> Descend sub folders recursively (option for --add). =item I<-v, --verbose={on,off}> Print verbose messages when running. =item I<--debug=DEBUG_OPTION> Print debug messages when running. =item I<-h, --help> Display help message and exit. =item I<--version> Output version information 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: