viper -- Update and prettify package-info.in provides.
[packages] / xemacs-packages / efs / efs-ka9q.el
1 ;; -*-Emacs-Lisp-*-
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;
4 ;; File:         efs-ka9q.el
5 ;; Release:      $efs release: 1.24 $
6 ;; Version:      #Revision: 1.2 $
7 ;; RCS:          
8 ;; Description:  KA9Q support for efs
9 ;; Author:       Sandy Rutherford <sandy@tsmi19.sissa.it>
10 ;; Created:      Mon Dec 21 10:34:43 1992 by sandy on ibm550
11 ;; Modified:     Sun Nov 27 18:32:56 1994 by sandy on gandalf
12 ;;
13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
15 ;;; This file is part of efs. See efs.el for copyright
16 ;;; (it's copylefted) and warranty (there isn't one) information.
17
18 ;;; Thanks go to Joe Reinhardt for beta testing.
19
20 (provide 'efs-ka9q)
21 (require 'efs)
22
23 (defconst efs-ka9q-version
24   (concat (substring "$efs release: 1.24 $" 14 -2)
25           "/"
26           (substring "#Revision: 1.2 $" 11 -2)))
27
28 ;;;-----------------------------------------------------------------
29 ;;; KA9Q support for efs
30 ;;;-----------------------------------------------------------------
31 ;;;
32 ;;; KA9Q is not really an OS, but an ftp server that runs on PC's.
33 ;;; It runs under DOS and unix. Seems to have been adopted by LINUX.
34
35 ;; KA9Q uses unix syntax for paths, so don't need to bother with pathname
36 ;; converters. It always gives a listing, even if a file or dir doesn't
37 ;; exist. Therefore, we shall assume that empty dir = nonexistent dir. sigh...
38
39 (defconst efs-ka9q-date-regexp
40   " +[.,0-9]* [ 0-2][0-9]:[0-9][0-9] +[0-9]+/[0-9]+/[0-9]+")
41   ;; (match-beginning 0) should be the last char of the filename.
42
43 (defun efs-ka9q-bogus-listing (dir path)
44   ;; Check to see if a 1-line ka9q listing is bogus, and the directory
45   ;; is really just a file.
46   (and
47    (not (string-equal "/" dir))
48    (goto-char (point-min))
49    (looking-at (regexp-quote
50                 (concat (efs-internal-file-name-nondirectory
51                          (efs-internal-directory-file-name dir))
52                         " ")))
53    (forward-line 1)
54    (looking-at "1 file\\. ")
55    (string-match "^No files\\. "
56                  ;; ls switches don't matter
57                  (efs-ls (concat path "*") "-al" t t))))
58   
59 (efs-defun efs-parse-listing ka9q
60   (host user dir path &optional switches)
61   ;; Parse the current listing which is assumed to be a ka9q listing.
62   ;; Format is based on version 890421.1a.linux.7 (whatever that means).
63   ;; Note that ka9q uses two files per line.
64   ;; HOST = remote host name
65   ;; USER = remote user name
66   ;; DIR = directory as a remote full path
67   ;; PATH = directory in full efs-path syntax
68   (let ((tbl (efs-make-hashtable))
69         dir-p file)
70     (efs-save-match-data
71       (if (and
72            (progn
73              (goto-char (point-max))
74              (forward-line -1)
75              ;; Although "No files." may refer to an empty
76              ;; directory, it may also be a non-existent
77              ;; dir. Returning nil should force a listing
78              ;; of the parent, which will sort things out.
79              (looking-at "[0-9]+ files?\\. "))
80            ;; Check for a bogus listing.
81            (not (efs-ka9q-bogus-listing dir path)))
82           (progn
83             (goto-char (point-min))
84             (while (re-search-forward efs-ka9q-date-regexp nil t)
85               (goto-char (match-beginning 0))
86               (if (setq dir-p (eq (char-before (point)) ?/))
87                   (forward-char -1))
88               (setq file (buffer-substring (point)
89                                            (progn (skip-chars-backward "^ \n")
90                                                   (point))))
91               (efs-put-hash-entry file (list dir-p) tbl)
92               (goto-char (match-end 0)))
93             (efs-put-hash-entry "." '(t) tbl)
94             (efs-put-hash-entry ".." '(t) tbl)
95             tbl)))))
96
97 ;;; Tree Dired
98
99 (defconst efs-dired-ka9q-re-exe
100   "^. [^ \n\r./]+\\.exe ")
101
102 (or (assq 'ka9q efs-dired-re-exe-alist)
103     (setq efs-dired-re-exe-alist
104           (cons (cons 'ka9q  efs-dired-ka9q-re-exe)
105                 efs-dired-re-exe-alist)))
106
107 (defconst efs-dired-ka9q-re-dir
108   "^. [^ \n\r/]+/ ")
109
110 (or (assq 'ka9q efs-dired-re-dir-alist)
111     (setq efs-dired-re-dir-alist
112           (cons (cons 'ka9q  efs-dired-ka9q-re-dir)
113                 efs-dired-re-dir-alist)))
114
115 (efs-defun efs-dired-fixup-listing ka9q (file path &optional switches wildcard)
116   ;; ka9q puts two files per line. Need to put in one file per line format
117   ;; for dired.
118   (let ((regexp (concat efs-ka9q-date-regexp "   ")))
119     (goto-char (point-min))
120     (while (re-search-forward regexp nil t)
121       (delete-char -3)
122       (insert-char ?\n 1))
123     ;; is there a blank line left?
124     (if (looking-at "[ \t]*\n")
125         (delete-region (match-beginning 0) (match-end 0)))))
126
127 (efs-defun efs-dired-ls-trim ka9q ()
128   (goto-char (point-min))
129   (let ((case-fold-search nil))
130     (forward-line 1)
131     (if (looking-at "\\([0-9]+\\|No\\) files?\\. ")
132         (delete-region (point) (point-max)))))
133
134 (efs-defun efs-dired-insert-headerline ka9q (dir)
135   ;; Insert a headerline
136   (insert-char ?\n 1)
137   (forward-char -1)
138   (efs-real-dired-insert-headerline dir))
139
140 (efs-defun efs-dired-manual-move-to-filename ka9q
141   (&optional raise-error bol eol)
142   ;; In dired, move to the first char of filename on this line.
143   ;; Returns (point) or nil if raise-error is nil, and there is no
144   ;; no filename on this line.
145   ;; This is the KA9Q version.
146   (or eol (setq eol (save-excursion (skip-chars-forward "^\r\n") (point))))
147   (let (case-fold-search)
148     (if bol
149         (goto-char bol)
150       (skip-chars-backward "^\n\r")
151       (setq bol (point)))
152     (if (re-search-forward efs-ka9q-date-regexp eol t)
153         (progn
154           (goto-char (match-beginning 0))
155           (skip-chars-backward "^ " bol)
156           (point))
157       (and raise-error (error "No file on this line")))))
158
159 (efs-defun efs-dired-manual-move-to-end-of-filename ka9q
160   (&optional no-error bol eol)
161   ;; Assumes point is at the beginning of filename.
162   ;; So, it should be called only after (dired-move-to-filename t)
163   ;; On failure signals an error, or returns nil.
164   ;; This is the KA9Q version.
165   (let ((opoint (point)))
166     (and selective-display
167          (null no-error)
168          (eq (char-after
169               (1- (or bol (save-excursion
170                             (skip-chars-backward "^\r\n")
171                             (point)))))
172              ?\r)
173          ;; File is hidden or omitted.
174          (cond
175           ((dired-subdir-hidden-p (dired-current-directory))
176            (error
177             (substitute-command-keys
178              "File line is hidden. Type \\[dired-hide-subdir] to unhide.")))
179           ((error
180             (substitute-command-keys
181              "File line is omitted. Type \\[dired-omit-toggle] to un-omit."
182              )))))
183     (skip-chars-forward "^ \n\r/")
184     (if (or (= opoint (point)) (not (memq (char-after (point)) '(?/ ?\ ))))
185         (if no-error
186             nil
187           (error "No file on this line"))
188       (point))))
189
190 ;;; end of efs-ka9q.el