#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1996-11-27 21:36 MET by <dfk@kantoor.ripe.net>.
# Source directory was `/export/nccfs50/localsrc-2.1/rmdupmail'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    586 -rw-rw-r-- Makefile
#   1087 -rw-rw-r-- rmdupmail.1
#   3666 -rw-rw-r-- rmdupmail.pl
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
# ============= Makefile ==============
if test -f 'Makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping Makefile (file already exists)'
else
  echo 'x - extracting Makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
#
# Makefile for rmdupmail
# (which didn't come with one, so I stole one. dfk)
#
X
X.SUFFIXES: .pl .
X
PERL=   /usr/bin/perl
PROG=	rmdupmail
MAN1=	rmdupmail.1
ALL=	$(PROG) $(MAN1)
X
X.pl:
X	rm -f $@
X	sed "s!%PERL%!$(PERL)!" <$< >$@
X	chmod 755 $@
X	$(PERL) -c $@ 
X
all:	$(ALL)
X
install: $(ALL)
X	install -c -m 755 $(PROG) /usr/local/bin/$(PROG)
X	install	-c -m 644 $(MAN1) /usr/local/man/man1/$(MAN1)
X
clean:
X	rm -f $(PROG) dist
X
dist:	rmdupmail.1 Makefile rmdupmail.pl
X	-packmail -odist -s100000 -t'rmdupmail - remove duplicate mail messages in MH-type folder' rmdupmail.1 Makefile rmdupmail.pl
SHAR_EOF
  $shar_touch -am 0305144096 'Makefile' &&
  chmod 0664 'Makefile' ||
  echo 'restore of Makefile failed'
  shar_count="`wc -c < 'Makefile'`"
  test 586 -eq "$shar_count" ||
    echo "Makefile: original size 586, current size $shar_count"
fi
# ============= rmdupmail.1 ==============
if test -f 'rmdupmail.1' && test X"$1" != X"-c"; then
  echo 'x - skipping rmdupmail.1 (file already exists)'
else
  echo 'x - extracting rmdupmail.1 (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'rmdupmail.1' &&
X.TH RMDUPMAIL 1 
X.SH NAME
rmdupmail \- remove duplicate mail messages in MH-type folder
X.SH SYNOPSIS
X.B rmdupmail
X.BI [\-n]\ [\-q]\ [\-f]
X.BI +folder
X.SH DESCRIPTION
X.IX  "rmdupmail command"  ""  "\fLrmdupmail\fP \(em remove duplicate mail messages in MH-type folder
X.B rmdupmail
removes all duplicate mail messages from the MH-type mail folder
X.I +folder.
The criteria for detecting duplicates are:
X
X.nf
X    - same message ID
X    - only one message-id header
X    - no resent headers
X.fi
X
Deletion means moving to a file starting with ",".
X.B rmdupmail 
reports all actions including the relevant subject headers to
stdout.
X
The \-n flag will show what
X.B rmdupmail
would do, without actually removing duplicated messages.
X
The \-q flag will cause
X.B rmdupmail
to be quiet, ie not report what duplicated messages it removes.
X
The \-f flag will cause
X.B rmdupmail
to really remove duplicate mail files, rather than moving them to ,nnn files.
X.SH "FILES"
Determines mailpath from .mh_profile.
X.SH "SEE ALSO"
X.BR mh (1)
X.BR rmm (1)
X.BR perl (1)
X.SH AUTHORS
Daniel Karrenberg <dfk@ripe.net>
SHAR_EOF
  $shar_touch -am 0305144096 'rmdupmail.1' &&
  chmod 0664 'rmdupmail.1' ||
  echo 'restore of rmdupmail.1 failed'
  shar_count="`wc -c < 'rmdupmail.1'`"
  test 1087 -eq "$shar_count" ||
    echo "rmdupmail.1: original size 1087, current size $shar_count"
fi
# ============= rmdupmail.pl ==============
if test -f 'rmdupmail.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping rmdupmail.pl (file already exists)'
else
  echo 'x - extracting rmdupmail.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'rmdupmail.pl' &&
