Mercurial > emacs
annotate lisp/url/url-file.el @ 98182:19ec1646fe6c
The Rmail/mbox merge has been abandoned in favor of a restart using
the current rmail.el file. A comprehensive list of changes will be
supplied when pmail.el is morphed back into rmail.el
The current status is that pmail.el supports basic Rmail navigation
(no summary support) and shows the current message in a special
buffer using buffer-swap-text. No decoding is done yet. That is the
next step.
author | Paul Reilly <pmr@pajato.com> |
---|---|
date | Mon, 15 Sep 2008 20:56:53 +0000 |
parents | 7369ded3b436 |
children | a9dc0e7c3f2b |
rev | line source |
---|---|
54695 | 1 ;;; url-file.el --- File retrieval code |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
2 |
64748
875dcc490074
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64084
diff
changeset
|
3 ;; Copyright (C) 1996, 1997, 1998, 1999, 2004, |
79720 | 4 ;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
5 |
54695 | 6 ;; Keywords: comm, data, processes |
7 | |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
8 ;; This file is part of GNU Emacs. |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
9 ;; |
94668
8259d0d8e107
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87649
diff
changeset
|
10 ;; GNU Emacs is free software: you can redistribute it and/or modify |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
11 ;; it under the terms of the GNU General Public License as published by |
94668
8259d0d8e107
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87649
diff
changeset
|
12 ;; the Free Software Foundation, either version 3 of the License, or |
8259d0d8e107
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87649
diff
changeset
|
13 ;; (at your option) any later version. |
8259d0d8e107
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87649
diff
changeset
|
14 |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
15 ;; GNU Emacs is distributed in the hope that it will be useful, |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
18 ;; GNU General Public License for more details. |
94668
8259d0d8e107
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87649
diff
changeset
|
19 |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
20 ;; You should have received a copy of the GNU General Public License |
94668
8259d0d8e107
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
87649
diff
changeset
|
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
22 |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
23 ;;; Commentary: |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
24 |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
25 ;;; Code: |
54695 | 26 |
27 (eval-when-compile (require 'cl)) | |
28 (require 'mailcap) | |
29 (require 'url-vars) | |
30 (require 'url-parse) | |
31 (require 'url-dired) | |
32 | |
33 (defconst url-file-default-port 21 "Default FTP port.") | |
34 (defconst url-file-asynchronous-p t "FTP transfers are asynchronous.") | |
35 (defalias 'url-file-expand-file-name 'url-default-expander) | |
36 | |
37 (defun url-file-find-possibly-compressed-file (fname &rest args) | |
38 "Find the exact file referenced by `fname'. | |
39 This tries the common compression extensions, because things like | |
40 ange-ftp and efs are not quite smart enough to realize when a server | |
41 can do automatic decompression for them, and won't find 'foo' if | |
96486
7369ded3b436
Typo and docstring fixes.
Juanma Barranquero <lekktu@gmail.com>
parents:
94668
diff
changeset
|
42 'foo.gz' exists, even though the FTP server would happily serve it up |
54695 | 43 to them." |
44 (let ((scratch nil) | |
45 (compressed-extensions '("" ".gz" ".z" ".Z" ".bz2")) | |
46 (found nil)) | |
47 (while (and compressed-extensions (not found)) | |
48 (if (file-exists-p (setq scratch (concat fname (pop compressed-extensions)))) | |
49 (setq found scratch))) | |
50 found)) | |
51 | |
52 (defun url-file-host-is-local-p (host) | |
78481
bc53aa750f3b
Replace `iff' in doc-strings and comments.
Glenn Morris <rgm@gnu.org>
parents:
78222
diff
changeset
|
53 "Return t if HOST references our local machine." |
54695 | 54 (let ((case-fold-search t)) |
55 (or | |
56 (null host) | |
57 (string= "" host) | |
58 (equal (downcase host) (downcase (system-name))) | |
59 (and (string-match "^localhost$" host) t) | |
60 (and (not (string-match (regexp-quote ".") host)) | |
61 (equal (downcase host) (if (string-match (regexp-quote ".") | |
62 (system-name)) | |
63 (substring (system-name) 0 | |
64 (match-beginning 0)) | |
65 (system-name))))))) | |
66 | |
67 (defun url-file-asynch-callback (x y name buff func args &optional efs) | |
68 (if (not (featurep 'ange-ftp)) | |
69 ;; EFS passes us an extra argument | |
70 (setq name buff | |
71 buff func | |
72 func args | |
73 args efs)) | |
74 (let ((size (nth 7 (file-attributes name)))) | |
63379
70cb4d2371b4
(url-file, url-file-asynch-callback): Use with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
57427
diff
changeset
|
75 (with-current-buffer buff |
54695 | 76 (goto-char (point-max)) |
77 (if (/= -1 size) | |
78 (insert (format "Content-length: %d\n" size))) | |
79 (insert "\n") | |
80 (insert-file-contents-literally name) | |
81 (if (not (url-file-host-is-local-p (url-host url-current-object))) | |
82 (condition-case () | |
83 (delete-file name) | |
84 (error nil))) | |
85 (apply func args)))) | |
86 | |
87104
ad4cfef6161e
Remove directory part from filenames in function declarations.
Glenn Morris <rgm@gnu.org>
parents:
86821
diff
changeset
|
87 (declare-function ange-ftp-set-passwd "ange-ftp" (host user passwd)) |
ad4cfef6161e
Remove directory part from filenames in function declarations.
Glenn Morris <rgm@gnu.org>
parents:
86821
diff
changeset
|
88 (declare-function ange-ftp-copy-file-internal "ange-ftp" |
86243
4d615a83cee2
* progmodes/idlw-help.el: Require browse-url unconditionally, it
Dan Nicolaescu <dann@ics.uci.edu>
parents:
83823
diff
changeset
|
89 (filename newname ok-if-already-exists |
4d615a83cee2
* progmodes/idlw-help.el: Require browse-url unconditionally, it
Dan Nicolaescu <dann@ics.uci.edu>
parents:
83823
diff
changeset
|
90 keep-date &optional msg cont nowait)) |
86265
22dc0bc9daf8
* frame.el (msdos-mouse-p):
Dan Nicolaescu <dann@ics.uci.edu>
parents:
86247
diff
changeset
|
91 (declare-function url-generate-unique-filename "url-util" (&optional fmt)) |
86243
4d615a83cee2
* progmodes/idlw-help.el: Require browse-url unconditionally, it
Dan Nicolaescu <dann@ics.uci.edu>
parents:
83823
diff
changeset
|
92 |
54695 | 93 (defun url-file-build-filename (url) |
94 (if (not (vectorp url)) | |
95 (setq url (url-generic-parse-url url))) | |
96 (let* ((user (url-user url)) | |
97 (pass (url-password url)) | |
98 (port (url-port url)) | |
99 (host (url-host url)) | |
100 (site (if (and port (/= port 21)) | |
101 (if (featurep 'ange-ftp) | |
102 (format "%s %d" host port) | |
103 ;; This works in Emacs 21's ange-ftp too. | |
104 (format "%s#%d" host port)) | |
105 host)) | |
106 (file (url-unhex-string (url-filename url))) | |
107 (filename (if (or user (not (url-file-host-is-local-p host))) | |
108 (concat "/" (or user "anonymous") "@" site ":" file) | |
109 (if (and (memq system-type | |
110 '(emx ms-dos windows-nt ms-windows)) | |
111 (string-match "^/[a-zA-Z]:/" file)) | |
112 (substring file 1) | |
113 file))) | |
114 pos-index) | |
115 | |
116 (and user pass | |
117 (cond | |
118 ((featurep 'ange-ftp) | |
119 (ange-ftp-set-passwd host user pass)) | |
86821
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
120 ((when (featurep 'xemacs) |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
121 (or (featurep 'efs) (featurep 'efs-auto) |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
122 (efs-set-passwd host user pass)))) |
54695 | 123 (t |
124 nil))) | |
125 | |
126 ;; This makes sure that directories have a trailing directory | |
127 ;; separator on them so URL expansion works right. | |
128 ;; | |
129 ;; FIXME? What happens if the remote system doesn't use our local | |
130 ;; directory-sep-char as its separator? Would it be safer to just | |
131 ;; use '/' unconditionally and rely on the FTP server to | |
132 ;; straighten it out for us? | |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
133 ;; (if (and (file-directory-p filename) |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
134 ;; (not (string-match (format "%c$" directory-sep-char) filename))) |
83823
dd2bcc6758a0
* url-parse.el (url): Use defstruct rather than macros. Update all callers.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
78481
diff
changeset
|
135 ;; (setf (url-filename url) |
dd2bcc6758a0
* url-parse.el (url): Use defstruct rather than macros. Update all callers.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
78481
diff
changeset
|
136 ;; (format "%s%c" filename directory-sep-char))) |
54695 | 137 (if (and (file-directory-p filename) |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
138 (not (string-match "/\\'" filename))) |
83823
dd2bcc6758a0
* url-parse.el (url): Use defstruct rather than macros. Update all callers.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
78481
diff
changeset
|
139 (setf (url-filename url) (format "%s/" filename))) |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
140 |
54695 | 141 |
142 ;; If it is a directory, look for an index file first. | |
143 (if (and (file-directory-p filename) | |
144 url-directory-index-file | |
145 (setq pos-index (expand-file-name url-directory-index-file filename)) | |
146 (file-exists-p pos-index) | |
147 (file-readable-p pos-index)) | |
148 (setq filename pos-index)) | |
149 | |
150 ;; Find the (possibly compressed) file | |
151 (setq filename (url-file-find-possibly-compressed-file filename)) | |
152 filename)) | |
153 | |
154 ;;;###autoload | |
155 (defun url-file (url callback cbargs) | |
156 "Handle file: and ftp: URLs." | |
157 (let* ((buffer nil) | |
158 (uncompressed-filename nil) | |
159 (content-type nil) | |
160 (content-encoding nil) | |
161 (coding-system-for-read 'binary)) | |
162 | |
163 (setq filename (url-file-build-filename url)) | |
164 | |
165 (if (not filename) | |
166 (error "File does not exist: %s" (url-recreate-url url))) | |
167 | |
168 ;; Need to figure out the content-type from the real extension, | |
169 ;; not the compressed one. | |
170 (setq uncompressed-filename (if (string-match "\\.\\(gz\\|Z\\|z\\)$" filename) | |
171 (substring filename 0 (match-beginning 0)) | |
172 filename)) | |
173 (setq content-type (mailcap-extension-to-mime | |
174 (url-file-extension uncompressed-filename)) | |
175 content-encoding (case (intern (url-file-extension filename)) | |
176 ((\.z \.gz) "gzip") | |
177 (\.Z "compress") | |
178 (\.uue "x-uuencoded") | |
179 (\.hqx "x-hqx") | |
180 (\.bz2 "x-bzip2") | |
181 (otherwise nil))) | |
182 | |
183 (if (file-directory-p filename) | |
184 ;; A directory is done the same whether we are local or remote | |
185 (url-find-file-dired filename) | |
63379
70cb4d2371b4
(url-file, url-file-asynch-callback): Use with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
57427
diff
changeset
|
186 (with-current-buffer |
70cb4d2371b4
(url-file, url-file-asynch-callback): Use with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
57427
diff
changeset
|
187 (setq buffer (generate-new-buffer " *url-file*")) |
54695 | 188 (mm-disable-multibyte) |
189 (setq url-current-object url) | |
190 (insert "Content-type: " (or content-type "application/octet-stream") "\n") | |
191 (if content-encoding | |
192 (insert "Content-transfer-encoding: " content-encoding "\n")) | |
193 (if (url-file-host-is-local-p (url-host url)) | |
194 ;; Local files are handled slightly oddly | |
195 (if (featurep 'ange-ftp) | |
196 (url-file-asynch-callback nil nil | |
197 filename | |
198 (current-buffer) | |
199 callback cbargs) | |
200 (url-file-asynch-callback nil nil nil | |
201 filename | |
202 (current-buffer) | |
203 callback cbargs)) | |
204 ;; FTP handling | |
205 (let* ((extension (url-file-extension filename)) | |
206 (new (url-generate-unique-filename | |
207 (and (> (length extension) 0) | |
208 (concat "%s." extension))))) | |
209 (if (featurep 'ange-ftp) | |
210 (ange-ftp-copy-file-internal filename (expand-file-name new) t | |
211 nil t | |
212 (list 'url-file-asynch-callback | |
213 new (current-buffer) | |
214 callback cbargs) | |
215 t) | |
86821
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
216 (when (featurep 'xemacs) |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
217 (autoload 'efs-copy-file-internal "efs") |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
218 (efs-copy-file-internal filename (efs-ftp-path filename) |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
219 new (efs-ftp-path new) |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
220 t nil 0 |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
221 (list 'url-file-asynch-callback |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
222 new (current-buffer) |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
223 callback cbargs) |
7193e8ecbb2e
(url-file-build-filename, url-file): Wrap uses of
Glenn Morris <rgm@gnu.org>
parents:
86265
diff
changeset
|
224 0 nil))))))) |
54695 | 225 buffer)) |
226 | |
227 (defmacro url-file-create-wrapper (method args) | |
54930
ca220b74ea4b
(url-file-create-wrapper): Use new backquote syntax.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54796
diff
changeset
|
228 `(defalias ',(intern (format "url-ftp-%s" method)) |
ca220b74ea4b
(url-file-create-wrapper): Use new backquote syntax.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54796
diff
changeset
|
229 (defun ,(intern (format "url-file-%s" method)) ,args |
ca220b74ea4b
(url-file-create-wrapper): Use new backquote syntax.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54796
diff
changeset
|
230 ,(format "FTP/FILE URL wrapper around `%s' call." method) |
ca220b74ea4b
(url-file-create-wrapper): Use new backquote syntax.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54796
diff
changeset
|
231 (setq url (url-file-build-filename url)) |
ca220b74ea4b
(url-file-create-wrapper): Use new backquote syntax.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54796
diff
changeset
|
232 (and url (,method ,@(remove '&rest (remove '&optional args))))))) |
54695 | 233 |
234 (url-file-create-wrapper file-exists-p (url)) | |
54930
ca220b74ea4b
(url-file-create-wrapper): Use new backquote syntax.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54796
diff
changeset
|
235 (url-file-create-wrapper file-attributes (url &optional id-format)) |
54695 | 236 (url-file-create-wrapper file-symlink-p (url)) |
237 (url-file-create-wrapper file-readable-p (url)) | |
238 (url-file-create-wrapper file-writable-p (url)) | |
239 (url-file-create-wrapper file-executable-p (url)) | |
66225 | 240 (url-file-create-wrapper directory-files (url &optional full match nosort)) |
241 (url-file-create-wrapper file-truename (url &optional counter prev-dirs)) | |
54695 | 242 |
243 (provide 'url-file) | |
54699 | 244 |
54796
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
245 ;; arch-tag: 010e914a-7313-494b-8a8c-6495a862157d |
351fde140ac4
(url-file-build-filename): Don't use directory-sep-char.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
54770
diff
changeset
|
246 ;;; url-file.el ends here |