// IfsFtpRetrieve.bcpl -- IFS Ftp Retrieve command // Copyright Xerox Corporation 1979, 1980, 1981 // Last modified May 11, 1982 11:33 AM by Taft get "IfsDirs.decl" get "IfsFiles.decl" get "IfsFtpProt.decl" external [ // outgoing procedures FtpSRetrieve; FtpSRetrieveFile // incoming procedures from other Ftp files FtpSMakeSFIL; FtpSSendMark FtpSCheckAccess; FtpSFillPLFromLD MtpSAnonymousAccess; FtpSCheckConnection DiskToNet; FileType; FreePList // incoming procedures from IFS Dirs NextFD; DestroyFD LookupIFSFile; OpenIFSStream; CloseIFSStream // incoming procedures - miscellaneous IFSPrintError // incoming statics CtxRunning ] //--------------------------------------------------------------------------- let FtpSRetrieve(remotePL, localPL) = valof //--------------------------------------------------------------------------- [ // repeat localPL = FreePList(localPL) unless FtpSCheckConnection() resultis false let ec = nil test CtxRunning>>FtpCtx.fd eq 0 ifso [ // first time for this Retrieve request FtpSMakeSFIL(remotePL) test CtxRunning>>FtpCtx.type eq jobTypeFTP ifso unless FtpSCheckAccess(remotePL) resultis false ifnot unless MtpSAnonymousAccess(remotePL) resultis false CtxRunning>>FtpCtx.fd = LookupIFSFile(remotePL>>PL.SFIL, lcMultiple+lcVHighest, lv ec, 0, remotePL>>PL.DIRE) if CtxRunning>>FtpCtx.fd eq 0 resultis FtpSSendMark(markNo, ec) ] ifnot unless NextFD(CtxRunning>>FtpCtx.fd, false) do [ // failed - no more files CtxRunning>>FtpCtx.fd = DestroyFD(CtxRunning>>FtpCtx.fd) resultis false ] let fd = CtxRunning>>FtpCtx.fd // Set up outgoing property list localPL = FtpSFillPLFromLD(remotePL, true) if localPL eq 0 then loop // file went away? // If we encounter problems with the pList, respond with either // markNo or markComment depending on whether the retrieve request // specified multiple files (serverFilename contained a wildcard char). let markFail = fd>>FD.template eq 0? markNo, markComment if localPL>>PL.TYPE eq Unspecified then [ // do it the hard way let diskStream = OpenIFSStream(fd, lv ec) test diskStream ne 0 ifso [ localPL>>PL.TYPE = FileType(diskStream)? Text, Binary CloseIFSStream(diskStream) ] ifnot localPL>>PL.TYPE = remotePL>>PL.TYPE ne 0? remotePL>>PL.TYPE, Binary ] if remotePL>>PL.TYPE ne 0 & localPL>>PL.TYPE ne remotePL>>PL.TYPE then test localPL>>PL.TYPE eq Binary ifso [ FtpSSendMark(markFail, ecNotRetrieved, lv fd>>FD.dr>>DR.pathName, IFSPrintError, ecBinaryNotText) loop ] ifnot [ FtpSSendMark(markComment, ecMayBeText, lv fd>>FD.dr>>DR.pathName) localPL>>PL.TYPE = Binary ] // FtpSRetrieve (cont'd) test localPL>>PL.TYPE eq Text ifso [ localPL>>PL.EOLC = CR if remotePL>>PL.EOLC eq CRLF then [ FtpSSendMark(markFail, ecNotRetrieved, lv fd>>FD.dr>>DR.pathName, IFSPrintError, ecCRLFConversion) loop ] ] ifnot test remotePL>>PL.BYTE eq 0 ifso if localPL>>PL.BYTE eq 0 then localPL>>PL.BYTE = 8 ifnot test localPL>>PL.BYTE eq 0 ifso localPL>>PL.BYTE = remotePL>>PL.BYTE ifnot if localPL>>PL.BYTE ne remotePL>>PL.BYTE then [ FtpSSendMark(markFail, ecNotRetrieved, lv fd>>FD.dr>>DR.pathName, IFSPrintError, ecByteSize) loop ] resultis localPL ] repeat //--------------------------------------------------------------------------- and FtpSRetrieveFile(pList) = valof //--------------------------------------------------------------------------- [ let ec = nil let diskStream = OpenIFSStream(CtxRunning>>FtpCtx.fd, lv ec, modeRead) if diskStream ne 0 then [ ec = DiskToNet(CtxRunning>>FtpCtx.bspStream, diskStream) CloseIFSStream(diskStream) ] resultis ec eq 0? true, FtpSSendMark(markNo, ec) ]