#!%PERL%
X
#
# rmdupmail dfk@ripe.net 93xxxx
#
# usage: rmdupmail +foldername
#
# removes duplicate mail messages from an MH-type folder
#
# criteria for detecting duplicates:
#
#	- same message ID
#	- only one message-id header
#	- no resent headers
#
# deltion means moving to file starting with "," (MH standard)
#
# Additions by MT:
# add -q flag:    quiet, will not produce any output
# add -n flag:    show what it would do, without actually doing it
# -q -n both specified will of course be a noop.
#
# Additions by dfk:
# add -f flag:    will unlink duplicates and not move them to ,*
X
require "getopts.pl";
X
&Getopts('qnf');
X
if ($#ARGV != 0 || $ARGV[0] !~ /\+\S+/) {
X	printf STDERR "usage: rmdupmail +foldername\n";
X	exit 1;
}
X
$HOME = $ENV{"HOME"};
X
# find mail path
#
open(MHPROFILE, "<$HOME/.mh_profile") || die "$HOME/.mh_profile: $!\n";
while (<MHPROFILE>) {
X	chop;
X	if (/^Path:\s+/i) {
X		$mhpath = $';
X		if (substr($mhpath, 1, 1) ne "/") {
X			$mhpath = "$HOME/$mhpath";
X		}
X		last;
X	}
}
$mhpath = "$HOME/Mail" unless ($mhpath);
X
# find messages in folder
#
$folder = substr($ARGV[0], 1);
$workdir = "$mhpath/$folder";
opendir(FOLDER, $workdir) || die "$workdir: $!\n";
@allmsgs = grep(/^[1-9][0-9]*$/, readdir(FOLDER));
closedir(FOLDER);
chdir($workdir) || die "$workdir: $!\n";
X		
# find and delete duplicates
#
while (@allmsgs) {
X	$msg = shift @allmsgs;
X	$msgid = &getid($msg);
X	if ($msgid ne "") {
X		if ($msgid{$msgid} ne "") {
X			if (!&isresent($msg)) {
X				printf "$msg is dup of %s, %s\n", 
X                                        $msgid{$msgid}, 
X                                        &getsubject($msg)         if !$opt_q;
X				&remove("$msg");
X			}
X			elsif (!&isresent($msgid{$msgid})) {
X				printf "%s is dup of %s, %s\n", 
X                                        $msgid{$msgid}, 
X                                        $msg, 
X				        &getsubject($msg) 	   if !$opt_q;
X				&remove("$msgid{$msgid}");
X			}
X		}
X		else {
X			$msgid{$msgid} = $msg;
X		}
X	}
#	else {
#		$bodysize{&getbdysize($msg)} .= "$msg,";
#	}
}
X
#while (($k, $v) = each %bodysize) {
#	chop($v);
#	@nbody = split(/,/, $v);
#	if (@nbody >1) {
#		print "$k = $v\n";
#	}
#}
X
sub getbdysize {
X
X	local($msg) = @_;
X	local($size) = 0;
X
X	unless (open (MSG, "<$msg")) {
X		 die "getbdysize can't open $msg: $!\n";
X	}
X
X	while (<MSG>) {
X		chop;
X		last if (/^\s*$/);
X	}	
X
X	while (<MSG>) {
X		$size += length($_);
X	}	
X
X	close(MSG);
X
#print STDERR "getbdysize($msg) = $size\n";
X	return ($size); 
}
X
sub getid {
X
X	local($msg) = @_;
X	local($msgid) = "";
X
X	unless (open (MSG, "<$msg")) {
X		 die "Can't open $msg: $!\n";
X	}
X
X	while (<MSG>) {
X		chop;
X		if (/^message-id:\s+/i) {
X			if ($msgid != "") {
X				printf "duplicate message-id in $msg\n" if !$opt_q;
X				close(MSG);
X				return "";
X			}
X			else {
X				$msgid = $';
X			}
X		}
X		if (/^\s*$/) {
X			close(MSG);
X			return $msgid;
X		}
X	}	
X	close(MSG);
X	return $msgid; 
}
X
sub getsubject {
X
X	local($msg) = @_;
X	local($subject) = "";
X
X	unless (open (MSG, "<$msg")) {
X		 die "Can't open $msg: $!\n";
X	}
X
X	while (<MSG>) {
X		chop;
X		if (/^subject:\s+(.*)/i) {
X			return $1;
X		}
X	}	
X	close(MSG);
X	return "";
}
X
sub isresent {
X
X	local($msg) = @_;
X
X	unless (open (MSG, "<$msg")) {
X		 die "Can't open $msg: $!\n";
X	}
X
X	while (<MSG>) {
X		chop;
X		if (/^resent-/i) {
X			close(MSG);
X			return 1;
X		}
X		if (/^\s*$/) {
X			close(MSG);
X			return 0;
X		}
X	}	
X	close(MSG);
X	return 0;; 
}
X
sub remove {
X
X	local($msg) = @_;
X
X	if (!$opt_n) {
X		if (!$opt_f) {
X			if (-e ",$msg") {
X				unlink(",$msg") || die "cannot unlink ,$msg: $!\n";
X			}
X			link($msg, ",$msg") || die "cannot link $msg to ,$msg: $!\n";
X		}
X		unlink($msg) || die "cannot unlink $msg: $!\n";
X	}
}
X
SHAR_EOF
  $shar_touch -am 0305141896 'rmdupmail.pl' &&
  chmod 0664 'rmdupmail.pl' ||
  echo 'restore of rmdupmail.pl failed'
  shar_count="`wc -c < 'rmdupmail.pl'`"
  test 3666 -eq "$shar_count" ||
    echo "rmdupmail.pl: original size 3666, current size $shar_count"
fi
exit 0
