head	3.7;
access;
symbols;
locks;
comment	@# @;


3.7
date	2001.11.16.02.08.16;	author cjmorlan;	state Exp;
branches;
next	3.6;

3.6
date	2001.09.25.18.52.26;	author cjmorlan;	state Exp;
branches;
next	3.5;

3.5
date	2001.03.06.18.47.33;	author cjmorlan;	state Exp;
branches;
next	3.4;

3.4
date	2001.03.06.18.09.55;	author cjmorlan;	state Exp;
branches;
next	3.3;

3.3
date	2001.03.06.18.08.37;	author cjmorlan;	state Exp;
branches;
next	3.2;

3.2
date	99.10.21.20.32.13;	author cjmorlan;	state Exp;
branches;
next	3.1;

3.1
date	99.10.20.18.04.54;	author cjmorlan;	state Exp;
branches;
next	3.0;

3.0
date	99.09.24.04.45.03;	author cmorland;	state Exp;
branches;
next	;


desc
@main source file
@


3.7
log
@Applied patch from Devin Reade
@
text
@#!/usr/bin/perl

@@temp = split(' ', '$Revision: 3.6 $ ');
$version = $temp[1];

use File::Copy;
use Getopt::Std;
use File::Path;

$homedir = $ENV{"HOME"} || $ENV{"LOGDIR"} || (getpwuid($<))[7];
if(substr($homedir,-1,1) ne "/") {$homedir = $homedir . "/";}

if($< == 0) {
	$configfile = "%%ETCPATH%%/changetrack.conf";
	$historypath = "%%HISTORYPATH%%/";
	}
else {
	$configfile =  $homedir . "changetrack.conf";
	$historypath = $homedir . "changetrack.output/";
	}

$error = getopts('hc:d:a:m:erqM:vuo:');

if($opt_h || !$error || @@ARGV)
	{
	if(@@ARGV) {print "Unknown option: @@ARGV\n";}
	print "
This is changetrack, version $version.
  This program keeps track of changes made to files.

  -h                          display this help and exit
  -c configfile               Set name of configuration file
  -d directory                Set output directory
  -e                          Make ed files for each one
  -r                          Don't use RCS
  -q                          Quiet mode -- display only important messages
  -m message                  Put a message in each file.
                              Useful for indicating reboots, etc.
                              Some special characters will break sh.
  -M message                  Like -m, except message is only printed for 
                              modified files.
  -v                          print version and exit.
  -u                          unified diffs. Tested with GNU diff
  -o emailaddress             Mail output to emailaddress. This is
                              supplemental to emails specified in the
                              config file.
";
	exit 1;  
	}

if ($opt_q) {
    $rcs_quiet = "-q";
} else {
    $rcs_quiet = "";
}
if($opt_v) {print "$version\n"; exit;}            # just the version
if($opt_c) {$configfile = $opt_c;}                # file storing files to check
if($opt_d) {$historypath = $opt_d;}               # directory to store output in
if($opt_u) {$diffargs = "-u";}                    # unified diffs

$message = $opt_m;                                # message (for reboots, etc.)
$Message = $opt_M;                                # other message.
if(substr($historypath,-1) ne "/") {$historypath = $historypath . "/";}
                                                  # needs to be a folder; forgot the '/'?

mkpath("$historypath",0,0711);                    # create it if it doesn't exist
mkpath("$historypath/RCS",0,0711);                # create RCS directory if it doesn't exist

$date = scalar localtime;                         # store the date in $date

open(CONFIG, "$configfile") or die "Exiting: can't open $configfile:$!\n";

# translate 'ls -l' to octal
sub getoctalbits {
    $out = "";
    $in = $_[0];
    $in = substr($in,1,9);
    @@tmp = (substr($in,0,3),substr($in,3,3),substr($in,6,3));
    foreach $one (@@tmp) {
	$num = 0;
	if(substr($one,0,1) ne "-") {$num += 4;}
	if(substr($one,1,1) ne "-") {$num += 2;}
	if(substr($one,2,1) ne "-") {$num += 1;}
	$out = $out . $num;
    }
    return $out;
}

