> UnZip/src v1.12  Unzip a ZIP file : v1.00 06-Jun-1999 JGH: Initial version, ignores CRCs (/ v1.01 16-Jun-1999 JGH: Reads command line 21 v1.02 22-Jun-1999 JGH: Undosifies filenames <= v1.03 17-Jul-1999 JGH: Fuller implementation, -a now -X F* v1.04 20-Nov-2000 JGH: -q quiet mode P) v1.05 28-Dec-2000 JGH: Minor tweeks Z/ v1.06 15-Jan-2001 JGH: Inflate on RISC OS dH v1.07 22-Mar-2001 JGH: Sets mdate/time, cdate/time on SJ and HADFS n/ v1.08 17-Jun-2001 JGH: Split into modules x6 v1.09 12-Jan-2002 JGH: Tweeked attribute setting 8 v1.10 22-Jun-2011 JGH: Fuller filename translation J v1.11 30-Sep-2017 JGH: Bugfix ensuring output file writeable on ADFS F v1.12 15-Oct-2017 JGH: fsname: -> -fsname-, optimised FNfn_zip() : @ctrl%255,name%128,extra%128,zp%6:A$=OS_GetEnv:in%=0:out%=0 Kquit$=cl(" -qu",1):debug%=cl("-de",0):hlp%=cl("-?",0): :exit() hdst$=cl("-d",1):vb%=cl("-q",0):sfe%=cl("-s",0):xtr%=cl("-X",0):inf%=cl("-255",0):in$=cl("",0) Cin$="-help":"BBC"s($(+7))" (C)J.G.Harston 1999-2017":hlp%= d IFdebug%:PRINT" run$='"run$"'"TAB(39)" quit$='"quit$"'"'" in$='"in$"'"TAB(39)" dst$='"dst$"'" H IFdebug%:PRINT"verbose=";vb%;" extra info=";xtr%;" info=";inf% Lhlp%:"Syntax: *UnZip infile -d path -q -X -255 -quit command":exit(0) :  :Close_All::exit() SX%=ctrl%:Y%=X%256: A%-1:max%=-A%-2000+4000*(>&FFFF): mem% max%:wr%=2:rd%=4 Din$="":"File to unzip: "in$:dst$="":"Destination path: "dst$ Bin$<>45:A%=in$,":",3):A%:in$="-"+in$,A%-1)+"-"+in$,A%+1) ":in%=(in$):in%=0:"File '"in$"' not found":exit(214) ,Tgbpb(rd%,in%,zp%,4,0):!zp%<>&04034B50:"Not a ZIP file":#in%:in%=0:exit(127) 6Efln%=10:A%=fs:sj%=((A%=5)2)+((A%=16)1)+((A%=8)8):A%=4:fln%=7 @dst$:dst$=dst$+"." JKdirs%=1 inf% 1 (sj%<>0):dirs%:vb%=:inf%=0:"Finishing... "; T5#in%=0::gbpb(rd%,in%,zp%,4,0):id%=!zp%:done%= ^(dirs%:inf%=0:sofar(#in%,#in%); h&(id%&FFFF)=&4B50 #in%:done%= rid%=&04034B50:file | IFid%=&02014B50:PROCdir  IFid%=&06054B50:PROCeof 3done%:#in%=#in%-3:"Damaged ZIP file?";13; *id%=&02014B50 id%=&06054B50 #in% :inf%=0:8,8,8:"Done." #in%:in%=0:exit(0): :  file @gbpb(rd%,in%,extra%,26,0):flags%=ex16(2): vers%=FNex16(0) Fmethod%=ex16(4):mtime%=fstime(ex16(6)):mdate%=fsdate(ex16(8)) Fcrc%=extra%!10:csize%=extra%!14:fsize%=extra%!18:nameln%=ex16(22) ;extln%=ex16(24):nameln%:gbpb(rd%,in%,mem%,nameln%,0) : 2 vers%=FNget16:flags%=FNget16:method%=FNget16 D mtime%=FNfstime(FNget16):mdate%=FNfsdate(FNget16):crc%=FNget32 B csize%=FNget32:fsize%=FNget32:nameln%=FNget16:extln%=FNget16 0 IFnameln%:PROCgbpb(rd%,in%,mem%,nameln%,0) &: 09mem%?nameln%=13:name$=$mem%:x%=01274:extra%!x%=0: :*extln%:gbpb(rd%,in%,extra%,extln%,0) D/hdrid%=ex16(0):dsz%=ex16(2):sig%=extra%!4 N2load%=extra%!8:exec%=extra%!12:attr%=extra%!16 X7ctime%=fstime(ex16(24)):cdate%=fsdate(ex16(26)) b?acc%=ex16(28):aux%=ex16(30):hdrid%<>&4341:dsz%=0:load%=0 l/ hdrid%=&4341 -> Created on Acorn computer v2 dsz% usually =&14, ie 20 bytes of extra data  sig%='ARC0' -> Archive aA$=fn_zip(name$):A%=0:B%=A$+".",".",A%+1):B%-A%>fln%+1:A$=A$,A%+fln%)+A$,B%):B%=A%+fln% ,A%=B%:B%>=A$:name$=A$:vb%:name$;" "; unzip:vb%:  :  ݤex16(A%)=extra%!A% &FFFF :  unzip  vb%:"Type ";method%;" - "; &method%=0 method%=8:unzipobj:  skip:vb%:"not supported";  :  unzipobj >ensurepath(dst$+name$):((name$,1)=".")dirs%)1:skip:  =dst$="":name$=45:name$="@."+name$: -name- -> @.-name- *6name$,1)=".":name$=name$,name$-1) unzipfile 4Ydsz%<24:cdate%=mdate%:dsz%<22:ctime%=mtime%:dsz%<13:attr%=&33:dsz%<12:exec%=load% >J(sj%1)=0:attr%=attr%-129:sj%8:attr%=attr%(-694*((attr%17)17)) HhX%!14=attr%:X%!15=mdate%:dsz%:X%!2=load%:X%!6=exec%:A%=file(dst$+name$,1) A%=file(dst$+name$,4) RPsj%1:dsz%>23:X%!2=acc%:X%!4=aux%:dsz%<26xtr%=0:A%=file(dst$+name$,&FD) \Qsj%1:dsz%>23:X%!6=mtime%:X%!9=cdate%:X%!11=ctime%:A%=file(dst$+name$,&FC) fUxtr%:sj%1:dsz%>25:"Account "+dst$+name$+" "+~acc%+" ("+~aux%+")",dsz%>27) p(sj%2)=0: zSX%!8=mdate%:A%=NetFS_OpN(19,5,10,dst$+name$):NetFS_OpN(18,64,8,dst$+name$): cB%=12:X%!8=cdate%:X%!10=ctime%:X%!13=mdate%:X%!15=mtime%:A%=NetFS_OpN(19,64,18,dst$+name$): f IFdsz%>23:X%!8=cdate%:X%!10=ctime%:X%!13=mdate%:X%!15=mtime%:A%=FNNetFS_OpN(19,64,18,dst$+name$) bxtr%:dsz%>25:A%=NetFS_OpN(0,0,7,"Account "+dst$+name$+" "+~acc%+" ("+~aux%+")",dsz%>27))  : unzipfile /method%=8:os%<>6:" unsupported";:skip: 7dst$+name$>63:'"Path may be too long for NetFS" : ޗ IFos%=6 AND HIMEM>&FFFF:SYS "XOS_File",1,dst$+name$,,,,&33 ELSE IFFNfile(dst$+name$,5):X%!2=0:X%!14=0:A%=FNfile(dst$+name$,1):REM Ensure writable  OSCLI"Save "+dst$+name$+" "+STR$~PAGE+"+"+STR$~(FNmin(fsize%,&C000))+" 0 0":X%!14=&33:A%=FNfile(dst$+name$,1):REM Reserve disk space, ensure writable : ? ADFS falls over if dest in a subdir and doesn't exist yet [ A%=1:IFos%=6:A%=FNfile(dst$+name$,5) :REM RISC OS OS_File,1 errors if file not found @ IFA%:X%!14=&33:A%=FNfile(dst$+name$,1):REM Ensure writable : $3 Extra OSFILE 5 to bypass ADFS and RISCOS bugs .Kfile(dst$+name$,5):X%!14=&33:A%=file(dst$+name$,1): Ensure writable 8_X%!10=0:X%!14=fsize%:file(dst$+name$,7)=7:X%!14=min(fsize%,&B000):A%=file(dst$+name$,0) B6: Reserve disk space, avoiding GoMMC/SDC I/O area L1(X%?142)=0:X%!14=&33:A%=file(dst$+name$,1) V?: Ensure overwritable again if default attrs are read-only `: j.out%=0:extract:(flags%8):#in%=#in%+12 tvb%:8,8,8:"Done."; ~out%:#out%:out%=0  : Bݤfstime(A%):=((A%&F800)2048)+((A%&7E0)*8)+((A%31)*131072) Rݤfsdate(A%):A%=A%-&200:=(A%31)+((A%&1E0)*8)+((A%&1E00)*8)+((A%&E000)256) : $extract:fsize%=0:(vb%3);: %method%=8:vb%:"Inflating ..."; 9method%=0:out%=(dst$+name$):vb%:"Extracting ..."; /method%=8:ZipTest:out%=(""): method%=8:put32(&04088B1F):put32(0):put32(&00200000):put32(&001C4341):put32(load%):put32(exec%):put32(attr%):put32(fsize%):put32(0):put32(0):put32(0) 1trans:method%=8:put32(crc%):put32(fsize%) #out%:out%=0:method%=0: -"ZipUnCompress "+dst$+name$   : 4skip:#in%=#in%+csize%+(12((flags%8)<>0)): (: 2%ZipTest:zipok%=zipok%:zipok%: <<*RMEnsure SparkFS 0.00 Error SparkFS needs to be running F=*RMEnsure Zip 0.00 Error SparkFS needs to load Zip module Pzipok%=: Z: d&ݤfn_zip(A$):B$="_ #?./$<^>&+@=%;" n' A%=1 A$:B%=B$,A$,A%,1),2)-1 x2 B%>-1:A$=A$,A%-1)+B$,(B%1)+1,1)+A$,A%+1)  A%:=A$ : "ensurepath(A$):A$,".")=0: IA$=A$+".":A$=A$, A$-1):A$,1)=".":A$=A$, A$-1):file(A$,5)=2: OB$=A$:A$="":B$:A%=B$+".","."):A$=A$+".",A$<>"")+B$,A%-1):B$=B$,A%+1) file(A$,5)<>2:"CDir "+A$  B$="": :  DEFPROCdir:ENDPROC  DEFPROCeof:ENDPROC : 8 DEFPROCCheckFS:sj%=0:A%=FNfs:IFA%=16:sj%=1:ENDPROC J IFA%=8:sj%=8:ENDPROC ELSE IFA%=4:fln%=7:ENDPROC ELSE IFA%<>5:ENDPROC < sj%=2:A%=FNNetFS_Op(25,""):IFINSTR($(X%+4),"SJ"):sj%=6  ENDPROC : "` DEFPROCCheckFS:sj%=0:A%=FNfs:sj%=((fs%=5)AND2)+((fs%=16)AND17)+((fs%=8)AND8):IFA%=4:fln%=7 , ENDPROC 6 b0 1 HADFS @ b1 2 NET J b3 8 ADFS T: ^' DEFFNget16:=BGET#in%+256*BGET#in% h0 DEFFNget32:PROCgbpb(rd%,in%,zp%,4,0):=!zp% r1put32(A%):!zp%=A%:gbpb(wr%,out%,zp%,4,0): |: , DEFPROCtrans:crc%=0:IFcsize%=0:ENDPROC < crc%=-1:ptr%=0:REPEAT:IFvb%:PRINTFNsofar(ptr%,csize%); trans:csize%=0: 'ptr%=0::vb%:sofar(ptr%,csize%); 0len%=max%:ptr%+len%>csize%:len%=csize%-ptr% :gbpb(rd%,in%,mem%,len%,0):gbpb(wr%,out%,mem%,len%,0) :ptr%=ptr%+len%:ptr%>=csize%: crc%=FNrev32(crc%)EOR-1  : !ݤmin(A%,B%):A%