home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxrsync.zip / rsynctst.cmd < prev    next >
OS/2 REXX Batch file  |  1999-11-15  |  11KB  |  377 lines

  1. /* 10 November 1999. Daniel Hellerstein (danielh@crosslink.net)
  2.     RsyncTst: example of how to use the RxRSYNC procedures 
  3.    See RxRSYNC.DOC, or RxRSYNC.CMD, for the details
  4. */
  5.  
  6. synopfile='synop.rsy'    /* name to use for synopsis file */
  7. difffile='diff.rsy'     /* name to use for difference file */
  8. quiet=0                /* set to 1 suppress some output */
  9.  
  10. parse arg oldfile newfile outfile .
  11.  
  12. say "Test of the RxRSYNC procedures "
  13. if oldfile='' | oldfile='?' | newfile='' then do
  14.    say "Call using: "
  15.    say "   RSYNCtst oldfile newfile outfile "
  16.    say " where: "
  17.    say "     oldfile: the old version  of a file"
  18.    say "     newfile: the new version of a file "
  19.    say "     outfile: name to use for the the duplicate of the newfile"
  20.    say " In addition, 'synopfile' and 'difffile ' will be created "
  21.    exit
  22. end /* do */
  23.  
  24. if outfile='' then outfile='RSYNCTST.OUT'
  25.  
  26. say " "
  27. say "Step1: create the synopsis file ("synopfile
  28. status=rsync_client(oldfile,synopfile,'This is a test of rsync',quiet)
  29. say "rsync client status: " status
  30. if abbrev(status,'OK')<>1 then exit
  31.  
  32. say ' '
  33. say "Step 2: create the difference file ("difffile
  34. status=rsync_server(synopfile,newfile,difffile,quiet)
  35. say "rsync server status: "status
  36. if abbrev(status,'OK')<>1 then exit
  37.  
  38. say ' '
  39. say "Step 3: duplicate the new file "outfile
  40. status=rsync_undiff(oldfile,difffile,outfile,quiet)
  41. say "rsync undiff status: "status
  42.  
  43. exit
  44.  
  45.  
  46.  
  47. /*******************************************************************/
  48. /*  rsync_client: creates a synopsis of an old version.
  49.  
  50.        status=rsync_client(oldver_file,synopsis_file,comment,quiet,blocksize)
  51.        quiet, blocksize, and comment are optional parameters
  52. */
  53.  
  54. rsync_client:procedure
  55.  
  56. /*********  USER changeable parameters  ************/
  57. /* (larger blocksizes means smaller synopsis, but possibly larger difference */
  58. blocksize=500
  59.  
  60. quiet=0         /*  default status messages: 1-terse, 0=normal */
  61.  
  62.  
  63. /**** END of USER changeable parameters  ************/
  64.  
  65. parse arg afile,outfile,comment,verbo,bsize
  66.  
  67. a=rsync_load_dlls()
  68. if a<>0 then return a
  69.  
  70. if afile='' then return "ERROR no old-version file specified"
  71. if outfile='' then return "ERROR no synopsis-file specified "
  72.  
  73. if verbo<>'' then verbose=verbo
  74. if bsize<>'' then do
  75.    if datatype(bsize)='NUM' then blocksize=bsize
  76. end /* do */
  77.  
  78. select
  79.    when verbose=0 then verbose=1
  80.    when verbose=1 then verbose=0
  81.    otherwise nop
  82. end
  83.  
  84. reportat=verbose
  85. if verbose<2 then reportat=250000
  86.  
  87. crlf='0d0a'x
  88. a=time('r')
  89.  
  90. if comment='' then comment=date('n')||' '||time('n')
  91.  
  92. /* read "Afile" */
  93. aa=translate(stream(afile,'c','open read'))
  94. if  abbrev(aa,'READY')=0 then return "ERROR could not open "afile
  95. isize=stream(afile,'c','query size')
  96. if isize='' | isize=0 then do
  97.     return 'ERROR 'afile " is unaccessible"
  98.     exit
  99. end
  100. astuff=charin(afile,1,isize)
  101. aa=stream(afile,'c','close')
  102.  
  103. amd4=rx_md4(astuff)
  104. if verbose>0 then  do
  105.   say "Rsync Client: read "isize" bytes from "afile
  106. end
  107.  
  108. /* break into chunks of size blocksize, and compute "adler" and md4 checksums */
  109. ifoo=trunc(isize/blocksize+0.999999)
  110.  
  111. /* Structure of client request file
  112.    Comment  -- 80 characters (i.e.; requested file name)
  113.    1 space
  114.    Blocksize  -- 6 digit integer
  115.    1 space
  116.    #Blocks    -- 8 digit character
  117.    1 space
  118.    md4        -- 32 digit md4
  119.    3 spaces
  120.    rsync1||md41||..||rsyncN||md4||N -- rsync and md4 values (machine format)
  121. */
  122.  
  123. ac1=left(comment,80)||' '||left(blocksize,6)||' '||left(ifoo,8)||' '||amd4||'   '
  124. iat=1
  125. do mm=1 to ifoo
  126.   if mm=ifoo then
  127.      ablock=substr(astuff,iat)
  128.   else
  129.      ablock=substr(astuff,iat,blocksize)
  130.   ac1=ac1||x2c(rx_rsync32_md4(ablock))
  131.   iat=iat+blocksize
  132. end
  133. foo=time('e')
  134. if verbose>0 then say '   Done creating hashes for  'ifoo' blocks'
  135.  
  136. foo=sysfiledelete(outfile)
  137. foo=charout(outfile,ac1,1)          /* create the message the client send to the server*/
  138. if foo<>0 then do
  139.   foo=stream(outfile,'c','close')
  140.   return "ERROR problem writing synopsis file "outfile
  141. end /* do */
  142. foo=stream(outfile,'c','close')
  143. b=time('e')
  144. if verbose>0 then 
  145.    say '   Saving synopsis file to 'outfile' [elapsed time='||strip(b,'t','0')
  146. nn=length(ac1)
  147. drop ac1
  148. return 'OK 'nn ' bytes written to synopsis file 'outfile
  149.  
  150.  
  151. /*******************************************************************/
  152. /*     rsync_server: uses this synopsis, and the new version, to create
  153.                    and rsync difference file
  154.  
  155.           status=rsync_server(synopsis_string,newver_file,diff_file,quiet)
  156.           quiet is an optional parameter
  157. *****************************************/
  158.  
  159. rsync_server: procedure
  160.  
  161. parse arg sfile,newverfile,outfile,verbo
  162.  
  163. a=rsync_load_dlls()
  164. if a<>0 then return a
  165.  
  166. if sfile='' then return "ERROR no synopsis file specified "
  167. if newverfile='' then return "ERROR no new_version file specified"
  168. if outfile='' then return "ERROR no difference file specified "
  169.  
  170. if verbo<>'' then verbose=verbo
  171. select
  172.    when verbose=0 then verbose=1
  173.    when verbose=1 then verbose=0
  174.    otherwise nop
  175. end
  176.  
  177. crlf='0d0a'x
  178. a=time('r')
  179.  
  180. b=time('r')
  181.  
  182. /* read "synopsis file" */
  183. aa=translate(stream(sfile,'c','open read'))
  184. if  abbrev(aa,'READY')=0 then return "ERROR could not open "sfile
  185. issize=stream(sfile,'c','query size')
  186. if issize='' | issize=0 then do
  187.     return 'ERROR 'sfile " is unaccessible"
  188.     exit
  189. end
  190. synopsis=charin(sfile,1,issize)
  191. aa=stream(sfile,'c','close')
  192. if verbose>0 then  do
  193.     say "Rsync server: read "issize" bytes in the synopsis file"
  194. end
  195.  
  196. in1=left(synopsis,132)
  197. parse var in1 comment +80 iblock numblocks amd4 gotcts .
  198.  
  199.  
  200. if datatype(iblock)<>'NUM' | datatype(numblocks)<>'NUM' then do
  201.     return 'ERROR not a proper synopsis 'iblock numblocks
  202. end
  203.  
  204. if verbose>0 then do
  205.   say "   Comment: "||left(comment,64)
  206.   say "            (client used blocksize=" iblock ', and sent 'numblocks' blocks '
  207. end
  208.  
  209. if stream(newverfile,'c','query exists')='' then  do
  210. say " sss "newverfile
  211.   return 'ERROR no such new_version file '||newverfile
  212. end
  213.  
  214. if verbose>0 then  do
  215.    nn=stream(newverfile,'c','query size')
  216.     say "   Read "nn" bytes in "newverfile
  217. end
  218.  
  219. /* call the integrated rsync_server procedure */
  220. foo=sysfiledelete(outfile)
  221. if foo>2 then return "ERROR could not delete old version of "outfile
  222.  
  223. status=rx_rsync_server(newverfile,synopsis,outfile)
  224.  
  225. b=time('e')
  226.  
  227. if verbose>0 then do
  228.     nn=stream(outfile,'c','query size')
  229.     say '   Saving difference file to 'outfile '[elapsed time='||strip(b,'t','0')
  230. end
  231.  
  232. return status
  233.  
  234.  
  235. /***************************************************/
  236. /*  rsync_undiff: uses the difference file, and the old version, to
  237.                    build a copy of the new version
  238.  
  239.      status=rsync_undiff(oldver_file,diff_file,newfile,quiet)
  240. **************************************/
  241.  
  242. rsync_undiff:procedure
  243.   parse arg afile,dfile,outfile,verbo
  244.  
  245. a=rsync_load_dlls()
  246. if a<>0 then return a
  247.  
  248. if afile='' then return "ERROR no old_version file specified"
  249. if dfile='' then return "ERROR no difference-file specified "
  250. if newfile='' then return "ERROR no new_version file specified "
  251.  
  252. if verbo<>'' then verbose=verbo
  253. select
  254.    when verbose=0 then verbose=1
  255.    when verbose=1 then verbose=0
  256.    otherwise nop
  257. end
  258.  
  259. crlf='0d0a'x
  260. a=time('r')
  261.  
  262. /* read "diff Afile" */
  263. aa=translate(stream(dfile,'c','open read'))
  264. if  abbrev(aa,'READY')=0 then return "ERROR could not open "dfile
  265. idsize=stream(dfile,'c','query size')
  266. if idsize='' | idsize=0 then do
  267.     return 'ERROR 'dfile " is unaccessible"
  268.     exit
  269. end
  270. s1=charin(dfile,1,idsize)
  271. aa=stream(dfile,'c','close')
  272. if verbose>0 then  do
  273.     say "Rsync undiff: read "idsize" bytes in the difference file"
  274. end
  275.  
  276. /* read "Afile" */
  277. aa=translate(stream(afile,'c','open read'))
  278. if  abbrev(aa,'READY')=0 then return "ERROR could not open "afile
  279. iasize=stream(afile,'c','query size')
  280. if iasize='' | iasize=0 then do
  281.     return 'ERROR 'afile " is unaccessible"
  282.     exit
  283. end
  284. astuff=charin(afile,1,iasize)
  285. aa=stream(afile,'c','close')
  286. if verbose>0 then  do
  287.     say "   "iasize" bytes in the old_version file"
  288. end
  289.  
  290. amd4=rx_md4(astuff)            /* md4 of old version */
  291.  
  292. /* get md4 and blocksize from s1 */
  293. parse var s1 smd4 bsize (crlf) s1
  294. if strip(translate(amd4))=strip(translate(smd4)) then do
  295.    if verbose>0 then
  296.        say "   File has not changed! "
  297.    bstuff=astuff
  298.    signal writeme1    
  299. end 
  300.  
  301. /* start building. Each records starts with a single character identifier,
  302. either a B or a C. Following the identifier is:
  303.    B: a block start: block end number, and then a crlf
  304.    C: a count of bytes (nnn), a ":", a string of length nnn, and a crlf
  305. */
  306. bstuff=''
  307. noted=0
  308. do forever
  309.    if length(s1)=0 | s1='' then leave
  310.    mbl=lengtH(bstuff)
  311.    if  mbl-noted> reportat then do
  312.       if verbose>0 then say "... Rsync client: # characters recovered "mbl
  313.       noted=mbl
  314.    end /* do */
  315.    parse var s1 atype +1 s1  ; atype=translate(atype)
  316.    select
  317.       when atype='C' then do
  318.          parse var s1 nnn ':' s1
  319.          parse var s1 ccs +(nnn) (crlf) s1
  320.          bstuff=bstuff||ccs
  321.       end /* do */
  322.       when atype='B' then do
  323.          parse var s1 idb1 ':' idb2 (crlf)  s1
  324.          i1=((idb1-1)*bsize)+1
  325.          i2=idb2*bsize
  326.          i2=min(i2,iasize)
  327.          bstuff=bstuff||substr(astuff,i1,1+i2-i1)
  328.       end /* do */
  329.       otherwise do
  330.          return "ERROR in differnce file: unknown type= "atype
  331.      end
  332.    end  /* select */
  333. end /* do */
  334.  
  335. /* compute md4 of this constructed file */
  336. b2md4=rx_md4(bstuff)
  337. if strip(translate(b2md4)) <> strip(translate(smd4)) then do
  338.    return "ERROR md4 does not match: "b2md4', 'smd4
  339. end /* do */
  340.  
  341. writeme1:   nop                 /* jump here if no change */
  342. foo=sysfiledelete(outfile)
  343. if foo>2 then return 'ERROR unable to delete output file 'outfile
  344. foo=charout(outfile,bstuff,1)          /* save the computed new file */
  345. foo=stream(outfile,'c','close')
  346. b=time('e')
  347. if verbose>0 then
  348.   say '   Saving duplicate to 'outfile ' [elapsed time='||strip(b,'t','0')
  349.  
  350. nn=length(bstuff)
  351. drop bstuff; drop astuff
  352.  
  353. return 'OK 'nn ' bytes written to  'outfile
  354.  
  355.  
  356. /****************************************************************/
  357. /* read in some useful procedures */
  358. rsync_load_dlls:procedure
  359. if rxfuncquery('rx_md4')=1  then do
  360.   call RXFuncAdd 'RXRsyncLoad', 'RXRSYNC', 'RxRsyncLoad'
  361.   call RxRsyncLoad
  362. end
  363. if rxfuncquery('rx_md4')=1  then do
  364.   return "ERROR could not load  RxRsync.DLL"
  365. end
  366. /* Load up advanced REXX functions */
  367. foo=rxfuncquery('sysloadfuncs')
  368. if foo=1 then do
  369.   call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  370.   call SysLoadFuncs
  371. end
  372. if rxfuncquery('sysfiledelete')=1  then do
  373.   return "ERROR could not load  REXXUTIL.DLL"
  374. end
  375. return 0
  376.  
  377.