AUSAM/source/S/dtp.sbak
//////////////////////////////////////////////////////////////////////////
// //
// this is a version of 'tp' modified by ian j. AGSM //
// //
// enhancements or otherwise: //
// //
// 1) new command 's'. this is a selective dump facility. //
// the number following 's' in the key is taken as a number //
// of hours -- if number absent then /etc/last-dump-time //
// contains time last dump -- any file modified within/since //
// that time will be dumped. //
// //
// 2) new commands implemented, new meanings, old //
// unused commands are out. see 'swtab' below //
// //
// 3) tape blocksize increased to tbloksiz bytes, this allows //
// more data to be kept on tape than is possible using //
// a blocksize of 512. bytes. //
// //
// Yet to be done: //
// dumps of 65536 and more blocks //
// virtual blocks //
// links //
// //
//////////////////////////////////////////////////////////////////////////
/ Tunable constants
tapesize = 2400. / default tape length in feet.
tbloksiz = 16384. / blocksize on tape - must be a integer power of 2
/ 16384. is max allowable for 800 BPI drives
/ the silly hardware times-out before write
/ has completed !! 32768 is fine for 1600 BPI
/ but 16384 is positive not negative like 32768.
/ 16384. is max possible value - too much
/ trouble otherwise.
tbloking = tbloksiz\/512. / sectors per tape block.
nrzreclen = [tbloksiz+534.+799.]\/800. / record length in inches (800bpi)
pereclen = [tbloksiz+1067.+1599.]\/1600. / record length in inches (1600bpi)
/ system calls...
smdate = 30.
mknod = 14.
lock = 56.
readlock = 0
writelock = 1
/ system constants
IFMT = 60000
ISDIR = 40000
ISBLK = 20000
EEXIST = 17.
/
iot = 4
sys time
mov r0,dumptime
mov r1,dumptime+2 / note program start time
mov (sp),rnarg
mov (sp)+,narg
mov $cmexit,command
tst (sp)+
cmp narg,$2
bge 1f
mov $2,narg
br 3f
1:
mov (sp)+,r0
mov sp,parg
sub $512.,sp
clr -(sp)
clr -(sp)
mov $1,-(sp) / outfd
mov sp,outbp / tty output buffer
mov sp,outbp1 / for benefit of flusher
1:
movb (r0)+,r1
beq 3f
mov $swtab,r2
2:
cmp r1,(r2)+
beq 2f
tst (r2)+
bne 2b
br useerr
2:
jsr pc,*(r2)+
br 1b
3:
jsr pc,opentap
sys signal; 2; 1
bit $1,r0
bne 0f
sys signal; 2; intrupt / lets remove temp file
0:
cmp tfilename,$tmpdirname
bne 0f
sys getpid / generate unique temp file name
mov $5,r2
1:
mov r0,r1
clr r0
div $10.,r0
add $'0,r1
movb r1,xxxxx-1(r2)
sob r2,1b
0:
sys indir; 0f
.data
0: sys creat
tfilename: tmpdirname; 0600
.text
bes 8f
sys close
mov tfilename,0f+2 / get new name
sys indir; 0f
.data
0: sys open; 0; 2
.text
bes 8f
mov r0,dirfd
sys fstat; statb / remember dev, inum
mov statb,tfdev
mov statb+2,tfino
mov tpsize,r0
jmp *command
8:
jsr r5,mesg
< directory file create error\n\0>; .even
jbr done
opentap:
cmp command,$cmn
beq 2f
sys open; magtape; 0
br 3f
2:
sys open; magtape; 1
3:
bes 1f
mov r0,fio
rts pc
1:
jsr r5,mesg
<Tape open error\n\0>; .even
jbr done
setcom:
cmp command,$cmexit
bne useerr
mov (r5)+,command
rts r5
noflag:
mov (r5)+,r0
beq 1f
tstb (r0)
beq noflag
br useerr
1:
rts r5
useerr:
jsr r5,mesg
<Bad usage\n\0>; .even
jbr done
/
swtab:
'0; dcof / d r i v e 0
'1; dcof / d r i v e 1
'm; dcm / d e n s i t y 800 b.p.i.
'h; dch / d e n s i t y 1600 b.p.i.
'f; dcf / f e e t - size of tape
't; dct / t e m p file name
/
'x; dcx / e x t r a c t named files.
'n; dcn / n e w dump tape to be created
'l; dcl / l i s t contents of dump tape
/
's; dcs / i n c r e m e n t a l l y dump files to dump tape
'c; dcc / c r e a t e as needed directories/special-files
'u; dcu / u p d a t e last dump time in /etc/last-dump-time (new dump only)
/
'v; dcv / v e r b o s e dont be silent, give all info
'q; dcq / q u e s t i o n after each file selected for user approval(y-yes n-no x-exit)
'i; dci / i g n o r e tape read/write errors
'.; dcd / d u m p all files, even those beginning with '.'
0; 0
dcof:
movb r1,magu
rts pc
dcm:
movb r1,magt
mov $nrzreclen,recordln
rts pc
dch:
movb r1,magt
mov $pereclen,recordln
rts pc
dcf:
jsr pc,argnum / see if tape length specified.
bne 0f / --> yes so use it.
mov $tapesize,r1 / assume tapesize ft. tape.
0:
mov r1,tpsize / save length of tape.
rts pc
dct: / get a name from arg list
cmp rnarg,$2 / sufficient args?
ble 0f
mov *parg,tfilename / next arg is temp file name
add $2,parg
dec rnarg
dec narg
0:
rts pc
dci:
incb fli
rts pc
dcd:
incb fld
rts pc
dcn:
jsr r5,setcom; cmn
rts pc
dcl:
jsr r5,setcom; cml
rts pc
dcu:
incb flu / cause start time to be written to /etc/last-dump-time
rts pc
dcv:
incb flv
rts pc
dcq:
incb flq
rts pc
dcx:
jsr r5,setcom; cmx
rts pc
dcc:
inc flc
rts pc
dcs:
incb fls / use selective file dump
jsr pc,argnum / obtain number that optionally follows
bne 4f / if non-zero then use hour interval specified
mov r0,-(sp) / save arg pointer
sys open; ldt; 0
bec 3f
2: jsr r5,mesg; < Cannot open last-dump-time\n\0>; .even
jbr done
3:
mov r0,r1
sys read; seltim; 4 / dump all files modded after this time
bes 2b
cmp $4,r0
bne 2b
mov r1,r0
sys close
mov (sp)+,r0
rts pc
4:
mov r0,-(sp)
mov r1,r0
mpy $-3600.,r0 / get seconds(-ve) not hours.
add dumptime+2,r1 / subtract
adc r0 / time
add dumptime,r0 / specified.
mov r0,seltim
mov r1,seltim+2 / all files modified after this time dumped
mov (sp)+,r0
rts pc
/
argnum:
clr r1
0:
movb (r0),r2 / pick next char from 1st argument.
sub $'0,r2
blt 1f / not a valid digit so branch
cmp $9.,r2
blt 1f / not a valid digit so branch
inc r0
mul $10.,r1
add r2,r1 / build no. of hours.
br 0b
1:
tst r1 / set cc to indicate whether number found
rts pc
//////////////////////////////////////////////////////////////////////////
cmexit:
jsr r5,mesg
<no function specified\n\0>; .even
jbr done
/
cmn:
jsr r5,noflag; flc; 0
/ determine those files to be dumped
jsr pc,getfiles
/ check to see if all files will fit on tape
mov nfiles,r0
mul $dirsiz,r0
add $tbloksiz-1,r1
adc r0
div $tbloksiz,r0
mov r0,-(sp) / big blocks occupied by tape directory
clr r0
mov tapad,r1
add $tbloking-1,r1
adc r0
div $tbloking,r0 / number big blocks wanted for files
add (sp)+,r0 / total number big blocks wanted
mul recordln,r0 / total number inches required
add $11.,r1
adc r0
div $12.,r0 / r0 = feet required
cmp tpsize,r0 / compare tape sizes (in feet)
bhis 0f / --> will fit on the tape
mov r0,-(sp)
jsr r5,mesg
<tape too small to contain all files\n\0>; .even
mov (sp)+,r0
jsr r5,numb; 5
jsr r5,mesg
< foot tape required\n\0>; .even
jbr done
/ will fit so lets get it all on tape
0:
jsr pc,fflush
jsr pc,make
tst flu
jeq usage / no update of last-dump-time reqd.
sys creat; ldt; 0600
bec 2f
1:
jsr r5,mesg
<can't update last-dump-time\n\0>; .even
jbr done
2:
mov r0,r1
sys write; dumptime; 4
bes 1b
cmp r0,$4
bne 1b
br usage
/
.globl _localtime,_ctime
cml:
jsr r5,noflag; flc; flq; 0
jsr pc,rddir / read tape directory onto disk and format it
jsr r5,mesg
<\n\n this dump initiated on \0>; .even
mov dumptime+2,-(sp)
mov dumptime,-(sp)
jsr pc,_ctime
mov r0,r1
jsr pc,pstr
tstb flv
beq 1f
jsr r5,mesg
<\n mode uid tapa size date time name\n\n\0>; .even
1:
jsr r5,gettape; taboc
jbr usage2
//////////////////////////////////////////////////////////////////////////
cmx:
jsr r5,noflag; 0
tstb flc
beq 1f
tstb flq
beq 1f
jbr useerr / don't allow directory create with questions
1:
jsr pc,rddir / read tape directory into core and format it
jsr pc,tread / get first tape block
jsr r5,gettape; xtract
br done
/
usage:
mov nused,r0
jsr r5,numb; 4
jsr r5,mesg
< tape blocks\n\0>; .even
usage2:
mov nfiles,r0 / no of files picked up
jsr r5,numb; 4
jsr r5,mesg
< files on tape\n\0>; .even
/////////////////////////////////////////////////////////////////////////
done:
jsr r5,mesg
<END\n\0>; .even
jsr pc,fflush
mov $15.,r1
0: mov r1,r0
sys close / close ALL files
sob r1,0b
intrupt:
mov tfilename,0f+2 / get dir file name
sys indir; 0f
.data
0: sys unlink; 0 / and remove it
.text
sys exit
/
pstr:
movb (r1)+,r0
beq 1f
jsr pc,putch
br pstr
1:
rts pc
/////////////////////////////////////////////////////////////////////////
mesg:
movb (r5)+,r0
beq 1f
jsr pc,putch
br mesg
1:
inc r5
bic $1,r5
rts r5
/////////////////////////////////////////////////////////////////////////
.data
.globl putc
putch:
jsr r5,putc
outbp: .=.+2
rts pc
/////////////////////////////////////////////////////////////////////////
.globl flush
fflush:
jsr r5,flush
outbp1: .=.+2
rts pc
.text
/////////////////////////////////////////////////////////////////////////
getc:
clr r0
sys read; ch; 1
movb ch,r0
rts pc
/
rddir:
mov dirfd,r0
sys seek; 0; 0 / position at start of disk dir.
jsr pc,tread / read first tape block
mov $tapeb,r0 / 'from'
mov $tapeheader,r1 / 'to'
mov $dirsiz\/2,r2 / number of words to copy
0:
mov (r0)+,(r1)+
sob r2,0b / copy tape header.
mov ndirblks,r2 / a zero means old format
br 2f / write this block to disk.
1:
jsr pc,tread / read next tape block.
bne 2f / a tape mark. Is it expected?
tst ndirblks / old format?
beq 3f / ok
jsr r5,mesg
<Unexpected tape mark in directory\n\0>; .even
jbr done
2: jsr pc,dwrite / write to disk for later use.
sob r2,1b / more to do?
3:
rts pc
/
wrdir:
mov dirfd,r0
sys seek; 0; 0 / position at start of disk dir.
jsr pc,dread / read first disk block
mov dirfd,r0
sys fstat; statb / get info on directory file
jes drderr
movb statb+9.,r0 / get high order size
mov statb+10.,r1 / get low order size
div $tbloksiz,r0 / calculate number of tape blocks
tst r1 / any remainder ??
beq 0f / --> no.
inc r0 / round
0:
mov r0,ndirblks / no of dir blocks !!
mov $tapeheader,r0 / 'from'
mov $tapeb,r1 / 'to'
mov $dirsiz\/2,r2 / number of bytes to copy
0:
mov (r0)+,(r1)+
sob r2,0b / copy tape header.
br 2f
1:
jsr pc,dread / read next directory block.
beq 3f / --> end of directory file.
2: jsr pc,twrite / write to tape
br 1b / continue.
3:
rts pc
/
tread:
mov fio,r0
sys read; tapeb; tbloksiz
bes trderr
tst r0 / set cc for eof test on return
beq 0f
cmp r0,$tbloksiz
bne trderr
tst r0 / set cc for eof test on return
0:
rts pc
trderr:
jsr r5,mesg
<Tape read error\n\0>; .even
tstb fli
jeq done / don't ignore the error, stop
mov $tapeb,r0
2:
clr (r0)+
cmp r0,$tapeb+tbloksiz
blo 2b
rts pc
/////////////////////////////////////////////////////////////////////////
dread:
mov dirfd,r0
sys read; tapeb; tbloksiz
bes drderr
bit $dirsiz-1,r0
bne drderr
tst r0
rts pc
drderr:
jsr r5,mesg
<Directory file read error\n\0>; .even
jbr done
eread:
mov dirfd,r0
sys read; cde; dirsiz
bes drderr
bit $!dirsiz,r0
bne drderr
tst r0
rts pc
/
twrite:
inc nused / keep track of number blocks written to tape
mov fio,r0
sys write; tapeb; tbloksiz
bes twrerr
cmp r0,$tbloksiz
bne twrerr
rts pc
twrerr:
jsr r5,mesg
<Tape write error\n\0>; .even
jbr done
/////////////////////////////////////////////////////////////////////////
dwrite:
mov dirfd,r0
sys write; tapeb; tbloksiz
bes dwrerr
cmp r0,$tbloksiz
bne dwrerr
rts pc
dwrerr:
jsr r5,mesg
<Directory file write error\n\0>; .even
jbr done
ewrite:
clr dirlast
ewrited:
mov ebufpt,r0
cmp r0,$tapeb+tbloksiz
blo 0f
mov dirfd,r0
sys write; tapeb; tbloksiz
bes dwrerr
cmp r0,$tbloksiz
bne dwrerr
mov $tapeb,r0
0:
mov $cde,r1
mov $dirsiz\/2,r2
0:
mov (r1)+,(r0)+
sob r2,0b
mov r0,ebufpt
rts pc
/
verify:
movb (r5)+,0f
inc r5
tstb flq
bne 1f
tstb flv
beq 2f
1:
jsr pc,9f
.data
9:
jsr r5,mesg
0:<x \0>; .even
rts pc
.text
mov r1,-(sp)
mov $cpathname,r1
jsr pc,pstr
mov (sp)+,r1
tstb flq
beq 1f
jsr r5,mesg
< \0>
jsr pc,fflush
jsr pc,getc
cmp r0,$'x
bne 3f
jsr pc,getc
jbr done
3:
cmp r0,$'\n
beq 3f
cmp r0,$'y
bne 4f
jsr pc,getc
cmp r0,$'\n
beq 2f
4:
jsr pc,getc
cmp r0,$'\n
bne 4b
br 3f
1:
jsr r5,mesg
<\n\0>
2:
tst (r5)+
3:
rts r5
/
getfiles:
cmp narg,$2
bne 1f
mov $".\0,cpathname
jsr pc,callout
1:
cmp narg,$2
ble 1f
dec narg
mov *parg,r1
add $2,parg
mov $cpathname,r2
2:
movb (r1)+,(r2)+
bne 2b
jsr pc,callout
mov $-1,dirlast
br 1b
1:
mov ebufpt,r0
sub $tapeb,r0
beq 1f
mov r0,2f+4
mov dirfd,r0
sys 0; 2f
.data
2: sys write; tapeb; 0
.text
bes 0f
cmp r0,2b+4
beq 1f
0:
jmp dwrerr
1:
rts pc
/
expand:
sys open; cpathname; 0
bes fserr
mov r0,-(sp)
1:
mov (sp),r0
sys read; catlb; 16.
bec 4f
tst (sp)+
jbr fserr
4:
tst r0
beq 1f
tst catlb
beq 1b
mov $catlb+2,r1
tstb fld / dump files starting with '.'?
bne 2f
cmpb (r1),$'.
beq 1b
br 3f
2:
cmp (r1),$'.
beq 1b
cmp (r1),$"..
bne 3f
tstb 2(r1)
beq 1b
3:
mov $cpathname,r0
mov $catlb+2,r1
2:
tstb (r0)+
bne 2b
dec r0
mov r0,-(sp)
cmpb -1(r0),$'/
beq 2f
movb $'/,(r0)+
2:
movb (r1)+,(r0)+
bne 2b
jsr pc,callout
clrb *(sp)+
br 1b
1:
mov (sp)+,r0
sys close
rts pc
/
callout:
sys stat; cpathname; statb
bec 0f
fserr:
mov $cpathname,r1
jsr pc,pstr
jsr r5,mesg
< -- Can't access file\n\0>; .even
rts pc
0:
cmp statb,tfdev / check for temp file
bne 0f
cmp statb+2,tfino
bne 0f
rts pc / don't dump it
0:
tstb fls / selective file dump ??
beq 0f / --> no.
cmp seltim,statb+32.
blo 0f / will dump
bhi 1f / dont dump
cmp seltim+2,statb+34.
blo 0f / will dump
1:
mov statb+4,r0
bic $!IFMT,r0
cmp $ISDIR,r0
jne 3f
0:
jsr r5,verify; 'a
rts pc
inc nfiles
clr csize
clr csize+2
movb statb+7,cuid
movb statb+8,cuid+1
mov statb+32.,ctime
mov statb+34.,ctime+2
mov tapad,ctapea / store tape address in tape dir entry
mov statb+4,r0
mov r0,cmode
bic $!IFMT,r0
bne 1f / --> not a plain file
movb statb+9.,csize / only 24 bits for the moment
mov csize,r2
mov statb+10.,r3
mov r3,csize+2
add $511.,r3
adc r2
ashc $-9,r2 / file size (next highest multiple of 512 bytes)
add r3,tapad / increment by size of file - ready for next file
jsr pc,ewrite / add to disk dir file
rts pc
1:
cmp r0,$ISDIR
jeq 2f / directory so see whats in it
mov statb+12.,cmajmin / identify the special file
jsr pc,ewrite / add to disk dir file
rts pc
2:
/ check directory for files to dump
/ add directory entry to disk directory
/ but delete it if no files dumped from the directory
tst dirlast /if last thing put in was directory
bgt 1f
cmp ebufpt,$tapeb+diruplim
blos 1f
mov ebufpt,r0
sub $tapeb,r0
mov r0,2f+4
mov dirfd,r0
sys 0;2f
.data
2: sys write; tapeb; 0
.text
jes dwrerr
cmp r0,2b+4
jne dwrerr
mov $tapeb,ebufpt
1:
jsr pc,ewrited / add to disk dir file
inc dirlast
jsr pc,expand
tst dirlast / any file dumped in this dir?
beq 3f / --> yes.
dec nfiles / no. delete reference to directory
dec dirlast / remember how many
sub $dirsiz,ebufpt
mov flq,-(sp)
clr flq / no questions !!
jsr r5,verify; 'd
0 / won't happen ever
mov (sp)+,flq
3:
rts pc
/
gettape:
clr exta / clr top 16 bits of tape addr
clr ctapea / clr bottom 16 bits of tape addr
mov nfiles,r4
bne 0f
jsr r5,mesg
<Tape empty?\n\0>; .even
jbr done
0:
mov dirfd,r0
sys seek; dirsiz; 0 / skip tape header
sub $2,narg / full extract or list?
bgt 0f
mov $1,narg
mov $1f,parg / dummy arg list
.data
1: 1f
1: 0
.text
0:
mov narg,r0
0:
clr -(sp)
sob r0,0b / table to record argument matches
0:
mov ctapea,r3 / save address last file
jsr pc,eread / get next dir entry
jeq drderr
cmp r3,ctapea / overflow into next 16bits ??
blos 1f / if not ignore
inc exta / full 32bit address
1:
mov parg,-(sp)
mov narg,-(sp)
1: / search for it amongst args
mov *2(sp),r3
cmp rnarg,$2 / global?
beq 3f
mov $cpathname,r2
2: tstb (r3) / end of arg?
beq 2f / a match!
cmpb (r2)+,(r3)+
beq 2b
br 4f / no match
2:
tstb (r2) / end of entry name?
beq 3f
cmpb (r2),$'/ / or path segment?
bne 4f
3:
mov r5,-(sp)
jsr pc,*(r5) / call passed routine to do work
mov (sp)+,r5
mov 2(sp),r0
sub parg,r0
add sp,r0
inc 4(r0) / record a match
br 2f
4:
add $2,2(sp)
dec (sp)
bne 1b
2:
cmp (sp)+,(sp)+ / pop off junk
sob r4,0b
/ search complete. now check for fails
mov narg,r2
mov parg,r3
0:
mov (r3)+,r1
mov (sp)+,r0 / count of references
bne 1f / it was matched
jsr pc,pstr
jsr r5,mesg
<: not found\n\0>; .even
br 2f
1:
add r0,r4
2:
sob r2,0b
cmp command,$cmx
bne 0f
mov r4,r0
jsr r5,numb; 6
jsr r5,mesg
< files extracted\n\0>; .even
0:
tst (r5)+ / chuck away arg
rts r5
/
numb:
mov r1,-(sp)
mov r0,-(sp)
mov r0,r1
clr r0 / 32bit number in r0,r1
br 1f
numbx:
mov r1,-(sp)
mov r0,-(sp)
mov 6(sp),r0
mov 8(sp),r1
1:
mov $catlb,r2
1:
mov $" ,(r2)+
cmp r2,$catlb+12.
blo 1b
cmp (r5),$2
bne 1f
mov $"00,-2(r2)
1:
jsr pc,numb2
clrb (r2)
sub (r5)+,r2
mov r2,r1
jsr pc,pstr
mov (sp)+,r0
mov (sp)+,r1
rts r5
numb1:
clr r0
div $10.,r0
mov r1,-(sp)
mov r0,r1
beq 1f
jsr pc,numb1
1:
mov (sp)+,r0
add $'0,r0
movb r0,(r2)+
rts pc
numb2:
div $10000.,r0
beq numb1 / --> if zero quotient
mov r1,-(sp)
mov r0,r1
jsr pc,numb1
mov (sp)+,r1
clr r0 / remainder is always 4 digits !!
div $1000.,r0
add $'0,r0
movb r0,(r2)+
clr r0
div $100.,r0
add $'0,r0
movb r0,(r2)+
clr r0
div $10.,r0
add $'0,r0
movb r0,(r2)+
add $'0,r1
movb r1,(r2)+ / greg rose responsible for this code
rts pc / ian j responsible for this comment
/
make:
jsr pc,wrdir
make1:
mov dirfd,r0
sys seek; dirsiz; 0 / start at first dir entry.
1:
jsr pc,eread / read next entry.
beq 1f / --> end of directory
bit $IFMT,cmode
bne 1b / --> not a plain file.
mov csize,r2
mov csize+2,r3
add $511.,r3
adc r2
ashc $-9,r2 / file size (next highest multiple of 512 bytes)
sys open; cpathname; 0 / open it for reading.
bes phserro
mov r0,r2 / save file descriptor for reads
.if lock
FLOCKED = 02000
bit $FLOCKED,cmode / is file one of those special locking types?
beq 6f
sys lock; readlock
.endif
6:
mov r2,r0
jsr pc,0f
.data
0:
sys read; 7: tapeb ; 8: tbloksiz
rts pc
.text
bes phserrr
add r0,7b / point next available location in tape buffer
mov r0,r5 / save count of bytes read
cmp $tapeb+tbloksiz,7b / file finished ??
bhi 5f / --> yes.
mov 8b,r0 / bytes to be read last read.
ash $-9,r0 / get as block count
sub r0,r3 / adjust file size counter
bmi phserrb / file has got bigger
beq 3f / file has not changed
mov $tapeb,7b
mov $tbloksiz,8b
jsr pc,twrite
br 6b
5:
add $511.,r0
ash $-9,r0 / blocks just read
sub r0,r3 / adjust file size
bmi phserrb / file is now bigger?
bgt phserrs / file is now smaller?
cmpb r5,csize+2 / check that file same length now
bne phserrs
sub $tapeb,7b / make relative
add $511.,7b
bic $511.,7b / round up next read start address.
add $tapeb,7b / make absolute.
mov $tapeb+tbloksiz,8b
sub 7b,8b / max length next record
cmp 7b,$tapeb+tbloksiz / any room left ??
bne 4f / --> yes, so continue
3:
jsr pc,twrite
mov $tapeb,7b / re-init
mov $tbloksiz,8b / re-init
4:
mov r2,r0
sys close
2:
br 1b / next file
1:
cmp 7b,$tapeb
beq 0f / only write last block if have to
jsr pc,twrite
mov $tapeb,7b / re-init
mov $tbloksiz,8b / re-init
0:
rts pc
/ //
// Recover from phase errors.
//
// O - Open error.
// R - Read error.
// B - File is now bigger.
// S - File is now smaller.
//
phserro:
movb $'O,phsedes
br phserr
phserrr:
movb $'R,phsedes
br phserr
phserrb:
movb $'B,phsedes
mov 7b,r1
mov r5,r0
bic $!511.,r0
beq 3f
add $-512.,r0
sub r0,r1 / r1 rounded up to next block
3:
mov r3,r0
ash $9.,r0
add r0,r1
br 5f
phserrs:
movb $'S,phsedes
mov r5,r0 / recover length really read
mov 7b,r1 / next address
bic $!511.,r0
beq 3f / already at a block address
0:
clrb (r1)+
inc r0
bit $512.,r0 / end of this block?
beq 0b
cmp r1,$tapeb+tbloksiz
blo 3f
jsr pc,twrite
mov $tapeb,r1
br 3f
phserr:
mov 7b,r1
3:
tst r3 / all done ??
ble 5f / --> yes !!
mov $256.,r0 / clear next block
0: clr (r1)+
sob r0,0b
cmp r1,$tapeb+tbloksiz
blo 1f
jsr pc,twrite
mov $tapeb,r1
1: dec r3
br 3b / go for next block
5:
mov r1,7b
neg r1
add $tapeb+tbloksiz,r1
mov r1,8b
/ the phase error file has been sortof dumped
/ now recover...
mov $cpathname,r1
jsr pc,pstr
mov $3f,r1
jsr pc,pstr
.data
3:
< -- Phase error >
phsedes: < \n\0>; .even
.text
cmp phsedes,$'O
beq 2b
mov r2,r0
sys close
br 2b
/
/ called from 'gettape' to list a directory entry.
taboc:
tstb flv
jeq 4f
mov cmode,r0
mov r0,-(sp)
movb $'-,r5
mov $tabpf,mss
bic $!IFMT,r0 / look at file type bits
beq 0f / --> plain file
movb $'d,r5
mov $tabdf,mss
cmp $ISDIR,r0
beq 0f / --> directory
movb $'c,r5
mov $tabsf,mss
cmp $ISBLK,r0
beq 0f / --> character special
movb $'b,r5 / block special
0: mov r5,r0
jsr pc,putch
mov (sp),r0
ash $-6,r0
bit $40,r0
jsr pc,pmod / print access bits for owner
mov (sp),r0
ash $-3,r0
bit $200,r0
jsr pc,pmod / print access bits for group
mov (sp)+,r0
bit $1000,r0
jsr pc,pmod / print access bits for others
mov cuid,r0
jsr r5,numb; 6 / user id.
mov ctapea,-(sp) / tape address
mov exta,-(sp) / tape address
jsr r5,numbx; 7
cmp (sp)+,(sp)+
jmp *mss / jump on file type
tabpf: mov csize+2,-(sp) / file size
mov csize,-(sp) / file size
jsr r5,numbx; 10.
cmp (sp)+,(sp)+
br 0f
tabdf: jsr r5,mesg
< \0>; .even
br 0f
tabsf: movb cmajmin+1,r0 / major dev no
bic $177400,r0 / lo byte only
jsr r5,numb; 6
movb $',,r0
jsr pc,putch
movb cmajmin,r0 / minor dev no
bic $177400,r0 / lo byte only
jsr r5,numb; 3
0: mov ctime+2,-(sp)
mov ctime,-(sp)
jsr pc,_localtime
tst (sp)+
mov r0,(sp)
mov 6(r0),r0 / day of the month(1-31)
jsr r5,numb; 3
mov $'/,r0
jsr pc,putch
mov (sp),r0
mov 8.(r0),r0 / month(0-11)
inc r0
jsr r5,numb; 2
mov $'/,r0
jsr pc,putch
mov (sp),r0
mov 10.(r0),r0 / year - 1900
jsr r5,numb; 2
mov (sp),r0
mov 4(r0),r0 / hours(0-23)
jsr r5,numb; 3
mov $':,r0
jsr pc,putch
mov (sp)+,r0
mov 2(r0),r0 / minutes(0-59)
jsr r5,numb; 2
mov $' ,r0
jsr pc,putch
4:
mov $cpathname,r1
jsr pc,pstr
jsr r5,mesg
<\n\0>
rts pc
pmod:
beq 1f
mov $'s,-(sp)
br 2f
1:
bit $1,r0
beq 1f
mov $'x,-(sp)
br 2f
1:
mov $'-,-(sp)
2:
bit $2,r0
beq 1f
mov $'w,-(sp)
br 2f
1:
mov $'-,-(sp)
2:
bit $4,r0
beq 1f
mov $'r,r0
br 2f
1:
mov $'-,r0
2:
jsr pc,putch
mov (sp)+,r0
jsr pc,putch
mov (sp)+,r0
jsr pc,putch
rts pc
/
/ if the file exists delete it iff not a directory.
/ this is necessary otherwise a filesys mess will result
xunlnk:
sys stat; cpathname; statb / get info on the file.
bes 0f / --> file don't exist
bic $!IFMT,statb+4 / isolate file type bits
cmp $ISDIR,statb+4 / directory ??
beq 0f
sys unlink; cpathname / remove it
0:
rts pc
/////////////////////////////////////////////////////////////////////////
/ called from 'gettape' to process a directory entry
xtract:
tstb flc / create directory mode ??
beq 0f / --> no.
mov cmode,r1
mov r1,9f
bic $!IFMT,r1
beq 0f / --> plain file
clr 8f / assume directory.
cmp r1,$ISDIR
beq 4f / --> directory.
mov cmajmin,8f / special file.
4:
jsr pc,xunlnk
jsr r5,verify; 'c
rts pc
bic $!60777,9f
sys 0; 7f
.data
7:
sys mknod; cpathname; 9: 0; 8: 0 / create directory or special file
.text
bec 3f
cmp r0,$EEXIST / file already exists?
jne crterr
cmp r1,$ISDIR
jne crterr
/ if directory already exists then ok
/ dont clutter up terminal with crap about create errors
sys stat; cpathname; statb
bic $!IFMT,statb+4
cmp $ISDIR,statb+4
jne crterr
jbr 5f
3:
cmp r1,$ISDIR
jne 5f
mov $cpathname,r0
mov $cpathname+1,r5
mov $namewk,r1
3:
movb (r0),(r1)+
beq 3f
cmpb (r0)+,$'/
bne 3b
mov r0,r5
br 3b
3:
movb $'/,-1(r1)
movb $'.,(r1)+
clrb (r1)
sys link; cpathname; namewk
movb $'.,(r1)+
clrb (r1)
movb -(r5),r1
clrb (r5) /name of parent directory
sys link; cpathname; namewk
movb r1,(r5)
br 5f
0:
bit $IFMT,cmode
bne 1f / --> not a plain file(ignore since flc=0)
jsr r5,verify; 'x
rts pc
mov r4,-(sp)
mov exta,r4 / position of file
mov ctapea,r5 / position of file
bic $tbloking-1,r5 / block address
sub tapad,r5 / seek distance
sbc r4 / seek distance
sub tapad+2,r4 / seek distance
ashc $0,r4 / test seek distance (32-bits)
beq 0f / tape position correct
bgt 4f / move tape forward
iot / this cannot happen.
/ directory is searched in order
/ It must be mangled to get here
4:
div $tbloking,r4 / convert to tape blocks
mov r4,r5 / the number of tape blocks.
4:
jsr pc,tread / read a record
add $tbloking,tapad / update tape address
adc tapad+2 / update tape address
sob r5,4b
0:
mov (sp)+,r4
jsr pc,xunlnk
mov cmode,0f
sys 0; 9f
.data
9:
sys creat; cpathname; 0:..
.text
bes crterr1 / unable to create the file ??
mov r0,r2 / save file descriptor
mov ctapea,r5 / tape address of the file
.if lock
bit $FLOCKED,cmode
beq 2f
sys lock; writelock
.endif
2:
bic $![tbloking-1],r5 / get block displacement in tape buffer
ash $9,r5 / get as byte displacement
mov r5,9f
add $tapeb,9f / start writing from here.
add $-tbloksiz,r5
neg r5 / bytes left in buffer
mov r5,8f
sub r5,csize+2
sbc csize / is this all the file ??
bge 0f / --> no.
add csize+2,r5
mov r5,8f
beq 2f / --> if null file/multiple of ....
clr r5
0:
mov r2,r0
sys 0; 7f
.data
7:
sys write; 9: 0; 8: 0
.text
bes crterr1 / write error
cmp r0,8b
bne crterr1 / write error (out of space probably)
tst r5
ble 2f / all done
jsr pc,tread
add $tbloking,tapad / update tape address
adc tapad+2 / update tape address
mov tapad,r5
br 2b / go again
2:
mov r2,r0
sys close
5:
mov cuid,0f
sys 0; 9f
.data
9:
sys chown; cpathname; 0:..
.text
mov ctime,r0
mov r1,-(sp)
mov ctime+2,r1
sys 0; 9f
.data
9:
sys smdate; cpathname
.text
mov (sp)+,r1
1:
rts pc
crterr1:
clr r0
mov r1,-(sp)
clr r1
sys smdate; cpathname
mov (sp)+,r1
mov r2,r0
sys close
crterr:
mov $cpathname,r1
jsr pc,pstr
jsr r5,mesg
< -- create error\n\0>; .even
rts pc
/
.data
tapad: 0;0 / first address in second file.
/ 32-bits for xtract, 16-bits otherwise
/ second 16 are the most significant.
tpsize: tapesize / number of feet on tape.
recordln: pereclen / size of a single record in inches.
ebufpt: tapeb + dirsiz
dirlast: -1 / count of level of empty directories
ldt:
</etc/last-dump-time\0>
dotname:
<.\0>
tmpdirname:
</tmp/temp.dtp.>
xxxxx: <xxxxx\0>
magtape:
</dev/r>
magt:
<mt>
magu:
<0\0>
.even
.bss
tapeb: . = . +tbloksiz
tapebend = .
dirfd: . = .+2
ch: .=.+1
fli: .=.+1
flu: .=.+1
fls: .=.+1
flc: .=.+1
flv: .=.+1
flq: .=.+1
fld: .=.+1
.even
seltim: .=.+4 / all files modified after this time dumped
tfdev: .=.+2 / dev of temp file
tfino: .=.+2 / inode number of temp file
command:.=.+2
size: .=.+2
nused: .=.+2 / no. of blocks used on tape
nfree: .=.+2
catlb: .=.+20.
narg: .=.+2
rnarg: .=.+2
parg: .=.+2
fio: .=.+2
exta: .=.+2 / used by gettape, xtract, taboc to simulate 32-bit
/ tape addresses - used as an extension of ctapea
mss: .=.+2
statb: .=.+40.
/ incore directory structure
cde:
cpathname: .=.+114. / file pathname (null terminated)
cmode: .=.+2. / file access bits
cuid: .=.+2. / the owner
csize: .=.+4. / file size (bytes)
cmajmin = csize+2 / for special files is maj/min number
ctime: .=.+4. / last modified time (secs since 1970)
ctapea: .=.+2. / multiple by 512 to get byte address on tape of file
/ tape directory structure
tpathname = 0 / file pathname (null terminated)
pathnaml = 114. / pathname max length. must be even length.
tmode = 114. / file access bits
tuid =116. / the owner
tsize = 118. / file size (bytes)
ttime = 122. / last modified time (secs since 1970)
ttapea = 126. / multiple by 512 to get byte address on tape of file
dirsiz = 128. / must be a power of 2 and a factor of 512.
dirresvd = 15. * dirsiz
diruplim = tbloksiz - dirresvd
/ tape header entry -- ( DUMMY directory entry )
tapeheader:
nfiles: .=.+2 / files dumped this tape
dumptime: .=.+4 / dump commenced at this time
ndirblks: .=.+2 / number of directory blocks
. = tapeheader + dirsiz
/ Name scratch area
namewk: .=.+pathnaml