[comp.mail.mh] MHALL - do something to a lot of folders

mesard@bbn.com (Wayne Mesard) (12/09/88)

Here's a little script I whipped up this morning.  It repeatedly applies
a command (with optional arguments) to a bunch of folders.  I wrote it
because I'm forever forgetting where I refile'd a message to the night
before, and wanted a quick n dirty way to look for it.

The default command and argument are "scan" and "last".  The default
folders are all your top-level folders.

When folders are explicitly named subfolders will also be processed.
The -n switch prevents this recursion.  Conversly, when no folders are
given, the top-level ones are used.  The -r switch will cause subfolders
to be processed as well.  To apply a command other than "scan" use the
-c switch.

Examples:
---------
mhall first:2 5 +unix +inbox
   Will "scan" the first two messages and message number 5 in +unix,
   +inbox and any subfolders.

mhall -c show
   Show the current message of each top-level folder.

mhall -c folder -pack -r
   Invoke "folder" with the -pack option on every folder and subfolder.

Disclaimer: This is not elegant.


------------------SNIP------------------
#!/bin/csh -fb

#      mhall - apply a command to some or all of your MH folders.
#      Copyright (c) 1988 Wayne Mesard
#
#      This is free software.  It may be reproduced, retransmitted,
#      redistributed and otherwise propogated at will, provided that
#      this notice remains intact and in place.
#
#      Please direct bug reports, code enhancements and comments
#      to mesard@BBN.COM.

set tfolders
set args
set cmd
set recurse
set curfolder = `folder -fast`

while ( X$1 != X )
  switch ($1)
    case -help:
      echo "syntax: `basename $0` [-r] [-n] [-c command] [command-arg...] [+folder...]"
      exit 0
    case -c:
      set cmd = "$2"
      shift
      breaksw
    case -r:
      set recurse = "-recurse"
      breaksw
    case -n:
      set recurse = "-norecurse"
      breaksw
    case +*:
      set tfolders = "$tfolders $1"
      breaksw
    default:
      set args = "$args $1"
      breaksw
  endsw
  shift
end

if ("$tfolders" == "") then
  set folders = `folders $recurse -fast`
else
  set folders
  foreach folder ($tfolders)
    set folders = "$folders `folder $folder -recurse $recurse -fast`"
  end
endif

if ("$cmd" == "") then
  set cmd = "scan"
  if ("$args" == "") set args = "last"
endif

onintr CLEANUP

foreach folder ($folders)
  echo :${folder}:
  $cmd +$folder $args
end

CLEANUP:
folder +$curfolder >/dev/null
exit 0

-------------------------SNOOP-------------------

-- 
unsigned *Wayne_Mesard();    Vique's Law:
MESARD@BBN.COM                 A man without religion is like a fish
BBN, Cambridge, MA             without a bicycle.

allbery@ncoast.UUCP (Brandon S. Allbery) (12/15/88)

As quoted from <33245@bbn.COM> by mesard@bbn.com (Wayne Mesard):
+---------------
| Here's a little script I whipped up this morning.  It repeatedly applies
| a command (with optional arguments) to a bunch of folders.  I wrote it
| because I'm forever forgetting where I refile'd a message to the night
| before, and wanted a quick n dirty way to look for it.
+---------------

As long as we're posting our usefuls...

I often save Usenet postings -- especially sources -- with rcvstore (in
fact, I've defined 'S' as a macro in rn which expands to
"|/u/mh/lib/rcvstore +", so I can type "Sfolder<cr>" and save something).
Of course, the time comes when I want to *do* something with it.  To
acilitate this, I whipped together a basic shell script and use variations
on it for applying commands to arbitrary messages.

Included below are "muns" (MH unshar) and "mpatch" (MH patch); the former is
pretty trivial, the latter does some intelligent things like extracting the
"patch" command line from lwall's metaconfig-generated patches so that "-p"
flags, etc. will automatically be included as needed.  Also included is
"muuns", an MH front-end for "uuns" (also included).  "Uuns" is a perl
script for unpacking multipart uuencoded postings in the format used by
comp.binaries.ibm.pc.  (Warning:  the coding of "uuns" may seem a bit
baroque, I'm still trying to make perl work correctly with ncoast's
brain-damaged compiler and some things that *should* work have to be coded
oddly to work around strangenesses.)

++Brandon

