.title k11cvt misc data/filename conversions for Kermit-11 .ident /1.0.01/ ; 20-Mar-84 11:31:06 Brian Nelson ; ; Copyright (C) 1984 Change Software, Inc. ; ; ; Attempt to parse filespecifications that may include DECNET ; remote node name and directories in a manner compatible ; with RSTS, RSX and RT11. ; ; This was first implemented using the host executives file ; name parsing services, ie for RSTS using the .FSS directive ; and for RSX using CSI and .PARSE to get the ; filespecification converted into rad50 and then converting ; back to ascii. The problem with doing it that way, apart ; from being a hack, is that we could not process DECNET node ; file specifications as the format of remote file names can ; never be expected to be compatible with the host system. ; Bob Denny wrote a new one for RSX which avoided this ; problem, and this version should work on all PDP11 ; operating systems. ; ; This is implemented using a transition state table driver ; thus allowing simple modification to accomodate the various ; types of node filenames that may come up in the future. ; ; ; For the time being, this routine will be placed in the over- ; lay region ERRDVR, since as of now it is only called from ; K11PAK and then only once for each file send to the remote ; system or micro. .include /IN:K11MAC.MAC/ .iif ndf, k11inc, .error ; missing INCLUDE for IN:K11MAC.MAC .sbttl generate character class table for filename state parsing .psect .macro chtype ch ,val .save .if ndf ,chtype .ift .psect chtype ,ro,d,lcl,rel,ovr chtype: .rept 128. .byte 0 .endr .endc .psect chtype . = chtype + ch .byte val .restore .endm chtype chtype 0 ,1 ; exit on null chtype 15 ,1 ; exit on chtype 73 ,1 ; exit on ';' chtype '[ ,2 ; start of a directory or uic chtype '( ,2 ; start of a rsts style ppn chtype '< ,2 ; start of a TOPS-20 directory chtype '] ,3 ; end of a directory chtype ') ,3 ; end of a ppn chtype '> ,3 ; end of a tops-20 directory chtype ': ,4 ; end of a device or node chtype '. ,5 ; part of a filename or directory chtype 54 ,6 ; part of a uic or ppn (',') chtype 40 ,7 ; spaces can be anywhere chtype '# ,0 ; ignore rsts equivalent for [1,0] chtype '$ ,0 ; ignore rsts/rsx equivalent for system chtype '! ,0 ; ignore rsts equivalent for [1,3] chtype '% ,0 ; ignore rsts equivalent for [1,4] chtype '& ,0 ; ignore rsts equivalent for [1,5] chtype '@ ,0 ; ignore rsts equivalent for assign ppn chtype '0 ,7 ; digits are ok most anywhere chtype '1 ,7 chtype '2 ,7 chtype '3 ,7 chtype '4 ,7 chtype '5 ,7 chtype '6 ,7 chtype '7 ,7 chtype '8 ,7 chtype '9 ,7 $ch = 'A&137 ; letters also please .rept 32 chtype $ch ,7 $ch = $ch + 1 .endr $ch = 'a!40 .rept 32 chtype $ch ,7 $ch = $ch + 1 .endr .sbttl state transition table .psect $pdata ptable: ; note: '<' , '(' are mapped the same as '[' ; '>' , ')' are mapped the same as ']' ; all characters that map to zero are ignored by the parser ; ; char other ,null ,'[ ,'] ,': ,'. ,', ,Let/Dig .byte 1 ,30. ,2 ,-1 ,11. ,21. ,-1 ,21. ; init .byte 2 ,30. ,-1 ,3 ,-1 ,2 ,2 ,2 ; [ ] .byte 3 ,30. ,-1 ,-1 ,14. ,23. ,3 ,23. ; [ ]xxx .byte 4 ,30. ,30. ,-1 ,-1 ,24. ,-1 ,24. ; xx.xx .even paction:.word null ,init ,copy ,fin .psect $code .sbttl namcvt parse filename to get only filename.type ; input: @r5 address of source filespecification ; 2(r5) resultant string address ; output: r0 error code, if any ; ; ; internal register usage ; ; r0 = action index ; r1 = current state ; r2 = input string pointer ; r4 --> resultant string namcvt::save ; save these in case we use them mov @r5 ,r2 ; point to the input string mov 2(r5) ,r4 ; point to the output string clrb @r4 ; init output to be .asciz mov #1 ,r1 ; initialize current state 10$: tst r1 ; current state is zero ? beq 80$ ; yes, exit then clr r3 ; get the next ch please bisb (r2)+ ,r3 ; simple bic #^C177 ,r3 ; insure in range 0..127 dec r1 ; use previous state to get the mul #10 ,r1 ; index into the state table movb chtype(r3),r0 add r0 ,r1 ; add in the character class movb ptable(r1),r1 ; and get the new state of system beq 80$ ; all done if new state is zero bmi 90$ ; error exit if < 0 clr r0 ; now mask off the action index from div #10. ,r0 ; the new state asl r0 ; action index times 2 for addressing jsr pc ,@paction(r0) ; simple br 10$ ; next please 80$: clr r0 ; no errors clrb @r4 ; .asciz for output br 100$ ; bye 90$: mov #-1 ,r0 ; error, bye 100$: unsave ; pop registers and exit return .sbttl action routines for the filename parser null: return init: mov 2(r5) ,r4 ; re-init the output string address return copy: movb r3 ,(r4)+ ; copy a byte clrb @r4 ; terminate the string return ; next please fin: save ; all done, look for a '.' mov 2(r5) ,r0 ; if there isn't any, add one at 10$: tstb @r0 ; end of the line yet ? beq 20$ ; yes cmpb @r0 ,#'. ; a dot hanging around today? beq 30$ ; yes, exit inc r0 ; no, try again please br 10$ 20$: movb #'. ,r3 ; no dot, stuff one in please call copy ; simple 30$: unsave ; pop temps and exit return .sbttl check_extension check filetype to presume binary file ; C H K E X T ; ; input: @r5 filename ; output: r0 = 0 assume not a binary file ; r0 <> 0 assume it's a binary file ; ; side effects: call to NAMCVT to get Kermit 'normal' filename .enabl lsb chkext::save ; save scratch registers we will use sub #100 ,sp ; allocate a temp buffer for the mov sp ,r1 ; parsed filename and point to it. calls namcvt ,<@r5,r1> ; convert host name to normal name. strlen r1 ; how much is left ? tst r0 ; if nothing, then presume not binary beq 290$ ; nothing to do, exit add r0 ,r1 ; point to the end of the filename 210$: cmpb -(r1) ,#'. ; look for a dot which will delimit the beq 220$ ; filetype sob r0 ,210$ ; not found, try again please br 290$ ; never found a '.' (can't happen) 220$: strlen r1 ; how many chars are in the filetype? cmp r0 ,#4 ; must be exactly four to match? bne 290$ ; no, exit without binary mode mov #bintyp ,r2 ; ok, get listhead of filetypes 230$: mov r2 ,r3 ; get next filetype address tstb @r3 ; end of the list ? beq 290$ ; if null, then all done mov r1 ,r4 ; not done, get pointer to passed type call 310$ ; convert to upper case please cmpb r0 ,(r3)+ ; look for match on filetype bne 240$ ; not today call 310$ ; convert to upper case please cmpb r0 ,(r3)+ ; again please bne 240$ ; not bloody likely call 310$ ; convert to upper case please cmpb r0 ,(r3)+ ; and so on bne 240$ ; you know call 310$ ; convert to upper case please cmpb r0 ,(r3)+ ; one more time beq 280$ ; a match, return (BINARY) 240$: add #4 ,r2 ; get the next one please br 230$ ; no match, try the next one 280$: mov #1 ,r0 ; return (BINARY) br 300$ ; and exit 290$: clr r0 ; not binary 300$: add #100 ,sp ; pop local buffer and exit unsave ; pop registers that we used return ; and exit 310$: movb (r4)+ ,r0 ; get the next character and convert to cmpb r0 ,#'A!40 ; upper case blo 320$ ; no cmpb r0 ,#'Z!40 ; well......? bhi 320$ ; not lower case bicb #40 ,r0 ; lower, convert to upper 320$: return .dsabl lsb .sbttl filetypes that are likely to be binary binini::strcpy #bintyp ,#binl return global ; list of filetypes that will almost always be binary for all exec's .save .psect $pdata .dsabl lc binl: .ascii /.TSK/ ; rsx/ias/rsts tasks 420$: .ascii /.SAV/ ; rt11/rsts save images 430$: .ascii /.OBJ/ ; compiler/mac output 440$: .ascii /.STB/ ; tkb/link symbol tables 450$: .ascii /.CRF/ ; tkb/link cross reference files 460$: .ascii /.TSD/ ; 'time shared dibol' for rt11 470$: .ascii /.BAC/ ; rsts basic+ 'compiled' files 480$: .ascii /.OLB/ ; rsx/ias/rsts object libraries 490$: .ascii /.MLB/ ; rsx/ias/rsts macro libraries 500$: .ascii /.RTS/ ; rsts/e run time systems 510$: .ascii /.EXE/ ; vms executable 520$: .ascii /.COM/ ; rsts/e v9 dcl files, CPM executables 530$: .ascii /.BIN/ ; xxdp+ and perhaps micros and others? 540$: .ascii /.SML/ ; system macro libs 550$: .ascii /.ULB/ ; rsts/rsx universal libs 560$: .ascii /.HLB/ ; help libs ala VMS style ? 570$: .ascii /.SYS/ ; RT11 drivers 580$: .ascii /.LIB/ ; RSTS/E reslibs 600$: .byte 0,0,0,0 ; end of it all .even .restore .sbttl fixfilename convert bad filename chars to something else ; FIXFILE (srcstring,dststring) ; ; Convert invalid characters to something reasonable, like 'X' ; ; Input: 0(r5) source string, .asciz ; 2(r5) destination string, .asciz at end ; Output: R0 zero if nothing, else nonzero (for warnings) ; ; The main reason for this is to protect ourselves against the ; filenaming conventions used for TOPS20 and VMS V4 so we can ; not die on a bad filename. .save .psect $pdata defchr::.byte 'X&137 .restore fixfil::save ; save whatever we may use mov @r5 ,r1 ; src string mov 2(r5) ,r2 ; dst string clr r3 ; assume no mods made to filename 10$: tstb @r1 ; end of the src filename ? beq 100$ ; yes, exit scan @r1 ,#okchr ; check for invalid characters tst r0 ; did we find one yet bne 20$ ; no (we checked for legit chars) mov sp ,r3 ; flag that we found a bad character movb defchr ,@r2 ; and insert the fixup character br 30$ ; exit 20$: movb @r1 ,@r2 ; character is ok, stuff it in 30$: inc r1 ; advance to next src char inc r2 ; advance to next dst char br 10$ ; next char in filename please 100$: mov r3 ,r0 ; return status clrb @r2 ; insure .asciz return unsave ; pop registers and exit return .save .psect $pdata .even .enabl lc okchr: .ascii /0123456789./ .ascii /abcdefghijklmnopqrstuvwxyz/ .ascii /ABCDEFGHIJKLMNOPQRSTUVWXYZ/ .byte 0 .even .restore .end