#!/usr/local/bin/perl # # pstamp : create timestamped copies of a file # # Author: Terence Kelly # # $Revision: 1.3 $ # $Source: /u/tpkelly/bin/RCS/pstamp,v $ # # Given two filename arguments, replace all instances of magic strings # in first file with corresponding values. Print results to second # filename. Do not clobber existing destination files. Set atime & # modtime of destination file to same values as source file. Re-set # atime & mtime of sourcefile to what they were before pstamp is run. # Set permissions on destination file to make it unwritable. # # To get started, run this file on itself as input and use diff to # compare results: "pstamp pstamp output ; diff pstamp output" # # USAGE: # # pstamp # # NOT YET IMPLEMENTED: # # Calculate size of *destination* file based on substitutions made and # allow that to be embedded in destination file. # # Should have a different mode of operation: pstamp # where user provides a suffix and a list of files. Each file is processed # and output is written to same filename with suffix appended. # # # List of magic strings: # $moddatestring = "MODDATE_STAMP"; $modtimestring = "MODTIME_STAMP"; $accdatestring = "ACCDATE_STAMP"; $acctimestring = "ACCTIME_STAMP"; $modstring = "MOD_STAMP"; $accstring = "ACC_STAMP"; $srcsizestring = "SRCSIZE_STAMP"; $srcfilenamestring = "SRCFILENAME_STAMP"; $dstfilenamestring = "DSTFILENAME_STAMP"; $linenumstring = "LINENO_STAMP"; if ($#ARGV != 1) { die "Wrong # of arguments. Usage: $0 \n"; } $srcfile = $ARGV[0]; $dstfile = $ARGV[1]; # # print STDERR "will process $srcfile to $dstfile\n"; # if (-e $dstfile) { die "File $dstfile already exists. Exiting.\n"; } # # Get stat on source file before touching it. # ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat($srcfile); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($mtime); $moddate = sprintf("%02d/%02d/%02d", $mon+1, $mday, $year); $modtime = sprintf("%02d:%02d:%02d", $hour, $min, $sec); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($atime); $accdate = sprintf("%02d/%02d/%02d", $mon+1, $mday, $year); $acctime = sprintf("%02d:%02d:%02d", $hour, $min, $sec); $mod = localtime($mtime); $acc = localtime($atime); # # Now open input & output files. # open(SRC, "<$srcfile") || die "Can't open $srcfile: $!\n"; open(DST, ">$dstfile") || die "Can't open $dstfile: $!\n"; select(DST); while () { s/$moddatestring/$moddate/g; s/$modtimestring/$modtime/g; s/$accdatestring/$accdate/g; s/$acctimestring/$acctime/g; s/$modstring/$mod/g; s/$accstring/$acc/g; s/$srcsizestring/$size/g; s/$srcfilenamestring/$srcfile/g; s/$dstfilenamestring/$dstfile/g; s/$linenumstring/$./g; print; } select(STDOUT); close(DST); # # Make sure source & destination files have same access & mod times. # Source file should look exactly as it did before operation; this # program is "pstealthy" in the sense that the source file's atime # as well as mtime are unchanged. The ctime will change; nothing can # be done about that, I think; the OS owns ctime. # $n = utime $atime, $mtime, ($dstfile); if ($n != 1) { warn "failed to change atime & mtime of destination file $dstfile\n"; } $n = utime $atime, $mtime, ($srcfile); if ($n != 1) { warn "failed to change atime & mtime of source file $srcfile\n"; } # # Change permissions on destination file to make it un-writeable. # $n = chmod 0400, ($dstfile); if ($n != 1) { warn "failed to change permissions mode of destination file $dstfile\n"; }