/* REXX RESTMAC Restores text from a backup dataset to the original dataset from which the backup was created. . Any shown lines in the backup dataset will flag the entire enclosing member for restoration. . It is not necessary to run PREVNAME prior to starting this macro. A 'skinny PREVNAME' will be performed in-line if necessary. . TERSE backups are handled as well as old-style (with stats on a separate line). . Actual restoration is done via EXECIO, and stats are altered via UPOE. */ address ISREDIT "MACRO (opts)" if rc = 20 then do /* ISREDIT not available */ address TSO parse source . . exec_name . ex_nam = Left( exec_name,8 ) /* predictable size */ helpmsg = ex_nam "is an EDIT macro" call HELP /* -*/ exit /* ...or call HELP */ end parse var opts parms "((" opts upper opts opts = Strip( opts,'T','5d'x ) /* yes we want no bananas */ parse var opts "TRACE" tv . parse value tv "N" with tv . rc = Trace( 'O' ) ; rc = Trace( tv ) monitor = WordPos( "MONITOR",opts ) > 0 noupdt = WordPos( "NOUPDT" ,opts ) > 0 call A_INIT /* Initialization */ call C_ORIG_NAME /* Find original DSN */ call E_PREVNAME /* Get candidate names */ call I_INVENTORY /* Start, End, and Stats */ call M_MOVE_DATA /* Transfer text */ exit /*@ RESTMAC */ /* Initialization . ----------------------------------------------------------------- */ A_INIT: /*@ */ address TSO upper parms parse value "" with, mbrlist stats. top. bottom. inventory parse value Copies( "0 ",20 ) with, sw. top bottom . parse value Date( 'S' ) Time( 'N' ) with, today now . sw.0AsIs = WordPos( "ASIS",opts ) > 0 return /*@ A_INIT -*/ /* Find original DSN . ----------------------------------------------------------------- */ C_ORIG_NAME: /*@ */ address ISREDIT "(dsn) = DATASET " if monitor then say "Working from" dsn if Pos( '.Z0',dsn ) > 0 then do pt = Pos( '.Z0',dsn ) parse var dsn front =(pt) '.' znode '.' back dsn = front'.'back end /* Z0 */ rdsn = Reverse( dsn ) parse var rdsn rllq '.' rtag '.' rfront origds = Reverse( rfront )'.'Reverse( rllq ) if monitor then say "Original DS:" origds return /*@ C_ORIG_NAME -*/ /* Get candidate names . ----------------------------------------------------------------- */ E_PREVNAME: /*@ */ address ISREDIT /* Has PREVNAME been run ? */ " F FIRST NX './' 1 " /* first membername */ if rc > 0 then do /* Nope, no PREVNAME */ " F LAST NX p'^' " if rc > 0 then return " F PREV './' 1 " /* NAME line */ do forever if rc > 0 then leave /* not found */ " F PREV NX p'^' " if rc > 0 then leave /* not found */ " F PREV './' 1 " end /* forever */ end /* Find all members */ /* Get all members in reverse order */ " F LAST NX './' 1 " do forever if rc > 0 then leave /* not found */ "(txt) = LINE .zcsr " /* get text */ parse var txt "NAME=" mbr . /* isolate mbrname */ mbrlist = mbr mbrlist /* add to list */ " F PREV NX './' 1 " end /* forever */ if monitor then say "Members selected:" Space( mbrlist,1 ) return /*@ E_PREVNAME -*/ /* Start, End, and Stats. Sets stats.mbr, top.mbr, and bottom,mbr . ----------------------------------------------------------------- */ I_INVENTORY: /*@ */ address ISREDIT "( bottom ) = LINENUM .zlast " /* initial value */ "SEEK LAST './' 1 " do forever if rc > 0 then leave "( txt ) = LINE .zcsr " /* the contents */ "( l# ) = LINENUM .zcsr " /* the line number */ parse var txt 'NAME='mbr stats.mbr top = l# + 1 /* next line # */ if stats.mbr = '' then do "( sttxt ) = LINE" top /* maybe stats? */ if Left( sttxt,1 ) = '<' then do /* yes, it is */ parse var sttxt '<' stats.mbr '>' top = top + 1 /* first data line */ end end /* blank stats */ else sttxt = stats.mbr parse value top+0 bottom+0 with , top.mbr bottom.mbr . inventory = mbr inventory bottom = l# - 1 /* line before ./ */ "SEEK PREV './' 1 " end /* forever */ if monitor then say "Found" Words( inventory ) "members in backup." return /*@ I_INVENTORY -*/ /* Transfer text . ----------------------------------------------------------------- */ M_MOVE_DATA: /*@ */ address TSO do Words( mbrlist ) /* each candidate */ parse var mbrlist mbr mbrlist "NEWSTACK" call ME_EXECIO /* Queue up text, transfer */ "DELSTACK" call MS_SET_STATS /* Refresh stats */ end /* mbrlist */ return /*@ M_MOVE_DATA -*/ /* Queue up text, transfer. . ----------------------------------------------------------------- */ ME_EXECIO: /*@ */ address ISREDIT do xx = top.mbr to bottom.mbr /* each line */ "( txt ) = LINE" xx queue txt /* onto the stack */ end /* each line */ rc = Trace( 'O' ) ; rc = Trace( tv ) curr = queued() /* current # of lines */ if monitor then say, curr "lines to be written for member" mbr address TSO cmd = "ALLOC FI( OUT ) DA( '"origds"("mbr")' ) SHR REU " if monitor then say cmd if noupdt = 0 then (cmd) cmd = "EXECIO " curr "DISKW OUT ( FINIS " if monitor then say cmd if noupdt = 0 then (cmd) return /*@ ME_EXECIO -*/ /* Refresh stats . ----------------------------------------------------------------- */ MS_SET_STATS: /*@ */ address ISPEXEC parse var stats.mbr vv '.' mm credate moddate modtm , curr orig lmod uid credate = Translate( 'CcYy/Mm/Dd' , credate , 'CcYyMmDd' ) if sw.0AsIs then do moddate = Translate( 'CcYy/Mm/Dd' , moddate , 'CcYyMmDd' ) end else do moddate = Translate( 'CcYy/Mm/Dd' , today , 'CcYyMmDd' ) modtm = now parse value vv+1 '00' with , vv mm . end newstats = vv mm credate moddate modtm curr orig lmod uid if monitor then say, "New stats for " mbr ":" newstats address TSO cmd = "UPOE " mbr "'"origds"'" newstats if monitor then say cmd if noupdt = 0 then (cmd) return /*@ MS_SET_STATS -*/ /* . ----------------------------------------------------------------- */ HELP: /*@ */ address TSO;"CLEAR" if helpmsg <> "" then say helpmsg parse source . . exec_name . ex_nam = Left(exec_name,8) /* predictable size */ say " " say " "ex_nam" (MACRO) restores text from datasets created by BACKUP. " say " Any shown lines in the backup dataset will be considered " say " as indicating the entire enclosing member is to be " say " recovered. The text of the member, whether changed or " say " original, will be restored to the dataset from which this " say " backup was developed. After recovery, the edit session " say " for the backup dataset may be cancelled without making the" say " changes permanent. " say " " say " Syntax: "ex_nam" (no parms) " say " (( ASIS " say " " say " ASIS if specified, the original VV, MM, MODDATE, and " say " MODTIME will be preserved. Otherwise, VV+1, MM=00, " say " and MODDATE and MODTIME will reflect the date and " say " time of restoration. " "NEWSTACK"; pull ; "CLEAR" ; "DELSTACK" say " " say " Debugging tools provided include: " say " " say " MONITOR: displays key information throughout processing. " say " " say " NOUPDT: by-pass all update logic. " say " " say " TRACE tv: will use value following TRACE to place the execution " say " into REXX TRACE Mode. " say " " say " " say " Debugging tools can be accessed in the following manner: " say " " say " TSO "ex_nam" parameters (( debug-options " say " " say " For example: " say " " say " TSO "ex_nam" (( trace ?r asis " if sysvar( "SYSISPF" ) = "ACTIVE" then, address ISPEXEC "CONTROL DISPLAY REFRESH" exit /*@ HELP */