#! /bin/sh # ^^^ SHELL SHOULD HAVE BUILT-IN echo FOR SPEED # $Header: /home/jerry/.bin/RCS/mhlinks,v 1.4 92/08/09 23:26:32 jerry mh_contrib $ ### mhlinks - find MH message(s) in all folders linked to named message(s) ### Usage: mhlinks [folder] [msgs] ## ## mhlinks SEARCHES THROUGH A DATABASE OF ALL YOUR MH MESSAGES. IT LISTS ## THE MESSAGE NUMBERS LINKED TO THE CURRENT MESSAGE OR TO THE MESSAGE(S) ## YOU NAME ON THE COMMAND LINE. THE DATABASE IS BUILD EVERY NIGHT ## (OR HOWEVER OFTEN YOU DO IT) BY THE PROGRAM mhlinks.build. ## ## USE THIS SCRIPT TO FIND ALL THE LINKS TO A MESSAGE YOU NEED TO ## REMOVE... OR FOR ANY REASON YOU NEED TO FIND ALL THE LINKS. ## THIS SCRIPT ISN'T FOOLPROOF; IF A MESSAGE HAS BEEN REPLACED RECENTLY, ## OR IF YOU'VE CHANGED THE LINKS, USE THE scanlinks SCRIPT INSTEAD. ## THIS SCRIPT WILL TRY TO WARN YOU WHEN THAT'S A PROBLEM. # TABSTOPS IN THIS CODE SET AT 4 # # USE AT YOUR OWN RISK. SEEMS TO WORK, BUT IT'S YOUR RESPONSIBILITY! # PLEASE TELL ME ABOUT BUGS AND FIXES: Jerry Peek, jerry@ora.com builder=mhlinks.build # PROGRAM THAT BUILDS $db FILE FROM at OR cron current=scanlinks # PROGRAM THAT SEARCHES $mhdir, NOT $db filelist=/tmp/MHLINKf$$ # UNCOMPRESSED $db FILE folopts="-nolist -nototal -nopack -fast" # OVERRIDE MH PROFILE mh=/usr/local/mh # WHERE MH PROGRAMS LIVE mhdir="`$mh/mhpath +`" || exit 1 # USER'S MH MAIL DIRECTORY myname="`basename $0`" # NAME OF THIS PROGRAM scanopts="-noclear -noheader -noreverse" # OVERRIDE MH PROFILE search=/home/jerry/.bin/bm # FAST SEARCH (OR JUST USE grep) smsglist=/tmp/MHLINKm$$ # MESSAGE(S) WE WANT TO FIND stat=1 # DEFAULT EXIT STATUS; SET TO 0 BEFORE NORMAL EXIT zcat=/usr/ucb/zcat # UNCOMPRESSES $db FILE umask 077 # MAKE TEMP FILES PRIVATE trap 'rm -f $filelist $smsglist; exit $stat' 0 1 2 15 # MESSAGE DATABASE FILE WITH LINES THAT LIST EACH I-NUMBER AND # MESSAGE(S) WITH THAT I-NUMBER... LIKE THIS: # 123 a/234 prog/c/14 # 127 a/453 misc/24 reports/17 # EACH LINE ENDS WITH A SPACE. SO, EACH MESSAGE HAS SPACES AROUND IT. db=$mhdir/mhlinks.list.Z $zcat $db > $filelist || { echo 1>&2 "$myname: can't read database '$db'. Be sure '$builder' script is running from 'cron'." exit 1 } while : do case "$1" in "") break ;; [+@]*) sfolder="$1" ;; # "SOURCE" FOLDER (LOOK FOR LINKS FROM HERE) -*) echo "$myname: warning: ignoring '$1'." 1>&2 ;; *) smsgargs="$smsgargs $1" ;; # "SOURCE" MESSAGES esac shift done # DON'T JUST DO folder +xxxx; IF FOLDER DOESN'T EXIST, IT'LL ASK create? # IF sfolder WASN'T SET ON COMMAND LINE, DEFAULTS TO CURRENT FOLDER. # NOTE: NEW MH 6.7.2 %(folder) ESCAPE FOR scan MIGHT REPLACE sfolname= LINE: sfolpath=`$mh/mhpath $sfolder` if [ $? -ne 0 -o \( ! -d "$sfolpath" \) ] then echo "$myname: quitting: missing '$sfolder'?" 1>&2; exit else sfolname="`$mh/folder $folopts $sfolder`" || exit fi if mhdir="`$mh/mhpath +`" then cd $mhdir || exit else echo "$myname: quitting: problem with MH directory." 1>&2 exit fi # IF NO MESSAGES NAMED ON COMMAND LINE, USE CURRENT MESSAGE IN FOLDER. # STRIP OFF $mhdir PATH; ADD SINGLE SPACE AT START AND END, LIKE: # inbox/23 $mh/scan $scanopts -format "${sfolname}/%(msg)" ${smsgargs=cur} > $smsglist || exit # QUICK HACK. CAN WE BE MORE EFFICIENT FOR LOTS OF MESSAGES # BY MAKING A PATTERN FILE FOR fgrep, sed, ETC? for file in `cat $smsglist` do # LIST MESSAGE; inum GOES INTO $2, FILENAMES INTO $3 ON. # SPACES AROUND NAME MAKE SURE NO OTHER MESSAGES ARE MATCHED: set x `$search " $file " $filelist` case $# in 1) echo 1>&2 "$myname: can't find '$file' in database. Try '$current' program instead." ;; *) # COMPARE LAST-INODE-MODIFIED TIME OF DATABASE TO THE MESSAGE. # IF THE MESSAGE COMES FIRST, WARN USER. # THIS COULD BE DONE FASTER, ESPECIALLY FOR LONG $smsglist! case "`/bin/ls -cdt $db $file`" in ${db}*) ;; *) echo "$myname: WARNING: database entry for $file may be old. Try '$current' program instead." 1>&2 ;; esac # STEP THROUGH MESSAGES, ARRANGE LIST STARTING WITH $file: out= shift; shift # GET RID OF x AND I-NUMBER for arg do case "$arg" in $file) ;; *) out="$out $arg" ;; esac done echo $file $out ;; esac done stat=0 # SORT OF PRESUMPTUOUS exit