;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 123.82
;;; Reason:
;;;  User FTP user interface: if you type a command that requires you to be connected
;;;  and you are not connected, tell user to connect first rather than throwing her
;;;  into the error handler.
;;; Written 28-Oct-87 19:50:14 by pld at site LMI Cambridge
;;; while running on Jack Flanders from band 2
;;; with Experimental System 123.81, 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.USER; FTP.LISP#34 at 28-Oct-87 19:50:32
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "

(defvar *ftp-connected-command-list* nil)

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:37
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defun execute-ftp-command-list (command-list &aux entry)
  (when command-list
    (setq entry (find-command-entry (car (last command-list)))))
  (when entry
    (let* ((func-name (car entry))
	   (func-sym (cdr entry))
	   (prompt-list (nthcdr (1- (length command-list))
				(get func-sym :prompt-list)))
	   input)
      (when (and (member func-sym *ftp-connected-command-list*)
		 (not *connected*))
	(format t "~&Connect to a remote host before doing ~S" func-name)
	(return-from execute-ftp-command-list nil))
      (when (and prompt-list (is-required-arg (car prompt-list)))
	(dolist (prompt prompt-list)
	  (fresh-line)
	  (setq input (global:prompt-and-read :string-or-nil prompt))
	  (when (and (null input) (is-required-arg prompt))
	    (when *bell*
	      (global:beep))
	    (format t "~&~A ~A~%" func-name (get func-sym :usage-string))
	    (return-from execute-ftp-command-list nil))
	  (push input command-list)))
      (setq command-list
	    (do () ((car command-list) (reverse command-list))
	      (pop command-list)))
      
      ;; typing  blows away our connection to the remote-host; this should be fixed.
      ;; this condition-case is here to prevent  from bombing us out of ftp.
      (global:condition-case ()
	  (apply func-sym (cdr command-list))
	(sys:abort)))))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:43
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defun hookup (host port &optional (keyword "FTP Control Connection"))
  (setq *remote-hostname* (if (numberp host)
			    (format nil "~X" host)
			  (string host)))
  (setq *control* (open (string-append "TCP-HOST:" host "." port)
		  :keyword keyword))
  (setq *connected* t)
  (if *verbose* (format t "~&Connected to ~S~%" host))
  (getreply nil))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:46
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defmacro defcmd (cmd-names arglist connection-needed-p &body body)
  (declare (zwei:indentation 2 1))
  (when (atom cmd-names)
    (setq cmd-names (list cmd-names)))
  (let ((cmd-sym (car cmd-names))
	(usage (usage-string arglist))
	(prompt (prompt-list arglist))
	(forms nil))
    
    ;; hack arglist so the cmd-func will tolerate
    ;; any number of arguments passed to it.
    (unless (member '&rest arglist :test #'eq)
      (setq arglist `(,@arglist &rest ignore)))
    
    (dolist (cmd-name cmd-names)
      (let ((name (substring (format nil "~(~A~)" cmd-name) 4)))
	(push `(progn
		 (global:record-source-file-name ',cmd-name 'defcmd)
		 (unless (assoc ,name *ftp-command-alist* :test #'string-equal)
		   (push `(,',name . ,',cmd-sym) *ftp-command-alist*))
		 (when ,connection-needed-p
		   (unless (member ',cmd-sym *ftp-connected-command-list* :test #'eq)
		     (push ',cmd-sym *ftp-connected-command-list*)))
		 )
	      forms)))
    
    `(progn
       ;; add all aliases into the alist of command names.
       ;; notice that names in the table have the "cmd-" prefix stripped.
       (eval-when (eval compile load)
	 ,@forms)
       (defun ,cmd-sym ,arglist
	 ,@body)
       (setf (get ',cmd-sym :usage-string) ',usage)
       (setf (get ',cmd-sym :prompt-list) ',prompt))))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:49
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-append (local-file &optional (remote-file local-file)) t
  "append to a file"
  (sendrequest "APPE" local-file remote-file))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:51
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-get cmd-recv) (remote-file &optional (local-file remote-file)) t
  "receive one file"
  (recvrequest "RETR" local-file remote-file))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:53
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-put cmd-send) (local-file &optional (remote-file local-file)) t
  "send one file"
  (sendrequest "STOR" local-file remote-file))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:55
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-mput cmd-msend) (&rest local-files) t
  "send multiple files"
  (multiple-command "put" #'cmd-put local-files))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:50:57
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-mget cmd-mrecv) (&rest remote-files) t
  "receive multiple files"
  (multiple-command "get" #'cmd-get remote-files))

;;; connection hacking commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:00
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-quit cmd-bye) () nil
  "terminate ftp session and exit"
  (throw 'quit nil))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:01
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-open (to) nil
  "connect to remote ftp"
  (when (and *connected* *control* (send *control* :remote-address))
    (cmd-close))
  (hookup to "FTP")
  (when *auto-login*
    (cmd-user)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:04
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-user (&optional username password account) t
  "send new user information (login)"
  (cond ((multiple-value-setq (*user* *pass* *acct*)
	    (if username
		(try-login username password account)
	      (try-login *user* *pass* *acct*))))
	(*verbose*
	 (format t "~&Login failed~%"))))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:07
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-close () t
  "terminate ftp session"
  (when *connected*
    (command "QUIT")
    (when *control*
      (close *control*)
      (setq *control* nil))
    (when *data*
      (close *data*)
      (setq *data* nil))
    (setq *connected* nil)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:09
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-quote (&rest command-line-to-send) t
  "send arbitrary ftp command"
  (= (sym complete) (command-1 (format nil "~{~A ~}" command-line-to-send))))

;;; help and status commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:13
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-help cmd-?) (&optional command) nil
  "print local help information"
  (let (last-entry
	alias-list)
    (fresh-line)
    (cond (command
	   (when (setq command (find-command-entry command))
	     (format t "~A:~A~%  ~A~%"
		     (car command)
		     (get (cdr command) :usage-string)
		     (or (documentation (cdr command))
			 ""))))
	  (t
	   (dolist (entry *ftp-command-alist*)
	     (when (and last-entry
			(not (eq (cdr entry) (cdr last-entry))))
	       (format t "*~{ ~A~^,~}:~A~%    ~A~%"
		       alias-list
		       (get (cdr last-entry) :usage-string)
		       (or (documentation (cdr last-entry)) ""))
	       (setq alias-list nil))
	     (push (car entry) alias-list)
	     (setq last-entry entry))))))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:15
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-status () nil
  "show current status"
  (if *connected*
      (format t "~&Connected to ~A~%" *remote-hostname*)
    (format t "~&Not connected~%"))
  (format t "Mode: ~A; Type: ~A; Form: ~A; Structure: ~A~%"
	  *mode* *type* *form* *struct*)
  (format t "Verbose: ~A; Bell: ~A; Prompting: ~A; Globbing: ~A~
	   ~&Hash mark printing: ~A; Use of PORT cmds: ~A~%"
	  (onoff *verbose*)
	  (onoff *bell*)
	  (onoff *prompt*)
	  (onoff *glob*)
	  (onoff *hash*)
	  (onoff *sendport*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:18
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-remotehelp (&optional subject) t
  "get help from remote server"
  (let ((*verbose* t))
    (if subject
	(commandp (sym complete) "HELP ~A" subject)
 (commandp (sym complete) "HELP"))))

;;; type setting commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:19
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-type (&optional type-name) nil
  "show/set file transfer type"
  (if type-name
      (execute-ftp-command-list `(,type-name))
    (format t "~&Using ~A type to transfer files.~%" *type*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:21
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-ascii () t
  "set ascii transfer type"
  (setopt *type* 'ascii))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:25
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-binary () t
  "set binary transfer type"
  (setopt *type* 'binary))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:26
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-image () t
  "set image transfer type"
  (setopt *type* 'image))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:27
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-ebcdic () t
  "set ebcdic transfer type"
  (setopt *type* 'ebcdic))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:29
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-tenex () t
  "set tenex transfer type"
  (setopt *type* 'tenex *bytesize*))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:31
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-16bit () t
  "set 16bit transfer type"
  (unless (setopt *type* '16bit)
    (setopt *type* 'binary)))

;;; format setting commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:32
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-form (&optional format-name) nil
  "show/set file transfer format"
  (if format-name
      (execute-ftp-command-list `(,format-name))
    (format t "~&Using ~A format to transfer files.~%" *form*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:34
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-non-print () t
  "set non-print transfer format"
  (setopt *form* 'non-print))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:36
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-telnet () t
  "set telnet transfer format"
  (setopt *form* 'telnet))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:38
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-carriage-control () t
  "set carriage-control transfer format"
  (setopt *form* 'carriage-control))

;;; struct setting commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:40
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-struct (&optional structure-name) nil
  "show/set file transfer structure"
  (if structure-name
      (execute-ftp-command-list `(,structure-name))
    (format t "~&Using ~A structure to transfer files.~%" *struct*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:42
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-file () t
  "set file transfer structure"
  (setopt *struct* 'file))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:43
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-record () t
  "set record transfer structure"
  (setopt *struct* 'record))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:45
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-page () t
  "set page transfer structure"
  (setopt *struct* 'page))

;;; mode setting commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:47
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "

 
(defcmd cmd-mode (&optional mode-name) nil
  "show/set file transfer mode"
  (if mode-name
      (execute-ftp-command-list `(,mode-name))
    (format t "~&Using ~A mode to transfer files.~%" *mode*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:48
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-stream () t
  "set stream transfer mode"
  (setopt *mode* 'stream))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:49
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-block () t
  "set block transfer mode"
  (setopt *mode* 'block))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:51
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-compressed () t
  "set compressed transfer mode"
  (setopt *mode* 'compressed))

;;; toggle setting commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:54
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-bell () nil
  "beep when command completed"
  (setq *bell* (not *bell*))
  (format t "~&Bell mode ~A.~%" (onoff *bell*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:55
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-debug () nil
  "toggle debugging mode"
  (setq *debug* (not *debug*))
  (format t "~&Debugging ~A.~%" (onoff *debug*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:57
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-glob () nil
  "toggle metacharacter expansion of local file names"
  (setq *glob* (not *glob*))
  (format t "~&Globbing ~A.~%" (onoff *glob*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:51:59
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-trace () nil
  "toggle packet tracing"
  (setq *trace* (not *trace*))
  (format t "~&Packet tracing ~A.~%" (onoff *trace*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:00
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-hash () nil
  "toggle printing `#' for each buffer transferred"
  (setq *hash* (not *hash*))
  (format t "~&Hash mark printing ~A.~%" (onoff *hash*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:01
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-verbose () nil
  "toggle verbose mode"
  (setq *verbose* (not *verbose*))
  (format t "~&Verbose mode ~A.~%" (onoff *verbose*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:03
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-prompt () nil
  "toggle interactive confirmation on `multiple' commands"
  (setq *prompt* (not *prompt*))
  (format t "~&Interactive mode ~A.~%" (onoff *prompt*)))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:05
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-sendport () nil
  "toggle use of PORT cmd use before each data connection"
  (setq *sendport* (not *sendport*))
  (format t "~&Use of PORT cmds ~A.~%" (onoff *sendport*)))

;;; directory hacking commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:06
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-cd (remote-directory) t
  "change remote working directory"
  (commandp (sym complete) "CWD ~A" remote-directory))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:08
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-lcd (&optional local-directory) nil
  "change local working directory"
  (let* ((defaults (fs:make-pathname-defaults))
	 (colon (string-search-char #\: local-directory))
	 (host (if colon (si:parse-host (substring local-directory 0 colon) t) si:local-host))
	 (pathname (fs:parse-pathname local-directory host defaults (if colon (1+ colon) 0))))
    (fs:set-default-pathname pathname)
    (format t "~&Local pathname default now ~A.~%" pathname)
    pathname))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:10
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-ls cmd-dir) (&optional remote-directory local-file) t
  "list contents of remote directory"
  (unless (eq *type* 'ascii)
    (cmd-ascii))
  (recvrequest "LIST" local-file remote-directory))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:12
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd (cmd-mls cmd-mdir) (&rest remote-directories) t
  "list contents of multiple remote directories"
  (multiple-command "ls" #'cmd-ls remote-directories))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:14
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "

	    
(defcmd cmd-pwd () t
  "print working directory on remote machine"
  (commandp (sym complete) "XPWD"))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:16
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-mkdir (remote-directory) t
   "make a directory on remote machine"
   (commandp (sym complete) "XMKD ~A" remote-directory))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:18
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-rmdir (remote-directory) t
  "remove a directory on remote machine"
  (commandp (sym complete) "XRMD ~A" remote-directory))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:19
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-expunge (remote-directory) t
  "expunge the contents of a directory"
  (let ((success (commandp (sym complete) "XPNG ~A" remote-directory)))
    (when success
      (let* ((reply (last-reply))
	     (start (and reply (string-search-char #\space reply)))
	     (blocks-freed (and start (parse-integer reply :start start :junk-allowed t))))
	(or blocks-freed 0)))))

;;; file hacking commands

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:21
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-delete (remote-file) t
  "delete one remote file"
  (commandp (sym complete) "DELE ~A" remote-file))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:23
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-undelete (remote-file) t
  "undelete one remote file"
  (commandp (sym complete) "XUND ~A" remote-file))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:24
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-mdelete (&rest remote-files) t
  "delete multiple remote files"
  (multiple-command "delete" #'cmd-delete remote-files))

))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:27
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-rename (from-name to-name) t
  "rename a remote file"
  (when (member (command "RNFR ~A" from-name)
		;; vms file server has bug, sends complete.
		(list (sym continue) (sym complete))
		:test #'eq)
    (commandp (sym complete) "RNTO ~A" to-name)))


))

; From modified file DJ: L.NETWORK.IP-TCP.USER; FTP.LISP#34 at 28-Oct-87 19:52:29
#10R FTP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "FTP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; USER; FTP  "


(defcmd cmd-history () nil
  "print command/reply history"
  (when (not (eq *history* :dont-record))
    (dolist (x (reverse *history*))
      (fresh-line)
      (princ x))))


))
