1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-26 17:03:20 +00:00

SCRAM - encrypt/decrypt file.

This commit is contained in:
Lars Brinkhoff
2018-02-28 19:45:58 +01:00
parent 6ec542590b
commit 1998766f04
5 changed files with 1850 additions and 0 deletions

View File

@@ -246,6 +246,7 @@ A list of [known ITS machines](doc/machines.md).
- RMTDEV, MLDEV for non-ITS hosts.
- SALV, old file system tool for KA and KL.
- SCANDL, TTY OUTPUT SPY.
- SCRAM, encypt/decrypt file.
- SEND, REPLY, replacements for DDT :SEND.
- SENDS, Chaosnet SEND server.
- SENSOR, sends censor.

View File

@@ -1374,6 +1374,10 @@ expect ":KILL"
respond "*" ":midas sys2;ts usq_sysen3;usq\r"
expect ":KILL"
# SCRAM
respond "*" ":midas sys2;ts scram_rwk;scram\r"
expect ":KILL"
# HOST
respond "*" ":midas sys3;ts host_sysnet;host\r"
expect ":KILL"

1236
src/rwk/empty.361 Normal file

File diff suppressed because it is too large Load Diff

416
src/rwk/files.12 Normal file
View File

@@ -0,0 +1,416 @@
.BEGIN RFN ;-*-MIDAS-*-
SUBTTL Routines for parsing and printing filenames
;Basic conventions:
;We assume that there are accumulators A, B, C, D and E, not necessarily
;consecutive, and that the stack is in P.
;No routine clobbers ACs other than the
;ones it is documented to clobber, and none touches even temporarily
;any AC other than A, B, C, D, E and P.
;All code generated is pure.
;The main routines, RFN, PFN, PFNBRF and PFNMCH, never skip.
;This file contains two routines, RFN to read filenames and PFN to print.
;Both expect a b.p. for ILDB'ing or IDPB'ing the text, in D.
;Both expect a pointer to a filename block in A.
;A filename block consists of four words, which hold th
;left-justified sixbit DEVICE, FN1, FN2 and SNAME in that order.
;The RFN routine assumes that the user has defined the label RSIXTP
;(RSIX-Terminator-P) which should expect a character in B
;and skip if it should terminate a filename, or start a switch.
;It will not be called with control characters.
;Thus, you might want it to skip when given ",", "_" or "/".
;PFN similarly assumes that there is a routine PSIXTP will will
;skip for a character in B that needs a ^Q printed in front of it.
;Normally, RSIXTP and PSIXTP can be the same routine.
;If you want switches to be processed in filenames,
;set $$SWITCH to 1 and define the label SWITCH as a routine to read a switch.
;It will be called with the first character of the switch in B.
;It can read more characters off D, or by calling RFN"RUC
;If it skips, RFN assumes that the character in B should be reprocessed.
;A slash is followed by a single switch, while parentheses enclose
;any number of switches. However, neither slash nor "(" will be
;recognized unless RSIXTP skips for it. This gives the caller
;run-time control of whether switches are to be processed.
;If $$MNAME is set, the user must define MNAME to point to
;a word holding this machine's name in SIXBIT. RFN"RMNAME initializes it.
;If $$PFNBRF is set, the user must define MSNAME to point to
;a word holding the "default" SNAME (the one not to be mentioned).
;These symbols should be defined by the user to select parts of this file:
IFNDEF $$RFN,$$RFN==0 ;Include RFN, the routine for reading filenames.
IFNDEF $$SWITCH,$$SWITCH==0 ;Include routines for processing "/" and "(-)" switches.
IFNDEF $$PFN,$$PFN==0 ;Include PFN, the routine for printing filenames.
IFNDEF $$PFNBRF,$$PFNBRF==0 ;Include routine to print filenames briefly.
IFNDEF $$RUC,$$RUC==0 ;1 => don't define RUC; use a user-supplied definition.
IFNDEF $$MNAME,$$MNAME==0 ;1 => assume MNAME is defined and holds this machine's name.
IFN $$SWITCH,$$RFN==1
IFN $$PFNBRF,$$PFNBRF==1
ifndef $$sixp,$$sixp==0 ;default to no special terminators
ifndef $$altp,$$altp==0 ;nonzero => altmode prints defaults
ifn $$altp,$$pfn==1 ;altmode requires that we be able to print
ifndef p,p==sp ;alternate name for P
.AUXIL ;Don't mention all our internal symbols in crefs.
;PRINT VERSION NUMBER
.TYO6 .IFNM1
.TYO 40
.TYO6 .IFNM2
PRINTX/ INCLUDED IN THIS ASSEMBLY.
/
DEFINE SYSCAL NAME,ARGS
.CALL [SETZ ? SIXBIT/NAME/ ? ARGS ((SETZ))]
TERMIN
IFN $$RFN,[ ;Routines for reading filenames.
;Read a file spec off the b.p. in D into the file block that A points at.
;A filename block has four words, which get the device name, sname, fn1 and fn2.
;The terminating character is left in B.
;In E's left half we return flags indicating which of the four names were
;specified: 1,, for the device; 2,, for the FN1; 4,, for the FN2; 10,, for the SNAME.
DEV==0 ;Indices into the filename block.
FN1==1
FN2==2
SNM==3
ifn $$altp,[
devloc: 0]
RFN: PUSH P,A
PUSH P,C
MOVE C,A ;Put the filename block addr in C since RSIXG returns in A.
PUSH P,FN1(C) ;Save default FN1, FN2 for ^X, ^Y.
PUSH P,FN2(C)
ifn $$altp,[movem c,devloc] ;save location of file block for restarting
restrt: SETZ E, ;Number of names stored yet is 0.
RFN0: PUSHJ P,RUC
ifn $$altp,[cain b,33 ;altmode?
jrst alttyp] ;yes, go print out our defaults
RFN2: PUSHJ P,RSIXG ;Read one filename.
JRST RFN1
PUSHJ P,RFNN ;If it's not null, store it.
RFN1:
ifn $$altp,[cain b,33 ;altmode?
jrst alttyp] ;yes, go print out our defaults
CAIE B,72 ;Check char that ended name, ":"
CAIN B,"73 ;or ";"
JRST RFN0
CAIN B,40 ;If was space, : or ;, read another name.
JRST RFN0
IFN $$SWITCH,[
CAIN B,57 ;"/" -- If stopped on "/" or "(", call switch rtn.
JRST RFNSL ;Read 1 switch.
CAIN B,50 ;"("
JRST RFNPAR ;Read many switches until ).
];IFN $$SWITCH
CAIE B,^X
CAIN B,^Y ;If was ^X or ^Y,
JRST RFNX ;use the default FN1 or FN2 as next name.
SUB P,[2,,2]
POP P,C
POP P,A
POPJ P,
;STORE THE NAME IN A.
RFNN: CAIN B,72 ;":"
JRST RFNC ;: => USE AS DEVICE.
CAIN B,73 ;";"
JRST RFNS ;; => USE AS SNAME.
AOJA E,RFNT(E) ;ELSE USE AS NEXT NAME IN NORMAL SEQUENCE.
;Table for storing a name normally.
;N'th entry used for N'th name.
RFNT: JRST RFNF1 ;1st name, set FN1
JRST RFNF2 ;Second, set FN2.
JRST RFNC ;Third, set device.
JRST RFNS ;Fourth, set sname.
SOS E ;Fifth one, ignore, and don't let count advance past 5.
POPJ P, ;So this word isn't part of the dispatch.
ifn $$altp,[
alttyp: type /$
/
push sp,d
move a,devloc ;restore saved filename block
move d,[tyo tyoc,b] ;type it out
call pfn
type / /
pop sp,d
jrst restrt ;go back and try again with our new defaults
]
IFN $$SWITCH,[ ;Code for processing switches, when a "/" or "(" is seen.
RFNPAR: PUSHJ P,RUC ;Get next char. Is it a ")"?
RFNPA1: CAIN B,51 ;")"
JRST RFN0 ;Paren ends switches.
CAIE B,0
CAIN B,^M
JRST RFN1 ;CR ends spec even in switch list.
PUSHJ P,SWITCH ;Try to gobble the switch.
JRST RFNPAR ;Char in I used up, get another.
JRST RFNPA1 ;Char in I not part of switch; is it ")"?
RFNSL: PUSHJ P,RUC
CAIE B,0
CAIN B,^M ;/<CR> ENDS SPEC.
JRST RFN1
PUSHJ P,SWITCH ;Otherwise, process it as switch.
JRST RFN0 ;No skip => char in B was gobbled by switch.
JRST RFN2 ;Skip => let next RSIXG gobble the char now in B.
];IFN $$SWITCH
;Here to store the word in A as the SNAME.
RFNS: MOVEM A,SNM(C) ;Set the sname.
TLO E,1_SNM ;Say the sname has been specified in this filespec.
MOVS A,DEV(C) ;Get the device,
TLNE E,1_DEV ;If dev was just spec'd, don't override the spec'd one.
POPJ P,
LSH A,-6 ;Else check 1st 2 chars,
CAIE A,'AI ' ;see if dev is one known to use the sname.
CAIN A,'ML '
POPJ P, ;If it is, nothing else to do.
CAIN A,'DM '
POPJ P,
CAIE A,'PK '
CAIN A,'PK '
POPJ P,
CAIE A,'CL '
CAIN A,'JO '
POPJ P,
RFNS1: MOVSI A,'DSK ' ;OTHERWISE SET THE DEVICE TO DSK:
;Here to store the word in A as the device name.
RFNC: MOVEM A,DEV(C) ;Set the dev name,
TLO E,1_DEV ;and say the device name was explicitly specified.
POPJ P,
;Here to store the word in A as the FN1.
RFNF1: MOVEM A,FN1(C) ;Set the FN1, say was spec'd.
TLO E,1_FN1
POPJ P,
;Here to store the word in A as the FN2.
RFNF2: MOVEM A,FN2(C) ;Set the FN2, say was spec'd.
TLO E,1_FN2
POPJ P,
;Here to process a ^X or ^Y, by taking the stacked default FN1 or FN2 and using it as input.
RFNX: ADDI B,(P) ;POINT TO THE STACKED DEFAULT FN1 OR FN2
MOVE A,-^Y(B) ;AND GET IT.
PUSHJ P,RFNN ;STORE IT NORMALLY.
JRST RFN0 ;GET NEXT NAME.
;Subroutines for filename reading.
IFE $$RUC,[
;Read char into B from b.p. in D and convert to upper case.
;Filename reading does all its input via RUC.
;If $$RUC is set, we assume that the user has defined RUC,
;and call the user's definition.
RUC: xct d ;D has op to put char in b
CAIge B,140
POPJ P,
caie b,177 ;don't modify rubout
SUBI B,40
popj p,
];IFE $$RUC
;Read SIXBIT word into A from source in D, leaving terminating char in B.
;Expects first character in B already.
;Terminates on a Space or control character or Rubout.
;Skips if the word was non-null.
RSIX: PUSH P,C
MOVE C,[440640,,A] ;Extra bit in b.p. set says RSIX, not RSIXG.
JRST RSIXG1
;Similar but stop on :, ;, and any characters which RSIXTP skips for.
;We assume that the user has defined RSIXTP to accept a character in B
;and skip or not, clobbering no ACs.
RSIXG: PUSH P,C
MOVE C,[440600,,A] ;BP FOR STORING THE SIXBIT.
RSIXG1: SETZ A, ;NO CHARS SO .
RSIX0: CAIn B,177
jrst [setz b, ;no char
came c,[440600,,a] ;don't over-rubout
jrst [dpb b,c ;clear out the old char
add c,[060000,,0] ;back up a char
jrst rsix4] ;and get another char to work with
jrst rsix4]
CAIN B,^Q
JRST RSIX2 ;^Q QUOTES A CHAR WHICH WOULD TERMINATE.
CAIG B,40
JRST RSIX1 ;SPACE OR CTL CHAR => STOP.
CAIGE B,100 ;(IF THIS SKIPS, ALL LATER TESTS WOULD FAIL ANYWAY)
TLNE C,40
JRST RSIX3 ;RSIX WAS CALLED, ALL OTHER CHARS NORMAL.
CAIE B,72 ;":"
CAIN B,73 ;";" -- RSIXG, STOP ON : AND ;.
JRST RSIX1
ifn $$sixp,[PUSHJ P,RSIXTP] ;only if we want to bother
JRST RSIX3
RSIX1: SKIPL C ;TERMINATE: SKIP IF GOT >= 1 CHAR.
AOS -1(P)
POP P,C
POPJ P,
RSIX2: PUSHJ P,RUC ;^Q => READ THE QUOTED CHAR.
RSIX3: SUBI B,40 ;INSERT NORMAL CHAR IN THE 6BIT.
TLNE C,77^4 ;IGNORE CHARS AFTER THE FIRST 6.
IDPB B,C
rsix4: PUSHJ P,RUC
JRST RSIX0
];IFN $$RFN
IFN $$PFN,[ ;Routines for printing filenames.
;Convert the filenames in the filename block which A points at
;to ASCII, depositing it down the destination in D, followed by a ^@
;which D is not advanced over.
;A filename block is four words containing the device, fn1, fn2 and sname.
;It is assumed that PSIXTP (PSIX-Terminator-P) is defined as a
;routine which, given a character in B, skips if a ^Q should be
;printed before that character. Space, colon and semicolon get ^Q'd
;in any case. Thus, you can usually make PSIXTP and RSIXTP the same.
;PFNMCH is the same as PFN except that if the device is DSK
;it prints the name of this machine (from MNAME) instead.
IFN $$MNAME,[
PFNMCH: PUSH P,B
PUSH P,C
MOVE C,DEV(A)
CAME C,[SIXBIT/DSK/]
MOVE C,MNAME
JRST PFN1
]
PFN: PUSH P,B
PUSH P,C
MOVE C,DEV(A) ;Print device name, colon, and space.
PFN1: PUSHJ P,PSIXF
MOVEI B,72 ;":"
xct d
MOVEI B,40
xct d
MOVE C,SNM(A) ;Print sname, semicolon, and space.
PUSHJ P,PSIXF
MOVEI B,73 ;";"
xct d
MOVEI B,40
xct d
MOVE C,FN1(A) ;Print fn1 and space.
PUSHJ P,PSIXF
MOVEI B,40
xct d
MOVE C,FN2(A) ;Print fn2.
PUSHJ P,PSIXF
;;the next have been commented out because it isn't needed: The user can do it
;; if he wants, since he gets his destination operation back again. But if it
;; is a TYO it will lose to go putting out stray nulls
; SETZ B, ;Store terminating ^@ but don't advance D over it.
; MOVE C,D
; IDPB B,C
POP P,C
POP P,B
POPJ P,
;Print SIXBIT word in C down destination in D,
;putting ^Q's before appropriate characters.
;Clobbers C.
PSIXF: LDB B,[360600,,C] ;Extract first character
LSH C,6 ;and flush it.
ADDI B,40
CAIE B,72 ;":"
CAIN B,73 ;";"
JRST PSIXF1
CAIN B,40
JRST PSIXF1
ifn $$sixp,[PUSHJ P,PSIXTP]
JRST PSIXF2
PSIXF1: PUSH P,B
MOVEI B,^Q
xct d
POP P,B
PSIXF2: xct d
JUMPN C,PSIXF ;ALL THE REST BLANK => DONE.
POPJ P,
];IFN $$PFN
IFN $$PFNBRF,[ ;Routine to print filenames, as briefly as possible.
;PFNBRF is called like PFN, but it omits names which have their default values.
;It is assumed that MSNAME is defined to be the address of a word
;holding the "default" SNAME.
PFNBRF: PUSH P,B
PUSH P,C
MOVE C,DEV(A) ;Print device name, colon, and space.
IFN $$MNAME,CAME C,MNAME
CAMN C,[SIXBIT /DSK/]
JRST PFNBR1
JUMPE C,PFNBR1
PUSHJ P,PSIXF
MOVEI B,72 ;":"
xct d
MOVEI B,40
xct d
PFNBR1: SKIPE C,SNM(A) ;Print sname, semicolon, and space.
CAMN C,MSNAME
JRST PFNBR2
PUSHJ P,PSIXF
MOVEI B,73 ;";"
xct d
MOVEI B,40
xct d
PFNBR2: MOVE C,FN1(A) ;Print fn1 and space.
PUSHJ P,PSIXF
SKIPN FN2(A)
JRST PFNBR3
MOVEI B,40
xct d
MOVE C,FN2(A) ;Print fn2.
PUSHJ P,PSIXF
PFNBR3:
; SETZ B, ;Store terminating ^@ but don't advance D over it.
; MOVE C,D
; IDPB B,C
POP P,C
POP P,B
POPJ P,
];IFN $$PFNBRF
IFN $$MNAME,[ ;Routine to initialize MNAME.
RMNAME: SYSCAL SSTATU,[REPEAT 6,[? %CLOUT,,MNAME]]
.LOSE %LSSYS
POPJ P,
];IFN $$MNAME
.END RFN

