home *** CD-ROM | disk | FTP | other *** search
- page 75,132
- title XONE - Make one ARC file from a member file
-
- ; usage:
- ; XONE inputname[.ARC] [filename] [outputname] [/R]
- ;
- ; remarks:
- ; The 'inputname' is required. It defines the ARC archive
- ; file which contains the member files that you want to extract.
- ; The extension defaults to .ARC.
- ;
- ; The 'filename' is optional. If omitted, all files in the
- ; archive are extracted. If supplied, only that file in the
- ; archive that matches the 'filename' is extracted.
- ; Each extracted file is created in the ARC format using the
- ; the original file name.
- ;
- ; The 'outputname' is optional. If supplied, it defines the name
- ; to be used for the extracted file. To use this operand, you must
- ; also supply the 'filename' operand to extract a single file.
- ;
- ; restrictions:
- ; XONE was written by Vernon Buerg and is for use without
- ; restrictions. Please try to distribute this program as-is,
- ; and without modification.
-
- .xlist
- print macro name ; display a field
- mov dx,offset name
- call prints
- endm
-
- printl macro text,ctl ; display a literal
- local txt,nxt
- mov dx,offset txt
- call prints
- jmp nxt
- txt db cr,lf,&text
- ifnb < ctl>
- db cr,lf,stopper
- else
- db stopper
- endif
- nxt equ $
- endm
-
- .sall
- .list
-
- header struc ; archive header
- mbrcode db 0 ; compression code
- mbrname db 13 dup (0) ; file name
- mbrsize dw 0,0 ; file size in archive
- mbrdate dw 0 ; creation date
- mbrtime dw 0 ; creation time
- mbrcrc dw 0 ; cyclic redunancy check
- mbrlen dw 0,0 ; true file size, bytes
- header ends
-
- cseg segment public para 'CODE'
- assume cs:cseg,ds:cseg,es:cseg
- org 100h
-
- xone proc far
- jmp start ; do our thing
-
- version db cr,' ',cr,lf ; overlay jmp above
- db ' XONE Make ARC file from member file(s) ',cr,lf
- db ' ---- Version 2.3 - by Vern Buerg',cr,lf,stopper
- usage db cr,lf,' usage: XONE archive[.ARC] [filespec] [output] [/R]'
- db cr,lf,eof
- db stopper ; 2.3, oops
- page
- ;
- ; return with error
-
- error: mov ax,cs ; insure seg regs
- mov ds,ax ; for proper exit
- mov sp,cs:stkptr
- mov errlvl,1 ; set bad return code
- ; mov dl,7 ; send bel char
- ; mov ah,2 ; to standard output
- ; int 21h
-
- ; set DOS error level and exit
-
- exit: mov sp,cs:stkptr ; just in case
- mov al,errlvl ; return code
- mov ah,4ch ; exit function
- int 21h
-
- subttl '--- constants, equates and work areas'
- page
-
- cr equ 13
- lf equ 10
- bel equ 7
- tab equ 9
- eof equ 26
-
- stopper equ 255 ; end of display line indicator
- arcmark equ 26 ; special archive marker
- xoneer equ 9 ; highest compression code used ;2.2
-
- stkptr dw 0 ; stack pointer upon entry
- errlvl db 0 ; dos error level returned
- psp dw 0 ; addr of psp
-
- prompt db ' already exists, re-use it? (y/N) ',stopper
- answer db 'n',cr,stopper
- found db 0 ; indicates if found a member
- reuse db 0 ; non-zero means overwrite existing file(s)
-
- notfnd db cr,' Member file not found - '
- member db 13 dup (0),0 ; selected member name
- db cr,lf,stopper
-
- archdl dw 0 ; ARC file handle
- arcname db 76 dup (stopper)
-
- outmsg db ' -> ' ; tells you what is being used
- outname db 76 dup (0) ; output file name
-
- ; i/o control variables
-
- inbufsz equ 18*1024 ; size of input buffer
- inadr dw offset inbuf ; offset to input buffer
- inptr dw offset inbuf ; offset to current byte
- insize dw inbufsz ; size of input buffer
- inlen dw 0 ; bytes left in buffer
- incurh dw 0 ; current file offset
- incurl dw 0 ; low word
-
- outbufsz equ 18*1024 ; size of output buffer
- outlen dw outbufsz ; bytes empty in output buffer
- outadr dw offset outbuf ; offset to output buffer
- outptr dw offset outbuf ; spot for next output char
- outsize dw outbufsz ; size of output buffer
- outhdl dw 0 ; output file handle
-
- vline db cr,lf
- vstyle db ' ' ; compression method
- db 'ed: '
- vname db 12 dup (0),0
- db stopper,0
-
- styles db ' sav' ; 1 = old, no compression
- db ' Sav' ; 2 = new, no compression
- db ' Pack' ; 3 = dle for repeat chars
- db ' Squeez' ; 4 = huffman encoding
- db ' crunch' ; 5 = lz, no crc
- db ' crunch' ; 6 = lz with crc
- db ' SEA' ; 7 = internal SEA use
- db ' Crunch' ; 8 = new lz with crc
- db ' squash' ; 9 = pk squashing
-
- wtg dw 0 ; index into where table
-
- where dw offset copy1 ; offset to routines for each type
- dw offset copy2
- dw offset unpack3
- dw offset unsqueez4
- dw offset uncrunch5
- dw offset uncrunch6
- dw offset uncrunch7
- dw offset uncrunch8
- dw offset unsquash9
-
- subttl '--- mainline processing'
- page
- ;
- ; gather command line operands
-
- start:
- mov stkptr,sp ; save stack ptr
- mov ax,cs
- mov ds,ax ; set local data seg
- mov cx,es
- mov psp,cx ; save psp addr
- mov es,ax
-
- print version ; display program version
-
- mov si,80h ; get command line operand
- sub cx,cx
- or cl,byte ptr [si] ; any operand?
- jnz parm1
-
- parm_error:
- print usage ; no, gotta have the ARC name
- jmp error
-
- ; pick off any trailing '/R' parameter
-
- parm1: inc si ; point to operand
- mov bx,si
- add bx,cx ; point to end of command line
- cmp word ptr -2[bx],'R/' ; is reuse specified?
- je parm1r
- cmp word ptr -2[bx],'r/'
- jne parm2
- parm1r: or reuse,1 ; indicate no checking
- mov word ptr -2[bx],0d0dh ; stop command line here
- sub cx,2 ; remove /R from command line
- jle parm_error ; oops, something is missing
-
- ; get first operand - input archive file name
-
- parm2: lodsb ; strip leading blanks
- cmp al,' '
- loope parm2
- mov di,offset arcname
- stosb
-
- parm3: lodsb ; copy ARC filename
- cmp al,cr ; end of name?
- je parm4
- cmp al,' ' ; delimiter?
- je parm4
- cmp al,tab ; delimiter?
- je parm4
- cmp al,',' ; delimiter?
- je parm4
- stosb
- cmp al,'.' ; got extension now?
- je parm5 ; yup, that's nice
- loop parm3
-
- parm4: mov ax,'A.' ; append default ext
- stosw
- mov ax,'CR'
- stosw
- jmp short parm6
-
- ; strip trailing blanks looking for second operand
-
- parm5: lodsb ; next ext char
- cmp al,cr ; end of it?
- je parm6
- cmp al,' ' ; delimiter?
- je parm6
- cmp al,tab ; another delimiter?
- je parm6
- stosb ; copy supplied extension
- loop parm5
- parm5a: dec di ; back up to end of ext
-
- parm6: mov al,0 ; append asciiz stopper
- stosb
-
- ; copy optional second (file selection) operand
-
- or cx,cx ; another operand?
- jz parm_done ; nope, extract all files
- mov di,offset member
- parm7: lodsb
- cmp al,cr ; end of operand?
- je parm20 ; yes, done
- cmp al,' ' ; delimiter for third operand?
- je parm10
- cmp al,tab
- je parm10
- cmp al,'a' ; lower case?
- jb parm8
- sub al,32
- parm8: stosb
- loop parm7
- parm9: mov ax,0ff00h ; append asciiz stopper
- stosw
- jmp short parm_done
-
- ; get third operand, if any, as output file name
-
- parm10: sub cx,1 ; account for delimiter
- jle parm_done
- mov di,offset outname ; third operand is target filename
- parm11: lodsb
- cmp al,' ' ; strip leading blanks
- loope parm11
- cmp al,cr ; ending c/r?
- je parm_done ; just trailing blanks, then
- jcxz parm20
- parm12: stosb ; blindly copy the rest
- lodsb
- cmp al,cr
- loopne parm12
- parm20: mov ax,0ff00h ; append stoppers
- stosw
-
- parm_done: ; hope we've got everything
- call openarc ; access the archive file
- jnc xonenext
- ret
-
- page
- ;
- ; process next archive header entry
-
- xonenext:
- call gethdr ; load next header
- jnc xone2 ; get CF at end of file, etc
- jmp exit ; all done
-
- xone2: cmp archdr.mbrcode,0 ; archive eof?
- jne xone2a ; nope, keep on truckin
-
- printl ' ' ; blank line
-
- call closarc ; close file
- cmp member,0 ; selecting one file?
- je xone_ok ; no, skip next
- cmp found,0 ; and did we get it?
- jne xone_ok
- print notfnd
- printl ' '
- xone_ok:
- jmp exit ; depart
-
- xone2a:
- cmp member,0 ; selecting one file?
- je xonego ; no, skip next
- mov si,offset member ; yes, compare names
- mov di,offset archdr.mbrname
- mov cx,13
- xonesel:
- lodsb
- cmp al,0 ; end of name
- je xonego ; yes, select the file
- cmp al,byte ptr [di] ; match so far?
- jne xone_agn ; no, skip this file
- inc di
- loop xonesel
- jmp short xonego ; it matches
-
- ; the following is used to skip to the next ARC entry
-
- xone_agn:
- mov cx,word ptr archdr.mbrsize+2
- mov dx,word ptr archdr.mbrsize
- add dx,incurl ; add current hdr offset
- adc cx,0
- add cx,incurh
- mov ax,4200h ; skip over file data
- mov bx,archdl
- int 21h
- mov incurh,dx ; new position
- mov incurl,ax
- mov inlen,0 ; reset read buffer
- jmp xonenext
-
- xonego:
- mov di,offset vname ; copy file name
- mov si,offset archdr.mbrname
- mov cx,13
- xone3:
- lodsb
- cmp al,0 ; end of name?
- je xone4
- stosb
- loop xone3
- jmp short xone5
- xone4:
- mov al,0 ; pad with asciiz
- rep stosb
-
- xone5:
- sub bx,bx ; determine style
- mov bl,archdr.mbrcode
- shl bx,1
- mov wtg,bx ; save where-to-go offset
- shl bx,1
- shl bx,1 ; times 8 for style table
- lea si,styles-8[bx] ; get ptr to style name
- mov di,offset vstyle
- mov cx,8
- rep movsb
-
- print vline ; display this file info
- cmp outname,0 ; specified different output?
- je xone6
- print outmsg
-
- xone6:
- call create ; allocate new file
-
- mov bx,wtg ; where to go
- jmp where-2[bx] ; let 'er rip
-
- subttl - Extract current member file
- page
- ;
- ; 1 - straight copy of all formats
-
- copy2:
- unpack3:
- unsqueez4:
- uncrunch5:
- uncrunch6:
- uncrunch7:
- uncrunch8:
- unsquash9:
-
- copy1:
- mov si,offset newhdr ; copy arc header first
- mov cx,hdrlen
- copyhdr:
- lodsb
- call putc
- loop copyhdr
-
- mov cx,word ptr archdr.mbrsize
- mov dx,word ptr archdr.mbrsize+2
- xone7:
- call getc ; straight copy
- jc xoner1
- call putc
- sub cx,1
- sbb dx,0
- or cx,cx ; any more bytes?
- jnz xone7 ; yup, keep on truckin'
- or dx,dx
- jnz xone7
- jmp xonemore
-
- xoner1: printl 'Premature EOF reading '
- print vname
- jmp error
-
- xonemore:
- mov al,arcmark ; append normal arc mark
- call putc
- mov al,0
- call putc
-
- call putblk ; flush buffer
- call closout ; close output
- jmp xonenext
-
- subttl ' - miscellaneous subroutines'
- page
-
- openarc proc near ; open new archive
- push bx
- mov dx,offset arcname
- mov ax,3d02h ; for input and output
- int 21h
- jc openerr
- mov archdl,ax ; save file handle
- clc
- printl ' Using: '
- print arcname
- printl ' '
- pop bx
- ret
- openerr:
- printl 'Unable to open archive: '
- print arcname
- jmp error
- openarc endp
-
-
- closarc proc near
- push bx
- mov bx,archdl ; previous handle
- or bx,bx ; already open?
- jz closed
- mov ah,3eh ; yes, so close it
- int 21h
- closed: mov archdl,0
- pop bx
- ret
- closarc endp
-
- note proc near ; note location of header
- push bx ; in ARC file
- sub cx,cx
- sub dx,dx
- mov ax,4201h ; get file pointer to EOF
- mov bx,archdl
- int 21h
- mov incurh,dx ; save hdr position
- mov incurl,ax
- pop bx
- ret
- note endp
-
- create proc near ; allocate new file
- push bx
- mov found,255 ; indicate member extracted
- test reuse,1 ; want to over-write?
- jnz create1 ; yup, life in the danger zone
- mov dx,offset outname ; output specified?
- cmp byte ptr outname,0
- jne open_it
- mov dx,offset vname ; no, use archive member file name
-
- open_it:
- mov ax,3d00h ; see if file already exists
- int 21h
- jc create1 ; looks good so far
-
- mov bx,ax ; close found file
- mov ah,3eh
- int 21h
-
- print prompt ; ask to re-use
- mov ah,0 ; get response
- int 16h
- mov answer,al ; echo response
- mov dx,offset answer
- call prints
-
- cmp answer,'Y' ; get the okay?
- je create1
- cmp answer,'y'
- je create1
- jmp xone_agn
-
- create1:
- mov dx,offset outname ; output specified?
- cmp byte ptr outname,0
- jne create_it
- mov dx,offset vname ; actual file name
- create_it:
- sub cx,cx ; normal attribute
- mov ah,3ch
- int 21h
- jc creater ; something failed
- mov outhdl,ax
- pop bx
- ret
- creater:
- printl 'CREATE failed - '
- print vname
- jmp error
- create endp
-
-
- closout proc near ; close output file
- mov bx,outhdl ; close output
- or bx,bx ; was it open?
- jz closedout ; no, that's funny
- mov ah,3eh
- int 21h
- closedout:
- ret
- closout endp
-
- ;
- ; print string like int 21h function 9
-
- prints proc near ; dx has offset to string
- push si ; ending in char x'ff'
- push bx
- push cx
- mov si,dx ; pointer to text
- sub cx,cx ; length of text
- ps1: lodsb
- cmp al,stopper ; ending stopper code?
- je ps9
- inc cx ; no, increment length
- jmp short ps1
-
- ps9: mov ah,40h ; write to stdout
- mov bx,1
- int 21h
-
- pop cx ; recover registers
- pop bx
- pop si
- ret
- prints endp
-
- subttl ' - i/o subroutines'
- page
-
- getc proc near ; return next byte in al
- push si ; or cf=1 for eof
- getc1:
- sub inlen,1 ; any left in buffer
- jns getc2 ; yes, pick it up
- call getblk
- jnc getc1
- pop si ; return cf=1 at eof
- ret
- getc2:
- mov si,inptr ; offset to next byte
- lodsb
- mov inptr,si
- add incurl,1 ; bump file offset
- adc incurh,0
- pop si
- ret
- getc endp
-
- getblk proc near ; read next block
- push ax
- push bx
- push cx
- push dx
- mov ah,3fh ; read from handle
- mov bx,archdl ; arc file handle
- mov cx,inbufsz ; input buffer size
- mov dx,offset inbuf ; offset to input buffer
- mov inptr,dx
- int 21h
- jc getblkr ; oops
- or ax,ax ; anything read?
- jnz getblka
- stc ; no, set cf=1 for eof
- jmp short getblkx ; and exit
- getblka:
- mov inlen,ax ; return count of bytes read
- clc
- getblkx:
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
- getblkr:
- printl "I/O error reading from "
- print arcname
- jmp error ; gotta quit
- getblk endp
-
- page
-
- putc proc near
- cmp outlen,0 ; any room left?
- jg putc1 ; yes, stuff into buffer
- call putblk ; no, write out buffer
- jnc putc
- ret ; return cf=1 for error
-
- putc1: mov di,outptr ; offset to next spot
- stosb
- mov outptr,di ; update ptr for next time
- dec outlen
- clc ; return cf=0 for okay
- ret
-
- putblk: push ax ; save regs
- push bx
- push cx
- push dx
- mov bx,outhdl ; output file handle
- mov cx,outsize ; buffer size
- mov ax,cx
- sub cx,outlen ; less bytes unfilled
- mov outlen,ax ; reset buffer size free
- mov dx,offset outbuf ; offset to buffer
- mov outptr,dx
- jcxz putblk0 ; have nothing to write?
- mov ah,40h ; write to a file
- int 21h
- jc putcerr ; write failed?
- cmp ax,cx ; wrote it all?
- jne putcerr
- putblk0:
- clc ; clear CF error inidcator
- pop dx ; recover regs
- pop cx
- pop bx
- pop ax
- ret
-
- putcerr:
- printl 'I/O error writing to '
- print vname
- jmp error
- putc endp
-
- subttl '--- load next archive header'
- page
-
- gethdr proc near
- mov cx,128 ; gotta look for the damn thing
- gethdr2:
- call getc ; get next file byte
- jc gethdrr1 ; premature eof
- cmp al,arcmark ; start of header?
- je gethdr3 ; yup, let's start cookin
- loop gethdr2
- gethdrr1:
- printl "Invalid archive format!"
- jmp error
-
- gethdr3:
- call getc ; get version code
- jc gethdrr1
- mov archdr.mbrcode,al
- cmp al,xoneer ; reasonable code?
- ja gethdrr1 ; nope, funny stuff
- cmp al,0 ; archive eof?
- je gethdr9 ; yup done
-
- mov cx,13 ; get member name
- mov di,offset archdr.mbrname
- gethdr4:
- call getc
- jc gethdrr1
- stosb
- loop gethdr4
- gethdr5:
- mov cx,10 ; length remaining
- cmp archdr.mbrcode,1 ; old format?
- je gethdr6 ; yes, it's short
- mov cl,14
- gethdr6:
- mov di,offset archdr.mbrsize
- gethdr7:
- call getc
- jc gethdrr1
- stosb
- loop gethdr7
- gethdr8:
- cmp archdr.mbrcode,1 ; old format?
- jne gethdr9 ; if so, it's short
- mov si,offset mbrsize
- mov di,offset mbrlen
- mov cx,4
- rep movsb
- gethdr9:
- clc
- ret
-
- gethdrr2:
- printl 'Invalid archive header'
- jmp error
- gethdr endp
-
- subttl '--- i/o data areas'
- page
-
- xone endp
-
- newhdr db arcmark ; starts an arc header
- archdr equ $ ; i/o area for a header
- hdrlen equ size header + 1 ; length of normal ARC header
-
- inbuf equ $ + 64 ; input buffer
-
- outbuf equ inbuf + inbufsz ; output buffer
-
- lastbyt equ outbuf + outbufsz
-
- pgmsize equ (lastbyt - xone + 1024) /16 ; paragraphs in program
-
- cseg ends
- end xone