home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
srev13h.zip
/
SRERSYNC.CMD
< prev
next >
Wrap
OS/2 REXX Batch file
|
1999-12-13
|
7KB
|
212 lines
/* 15 Nov 1999:
sreRsync: an SRE-http pre-reply procedure that implements Rsync
This SRE-http pre-reply procedure implements rsync differencing.
If an rsync-signature request header is present, it
will either create an rsync difference file (to be sent to the client)
or add an rsync-signature response header.
a) Rsync-signature: 0
Create an rsync-signature of the response. This can be
used (in an Rsync-signature request header) by the client
in a future request
b) Rsync-signature: long_strip_of_base64_characters
Compute a difference file using the "current instance" of the
resource (i.e.; the value of the "content" argument) and the
"synopsis" contained in the long_string_of_base64_characters.
This difference will be returned to the client, along with a
Content-encoding: rsync-sre
response header.
IMPORTANT NOTE:
To use sreRsync, you MUST have the RxRSYNC.DLL library installed.
For more details, please see sreRsync.doc
*/
sre_rsync:
/* -------- User changeable parameters ---------- */
/* Number of blocks to use when creating rsync-signature response header.
More blocks means longer request header, but more chances of a match
45 yields about a 500 byte header, which is pushing acceptable
limits. Rsync_blocks must be between 10 and 255 */
rsync_blocks=45
/* -------- End of User changeable parameters ---------- */
if rxfuncquery('rx_md4')=1 then do
aa=RXFuncAdd( 'RXRsyncLoad', 'RXRSYNC', 'RxRsyncLoad')
if aa=0 then do
call RxRsyncLoad
end
else do
if verbose>1 then call pmprintf('SRE-http SRERsync procedure: ERROR -- can not find RxRSYNC.DLL')
end
if rxfuncquery('rx_md4')=1 then return 0 /* no rsync procs available, so give up */
call pmprintf('foo')
end
parse arg contents,fileflag,mimetype,clen,modstring
verbose=value('SREF_VERBOSE',,'os2environment')
/* 1) Look for a rsync-signature request header. If none, do nothing */
rheader=reqfield('rsync-signature')
if rheader='' then return 0
/* reqfield has problems, so re-read using entire head */
'read header var hh '
do until hh =''
parse var hh aline '0d0a'x hh
aline=strip(aline)
if abbrev(translate(aline),'RSYNC-SIGNATURE:')=1 then do
parse var aline . ':' rheader
DO UNTIL HH=''
PARSE VAR hh aline '0d0a'x hh
if pos(':',aline)>0 then leave
rheader=rheader||aline
end /* do concatenate lines (goserve screwiness correction */
rheader=strip(rheader)
leave
end /* found a rsync-signature set of lines (in header) */
end /* do */
/* got an rsync signature. Unpack64 it. */
if rsign<>'' & rsign<>0 & rsign<>1 then
rsign=pack64(rheader)
/* create a rsync-signature? */
if rsign='' | rsign=0 & rsign<>1 then do /* rsync-signature: with no value */
say " .... rsigh "rsign
if fileflag=1 then do /* read contents */
foo=stream(contents,'c','open read')
if abbrev(strip(translate(foo)),'READY')=0 then return 0 /* problem opening, give up */
jlen=stream(contents,'c','query size')
if jlen=0 | jlen='' then return 0
aa=charin(contents,1,jlen)
foo=stream(contents,'c','close')
contents=aa
end /* else, use contents as is */
bss=rsync_synopsis(rsync_blocks) /* expose contents */
'HEADER add Rsync-signature: 'bss
return 0
end /* do */
/* else, compute rsync differnce file */
/* the signature, which is usually about 500 bytes "pre pack 64 conversion"
(hence about 375 bytes post conversion) has the following structure:
blocksize: 4 bytes. A 32 bit number: blocksize=x2d(c2x(vv))
Number_of_blocks: 1 bytes: a 8 bit number (max of 256 blocks)
block1: 8 bytes: The first four characters is a 32 bit "rolling" checksum,
the second 4 characters are the leftmost 32 bits of
an md4.
...
blockn
*/
if fileflag=1 then
jlen=stream(contents,'c','query size')
else
jlen=length(contents)
blocksize=c2d(substr(rsign,1,4))
nblocks=c2d(substr(rsign,5,1))
stuff=''
if verbose>2 then say 'sreRsync: Rsync-signature has 'nblocks 'blocks of size ='blocksize
do mm=1 to nblocks
jat=((mm-1)*8)+6
foo=substr(rsign,jat,8)
stuff=stuff||left(foo,20)
end
/* make a synopsis for feeding to rx_rsync_server */
comment='srersync pre-reply '
aa=left(comment,81)||left(blocksize,7)||left(nblocks,9)||left('md4',35)
stuff=aa||stuff
tdir=value('SREF_TEMP_DATA_DIR',,'os2environment')
a1=SYStempfilename(tdir||'\_RERSYNC.???')
del_contents=0
if fileflag=0 then do
parse var a1 . '.' ext
a2=tdir||'\__RESYNC.'||aext
foo=charout(a2,contents,1)
if foo<>0 then return 0 /* error, give up */
foo=stream(a2,'c','close')
contents=a2
del_contents=1
end
status=rx_rsync_gdiff(contents,stuff,a1,1)
if abbrev(status,'OK')=0 then do
if verbose>1 then call pmprintf('sreRsync pre-reply WARNING: 'status)
return 0 /* give up */
end
if verbose>2 then call pmprintf('sreRsync: status= 'status)
if del_contents=1 then foo=sysfiledelete(a2)
foo=stream(a1,'c','open read')
if abbrev(strip(translate(foo)),'READY')=0 then do
if verbose>1 then call pmprintf('SRE-http SRERsync pre-reply WARNING: unable to open difference file 'a1)
return 0
end
issize=stream(a1,'c','query size')
if (issize=0 | issize='') then do
if verbose>1 then call pmprintf('SRE-http SRERsync pre-reply WARNING: 0 sized difference file 'a1)
return 0
end
stuff=charin(a1,1,issize)
issize=stream(a1,'c','CLOSE')
foo=sysfiledelete(a1)
'HEADER add Content-encoding: rsync-sre '
return modstring||' '||mimetype||' 1 '||'0d0a'x||stuff
/*****************/
/* create rsync synopsis */
/*******************************************/
rsync_synopsis:procedure EXPOSE contents
parse arg nblocks
if nblocks='' then nblocks=45
if datatype(nblocks)<>'NUM' then nblocks=45
if nblocks<10 | nblocks>255 then nblocks=45 /* 255 limit on # of blocks */
isize=length(contents)
blocksize=trunc(0.9999 + (isize/nblocks))
if blocksize<200 then do
blocksize=200
nblocks=trunc((isize/blocksize)+0.999)
end /* do */
ac1=d2c(blocksize)
ac1=right(ac1,4,x2c('00'))
ac1=ac1||d2c(nblocks)
iat=1
do mm=1 to nblocks
if mm=nblocks then
ablock=substr(contents,iat)
else
ablock=substr(contents,iat,blocksize)
ac0=left(x2c(rx_rsync32_md4(ablock)),8)
ac1=ac1||ac0
iat=iat+blocksize
end
ac1=sref_mkpack64(ac1)
return ac1