home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
cmdpk164.zip
/
xcp.cmd
< prev
next >
Wrap
OS/2 REXX Batch file
|
1998-01-10
|
15KB
|
495 lines
/* This is CommandPak's xcp command. */
/* (w) 1998 Ulrich Möller */
'@echo off'
/* to do: SIMPLE_BACKUP_SUFFIX env var
"-S" for suffix setting */
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
/* The following messages have not yet been moved into XHELPxxx.MSG and will thus
always be displayed in English. Language support might be added in a later release. */
nl = '0d0a'x
err = '<HTML><I>Error in xcp:</I> '
errhlp = 'Type <A HREF="">xcp -h</A> for help.'
nofilesMsg = err||'File(s) not found. '||errhlp
unknownoptionMsg = err||'Unknown option (<B>-%a</B>). '||errhlp
errorMsg1 = err||'Using these options is not allowed with two file specifications. '||errhlp
errorMsg2 = err||'You must give two file specifications here. '||errhlp
errorMsgFiles = err||'You have not specified any files. '||errhlp
errorMsgTest = err||'The "test" option must be used with other options. '||errhlp
errorMsgForce = err||'The "force" option can only be used when moving files. '||errhlp
errorMsgInteractive = err||'The "interactive" option can presently not be used with the options you have specified. '||errhlp
invwcMsg = err||'Invalid wildcard usage. '||errhlp
checkingMsg = "Checking" /* argument will be added automatically */
procMsg = "Processing" /* argument will be added automatically */
replacedMsg = ' Replaced invalid characters in .LONGNAME:'
longDelMsg = " .LONGNAME for %a deleted (contained %b)"
skipMsg = ' Skipped deleting .LONGNAME; contains important characters'
inuseMsg = " Could not remove .LONGNAME for %a; file seems to be in use"
backedupMsg = " Backed up %a to %b"
copyMsg = " Copying %a to %b"
replaceMsg = " %a exists."nl" (R)eplace (B)ackup original (S)kip replace_(A)ll? "
interactMsg = " Is this OK? (Y)es (N)o (A)ll "
dontWorryMsg = "Don't worry, this was test mode only. Nothing was modified."
interruptMsg = "xcp was interrupted externally."
invalidChars = '\/:*?"<>|,+=[];'
signal on halt; trace off
parse arg args
alwaysReplace = 0
old. = ""
new. = ""
deletelong = 0
verbose = 0
quiet = 0
test = 0
debug = 0
movealso = 0
force = 0
interactive = 0
backup = 0
FAT=0
/* first process arguments/options */
do while (args \= "")
parse value args with opt1 args
if debug then Say " Parsing" opt1
if (substr(opt1, 1, 1)="-") | (substr(opt1, 1, 1)="/") then do
do optcount = 2 to length(opt1) by 1
optchar = substr(opt1, optcount, 1)
if debug then Say " Subparsing" optchar
select
when (optchar="D") then do
Say "Debug messages turned on."
debug = 1
verbose = 1
test = 1
end
when (optchar="d") then
deletelong = 1
when (optchar="t") then do
test = 1
verbose = 1
end
when (optchar="8") then
FAT = 1
when (optchar="b") then do
backup = 1
interactive = 0
force = 0
end
when (optchar="f") then do
force = 1
interactive = 0
backup = 0
end
when (optchar="i") then do
interactive = 1
force=0
end
when (optchar="v") then do
verbose = 1
quiet = 0
end
when (optchar="q") then do
quiet = 1
verbose = 0
end
when (optchar="h") | (optchar = "?") then do
'call xhelp xcp'
exit
end
otherwise do
'call xhelp "'strReplace(unknownoptionMsg, "%a", optchar)'"'
exit
end
end /* select */
end /* do */
end /* if */
else
if old.complete = "" then
old.complete = opt1
else new.complete = opt1
end /* do while */
if (old.complete = "") then do
'call xhelp "'errorMsgFiles'"'
exit
end
/* now collect files */
if debug then
say "Collecting files"
files.0 = 0
curdir = directory()
if (directory(old.complete) \= "") then do
files.1 = old.complete
files.0 = 1
end
else if (old.complete = "..") then do
files.1 = ".."
files.0 = 1 /* these are funny bugs in SysFileTree */
end
else do
rc = SysFileTree(old.complete, files, "FO", '*--*-')
/* Attribs: 'ADHRS' */
if debug then Say " "files.0 "file(s) found"
if files.0 = 0 then do
'call xhelp "'nofilesMsg'"'
exit
end
end
call directory(curdir)
renMode = 0
moveMode = 0
extMode = 0
wildcards = 0
do
if debug then say "Entering mode analysis for old.spec"
old.path = filespec('drive', old.complete)||filespec('path', old.complete)
old.spec = filespec('name', old.complete)
if debug then do
say ' old.path: "'old.path'"'
say ' old.spec: "'old.spec'"'
end
end
if (new.complete = "") then do /* no second spec given: assume current dir */
new.complete = "."
end
if (new.complete \= "") then do
/* second spec given: seems to be rename/move mode. */
if debug then say "Entering mode analysis for newspec"
if (new.complete \= "\") & (substr(new.complete, 2) \= ":\") & (right(new.complete, 1) = "\") then new.complete = strip(new.complete, 't', '\')
curdir = directory()
if (directory(new.complete) \= "") then do
/* second spec is dir only --> just move, no rename */
moveMode = 1
new.path = new.complete
renMode = 0
new.spec = ""
end
else do
new.path = filespec('drive', new.complete)||filespec('path', new.complete)
new.spec = filespec('name', new.complete)
if (new.path \= "") then do
moveMode = 1
if (new.path \= "\") & (substr(new.path, 2) \= ":\") & (right(new.path, 1) = "\") then new.path = strip(new.path, 't', '\')
end
else do
moveMode = 1
new.path = directory()
end
if (new.spec \= "") then do
renMode = 1
end
/* second spec is */
end
call directory curdir
if debug then do
if renMode then say " -> Copy mode enabled; renaming to" new.spec
if moveMode then say " -> Copy mode enabled; moving to" new.path
if extMode then say " -> Extended mode enabled"
end
if extMode then do
'call xhelp "'errorMsg1'"'
exit
end
end
if renMode then do
/* now evaluate wildcards */
if (pos('*', new.spec) \= 0) | (pos('?', new.spec) \= 0) then do
wildcards = 1
if debug then say "Evaluating wildcards"
old.wild.pos = pos('*', old.spec)
new.wild.pos = pos('*', new.spec)
if (old.wild.pos = 1) then
if (pos('*', substr(old.spec, old.wild.pos+1)) > 0) then call invwc
else if (new.wild.pos = 1) then
if (pos('*', substr(new.spec, new.wild.pos+1)) > 0) then call invwc
else do
old.wild.sub = translate(substr(old.spec, old.wild.pos+1))
new.wild.sub = substr(new.spec, new.wild.pos+1)
end
else call invwc
else if (old.wild.pos = length(old.spec)) then
if (new.wild.pos = length(new.spec)) then do
old.wild.sub = translate(substr(old.spec, 1, old.wild.pos-1))
new.wild.sub = substr(new.spec, 1, new.wild.pos-1)
end
else call invwc
else call invwc
if debug then do
say ' old.wild.sub: "'old.wild.sub'"'
say ' new.wild.sub: "'new.wild.sub'"'
end
end /* wildcards */
end
/* now work on file list */
if debug then say "Entering file processing"nl
do i = 1 to files.0
oldName = files.i
oldnameonly = filespec('name', oldname)
if (deleteLong) then
call deleteLongname oldname
/* check which mode we're in */
select
when (moveMode) then do /* move: when different directory specified */
/* first compose new name */
if renMode then
newNameOnly = getNewName(oldname)
else
newNameOnly = filespec('name', oldname)
if (FAT) then
newNameOnly = makeFAT(newNameOnly)
if (right(new.path, 1) \= "\") then
moveTo = new.path||'\'
else moveTo = new.path
newName = moveTo||newNameOnly
/* now check if copying is allowed; confirm if neccessary */
moveOK = 1
if (verbose | interactive) then
say strReplace(strReplace(copyMsg, '%a', oldname), '%b', newname)
else if (\quiet) then say oldname
if (stream(newName,'c','query exist') \= "") then do
if (force) then
'del' newName
else if (backup) then
call backupFile newName
else do
resp = queryExists(strReplace(replaceMsg, '%a', newName))
if (resp = "R") then
'del' newName
else if (resp = "B") then
call backupFile newName
else
moveOK = 0
end
end
else
if (interactive) then
moveOK = (queryYN(interactMsg))
/* finally, copy file */
if (moveOK) then
if (\test) then do
'copy' oldname newname ">NUL"
/* 'del' oldname '/N' */
end
else if debug then do
Say ' -- copy' oldname newname
/* Say ' -- del' oldname */
end
end
when renMode then do
/* rename only */
newNameOnly = getNewName(files.i)
if (FAT) then
newNameOnly = makeFAT(newNameOnly)
call copyFile oldname newNameOnly
end
otherwise ;
end /* select */
end /* do files.i */
if (test) then say dontWorryMsg
exit
getNewName:
_oldname = arg(1)
if (wildcards) then
_newname = strReplace(filespec('name', _oldname), old.wild.sub, new.wild.sub)
else
_newname = new.spec
return _newName
makeFAT: procedure expose debug
_old = arg(1)
_p = pos(".", _old)
_p2 = _p
if _p2 > 8 then _p2=8
if (_p > 0) then do
_new = left(_old, _p2-1)||"."||substr(_old, _p+1, 3)
end
else _new = left(_old, 8)
if debug then
say " makeFAT:" _old "-->" _new
return _new
deleteLongname:
realname = arg(1)
rc = SysGetEA(realname, ".LONGNAME", "longname_")
longname = substr(longname_, 5)
if (longname \= "") then
if ((\invalidName(longname)) | force) then do
if \test then
call SysPutEA realname, ".LONGNAME", ""
if (\quiet) then do
rc = SysGetEA(realname, ".LONGNAME", "longname2")
if ((longname2 \= "") & \test & \quiet) then
Say strReplace(inuseMsg, '%a', realname)
else
if (\quiet) then
Say strReplace(strReplace(longDelMsg, '%b', longname), '%a', realname)
end
end
else
if \quiet then
Say skipMsg
return
copyFile:
if (deleteLong) then
call deleteLongname oldname
if (filespec("NAME", oldname) \= newNameOnly) then do
if (verbose | interactive) then
say strReplace(strReplace(copyMsg, '%a', oldname), '%b', newNameOnly)
renOK = \interactive
if (interactive) then
renOK = queryYN(interactMsg)
if (renOK) then
if (\test) then
'copy' oldname newNameOnly
else if debug then
Say ' -- copy' oldname newNameOnly
end
return
backupFile:
oldfile = arg(1)
oldfile2 = oldfile
ext = ""
p = lastpos(".", oldfile)
if (p > 0) then do
ext = substr(oldfile, p)
oldfile2 = left(oldfile, p-1)
end
p = lastpos("!", oldfile2)
if (p > 0) then do
if datatype(substr(oldfile2, p+1)) = "NUM" then do
bak = substr(oldfile2, p+1)+1
oldfile2 = left(oldfile2, p-1)
end
else bak = 1
end
else bak = 1
newfile = filespec('name', oldfile2)
do while (stream(moveTo||newfile"!"bak||ext,'c','query exist') \= "")
bak = bak+1
end
if (verbose) then say strReplace(strReplace(backedupMsg, '%b', newfile"!"bak||ext), '%a', oldfile)
'ren' oldfile newfile"!"bak||ext
return
strReplace:
parse arg str, old, new
p = pos(translate(old), translate(str))
if (p > 0) then
return left(str, p-1)||new||substr(str,p+length(old))
else
return str
invwc:
'call xhelp "'invwcMsg'"'
exit
lowercase:
return translate(arg(1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
invalidName:
invalid = 0
do i9 = 1 to length(longname)
if (pos(substr(longname, i9, 1), invalidChars) \= 0) then
invalid = 1
if invalid then leave
end
return invalid
queryYN:
if \alwaysReplace then do
call charout , arg(1)
key = ''
do until pos(key,"YNA") > 0
key = translate(SysGetKey("NOECHO"))
end /* do */
Say key
if (key = "A") then
alwaysReplace = 1
end
if (alwaysReplace) then key = "Y"
return (translate(key) = "Y")
queryExists:
if \alwaysReplace then do
call charout , arg(1)
key = ''
do until pos(key,"RBSA") > 0
key = translate(SysGetKey("NOECHO"))
end /* do */
Say key
if (key = "A") then
alwaysReplace = 1
end
if (alwaysReplace) then key = "R"
return key
halt:
"call xhelp -f abortMsg xcp"
exit