[comp.sources.amiga] v89i139: backup.rexx - a backup script in arexx

page%swap@Sun.COM (Bob Page) (05/17/89)

Submitted-by: bmacintyre@watcgl.waterloo.edu (Blair MacIntyre)
Posting-number: Volume 89, Issue 139
Archive-name: dos/fs/rxbackup.1

backup.rexx behaves much like the Unix backup program, creating a
directory tree with a directory for each file and saving files by the
date they were changed.

The reason I am posting this is to allow others to have yet-another
sample Arexx program.  Besides, I think it's useful!!

[unix has a 'backup' program?  ..bob]

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	Readme
#	backup.rexx
# This is archive 1 of a 1-part kit.
# This archive created: Wed May 17 20:01:54 1989
echo "extracting Readme"
sed 's/^X//' << \SHAR_EOF > Readme
XOk, so I finally got around to using ARexx, after watching the manual
Xcollect dust for 4 months.  As I posted recently, I would have really
Xliked more examples ... it would have been easier.  But it was 
Xsurprisingly easy.
X
XSo, my first effort is a script called backup.rexx which is based on
Xarchie.rexx ( which I think I got off of comp.sources.amiga some
Xtime ago. )
X
XIt behaves much like the Unix backup program, creating a directory
Xtree with a directory for each file and saving files by the date
Xthey were changed.
X
Xie. backing up /d1/d2/file with a file stamp of 01 May 11:15 would give
X        /d1/d2/file/01-May-11-15 in the backup directory
X
XThe source and destination directories are specified at execution time.
X
XThe reason I am posting this is to allow others to have yet-another
Xsample Arexx program.  Besides, I think it's useful!!
X
XOne thing to note is that is corrects a problem in Archie.rexx, which
Xwouldn't work on files or directories with embedded spaces in the name.
XRead the comments to see how.  
X
XAnother interesting point was that, for safety, I had to force quotation
Xof the "makedir" and "copy" parameters, because a file such as "blat5.1+" 
Xneeds to be quoted, for example.  I discovered that the hard way!
X
XNOTE:  you need some form of ls (I'm using the Manx one) in your C:
Xdir for this to work!!!
X
X=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-///-=
X= Blair MacIntyre, bmacintyre@watcgl.{waterloo.edu, UWaterloo.ca}     \\\///  =
X=   now appearing at the Computer Graphics Lab, U of Waterloo!         \XX/   =
X= "Don't be mean ... remember, no matter where you go, there you are." BBanzai=
X
X
SHAR_EOF
echo "extracting backup.rexx"
sed 's/^X//' << \SHAR_EOF > backup.rexx
X/*
X *   Backup.rexx -- by Blair MacIntyre
X *	 a temporary backup utility based on
X *	   Archie.rexx -- a backup utility by <CB> aka Christian Balzer
X *			  which was based on du.rexx by Larry Phillips.
X *
X * Usage: [rx] backup SOURCE DESTINATION [-options]
X *
X * SOURCE and DESTINATION are valid AmigaDOS path's WITHOUT trailing
X * slashes '/'.
X * Valid options are: Currently none...
X *
X * Backup will copy all files that don't have the archive bit set
X * from SOURCE and it's subdirectories to DESTINATION, with the modification
X * that each file will now be a directory and will have files for each time
X * copied with the filename being the date.
X *
X * If these directories don't exist at DESTINATION, backup will try to create
X * them on the fly and thus preserving the original structure at SOURCE.
X * After the file has been copied, it's archive bit will be set.
X *
X * Note: The files will be copied with 'CLONE' flag of the COPY command
X * set. This of course only works with the 1.3 version of COPY.
X *
X * Unlike Archie, filenames or directories containing blanks
X * (like "My Dir:My File"), ARE supported!
X *
X * BIG NOTE:  you need "ls" in your c: directory.  I have tried this
X *            with the manx ls, so I don't know about the PD one.
X *
X */
X
X/* This is Public Domain, read the source and learn - I did!!! */
X
Xsay 'Backup 2.4 (Based on Archie 1.6) (3-May-89)'
X
X/* open the Rexx support library */
X
Xif ~show('L',"rexxsupport.library") then
Xdo
X    if addlib('rexxsupport.library',0,-30,0) then
X	say 'added rexxsupport.library'
X    else
X    do
X	say 'support library not available'
X	exit 10
X    end
Xend
X
Xaddress command
Xcall pragma 'priority',-1
X
Xarg rein
X
X/* The parser */
Xcopt = 'clone'
X
Xif words(rein) < 2 then
Xdo
X    say 'Backup: give me a SOURCE *AND* a DESTINATION path'
X    exit 10
Xend
X
Xroot = subword(rein,1,1)
Xdest = subword(rein,2,1)
X
Xif ~ exists(root) then
Xdo
X    say 'Source not found'
X    say 'Exiting... Check your parameters'
X    exit 10
Xend
X
X/* enclose file parms for makedir ( and eventually, copy ) in "quotes" to
X   handle spaces */
X
Xif ~ exists(dest) then
Xdo
X    say 'Destination not found'
X    newdest = """" || dest || """"
X    say 'I''ll try to create it for you...'newdest
X    'makedir ' newdest
X    if ~ exists(dest) then
X    do
X	say 'Exiting... Check your parameters'
X	exit 15
X    end
X    say 'Created 'dest
Xend
X
Xif right(root,1) ~= ':' then
X    root = root || '/'
Xif root = '/' then
X    root = ''
X
Xif right(dest,1) ~= ':' then
X    dest = dest || '/'
Xif dest = '/' then
X    dest = ''
X
Xrlen = length(root)
X
Xbytes = 0
Xblocks = 0
Xfiles = 0
Xdircount = 1
X
Xsay 'Backup is doing it''s job on 'root
Xcall dolist root , 1
X
Xsay
Xsay 'Backed Up:' bytes 'bytes,' blocks 'blocks, ',
X     files 'files in a total 'dircount' directories.'
Xexit 0
X
X/* The real thing
X *
X * x is the dir we are working on
X * depth is the recursion level, so we can have a unique pipe!
X */
X
Xdolist: procedure expose bytes blocks files dest rlen dircount copt
Xparse arg x, depth
X
Xsay 'working on directory' x
X
X/* I'm not using showdir() for the file list because I want the time
X   stamps as well - can you say KLUDGE boys and girls?!?  Good, I knew you
X   could! */
X
Xpipefile = "pipe:backup_ls_" || depth
Xthedate = 'file' || depth
Xcall open thedate, pipefile, 'Read'
X'ls' ">"pipefile "-l" x
X
X/* the other reason for not using showdir() is that the filenames with spaces
X   get split up and we can't tell which they are ... */
X
Xdo forever
X
X    /* datestr contains the "ls -l" line for the current file */
X    datestr = readln( thedate )
X
X    /* if the number of words is less than 6, this is not a file line,
X       which means it is the "No files found" line.  However, I'm not making
X       it dependent on that exact string */
X    if words( datestr ) < 6 then
X	leave
X
X    /* apparantly the Manx version of ls doesn't print the summary line if
X       a directory only has one subfile ... pftt! */
X    if eof( thedate ) then
X       leave
X
X    /* the last line of an "ls -l" starts with a number */
X    if datatype(word(datestr,1), 'Numeric') then
X	leave
X
X    /* I used to grad the 6th word as the file name, but that went TU on names
X       with embedded spaces.  Grab *ALL* after the 5th ... */
X    temp = x || subword(datestr, 6)
X    flen = length(subword(datestr, 6))
X    type = statef(temp)
X
X    /* create a subdir for all dirs AND files! */
X    subdir = dest || right(temp,(length(temp) - rlen))
X    if ~ exists(subdir) then
X    do
X	say ' *** Creating directory' subdir
X	newsubdir = """" || subdir || """"
X	'makedir' newsubdir
X	if ~ exists(subdir) then
X	do
X	    say 'Oop Ack Pftt ... sorry ... Exiting'
X	    exit 20
X	end
X    end
X
X    /* recursively do directories */
X
X    if word(type,1) = 'DIR' then
X    do
X	call dolist temp || '/', depth + 1
X	dircount = dircount + 1
X    end
X
X    /* files get dated files made of them! */
X    if word(type,1) = 'FILE' then
X    do
X	if substr(word(type,4),4,1) = '-' then
X	do
X
X	    datefile = word(datestr,3) || '-' || word(datestr,4) || '-' || overlay('-',word(datestr,5),'3')
X	    target = dest || right(temp,(length(temp) - rlen)) || '/' || datefile
X
X	    if ~ exists(target) then
X	    do
X		newsrc = """" || temp || """"
X		newtgt = """" || target || """"
X		'copy ' newsrc newtgt copt
X		files = files + 1
X		bytes = bytes + word(type,2)
X		blocks = blocks + word(type,3) + 1
X		say 'Backed up file 'temp' as 'datefile
X	    end
X	end
X    end
Xend
X
Xcall close thedate
X
Xreturn
SHAR_EOF
echo "End of archive 1 (of 1)"
# if you want to concatenate archives, remove anything after this line
exit