// FtpUserUtil.bcpl -- routines common to FtpKbd* and FtpCli* // Copyright Xerox Corporation 1979, 1980, 1981, 1982 // Last modifed October 11, 1982 1:01 AM by Boggs get "Pup.decl" get "FtpProt.decl" get "FtpUser.decl" get "AltoFileSys.d" external [ // outgoing procedures FtpUserFinishProc; LogPuts ProcessNoCode; GetNamePassword OpenUserConn; UserKey ListPrint; ListPuts FillPLFromLD // incoming procedures FalsePredicate; MoveBlock Resets; Closes; Puts OtherPup; FreePointer SetTimer; TimerHasExpired; Block OpenLevel1Socket; CloseLevel1Socket OpenRTPSocket; CloseRTPSocket CreateBSPStream; CloseBSPSocket; UserOpen InitCmd; DefaultPhrase; TerminatingChar; GetString; GetPhrase ExtractSubstring; StringCompare PutTemplate; Wss; CliError UNPACKDT; CONVUDT InitPList; FileType ReadLeaderPage; LnPageSize // outgoing statics listST // incoming statics CtxRunning; defaultPL; cliFlag; lvUserFinishProc userSoc; userCtx; userDsp; userKeys; userUFP; userDspLen; logStream ] manifest [ fcOK = 0 kbdAd = 177034b ] static listST //----------------------------------------------------------------------------------------- let FtpUserFinishProc(fc) be //----------------------------------------------------------------------------------------- [ if userCtx>>FtpCtx.connFlag then [ Wss(userDsp, "*NClosing connections...*N") CtxRunning>>FtpCtx.connFlag = false CloseBSPSocket(userSoc, (fc eq fcOK? 3000, 0)) ] @lvUserFinishProc = userUFP ] //----------------------------------------------------------------------------------------- and LogPuts(st, char) be //----------------------------------------------------------------------------------------- [ Puts(userDspLen, char) if logStream ne 0 then Puts(logStream, char) ] //----------------------------------------------------------------------------------------- and ProcessNoCode(noCode, pList) = valof //----------------------------------------------------------------------------------------- [ Resets(userKeys) switchon noCode into [ case 20b: case 21b: case 2: // user params [ unless GetNamePassword("*NLogin user ", lv defaultPL>>PL.UNAM, lv defaultPL>>PL.UPSW) resultis false ResetProp(lv pList>>PL.UNAM, defaultPL>>PL.UNAM) ResetProp(lv pList>>PL.UPSW, defaultPL>>PL.UPSW) endcase ] case 23b: case 24b: // connect params [ unless GetNamePassword("*NConnect to directory ", lv defaultPL>>PL.CNAM, lv defaultPL>>PL.CPSW) resultis false ResetProp(lv pList>>PL.CNAM, defaultPL>>PL.CNAM) ResetProp(lv pList>>PL.CPSW, defaultPL>>PL.CPSW) endcase ] default: [ if cliFlag then CliError(); resultis false ] ] Wss(userDsp, " Retrying...") resultis true ] //----------------------------------------------------------------------------------------- and ResetProp(lvFPL, def) be //----------------------------------------------------------------------------------------- [ if def ne 0 then if StringCompare(def, @lvFPL) ne 0 then [ FreePointer(lvFPL) @lvFPL = ExtractSubstring(def) ] ] //----------------------------------------------------------------------------------------- and GetNamePassword(prompt, lvName, lvPassword) = valof //----------------------------------------------------------------------------------------- [ let cs = InitCmd(256, 3, 0, 0, 0, userKeys, userDsp) if cs eq 0 resultis false if lvName ne 0 then [ if prompt ne 0 then Wss(cs, prompt) if @lvName ne 0 then DefaultPhrase(cs, @lvName) let name = GetString(cs) FreePointer(lvName); @lvName = name if TerminatingChar(cs) eq $*N then lvPassword = 0 ] if lvPassword ne 0 then [ FreePointer(lvPassword) Wss(cs, " Password ") GetPhrase(cs, 0, 0, FalsePredicate) Resets(cs) @lvPassword = GetString(cs) ] Closes(cs) resultis true ] //----------------------------------------------------------------------------------------- and OpenUserConn(port) = valof //----------------------------------------------------------------------------------------- [ if (port>>Port.socket^1 eq 0 & port>>Port.socket^2 eq 0) % port>>Port.host eq 0 then resultis false OpenLevel1Socket(userSoc, 0, port) OpenRTPSocket(userSoc, 0, modeInitAndReturn, 0, OtherPup) let timer = nil; SetTimer(lv timer, 6000) Block() repeatwhile userSoc>>RTPSoc.state eq stateRFCOut & not UserKey() & not TimerHasExpired(lv timer) unless userSoc>>RTPSoc.state eq stateOpen do [ Wss(userDsp, "*NConnection attempt failed") CloseRTPSocket(userSoc, 0) CloseLevel1Socket(userSoc) resultis false ] CtxRunning>>FtpCtx.bspStream = CreateBSPStream(userSoc) let Version(stream) be Wss(stream, "BCPL Pup FTP User, 14 May 82") resultis UserOpen(Version) ] //----------------------------------------------------------------------------------------- and UserKey() = (kbdAd!1 & 2) eq 0 //----------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- and ListPrint(remotePL, localPL) be //----------------------------------------------------------------------------------------- [ let options = listST>>ST.par1 if listST>>ST.par3 then //print a title [ listST>>ST.par3 = false unless options eq 1b15 rshift offset DPRP.SFIL do Puts(userDsp, $*N) listST>>ST.par2 = 0; NextField(wName) if (options & lbType) ne 0 then [ NextField(wType); Wss(listST, "Type") ] if (options & lbLength) ne 0 then [ NextField(wLength); Wss(listST, "Length") ] if (options & lbCreate) ne 0 then [ NextField(wDate); Wss(listST, "Create") ] if (options & lbWrite) ne 0 then [ NextField(wDate); Wss(listST, "Write") ] if (options & lbRead) ne 0 then [ NextField(wDate); Wss(listST, "Read") ] if (options & lbAuthor) ne 0 then [ NextField(wAuthor); Wss(listST, "Author") ] ] listST>>ST.par2 = 0; Puts(userDsp, $*N); NextField(wName) Wss(listST, (remotePL>>PL.SFIL? remotePL>>PL.SFIL, remotePL>>PL.NAMB)) if (options & lbType) ne 0 then [ NextField(wType) switchon remotePL>>PL.TYPE into [ case Text: [ Wss(listST, "Text"); endcase ] case Binary: [ PutTemplate(listST, "B($UD)", remotePL>>PL.BYTE); endcase ] default: [ Wss(listST, " ?"); endcase ] ] ] if (options & lbLength) ne 0 then [ NextField(wLength) PutTemplate(listST, "$EUD", lv remotePL>>PL.SIZE) ] if (options & lbCreate) ne 0 then [ NextField(wDate); PrintDate(lv remotePL>>PL.CDAT) ] if (options & lbWrite) ne 0 then [ NextField(wDate); PrintDate(lv remotePL>>PL.WDAT) ] if (options & lbRead) ne 0 then [ NextField(wDate); PrintDate(lv remotePL>>PL.RDAT) ] if (options & lbAuthor) ne 0 then [ NextField(wAuthor) test remotePL>>PL.AUTH ne 0 ifso Wss(listST, remotePL>>PL.AUTH) ifnot Wss(listST, " ---") ] ] //----------------------------------------------------------------------------------------- and ListPuts(st, char) be //----------------------------------------------------------------------------------------- [ Puts(userDsp, char) st>>ST.par2 = st>>ST.par2 -1 ] //----------------------------------------------------------------------------------------- and NextField(width) be //----------------------------------------------------------------------------------------- [ test listST>>ST.par2 gr 0 ifso until listST>>ST.par2 eq 0 do Puts(listST, $*S) ifnot if listST>>ST.par2 le 0 then [ width = width + listST>>ST.par2 // par2 is negative Wss(listST, " ") ] listST>>ST.par2 = width ] //----------------------------------------------------------------------------------------- and PrintDate(dt) be //----------------------------------------------------------------------------------------- [ if dt!0 eq 0 then [ Wss(listST, " ---"); return ] let uv = vec 7; UNPACKDT(dt, uv) let date = vec 12; CONVUDT(date, uv) Wss(listST, date) ] //----------------------------------------------------------------------------------------- and FillPLFromLD() = valof //----------------------------------------------------------------------------------------- [ let pl = InitPList(defaultPL) let fileType = FileType() if defaultPL>>PL.TYPE eq Text & fileType eq Binary then [ Wss(userDsp, "*NFile is Binary, but you have made the default Text") Wss(userDsp, "*NThis operation will lose information") ] if pl>>PL.TYPE eq 0 then pl>>PL.TYPE = fileType test pl>>PL.TYPE eq Binary ifso if pl>>PL.BYTE eq 0 then pl>>PL.BYTE = 8 ifnot if pl>>PL.EOLC eq 0 then pl>>PL.EOLC = CR let ld = CtxRunning>>FtpCtx.buffer ReadLeaderPage(CtxRunning>>FtpCtx.diskStream, ld) MoveBlock(lv pl>>PL.CDAT, lv ld>>LD.created, 2) MoveBlock(lv pl>>PL.RDAT, lv ld>>LD.read, 2) MoveBlock(lv pl>>PL.WDAT, lv ld>>LD.written, 2) let siz = lv pl>>PL.SIZE let fa = lv ld>>LD.hintLastPageFa let lnBytes = LnPageSize(CtxRunning>>FtpCtx.diskStream) +1 let numPages = fa>>FA.pageNumber -1 //don't count leader page unless numPages eq -1 do [ siz!0 = numPages rshift (16-lnBytes) siz!1 = numPages lshift lnBytes + fa>>FA.charPos ] resultis pl ]