if(!$opt_q) {print "Using $configfile, writing to $historypath\n";};
$emailaddresses = "";

while(<CONFIG>) {
    # for each config line
    chomp;
    
    #ignore comments
    if(m/\s*#/) {
       next; }
    
    # ignore blank lines
    if(m/^\s*$/) {
	next; }
       
    ($filename,$email,$options)=split(/\s+:\s+/); 
    # get the info
    @@emails = split(/\s+/,$email);

    # add any address specified by -o on command line
    if (defined($opt_o) && ($opt_o ne '')) {
	push @@emails, $opt_o;
    }

    # list of emails for this file
    foreach $email (@@emails) {
	if(($x=index($emailaddresses,$email,0)) == -1) {
	    # if the user is not yet in the list, add them
	    $emailaddresses .= " " . $email;
	}
    }
    
    # make these relative to user's home directory
    if(substr($filename,0,1) ne "/") {
	$filename = $homedir . $filename;
    }
		
    open(LS,"ls -l -d $filename |");              # match wildcards like 'ls'
    $anyfile = 0;                                 # flag in case we find nothing
    while(<LS>) {                                 # may match several (wildcards)
	@@diff = ();
	@@ed = ();
	chomp;
	# the next line should be gone, and just a maximal match. How?
	while(m/  /) {s/  / /};
	@@temp = split(/\s+/);
	$realfile = $temp[8];                     # filename
	if((substr($realfile,-1,1) eq "~") && ($filename =~ m/\*/)) {
	    # it's a backup file not explicitly included	
	    if(!$opt_q)
	    { print "Skipping backup file $realfile\n";}
	    next;	
	}
	
	$filebits = $temp[0];                     # permissions string
	if(substr($filebits,0,1) eq "d")
	{
	    if(!$opt_q)
	    { print "Skipping directory $realfile\n";}
	    
	    next;
	}
	$anyfile = 1;                             # at least one real file found
	$compfile = $realfile;                    # file for comparison
	
	@@temp = stat $realfile;                   # other statistics:
	$fileuid = $temp[4];                      # owner,
	$filegid = $temp[5];                      # group
	
	while($compfile =~ m/\//) {               # replace '/' with ':'
	    $compfile =~ s/\//:/;}

	$compfile =~ s/^://;                      # trash leading ':'
	
	$compfile = $historypath . $compfile;
	$logfile = $compfile . ".history";        # stores past events
	$statfile = $compfile . ".statistics";    # stores current file info
	$origfile = $compfile . ".original";      # stores name of original file
	if($opt_e) {
	    $outfile = $compfile . ".edout";      # output from ed script
	    $edfile = $compfile . ".ed";          # ed script
	}
	$yestfile = $compfile . ".yesterday";     # stores current data
	
	if(!open(OLD,"$yestfile")) {              # can't open yesterday, doesn't exist.
	    @@diff = (@@diff, "New file $realfile\n");
	    if($opt_e) {
		@@ed = (@@ed,"# cat this file into ed, eg 'cat $edfile | ed'\n");
		@@ed = (@@ed,"# output goes into $outfile\n");
		@@ed = (@@ed,"# edit this file to get rid of commands you don't want.\n");
		@@ed = (@@ed,"\n!cp $origfile $outfile\n");
		@@ed = (@@ed,"E $outfile\n");
		copy($realfile, $origfile);       # keep a copy of original file
	    }

	    copy($realfile, $yestfile);           # so no changes noted today.
	    open (STAT, ">$statfile") or die "Exiting: can't open > $statfile:$!\n";
	    print STAT "$filebits\n$fileuid\n$filegid\n";
	    close(STAT);
	    if(!$opt_r) {
		`cp $realfile $compfile`;
		chdir($historypath);
		system("rcs $rcs_quiet -i -t-'this is $realfile' $compfile");
		`rcs $rcs_quiet -U $compfile`;
		`rm $compfile -f`;
	    }
	}
	else {
	    # only opening it to see if it exists.
	    close(OLD);
	}
	
	open(STAT, "$statfile") or die "Exiting: can't open < $statfile:$!\n";
	$oldfilebits = <STAT>;                    # get the comparison permissions
	chomp($oldfilebits);
	
	$oldfileuid = <STAT>;                     # get the old owner
	chomp($oldfileuid);

	$oldfilegid = <STAT>;                     # get the old group
	chomp($oldfilegid);

	close(STAT);

	$statschanged = 0;                        # 'nothing changed' flag

	$newnums = getoctalbits($filebits);
	if($oldfilebits ne $filebits) {
	    @@diff = (@@diff, "File permissions changed: was $oldfilebits now $filebits\n");
	    @@ed = (@@ed, "!chmod $newnums $outfile\n");
	    $statschanged = 1;
	}

	if($oldfileuid != $fileuid) {
	    $oldusername = getpwuid($oldfileuid);
	    $username = getpwuid($fileuid);
	    @@diff = (@@diff, "Owner changed: was $oldusername ($oldfileuid) now $username ($fileuid)\n");
	    @@ed = (@@ed,"!chown $fileuid $outfile\n");
	    $statschanged = 1;
	}

	if($oldfilegid != $filegid) {
	    $oldgroupname = getgrgid($oldfilegid);
	    $groupname = getgrgid($filegid);
	    @@diff = (@@diff, "Group changed: was $oldgroupname ($oldfilegid) now $groupname ($filegid)\n");
	    @@ed = (@@ed,"!chgrp $filegid $outfile\n");
	    $statschanged = 1;
	}

	if($statschanged) {
	    open(STAT, ">$statfile") or die "Exiting: can't open to rewrite $statfile:$!\n";
	    print STAT "$filebits\n$fileuid\n$filegid\n";
	    close(STAT);
	}

	open(DIFF, "diff $diffargs $yestfile $realfile |") or die "Exiting: can't run diff:$!\n";
	
	if(!$opt_q) {
	    print "$realfile";};
   	
	while(<DIFF>) {

	    # line starts with < or > or not unified header
	    if(m/^\</ || m/^\>/ || ($opt_u && !(m/^\-\-\-/||m/^\+\+\+/))) {
		if(!$opt_q) {
		    print ".";};                  # indicate progress
		
		@@diff = (@@diff, $_);              # get that line
	    }
	    $diff = 1;                            # flag the changes
     	}
	close(DIFF);
	
	if($diff) {
	    open(DIFF, "diff -e $yestfile $realfile |") or die "Can't do diff -e:$!\n";
	    # use -e to create ed commands
	    while(<DIFF>) {
		@@ed = (@@ed,"$_");                 # get the 'ed'-styled diffs. No need to understand them.
	    }
	    close(DIFF);
	}
	
	if(!$opt_q) {print "\n";};
	
	if(@@diff || $message) {                   # there is something to add to the output file
	    # deal with emailing
	    foreach $email (@@emails)
	    {
		# it's ok to append to things that don't exist.
		$emessages{$email} .= "Changes made to $realfile follow:\n";
		foreach $line (@@diff) {
		    $emessages{$email} .= "  $line";
		}
		if($message) {
		    $emessages{$email} .= $message;}
		# don't forget the message
		$emessages{$email} .= "\n";       # separate from next file
	    }
	    
	    open(LOG,">>$logfile") or die "Exiting: can't open $logfile:$!\n";
	    print LOG "Changes made on $date follow:\n";
	    foreach $line (@@diff)                     
	    {
		print LOG "  $line";              # save the line
	    }
	    if($message) {
		print LOG "  $message\n";         # save any message (nb after all changes)
	    }
	    if(@@diff && $Message) {
		print LOG $Message;               # only if there are changes
	    }
	    print LOG "\n";                       # and a blank line
	    copy($realfile, $yestfile);           # save the file for next time
	    close(LOG);
	    
	    if($opt_e)
	    {
		open(ED,">>$edfile") or die "Exiting: can't open $edfile:$!\n";
		foreach $line (@@ed) {
		    print ED $line;               # save the edits as well
		}	
		print ED "w\n";                   # make sure ed writes the changes when run.
		close(ED);
	    }
	    
	    if(!$opt_r) {
		chdir($historypath) or die "Can't chdir to $historypath for ci: $!\n";
		my $quiet = "";
		print "cp $realfile $compfile\n" unless defined($opt_q);
		`cp $realfile $compfile`;         # make backup copy
		#`mv $realfile $realfile.track`;  # copy backwards, to keep modification date
		#`cp $realfile.track $realfile`;  # make backup copy
		system("ci $rcs_quiet -m'modification of $realfile on $date' -l $compfile");
		`rm $compfile`;
	    }
	}
    }
    
    close(LS);
    if(!$anyfile) {
	# no file was matched by 'ls', so create message for misspelled files
	$origfile = $filename;
	while($filename =~ m/\//) {$filename =~ s/\//:/;}
	if(substr($filename,0,1) eq ":") {$filename = substr($filename,1);}
	open(LOG, ">>$historypath$filename");
	print LOG "$date No files match `$origfile'\n";
	close(LOG);
    }
}

# Exactly one of the next two lines should be commented out.
# If Mail::Sendmail (from CPAN) is installed, comment out the exit(),
# or else the program will terminate without sending emails.
# If Mail::Sendmail is not installed, comment out the 'use', or else
# this script will fail to run.
#
# Also, the $mailfrom variable must be a valid email address (or at least
# be from a valid domain).  Otherwise, outbound mail may get rejected by an
# intermediate MTA before it is delivered to your mailbox (the old
# 'changetrack@@localhost' address is blocked by some anti-spam filters).

#use Mail::Sendmail;
exit();

my $mailfrom = '%%MAILFROM%%';

if($emailaddresses) {

    @@emails = split(/\s+/,$emailaddresses);
	
    foreach $email (@@emails) {
	if(($email) && ($message = $emessages{$email})) {
	    %mail = (To => $email,
		     From => $mailfrom,
		     Message => "$message",
		     Subject => "changed files: $date"
		     );
	    
	    sendmail(%mail) or warn $Mail::Sendmail::error;
	}
    }
}

# $Log: changetrack,v $
# Revision 3.6  2001/09/25 18:52:26  cjmorlan
# Applied patch from Devin Reade to fix -o option.
#
# Revision 3.5  2001/03/06 18:47:33  cjmorlan
# Intented according to emacs default.
# Fixed some @@foo[]
#
# Revision 3.4  2001/03/06 18:09:55  cjmorlan
# Made version match RCS revision.
#
# Revision 3.3  2001/03/06 18:08:37  cjmorlan
# Added change from Ian Zimmerman, fixing RCS integration bug.
#
# Revision 3.2  1999/10/21 20:32:13  cjmorlan
# added email features, cleaned.
# Release version 2
#
# Revision 3.1  1999/10/20 18:04:54  cjmorlan
# replaced quotewords with split
#
# Revision 3.0  1999/09/24 04:45:03  cmorland
# To add ideas from FSF
#

@


3.6
log
@Applied patch from Devin Reade to fix -o option.
@
text
@d3 1
a3 1
@@temp = split(' ', '$Revision: 3.5 $ ');
d14 2
a15 2
	$configfile = "/etc/changetrack.conf";
	$historypath = "/changetrack.output/";
d51 5
d191 2
a192 2
		system("rcs -i -t-'this is $realfile' $compfile");
		`rcs -U $compfile`;
d316 2
a317 1
		print "cp $realfile $compfile\n";
d321 1
a321 1
		system("ci -m'modification of $realfile on $date' -l $compfile");
d339 1
a339 1
# exactly one of the next two lines should be commented out.
d341 8
a348 2
# or else the program will terminate without sending emails;
# if that is not installed, comment out the 'use', or else it won't run.
d353 2
d356 1
d362 1
a362 1
		     From => 'changetrack@@localhost',
d373 3
@


3.5
log
@Intented according to emacs default.
Fixed some @@foo[]
@
text
@d3 1
a3 1
@@temp = split(' ', '$Revision: 3.4 $ ');
d22 1
a22 1
$error = getopts('hc:d:a:m:erqM:vuo');
d102 6
a108 1

d358 4
@


3.4
log
@Made version match RCS revision.
@
text
@d3 2
a4 1
$version = "$Revision$";
d13 1
a13 2
if($< == 0)
	{
d17 1
a17 2
else
	{
d51 4
a54 4
if($opt_v) {print "$version\n"; exit;}          # just the version
if($opt_c) {$configfile = $opt_c;}              # file storing files to check
if($opt_d) {$historypath = $opt_d;}             # directory to store output in
if($opt_u) {$diffargs = "-u";}                  # unified diffs
d56 2
a57 2
$message = $opt_m;                              # message (for reboots, etc.)
$Message = $opt_M;                              # other message.
d59 1
a59 1
                                                # needs to be a folder; forgot the '/'?
d61 2
a62 2
mkpath("$historypath",0,0711);                  # create it if it doesn't exist
mkpath("$historypath/RCS",0,0711);              # create RCS directory if it doesn't exist
d64 1
a64 1
$date = scalar localtime;                       # store the date in $date
d68 15
a82 16
sub getoctalbits                                # translate 'ls -l' to octal
  {
	$out = "";
	$in = $_[0];
	$in = substr($in,1,9);
	@@tmp = (substr($in,0,3),substr($in,3,3),substr($in,6,3));
	foreach $one (@@tmp)
		{
		$num = 0;
		if(substr($one,0,1) ne "-") {$num += 4;}
		if(substr($one,1,1) ne "-") {$num += 2;}
		if(substr($one,2,1) ne "-") {$num += 1;}
		$out = $out . $num;
		}
	return $out;
	}
d87 48
a134 1
while(<CONFIG>)                                 # for each config line
d136 58
a193 3
	chomp;
	if(m/\s*#/) {next;}                           # ignore comments
	if(m/^\s*$/) {next;}                          # and blank lines
d195 9
a203 2
	($filename,$email,$options)=split(/\s+:\s+/); # get the info
	@@emails = split(/\s+/,$email);                # list of emails for this file
d205 35
a239 143
	foreach $email (@@emails)
		{
		if(($x=index($emailaddresses,$email,0)) == -1)
			{                                         # if the user is not yet in 
			$emailaddresses .= " " . $email;          # the list, add them.
			}
		}
		
	if(substr($filename,0,1) ne "/")              # make these relative to user's home directory
		{
		$filename = $homedir . $filename;
		}
		
	open(LS,"ls -l -d $filename |");              # match wildcards like 'ls'
	$anyfile = 0;                                 # flag in case we find nothing
	while(<LS>)                                   # may match several (wildcards)
		{
		@@diff = ();
		@@ed = ();
		chomp;
		# the next line should be gone, and just a maximal match. How?
		while(m/  /) {s/  / /};
		@@temp = split(/\s+/);
		$realfile = @@temp[8];                       # filename
		if((substr($realfile,-1,1) eq "~") && ($filename =~ m/\*/))
			{
			# it's a backup file not explicitly included	
			if(!$opt_q)
				{ print "Skipping backup file $realfile\n";}
			next;	
			}
	
		$filebits = @@temp[0];                       # permissions string
		if(substr($filebits,0,1) eq "d")
			{
			if(!$opt_q)
				{ print "Skipping directory $realfile\n";}

			next;
			}
		$anyfile = 1;                               # at least one real file found
		$compfile = $realfile;                      # file for comparison

		@@temp = stat $realfile;                     # other statistics:
		$fileuid = $temp[4];                        # owner,
		$filegid = $temp[5];                        # group

		while($compfile =~ m/\//)                   # replace '/' with ':'
			{$compfile =~ s/\//:/;}
		$compfile =~ s/^://;                        # trash leading ':'

		$compfile = $historypath . $compfile;
		$logfile = $compfile . ".history";          # stores past events
		$statfile = $compfile . ".statistics";      # stores current file info
		$origfile = $compfile . ".original";        # stores name of original file
		if($opt_e)
			{	
			$outfile = $compfile . ".edout";          # output from ed script
			$edfile = $compfile . ".ed";              # ed script
			}
		$yestfile = $compfile . ".yesterday";       # stores current data

		if(!open(OLD,"$yestfile"))                  # can't open yesterday, doesn't exist.
      {
      @@diff = (@@diff, "New file $realfile\n");
			if($opt_e)
				{
				@@ed = (@@ed,"# cat this file into ed, eg 'cat $edfile | ed'\n");
				@@ed = (@@ed,"# output goes into $outfile\n");
				@@ed = (@@ed,"# edit this file to get rid of commands you don't want.\n");
				@@ed = (@@ed,"\n!cp $origfile $outfile\n");
				@@ed = (@@ed,"E $outfile\n");
				copy($realfile, $origfile);             # keep a copy of original file
				}

			copy($realfile, $yestfile);               # so no changes noted today.
			open (STAT, ">$statfile") or die "Exiting: can't open > $statfile:$!\n";
			print STAT "$filebits\n$fileuid\n$filegid\n";
			close(STAT);
			if(!$opt_r)
				{
				`cp $realfile $compfile`;
				chdir($historypath);
#				open(RCS, "| rcs -i $compfile");
#				print RCS "this is $realfile\n.\n";
#				close(RCS);
				system("rcs -i -t-'this is $realfile' $compfile");
				`rcs -U $compfile`;
				`rm $compfile -f`;
				}
			}
		else
			{
			# only opening it to see if it exists.
			close(OLD);
			}

    open(STAT, "$statfile") or die "Exiting: can't open < $statfile:$!\n";
    $oldfilebits = <STAT>;                      # get the comparison permissions
    chomp($oldfilebits);

		$oldfileuid = <STAT>;                       # get the old owner
    chomp($oldfileuid);

    $oldfilegid = <STAT>;                       # get the old group
    chomp($oldfilegid);

    close(STAT);

    $statschanged = 0;                          # 'nothing changed' flag

		$newnums = getoctalbits($filebits);
    if($oldfilebits ne $filebits)
      {
      @@diff = (@@diff, "File permissions changed: was $oldfilebits now $filebits\n");
			@@ed = (@@ed, "!chmod $newnums $outfile\n");
			$statschanged = 1;
      }

    if($oldfileuid != $fileuid)
      {
      $oldusername = getpwuid($oldfileuid);
      $username = getpwuid($fileuid);
      @@diff = (@@diff, "Owner changed: was $oldusername ($oldfileuid) now $username ($fileuid)\n");
			@@ed = (@@ed,"!chown $fileuid $outfile\n");
			$statschanged = 1;
      }

    if($oldfilegid != $filegid)
      {
      $oldgroupname = getgrgid($oldfilegid);
      $groupname = getgrgid($filegid);
      @@diff = (@@diff, "Group changed: was $oldgroupname ($oldfilegid) now $groupname ($filegid)\n");
			@@ed = (@@ed,"!chgrp $filegid $outfile\n");
			$statschanged = 1;
      }

    if($statschanged)
      {
      open(STAT, ">$statfile") or die "Exiting: can't open to rewrite $statfile:$!\n";
      print STAT "$filebits\n$fileuid\n$filegid\n";
      close(STAT);
      }
d241 4
a244 1
		open(DIFF, "diff $diffargs $yestfile $realfile |") or die "Exiting: can't run diff:$!\n";
d246 3
a248 12
		if(!$opt_q) {print "$realfile";};
   	
		while(<DIFF>)
     	{
			if(m/^\</ || m/^\>/ ||                    # line starts with < or >
				($opt_u && !(m/^\-\-\-/||m/^\+\+\+/)))  # or not unified header.
     	  {
     	  if(!$opt_q) {print ".";};               # indicate progress
				
				@@diff = (@@diff, $_);                    # get that line
     	  }
     	$diff = 1;                                # flag the changes
d250 64
a313 69
    close(DIFF);

		if($diff)
			{
			open(DIFF, "diff -e $yestfile $realfile |") or die "Can't do diff -e:$!\n";
                                                # use -e to create ed commands
			while(<DIFF>)
				{
				@@ed = (@@ed,"$_");                       # get the 'ed'-styled diffs. No need to understand them.
				}
			close(DIFF);
			}
			
    if(!$opt_q) {print "\n";};

    if(@@diff || $message)                       # there is something to add to the output file
      {
      # deal with emailing
			foreach $email (@@emails)
				{
				# it's ok to append to things that don't exist.
				$emessages{$email} .= "Changes made to $realfile follow:\n";
				foreach $line (@@diff)
					{
					$emessages{$email} .= "  $line";
					}
				if($message) {$emessages{$email} .= $message;}
				                                        # don't forget the message
				$emessages{$email} .= "\n";             # separate from next file
				}

			open(LOG,">>$logfile") or die "Exiting: can't open $logfile:$!\n";
      print LOG "Changes made on $date follow:\n";
      foreach $line (@@diff)                     
        {
        print LOG "  $line";                    # save the line
				}
      if($message) {print LOG "  $message\n"};  # save any message (nb after all changes)
			if(@@diff && $Message){print LOG $Message;}# only if there are changes
			print LOG "\n";                           # and a blank line
      copy($realfile, $yestfile);               # save the file for next time
			close(LOG);

			if($opt_e)
				{
				open(ED,">>$edfile") or die "Exiting: can't open $edfile:$!\n";
				foreach $line (@@ed)
					{
					print ED $line;                       # save the edits as well
					}	
				print ED "w\n";                         # make sure ed writes the changes when run.
				close(ED);
				}

			if(!$opt_r)
				{
				chdir($historypath) or die "Can't chdir to $historypath for ci: $!\n";
				print "cp $realfile $compfile\n";
      	`cp $realfile $compfile`;               # make backup copy
				#`mv $realfile $realfile.track`;        # copy backwards, to keep modification date
				#`cp $realfile.track $realfile`;        # make backup copy
#				open(RCS,"| ci -l $compfile"); # modify backup copy
#				print RCS "modification of $realfile on $date\n.\n";
#				close(RCS);
				system("ci -m'modification of $realfile on $date' -l $compfile");
      	#`mv $realfile.track $realfile`;        # replace original file 
    		`rm $compfile`;
				}
		  }
d315 10
a324 10

  close(LS);
  if(!$anyfile)                                 # no file was matched by 'ls'.
		{                                           # create message for misspelled files
		$origfile = $filename;
    while($filename =~ m/\//) {$filename =~ s/\//:/;}
		if(substr($filename,0,1) eq ":") {$filename = substr($filename,1);}
		open(LOG, ">>$historypath$filename");
    print LOG "$date No files match `$origfile'\n";
    close(LOG);
d326 1
a326 1
  }
d336 12
a347 18
if($emailaddresses)
	{
	@@emails = split(/\s+/,$emailaddresses);

	foreach $email (@@emails)
		{
		#print "$email\n";
		if(($email) && ($message = $emessages{$email}))
			{
			%mail = (To => $email,
               From => 'changetrack@@localhost',
               Message => "$message",
               Subject => "changed files: $date"
							 );
		
			sendmail(%mail) or warn $Mail::Sendmail::error;
			}
		}
d349 2
d353 3
d369 1
@


3.3
log
@Added change from Ian Zimmerman, fixing RCS integration bug.
@
text
@d3 1
a3 1
$version = "2.0.3";
d369 3
@


3.2
log
@added email features, cleaned.
Release version 2
@
text
@d3 1
a3 1
$version = "2.0";
d23 1
a23 1
$error = getopts('hc:d:a:m:erqM:vo');
d44 4
a47 1
  -o emailaddress             Mail output to emailaddress.
d55 2
d181 4
a184 3
				open(RCS, "| rcs -i $compfile");
				print RCS "this is $realfile\n.\n";
				close(RCS);
d242 1
a242 1
		open(DIFF, "diff $yestfile $realfile |") or die "Exiting: can't run diff:$!\n";
d248 2
a249 1
			if(m/^\</ || m/^\>/)                      # does the line starts with < or >
d278 1
a278 1
				$emessages{$email} .= "Changes made to $filename follow:\n";
d283 3
d318 4
a321 3
				open(RCS,"| ci -l $compfile"); # modify backup copy
				print RCS "modification of $realfile on $date\n.\n";
				close(RCS);
d340 7
a346 1
use Mail::Sendmail;
d348 1
a348 2
@@emails = split(/\s+/,$emailaddresses);
foreach $email (@@emails)
d350 3
a352 2
	#print "$email\n";
	if(($email) && ($message = $emessages{$email}))
d354 8
a361 4
		%mail = (To => $email,
	           From => 'changetrack@@localhost',
					   Message => "$message"
						 );
d363 2
a364 1
		sendmail(%mail) or warn $Mail::Sendmail::error;
d369 4
@


3.1
log
@replaced quotewords with split
@
text
@d3 1
a3 1
$version = 1.41;
d51 1
a51 1
if($opt_d) {$historypath = $opt_d;}             # directory wherein to store output
d64 3
a66 3
sub getoctalbits                                # translate 'ls -l' output to octal
	{
  $out = "";
d82 1
d87 5
a91 4
	$filename = $_;
	if($filename =~ m/^ *#/) {next;}              # ignore comments
	if(($filename =~ m/^$/) || ($filename =~ m/^ *$/)) {next;}
                                                # and blank lines
d93 9
a101 1
  if(substr($filename,0,1) ne "/")              # make these relative to the user's home directory
d106 1
a106 1
	open(LS,"ls -l -d $filename |");                 # match any wildcards that 'ls' does.
d108 1
a108 1
	while(<LS>)                                   # may be more than one (wildcards)
d113 1
d115 1
a115 1
		@@temp = split(" ", $_);
d133 1
a133 1
		$anyfile=1;																	# at least one real file found
d165 1
a165 1
				copy($realfile, $origfile);             # keep a copy of the original file
d168 2
a169 2
			copy($realfile, $yestfile);               # save it now, so no changes noted today.
			open (STAT, ">$statfile") or die "Exiting: can't open to create $statfile:$!\n";
d189 1
a189 1
    open(STAT, "$statfile") or die "Exiting: can't open to read $statfile:$!\n";
d215 1
a215 1
      @@diff = (@@diff, "Owner changed: was $oldusername ($oldfileuid) now username ($fileuid)\n");
d267 12
a278 1
      open(LOG,">>$logfile") or die "Exiting: can't open $logfile:$!\n";
d283 1
a283 1
        }
d329 17
d347 3
@


3.0
log
@To add ideas from FSF
@
text
@a4 1
use Text::ParseWords;
d104 1
a104 1
		@@temp = quotewords(" ", 0, $_);
d308 3
@
