.title tail .psect buffer,wrt,noexe ifab: $fab fna=nam,xab=ixab,fac= irab: $rab fab=ifab,ubf=buffer0,usz=512,rac=seq ixab: $xabfhc buffer0: .blkb 512 buffer1: .blkb 512 buffer2: .blkb 512 buffer3: .blkb 512 namd: .word 40 ; file name desc. .byte 14,1 .long nam nam: .blkb 40 namlen: .long 0 prompt: .ascid /_File: / ttname: .ascid /sys$output/ sorry: .ascic /%Sorry...this file format is too complicated for me./ outlen: .word 0 .byte 14,1 outptr: .long 0 ;***************************************************** ; ; get a file name and type out the last 1k bytes ; ;****************************************************** .psect ucode,exe .entry tail,^m<> pushal namlen pushal prompt pushal namd calls #3,g^lib$get_foreign bsbw error movb namlen,ifab+fab$b_fns ;insert file name length $open fab=ifab ;open it bsbw error $connect rab=irab ;connect rab bsbw error ;---------------------------------------------------------------- ; first read in the end of the file (up to three blocks worth) ;---------------------------------------------------------------- ; ; r6 - block number ; r7 - size of just read block ; r8 - buffer pointer ; r9 - total bytes read ; clrq r8 moval buffer0,r8 ; start with buffer0 subl3 #3,ixab+xab$l_ebk,r6 ; back into the file 3 blocks bgeq 1$ movl #1,r6 ; start no lower than block 1 1$: movl r6,irab+rab$l_bkt ; block to read movl r8,irab+rab$l_ubf $read rab=irab ;read it bsbw error movzwl irab+rab$w_rsz,r7 ; get length addl2 r7,r9 ; and add to total addl2 #512,r8 ; point to next buffer acbl ixab+xab$l_ebk,#1,r6,1$ moval buffer0(r9),r10 ; point to last byte ; in buffer ;---------------------------------------------------------------- ; check to see what type of file we have and how it is formatted. ; if we understand it then print it else tell the user we are ; inadequate ; for now only VARiable length records, and VFC 2 byte header ; formats are implemented. ; this covers most 'normal' text files and log files ;---------------------------------------------------------------- check: movl #1,r6 ; flag for VFC (1=no) cmpb ifab+fab$b_rfm,#fab$c_var ; variable length records beql var cmpb ifab+fab$b_rfm,#fab$c_vfc ; variable fixed control beql 1$ brw inadequate 1$: bbs #fab$v_prn,ifab+fab$b_rat,2$ ; printer control brw inadequate 2$: cmpb ifab+fab$b_fsz,#2 ; fixed size = 2 beql var brw inadequate ;------------------------------------------------------------ ; print each record, being careful not to let wonderful RMS ; formatting throw us a curve ball ;------------------------------------------------------------ ; ; r9 - number of bytes in buffer1, buffer2, buffer3 ; r11 - number of bytes yet to process ; r10 - pointer to last byte to process ; r4 - points to beginning of record ; r5 - points to printable part of record ; r7 - length of printable part ; r6 - VFC flag ; ; RMS leaves gunk between records so must keep looking for null ; every time ; ; the check to see if we are finished is done two ways, one by ; checking that the number of bytes left to process is negative or zero, ; the other is to check that the pointer to be used to print ; is not beyond the end of the buffer(s). this is necessary ; because there could be junk at the end if the file. ; var: movl r9,r11 moval buffer0,r4 ; start at the beginning tstb (r4) bneq loop ; if starting on a null skpc #0,r11,(r4) ; skip them movl r1,r4 ; update pointer movl r0,r11 ; remaining byte count loop: locc #0,r11,(r4) ; find next null beql eof ; no more to find tstb 1(r1) ; len could be zero!! bneq 1$ clrw outlen ; if so handle properly clrl r7 brb novfc 1$: subl3 #1,r1,r4 ; back-up pointer, and move it to r4 movw (r4),outlen ; set up length of record movzwl (r4),r7 addl3 r4,#2,r5 ; bump pointer to text blbs r6,novfc addl2 #2,r5 ; skip printer control (if any) novfc: movl r5,outptr ; set-up text pointer cmpl r5,r10 bgeq eof ; pointer is beyond buffer(s) pushal outlen calls #1,g^lib$put_output ; print it addl2 r7,r4 ; bump pointer over this record addl2 #2,r4 subl3 r4,r10,r11 ; calc. remaining # of bytes cmpl r4,r10 ; done yet ? bgtr eof tstb (r4) bneq loop incl r4 ; never start on a null it is brw loop ; just junk eof: $close fab=ifab ; close $exit_s r0 inadequate: ; you lose moval sorry+2,outptr movw sorry,outlen pushal outlen calls #1,g^lib$put_output brb eof error: blbs r0,1$ $exit_s r0 1$: rsb .end tail