Annotation of 43BSDReno/contrib/emacs-18.55/lisp/ftp.el, revision 1.1

1.1     ! root        1: ;; File input and output over Internet using FTP
        !             2: ;; Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: ;; Author [email protected].
        !             4: 
        !             5: ;; This file is part of GNU Emacs.
        !             6: 
        !             7: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             8: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             9: ;; accepts responsibility to anyone for the consequences of using it
        !            10: ;; or for whether it serves any particular purpose or works at all,
        !            11: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            12: ;; License for full details.
        !            13: 
        !            14: ;; Everyone is granted permission to copy, modify and redistribute
        !            15: ;; GNU Emacs, but only under the conditions described in the
        !            16: ;; GNU Emacs General Public License.   A copy of this license is
        !            17: ;; supposed to have been given to you along with GNU Emacs so you
        !            18: ;; can know your rights and responsibilities.  It should be in a
        !            19: ;; file named COPYING.  Among other things, the copyright notice
        !            20: ;; and this notice must be preserved on all copies.
        !            21: 
        !            22: 
        !            23: ;; you can turn this off by doing
        !            24: ;;  (setq ftp-password-alist 'compulsory-urinalysis)
        !            25: (defvar ftp-password-alist () "Security sucks")
        !            26: 
        !            27: (defun read-ftp-user-password (host user new)
        !            28:   (let (tem)
        !            29:     (if (and (not new)
        !            30:             (listp ftp-password-alist)
        !            31:             (setq tem (cdr (assoc host ftp-password-alist)))
        !            32:             (or (null user)
        !            33:                 (string= user (car tem))))
        !            34:        tem
        !            35:       (or user
        !            36:          (progn
        !            37:            (setq tem (or (and (listp ftp-password-alist)
        !            38:                               (car (cdr (assoc host ftp-password-alist))))
        !            39:                          (user-login-name)))
        !            40:            (setq user (read-string (format
        !            41:                                      "User-name for %s (default \"%s\"): "
        !            42:                                      host tem)))
        !            43:            (if (equal user "") (setq user tem))))
        !            44:       (setq tem (cons user
        !            45:                      ;; If you want to use some non-echoing string-reader,
        !            46:                      ;; feel free to write it yourself.  I don't care enough.
        !            47:                      (read-string (format "Password for %s@%s: " user host)
        !            48:                        (if (not (listp ftp-password-alist))
        !            49:                            ""
        !            50:                          (or (cdr (cdr (assoc host ftp-password-alist)))
        !            51:                              (let ((l ftp-password-alist))
        !            52:                                (catch 'foo
        !            53:                                  (while l
        !            54:                                    (if (string= (car (cdr (car l))) user)
        !            55:                                        (throw 'foo (cdr (cdr (car l))))
        !            56:                                      (setq l (cdr l))))
        !            57:                                  nil))
        !            58:                              "")))))
        !            59:       (message "")
        !            60:       (if (and (listp ftp-password-alist)
        !            61:               (not (string= (cdr tem) "")))
        !            62:          (setq ftp-password-alist (cons (cons host tem)
        !            63:                                         ftp-password-alist)))
        !            64:       tem)))
        !            65: 
        !            66: (defun ftp-read-file-name (prompt)
        !            67:   (let ((s ""))
        !            68:     (while (not (string-match "\\`[ \t]*\\([^ \t:]+\\)[ \t]*:\\(.+\\)\\'" s))
        !            69:       (setq s (read-string prompt s)))
        !            70:     (list (substring s (match-beginning 1) (match-end 1))
        !            71:          (substring s (match-beginning 2) (match-end 2)))))
        !            72: 
        !            73: 
        !            74: (defun ftp-find-file (host file &optional user password)
        !            75:   "FTP to HOST to get FILE, logging in as USER with password PASSWORD.
        !            76: Interactively, HOST and FILE are specified by reading a string with
        !            77:  a colon character separating the host from the filename.
        !            78: USER and PASSWORD are defaulted from the values used when
        !            79:  last ftping from HOST (unless password-remembering is disabled).
        !            80:  Supply a password of the symbol `t' to override this default
        !            81:  (interactively, this is done by giving a prefix arg)"
        !            82:   (interactive
        !            83:        (append (ftp-read-file-name "FTP get host:file: ")
        !            84:                (list nil (not (null current-prefix-arg)))))
        !            85:   (ftp-find-file-or-directory host file t user password))
        !            86: 
        !            87: (defun ftp-list-directory (host file &optional user password)
        !            88:   "FTP to HOST to list DIRECTORY, logging in as USER with password PASSWORD.
        !            89: Interactively, HOST and FILE are specified by reading a string with
        !            90:  a colon character separating the host from the filename.
        !            91: USER and PASSWORD are defaulted from the values used when
        !            92:  last ftping from HOST (unless password-remembering is disabled).
        !            93:  Supply a password of the symbol `t' to override this default
        !            94:  (interactively, this is done by giving a prefix arg)"
        !            95:   (interactive
        !            96:        (append (ftp-read-file-name "FTP get host:directory: ")
        !            97:                (list nil (not (null current-prefix-arg)))))
        !            98:   (ftp-find-file-or-directory host file nil user password))
        !            99: 
        !           100: (defun ftp-find-file-or-directory (host file filep &optional user password)
        !           101:   "FTP to HOST to get FILE.  Third arg is t for file, nil for directory.
        !           102: Log in as USER with PASSWORD.  If USER is nil or PASSWORD is nil or t,
        !           103: we prompt for the user name and password."
        !           104:   (or (and user password (not (eq password t)))
        !           105:       (progn (setq user (read-ftp-user-password host user (eq password t))
        !           106:                   password (cdr user)
        !           107:                   user (car user))))
        !           108:   (let ((buffer (get-buffer-create (format "*ftp%s %s:%s*"
        !           109:                                           (if filep "" "-directory")
        !           110:                                           host file))))
        !           111:     (set-buffer buffer)
        !           112:     (let ((process (ftp-setup-buffer host file))
        !           113:          (case-fold-search nil))
        !           114:       (let ((win nil))
        !           115:        (unwind-protect
        !           116:            (if (setq win (ftp-login process host user password))
        !           117:                (message "Logged in")
        !           118:              (error "Ftp login lost"))
        !           119:          (or win (delete-process process))))
        !           120:       (message "Opening %s %s:%s..." (if filep "file" "directory")
        !           121:               host file)
        !           122:       (if (ftp-command process
        !           123:                       (format "%s \"%s\" -\nquit\n" (if filep "get" "dir")
        !           124:                               file)
        !           125:                       "\\(150\\|125\\).*\n"
        !           126:                       "200.*\n")
        !           127:          (progn (forward-line 1)
        !           128:                 (let ((buffer-read-only nil))
        !           129:                   (delete-region (point-min) (point)))
        !           130:                 (message "Retrieving %s:%s in background.  Bye!" host file)
        !           131:                 (set-process-sentinel process
        !           132:                                       'ftp-asynchronous-input-sentinel)
        !           133:                 process)
        !           134:        (switch-to-buffer buffer)
        !           135:        (let ((buffer-read-only nil))
        !           136:          (insert-before-markers "<<<Ftp lost>>>"))
        !           137:        (delete-process process)
        !           138:        (error "Ftp %s:%s lost" host file)))))
        !           139: 
        !           140: 
        !           141: (defun ftp-write-file (host file &optional user password)
        !           142:   "FTP to HOST to write FILE, logging in as USER with password PASSWORD.
        !           143: Interactively, HOST and FILE are specified by reading a string with colon
        !           144: separating the host from the filename.
        !           145: USER and PASSWORD are defaulted from the values used when
        !           146:  last ftping from HOST (unless password-remembering is disabled).
        !           147:  Supply a password of the symbol `t' to override this default
        !           148:  (interactively, this is done by giving a prefix arg)"
        !           149:   (interactive
        !           150:     (append (ftp-read-file-name "FTP write host:file: ")
        !           151:            (list nil (not (null current-prefix-arg)))))
        !           152:   (or (and user password (not (eq password t)))
        !           153:       (progn (setq user (read-ftp-user-password host user (eq password t))
        !           154:                   password (cdr user)
        !           155:                   user (car user))))
        !           156:   (let ((buffer (get-buffer-create (format "*ftp %s:%s*" host file)))
        !           157:        (tmp (make-temp-name "/tmp/emacsftp")))
        !           158:     (write-region (point-min) (point-max) tmp)
        !           159:     (set-buffer buffer)
        !           160:     (make-local-variable 'ftp-temp-file-name)
        !           161:     (setq ftp-temp-file-name tmp)
        !           162:     (let ((process (ftp-setup-buffer host file))
        !           163:          (case-fold-search nil))
        !           164:       (let ((win nil))
        !           165:        (unwind-protect
        !           166:            (if (setq win (ftp-login process host user password))
        !           167:                (message "Logged in")
        !           168:                (error "Ftp login lost"))
        !           169:          (or win (delete-process process))))
        !           170:       (message "Opening file %s:%s..." host file)
        !           171:       (if (ftp-command process
        !           172:                       (format "send \"%s\" \"%s\"\nquit\n" tmp file)
        !           173:                       "150.*\n"
        !           174:                       "200.*\n")
        !           175:          (progn (forward-line 1)
        !           176:                 (let ((buffer-read-only nil))
        !           177:                   (delete-region (point-min) (point)))
        !           178:                 (message "Saving %s:%s in background.  Bye!" host file)
        !           179:                 (set-process-sentinel process
        !           180:                                       'ftp-asynchronous-output-sentinel)
        !           181:                 process)
        !           182:        (switch-to-buffer buffer)
        !           183:        (let ((buffer-read-only nil))
        !           184:          (insert-before-markers "<<<Ftp lost>>>"))
        !           185:        (delete-process process)
        !           186:        (error "Ftp write %s:%s lost" host file)))))
        !           187: 
        !           188: 
        !           189: (defun ftp-setup-buffer (host file)
        !           190:   (fundamental-mode)
        !           191:   (and (get-buffer-process (current-buffer))
        !           192:        (progn (discard-input)
        !           193:              (if (y-or-n-p (format "Kill process \"%s\" in %s? "
        !           194:                                    (process-name (get-buffer-process
        !           195:                                                    (current-buffer)))
        !           196:                                    (buffer-name (current-buffer))))
        !           197:                  (while (get-buffer-process (current-buffer))
        !           198:                    (kill-process (get-buffer-process (current-buffer))))
        !           199:                (error "Foo"))))
        !           200:   ;(buffer-flush-undo (current-buffer))
        !           201:   (setq buffer-read-only nil)
        !           202:   (erase-buffer)
        !           203:   (make-local-variable 'ftp-host)
        !           204:   (setq ftp-host host)
        !           205:   (make-local-variable 'ftp-file)
        !           206:   (setq ftp-file file)
        !           207:   (setq buffer-read-only t)
        !           208:   (start-process "ftp" (current-buffer) "ftp" "-i" "-n" "-g"))
        !           209: 
        !           210: 
        !           211: (defun ftp-login (process host user password)
        !           212:   (message "FTP logging in as %s@%s..." user host)
        !           213:   (if (ftp-command process
        !           214:                   (format "open %s\nuser %s %s\n" host user password)
        !           215:                   "230.*\n"
        !           216:                   "\\(Connected to \\|220\\|331\\).*\n")
        !           217:       t
        !           218:     (switch-to-buffer (process-buffer process))
        !           219:     (delete-process process)
        !           220:     (if (listp ftp-password-alist)
        !           221:        (setq ftp-password-alist (delq (assoc host ftp-password-alist)
        !           222:                                       ftp-password-alist)))
        !           223:     nil))
        !           224: 
        !           225: (defun ftp-command (process command win ignore)
        !           226:   (process-send-string process command)
        !           227:   (let ((p 1))
        !           228:     (while (numberp p)
        !           229:       (cond ;((not (bolp)))
        !           230:            ((looking-at win)
        !           231:             (goto-char (point-max))
        !           232:             (setq p t))
        !           233:            ((looking-at "^ftp> \\|^\n")
        !           234:             (goto-char (match-end 0)))
        !           235:            ((looking-at ignore)
        !           236:             (forward-line 1))
        !           237:            ((not (search-forward "\n" nil t))
        !           238:             ;; the way asynchronous process-output fucks with (point)
        !           239:             ;;  is really really disgusting.
        !           240:             (setq p (point))
        !           241:             (condition-case ()
        !           242:                 (accept-process-output process)
        !           243:               (error nil))
        !           244:             (goto-char p))
        !           245:            (t
        !           246:             (setq p nil))))
        !           247:     p))
        !           248: 
        !           249: 
        !           250: (defun ftp-asynchronous-input-sentinel (process msg)
        !           251:   (ftp-sentinel process msg t t))
        !           252: (defun ftp-synchronous-input-sentinel (process msg)
        !           253:   (ftp-sentinel process msg nil t))
        !           254: (defun ftp-asynchronous-output-sentinel (process msg)
        !           255:   (ftp-sentinel process msg t nil))
        !           256: (defun ftp-synchronous-output-sentinel (process msg)
        !           257:   (ftp-sentinel process msg nil nil))
        !           258: 
        !           259: (defun ftp-sentinel (process msg asynchronous input)
        !           260:   (cond ((null (buffer-name (process-buffer process)))
        !           261:         ;; deleted buffer
        !           262:         (set-process-buffer process nil))
        !           263:        ((and (eq (process-status process) 'exit)
        !           264:              (= (process-exit-status process) 0))
        !           265:         (save-excursion
        !           266:           (set-buffer (process-buffer process))
        !           267:           (let (msg
        !           268:                 (r (if input "[0-9]+ bytes received in [0-9]+\\.[0-9]+ seconds.*$" "[0-9]+ bytes sent in [0-9]+\\.[0-9]+ seconds.*$"))
        !           269:                 (buffer-read-only nil))
        !           270:             (goto-char (point-max))
        !           271:             (search-backward "226 ")
        !           272:             (if (looking-at r)
        !           273:                 (search-backward "226 "))
        !           274:             (let ((p (point)))
        !           275:               (setq msg (concat (format "ftp %s %s:%s done"
        !           276:                                         (if input "read" "write")
        !           277:                                         ftp-host ftp-file)
        !           278:                                 (if (re-search-forward r nil t)
        !           279:                                     (concat ": " (buffer-substring
        !           280:                                                    (match-beginning 0)
        !           281:                                                    (match-end 0)))
        !           282:                                     "")))
        !           283:               (delete-region p (point-max))
        !           284:               (save-excursion
        !           285:                 (set-buffer (get-buffer-create "*ftp log*"))
        !           286:                 (let ((buffer-read-only nil))
        !           287:                   (insert msg ?\n)))
        !           288:               (set-buffer-modified-p nil))
        !           289:             (if (not input)
        !           290:                 (progn
        !           291:                   (condition-case ()
        !           292:                       (and (boundp 'ftp-temp-file-name)
        !           293:                            ftp-temp-file-name
        !           294:                            (delete-file ftp-temp-file-name))
        !           295:                     (error nil))
        !           296:                   (kill-buffer (current-buffer)))
        !           297:               ;; You don't want to look at this.
        !           298:               (let ((kludge (generate-new-buffer (format "%s:%s (ftp)"
        !           299:                                                          ftp-host ftp-file))))
        !           300:                 (setq kludge (prog1 (buffer-name kludge) (kill-buffer kludge)))
        !           301:                 (rename-buffer kludge)
        !           302:                 ;; ok, you can look again now.
        !           303:                 (ftp-setup-write-file-hooks)))
        !           304:             (if (and asynchronous
        !           305:                      ;(waiting-for-user-input-p)
        !           306:                      )
        !           307:                 (progn (message "%s" msg)
        !           308:                        (sleep-for 2))))))
        !           309:        ((memq (process-status process) '(exit signal))
        !           310:         (save-excursion
        !           311:           (set-buffer (process-buffer process))
        !           312:           (setq msg (format "Ftp died (buffer %s): %s"
        !           313:                             (buffer-name (current-buffer))
        !           314:                             msg))
        !           315:           (let ((buffer-read-only nil))
        !           316:             (goto-char (point-max))
        !           317:             (insert ?\n ?\n msg))
        !           318:           (delete-process proc)
        !           319:           (set-buffer (get-buffer-create "*ftp log*"))
        !           320:           (let ((buffer-read-only nil))
        !           321:             (goto-char (point-max))
        !           322:             (insert msg))
        !           323:           (if (waiting-for-user-input-p)
        !           324:               (error "%s" msg))))))
        !           325: 
        !           326: (defun ftp-setup-write-file-hooks ()
        !           327:   (let ((hooks write-file-hooks))
        !           328:     (make-local-variable 'write-file-hooks)
        !           329:     (setq write-file-hooks (append write-file-hooks
        !           330:                                   '(ftp-write-file-hook))))
        !           331:   (make-local-variable 'revert-buffer-function)
        !           332:   (setq revert-buffer-function 'ftp-revert-buffer)
        !           333:   (setq default-directory "/tmp/")
        !           334:   (setq buffer-file-name (concat default-directory
        !           335:                                 (make-temp-name
        !           336:                                  (buffer-name (current-buffer)))))
        !           337:   (setq buffer-read-only nil))
        !           338: 
        !           339: (defun ftp-write-file-hook ()
        !           340:   (let ((process (ftp-write-file ftp-host ftp-file)))
        !           341:     (set-process-sentinel process 'ftp-synchronous-output-sentinel)
        !           342:     (message "FTP writing %s:%s..." ftp-host ftp-file)
        !           343:     (while (eq (process-status process) 'run)
        !           344:       (condition-case ()
        !           345:          (accept-process-output process)
        !           346:        (error nil)))
        !           347:     (and (eq (process-status process) 'exit)
        !           348:         (= (process-exit-status process) 0)
        !           349:         (set-buffer-modified-p nil)))
        !           350:   (message "Written")
        !           351:   t)
        !           352: 
        !           353: (defun ftp-revert-buffer (&rest ignore)
        !           354:   (let ((process (ftp-find-file ftp-host ftp-file)))
        !           355:     (set-process-sentinel process 'ftp-synchronous-input-sentinel)
        !           356:     (message "FTP reverting %s:%s" ftp-host ftp-file)
        !           357:     (while (eq (process-status process) 'run)
        !           358:       (condition-case ()
        !           359:          (accept-process-output process)
        !           360:        (error nil)))
        !           361:     (and (eq (process-status process) 'exit)
        !           362:         (= (process-exit-status process) 0)
        !           363:         (set-buffer-modified-p nil))
        !           364:     (message "Reverted")))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.