;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*- ;;; Patch file for System version 123.39 ;;; Reason: ;;; If an FTP connection is interrupted for a long time (e.g. you are loading a file which ;;; causes other files to be loaded), the remote end can time out and send a RST. ;;; Two problems, two cures: ;;; - FTP data connection now requests pessimistic window -- when no read buffers ;;; available, the remote end will get a zero window, which it must (per TCP spec) ;;; be patient about. ;;; - TCP-STREAM now has a cerror for :reset and :close messages (remote and local ;;; aborts), allowing you to treat them as end-of-file, but not assuming that ;;; that is what you want to do. ;;; Written 7-Oct-87 16:50:42 by pld at site LMI Cambridge ;;; while running on Jack Flanders from band 2 ;;; with Experimental System 123.38, Experimental Local-File 73.0, Experimental FILE-Server 22.0, Experimental Unix-Interface 11.0, Experimental Tape 18.0, Experimental KERMIT 34.0, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, microcode 1754, SDU Boot Tape 3.12, SDU ROM 8. ; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; TCP-STREAM.LISP#39 at 7-Oct-87 16:50:43 #10R TCP#: (COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "TCP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; TCP-STREAM  " (defmethod (tcp-stream-mixin :handle-replies) (&optional no-hang-p) (loop (cond ((send socket :listen) ;Activity on the socket (let ((item (send socket :read-data))) (case (first item) (:open (send self :build-buffers) (return :open)) (:write-reply (send self :write-reply (second item)) (return :write-reply)) (:data (send self :read-reply (second item)) (when (eq (third item) :eof) (setq closing t)) (return :read-reply)) (:closing ;Remote side has closed (setq closing t) (return :remote-close)) (:reset (setq closing t) (setq open nil) ;;(cerror "Continue, treating as end-of-file" "Connection reset remotely") (return :reset)) (:close ;Socket closed out from under us (setq closing t) (setq open nil) ;;(cerror "Continue, treating as end-of-file" "Connection reset locally") (return :local-close)) ((:network-unreachable :host-unreachable :protocol-unreachable :port-unreachable) (setq closing t) (setq open nil) (send socket :abort) (return :unreachable)) (:timeout (return :timeout)) (otherwise ;;Ignore it )))) (no-hang-p ;No activity and no-hang (return nil)) (t ;No activity -- wait (wait-for-reply socket))))) )) ; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#25 at 7-Oct-87 16:50:54 #10R FTP#: (COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  " (defun initconn (direction) (when *data* (close *data*) (setq *data* nil)) (let ((addr nil) (port nil) (result nil)) (setq *data* (open (format nil "TCP-HOST:~D.FTP-DATA~:[#~D~;~]" (send *cin* :remote-address) *sendport* (send *cin* :local-port)) :direction direction :input-buffers 16 :output-buffers 16 :optimistic nil :keyword "FTP Data Connection" :connect nil)) (when *sendport* (setq addr (send *data* :local-address)) (setq port (send *data* :local-port)) (setq result (command "PORT ~D,~D,~D,~D,~D,~D" (ldb (byte 8 24) addr) (ldb (byte 8 16) addr) (ldb (byte 8 8) addr) (ldb (byte 8 0) addr) (ldb (byte 8 8) port) (ldb (byte 8 0) port))) (if (= result (sym error)) (let ((*sendport* nil)) (initconn direction)) (not (= result (sym complete))))))) ))