home *** CD-ROM | disk | FTP | other *** search
- ;---------------------------------------------------------------------;
- ; ;
- ; SPAZ 1.50 ;
- ; October 7, 1990 ;
- ; ;
- ; By Dan Thomson, Andrew Farmer and Jeffrey Nonken. ;
- ; ;
- ; ;
- ; SOURCE CODE ;
- ; ;
- ; ;
- ; Copyright (c) 1989-1990 Dan Thomson and Andrew Farmer. ;
- ; All Rights Reserved. ;
- ; ;
- ;---------------------------------------------------------------------;
-
- name SPAZ
- page 60,132
- title Smart Pak, Arc and Zoo Shell
-
- false equ 00h
- tab equ 09h ;ASCII tab
- lf equ 0ah ;ASCII line feed
- cr equ 0dh ;ASCII carriage return
- blank equ 20h ;ASCII blank
- arc_len equ 21h ;Only save info for sort
- DOS equ 21h ;DOS int call
- CntrolC equ 23h ;Control C checking...
- cmdtail equ 80h ;Offset to command tail
- true equ 255
- bsize equ 4096 ;Size of copy buffer
-
- ; If you have lots of memory, (Not running a multi-tasker) then the
- ; following variables can be changed to allow running SPAZ a little
- ; faster, but using alot more memory....
-
- ; 1. Entries is the number of members in a standard ARC file that
- ; can be stored for sorting. If an ARC has more than 150, the
- ; file is not sorted. This can be increased until buffers reach
- ; (64K - code size). Each entry needs 29 bytes of buffer space.
-
- Entries equ 150
-
- ; 2. This entry controls how many file names will be stored in
- ; memory. This is used during wild card processing to run
- ; SPAZ on each individual name. It has been set at 30 to
- ; allow most systems to run without writing to disk. If you
- ; run a busy mail system or process alot of archives, this
- ; can be increased (at the cost of memory) for faster processing.
-
- NamesFound equ 30
-
- ;DOS interupt equates...
-
- CharacterOutput equ 02h
- OutputString equ 09h
- SetDTA equ 1ah
- SetVector equ 25h
- GetVector equ 35h
- CreateFile equ 3ch
- OpenFile equ 3dh
- CloseFile equ 3eh
- ReadFile equ 3fh
- WriteFile equ 40h
- DeleteFile equ 41h
- MoveFilePointer equ 42h
- GetOrSetAttribute equ 43h
- ModifyMemory equ 4ah
- ExecuteProgram equ 4bh
- ExitWithCode equ 4ch
- GetReturnCode equ 4dh
- SearchForFirst equ 4eh
- SearchForNext equ 4fh
- RenameFile equ 56h
-
- cseg segment para public 'code'
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
-
- org 100h ;Skip to end of the PSP
- entry: jmp start ;comm file entry always 0100H
-
- TitleScreen db cr,lf,'SPAZ 1.50; Written by Dan Thomson, Andrew Farmer and Jeffrey Nonken.',cr,lf
- db 'Copyright (c) 1989-1990 Dan Thomson & Andrew Farmer. All Rights Reserved.',cr,lf
- TitleLength equ $-TitleScreen
-
- Usage db cr,lf,'Syntax/Usage: SPAZ [switches] Path\Archive [switches] [files....]'
- db cr,lf,'Square brackets indicate optionals. Switches are set with - or /.'
- db cr,lf,cr,lf,'Switches:',cr,lf,cr,lf
- db ' -A Will use ONLY "ARCE" on standard (ARC Style) archives.',cr,lf
- db ' -D Will delete the archive if the extract was successful.',cr,lf
- db ' -F Will process all Compressed Mail bundles found in Dir.',cr,lf
- db ' -Maddr Will calculate Compressed Mail bundle name to show the',cr,lf
- db ' sending Net Address. "addr" is YOUR Net/Node address.',cr,lf
- db ' -N Will NOT attempt to sort the archive prior to extract.',cr,lf
- db ' -O|-R Overwrite. Will NOT prompt if existing file is found.',cr,lf
- db ' -V Verbose Mode. Will display the runtime configuration.',cr,lf,cr,lf
- db 'If -F is used then "Archive" MUST be a Path ONLY, not a Filename.',cr,lf
- db 'Use of -F forces -D and -O to be set TRUE and -N to be set False.',cr,lf
- UsageLength equ $-Usage
-
- even
- errmsg dw err2,err2,err2,err4,err5,err13
- dw err13,err8,err8,err10,err11,err5
- dw err13,err15,err15,err2,err2,err2
- dw err20,err20,err21,err22,err23,err24,err25
-
- err2 db cr,lf,'File not found: ',0
- err4 db cr,lf,'Too many open files.',cr,lf,0
- err5 db cr,lf,'Access denied.',cr,lf,0
- err8 db cr,lf,'Insufficient memory.',cr,lf,0
- err10 db cr,lf,'Invalid environment.',cr,lf,0
- err11 db cr,lf,'Invalid format.',cr,lf,0
- err13 db cr,lf,'Invalid data.',cr,lf,0
- err15 db cr,lf,'Invalid drive was specified.',cr,lf,0
- err20 db cr,lf,'Invalid file format, not changed.',cr,lf,0
- err21 db cr,lf,'Too many archive entries.',cr,lf,0
- err22 db cr,lf,'Unarchiver not found on path.',cr,lf,0
- err23 db cr,lf,'Invalid Command Line Option used.',cr,lf,0
- err24 db cr,lf,'Archive name not specified!',cr,lf,0
- err25 db cr,lf,'Invalid directory specified.',cr,lf,'$'
- NoMail db cr,lf,'No Compressed Mail Bundles Found in Directory!',cr,lf,cr,lf,'$'
- SortErr db 'Sort failed, attempting extract anyway...',cr,lf,0
- zerr db 'Problem reading archive for type check.',cr,lf,0
- crlf equ $-3
- TempErr db 'Unable to process temporary file, aborting.',cr,lf,'$'
- del_msg db cr,lf,'Extract successful - Unlinking ',0
- will db cr,lf,'Will ',0
- wont db cr,lf,'Will NOT ',0
- info1 db 'use ARCE on standard (ARC style) archives.',0
- info2 db 'delete the archives if extract was successful.',0
- info3 db 'attempt to sort the archives.',cr,lf,0
- info4 db ' - From: ',0
- info5 db 'expand network addresses.',0
- info6 db 'process Compressed Mail bundles ONLY.',0
- info7 db 'operate in overwrite mode.',0
-
- msg1 db ' Adjusting: ',0
- msg2 db '- Location = ',0
- msg3 db ' Length = ',0
- msg4 db 'Searching: ',0
-
- UnArc1 db 'PKXARC.EXE',0
- UnArc2 db 'PKXARC.COM',0
- UnArc3 db 'PKUNPAK.EXE',0
- UnArc4 db 'LOOZ.EXE',0
- UnArc5 db 'PAK.EXE',0
- UnArc6 db 'ARCE.COM',0
- UnArc7 db 'ZOO.EXE',0
- UnArc8 db 'DWC.EXE',0
- UnArc9 db 'PKUNZIP.EXE',0
- UnArc10 db 'LHARC.EXE',0
-
- on_disk db 0 ;True if names on disk .jjn
- num_names db 0 ;# of filenames in buffer .jjn
- num_hdr db 0 ;Number of headers input
- first db true ;Flag for search first/next
- flag db false ;Show sort done on pass
- Zooflag db false ;Flag to signify zoo file
- Crushed db false ;Flag to signify crushed files
- A_Flag db false ;Set no default archiver
- D_Flag db false ;Set no delete when finished
- F_Flag db false ;Set no mail only stuff
- M_Flag db false ;Show net/node on extract?
- N_Flag db true ;Set default sort performed
- O_Flag db false ;Set default to non-overwrite
- Q_Flag db true ;Set default to quiet
- IsZip db false ;Flag to show ZIP file
- IsDWC db false ;Flag to show DWC file
- IsLZH db false ;Flag to show LZH file
- Parsed db false ;Flag to show names were parsed
- Got_name db false ;Cmd line fname is OK...
- Characters db false ;Print string char counter
- Last_Chance db false ;Flag for Arce useage
- elevel db 0 ;Last reported error level
- count db 0 ;Number of passes complete
- order db 0 ;Flag to show archive in order
- temp db 'SpazTmp1.$$$',0 ;Temp filename to use
- thomlen equ $-temp ; .jjn
- filename_file db 'SpazTmp2.$$$',0 ;Filename for list of files
- end_arc db 1Ah,0 ;Mark to show end of arc
- even
- arg_len dw 0 ;Length of command line arg
- buf_pos dw 0 ;Position in header buffer
- endpath dw 0 ;Holds end of path address
- pathlen dw 0 ;Holds length of path .jjn
- files_handle dw 0 ;Handle for filespec file .jjn
- name_count dw 0 ;Number of filenames found .jjn
- names_used dw 0 ;Number of names used after.jjn
- ; all the names were found .jjn
- fname_ptr dw 0 ;Point into filename buffer.jjn
- Opt_Address dw false ;Pointer to cmd line fname
- Opt_Length dw false ;Address of cmd line fname
- high_pos dw 0 ;High byte of file pointer
- low_pos dw 0 ;Low byte of file pointer
- in_handle dw 0 ;Handle for read file
- out_handle dw 0 ;Handle for write file
-
-
- par_blk dw 0 ;Copy of parent's environment
- dw offset cmd_cnt ;Pointer to command line
- sg1 dw 0
- dw offset fcb1
- sg2 dw 0
- dw offset fcb2
- sg3 dw 0
-
- stk_seg dw 0 ;Saved stack segment
- stk_ptr dw 0 ;Saved stack pointer
- dir dw 0 ;Pointer for PATH search
- enddir dw 0 ;End address of PATH variable
- cmd1_cnt dw 0 ;Length of wildcard filename
- env_len dw 0 ;Length of PATH in Environment
- BundlePosition dw offset BundleNames ;Current position for mail
- env db 'PATH',0 ;Environment variable to find
- DefaultBundle db '*.MO?',0 ;First mail type to look for
- BundleNames db 'TUWETHFRSASU' ; and the rest of 'em....
-
-
- Spaz proc near ;Entry point from MS-DOS
-
- start: mov AX,CS
- mov sg1,AX
- mov sg2,AX
- mov sg3,AX
-
- mov AH,SetDTA ;AH = Set Disk Tranfer Area
- mov DX,offset dta_buf ;Address of scratch space
- int DOS ;Give it to DOS
-
- xor AX,AX
- mov word ptr Names_Count,AX
- cli ;Disable interupts
- lea sp,bottom-1 ;Move stack to save position
- sti ;OK for interups now...
-
- mov DX,offset bottom ;Point DX to end of Spaz
- mov BX,DX ;Info needed in BX
- add BX,0fh ;Add 1 paragraph to it
- mov CL,4 ;CL = counter for shift
- shr BX,CL ;= BX/16 (# of paras needed)
- mov AH,ModifyMemory ;AH = Modify memory block
- int DOS ;Extra memory released...
-
- ; First, identify self and examine parameters...
-
- mov DX,offset TitleScreen ;DX points to message
- mov BX,2 ;Output to standard error
- mov CX,TitleLength ;Length of header string
- mov AH,WriteFile ;Output to handle
- int DOS ;Call DOS to do it
- mov SI,offset env ;Search for 'PATH'
- mov es,es:[2ch] ;Get environment segment
- call getenv ;Read in PATH string
-
- mov BX,cmdtail ;ES:BX = command parameters
- call argc ;Get number of arguments
- cmp AX,2 ;At least 1 argument?
- jae args_ok ;If yes, keep going
-
- Syntax: mov DX,offset Usage ;DX points to usage string
- mov BX,2 ;Output to standard error
- mov CX,UsageLength ;Length of usage string
- mov AH,WriteFile ;Output to handle
- int DOS ;Call DOS to do it
- mov AL,0 ;Errorlevel 0 exit
- mov AH,ExitWithCode ;AH = Terminate to DOS
- int DOS ;Transfer to DOS (for good)
-
- args_ok:
- call options ;Scan off any options
-
- ; Here, ES:BX = argument address and AX = argument length
-
- cld ;Direction register increments
- mov SI,BX ;Point SI to argument
- lea DI,cmd1 ;DI = destination
- mov CX,AX ;Put character count in CX
- mov cmd1_cnt,AX ;And save it for later!
- rep movsb ;Move argument to buffer
-
- ; End the filename (or PATH if -F used) with a zip.
-
- mov byte ptr [DI],0
-
- ; Here, we check for a -F option. If it is true, we tack on the
- ; default filename (*.MO?) and start a mail run.
-
- cmp F_Flag,true ;Is this a mail run?
- jne NotAMailRun ;Nope, continue
-
- cmp byte ptr [DI-1],'\' ;Did they have backslash?
- je AddName ;If yes, do the name
- mov byte ptr [DI],'\' ;Else add a slash
- inc word ptr cmd1_cnt ;And bump counter
- inc DI ;Adjust pointer
- AddName:
- mov byte ptr [DI-1],0 ;Make it ASCIIZ
- mov DX,offset cmd1 ;Point to filename/path
- mov AX,4300h ;Get attribute
- int DOS ;Call DOS to do it
- mov byte ptr [DI-1],'\' ;Restore back slash
- and CX,00010000b ;Is this a directory?
- jnz DirectoryFound ;Go if yes.
- mov DX,offset err25 ;Invalid directory message
- mov AH,OutputString ;DOS print string function
- int DOS ;Call DOS to do it
- jmp syntax ;Display syntax screen
-
- DirectoryFound:
- mov SI,offset DefaultBundle ;Point to bundle name
- mov CX,3 ;Count for name length
- rep movsw ;Stuff name in buffer
- add cmd1_cnt,6 ;Fix the counter
- jmp short Isolate ;No need to check it now
-
- ; Here, we will check to make sure there is a valid extension.
- ; If none was given, a default extention of '.*' will be added.
-
- NotAMailRun:
- std ;Set up to move backwards
- mov SI,offset cmd1 ;Get address of filename
- mov DI,SI ;So we can check for end
- mov AX,cmd1_cnt ;Get length in AX
- add SI,AX ;Point to end of filename
- push SI ;Save end address
- scan: lodsb ;Get a character
- cmp AL,'.' ;Is it a period?
- je ExtentionIsOk ;If yes, extention OK
- cmp AL,'\' ;Is it filename separater?
- je UseDefault ;Stop if yes
- cmp DI,SI ;Scanned whole name?
- jne scan ;No, go get more
- UseDefault:
- pop DI ;DI = end address of filename
- mov byte ptr [DI],'*' ;Add full wildcard search
- mov byte ptr [DI+1],'.' ;Add a dot to filename
- mov byte ptr [DI+2],'*' ;Add wildcard extension
- mov byte ptr [DI+3],0 ;End it with a zip
- add word ptr cmd1_cnt,3 ;Adjust length count
- push DI ;Maintain stack balance
-
- ; Next, we isolate the path from the filename so that successive
- ; filenames can be tacked onto it in case wildcards are used...
-
- public ExtentionIsOk
- ExtentionIsOk:
- add SP,2 ;Remove garbage from stack
-
- Isolate:
- call show_opt ;Display option info
- std ;Set up to move backwards
- mov SI,offset cmd1 ;Get address of filename
- ;so we can check for a path.jjn
- mov CX,cmd1_cnt ;Get length in CX .jjn
- add SI,CX ;SI = end of filename .jjn
- dec SI ; .jjn
- public path1
- path1: lodsb ;Get a character
- cmp AL,'\' ;Filename separator?
- je save_path ;Stop if yes
- cmp AL,':' ;Drive separator?
- je save_path ;Stop if yes
- loop path1 ;Decrement and loop .jjn
- inc SI
- mov endpath,SI ;Save address
- mov pathlen,CX ;Save path length (0) .jjn
- jmp short _end_p ;Skip double save .jjn
- public save_path
- save_path:
- inc SI ;Adjust past \ character
- inc SI ;Need 2 for auto dec...
- mov endpath,SI ;Save address of end of path
- mov pathlen,CX ;Save path length .jjn
- _end_p: ; .jjn
- cld ;Set direction forward
- ;
- ; Now we call the wildcard expander. This creates a list of filenames that
- ; match the filespec so we can retrieve them later. If there are more than
- ; 'NamesFound' matches, it will save them on disk.
- ;
- mov on_disk,0 ;List of files is not on disk
- mov Name_count,0 ;No names found yet
- mov num_names,0
- DoAllMail:
- call FindNames ; Find all matching files .jjn
- cmp F_Flag,true ;Are we doing a mail run?
- jne NotDoingMail ;Go if not
-
- mov SI,BundlePosition ;Get address for bundle name
- cmp SI,offset SPAZ ;No more names to do?
- je NotDoingMail ;If not, we're done...
- lodsw ;Get next bundle name
- mov DI,EndPath ;End of path to filename
- add DI,2 ;Adjust to right spot
- stosw ;And stuff in new name
- mov BundlePosition,SI ;Save new name offset
- jmp short DoAllMail ;And get more filenames
-
- NotDoingMail:
- cmp on_disk,0 ;Is stuff on disk?
- jz NothingOnDisk ;Nope skip pointer adjust
- mov AH,MoveFilePointer ;Move pointer DOS function
- xor CX,CX ;Offset from beginning of file
- mov DX,CX ;32 bit
- mov AL,CL ;Mark for 'beginning'
- mov BX,files_handle ;Get the file handle
- int DOS ;Call DOS to do it
- NothingOnDisk:
- mov AX,name_count ; number of names found
- or AX,AX ; return with zero flag set
- jnz Main ; skip error stuff .jjn
-
- ; If we got here, there were no names found.
- ; (Moved from the old wild_card procedure. .jjn)
-
- cmp F_Flag,true ;Was this a mail run?
- jne NormalNotFound ;If not, do normal exit
- mov DX,offset NoMail ;Mail run error message
- mov AH,OutputString ;DOS print string function
- int DOS ;Call DOS to do it
- jmp short DoneTotally ;Denis Miller time
- NormalNotFound:
- mov AX,2 ;Change error to file not found
- call err_msg ;Display error in english
- push AX ;Save error code
- mov SI,offset cmd1 ;Point to filename
- call upper ;Convert to upper case
- call ShowIt ;Show it (not found)
- mov SI,offset crlf ;CR,LF
- call ShowIt ;On screen
- pop AX ;Restore error code
- DoneTotally:
- mov AH,ExitWithCode ;Terminate with code
- int DOS ;Exit program
-
- ; This is the main loop of the program. It is run once for every
- ; matching filename found from the command line. Needed variables
- ; are reset each time through.
-
- Main:
- mov zooflag,false ;Reset variables
- mov byte ptr cmd_cnt,9
- mov crushed,false
- mov word ptr buf_pos,0
- mov flag,false
- mov count,false
- mov order,false
- mov num_hdr,false
- mov IsZip,false
- mov IsDWC,false
- mov IsLZH,false
- mov Last_Chance,false
-
- mov DI,offset ExtractOptions ;Point to last set of options
- mov CX,9 ;Max options set at 5 bytes
- mov AL,blank ;Blank them out (spaces)
- rep stosb
-
- mov SI,offset crlf ;Cr,Lf between runs
- call ShowIt
- call wild_card ;Grab a filename to work on
-
- ; If we return from wild_card, at least 1 matching filename was found.
- ; Otherwise the program reports its status and quits. If a wild card
- ; was used, it has now been extended to a fully qualified filename. Now
- ; it has to be checked for archive type etc. etc.
-
- mov SI,offset msg4 ;SI = 'Searching:'
- call ShowIt ;Put it on screen
- mov SI,offset cmd1 ;SI = filename
- call upper ;Convert it to upper case
- call ShowIt ;Put it on screen
- cmp M_Flag,true ;Displaying net/node?
- jne NoAddress ;Skip next part if not
- call DisplayNode ;Figure out the info
- mov SI,offset info4 ;From message
- call ShowIt ;Display it
- mov SI,offset BuildNet ;Our ASCII info
- call ShowIt ;Display it
- NoAddress:
- mov SI,offset crlf ;SI = cr/lf
- call ShowIt ;On screen
-
- mov SI,offset cmd1 ;SI = full filename
- mov DI,offset pakfile ;DI = new command line
- do_count:
- lodsb ;Get a character from line
- cmp AL,0 ;End of filename?
- je done ;yes, we are finished
- cmp AL,cr
- je done1
- inc byte ptr cmd_cnt ;Else, bump character counter
- stosb ;Save char in command line
- jmp short do_count ;and loop back...
-
- done: mov AL,cr ;Cmd line must end with cr
- done1: stosb ;Stuff final character
-
- mov byte ptr [DI],0 ;make it ASCIIZ ***
-
- ; This little section adds any unique file names that are to be
- ; extracted from the archive. If this option is used in conjunction
- ; with /d, the archive will be deleted after extraction. BE CAREFUL
-
- cmp Parsed,true ;Were filenames specified?
- jne No_Parsed ;Skip this if not
- dec DI ;Back up destination pointer
- mov SI,offset Extract_Names ;SI = extract name buffer
- mov CX,word ptr Names_Count ;Get length of names
- add byte ptr cmd_cnt,CL
- rep movsb ;Set up the line
- mov byte ptr [DI],cr ;End it all with a cr
- mov byte ptr [DI+1],0 ;Make it ASCIIZ
-
- ; Here is where we check the archive type. If it is a zoo file, it is
- ; extracted as is. If it is an ARC/PAK/PK file, it is first checked to
- ; ensure that it is in proper order by date time...
-
- No_Parsed:
- call ArchiveCheck ;Check the archive type
- jnc Zoo_Check_OK ;If all is well, continue
- jmp main ;Else, try to do the next one
-
- Zoo_Check_OK:
- mov DX,offset UnArc4 ;Point to LOOZ.EXE
- cmp zooflag,true ;Is this a zoo file?
- jne no_zoo
- call find ;Does LOOZ exist?
- jc no_looz ;Nope, check for zoo
-
- ; If execution falls here, LOOZ was found on the path. We have to change
- ; the extract option to 'x' as looz does not understand 'e'
-
- cmp O_Flag,true ;Do we want forced overwrite?
- jne DontForceLooz ;Go if not
- jmp short no_looz ;If we do, call zoo instead
- DontForceLooz:
- mov byte ptr ExtractOptions + 1,'x' ;Change extract option
- jmp X_OK ;Go execute looz
-
- ; If we get here, a zoo archive was detected, and LOOZ was not found.
- ; Check for ZOO.EXE and quit if not found...
-
- no_looz:
- mov DX,offset UnArc7 ;DX = zoo.exe
- cmp O_Flag,true ;Do we want forced overwrite?
- jne DoNotForceZoo ;Exit if not, else
- mov byte ptr ExtractOptions +2,'S' ;This will force overwrite
- mov byte ptr ExtractOptions +3,'O' ;This is needed too
- DoNotForceZoo:
- mov byte ptr ExtractOptions +1,'x' ;Change extract option
- jmp zoo ;Go hunt for it
-
- no_zoo: cmp IsDWC,true ;Is this a DWC file?
- jne TryZIP ;Nope, check for ZIP
- mov DX,offset UnArc8 ;Point to 'DWC.EXE'
- cmp O_Flag,true ;Overwrite mode?
- jne DoNotForceDwc ;If not, exit
- mov byte ptr ExtractOptions + 1,'x' ;This will allow DWC
- mov byte ptr ExtractOptions + 2,'w' ;to overwrite existing files
- jmp Zoo ;Try to run it
- DoNotForceDwc:
- mov byte ptr ExtractOptions + 1,'e' ;Normal extract mode
- jmp Zoo ;Try to run it
-
- TryZIP: cmp IsZIP,true ;Is this a ZIP file?
- jne TryLZH ;If not, check for LHArc
- mov DX,offset UnArc9 ;Point to 'PKUNZIP.EXE'
- cmp O_Flag,true ;Overwrite mode?
- jne DoNotForceZIP ;Exit if not
- mov byte ptr ExtractOptions + 1,'-' ;This will allow Zip
- mov byte ptr ExtractOptions + 2,'o' ;to overwrite existing files
- jmp Zoo ;Try to run it
- DoNotForceZIP:
- jmp Zoo ;Try to run it
-
- TryLZH: cmp IsLZH,true ;Is this an LHZ file?
- jne TryNormal ;Must be an ARC
- mov DX,offset UnArc10 ;Point to 'LHARC.EXE'
- mov byte ptr ExtractOptions,'e' ;Must have extract option
- cmp O_Flag,true ;Overwrite mode?
- jne DoNotForceLZH ;Exit if not
- mov byte ptr ExtractOptions + 2,'/' ;This will allow LHArc
- mov byte ptr ExtractOptions + 3,'m' ;to overwrite existing files
- mov byte ptr ExtractOptions + 4,'c' ;Not very exotic....
- jmp Zoo ;Try to run it
- DoNotForceLZH:
- jmp Zoo ;Try to run it
-
- TryNormal:
- call Sort_It
- jnc part2 ;Sort was good, go unarc
-
- mov SI,offset sorterr ;Point to error message
- call ShowIt ;Put it on screen
-
- Part2:
- mov byte ptr ExtractOptions + 1,'e' ;Normal extract option
- cmp Crushed,true ;Crushed files?
- jne part3 ;Nope, check for ARCE
-
- Part2a: mov DX,offset UnArc5 ;Point to PAK.EXE
- cmp O_Flag,true ;Overwrite mode?
- jne DoNotForcePak ;Exit if not
- mov byte ptr ExtractOptions + 2,' ' ;A space for the new PAK
- mov byte ptr ExtractOptions + 3,'/' ;A hyphen for the new PAK
- mov byte ptr ExtractOptions + 4,'w' ;This tells pak to force
- mov byte ptr ExtractOptions + 5,'a' ; overwrites always
- DoNotForcePak:
- cmp byte ptr D_flag,true ;Was delete flag set?
- jne NoDelete ;Nope, continue...
- mov byte ptr ExtractOptions + 1,'x' ;Delete archive when done
- NoDelete:
- jmp zoo ;Do PAK and PAK only.
-
- part3: cmp byte ptr A_Flag,true ;Default to ARCE?
- jne Xarc ;Go if not
-
- NoneFound:
- cmp Crushed,true ;Crushed files?
- jne OkForArce ;Nope, keep going
- jmp Give_Up ;If yes, just quit
- OkForArce:
- cmp O_Flag,true ;Force overwrite mode?
- jne DontForceArce ;Go if not
-
- mov SI,offset pakfile ;Point to command line
- goagain:
- lodsb
- or AL,AL
- jnz goagain
- mov DI,SI ;Get address in DI
- mov byte ptr [DI-2],Blank ;Put in a space
- mov byte ptr [DI-1],'/' ;and an Option delimiter
- mov byte ptr [DI],'R' ;and Force overwrites...
- mov byte ptr [DI+1],cr
- mov byte ptr [DI+2],0
- add byte ptr cmd_cnt,3 ;Fix the count up
-
- DontForceArce:
- mov DX,offset UnArc6 ;Else point to it
- mov byte ptr ExtractOptions + 1,' ' ;This removes any options
- mov byte ptr ExtractOptions + 2,' ' ; that may have been put
- mov byte ptr ExtractOptions + 3,' ' ; in by other un-archers
- jmp short zoo ;Go try to run it
-
- Xarc: mov DX,offset UnArc1 ;Point to PKXARC.EXE
- mov byte ptr ExtractOptions + 1,' ' ;Remove 'e' option
- cmp O_Flag,true ;Overwrite mode?
- jne DoNotForceXarc ;Exit if not
- mov byte ptr ExtractOptions + 1,'-' ;This forces PKWare to use
- mov byte ptr ExtractOptions + 2,'r' ; it's overwrite mode
- DoNotForceXarc:
- call find ;See if it exists
- jnc X_OK ;Got it!
-
- mov DX,offset UnArc2 ;Point to PKXARC.COM
- call find ;See if it exists
- jnc X_OK ;Got it!
-
- mov DX,offset UnArc3 ;Point to PKUNPAK.EXE
- call find ;See if it exists
- jnc X_OK ;Got it, keep going
-
- mov DX,offset UnArc5 ;Point to PAK.EXE
- mov byte ptr ExtractOptions + 1,'e' ;Set up extract for pak
- cmp O_Flag,true ;Overwrite mode?
- jne DontForcePak ;Exit if not
- mov byte ptr ExtractOptions + 2,' ' ;A space for the new PAK
- mov byte ptr ExtractOptions + 3,'/' ;A hyphen for the new PAK
- mov byte ptr ExtractOptions + 4,'w' ;This tells pak to force
- mov byte ptr ExtractOptions + 5,'a' ;overwrite always
- DontForcePak:
- cmp byte ptr D_flag,true ;Was delete flag set?
- jne part3a ;Nope, continue...
- mov byte ptr ExtractOptions + 1,'x' ;Delete archive when done
-
- part3a: call find ;See if it exists
- jnc X_OK ;Got it, continue
- jmp NoneFound ;Try Arce....
-
- Zoo: call find ;See if it exists
- jnc X_OK ;Got it!
-
- ; If this code is executed, then no Un-Arc program was found on the
- ; path. It reports the error and aborts...
-
- Give_Up:
- mov AX,22 ;Unarcher not found
- call err_msg ;Report error in english
- mov AH,ExitWithCode ;Exit with code
- int DOS ;Back to DOS (for good)
-
- X_OK: mov BX,offset par_blk ;BX points to spawn info
- mov AL,0 ;AL = load and execute
- push DS
- push ES
- cli ;Disable interupts
- mov stk_seg,SS ;Save the Stack
- mov stk_ptr,SP ;Both parts...
- sti ;Enable inerupts
- mov AH,ExecuteProgram ;AH = MSDOS exec function
- int DOS ;Transfer to DOS
- cli ;disable interupts
- mov SS,stk_seg ;Restore stack segment
- mov SP,stk_ptr ;Restore stack pointer
- sti ;Enable interupts
- pop ES
- pop DS
-
- mov AH,GetReturnCode ;Get return code from Un-Arcer
- int DOS ;Transfer to DOS
- mov elevel,AL ;Save errorlevel for later
-
- cmp byte ptr crushed,true ;Did we use PAK?
- jne normal ;Nope, check for delete flag
-
- cmp byte ptr D_Flag,true ;Did we mark for delete?
- jne main_loop ;Exit if no
-
- mov SI,offset del_msg ;SI = 'Unlinking...'
- call ShowIt
- mov SI,offset cmd1 ;SI = filename
- call ShowIt
- mov SI,offset crlf
- call ShowIt
- jmp short main_loop ;Go do next file
-
- normal: or AL,AL ;Make sure all is well
- jnz main_loop ;Before allowing a delete
-
- cmp byte ptr D_Flag,true ;Should we delete arc file?
- jne main_loop ;Skip if not
-
- mov SI,offset del_msg ;SI = 'Unlinking...'
- call ShowIt
- mov SI,offset cmd1 ;SI = filename
- call ShowIt
- mov SI,offset crlf
- call ShowIt
-
- mov AH,DeleteFile ;AH = delete file
- mov DX,offset cmd1 ;DX = archive name
- int DOS ;Call DOS to do it
- jnc main_loop ;Go if no errors
- call err_msg ;Show errors but continue...
- main_loop:
- jmp main ;Go get next file
-
-
- ; Print ASCIIZ string pointed to by SI
-
- ShowIt:
- mov AH,CharacterOutput ;Function = console out
- mov byte ptr Characters,0 ;Set count to zip
- show_loop: lodsb ;Get a character
- or AL,AL ;Is it a 0?
- jz ShowIt_exit ;If yes, exit
- inc byte ptr Characters ;Bump char counter
- mov DL,AL ;ASCII char in DL
- int DOS ;Call DOS to print it
- jmp short show_loop ;Go get more
- ShowIt_exit:
- ret ;Return to caller
-
- Spaz endp
-
- argc proc near ;count command line arguments
-
- push BX ;save original BX and CX
- push CX ; for later
- mov AX,1 ;force count >= 1
- argc1: mov CX,-1 ;set flag = outside argument
- argc2: inc BX ;point to next character
- cmp byte ptr [BX],cr
- je argc3 ;exit if carriage return
- cmp byte ptr [BX],blank
- je argc1 ;out of argument if blank
- cmp byte ptr [BX],tab
- je argc1 ;outside argument if ASCII tab
- ;otherwise not blank or tab,
- jcxz argc2 ;jump if already in argument
- inc AX ;else found argument, count it
- not CX ;set flag = inside argument
- jmp argc2 ;and look at next character
-
- argc3: pop CX ;restore original BX and CX
- pop BX
- ret ;return AX = argument count
-
- argc endp
-
-
- argv proc near ;get address & length of
- ;command tail argument
- xor AH,AH ;initialize argument countef
- argv1: mov CX,-1 ;set flag = outside argument
- argv2: inc BX ;point to next character
- cmp byte ptr [BX],cr
- je argv7 ;exit if carriage return
- cmp byte ptr [BX],blank
- je argv1 ;outside argument if ASCII blank
- cmp byte ptr [BX],tab
- je argv1 ;outside argument if ASCII tab
- ;if not blank or tab...
- jcxz argv2 ;jump if already inside argument
- inc AH ;else count arguments found
- cmp AH,AL ;is this the one we're looking for?
- je argv4 ;yes, go find its length
- not CX ;no, set flag = inside argument
- jmp argv2 ;and look at next character
-
- argv4: ;found desired argument, now
- ;determine its length...
- mov AX,BX ;save param, starting address
-
- argv5: inc BX ;point to next character
- cmp byte ptr [BX],cr
- je argv6 ;found end if carriage return
- cmp byte ptr [BX],blank
- je argv6 ;found end if ASCII blank
- cmp byte ptr [BX],tab
- jne argv5 ;found end if ASCII tab
-
- argv6: xchg BX,AX ;set ES:BX = argument address
- sub AX,BX ;and AX = argument length
- jmp short argvx ;return to caller
- argv7: xor AX,AX ;set AX = 0, argument not found
- argvx: ret ;return to caller
-
- argv endp
-
-
- getenv proc near ; return address and length
- ; of environment variable
-
- push CX ; save registers
- push SI
-
- mov CX,8000h ; assume max env. = 32 KB
- xor DI,DI ; initial env. offset
- xor AX,AX ; default length result
- get1: cmp byte ptr ES:[DI],0 ; check for end of environment
- je get4 ; end reached, return AX = 0
- pop SI ; initialize address of target
- push SI ; variable to be found
-
- repe cmpsb ;Compare target and env. strings
- cmp byte ptr [SI-1],0
- jne get2 ;Jump if incomplete match
- cmp byte ptr ES:[DI-1],'='
- je get3 ;Jump if match was complete
-
- get2: repne scasb ;No match, scan for end string
- jmp get1 ;Try again to match
-
- get3: push DI ;Save address after = sign
- repne scasb ;Look for end of this string
- pop AX ;Get back starting address
- xchg DI,AX ;Find string length
- sub AX,DI
- dec AX ;Don't include null byte
-
- get4: pop SI ;Common exit point
- pop CX
- mov CS:env_len,AX ;Save PATH length
- or AX,AX ;Null PATH?
- jz get5 ;Exit if yes
- push ES ;Get path segment into
- pop DS ; DX for string move
- push CS ;Now ES points to data
- pop ES ; in our code segment
- mov CX,AX ;Get length of path in CX
- mov SI,DI ;Path is now source
- mov DI,offset saved ;Destination is our area
- rep movsb ;Move path into this segment
- get5: push CS ;Now we have to restore
- pop DS ; the original DS
- push CS
- pop ES
- ret ;Return to caller
- getenv endp
-
-
- ; This routine searches the current directory, and (if needed), the
- ; entire PATH, looking for an unarchiver to use. It is called with
- ; DX pointing to an ASCIIZ filename to look for and returns with
- ; carry clear if it is found. Carry Set if not found.
-
- find proc near
- push DX ;Save pointer to filename
- mov AH,SearchForFirst ;Search for first
- pop DX ;Get filename address
- push DX ;Save it again
- xor CX,CX ;Normal attribute
- int DOS ;Give it to DOS
- jc find1 ;Not found, search path
- pop DX ;Point DX to filename
- ret ;exit Find...
-
- find1: mov AX,env_len ;Get PATH length
- or AX,AX ;Did we find a path?
- jnz find2 ;Keep going if yes
- no_exist:
- pop DX ;Point DX to filename
- stc ;Carry set to show error
- ret ;Exit Find
-
- find2: mov DI,offset saved ;Point to the path string
- mov dir,DI ;dir = start of path string
- add DI,AX ;AX = end of path string
- mov enddir,DI ;save it
- mov byte ptr [DI],0 ;Null terminator for path
-
- find3: mov DI,offset new ;Area for path\filename
- mov SI,dir ;Get current address in path
-
- cmp [enddir],SI ;End of path variable?
- jbe no_exist ;Not found, exit
-
- find4: lodsb ;Get a character
- cmp AL,';' ;Seperator?
- je find5 ;Yes, go tack on filename
- cmp AL,0 ;Are we finished?
- je find5 ;Yes, go
- stosb ;Stuff character
- jmp short find4 ;and go for another
-
- find5: mov dir,SI ;Save current path address
- cmp byte ptr [DI-1],'\' ;Path separator?
- je find6 ;Yup, keep goin
- mov byte ptr [DI],'\' ;Else, put one in
- inc DI ;Bump the pointer
-
- find6: pop SI ;Get filename address
- push SI ;Save it back again
-
- find7: lodsb ;Get character from filename
- cmp AL,0 ;Got whole filename?
- je find8 ;Go if yes
- stosb ;Else put character in buffer
- jmp find7 ;Go get the rest
-
- find8: stosb ;Save the null (ASCIIZ)
- mov AH,SearchForFirst ;Search for first
- mov DX,offset new ;Point to path\filename
- xor CX,CX ;Normal attribute
- int DOS ;Give it to DOS
- jc find3 ;Not found try next path
- pop DX ;Clear junk off stack
- mov DX,offset new ;DX = full path\filename
- clc ;Show no errors
- ret ;Exit (so we can exec it)
- find endp
-
-
- ; This routine determines what type of archive is being worked on.
- ; It will set a flag to tell SPAZ which un-archiver to try and use.
-
- ArchiveCheck proc near
-
- mov AH,OpenFile ;AH = open file request
- mov AL,0 ;read access only
- mov DX,offset cmd1 ;Point to archive name
- int DOS ;Call DOS to open it
- jc probs
-
- xchg AX,BX ;Handle in BX
- mov AH,ReadFile ;AH = read file
- mov CX,4 ;Read first 4 bytes
- mov DX,offset Usage ;Read byte into usage area
- int DOS ;Call DOS to do it
- jc probs
-
- mov AH,MoveFilePointer ;Get ready to adjust
- mov AL,2 ;From end of file
- mov CX,0ffffh ;2 spaces
- mov DX,0fffeh
- int DOS ;Call DOS to do it
- jc probs
-
- mov AH,ReadFile ;Read last 2 bytes
- mov CX,2
- mov DX,offset Usage + 4 ;Buffer for save
- int DOS ;Call DOS to do it
- jc probs
-
- mov AH,CloseFile ;AH = close file
- int DOS ;Call DOS to do it
- jc probs
-
- mov AX,word ptr Usage + 4 ;Get DWC bytes
- cmp AX,4357h ;Is it a DWC file?
- jne IsItZoo ;Go, if not
- mov IsDWC,true ;Else set flag
- jmp short EndCheck ;And exit
-
- IsItZoo:
- mov AX,word ptr Usage ;Get value
- cmp AX,4f5ah ;Is it a zoo file?
- jne IsItZip ;Go if not, else
- mov zooflag,true ;Mark for zoo
- jmp short EndCheck
-
- IsItZip:
- cmp AX,4b50h ;Is it a ZIP file?
- jne IsItArc ;Go, if not
- mov IsZip,true ;Set flag
- jmp short EndCheck ;We're outa here
-
- IsItArc:
- cmp AL,1Ah ;Is it a normal Arc/Pak?
- jne IsItLZH ;Skip this file if not
- jmp short EndCheck ;We're outa here
-
- IsItLZH:
- mov AX,word ptr Usage + 2 ;Get LH's ID bytes
- cmp AX,6C2Dh ;Is this an LH Arc?
- jne NotAnArchive ;Report error if not
- mov IsLZH,true ;Mark for LHArc
- EndCheck:
- clc ;Show no errors
- ret
-
- probs: push AX ;Save error code
- call err_msg ;Report error in english
- mov SI,offset zerr ;SI = Zoo check error message
- call ShowIt ;Display it
- pop AX ;Restore error code
- NotAnArchive:
- stc ;Show error
- ret ;Return to caller
-
- ArchiveCheck endp
-
-
- ; This routine is responsible for sorting ARCType bundles into proper
- ; FidoNet Mail format. i.e. Sorted by date/time. It is accomplished
- ; by sorting all the headers and re-writting the entire archive...
-
- Sort_It proc near
- cld ;Move forward again...
- xor AL,AL
- mov num_hdr,AL ;Init header counter
- mov flag,false
-
- mov DX,offset cmd1 ;DX = Archive filename
-
- mov AH,OpenFile ;AX = Open file
- xor AL,AL ;Normal Attribute
- int DOS ;Give it to DOS
- jnc open_ok ;Continue if it worked
- jmp short inv_hdr ;Go report errors
-
-
- ; This routine will read in the archive file headers so that they
- ; can be sorted.
-
- open_ok:
- mov in_handle,AX ;Save file handle
- mov buf_pos,0 ;Init buffer position
- call read_hdr ;Read in first header
- jnc got_1st ;If clear, we're OK
-
- ; Truncated file. Somethings weird in Denmark!
-
- mov AX,19 ;Truncated file
- inv_hdr:
- call err_msg ;Put it on screen
- stc
- ret ;Exit Sort_It with error
-
-
- ; If we get this far, the first header has been read in. Stuff it in
- ; the buffer and go for the rest...
-
- got_1st:
- mov SI,cmdtail ;Point to arc data
- cmp byte ptr [SI+1],0 ;End of Archive?
- jne Chk_Crushed ;Exit for sort
- jmp got_em
- Chk_Crushed:
- cmp byte ptr [SI+1],10 ;Crushed file?
- jb Not_Crushed ;Nope, continue
- mov Crushed,true ;Else, show crushed
- Not_Crushed:
- cmp byte ptr [SI],1ah ;Do we have a PAK file?
- je pak_ok ;If yes, keep going
- mov AX,20 ;Invalid header
- call err_msg ;Report error in english
- add sp,2 ;Remove return address
- mov AH,CloseFile ;Close the file
- mov BX,in_handle
- int DOS ;Call DOS to close file
- mov byte ptr elevel,1 ;Report error for no delete
- jmp main ;Bad file, try the next one
-
- pak_ok: mov DI,offset hdr_buf ;Get buffer address
- add DI,[buf_pos] ;Adjust to current pos
- mov AX,low_pos ;Get file pointer low word
- mov [DI],AX ;Stuff it in buffer
- mov AX,high_pos ;Get file pointer high word
- mov [DI+2],AX ;Stuff it in buffer
- add DI,4 ;Adjust the pointer
- mov CX,29 ;Length of archive header
- rep movsb ;Put info in buffer
- add buf_pos,arc_len ;Bump the buffer pointer
-
- inc num_hdr
- cmp num_hdr,Entries ;Have we got too many?
- jb room ;Nope, continue...
-
- mov AX,21 ;Too many archive entries
- jmp nope ;Report and exit
-
- room: call read_next ;Get next header
- jnc got_1st ;Go stuff it in buffer
- jmp short got_em ;Got all headers, exit
-
- read_next:
- mov DI,cmdtail ;DI = start of header
- mov DX,word ptr [DI+15] ;DX = low byte of arc size
- mov CX,word ptr [DI+17] ;CX = high byte of arc size
- mov BX,in_handle ;BX = opened file handle
- mov AH,MoveFilePointer ;AH = move file pointer
- mov AL,1 ;AL = from current position
- int DOS ;Give it to DOS
- read_hdr:
- mov BX,in_handle ;Get opened file handle
- xor CX,CX ;Set offset for search
- xor DX,DX ; to zero bytes
- mov AH,MoveFilePointer ;AH = move file pointrr
- mov AL,1 ;AL = from currcnt position
- int DOS ;Call DOS to do it
- mov high_pos,DX ;Save the high word
- mov low_pos,AX ;Save the low word
- mov BX,in_handle ;Get opened file handle
- mov CX,29 ;Read in 29 bytes
- mov DX,cmdtail ;Buffer for read...
- mov AH,ReadFile ;Read from file
- int DOS ;Give it to DOS
- ret
-
- got_em: mov Order,true ;Archive already in order
-
- cmp byte ptr N_Flag,false ;Skip sort?
- jne sort ;If yes, exit
- mov BX,in_handle ;Get the file handle
- mov AH,CloseFile ;So we can close it
- int DOS ;Call DOS to do it
- jmp Back_to_main ;Exit sort
-
- sort: mov flag,false ;Show no changes made
- mov count,1 ;To prevent sort past end
- mov AH,num_hdr ;Get number of entrys
- cmp AH,1 ;Is there only 1 entry?
- jbe sort_exit ;No sort if 0 or 1 entry
-
- mov SI,offset hdr_buf ;SI = start of header buffer
- mov DI,offset hdr_buf+arc_len ;DI = 2nd entry in buffer
- sort1: mov BX,23 ;BX = offset to header date
- mov AX,[SI+BX] ;Get date from 1st entry
- mov DX,[DI+BX] ;Got date from 2nd entry
- cmp AX,DX ;Which is higher?
- ja change ;Swap if 1st > 2nd
- jne sort2 ;If not = get next entry
- mov BX,25 ; else get offset to time
- mov AX,[SI+BX] ;Get time from 1st entry
- mov DX,[DI+BX] ;Get time from 2nd entry
- cmp AX,DX ;Which is higher?
- ja change ;Swap if 1st > 2nd
-
- ; If Date and Time are identical, no changes are made
-
- sort2: add SI,arc_len ;Point to next entry
- add DI,arc_len ;Point to next entry
- inc count ;Bump # of entries completed
- mov AH,count ;Get the number
- cmp AH,num_hdr ;Done all entries?
- je pass ;End of this pass if yes
- jmp short sort1 ;Else do next entry
-
- ; This section will swap the entry pointed to by SI with the entry
- ; pointed to by DI...
-
- change: push SI ;Save pointer to 1st entry
- push DI ;Save pointer to 2nd entry
- mov CX,arc_len ;# of bytes in an entry
- chg1: mov AL,[DI] ;Get byte from destination
- movsb ;Move Source to Destination
- mov [SI-1],AL ;Move Destination to Source
- loop chg1 ;Loop back for more
- pop DI ;Restore 2nd entry address
- pop SI ;Restore 1st entry address
- mov flag,true ;A swap has been made (pass)
- mov Order,false ;Show swap made (constant)
- jmp sort2 ;Do next entry
-
- ; Here we check if a change was made. If no changes were made
- ; then the archive was already in order...
-
- pass: mov AH,flag ;Get the sort flag
- cmp AH,true ;Was a change made?
- je sort ;Go again if change was made
-
- sort_exit:
- mov AL,Order ;Was archive in order?
- cmp AL,true ;If yes, do not write
- jne write
- mov BX,in_handle ;Get the file handle
- mov AH,CloseFile ;So we can close it
- int DOS ;Call DOS to do it
- jmp Back_to_main ;The file out again.
-
- write:
- mov DI,offset tempspec ;point to temp filespec .jjn
- mov SI,offset cmd1 ;get location of command .jjn
- mov CX,pathlen ;get path length .jjn
- rep movsb ;make a copy .jjn
- mov SI,offset temp ;Point to temp filename .jjn
- mov CX,thomlen ;get length of filename .jjn
- rep movsb ;copy it after the path .jjn
- mov DX,offset tempspec ;Point to temp filespec .jjn
- xor CX,CX ;Use normal attribute
- mov AH,CreateFile ;AH = create or truncate
- int DOS ;Call DOS to do it
- jnc create_ok ;Go if all is well
- nope: call err_msg ;Report error in english
- stc ;Carry = Sort failed
- ret ;Back to main section
-
- ; Here, the temp file has been created and the handle for that file is
- ; in AX.
-
- create_ok:
- mov out_handle,AX ;Save handle for write file
-
- ; Now, we have to read in the sorted entry info, and gather more stuff
- ; from the archive headers
-
- mov SI,offset hdr_buf ;Point to the sorted info
- mov AL,num_hdr ;Get number of entries
- nxt_hdr:
- mov flag,false ;Use flag for eof check
- push AX ;Save # of entries for later
- push SI ;Save buffer pointer
- mov DX,[SI] ;Get low word of file position
- mov CX,[SI+2] ;Get high word of position
- mov low_pos,DX
- mov high_pos,CX
-
- clc
- add DX,29 ;Adjust for arc header
- adc CX,0 ;Include carry if any
-
- mov BX,in_handle ;Get read file handle
- mov AL,0 ;Offset is from beginning
- mov AH,MoveFilePointer ;AH = move file pointer
- int DOS ;Call DOS to do it
-
- ; The file pointer has been set to the read location. First we
- ; write the header. Then we read and write the archive data.
-
- hdr_in: call info ;Print the copy info
- pop DX ;Get buffer pointer
- push DX ;And save it again
- add DX,4 ;Skip past file location
- mov CX,29 ;Number of bytes to write
- mov BX,out_handle ;Get the write file handle
- mov AH,WriteFile ;AH = write to file
- int DOS ;Call DOS to write the header
- jnc hdr_out ;Header written ... go
- add sp,4 ;Get rid of stack junk
- jmp short nope ;Exit, we had problems
-
- hdr_out:
- pop SI ;Point to the header
- push SI ;Save it back
- mov DX,[SI+21] ;Get high word of entry size
- mov AX,[SI+19] ;Get low word of entry size
-
- ; DX:AX contains the number of bytes that have to be read/written.
-
- xor CX,CX ;High word of buffer size
- mov BX,bsize ;Low word of buffer size
-
- ; CX:BX contains the number of bytes we can do at one time.
-
- cont: clc ;Get ready for subtract
- sub AX,BX ;Subtract low word
- sbb DX,CX ;Subtract high word
- push AX
- push DX
- push BX
- push CX
- jae more1 ;There's still more to go
-
- clc
- add BX,AX ;Add back last result
- mov flag,true ;Show end of data reached
-
- ; Here BX contains the remaining number of bytes to read write.
- ; So we have to put it in CX
-
- more1: xchg BX,CX ;Get count in CX
- mov DX,offset cpy_buf ;Point to our buffer
- mov BX,in_handle ;Handle for read
- mov AH,ReadFile ;AH = read file
-
- ; Note: CX should contain [bsize] OR the remaining bytes to go...
-
- int DOS ;Call DOS to read file
- jnc data_ok ;Got the data
- add sp,12 ;Remove stack junk
- jmp nope ;Exit, we had probs...
-
- data_ok:
- mov BX,out_handle ;Handle for write
- mov AH,WriteFile ;AH = write to file
- int DOS ;Call DOS to write out buffer
- jnc write_ok ;Go if all is well, else
- add sp,12 ;Remove junk from stack
- jmp nope ;Exit...
-
- write_ok:
- cmp flag,true ;Was this end of arc data?
- je do_next ;Get next header if yes
- pop CX ;Low word buffer size
- pop BX ;Low word file size
- pop DX ;High word file size
- pop AX ;Low word buffer size
- jmp cont ;Continue with this entry
- do_next:
- add SP,8 ;Clear junk off stack
- pop SI ;Get back buffer position
- add SI,33 ;Adjust to next entry
- pop AX ;Get back number of entrys
- dec AL ;Subtract 1 from it
- jz no_more ;We're done with data
- jmp nxt_hdr ;Else go get the next one
- no_more:
-
- ; Before we quit, we have to write out a 1A 00 to show the end of
- ; the archive.
-
- mov AH,WriteFile ;AH = write to file
- mov BX,out_handle ;Handle for write file
- mov CX,2 ;Number of bytes to write
- mov DX,offset end_arc ;Point to the data
- int DOS ;Call DOS to do it
- jnc delete ;We're finished !
- jmp nope ;Exit sort routine
-
- ; Now that the meat of the work is done, we have to delete the old
- ; arc file and rename the new one.
-
- delete: mov BX,in_handle
- mov AH,CloseFile
- int DOS
- mov BX,out_handle
- mov AH,CloseFile
- int DOS
-
- mov DX,offset cmd1 ;Point to original name
- mov AH,DeleteFile ;AH = delete file
- int DOS ;Call DOS to do it
- jnc del_ok
- jmp nope
-
- del_ok: mov AH,RenameFile ;AH = rename file
- mov DI,offset cmd1 ;Original filename
- mov DX,offset tempspec ;Temporary filename .jjn
- int DOS ;Call DOS to do it
- jnc Back_to_main ;Go if no problems
- jmp nope ;Exit program...
- Back_to_main:
- clc ;Sort done. No errors
- ret ;Return to main section
-
- ; Convert double word to ascii decimal. Uses divide instruction
- ; Parameters passed in registers as follows:
- ; DX:AX = binary word to be converted
-
- DecimalOut:
- push DI
- push AX
- mov DI,offset decbuf ; address of output buffer
- mov CX,7 ; buffer length-1
- mov AL,' ' ; pad character
- rep stosb ; clear buffer & point to end
- mov byte ptr [DI], 0 ; init end of string
- dec DI
- pop AX ;Get low word back
- xchg BP,DX ;Save high word
- mov BX,10 ;Use base 10 for decimal
- mov CL,30h ;For conversion to ASCII
- HighWordLoop:
- or BP,BP ;Are we done with high words?
- jz LowWordLoop ;Yes
- xchg AX,BP ;No, get high word
- xor DX,DX ;Clear DX
- div BX
- xchg BP,AX ;Save new high word
- div BX ;Divide low word + remainder
- or DL,CL ;Convert hex value to ASCII
- mov [DI],DL ;Save decimal character
- dec DI ;Back up in the buffer
- jmp HighWordLoop ;Repeat until done
- LowWordLoop:
- xor DX,DX ;Clear DX
- div BX
- or DL,CL ;Convert hex value to ASCII
- mov [DI],DL ;Save decimal character
- dec DI ;Back up in the buffer
- or AX,AX ;Are we done?
- jnz LowWordLoop ;No
-
- pop DI
- ret
- Sort_It endp
-
-
- ;Convert an ASCIIZ string to upper case.
- ; Call with SI pointing to string to be converted
-
- upper proc near
- push SI ; save string address
- up1: lodsb ; next character
- or AL,AL ; found end (null byte) ?
- jz up2 ; yes, jump
- cmp AL,'a' ; test if in range 'a'-'z'
- jb up1 ; skip it if not >= a
- cmp AL,'z'
- ja up1 ; skip it if not <= z
- sub byte ptr [SI-1],'a'-'A' ; change char to upper case
- jmp up1 ; get another char
-
- up2: pop SI ; restore original string
- ret ; address and return
- upper endp
-
-
- ; This routine is called by the sort. It prints a line of information
- ; for every entry in the archive detailing its size, filename, and
- ; new locatio in the archive....
-
- info proc near
- mov SI,offset msg1 ;SI = 'Adjusting'
- call ShowIt ;Put it on screen
- mov BP,SP ;Get stack pointer
- mov SI,[BP+2] ;SI = address of arc entry
- add SI,6 ;Now SI points to filename
- push SI ;Save address for later
- call ShowIt ;Put it on screen
-
- mov CX,14 ;Tab length for info screen
- sub CL,Characters ;Subtract # of chars printed
- mov DL,blank ;AL = space
- mov AH,CharacterOutput ;Function = console out
- info_loop:
- int DOS ;Call DOS to print space
- loop info_loop ;Loop till tab is complete
-
- mov SI,offset msg2 ;SI = 'Location ='
- call ShowIt ;Put it on screen
- mov DX,high_pos ;High word file position
- mov AX,low_pos ;Low word file position
- call DecimalOut ;Convert to ASCII and print
- mov SI,offset decbuf ;Yes, String address to SI
- call ShowIt ; Output it
- mov SI,offset msg3 ;SI = 'Length ='
- call ShowIt ;Put it on screen
- pop SI ;Restore Arc filename address
- mov AX,[SI+13] ;Low word file size
- mov DX,[SI+15] ;High word file size
- clc ;Get ready for addition
- add AX,29 ;Add in length of header
- adc DX,0 ;Add in any carry
- call DecimalOut ;Convert to ASCII and print
- mov SI,offset decbuf ;Yes, String address to SI
- call ShowIt ; Output it
- mov SI,offset crlf ;SI = cr/lf
- call ShowIt ;Put it on screen
- ret ;Return to caller
- info endp
-
- ; This routine prints one of DOS's error messages and returns to
- ; which ever section of the code called it...
-
- err_msg proc near
- push AX ;Save errorlevel
- dec AX ;Adjust for beginning of table
- add AX,AX ; * 2 for DW variables
- mov SI,AX ;Get offset in SI
- mov SI,errmsg[SI] ;Now SI = address of string
- call ShowIt ;Put it on screen
- pop AX ;Restore errorlevel
- ret
- err_msg endp
-
-
- ;************************************************************************
- ; FindNames: find all file names matching the file specification in cmd1.
- ; REGISTERS ON EXIT:
- ; AX = number of files found (may be 0).
- ; ZF = reset if files found, set if no files found.
- ; This procedure written by Jeffrey J Nonken. (Modified by Dan)
- ;************************************************************************
-
- public FindNames
- FindNames proc near
- mov DI,offset save_buf ;Get dest addresm of filename
- mov AL,num_names ;Get # of names already there
- mov CL,13 ;Length of 1 entry
- mul CL ;Names * 13
- add DI,AX ;Now DI points into buffer
-
- mov AH,SearchForFirst ;AH = Search for first
- xor CX,CX ;Attribute = 'normal'
- mov DX,offset cmd1 ;Point to ASCIIZ filename
- int DOS ;Give it to DOS
- jnc get1fname ; Found a file, process it
- jmp no_files ;Finished with search
-
- ; Loop to here if buffer was written to disk.
-
- clean_buf:
- mov num_names,0 ; no more names in the buffer
- mov DI,offset save_buf ;Get dest address of filename
-
- ; Loop to here after each file name, look for the next one.
-
- next:
- mov AH,SearchForNext ;AH = Search for next
- int DOS ;Give it to DOS
- jnc get1fname ; Found a file, process it
- jmp short NoMoreFiles ; If not, quit now.
- get1fname:
-
- ;Now we move the filename.ext up to our own ASCIIZ string
- ;so that open can use the correct path to the file.
-
- mov SI,offset dta_buf+30 ;SI = filename found
- mov CX,6 ; Name is <= 13 bytes
- ; (including trailing null)
- rep movsw ; Move 12 bytes (6 words)
- movsb ; Move the last byte
- inc name_count ; Count up (total count)
- inc num_names ; Count up (buffer count)
- cmp num_names,NamesFound ; See if we have names yet
- jb next ; Just repeat if not
-
- ; If we got here, there were at least 'NamesFound' names.
- ; Start writing them to disk.
-
- cmp on_disk,0 ; See if there's a file open
- jnz already_open ; If so, skip the open step
- mov DX,offset filename_file ; Get the file's name
- mov AH,CreateFile ; Open the file
- xor CX,CX ;No attributes
- int DOS ; Do it
- mov files_handle,AX ; Save the file handle(error)
- jnc already_open ; If no errors, write to file
- call err_msg ;Report error in english
- mov DX,offset TempErr ;Unable to create file
- mov AH,OutputString ;DOS print string function
- int DOS ;Display error
- jmp short NoMoreFiles ;Continue on
-
- ; If the temporary file can't be created, we exit here. This will allow
- ; SPAZ to process at least 'NamesFound' archives before quitting. If this
- ; is a disk full condition, it will be reported by the un-archiver.
-
- already_open:
- mov DX,offset save_buf ; point to buffer
- mov BX,files_handle ; get the file handle
- mov CX,13 * NamesFound ; number of file names to write
- mov AH,WriteFile ; write to the file
- int DOS
- mov on_disk,1 ; say it's on disk
- jmp clean_buf ; loop around and clear buffer
-
- ; No more files found. Clean up and exit.
-
- NoMoreFiles: ; Last file was found
- cmp on_disk,0 ; see if there is a files file
- jz no_files ; if not, just return
- cmp num_names,0 ; see if any left in buffer
- jz no_files
- mov AL,num_names ; Yes, get the number of names
- mov BL,13 ; length of a name
- mul BL ; how many bytes to write
- mov DX,offset save_buf ; point to buffer
- mov BX,files_handle ; get the file handle
- mov CX,AX ; number of bytes to write
- mov AH,WriteFile ; write to the file
- int DOS
-
- ; Hmmmmm. If disk is full, un-archiver will report error. If it's just
- ; a bad read/write, DOS's abort, retry, ignore will display. Don't
- ; think we have to check?
-
- ; All files (if any) have been found and buffered or written to disk. Save
- ; the address of the buffer in case we have files in the buffer. Restore the
- ; DTA.
-
- no_files:
- mov fname_ptr,offset save_buf ;Address of scratch space
- mov names_used,0 ; No names used yet
- ret
- FindNames endp
-
- ;****************************************************************************
- ; wild_card: Each time called this returns the next name in the list, if any.
- ; It 'returns' it by copying it into the end of the command line buffer
- ; after the path so it can be used immediatly. If it has no more names,
- ; it exits the program.
- ; This procedure written by Jeffrey J. Nonken (and mangled by Dan)
- ;****************************************************************************
- public wild_card
- wild_card proc near
- mov AX,names_used ; Get number of names returned
- cmp AX,name_count ; Compare to total # of names
- jb more_names ; If less, we still have some
-
- ; We have no names left to return. See if they were on disk. If so, close up.
-
- cmp on_disk,0 ; see if on disk
- jz w_skip_close ; if not, skip over the close
- mov AH,CloseFile ; close file command
- mov BX,files_handle ; get the file handle
- int DOS
- mov AH,DeleteFile ; Delete file command
- mov DX,offset filename_file ; Name of file to delete
- int DOS ; Delete our scratch file
- w_skip_close:
- mov AL,elevel ;Get last reported errorlevel
- mov AH,ExitWithCode ;Terminate with return code
- int DOS ;Exit program
-
-
- ; We still have names left. Let's see if they're on disk.
-
- more_names:
- cmp on_disk,0 ; Are they stored on disk?
- jz not_on_disk ; If not, get from the buffer.
-
- ; If we got here, the files are stored on disk. Read one name, 13 bytes, right
- ; into the file spec. The name was originally null terminated, so extra junk
- ; on the end won't matter.
-
- mov AH,ReadFile ; Read file command
- mov BX,files_handle ; get the file handle
- mov DX,endpath ;Get end address of path
- mov CX,13 ; Read 1 filename
- int DOS
- jnc w_got1 ; If no carry, we got it
-
- ; If we can't process the temp file, SPAZ has no filenames to work with.
- ; The only safe thing to do, is exit with the errorlevel. This will leave
- ; any archives intact so they can be handled later.
-
- call err_msg ;Report error in english
- mov DX,offset TempErr ;Error processing temp file
- mov AH,OutputString ;DOS print string function
- int DOS ;Display error
- mov AH,ExitWithCode ;Terminate SPAZ
- int DOS ;Tell DOS to do it
-
-
- ; If we got here, there are four or fewer filenames, and they are in the
- ; scratch buffer. fname_ptr points to the current filename. Just copy all
- ; 13 bytes in; as before, the name was already null terminated.
-
- not_on_disk:
- push SI ; Save the index registers
- push DI
- mov SI,fname_ptr ; get the current source ptr
- mov DI,endpath ; Get end address of path
- mov CX,6 ; copy 12 bytes (6 words)
- rep movsw
- movsb ; copy the 13th byte
- mov fname_ptr,SI ; save the new pointer
- pop DI ; restore the index registers
- pop SI
-
- ; One way or another, we copied a filename.
-
- w_got1:
- inc names_used ; Note that we used a name
- clc ; Clear the carry flag
- ret
- wild_card endp
-
-
- ; The following routine scans each command line option and sets various
- ; flags according to options used.
-
- options proc near
- cld ;Ensure forward movements
- xor AX,AX ;Start with argument 1
- Opt0: inc AX ;Bump argument number
- push AX ;Save argument number
- mov BX,cmdtail ;Point BX to command line
- call argv ;Get info on argument
- or AX,AX ;Did we find an argument?
- jnz StillMore
- jmp end_Opts ;Nope, we must be done...
- StillMore:
- push AX ;Save argument length
- mov SI,BX ;Address in SI
- call upper ;Convert to upper case
- lodsb ;Get first character
- cmp AL,'/' ;Is this an option?
- je Opt1 ;Go get it if yes
- cmp AL,'-' ;Option?
- jne arc_name ;Get archive name
- Opt1: pop AX ;Get argument length back
- push AX ;Maintain stack balance
- cmp AX,2 ;Check for valid size
- jne bad_opt ;Report bad option
- lodsb ;Get option ID
- cmp AL,'D' ;Delete flag?
- jne Opt2 ;Next check if not
- mov byte ptr D_Flag,true ;Set flag to delete arc's
- jmp short nxt_opt ;Do next option
- Opt2: cmp AL,'N' ;Sort flag?
- jne Opt3 ;Next check if not
- mov byte ptr N_Flag,false ;Set flag for no sort
- jmp short nxt_opt ;Do next option
- Opt3: cmp AL,'A' ;Default arc program flag?
- jne Opt4 ;Next check if not
- mov byte ptr A_Flag,true ;Set flag to show default set
- jmp short nxt_opt ;Do next option
- Opt4: cmp AL,'V' ;Verbose mode desired?
- jne Opt5 ;Next check if not
- mov byte ptr Q_Flag,false ;**Kludge** inverted quiet
- jmp short nxt_opt ;Do next option
- Opt5: cmp AL,'F' ;Is this a mail run?
- jne Opt6 ;Report bad option if not
- mov byte ptr F_Flag,true ;Set up for mail run
- jmp short nxt_opt ;Do next option
- Opt6: cmp AL,'O' ;Overwrite mode?
- jne Opt7 ;Make 1 more check
- mov byte ptr O_Flag,true ;Set overwrite mode
- jmp short nxt_opt
- Opt7: cmp AL,'R' ;For Opus compatibility
- jne bad_opt ;Report bad option if not
- mov byte ptr O_Flag,true ;Set overwrite mode
- jmp short nxt_opt
- bad_opt:
- call CheckMFlag ;Are we expanding addresses?
- jnc Nxt_Opt ;It's Ok, keep going
- mov AX,23 ;Unknow option used...
- call err_msg ;Report it
- jmp syntax ;Show syntax screen and exit
-
- arc_name:
- pop AX ;Get length back
- push AX ;Maintain stack balance
- cmp byte ptr Got_name,true ;Do we have an archive name?
- jne arc_name1 ;Nope, go get it
- call parse_line ;Yup, pass it the filenames...
- jmp short nxt_opt ;Continue with options
-
- arc_name1:
- mov Opt_Address,BX ;Save address of file name
- mov Opt_Length,AX ;Save length of file name
- mov byte ptr Got_name,true ;Set flag to show we got it!
-
- nxt_opt:
- pop AX ;Remove argument length
- pop AX ;Get arg number to work on
- jmp Opt0 ;Continue...
-
- end_Opts:
- add SP,2 ;Clean off stack junk
- cmp byte ptr Got_name,true ;Did we get a filename?
- jne bad_line ;Report error if not
- cmp F_Flag,true ;Is this a mail run?
- jne RestoreArg ;Go if not
- mov byte ptr D_Flag,true ;Set auto delete
- mov byte ptr N_Flag,true ;Force an archive sort
- mov byte ptr O_Flag,true ;Force overwrite mode
- RestoreArg:
- mov AX,Opt_Length ;Get length of argument
- mov BX,Opt_Address ;Get address of argument
- ret ;And we are outa' here..
-
- ;If the program falls through to here, all arguments were examined and
- ;an archive name was NOT found. Report an error, show the syntax screen
- ;and quit. What else can we do?
-
- bad_line:
- mov AX,24
- call err_msg
- jmp syntax
- options endp
-
-
- CheckMFlag proc near
-
- lodsb ;Get next character
- cmp AL,'M' ;Is this the M flag?
- jne NotTheMFlag ;Exit if no
- call DecimalIn ;Get net number
- mov word ptr OurNet,DX ;Save it
- call DecimalIn ;Get node number
- mov word ptr OurNode,DX ;Save it
- mov M_Flag,true ;Set our flag
- clc ;Show we processed it
- ret ;And exit
- NotTheMFlag:
- stc ;Oops, a boo-boo...
- ret ;Back to caller
-
- CheckMFlag endp
-
-
- ; This routine displays the current settings of the command line
- ; parameters. i.e. will sort, will not delete etc...
-
- show_opt proc near
- push AX
- push BX
-
- cmp byte ptr Q_Flag,true ;Quiet mode?
- jne NotQuietMode
- jmp show_x ;Exit if yes
-
- NotQuietMode:
- cld ;Ensure forward movements
- mov SI,offset will ;Point to will message
- cmp byte ptr A_Flag,true ;Use Arce?
- je show1
- mov SI,offset wont
- show1: call ShowIt
- mov SI,offset info1
- call ShowIt
-
- mov SI,offset will
- cmp byte ptr D_Flag,true ;Delete archives?
- je show2
- mov SI,offset wont
- show2: call ShowIt
- mov SI,offset info2
- call ShowIt
-
- mov SI,offset will
- cmp M_Flag,true ;Expand net address?
- je show3
- mov SI,offset wont
- show3: call ShowIt
- mov SI,offset info5
- call ShowIt
-
- mov SI,offset will
- cmp F_Flag,true ;A mail run?
- je show4
- mov SI,offset wont
- show4: call ShowIt
- mov SI,offset info6
- call ShowIt
-
- mov SI,offset will
- cmp byte ptr O_Flag,true ;Force overwrite mode?
- je show5
- mov SI,offset wont
- show5: call ShowIt
- mov SI,offset info7
- call ShowIt
-
- mov SI,offset will
- cmp byte ptr N_Flag,true ;Sort archive?
- je show6
- mov SI,offset wont
- show6: call ShowIt
- mov SI,offset info3
- call ShowIt
-
- show_x: pop BX
- pop AX
- ret
- show_opt endp
-
-
- ; This procedure converts an ASCII number to it's binary form. The
- ; routine will exit when the first non-ascii-number is reached. The
- ; binary value is returned in DX.
-
- DecimalIn proc near
-
- xor DX,DX ;Initialize variable
- DecimalLoop:
- lodsb ;Get first character
- sub AL,30h ;Subtract ASCII base
- jl DecimalExit ;If too low, we're finished
- cmp AL,9
- jg DecimalExit ;If too high, we're finished
- cbw ;Convert to word value
- push AX ;Save digit
- mov AX,DX
- mov CX,10 ;Working with base 10
- mul CX ; 10 * digit
- mov DX,AX ;Result in DX
- pop AX ;Get number back
- add DX,AX ;Add number in
- jmp short DecimalLoop ;Get next digit
- DecimalExit:
- ret ;Back to main section
-
- DecimalIn endp
-
-
- ; This routine parses filenames from the command line that must be passed
- ; to the unarchive program.
-
- parse_line proc near
- cld ;Go in the right direction!
- mov Parsed,true ;Show names were parsed
- mov CX,word ptr Names_Count ;Get current character count
- push AX ;Save argument length
- add AX,CX ;AX = new length total
- mov SI,BX ;Argument address to source
- mov DI,offset Extract_Names ;DI = buffer address
- add DI,CX ;Adjust to current position
- mov byte ptr [DI],blank ;Add in a space
- inc DI ;Adjust pointer
- inc AX ;Add 1 to total length
- mov word ptr Names_Count,AX ;Save new total length
- pop CX ;Get argument length in CX
- rep movsb ;Move extract name into buffer
- mov byte ptr [DI],0 ;End it with a null
- ret
- parse_line endp
-
-
- DisplayNode proc near
-
- cmp M_Flag,true ;Should we do this?
- jne ExitDisplayNode ;Exit if not
-
- mov SI,endpath ;Point to bundle name
- call GetFromAddress ;Decode the Address
- mov DI,offset BuildNet ;Where to store it
- mov AX,word ptr FromNet ;Get the Senders net
- mov DX,word ptr OurNet ;Get our own net
- add AX,DX ;Figure out the difference
- xor DX,DX ;Get ready for conversion
- call DecimalOut ;Convert to ASCII
- call InsertAddress ;Add Net number to string
- mov AL,'/' ;Address delimiter
- stosb ;Stuff it in
- mov AX,word ptr FromNode ;Get the Senders node
- mov DX,word ptr OurNode ;Get our node address
- add AX,DX ;Figure out the difference
- xor DX,DX ;Get ready for conversion
- call DecimalOut ;Convert to ASCII
- call InsertAddress ;Add node number to string
- mov byte ptr [DI],0 ;Make it ASCIIZ
- ExitDisplayNode:
- ret ;Back to main
-
- DisplayNode endp
-
-
- InsertAddress proc near
-
- mov SI,offset DecBuf ;Point to ASCII buffer
- Insert1:
- lodsb ;Get a byte
- cmp AL,blank ;Is it ASCII space?
- je Insert1 ;Loop if yes
- Insert2:
- stosb ;Not 0, we keep it...
- lodsb ;And get another
- or AL,AL ;Check for end
- jnz Insert2 ;Loop till finished
- ret ;Back to caller
-
- InsertAddress endp
-
-
- GetFromAddress proc near
-
- call GetNet ;Get the net bundle is from
- mov word ptr FromNet,DX ;And save it
- call GetNet ;Get the node number
- mov word ptr FromNode,DX ;And save it
- ret ;That's it!
- GetNet:
- xor DX,DX ;Start with 0
- mov CX,4 ;Counter for Hex number
- Net1: lodsb ;Grab a byte
- sub AL,30h ;Mask off the ASCII
- jl Net3 ;Too low, exit
- cmp AL,9 ;0 to 9?
- jle Net2 ;If yes, no adjustment
- and AL,5fh ;Mask off the casing
- sub AL,7 ;Adjust for A-F
- jl Net3 ;Quit if too low
- cmp AL,15 ;Higher than F?
- jg Net3 ;Quit if too high
- Net2: push CX ;Save character counter
- cbw ;Sign extend our number
- mov CL,4 ;4 bits per hex character
- sal DX,CL ;Shift over previous value
- add DX,AX ;And add in the new
- pop CX ;Restore character counter
- loop Net1 ;Do 4 characters
- Net3: ret ;And then exit
-
- GetFromAddress endp
-
-
- BuildNet equ $ ;Buffer for Net/Node
- FromNet equ BuildNet + 12 ;Sending Net
- FromNode equ FromNet + 2 ;Sending Node
- OurNet equ FromNode + 2 ;Our Net
- OurNode equ OurNet + 2 ;Our Node
- cpy_buf equ OurNode + 2 ;Storage for copy buffer
- hdr_buf equ cpy_buf + bsize ;Buffer to hold headers
- cmd1 equ hdr_buf + entries * arc_len ;Buffer for wildcard filenames
- new equ cmd1 + 80 ;Buffer for Arc path search
- saved equ new + 80 ;Buffer for Arc exec
- decbuf equ saved + 192 ;Buffer for decimal conversions
- dta_buf equ decbuf + 8 ;Disk Transfer Area
- Def_Arc equ dta_buf + 43 ;Default Archive Name
- Fcb1 equ Def_Arc + 13 ;File Control Block 1
- Fcb2 equ Fcb1 + 37 ;File control Block 2
- Cmd_Cnt equ Fcb2 + 37 ;Command Line Char Counter
- ExtractOptions equ Cmd_Cnt + 1 ;Options to pass to Un-Archer
- Pakfile equ ExtractOptions + 9 ;Filenames to pass to Un-Archer
- Extract_Names equ Pakfile + 160 ;Buffer for names to extract
- Names_Count equ Extract_Names + 128 ;Count for names to extract
- tempspec equ Names_Count + 2 ;Scratch for temp filespec .jjn
- save_buf equ tempspec + 80 ; Filename buffer .jjn
- stk equ save_buf + (13 * NamesFound) ;Stack Area .jjn
- bottom equ stk + 200 ;End of code and data
-
- cseg ends
-
- end entry