home *** CD-ROM | disk | FTP | other *** search
- ; Tee, split stdinput to stdoutput and multiple file streams.
-
- INCLUDE "/include/init.i"
-
- ; Local Equs
-
- BufSize EQU 512
- Handles EQU BufSize
-
- ; Variable storage
-
- STRUCT ArgArray,(2+1)*4 ; +1 'cause I'm parnoid
- SIZE
-
- ; Regs
-
- AppendBool EQUR D4
- StdInput EQUR D5
- AllocStruct EQUR D6
- ActualLength EQUR D7
-
- FileNamePtrPtr EQUR A2
- HandlePtr EQUR A3
- ErrorStrPtr EQUR A4
-
- ; Start
-
- STACK 4000
- INIT
-
- ; Let ARP interpret the commandline
-
- MOVE.L ComLineBase(GP),A0
- MOVE.L ComLineSize(GP),D0
- LEA HelpMsg(PC),A1
- LEA ArgArray(GP),A2
- LEA Template(PC),A3
- MOVE.L A1,(A2)
- CALL GADS
- TST.L D0
- BEQ.S UnusableArgs
- BPL.S ArgsMightBeOK
- UnusableArgs:
- MOVE.L (A2),ErrorStrPtr
- BRA ErrorExit
- ArgsMightBeOK:
-
- ; Fetch the -a switch and check if at least one file present.
-
- MOVE.L 4(A2),AppendBool
- BEQ.S ArgsOK
- LEA HelpMsg(PC),ErrorStrPtr
- MOVEQ #1,D1
- CMP.L D0,D1
- BEQ ErrorExit
- ArgsOK:
-
- ; Alloc tracked mem for the read write buf and the handles.
-
- LEA OutOfMem(PC),ErrorStrPtr
- ADDQ.L #1+1,D0 ; Make space for StdOut + null termination
- LSL.L #2,D0 ; in the file handles longword array.
- ADD.L #BufSize,D0 ; Buffer and Handles use same mem allocation
- MOVEQ #0,D1
- CALL ArpAllocMem
- MOVE.L D0,AllocStruct ; Data reg, so Z gets set
- BEQ ErrorExit
-
- ; Initialize the handle and filename longword array pointers
-
- MOVE.L ArgArray(GP),FileNamePtrPtr
- MOVE.L AllocStruct,A0
- LEA Handles(A0),HandlePtr
-
- ; Open the standard input and output
-
- CALL Input
- MOVE.L D0,StdInput
- CALL Output
- MOVE.L D0,(HandlePtr)+
-
-
- ;----- The open the files, and seek to end loop
-
- LEA OpenError(PC),ErrorStrPtr
- OpenNextFile:
- TST.L (FileNamePtrPtr)
- BEQ.S AllFilesOpened
-
- ; If Appending, try to open (tracked) the file as an old file
-
- TST.L AppendBool
- BEQ.S NoAppendingRequested
- MOVE.L (FileNamePtrPtr),D1
- MOVE.L #MODE_OLDFILE,D2
- CALL ArpOpen
- MOVE.L D0,(HandlePtr)
- BEQ.S TryToOpenNewFile
-
- ; Seek to the end
-
- MOVE.L D0,D1
- MOVEQ #0,D2
- MOVE.L #OFFSET_END,D3
- CALL Seek
- ADDQ.L #1,D0
- BEQ ErrorExit
- BRA.S IncrementAndLoop
- NoAppendingRequested:
-
- ; Open files (tracked) as new
-
- TryToOpenNewFile:
- MOVE.L (FileNamePtrPtr),D1
- MOVE.L #MODE_NEWFILE,D2
- CALL ArpOpen
- MOVE.L D0,(HandlePtr)
- BEQ ErrorExit
-
- ; Update pointers and loop back
-
- IncrementAndLoop:
- ADDQ.L #4,FileNamePtrPtr
- ADDQ.L #4,HandlePtr
- BRA OpenNextFile
- AllFilesOpened:
- CLR.L (HandlePtr) ; Null termination
-
-
- ;----- The single input multi output copy loop, check for ^C & initize
-
- DoNextRdWrChunk:
- SUB.L A1,A1
- CALL CheckAbort
- MOVE.L A1,ErrorStrPtr
- TST.L D0
- BNE.S ErrorExit
-
- LEA WriteError(PC),ErrorStrPtr
- MOVE.L AllocStruct,A0
- LEA Handles(A0),HandlePtr ; Reset to start of array
-
- ; Read from the standard input until EOF or error
-
- MOVE.L StdInput,D1
- MOVE.L AllocStruct,D2
- MOVE.L #BufSize,D3
- CALL Read
- MOVE.L D0,ActualLength
- BEQ.S Exit
- BMI.S ErrorExit
-
- ; Do the multiwrite, and loop back
-
- DoNextWrite:
- MOVE.L (HandlePtr)+,D1
- BEQ DoNextRdWrChunk
- MOVE.L AllocStruct,D2
- MOVE.L ActualLength,D3
- CALL Write
- CMP.L D0,D3
- BNE.S ErrorExit
- BRA DoNextWrite
-
-
- ; Done, cleanup
-
- Exit:
- CLR.W ReturnCode(GP)
- SUB.L ErrorStrPtr,ErrorStrPtr
- ErrorExit:
-
- ; Display error string, if any, and exit
-
- MOVE.L ErrorStrPtr,D0
- BEQ.S NoErrorMsg
- MOVE.L D0,A1
- CALL Puts
- NoErrorMsg:
- RTS
-
- ; The string section
-
- Template:
- DC.B 'Files/...,-a=APPEND/s',0
- HelpMsg:
- DC.B 'Tee - pipe fitting.',10
- DC.B 'Usage: Tee [-a] <File> [...]',0
- OutOfMem:
- DC.B 'Out of memory!',0
- OpenError:
- DC.B 'Tee-file could not be opened',10
- WriteError:
- DC.B 'Error while writing to tee-file',0
- CNOP 0,2
-
- END
-