;;; -*- Mode:Lisp; Readtable:ZL; Package:USER; Base:8; Patch-File:T -*- ;;; Patch file for System version 123.134 ;;; Reason: ;;; Supdup and Telnet windows now work with Chaos or TCP. Telnet favors TCP, SUPDUP favors Chaos. ;;; You can connect to (tcp or chaos) "host", (tcp) "host/port", (chaos) "host/contact-name". ;;; Written 2-Dec-87 16:03:42 by pld at site Gigamos Cambridge ;;; while running on Jack Flanders from band 2 ;;; with Experimental System 123.132, Experimental Local-File 73.3, Experimental FILE-Server 22.1, Experimental Unix-Interface 11.0, Experimental Tape 18.0, Experimental KERMIT 34.0, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, Experimental Site Data Editor 8.4, microcode 1754, SDU Boot Tape 3.12, SDU ROM 8. ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:06:58 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (defmethod (basic-nvt :connected-p) () (and connection (etypecase connection (chaos:conn (eq (chaos:state connection) 'chaos:open-state)) (tcp:tcp-buffered-stream (not (null (send connection :remote-address))))))) )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:01 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (defmethod (basic-nvt :new-connection) (host protocol contact contact-p window &aux label-spec conn) (multiple-value-setq (host contact label-spec) (expand-path tv:name host contact contact-p)) (when host (ecase protocol (:chaos (setq conn (chaos:connect host contact window))) (:internet (setq conn (condition-case (error) (tcpa:open-easy-tcp-stream host contact nil :keyword tv:name :optimistic nil) (error error))))) (unless (errorp conn) (send self :set-label label-spec) (send self :set-connection conn)) conn)) ;;; Path may be any of these: ;;; NIL: Use associated machine. ;;; a fixnum: Use the host whose Chaos address is that number. ;;; host-name: Use that host. ;;; host-name/contact-string: Use that chaos host and that contact string. ;;; internet-host-name/number: Use that Internet host and that socket. ;;; The ARPA-SOCKET and CONNECT-NAME arguments are overriden by the above. ;;; Socket numbers are in octal. ;;; If this returns NIL, that means an error occured while parsing the path )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:03 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (defun parse-path (path contact-name tcp-port &optional (protocol :chaos)) (declare (values host protocol contact contact-specified-p)) (and path (symbolp path) (setq path (symbol-name path))) (condition-case (lossage) (let (host specified-contact slash-p number) (typecase path (null (setq host si:associated-machine)) (integer (or (setq host (si:get-host-from-address path :chaos)) (setq host path))) (string (when (setq slash-p (string-search-char #// path)) (cond ((setq number (parse-number path (1+ slash-p) nil 10. t)) ;; Format is "internet-host-name/number". (setq specified-contact number) (setq protocol :internet)) (t ;; Format is "host-name/contact-string". (setq specified-contact (substring path (1+ slash-p))) (setq protocol :chaos))) (setq path (substring path 0 slash-p))) (cond ((setq host (si:parse-host path t nil)) ;Known host (unless (send host :network-typep protocol) ;Unknown protocol for this host (if specified-contact ;Can't switch protocols... (setq host nil) (setq protocol (ecase protocol ;Otherwise, check other protocol (:chaos :internet) (:internet :chaos))) (unless (send host :network-typep protocol) (setq host nil))))) (specified-contact ;;If contact name or number specified, must find particular format of address (setq host (nth-value 1 (funcall (ecase protocol (:chaos 'chaos:address-parse) (:internet 'ip:parse-internet-address)) path)))) ((setq host (nth-value 1 (ip:parse-internet-address path))) (setq protocol :internet)) ((setq host (nth-value 1 (chaos:address-parse path))) (setq protocol :chaos)) (t (setq host nil)))) (si:host (setq host path)) (t (error "Invalid host specification"))) (values host protocol (or specified-contact (ecase protocol (:chaos contact-name) (:internet tcp-port))) (not (null specified-contact)))) (error (format *terminal-io* "~&Error: ~A~%" lossage) (signal eh:abort-object)) nil)) )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:06 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (DEFUN EXPAND-PATH (PROGNAME HOST CONTACT CONTACT-P) (DECLARE (VALUES HOST CONTACT LABEL)) (VALUES HOST CONTACT (FORMAT NIL "~A -- ~A~:[ (~D)~]" PROGNAME HOST (NOT CONTACT-P) CONTACT))) )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:07 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (defmethod (basic-nvt :set-connection) (new-connection) (send typein-process :reset) (send typeout-process :reset) (setq stream (etypecase new-connection (chaos:conn (chaos:make-stream new-connection)) (tcp:tcp-buffered-stream new-connection))) (send self :gobble-greeting) ;; Typeout process initially waits to see CONNECTION non-NIL. (setq connection new-connection) (setq black-on-white nil)) )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:13 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (DEFMETHOD (BASIC-NVT :DISCONNECT) () (SEND TYPEIN-PROCESS ':FLUSH) (SEND TYPEOUT-PROCESS ':FLUSH) (WHEN CONNECTION (when (typep connection 'chaos:conn) (CHAOS:CLOSE-CONN CONNECTION) (CHAOS:REMOVE-CONN CONNECTION)) (SETQ CONNECTION NIL) (close stream)) (SEND TYPEIN-PROCESS ':RESET) (SEND TYPEOUT-PROCESS ':RESET)) ;;;This is the typein process )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:15 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (DEFMETHOD (BASIC-NVT :TYPEIN-TOP-LEVEL) (&OPTIONAL (TOP-LEVEL-P T) &AUX (TERMINAL-IO SELF)) (DO ((STR NIL NIL)) (NIL) (SETQ RETURN-TO-CALLER NIL) (SETQ STR ':ABORT) (CATCH-ERROR-RESTART-IF TOP-LEVEL-P ((SYS:ABORT ERROR) "Return to command level; optionally disconnect.") (SETQ STR (CATCH 'NVT-DONE (COND (CONNECTION (SEND SELF :SET-SUPER-IMAGE-MODE T) (CONDITION-BIND ((SYS:REMOTE-NETWORK-ERROR 'NET-ERROR)) (DO ((CH)) (NIL) (OR (SEND SELF :LISTEN) (LOCK-OUTPUT (SEND STREAM :FORCE-OUTPUT))) (SETQ CH (SEND SELF :ANY-TYI)) (IF (CONSP CH) (CASE (CAR CH) (:ERROR (THROW 'NVT-DONE (CADR CH))) (:MORE (SEND SELF ':MORE-TYI)) (OTHERWISE (SEND SELF :NET-OUTPUT-TRANSLATED CH))) (etypecase connection (chaos:conn (SELECTQ (CHAOS:STATE CONNECTION) (CHAOS:OPEN-STATE) (CHAOS:HOST-DOWN-STATE (THROW 'NVT-DONE "Foreign Host died")) (CHAOS:CLS-RECEIVED-STATE (THROW 'NVT-DONE "Closed by foreign host")) (CHAOS:LOS-RECEIVED-STATE (THROW 'NVT-DONE "Connection closed due to lossage:")) (OTHERWISE (THROW 'NVT-DONE (FORMAT NIL "Connection in unknown state:~S" (CHAOS:STATE CONNECTION)))))) (tcp:tcp-buffered-stream (unless (send stream :remote-address) (throw 'nvt-done "Connection closed")))) (IF (= (CHAR-UPCASE CH) ESCAPE-CHAR) ;;Handle the escape character, (SEND SELF ':HANDLE-ESCAPE) ;; otherwise just send through what user typed. (SEND SELF ':NET-OUTPUT-TRANSLATED CH)))))) (CONNECT-TO (SEND SELF :CLEAR-WINDOW) (CONDITION-CASE (ERROR) (SEND SELF :CONNECT (PROG1 CONNECT-TO (SETQ CONNECT-TO NIL))) (SYS:REMOTE-NETWORK-ERROR ERROR))) (T (SEND SELF :SET-SUPER-IMAGE-MODE NIL) (LETF (((TV:IO-BUFFER-OUTPUT-FUNCTION TV:IO-BUFFER) 'SUPDUP-IO-BUFFER-OUTPUT-FUNCTION)) (DO () (()) ;; Loop until loser types in something non-blank. (FORMAT T "~&~A. Type the HELP key for help.~@ Connect to host: " PROGRAM-NAME) (LET ((HOST-NAME (STRING-TRIM '(#/SPACE #/TAB) (READLINE)))) (WHEN (PLUSP (STRING-LENGTH HOST-NAME)) (RETURN (CONDITION-CASE (ERROR) (SEND SELF :CONNECT HOST-NAME) (SYS:REMOTE-NETWORK-ERROR ERROR)))))))))))) (COND ((ERRORP STR) (SETQ STR (SEND STR :REPORT-STRING))) ((EQ STR ':ABORT) (SETQ STR (IF (AND CONNECTION (Y-OR-N-P "Disconnect the ~A connection? " program-name)) "Connection aborted" NIL)))) (WHEN (STRINGP STR) (SEND SELF :DISCONNECT) (FORMAT SELF "~%~A~%" STR) (AND RETURN-TO-CALLER (RETURN T))))) )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:17 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (DEFMETHOD (BASIC-NVT :HELP-MESSAGE) (&AUX (FORMAT-ARGS (LIST "~ ~&You are using the ~A remote-login program. To connect to any Chaosnet or Internet host, just type the target host name. If you want to connect to an Internet host and specify a particular gateway host, type the gateway host name, an altmode, and the target host name. If you want to connect to a specific socket on an Internet host, follow the name of the Internet host by a slash and the socket number in octal. If you want to connect to a specific connect-name on a Chaosnet host, follow the name of the Chaosnet host by a slash and the connect name. Summary: host (for either network) chaos-host//connect-name internet-host//socket-number (octal) At any time you can type the [Network] key to give any of a number of useful commands. For descriptions of the available commands, type [Network] [Help]. Connect to host: " PROGRAM-NAME))) (COND ((NULL CONNECTION) (SEND *STANDARD-OUTPUT* :CLEAR-WINDOW) (APPLY #'FORMAT T FORMAT-ARGS)) (T (SI:WITH-HELP-STREAM (HELP-STREAM :LABEL "Keyboard system commands") (APPLY #'FORMAT HELP-STREAM FORMAT-ARGS))))) ;;;Condition handler for typein side. )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:22 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (DEFMETHOD (BASIC-SUPDUP :CONNECT) (&OPTIONAL PATH (NET-WINDOW 3)) (MULTIPLE-VALUE-BIND (HOST protocol CONTACT CONTACT-P) (PARSE-PATH PATH "SUPDUP" 95. :chaos) ;; If the host runs the WAITS operating system, it will require char i/d. (LET ((SUPDUP-%TOCID (COND ((TYPEP HOST 'SI:HOST) (MEMQ (SEND HOST ':SYSTEM-TYPE) '(:MULTICS :WAITS))) ((STRINGP HOST) ;No host name server. flush this when (MEM 'EQUALP HOST '("SAIL" "S1-A"))) ;above thing wins. (T SUPDUP-%TOCID)))) (SEND SELF :NEW-CONNECTION HOST protocol CONTACT CONTACT-P NET-WINDOW)))) )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:24 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (DEFMETHOD (BASIC-TELNET :CONNECT) (&OPTIONAL PATH (NET-WINDOW 3) &AUX CONN) (MULTIPLE-VALUE-BIND (HOST protocol CONTACT CONTACT-P) (PARSE-PATH PATH "TELNET" 23. :internet) (SETQ CONN (SEND SELF :NEW-CONNECTION HOST protocol CONTACT CONTACT-P NET-WINDOW))) (IF (ERRORP CONN) ;; Lose, return "error code". CONN ;; Win, request remote echoing. (TELNET-ECHO T))) )) ; From modified file DJ: L.NETWORK; SUPDUP.LISP#295 at 2-Dec-87 16:07:25 #8R SUPDUP#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "SUPDUP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; SUPDUP  " (defmethod (basic-telnet :send-ip) () ;; Send a New Telnet "Interrupt Process". (lock-output (send stream :force-output) (send stream :set-urgent-output t) (send stream :tyo nvt-iac) (send stream :tyo nvt-ip) (send stream :tyo nvt-iac) (send stream :tyo nvt-dm) (send stream :force-output) (send stream :set-urgent-output nil))) )) ;;;Must reset windows as the toplevel-function has changed (dolist (x supdup:telnet-windows) (send (symeval-in-instance x 'supdup:typein-process) :reset)) (dolist (x supdup:supdup-windows) (send (symeval-in-instance x 'supdup:typein-process) :reset))