193
src/rwk/scram.42 Normal file
View File

@@ -0,0 +1,193 @@
dsklen==1000*5
kybufl==100
uf6toa==-1
ufsiot==-1
ufdie==-1
uftyi==-1
uftyo==-1
ufrd6==-1
fgetp==-1
.insrt rwk;empty >
$$altp==-1 ;include altmode typeing of defaults
$$rfn==-1 ;include reading of file names
$$pfn==-1 ;include printing of file names
jrst go1 ;skip stuff in files
.insrt rwk;files >
go1: type /CSCRAMBLE version / ;notify who we are
move a,versio
6toa a,[tyo tyoc,a]
.suset [.rsname,,sname] ;get default sname
type /AEnter your input file: /
syscal ttyset,[argi,,tyic
[424242,,424242]
[424202,,424242]]
loss
.suset [.rsname,,dir]
finget: movei a,device ;get pointer to file block
move d,[tyi tyic,b] ;d gets operation to read into b
call rfn"rfn
syscal open,[cnti,,.uai
argi,,dski
device
...fn1
...fn2
sname]
do [type /
Sorry, that file does not seem to be there....try again.
/
jrst finget]
type /
Please enter an output file for my results (TTY: for the TTY)
/
foutgt: movei a,device ;a gets pointer to file block
move d,[tyi tyic,b] ;d gets operation to get chars
call rfn"rfn ;and read the name
syscal open,[cnti,,.uao
argi,,dsko
device
['_SCRAM']
['OUTPUT']
sname]
do [type /
For some reason that does not seem to be a legit output file
Please try again.
/
jrst foutgt]
type /
Enter your key-phrase.
/
move c,[440700,,keybuf]
loop a,0,kybufl,[
tyi tyic,b
cain b,3
exit
cain b,15
exit
idpb b,c]
movem c,keyend
syscal ttyset,[argi,,tyic
[020202,,020202]
[020202,,020202]]
loss
type /
Is this to be an ENCODE operation? /
tyi tyic,a
caie a,131 ;is it Y?
cain a,171 ;or y?
do [type /Yes
/
jrst start]
type /No
/
move a,[sub e,d] ;the reverse operation
movem a,instr
start: syscal ttyset,[argi,,tyic
[424242,,424242]
[424242,,424242]]
loss
type /
Starting......
/
morcop: skipn ttyp ;are we reading from TTY?
do [move a,[440700,,dskbuf] ;no...get buffer full from disk
movei b,dsklen
syscal siot,[argi,,dski
a
b]
jrst [type /AScrewed on input somehow; I dunno, was partly done...A/
syscal close,[argi,,dski]
.lose 1000
syscal close,[argi,,dsko]
.lose 1000
ret]
] ;end of do
movei d,dsklen ;lets figure out how many were moved
cain b,0 ;is it the end?
skipn ttyp ;if we're not reading from TTY
sub d,b ;we do things a whole buffer at a time!
;look MA, no random +1 or -1 's! (ITS WINS!!)
setz a,
subi a,(d)
lsh a,22
skipn ttyp ;if we are not reading from the TTY
movem d,count ;save the count in the buffer
move c,[440700,,dskbuf]
move f,keyptr
codlop: skipe ttyp ;if reading from TTY
do [tyi tyic,e ;get it by reading
aos count ;count the chars in the buffer
cain e,3 ;if it is a ^C
jrst [setom b, ;pretend our count wasn't counted out
jrst codend] ;go finish up
][ ildb e,c] ;else from buffer
ildb d,f ;get key
XCT instr
dpb e,c
camn f,keyend
do [move f,[440700,,keybuf]
movem f,keyptr]
aobjn a,codlop
movem f,keyptr
move d,count
codend: move c,[440700,,dskbuf]
syscal siot,[argi,,dsko
c
d]
jrst [type /AI was writing it out and lost somehow. Are the disks full?A/
syscal close,[argi,,dski]
.lose 1000
syscal close,[argi,,dsko]
.lose 1000
ret]
cain b,0 ;zero? Are we really done?
jrst morcop ; nope, copy some more
syscal close,[argi,,dski]
skip ;ignore
syscal renmwo,[argi,,dsko
...fn1
...fn2]
skip ;ignore failure...it might not be DSK
syscal close,[argi,,dsko]
.lose 1000
die [text /ADone!
/]
ttyp: 0 ;non-zero if input is from TTY
keyend: 0
keyptr: 440700,,keybuf
instr: add e,d ;instruction to do for encode/decode
count: 0
dskbuf: block dsklen/5
keybuf: block <kybufl+4>/5
device: 'DSK '
...FN1: '@ '
...FN2: '> '
sname: ' '
versio: .fnam2
end go