----------------------------------- cut here -----------------------------------
#! /bin/sh
# This file was wrapped with "dummyshar".  "sh" this file to extract.
# Contents:	muns	mpatch	muuns	uuns
echo extracting 'muns'
if test -f 'muns' -a -z "$1"; then echo Not overwriting 'muns'; else
sed 's/^X//' << \EOF > 'muns'
Xif [ $# = 0 ]; then
X	echo "usage: muns [+folder] msgs [[+folder] msgs] ..." >&2
X	exit 1
Xfi
Xwhile [ $# -gt 0 ]; do
X	folder=
X	case "$1" in
X	+*)	if [ $# = 1 ]; then
X			mhpath "$1" > /dev/null
X			exit 0
X		fi
X		folder="$1"
X		shift
X		;;
X	esac
X	for msg in `mhpath $folder "$1"`; do
X		echo "shar: unpacking ${msg}"
X		sed -e '1,/^[:#]/d' "$msg" | sh
X	done
X	shift
Xdone
EOF
chars=`wc -c < 'muns'`
if test $chars !=     380; then echo 'muns' is $chars characters, should be     380 characters!; fi
fi
echo extracting 'mpatch'
if test -f 'mpatch' -a -z "$1"; then echo Not overwriting 'mpatch'; else
sed 's/^X//' << \EOF > 'mpatch'
X:
X# apply a patch, extracting from the file the proper command if possible
X# and if not, defaulting.  (This picks up any necessary "-p" flags, etc.)
X# MH version
X
Xif [ $# = 0 ]; then
X	echo "usage: mpatch [+folder] msgs [[+folder] msgs] ..." >&2
X	exit 1
Xfi
Xwhile [ $# -gt 0 ]; do
X	folder=
X	case "$1" in
X	+*)	if [ $# = 1 ]; then
X			mhpath "$1" > /dev/null
X			exit 0
X		fi
X		folder="$1"
X		shift
X		;;
X	esac
X	for msg in `mhpath $folder "$1"`; do
X		patch="`sed -n 's/^.*Outside of rn, say \"cd DIR; \([^<][^<]*\).*$/\1/p' $msg`"
X		case "x$patch" in
X		x)	patch="patch -N" ;;
X		esac
X# this also makes the message current so we can use "mpatch next"...
X		show -noshowproc $folder "$1" | eval "$patch"
X	done
X	shift
Xdone
EOF
chars=`wc -c < 'mpatch'`
if test $chars !=     739; then echo 'mpatch' is $chars characters, should be     739 characters!; fi
fi
echo extracting 'muuns'
if test -f 'muuns' -a -z "$1"; then echo Not overwriting 'muuns'; else
sed 's/^X//' << \EOF > 'muuns'
Xif [ $# = 0 ]; then
X	echo "usage: muuns [+folder] msgs [[+folder] msgs] ..." >&2
X	exit 1
Xfi
Xwhile [ $# -gt 0 ]; do
X	folder=
X	case "$1" in
X	+*)	if [ $# = 1 ]; then
X			mhpath "$1" > /dev/null
X			exit 0
X		fi
X		folder="$1"
X		shift
X		;;
X	esac
X	for msg in `mhpath "$folder" "$1"`; do
X		uuns "$msg"
X	done
X	shift
Xdone
EOF
chars=`wc -c < 'muuns'`
if test $chars !=     330; then echo 'muuns' is $chars characters, should be     330 characters!; fi
fi
echo extracting 'uuns'
if test -f 'uuns' -a -z "$1"; then echo Not overwriting 'uuns'; else
sed 's/^X//' << \EOF > 'uuns'
Xeval "exec perl -S $0 $*"
X	if $running_under_a_shell;
X
X#
X# (attempt to) unshar a comp.binaries.ibm.pc-style multipart uuencode
X#
X
Xunshift(@ARGV, '-') if $#ARGV < 0;
Xwhile ($thisfile = shift(@ARGV)) {
X	print "extracting $thisfile\n";
X	open(part, $thisfile);
X	# collect header information
X	$thispart = 1;
X	$lastpart = 1;
X	while (<part>) {
X		if (/^part([0-9][0-9])\/([0-9][0-9])$/) {
X			$thispart = $1;
X			$lastpart = $2;
X			next;
X		}
X		last if /^BEGIN--/;
X	}
X	
X	# now process submission to line starting with END--
X	$outemp = '>part' . $thispart;
X	open(outemp);
X	while (<part>) {
X		last if /^END--/;
X		print outemp;
X	}
X	close(outemp);
X}
X
X# all done?
Xprint "checking...";
Xopen(filelist, 'ls part[0-9][0-9]|');
X$haveall = 1;
X$current = 1;
Xwhile (<filelist>) {
X	$thisone = $_;
X	$thisone =~ s/part//;
X	chop($thisone);
X	print " ", $thisone + 0;
X	$haveall = 0 if $thisone != $current;
X	$current++;
X}
Xprint " (of ", $lastpart + 0, " parts)\n";
Xclose(filelist);
Xexit unless $haveall && $current == $lastpart + 1;
X
X# combine and uudecode parts
Xprint "decoding\n";
Xopen(uudecode, '|uudecode');
X$current = 1;
Xwhile ($current <= $lastpart) {
X	open(part, 'part' . sprintf('%02d', $current));
X	while (<part>) {
X		print uudecode;
X	}
X	close(part);
X	$current++;
X}
Xclose(uudecode);
Xsystem('rm -f part[0-9][0-9]');
EOF
chars=`wc -c < 'uuns'`
if test $chars !=    1358; then echo 'uuns' is $chars characters, should be    1358 characters!; fi
fi
exit 0
-- 
Brandon S. Allbery, comp.sources.misc moderator and one admin of ncoast PA UN*X
uunet!hal.cwru.edu!ncoast!allbery		    ncoast!allbery@hal.cwru.edu
comp.sources.misc is moving off ncoast -- please do NOT send submissions direct
      Send comp.sources.misc submissions to comp-sources-misc@<backbone>.