[alt.sources] Keep your personal copy of SIMIBM.IDX up to date

raymond@math.berkeley.edu (Raymond Chen) (03/03/90)

In comp.binaries.ibm.pc.d and comp.sys.ibm.pc (and sometimes even
comp.sys.ibm.pc.programmer) there are frequent requests for programs
that do X.  Very often, a program to do X exists on SIMTEL20, so I
wrote this collection of scripts to keep my index of SIMTEL20's
archive up-to-date.

If everybody used programs like these, wouldn't the world be a better place?
(Okay, maybe not.)


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README simstart.pl lookup simtel.update
# Wrapped by raymond@spam on Fri Mar  2 15:48:37 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(3790 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis package contains a trio of perl scripts for keeping track
Xof the files on SIMTEL20.  Here's how you use them:
X
XINSTALLATION:
X
X	Create a directory called "index" off your home directory.
X
X	Get a copy of SIMIBM.IDX from SIMTEL20 and put it in your 
X	index directory.
X
X	Type
X		simstart >simibm.new
X
X	rename simibm.new to simibm.idx (thus overwriting the original)
X	and (optionally) compress it to save disk space.
X
XUSAGE:
X
X	To look up a program type
X
X		lookup keyword
X
X	For example, I could type  "lookup environment".  Any program which
X	has the word "environment" in its "Description" field will be
X	printed, along with the directory it can be found in.  The keyword
X	can be any regular expression.  Case is ignored in the search.
X
X	I use this program when replying to articles in comp.sys.ibm.pc
X	and comp.binaries.ibm.pc.d where people ask "Is there a program
X	that does X?"  I just type "lookup X", edit the output, and
X	mail it.
X
XUPDATING:
X
X	Periodically, Keith Petersen posts a list of all the files that
X	have been added to the SIMTEL20 archives in the past month.
X	Save them to some file, say "new.files".  You can concatenate
X	a whole bunch of updates together.  You don't have to trim
X	off leading or trailing gunk; the update program will skip
X	over them.
X
X	When you think you've collected enough stuff, type
X
X		simtel.update new.files
X
X	(If no filename is provided, it looks for the new files from
X	stdin.)  The program will apply the changes to your simibm.idx
X	file and produce a file called "simibm.new" in your index directory.
X
X	The program outputs the name of each directory as it processes
X	it.  It prints a "+" when the new.files contains a new file,
X	and it prints a "." when the new.files contains a file that
X	is already on the list.  (This way you can feed the same file
X	to simtel.update multiple times and it won't cause problems.)
X	After checking that simtel.new is all right, rename it to simtel.idx
X	and you're back in business.
X
X	If you give the option -q, then simtel.update operates quietly.
X
X	Since Keith's monthly article does not list files which have
X	been deleted, you will have to go through the simibm.new file
X	and delete the files which have been superseded.  (For example,
X	if a file BLURFL31.ARC is added which is version 3.1 of the Blurfl
X	program, the old version BLURFL30.ARC will still be on the list
X	even though Keith has probably deleted BLURFL30.ARC from the
X	Simtel20 archives.)
X
X	If you give the option -m, then simtel.update will prepend a
X	nonprinting control character (currently Ctrl-A) to all newly-added
X	files.  This way you can edit the simibm.idx file searching for
X	Ctrl-A and manually delete files which have been superseded.
X
XBUGS:
X
X	simtel.update is sensitive to the layout that Keith uses in
X	his monthly updates.  If he changes the way he posts the
X	updates, simtel.update will either [1] fail to notice that
X	a file has been added to the archives, or [2] accidentally
X	duplicate files.
X
X	lookup does not put \b's around your regexp.  So a search
X	for "test" will match "testing", "untested", and "contest".
X
X	The index is stored in printable ASCII, except that blank
X	lines are changed into lines containing the single character `~'.
X	Watch for that if you feel like printing the index.  
X
XWISH LIST:
X
X	A way for Keith to tell us when he has deleted files from
X	the SIMTEL20 archive so no manual editing of the simibm.new
X	file is necessary.  Perhaps something like
X
XDirectory PD1:<MSDOS.BLURFL>
X Filename  Type   Size   Date    Description
X===========================================================================
XBLURFL30.ARC  Deleted (Superseded by BLURFL31.ARC)
XBLURFL31.ARC  B  231947  890411  The Blurfl command language, version 3.1
X
XAUTHOR:
X	Raymond Chen (raymond@math.berkeley.edu).  Mail bug reports here.
END_OF_FILE
if test 3790 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'simstart.pl' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'simstart.pl'\"
else
echo shar: Extracting \"'simstart.pl'\" \(924 characters\)
sed "s/^X//" >'simstart.pl' <<'END_OF_FILE'
X#!/usr/custom/bin/perl
X#
X# simstart.pl
X#
X# Converts simibm.idx into a form that simtel.update and lookup can use.
X#
Xformat stdout =
X@<<<<<<<<<<<< @<<@>>>>>  @<<<<<  @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X$file,       $at,$size,  $date,  $comment
X.
X
X$simfile = "simibm.idx";
X
X$= = 0;				# No automatic page breaks
X
Xopen(in, $simfile);		# Open simibm.idx
Xwhile (<in>)			# Read one line
X{
X        ($dev,$dir,$file,$size,$type,$date,$comment) = 
X		/^"(.*)","(.*)","(.*)",.*,(.*),(.),(.*),"(.*)"/;
X	$at = ($type == 8) ? "B" : "A";
X        if ( $ldev ne $dev || $ldir ne $dir ) {		# New page
X               print "~\nDirectory $dev$dir\n";
X               print "Filename    Type Length  Date    Description\n";
X               print "===============================================================================\n";
X        }
X        write();		# Write the line
X        $ldev = $dev;
X        $ldir = $dir;
X}
X
Xprint "~\n";
END_OF_FILE
if test 924 -ne `wc -c <'simstart.pl'`; then
    echo shar: \"'simstart.pl'\" unpacked with wrong size!
fi
chmod +x 'simstart.pl'
# end of 'simstart.pl'
fi
if test -f 'lookup' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lookup'\"
else
echo shar: Extracting \"'lookup'\" \(567 characters\)
sed "s/^X//" >'lookup' <<'END_OF_FILE'
X#!/usr/custom/bin/perl
X
X# lookup: Looks up a word/phrase in the simibm.idx file
X
Xdie "usage: $0 word" if $#ARGV = $[;
X
X$pattern = shift(ARGV);
X
X$HOME = $ENV{"HOME"};
X
X$simibm = "$HOME/index/simibm.idx";
Xopen(in, "<".$simibm) || 
Xopen(in, "zcat $simibm |") ||
Xdie "Couldn't open $simibm";
X
X$dir = $prevdir = "";
X
Xeval '
Xsub printit {
X    if (/' . $pattern . '/i) {
X    print $dir if $dir ne $prevdir;
X    $prevdir = $dir;
X    print;
X    }
X}';
X
Xwhile (<in>) { 
X  if (/^~$/) {
X     $dir = <in>; 
X     $_ = <in>; $_ = <in>; # skip two header lines
X  }
X  do printit();
X}
X
END_OF_FILE
if test 567 -ne `wc -c <'lookup'`; then
    echo shar: \"'lookup'\" unpacked with wrong size!
fi
chmod +x 'lookup'
# end of 'lookup'
fi
if test -f 'simtel.update' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'simtel.update'\"
else
echo shar: Extracting \"'simtel.update'\" \(2886 characters\)
sed "s/^X//" >'simtel.update' <<'END_OF_FILE'
X#!/usr/custom/bin/perl -s
X
X# simtel.update:  Updates the master file from Keith's Monthly Postings
X
X$HOME = $ENV{"HOME"};
X$simdir = "$HOME/index/";
X
X$simibm = $simdir . "simibm.idx";
X$simnew = ">" . $simdir . "simibm.new";
X
Xopen(in, "<".$simibm) || 
X($simnew = "| compress $simnew.Z",
X open(in, "zcat $simibm |")) || die "Couldn't open $simibm";
X
Xopen(out, $simnew) || "Couldn't open $simnew";
X
X# Plan of attack:
X#
X# Start in state "skipping".
X#
X# Skipping:  Read from <> until /^Directory/.  Save the directory name
X#	     and call "find_directory".  Then switch to state "matching".
X#
X# Matching:  Read a filename from <>.  If a blank line, switch to Skipping.
X#	     Otherwise call "find_match" to insert the guy.
X
X$added = $unchanged = $directory_count = 0;
X$marker = $m ? "\001" : "";
X$skipping = 1;
X$prevline = <in>;	# our peek-ahead buffer.
X
Xwhile ($skipping > 0) {
X  $skipping = do skip() if ($skipping == 1);
X  $skipping = do match() if ($skipping == 2);
X}
X
X# skip:  Skip to a new directory.
Xsub skip {
X  while (<>) {
X    next unless /^Directory/;
X    $dirname = $_;
X    # If it's a genuine directory change, we'll have these headers.
X    next unless (<> eq " Filename   Type Length   Date    Description\n");
X    next unless (<> eq "==============================================\n");
X    return 2 * do find_directory();
X  }
X  # if we get here, we've hit EOF.
X  return 0;
X}
X
X# find_directory:  Find the directory in $dirname, 
X# outputting the gunk we skipped over to get there.
X
Xsub find_directory {
X  chop($_ = $dirname);
X  print "\n", $_ if !$q;# tell the user we're looking for a directory
X  print out $prevline;	# output the tilde.
X  while (<in>) {
X    print out;		# display the next line in the file.
X    next if ($_ ne $dirname); # blip past stuff we don't want.
X
X    print out $_ = <in>;	# blip the header
X    print out $_ = <in>;	# blip the divider
X    $prevline = <in>;
X    $directory_count++;
X    return 1;		# keep going
X  }
X  # if we get here, we've hit EOF.  So complain.
X  print stderr "Couldn't find directory $dirname";
X  $prevline = "";
X  return 0;
X}
X
Xsub match {
X  return 0 unless ($file = <>);
X  return 1 if ($file eq "\n");
X  return 2 * do find_match();
X}
X
X# find-match:  Filename to match is in $file.
X
Xsub find_match {
X  while ($prevline lt $file) {  # while haven't found the right place
X    print out $prevline;	# dump the previous line
X    return 0 unless $prevline = <in>; # get the next line
X  }
X  if ($prevline eq $file) { 
X    $unchanged++; 
X    print "." if !$q;
X    return 1; 
X  }
X  print out $marker, $file;	# insert the new guy
X  print "+" if !$q;		# let user know
X  $added++;			# bump the count.
X  return 1;
X}
X
X# cleanup
X
X
Xprint	"\n",
X	$directory_count, " directories, ", 
X	$unchanged, " unchanged, ",
X	$added, " added\n" if !$q;
X
Xprint out $prevline;
Xprint out <in>;
Xclose(in);
X
X$? = 0; close(out);
X
Xdie "Error writing output: " . $! if $?;
END_OF_FILE
if test 2886 -ne `wc -c <'simtel.update'`; then
    echo shar: \"'simtel.update'\" unpacked with wrong size!
fi
chmod +x 'simtel.update'
# end of 'simtel.update'
fi
echo shar: End of shell archive.
exit 0
--
raymond@math.berkeley.edu    Maintainer of the csip Frequently Asked Questions