comparison lisp/eshell/esh-util.el @ 32446:aab90b31807c

Added better remote directory support to Eshell, as well as a few bug fixes. See the ChangeLog.
author John Wiegley <johnw@newartisans.com>
date Fri, 13 Oct 2000 09:02:39 +0000
parents 3099993cba0f
children b338a85bdffc
comparison
equal deleted inserted replaced
32445:05513a882886 32446:aab90b31807c
82 "*Regular expression used to match numeric arguments. 82 "*Regular expression used to match numeric arguments.
83 If `eshell-convert-numeric-arguments' is non-nil, and an argument 83 If `eshell-convert-numeric-arguments' is non-nil, and an argument
84 matches this regexp, it will be converted to a Lisp number, using the 84 matches this regexp, it will be converted to a Lisp number, using the
85 function `string-to-number'." 85 function `string-to-number'."
86 :type 'regexp 86 :type 'regexp
87 :group 'eshell-util)
88
89 (defcustom eshell-ange-ls-uids nil
90 "*List of user/host/id strings, used to determine remote ownership."
91 :type '(list (cons :tag "Host/User Pair"
92 (string :tag "Hostname")
93 (repeat (cons :tag "User/UID List"
94 (string :tag "Username")
95 (repeat :tag "UIDs" string)))))
87 :group 'eshell-util) 96 :group 'eshell-util)
88 97
89 ;;; Internal Variables: 98 ;;; Internal Variables:
90 99
91 (defvar eshell-group-names nil 100 (defvar eshell-group-names nil
556 string))) 565 string)))
557 566
558 (unless (fboundp 'directory-files-and-attributes) 567 (unless (fboundp 'directory-files-and-attributes)
559 (defun directory-files-and-attributes (dir &optional full match nosort) 568 (defun directory-files-and-attributes (dir &optional full match nosort)
560 (documentation 'directory-files) 569 (documentation 'directory-files)
561 (let* ((dir (expand-file-name dir)) 570 (let ((dir (expand-file-name dir)) ange-cache)
562 (default-directory dir))
563 (mapcar 571 (mapcar
564 (function 572 (function
565 (lambda (file) 573 (lambda (file)
566 (cons file (file-attributes file)))) 574 (cons file (eshell-file-attributes (expand-file-name file dir)))))
567 (directory-files dir full match nosort))))) 575 (directory-files dir full match nosort)))))
576
577 (eval-when-compile
578 (defvar ange-cache))
568 579
569 (defun eshell-directory-files-and-attributes (dir &optional full match nosort) 580 (defun eshell-directory-files-and-attributes (dir &optional full match nosort)
570 "Make sure to use the handler for `directory-file-and-attributes'." 581 "Make sure to use the handler for `directory-file-and-attributes'."
571 (let ((dfh (find-file-name-handler dir 'directory-files))) 582 (let* ((dir (expand-file-name dir))
583 (dfh (find-file-name-handler dir 'directory-files)))
572 (if (not dfh) 584 (if (not dfh)
573 (directory-files-and-attributes dir full match nosort) 585 (directory-files-and-attributes dir full match nosort)
574 (let* ((files (funcall dfh 'directory-files dir full match nosort)) 586 (let ((files (funcall dfh 'directory-files dir full match nosort))
575 (fah (find-file-name-handler dir 'file-attributes)) 587 (fah (find-file-name-handler dir 'file-attributes)))
576 (default-directory (expand-file-name dir)))
577 (mapcar 588 (mapcar
578 (function 589 (function
579 (lambda (file) 590 (lambda (file)
580 (cons file (funcall fah 'file-attributes file)))) 591 (cons file (if fah
592 (eshell-file-attributes
593 (expand-file-name file dir))
594 (file-attributes (expand-file-name file dir))))))
581 files))))) 595 files)))))
596
597 (defun eshell-current-ange-uids ()
598 (if (string-match "/\\([^@]+\\)@\\([^:]+\\):" default-directory)
599 (let* ((host (match-string 2 default-directory))
600 (user (match-string 1 default-directory))
601 (host-users (assoc host eshell-ange-ls-uids)))
602 (when host-users
603 (setq host-users (cdr host-users))
604 (cdr (assoc user host-users))))))
605
606 ;; Add an autoload for parse-time-string
607 (if (and (not (fboundp 'parse-time-string))
608 (locate-library "parse-time"))
609 (autoload 'parse-time-string "parse-time"))
610
611 (defun eshell-parse-ange-ls (dir)
612 (let (entry)
613 (with-temp-buffer
614 (insert (ange-ftp-ls dir "-la" nil))
615 (goto-char (point-min))
616 (if (looking-at "^total [0-9]+$")
617 (forward-line 1))
618 ;; Some systems put in a blank line here.
619 (if (eolp) (forward-line 1))
620 (while (looking-at
621 `,(concat "\\([dlscb-][rwxst-]+\\)"
622 "\\s-*" "\\([0-9]+\\)" "\\s-+"
623 "\\(\\S-+\\)" "\\s-+"
624 "\\(\\S-+\\)" "\\s-+"
625 "\\([0-9]+\\)" "\\s-+" "\\(.*\\)"))
626 (let* ((perms (match-string 1))
627 (links (string-to-number (match-string 2)))
628 (user (match-string 3))
629 (group (match-string 4))
630 (size (string-to-number (match-string 5)))
631 (mtime
632 (if (fboundp 'parse-time-string)
633 (let ((moment (parse-time-string
634 (match-string 6))))
635 (if (nth 0 moment)
636 (setcar (nthcdr 5 moment)
637 (nth 5 (decode-time (current-time))))
638 (setcar (nthcdr 0 moment) 0)
639 (setcar (nthcdr 1 moment) 0)
640 (setcar (nthcdr 2 moment) 0))
641 (apply 'encode-time moment))
642 (ange-ftp-file-modtime (expand-file-name name dir))))
643 (name (ange-ftp-parse-filename))
644 symlink)
645 (if (string-match "\\(.+\\) -> \\(.+\\)" name)
646 (setq symlink (match-string 2 name)
647 name (match-string 1 name)))
648 (setq entry
649 (cons
650 (cons name
651 (list (if (eq (aref perms 0) ?d)
652 t
653 symlink)
654 links user group
655 nil mtime nil
656 size perms nil nil)) entry)))
657 (forward-line)))
658 entry))
659
660 (defun eshell-file-attributes (file)
661 "Return the attributes of FILE, playing tricks if it's over ange-ftp."
662 (let* ((file (expand-file-name file))
663 (handler (find-file-name-handler file 'file-attributes))
664 entry)
665 (if (not handler)
666 (file-attributes file)
667 (if (eq (find-file-name-handler (file-name-directory file)
668 'directory-files)
669 'ange-ftp-hook-function)
670 (let ((base (file-name-nondirectory file))
671 (dir (file-name-directory file)))
672 (if (boundp 'ange-cache)
673 (setq entry (cdr (assoc base (cdr (assoc dir ange-cache))))))
674 (unless entry
675 (setq entry (eshell-parse-ange-ls dir))
676 (if (boundp 'ange-cache)
677 (setq ange-cache
678 (cons (cons dir entry)
679 ange-cache)))
680 (if entry
681 (let ((fentry (assoc base (cdr entry))))
682 (if fentry
683 (setq entry (cdr fentry))
684 (setq entry nil)))))))
685 (or entry (funcall handler 'file-attributes file)))))
582 686
583 (defun eshell-copy-list (list) 687 (defun eshell-copy-list (list)
584 "Return a copy of a list, which may be a dotted list. 688 "Return a copy of a list, which may be a dotted list.
585 The elements of the list are not copied, just the list structure itself." 689 The elements of the list are not copied, just the list structure itself."
586 (if (consp list) 690 (if (consp list)