aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/url
diff options
context:
space:
mode:
authorMiles Bader2004-10-14 08:50:09 +0000
committerMiles Bader2004-10-14 08:50:09 +0000
commit91900dd736dc0ab57a38da1fa9daa5ddde487bfb (patch)
treef592b350cad8a3a6bd196722bb553469c5781c1a /lisp/url
parent2beba76dd5f6e3f1fcf9cba8b66e465ae9e20519 (diff)
parentebbeed623cb9902e520fc67d6d271e222e16867f (diff)
downloademacs-91900dd736dc0ab57a38da1fa9daa5ddde487bfb.tar.gz
emacs-91900dd736dc0ab57a38da1fa9daa5ddde487bfb.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-57
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-594 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-598 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-599 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-600 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-602 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-603 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-604 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-609 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-610 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-611 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-614 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-615 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-42 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-43 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-44 - miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-46 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-47 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-48 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-49 Add {arch}/=commit-merge-make-log * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-50 {arch}/=commit-merge-make-log: Don't die if there are no ChangeLog changes
Diffstat (limited to 'lisp/url')
-rw-r--r--lisp/url/ChangeLog61
-rw-r--r--lisp/url/url-auth.el316
-rw-r--r--lisp/url/url-cache.el202
-rw-r--r--lisp/url/url-cookie.el466
-rw-r--r--lisp/url/url-dired.el100
-rw-r--r--lisp/url/url-file.el1
-rw-r--r--lisp/url/url-ftp.el42
-rw-r--r--lisp/url/url-gw.el268
-rw-r--r--lisp/url/url-handlers.el3
-rw-r--r--lisp/url/url-history.el199
-rw-r--r--lisp/url/url-https.el14
-rw-r--r--lisp/url/url-irc.el76
-rw-r--r--lisp/url/url-ldap.el240
-rw-r--r--lisp/url/url-mailto.el131
-rw-r--r--lisp/url/url-methods.el150
-rw-r--r--lisp/url/url-misc.el117
-rw-r--r--lisp/url/url-news.el135
-rw-r--r--lisp/url/url-nfs.el3
-rw-r--r--lisp/url/url-parse.el210
-rw-r--r--lisp/url/url-privacy.el81
-rw-r--r--lisp/url/url-util.el3
-rw-r--r--lisp/url/url-vars.el431
-rw-r--r--lisp/url/url.el269
23 files changed, 3504 insertions, 14 deletions
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index 69851ac5046..91a6c869a21 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,64 @@
12004-10-12 Simon Josefsson <jas@extundo.com>
2
3 * url-vars.el (url-gateway-method): Add new method `tls'.
4
5 * url-news.el (url-snews): Use nntp-open-tls-stream if
6 url-gateway-method is tls.
7
8 * url-ldap.el (url-ldap-certificate-formatter): Use
9 tls-certificate-information if ssl.el is not available.
10
11 * url-https.el (url-https-create-secure-wrapper): Use tls if ssl
12 is not available.
13
14 * url-gw.el (url-open-stream): Support tls url-gateway-method.
15 (url-open-stream): Likewise.
16
172004-10-10 Lars Hansen <larsh@math.ku.dk>
18
19 * url-auth.el: Fix copyright notice.
20
21 * url-cache.el: Fix copyright notice.
22
23 * url-cookie.el: Fix copyright notice.
24
25 * url-dired.el: Fix copyright notice.
26
27 * url-file.el: Fix copyright notice.
28
29 * url-ftp.el: Fix copyright notice.
30
31 * url-handlers.el: Fix copyright notice.
32
33 * url-history.el: Fix copyright notice.
34
35 * url-irc.el: Fix copyright notice.
36
37 * url-mailto.el: Fix copyright notice.
38
39 * url-methods.el: Fix copyright notice.
40
41 * url-misc.el: Fix copyright notice.
42
43 * url-news.el: Fix copyright notice.
44
45 * url-nfs.el: Fix copyright notice.
46
47 * url-parse.el: Fix copyright notice.
48
49 * url-privacy.el: Fix copyright notice.
50
51 * url-vars.el: Fix copyright notice.
52
53 * url.el: Fix copyright notice.
54
55 * url-util.el: Fix copyright notice.
56
572004-10-06 Stefan Monnier <monnier@iro.umontreal.ca>
58
59 * url-handlers.el (url-insert-file-contents): Use the URL to decide the
60 encoding, not the buffer-file-name (which might not even exist).
61
12004-09-20 Stefan Monnier <monnier@iro.umontreal.ca> 622004-09-20 Stefan Monnier <monnier@iro.umontreal.ca>
2 63
3 * url-handlers.el (url-insert-file-contents): Decode contents. 64 * url-handlers.el (url-insert-file-contents): Decode contents.
diff --git a/lisp/url/url-auth.el b/lisp/url/url-auth.el
new file mode 100644
index 00000000000..39bb730bebc
--- /dev/null
+++ b/lisp/url/url-auth.el
@@ -0,0 +1,316 @@
1;;; url-auth.el --- Uniform Resource Locator authorization modules
2;; Keywords: comm, data, processes, hypermedia
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
25(require 'url-vars)
26(require 'url-parse)
27(autoload 'url-warn "url")
28
29(defsubst url-auth-user-prompt (url realm)
30 "String to usefully prompt for a username."
31 (concat "Username [for "
32 (or realm (url-truncate-url-for-viewing
33 (url-recreate-url url)
34 (- (window-width) 10 20)))
35 "]: "))
36
37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38;;; Basic authorization code
39;;; ------------------------
40;;; This implements the BASIC authorization type. See the online
41;;; documentation at
42;;; http://www.w3.org/hypertext/WWW/AccessAuthorization/Basic.html
43;;; for the complete documentation on this type.
44;;;
45;;; This is very insecure, but it works as a proof-of-concept
46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47(defvar url-basic-auth-storage 'url-http-real-basic-auth-storage
48 "Where usernames and passwords are stored.
49
50Must be a symbol pointing to another variable that will actually store
51the information. The value of this variable is an assoc list of assoc
52lists. The first assoc list is keyed by the server name. The cdr of
53this is an assoc list based on the 'directory' specified by the url we
54are looking up.")
55
56(defun url-basic-auth (url &optional prompt overwrite realm args)
57 "Get the username/password for the specified URL.
58If optional argument PROMPT is non-nil, ask for the username/password
59to use for the url and its descendants. If optional third argument
60OVERWRITE is non-nil, overwrite the old username/password pair if it
61is found in the assoc list. If REALM is specified, use that as the realm
62instead of the pathname inheritance method."
63 (let* ((href (if (stringp url)
64 (url-generic-parse-url url)
65 url))
66 (server (url-host href))
67 (port (url-port href))
68 (path (url-filename href))
69 user pass byserv retval data)
70 (setq server (format "%s:%d" server port)
71 path (cond
72 (realm realm)
73 ((string-match "/$" path) path)
74 (t (url-basepath path)))
75 byserv (cdr-safe (assoc server
76 (symbol-value url-basic-auth-storage))))
77 (cond
78 ((and prompt (not byserv))
79 (setq user (read-string (url-auth-user-prompt url realm)
80 (user-real-login-name))
81 pass (funcall url-passwd-entry-func "Password: "))
82 (set url-basic-auth-storage
83 (cons (list server
84 (cons path
85 (setq retval
86 (base64-encode-string
87 (format "%s:%s" user pass)))))
88 (symbol-value url-basic-auth-storage))))
89 (byserv
90 (setq retval (cdr-safe (assoc path byserv)))
91 (if (and (not retval)
92 (string-match "/" path))
93 (while (and byserv (not retval))
94 (setq data (car (car byserv)))
95 (if (or (not (string-match "/" data)) ; Its a realm - take it!
96 (and
97 (>= (length path) (length data))
98 (string= data (substring path 0 (length data)))))
99 (setq retval (cdr (car byserv))))
100 (setq byserv (cdr byserv))))
101 (if (or (and (not retval) prompt) overwrite)
102 (progn
103 (setq user (read-string (url-auth-user-prompt url realm)
104 (user-real-login-name))
105 pass (funcall url-passwd-entry-func "Password: ")
106 retval (base64-encode-string (format "%s:%s" user pass))
107 byserv (assoc server (symbol-value url-basic-auth-storage)))
108 (setcdr byserv
109 (cons (cons path retval) (cdr byserv))))))
110 (t (setq retval nil)))
111 (if retval (setq retval (concat "Basic " retval)))
112 retval))
113
114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
115;;; Digest authorization code
116;;; ------------------------
117;;; This implements the DIGEST authorization type. See the internet draft
118;;; ftp://ds.internic.net/internet-drafts/draft-ietf-http-digest-aa-01.txt
119;;; for the complete documentation on this type.
120;;;
121;;; This is very secure
122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
123(defvar url-digest-auth-storage nil
124 "Where usernames and passwords are stored. Its value is an assoc list of
125assoc lists. The first assoc list is keyed by the server name. The cdr of
126this is an assoc list based on the 'directory' specified by the url we are
127looking up.")
128
129(defun url-digest-auth-create-key (username password realm method uri)
130 "Create a key for digest authentication method"
131 (let* ((info (if (stringp uri)
132 (url-generic-parse-url uri)
133 uri))
134 (a1 (md5 (concat username ":" realm ":" password)))
135 (a2 (md5 (concat method ":" (url-filename info)))))
136 (list a1 a2)))
137
138(defun url-digest-auth (url &optional prompt overwrite realm args)
139 "Get the username/password for the specified URL.
140If optional argument PROMPT is non-nil, ask for the username/password
141to use for the url and its descendants. If optional third argument
142OVERWRITE is non-nil, overwrite the old username/password pair if it
143is found in the assoc list. If REALM is specified, use that as the realm
144instead of hostname:portnum."
145 (if args
146 (let* ((href (if (stringp url)
147 (url-generic-parse-url url)
148 url))
149 (server (url-host href))
150 (port (url-port href))
151 (path (url-filename href))
152 user pass byserv retval data)
153 (setq path (cond
154 (realm realm)
155 ((string-match "/$" path) path)
156 (t (url-basepath path)))
157 server (format "%s:%d" server port)
158 byserv (cdr-safe (assoc server url-digest-auth-storage)))
159 (cond
160 ((and prompt (not byserv))
161 (setq user (read-string (url-auth-user-prompt url realm)
162 (user-real-login-name))
163 pass (funcall url-passwd-entry-func "Password: ")
164 url-digest-auth-storage
165 (cons (list server
166 (cons path
167 (setq retval
168 (cons user
169 (url-digest-auth-create-key
170 user pass realm
171 (or url-request-method "GET")
172 url)))))
173 url-digest-auth-storage)))
174 (byserv
175 (setq retval (cdr-safe (assoc path byserv)))
176 (if (and (not retval) ; no exact match, check directories
177 (string-match "/" path)) ; not looking for a realm
178 (while (and byserv (not retval))
179 (setq data (car (car byserv)))
180 (if (or (not (string-match "/" data))
181 (and
182 (>= (length path) (length data))
183 (string= data (substring path 0 (length data)))))
184 (setq retval (cdr (car byserv))))
185 (setq byserv (cdr byserv))))
186 (if (or (and (not retval) prompt) overwrite)
187 (progn
188 (setq user (read-string (url-auth-user-prompt url realm)
189 (user-real-login-name))
190 pass (funcall url-passwd-entry-func "Password: ")
191 retval (setq retval
192 (cons user
193 (url-digest-auth-create-key
194 user pass realm
195 (or url-request-method "GET")
196 url)))
197 byserv (assoc server url-digest-auth-storage))
198 (setcdr byserv
199 (cons (cons path retval) (cdr byserv))))))
200 (t (setq retval nil)))
201 (if retval
202 (let ((nonce (or (cdr-safe (assoc "nonce" args)) "nonegiven"))
203 (opaque (or (cdr-safe (assoc "opaque" args)) "nonegiven")))
204 (format
205 (concat "Digest username=\"%s\", realm=\"%s\","
206 "nonce=\"%s\", uri=\"%s\","
207 "response=\"%s\", opaque=\"%s\"")
208 (nth 0 retval) realm nonce (url-filename href)
209 (md5 (concat (nth 1 retval) ":" nonce ":"
210 (nth 2 retval))) opaque))))))
211
212(defvar url-registered-auth-schemes nil
213 "A list of the registered authorization schemes and various and sundry
214information associated with them.")
215
216;;;###autoload
217(defun url-get-authentication (url realm type prompt &optional args)
218 "Return an authorization string suitable for use in the WWW-Authenticate
219header in an HTTP/1.0 request.
220
221URL is the url you are requesting authorization to. This can be either a
222 string representing the URL, or the parsed representation returned by
223 `url-generic-parse-url'
224REALM is the realm at a specific site we are looking for. This should be a
225 string specifying the exact realm, or nil or the symbol 'any' to
226 specify that the filename portion of the URL should be used as the
227 realm
228TYPE is the type of authentication to be returned. This is either a string
229 representing the type (basic, digest, etc), or nil or the symbol 'any'
230 to specify that any authentication is acceptable. If requesting 'any'
231 the strongest matching authentication will be returned. If this is
232 wrong, its no big deal, the error from the server will specify exactly
233 what type of auth to use
234PROMPT is boolean - specifies whether to ask the user for a username/password
235 if one cannot be found in the cache"
236 (if (not realm)
237 (setq realm (cdr-safe (assoc "realm" args))))
238 (if (stringp url)
239 (setq url (url-generic-parse-url url)))
240 (if (or (null type) (eq type 'any))
241 ;; Whooo doogies!
242 ;; Go through and get _all_ the authorization strings that could apply
243 ;; to this URL, store them along with the 'rating' we have in the list
244 ;; of schemes, then sort them so that the 'best' is at the front of the
245 ;; list, then get the car, then get the cdr.
246 ;; Zooom zooom zoooooom
247 (cdr-safe
248 (car-safe
249 (sort
250 (mapcar
251 (function
252 (lambda (scheme)
253 (if (fboundp (car (cdr scheme)))
254 (cons (cdr (cdr scheme))
255 (funcall (car (cdr scheme)) url nil nil realm))
256 (cons 0 nil))))
257 url-registered-auth-schemes)
258 (function
259 (lambda (x y)
260 (cond
261 ((null (cdr x)) nil)
262 ((and (cdr x) (null (cdr y))) t)
263 ((and (cdr x) (cdr y))
264 (>= (car x) (car y)))
265 (t nil)))))))
266 (if (symbolp type) (setq type (symbol-name type)))
267 (let* ((scheme (car-safe
268 (cdr-safe (assoc (downcase type)
269 url-registered-auth-schemes)))))
270 (if (and scheme (fboundp scheme))
271 (funcall scheme url prompt
272 (and prompt
273 (funcall scheme url nil nil realm args))
274 realm args)))))
275
276;;;###autoload
277(defun url-register-auth-scheme (type &optional function rating)
278 "Register an HTTP authentication method.
279
280TYPE is a string or symbol specifying the name of the method. This
281 should be the same thing you expect to get returned in an Authenticate
282 header in HTTP/1.0 - it will be downcased.
283FUNCTION is the function to call to get the authorization information. This
284 defaults to `url-?-auth', where ? is TYPE
285RATING a rating between 1 and 10 of the strength of the authentication.
286 This is used when asking for the best authentication for a specific
287 URL. The item with the highest rating is returned."
288 (let* ((type (cond
289 ((stringp type) (downcase type))
290 ((symbolp type) (downcase (symbol-name type)))
291 (t (error "Bad call to `url-register-auth-scheme'"))))
292 (function (or function (intern (concat "url-" type "-auth"))))
293 (rating (cond
294 ((null rating) 2)
295 ((stringp rating) (string-to-int rating))
296 (t rating)))
297 (node (assoc type url-registered-auth-schemes)))
298 (if (not (fboundp function))
299 (url-warn 'security
300 (format (concat
301 "Tried to register `%s' as an auth scheme"
302 ", but it is not a function!") function)))
303
304 (if node
305 (setcdr node (cons function rating))
306 (setq url-registered-auth-schemes
307 (cons (cons type (cons function rating))
308 url-registered-auth-schemes)))))
309
310(defun url-auth-registered (scheme)
311 ;; Return non-nil iff SCHEME is registered as an auth type
312 (assoc scheme url-registered-auth-schemes))
313
314(provide 'url-auth)
315
316;;; arch-tag: 04058625-616d-44e4-9dbf-4b46b00b2a91
diff --git a/lisp/url/url-cache.el b/lisp/url/url-cache.el
new file mode 100644
index 00000000000..1e3374639e1
--- /dev/null
+++ b/lisp/url/url-cache.el
@@ -0,0 +1,202 @@
1;;; url-cache.el --- Uniform Resource Locator retrieval tool
2;; Keywords: comm, data, processes, hypermedia
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24(require 'url-parse)
25(require 'url-util)
26
27(defcustom url-cache-directory
28 (expand-file-name "cache" url-configuration-directory)
29 "*The directory where cache files should be stored."
30 :type 'directory
31 :group 'url-file)
32
33;; Cache manager
34(defun url-cache-file-writable-p (file)
35 "Follows the documentation of `file-writable-p', unlike `file-writable-p'."
36 (and (file-writable-p file)
37 (if (file-exists-p file)
38 (not (file-directory-p file))
39 (file-directory-p (file-name-directory file)))))
40
41(defun url-cache-prepare (file)
42 "Makes it possible to cache data in FILE.
43Creates any necessary parent directories, deleting any non-directory files
44that would stop this. Returns nil if parent directories can not be
45created. If FILE already exists as a non-directory, it changes
46permissions of FILE or deletes FILE to make it possible to write a new
47version of FILE. Returns nil if this can not be done. Returns nil if
48FILE already exists as a directory. Otherwise, returns t, indicating that
49FILE can be created or overwritten."
50 (cond
51 ((url-cache-file-writable-p file)
52 t)
53 ((file-directory-p file)
54 nil)
55 (t
56 (condition-case ()
57 (or (make-directory (file-name-directory file) t) t)
58 (error nil)))))
59
60;;;###autoload
61(defun url-store-in-cache (&optional buff)
62 "Store buffer BUFF in the cache."
63 (if (not (and buff (get-buffer buff)))
64 nil
65 (save-excursion
66 (and buff (set-buffer buff))
67 (let* ((fname (url-cache-create-filename (url-view-url t))))
68 (if (url-cache-prepare fname)
69 (let ((coding-system-for-write 'binary))
70 (write-region (point-min) (point-max) fname nil 5)))))))
71
72;;;###autoload
73(defun url-is-cached (url)
74 "Return non-nil if the URL is cached."
75 (let* ((fname (url-cache-create-filename url))
76 (attribs (file-attributes fname)))
77 (and fname ; got a filename
78 (file-exists-p fname) ; file exists
79 (not (eq (nth 0 attribs) t)) ; Its not a directory
80 (nth 5 attribs)))) ; Can get last mod-time
81
82(defun url-cache-create-filename-human-readable (url)
83 "Return a filename in the local cache for URL"
84 (if url
85 (let* ((url (if (vectorp url) (url-recreate-url url) url))
86 (urlobj (url-generic-parse-url url))
87 (protocol (url-type urlobj))
88 (hostname (url-host urlobj))
89 (host-components
90 (cons
91 (user-real-login-name)
92 (cons (or protocol "file")
93 (reverse (split-string (or hostname "localhost")
94 (eval-when-compile
95 (regexp-quote ".")))))))
96 (fname (url-filename urlobj)))
97 (if (and fname (/= (length fname) 0) (= (aref fname 0) ?/))
98 (setq fname (substring fname 1 nil)))
99 (if fname
100 (let ((slash nil))
101 (setq fname
102 (mapconcat
103 (function
104 (lambda (x)
105 (cond
106 ((and (= ?/ x) slash)
107 (setq slash nil)
108 "%2F")
109 ((= ?/ x)
110 (setq slash t)
111 "/")
112 (t
113 (setq slash nil)
114 (char-to-string x))))) fname ""))))
115
116 (setq fname (and fname
117 (mapconcat
118 (function (lambda (x)
119 (if (= x ?~) "" (char-to-string x))))
120 fname ""))
121 fname (cond
122 ((null fname) nil)
123 ((or (string= "" fname) (string= "/" fname))
124 url-directory-index-file)
125 ((= (string-to-char fname) ?/)
126 (if (string= (substring fname -1 nil) "/")
127 (concat fname url-directory-index-file)
128 (substring fname 1 nil)))
129 (t
130 (if (string= (substring fname -1 nil) "/")
131 (concat fname url-directory-index-file)
132 fname))))
133 (and fname
134 (expand-file-name fname
135 (expand-file-name
136 (mapconcat 'identity host-components "/")
137 url-cache-directory))))))
138
139(defun url-cache-create-filename-using-md5 (url)
140 "Create a cached filename using MD5.
141Very fast if you have an `md5' primitive function, suitably fast otherwise."
142 (require 'md5)
143 (if url
144 (let* ((url (if (vectorp url) (url-recreate-url url) url))
145 (checksum (md5 url))
146 (urlobj (url-generic-parse-url url))
147 (protocol (url-type urlobj))
148 (hostname (url-host urlobj))
149 (host-components
150 (cons
151 (user-real-login-name)
152 (cons (or protocol "file")
153 (nreverse
154 (delq nil
155 (split-string (or hostname "localhost")
156 (eval-when-compile
157 (regexp-quote "."))))))))
158 (fname (url-filename urlobj)))
159 (and fname
160 (expand-file-name checksum
161 (expand-file-name
162 (mapconcat 'identity host-components "/")
163 url-cache-directory))))))
164
165(defcustom url-cache-creation-function 'url-cache-create-filename-using-md5
166 "*What function to use to create a cached filename."
167 :type '(choice (const :tag "MD5 of filename (low collision rate)"
168 :value url-cache-create-filename-using-md5)
169 (const :tag "Human readable filenames (higher collision rate)"
170 :value url-cache-create-filename-human-readable)
171 (function :tag "Other"))
172 :group 'url-cache)
173
174(defun url-cache-create-filename (url)
175 (funcall url-cache-creation-function url))
176
177;;;###autoload
178(defun url-cache-extract (fnam)
179 "Extract FNAM from the local disk cache"
180 (erase-buffer)
181 (insert-file-contents-literally fnam))
182
183;;;###autoload
184(defun url-cache-expired (url mod)
185 "Return t iff a cached file has expired."
186 (let* ((urlobj (if (vectorp url) url (url-generic-parse-url url)))
187 (type (url-type urlobj)))
188 (cond
189 (url-standalone-mode
190 (not (file-exists-p (url-cache-create-filename url))))
191 ((string= type "http")
192 t)
193 ((member type '("file" "ftp"))
194 (if (or (equal mod '(0 0)) (not mod))
195 t
196 (or (> (nth 0 mod) (nth 0 (current-time)))
197 (> (nth 1 mod) (nth 1 (current-time))))))
198 (t nil))))
199
200(provide 'url-cache)
201
202;;; arch-tag: 95b050a6-8e81-4f23-8e63-191b9d1d657c
diff --git a/lisp/url/url-cookie.el b/lisp/url/url-cookie.el
new file mode 100644
index 00000000000..9f7db867597
--- /dev/null
+++ b/lisp/url/url-cookie.el
@@ -0,0 +1,466 @@
1;;; url-cookie.el --- Netscape Cookie support
2
3;; Copyright (c) 1996 - 1999,2004 Free Software Foundation, Inc.
4
5;; Keywords: comm, data, processes, hypermedia
6
7;; This file is part of GNU Emacs.
8;;
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
23
24;;; Commentary:
25
26;;; Code:
27
28(require 'timezone)
29(require 'url-util)
30(require 'url-parse)
31(eval-when-compile (require 'cl))
32
33;; See http://home.netscape.com/newsref/std/cookie_spec.html for the
34;; 'open standard' defining this crap.
35;;
36;; A cookie is stored internally as a vector of 7 slots
37;; [ 'cookie name value expires path domain secure ]
38
39(defsubst url-cookie-name (cookie) (aref cookie 1))
40(defsubst url-cookie-value (cookie) (aref cookie 2))
41(defsubst url-cookie-expires (cookie) (aref cookie 3))
42(defsubst url-cookie-path (cookie) (aref cookie 4))
43(defsubst url-cookie-domain (cookie) (aref cookie 5))
44(defsubst url-cookie-secure (cookie) (aref cookie 6))
45
46(defsubst url-cookie-set-name (cookie val) (aset cookie 1 val))
47(defsubst url-cookie-set-value (cookie val) (aset cookie 2 val))
48(defsubst url-cookie-set-expires (cookie val) (aset cookie 3 val))
49(defsubst url-cookie-set-path (cookie val) (aset cookie 4 val))
50(defsubst url-cookie-set-domain (cookie val) (aset cookie 5 val))
51(defsubst url-cookie-set-secure (cookie val) (aset cookie 6 val))
52(defsubst url-cookie-retrieve-arg (key args) (nth 1 (memq key args)))
53
54(defsubst url-cookie-create (&rest args)
55 (let ((retval (make-vector 7 nil)))
56 (aset retval 0 'cookie)
57 (url-cookie-set-name retval (url-cookie-retrieve-arg :name args))
58 (url-cookie-set-value retval (url-cookie-retrieve-arg :value args))
59 (url-cookie-set-expires retval (url-cookie-retrieve-arg :expires args))
60 (url-cookie-set-path retval (url-cookie-retrieve-arg :path args))
61 (url-cookie-set-domain retval (url-cookie-retrieve-arg :domain args))
62 (url-cookie-set-secure retval (url-cookie-retrieve-arg :secure args))
63 retval))
64
65(defun url-cookie-p (obj)
66 (and (vectorp obj) (= (length obj) 7) (eq (aref obj 0) 'cookie)))
67
68(defgroup url-cookie nil
69 "URL cookies"
70 :prefix "url-"
71 :prefix "url-cookie-"
72 :group 'url)
73
74(defvar url-cookie-storage nil "Where cookies are stored.")
75(defvar url-cookie-secure-storage nil "Where secure cookies are stored.")
76(defcustom url-cookie-file nil "*Where cookies are stored on disk."
77 :type '(choice (const :tag "Default" :value nil) file)
78 :group 'url-file
79 :group 'url-cookie)
80
81(defcustom url-cookie-confirmation nil
82 "*If non-nil, confirmation by the user is required to accept HTTP cookies."
83 :type 'boolean
84 :group 'url-cookie)
85
86(defcustom url-cookie-multiple-line nil
87 "*If nil, HTTP requests put all cookies for the server on one line.
88Some web servers, such as http://www.hotmail.com/, only accept cookies
89when they are on one line. This is broken behaviour, but just try
90telling Microsoft that.")
91
92(defvar url-cookies-changed-since-last-save nil
93 "Whether the cookies list has changed since the last save operation.")
94
95;;;###autoload
96(defun url-cookie-parse-file (&optional fname)
97 (setq fname (or fname url-cookie-file))
98 (condition-case ()
99 (load fname nil t)
100 (error (message "Could not load cookie file %s" fname))))
101
102(defun url-cookie-clean-up (&optional secure)
103 (let* (
104 (var (if secure 'url-cookie-secure-storage 'url-cookie-storage))
105 (val (symbol-value var))
106 (cur nil)
107 (new nil)
108 (cookies nil)
109 (cur-cookie nil)
110 (new-cookies nil)
111 )
112 (while val
113 (setq cur (car val)
114 val (cdr val)
115 new-cookies nil
116 cookies (cdr cur))
117 (while cookies
118 (setq cur-cookie (car cookies)
119 cookies (cdr cookies))
120 (if (or (not (url-cookie-p cur-cookie))
121 (url-cookie-expired-p cur-cookie)
122 (null (url-cookie-expires cur-cookie)))
123 nil
124 (setq new-cookies (cons cur-cookie new-cookies))))
125 (if (not new-cookies)
126 nil
127 (setcdr cur new-cookies)
128 (setq new (cons cur new))))
129 (set var new)))
130
131;;;###autoload
132(defun url-cookie-write-file (&optional fname)
133 (setq fname (or fname url-cookie-file))
134 (cond
135 ((not url-cookies-changed-since-last-save) nil)
136 ((not (file-writable-p fname))
137 (message "Cookies file %s (see variable `url-cookie-file') is unwritable." fname))
138 (t
139 (url-cookie-clean-up)
140 (url-cookie-clean-up t)
141 (save-excursion
142 (set-buffer (get-buffer-create " *cookies*"))
143 (erase-buffer)
144 (fundamental-mode)
145 (insert ";; Emacs-W3 HTTP cookies file\n"
146 ";; Automatically generated file!!! DO NOT EDIT!!!\n\n"
147 "(setq url-cookie-storage\n '")
148 (pp url-cookie-storage (current-buffer))
149 (insert ")\n(setq url-cookie-secure-storage\n '")
150 (pp url-cookie-secure-storage (current-buffer))
151 (insert ")\n")
152 (write-file fname)
153 (kill-buffer (current-buffer))))))
154
155(defun url-cookie-store (name value &optional expires domain path secure)
156 "Store a netscape-style cookie."
157 (let* ((storage (if secure url-cookie-secure-storage url-cookie-storage))
158 (tmp storage)
159 (cur nil)
160 (found-domain nil))
161
162 ;; First, look for a matching domain
163 (setq found-domain (assoc domain storage))
164
165 (if found-domain
166 ;; Need to either stick the new cookie in existing domain storage
167 ;; or possibly replace an existing cookie if the names match.
168 (progn
169 (setq storage (cdr found-domain)
170 tmp nil)
171 (while storage
172 (setq cur (car storage)
173 storage (cdr storage))
174 (if (and (equal path (url-cookie-path cur))
175 (equal name (url-cookie-name cur)))
176 (progn
177 (url-cookie-set-expires cur expires)
178 (url-cookie-set-value cur value)
179 (setq tmp t))))
180 (if (not tmp)
181 ;; New cookie
182 (setcdr found-domain (cons
183 (url-cookie-create :name name
184 :value value
185 :expires expires
186 :domain domain
187 :path path
188 :secure secure)
189 (cdr found-domain)))))
190 ;; Need to add a new top-level domain
191 (setq tmp (url-cookie-create :name name
192 :value value
193 :expires expires
194 :domain domain
195 :path path
196 :secure secure))
197 (cond
198 (storage
199 (setcdr storage (cons (list domain tmp) (cdr storage))))
200 (secure
201 (setq url-cookie-secure-storage (list (list domain tmp))))
202 (t
203 (setq url-cookie-storage (list (list domain tmp))))))))
204
205(defun url-cookie-expired-p (cookie)
206 (let* (
207 (exp (url-cookie-expires cookie))
208 (cur-date (and exp (timezone-parse-date (current-time-string))))
209 (exp-date (and exp (timezone-parse-date exp)))
210 (cur-greg (and cur-date (timezone-absolute-from-gregorian
211 (string-to-int (aref cur-date 1))
212 (string-to-int (aref cur-date 2))
213 (string-to-int (aref cur-date 0)))))
214 (exp-greg (and exp (timezone-absolute-from-gregorian
215 (string-to-int (aref exp-date 1))
216 (string-to-int (aref exp-date 2))
217 (string-to-int (aref exp-date 0)))))
218 (diff-in-days (and exp (- cur-greg exp-greg)))
219 )
220 (cond
221 ((not exp) nil) ; No expiry == expires at browser quit
222 ((< diff-in-days 0) nil) ; Expires sometime after today
223 ((> diff-in-days 0) t) ; Expired before today
224 (t ; Expires sometime today, check times
225 (let* ((cur-time (timezone-parse-time (aref cur-date 3)))
226 (exp-time (timezone-parse-time (aref exp-date 3)))
227 (cur-norm (+ (* 360 (string-to-int (aref cur-time 2)))
228 (* 60 (string-to-int (aref cur-time 1)))
229 (* 1 (string-to-int (aref cur-time 0)))))
230 (exp-norm (+ (* 360 (string-to-int (aref exp-time 2)))
231 (* 60 (string-to-int (aref exp-time 1)))
232 (* 1 (string-to-int (aref exp-time 0))))))
233 (> (- cur-norm exp-norm) 1))))))
234
235;;;###autoload
236(defun url-cookie-retrieve (host path &optional secure)
237 "Retrieve all the netscape-style cookies for a specified HOST and PATH."
238 (let ((storage (if secure
239 (append url-cookie-secure-storage url-cookie-storage)
240 url-cookie-storage))
241 (case-fold-search t)
242 (cookies nil)
243 (cur nil)
244 (retval nil)
245 (path-regexp nil))
246 (while storage
247 (setq cur (car storage)
248 storage (cdr storage)
249 cookies (cdr cur))
250 (if (and (car cur)
251 (string-match (concat "^.*" (regexp-quote (car cur)) "$") host))
252 ;; The domains match - a possible hit!
253 (while cookies
254 (setq cur (car cookies)
255 cookies (cdr cookies)
256 path-regexp (concat "^" (regexp-quote
257 (url-cookie-path cur))))
258 (if (and (string-match path-regexp path)
259 (not (url-cookie-expired-p cur)))
260 (setq retval (cons cur retval))))))
261 retval))
262
263;;;###autolaod
264(defun url-cookie-generate-header-lines (host path secure)
265 (let* ((cookies (url-cookie-retrieve host path secure))
266 (retval nil)
267 (cur nil)
268 (chunk nil))
269 ;; Have to sort this for sending most specific cookies first
270 (setq cookies (and cookies
271 (sort cookies
272 (function
273 (lambda (x y)
274 (> (length (url-cookie-path x))
275 (length (url-cookie-path y))))))))
276 (while cookies
277 (setq cur (car cookies)
278 cookies (cdr cookies)
279 chunk (format "%s=%s" (url-cookie-name cur) (url-cookie-value cur))
280 retval (if (and url-cookie-multiple-line
281 (< 80 (+ (length retval) (length chunk) 4)))
282 (concat retval "\r\nCookie: " chunk)
283 (if retval
284 (concat retval "; " chunk)
285 (concat "Cookie: " chunk)))))
286 (if retval
287 (concat retval "\r\n")
288 "")))
289
290(defvar url-cookie-two-dot-domains
291 (concat "\\.\\("
292 (mapconcat 'identity (list "com" "edu" "net" "org" "gov" "mil" "int")
293 "\\|")
294 "\\)$")
295 "A regexp of top level domains that only require two matching
296'.'s in the domain name in order to set a cookie.")
297
298(defcustom url-cookie-trusted-urls nil
299 "*A list of regular expressions matching URLs to always accept cookies from."
300 :type '(repeat regexp)
301 :group 'url-cookie)
302
303(defcustom url-cookie-untrusted-urls nil
304 "*A list of regular expressions matching URLs to never accept cookies from."
305 :type '(repeat regexp)
306 :group 'url-cookie)
307
308(defun url-cookie-host-can-set-p (host domain)
309 (let ((numdots 0)
310 (tmp domain)
311 (last nil)
312 (case-fold-search t)
313 (mindots 3))
314 (while (setq last (string-match "\\." domain last))
315 (setq numdots (1+ numdots)
316 last (1+ last)))
317 (if (string-match url-cookie-two-dot-domains domain)
318 (setq mindots 2))
319 (cond
320 ((string= host domain) ; Apparently netscape lets you do this
321 t)
322 ((>= numdots mindots) ; We have enough dots in domain name
323 ;; Need to check and make sure the host is actually _in_ the
324 ;; domain it wants to set a cookie for though.
325 (string-match (concat (regexp-quote domain) "$") host))
326 (t
327 nil))))
328
329;;;###autoload
330(defun url-cookie-handle-set-cookie (str)
331 (setq url-cookies-changed-since-last-save t)
332 (let* ((args (url-parse-args str t))
333 (case-fold-search t)
334 (secure (and (assoc-string "secure" args t) t))
335 (domain (or (cdr-safe (assoc-string "domain" args t))
336 (url-host url-current-object)))
337 (current-url (url-view-url t))
338 (trusted url-cookie-trusted-urls)
339 (untrusted url-cookie-untrusted-urls)
340 (expires (cdr-safe (assoc-string "expires" args t)))
341 (path (or (cdr-safe (assoc-string "path" args t))
342 (file-name-directory
343 (url-filename url-current-object))))
344 (rest nil))
345 (while args
346 (if (not (member (downcase (car (car args)))
347 '("secure" "domain" "expires" "path")))
348 (setq rest (cons (car args) rest)))
349 (setq args (cdr args)))
350
351 ;; Sometimes we get dates that the timezone package cannot handle very
352 ;; gracefully - take care of this here, instead of in url-cookie-expired-p
353 ;; to speed things up.
354 (if (and expires
355 (string-match
356 (concat "^[^,]+, +\\(..\\)-\\(...\\)-\\(..\\) +"
357 "\\(..:..:..\\) +\\[*\\([^\]]+\\)\\]*$")
358 expires))
359 (setq expires (concat (match-string 1 expires) " "
360 (match-string 2 expires) " "
361 (match-string 3 expires) " "
362 (match-string 4 expires) " ["
363 (match-string 5 expires) "]")))
364
365 ;; This one is for older Emacs/XEmacs variants that don't
366 ;; understand this format without tenths of a second in it.
367 ;; Wednesday, 30-Dec-2037 16:00:00 GMT
368 ;; - vs -
369 ;; Wednesday, 30-Dec-2037 16:00:00.00 GMT
370 (if (and expires
371 (string-match
372 "\\([0-9]+\\)-\\([A-Za-z]+\\)-\\([0-9]+\\)[ \t]+\\([0-9]+:[0-9]+:[0-9]+\\)\\(\\.[0-9]+\\)*[ \t]+\\([-+a-zA-Z0-9]+\\)"
373 expires))
374 (setq expires (concat (match-string 1 expires) "-" ; day
375 (match-string 2 expires) "-" ; month
376 (match-string 3 expires) " " ; year
377 (match-string 4 expires) ".00 " ; hour:minutes:seconds
378 (match-string 6 expires)))) ":" ; timezone
379
380 (while (consp trusted)
381 (if (string-match (car trusted) current-url)
382 (setq trusted (- (match-end 0) (match-beginning 0)))
383 (pop trusted)))
384 (while (consp untrusted)
385 (if (string-match (car untrusted) current-url)
386 (setq untrusted (- (match-end 0) (match-beginning 0)))
387 (pop untrusted)))
388 (if (and trusted untrusted)
389 ;; Choose the more specific match
390 (if (> trusted untrusted)
391 (setq untrusted nil)
392 (setq trusted nil)))
393 (cond
394 (untrusted
395 ;; The site was explicity marked as untrusted by the user
396 nil)
397 ((or (eq url-privacy-level 'paranoid)
398 (and (listp url-privacy-level) (memq 'cookies url-privacy-level)))
399 ;; user never wants cookies
400 nil)
401 ((and url-cookie-confirmation
402 (not trusted)
403 (save-window-excursion
404 (with-output-to-temp-buffer "*Cookie Warning*"
405 (mapcar
406 (function
407 (lambda (x)
408 (princ (format "%s - %s" (car x) (cdr x))))) rest))
409 (prog1
410 (not (funcall url-confirmation-func
411 (format "Allow %s to set these cookies? "
412 (url-host url-current-object))))
413 (if (get-buffer "*Cookie Warning*")
414 (kill-buffer "*Cookie Warning*")))))
415 ;; user wants to be asked, and declined.
416 nil)
417 ((url-cookie-host-can-set-p (url-host url-current-object) domain)
418 ;; Cookie is accepted by the user, and passes our security checks
419 (let ((cur nil))
420 (while rest
421 (setq cur (pop rest))
422 (url-cookie-store (car cur) (cdr cur)
423 expires domain path secure))))
424 (t
425 (message "%s tried to set a cookie for domain %s - rejected."
426 (url-host url-current-object) domain)))))
427
428(defvar url-cookie-timer nil)
429
430(defcustom url-cookie-save-interval 3600
431 "*The number of seconds between automatic saves of cookies.
432Default is 1 hour. Note that if you change this variable outside of
433the `customize' interface after `url-do-setup' has been run, you need
434to run the `url-cookie-setup-save-timer' function manually."
435 :set (function (lambda (var val)
436 (set-default var val)
437 (and (featurep 'url)
438 (fboundp 'url-cookie-setup-save-timer)
439 (url-cookie-setup-save-timer))))
440 :type 'integer
441 :group 'url)
442
443;;;###autoload
444(defun url-cookie-setup-save-timer ()
445 "Reset the cookie saver timer."
446 (interactive)
447 (ignore-errors
448 (cond ((fboundp 'cancel-timer) (cancel-timer url-cookie-timer))
449 ((fboundp 'delete-itimer) (delete-itimer url-cookie-timer))))
450 (setq url-cookie-timer nil)
451 (if url-cookie-save-interval
452 (setq url-cookie-timer
453 (cond
454 ((fboundp 'run-at-time)
455 (run-at-time url-cookie-save-interval
456 url-cookie-save-interval
457 'url-cookie-write-file))
458 ((fboundp 'start-itimer)
459 (start-itimer "url-cookie-saver" 'url-cookie-write-file
460 url-cookie-save-interval
461 url-cookie-save-interval))))))
462
463(provide 'url-cookie)
464
465;; arch-tag: 2568751b-6452-4398-aa2d-303edadb54d7
466;;; url-cookie.el ends here
diff --git a/lisp/url/url-dired.el b/lisp/url/url-dired.el
new file mode 100644
index 00000000000..73307412e1e
--- /dev/null
+++ b/lisp/url/url-dired.el
@@ -0,0 +1,100 @@
1;;; url-dired.el --- URL Dired minor mode
2;; Keywords: comm, files
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
25(autoload 'w3-fetch "w3")
26(autoload 'w3-open-local "w3")
27(autoload 'dired-get-filename "dired")
28
29(defvar url-dired-minor-mode-map
30 (let ((map (make-sparse-keymap)))
31 (define-key map "\C-m" 'url-dired-find-file)
32 (if (featurep 'xemacs)
33 (define-key map [button2] 'url-dired-find-file-mouse)
34 (define-key map [mouse-2] 'url-dired-find-file-mouse))
35 map)
36 "Keymap used when browsing directories.")
37
38(defvar url-dired-minor-mode nil
39 "Whether we are in url-dired-minor-mode")
40
41(make-variable-buffer-local 'url-dired-minor-mode)
42
43(defun url-dired-find-file ()
44 "In dired, visit the file or directory named on this line, using Emacs-W3."
45 (interactive)
46 (let ((filename (dired-get-filename)))
47 (cond ((string-match "/\\(.*@.*\\):\\(/.*\\)" filename)
48 (w3-fetch (concat "file://" (match-string 1 filename) (match-string 2 filename))))
49 (t
50 (w3-open-local filename)))))
51
52(defun url-dired-find-file-mouse (event)
53 "In dired, visit the file or directory name you click on, using Emacs-W3."
54 (interactive "@e")
55 (mouse-set-point event)
56 (url-dired-find-file))
57
58(defun url-dired-minor-mode (&optional arg)
59 "Minor mode for directory browsing with Emacs-W3."
60 (interactive "P")
61 (cond
62 ((null arg)
63 (setq url-dired-minor-mode (not url-dired-minor-mode)))
64 ((equal 0 arg)
65 (setq url-dired-minor-mode nil))
66 (t
67 (setq url-dired-minor-mode t))))
68
69(if (not (fboundp 'add-minor-mode))
70 (defun add-minor-mode (toggle name &optional keymap after toggle-fun)
71 "Add a minor mode to `minor-mode-alist' and `minor-mode-map-alist'.
72TOGGLE is a symbol which is used as the variable which toggle the minor mode,
73NAME is the name that should appear in the modeline (it should be a string
74beginning with a space), KEYMAP is a keymap to make active when the minor
75mode is active, and AFTER is the toggling symbol used for another minor
76mode. If AFTER is non-nil, then it is used to position the new mode in the
77minor-mode alists. TOGGLE-FUN specifies an interactive function that
78is called to toggle the mode on and off; this affects what appens when
79button2 is pressed on the mode, and when button3 is pressed somewhere
80in the list of modes. If TOGGLE-FUN is nil and TOGGLE names an
81interactive function, TOGGLE is used as the toggle function.
82
83Example: (add-minor-mode 'view-minor-mode \" View\" view-mode-map)"
84 (if (not (assq toggle minor-mode-alist))
85 (setq minor-mode-alist (cons (list toggle name) minor-mode-alist)))
86 (if (and keymap (not (assq toggle minor-mode-map-alist)))
87 (setq minor-mode-map-alist (cons (cons toggle keymap)
88 minor-mode-map-alist)))))
89
90(add-minor-mode 'url-dired-minor-mode " URL" url-dired-minor-mode-map)
91
92(defun url-find-file-dired (dir)
93 "\"Edit\" directory DIR, but with additional URL-friendly bindings."
94 (interactive "DURL Dired (directory): ")
95 (find-file dir)
96 (url-dired-minor-mode t))
97
98(provide 'url-dired)
99
100;;; arch-tag: 2694f21a-43e1-4391-b3cb-cf6e5349f15f
diff --git a/lisp/url/url-file.el b/lisp/url/url-file.el
index 77c2e74555f..0aa23acc0ec 100644
--- a/lisp/url/url-file.el
+++ b/lisp/url/url-file.el
@@ -1,7 +1,6 @@
1;;; url-file.el --- File retrieval code 1;;; url-file.el --- File retrieval code
2 2
3;; Copyright (c) 1996 - 1999,2004 Free Software Foundation, Inc. 3;; Copyright (c) 1996 - 1999,2004 Free Software Foundation, Inc.
4;; Copyright (c) 1993 - 1996 by William M. Perry <wmperry@cs.indiana.edu>
5 4
6;; Keywords: comm, data, processes 5;; Keywords: comm, data, processes
7 6
diff --git a/lisp/url/url-ftp.el b/lisp/url/url-ftp.el
new file mode 100644
index 00000000000..4346f3910b1
--- /dev/null
+++ b/lisp/url/url-ftp.el
@@ -0,0 +1,42 @@
1;;; url-ftp.el --- FTP wrapper
2;; Keywords: comm, data, processes
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
25;; We knew not what we did when we overloaded 'file' to mean 'file'
26;; and 'ftp' back in the dark ages of the web.
27;;
28;; This stub file is just here to please the auto-scheme-loading code
29;; in url-methods.el and just maps everything onto the code in
30;; url-file.
31
32(require 'url-parse)
33(require 'url-file)
34
35(defconst url-ftp-default-port 21 "Default FTP port.")
36(defconst url-ftp-asynchronous-p t "FTP transfers are asynchronous.")
37(defalias 'url-ftp-expand-file-name 'url-default-expander)
38(defalias 'url-ftp 'url-file)
39
40(provide 'url-ftp)
41
42;;; arch-tag: 9c3e70c4-350f-4d4a-bb51-a1e9b459e7dc
diff --git a/lisp/url/url-gw.el b/lisp/url/url-gw.el
new file mode 100644
index 00000000000..608827d7cee
--- /dev/null
+++ b/lisp/url/url-gw.el
@@ -0,0 +1,268 @@
1;;; url-gw.el --- Gateway munging for URL loading
2;; Author: Bill Perry <wmperry@gnu.org>
3;; Keywords: comm, data, processes
4
5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6;;; Copyright (c) 1997, 1998, 2004 Free Software Foundation, Inc.
7;;;
8;;; This file is part of GNU Emacs.
9;;;
10;;; GNU Emacs is free software; you can redistribute it and/or modify
11;;; it under the terms of the GNU General Public License as published by
12;;; the Free Software Foundation; either version 2, or (at your option)
13;;; any later version.
14;;;
15;;; GNU Emacs is distributed in the hope that it will be useful,
16;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;;; GNU General Public License for more details.
19;;;
20;;; You should have received a copy of the GNU General Public License
21;;; along with GNU Emacs; see the file COPYING. If not, write to the
22;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;;; Boston, MA 02111-1307, USA.
24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25(eval-when-compile (require 'cl))
26(require 'url-vars)
27
28;; Fixme: support SSH explicitly or via a url-gateway-rlogin-program?
29
30(autoload 'socks-open-network-stream "socks")
31(autoload 'open-ssl-stream "ssl")
32(autoload 'open-tls-stream "tls")
33
34(defgroup url-gateway nil
35 "URL gateway variables"
36 :group 'url)
37
38(defcustom url-gateway-local-host-regexp nil
39 "*A regular expression specifying local hostnames/machines."
40 :type '(choice (const nil) regexp)
41 :group 'url-gateway)
42
43(defcustom url-gateway-prompt-pattern
44 "^[^#$%>;]*[#$%>;] *" ;; "bash\\|\$ *\r?$\\|> *\r?"
45 "*A regular expression matching a shell prompt."
46 :type 'regexp
47 :group 'url-gateway)
48
49(defcustom url-gateway-rlogin-host nil
50 "*What hostname to actually rlog into before doing a telnet."
51 :type '(choice (const nil) string)
52 :group 'url-gateway)
53
54(defcustom url-gateway-rlogin-user-name nil
55 "*Username to log into the remote machine with when using rlogin."
56 :type '(choice (const nil) string)
57 :group 'url-gateway)
58
59(defcustom url-gateway-rlogin-parameters '("telnet" "-8")
60 "*Parameters to `url-open-rlogin'.
61This list will be used as the parameter list given to rsh."
62 :type '(repeat string)
63 :group 'url-gateway)
64
65(defcustom url-gateway-telnet-host nil
66 "*What hostname to actually login to before doing a telnet."
67 :type '(choice (const nil) string)
68 :group 'url-gateway)
69
70(defcustom url-gateway-telnet-parameters '("exec" "telnet" "-8")
71 "*Parameters to `url-open-telnet'.
72This list will be executed as a command after logging in via telnet."
73 :type '(repeat string)
74 :group 'url-gateway)
75
76(defcustom url-gateway-telnet-login-prompt "^\r*.?login:"
77 "*Prompt that tells us we should send our username when loggin in w/telnet."
78 :type 'regexp
79 :group 'url-gateway)
80
81(defcustom url-gateway-telnet-password-prompt "^\r*.?password:"
82 "*Prompt that tells us we should send our password when loggin in w/telnet."
83 :type 'regexp
84 :group 'url-gateway)
85
86(defcustom url-gateway-telnet-user-name nil
87 "User name to log in via telnet with."
88 :type '(choice (const nil) string)
89 :group 'url-gateway)
90
91(defcustom url-gateway-telnet-password nil
92 "Password to use to log in via telnet with."
93 :type '(choice (const nil) string)
94 :group 'url-gateway)
95
96(defcustom url-gateway-broken-resolution nil
97 "*Whether to use nslookup to resolve hostnames.
98This should be used when your version of Emacs cannot correctly use DNS,
99but your machine can. This usually happens if you are running a statically
100linked Emacs under SunOS 4.x"
101 :type 'boolean
102 :group 'url-gateway)
103
104(defcustom url-gateway-nslookup-program "nslookup"
105 "*If non-NIL then a string naming nslookup program."
106 :type '(choice (const :tag "None" :value nil) string)
107 :group 'url-gateway)
108
109;; Stolen from ange-ftp
110;;;###autoload
111(defun url-gateway-nslookup-host (host)
112 "Attempt to resolve the given HOST using nslookup if possible."
113 (interactive "sHost: ")
114 (if url-gateway-nslookup-program
115 (let ((proc (start-process " *nslookup*" " *nslookup*"
116 url-gateway-nslookup-program host))
117 (res host))
118 (process-kill-without-query proc)
119 (save-excursion
120 (set-buffer (process-buffer proc))
121 (while (memq (process-status proc) '(run open))
122 (accept-process-output proc))
123 (goto-char (point-min))
124 (if (re-search-forward "Name:.*\nAddress: *\\(.*\\)$" nil t)
125 (setq res (buffer-substring (match-beginning 1)
126 (match-end 1))))
127 (kill-buffer (current-buffer)))
128 res)
129 host))
130
131;; Stolen from red gnus nntp.el
132(defun url-wait-for-string (regexp proc)
133 "Wait until string matching REGEXP arrives in process PROC's buffer."
134 (let ((buf (current-buffer)))
135 (goto-char (point-min))
136 (while (not (re-search-forward regexp nil t))
137 (accept-process-output proc)
138 (set-buffer buf)
139 (goto-char (point-min)))))
140
141;; Stolen from red gnus nntp.el
142(defun url-open-rlogin (name buffer host service)
143 "Open a connection using rsh."
144 (if (not (stringp service))
145 (setq service (int-to-string service)))
146 (let ((proc (if url-gateway-rlogin-user-name
147 (start-process
148 name buffer "rsh"
149 url-gateway-rlogin-host "-l" url-gateway-rlogin-user-name
150 (mapconcat 'identity
151 (append url-gateway-rlogin-parameters
152 (list host service)) " "))
153 (start-process
154 name buffer "rsh" url-gateway-rlogin-host
155 (mapconcat 'identity
156 (append url-gateway-rlogin-parameters
157 (list host service))
158 " ")))))
159 (set-buffer buffer)
160 (url-wait-for-string "^\r*200" proc)
161 (beginning-of-line)
162 (delete-region (point-min) (point))
163 proc))
164
165;; Stolen from red gnus nntp.el
166(defun url-open-telnet (name buffer host service)
167 (if (not (stringp service))
168 (setq service (int-to-string service)))
169 (save-excursion
170 (set-buffer (get-buffer-create buffer))
171 (erase-buffer)
172 (let ((proc (start-process name buffer "telnet" "-8"))
173 (case-fold-search t))
174 (when (memq (process-status proc) '(open run))
175 (process-send-string proc "set escape \^X\n")
176 (process-send-string proc (concat
177 "open " url-gateway-telnet-host "\n"))
178 (url-wait-for-string url-gateway-telnet-login-prompt proc)
179 (process-send-string
180 proc (concat
181 (or url-gateway-telnet-user-name
182 (setq url-gateway-telnet-user-name (read-string "login: ")))
183 "\n"))
184 (url-wait-for-string url-gateway-telnet-password-prompt proc)
185 (process-send-string
186 proc (concat
187 (or url-gateway-telnet-password
188 (setq url-gateway-telnet-password
189 (funcall url-passwd-entry-func "Password: ")))
190 "\n"))
191 (erase-buffer)
192 (url-wait-for-string url-gateway-prompt-pattern proc)
193 (process-send-string
194 proc (concat (mapconcat 'identity
195 (append url-gateway-telnet-parameters
196 (list host service)) " ") "\n"))
197 (url-wait-for-string "^\r*Escape character.*\r*\n+" proc)
198 (delete-region (point-min) (match-end 0))
199 (process-send-string proc "\^]\n")
200 (url-wait-for-string "^telnet" proc)
201 (process-send-string proc "mode character\n")
202 (accept-process-output proc 1)
203 (sit-for 1)
204 (goto-char (point-min))
205 (forward-line 1)
206 (delete-region (point) (point-max)))
207 proc)))
208
209;;;###autoload
210(defun url-open-stream (name buffer host service)
211 "Open a stream to HOST, possibly via a gateway.
212Args per `open-network-stream'.
213Will not make a connexion if `url-gateway-unplugged' is non-nil."
214 (unless url-gateway-unplugged
215 (let ((gw-method (if (and url-gateway-local-host-regexp
216 (not (eq 'tls url-gateway-method))
217 (not (eq 'ssl url-gateway-method))
218 (string-match
219 url-gateway-local-host-regexp
220 host))
221 'native
222 url-gateway-method))
223;;; ;; This hack is for OS/2 Emacs so that it will not do bogus CRLF
224;;; ;; conversions while trying to be 'helpful'
225;;; (tcp-binary-process-output-services (if (stringp service)
226;;; (list service)
227;;; (list service
228;;; (int-to-string service))))
229
230 ;; An attempt to deal with denied connections, and attempt
231 ;; to reconnect
232 (cur-retries 0)
233 (retry t)
234 (errobj nil)
235 (conn nil))
236
237 ;; If the user told us to do DNS for them, do it.
238 (if url-gateway-broken-resolution
239 (setq host (url-gateway-nslookup-host host)))
240
241 (condition-case errobj
242 ;; This is a clean way to ensure the new process inherits the
243 ;; right coding systems in both Emacs and XEmacs.
244 (let ((coding-system-for-read 'binary)
245 (coding-system-for-write 'binary))
246 (setq conn (case gw-method
247 (tls
248 (open-tls-stream name buffer host service))
249 (ssl
250 (open-ssl-stream name buffer host service))
251 ((native)
252 (open-network-stream name buffer host service))
253 (socks
254 (socks-open-network-stream name buffer host service))
255 (telnet
256 (url-open-telnet name buffer host service))
257 (rlogin
258 (url-open-rlogin name buffer host service))
259 (otherwise
260 (error "Bad setting of url-gateway-method: %s"
261 url-gateway-method)))))
262 (error
263 (setq conn nil)))
264 conn)))
265
266(provide 'url-gw)
267
268;;; arch-tag: 1c4c0317-6d03-45b8-b3f3-838bd8f9d838
diff --git a/lisp/url/url-handlers.el b/lisp/url/url-handlers.el
index 56497b00119..db961b9c27e 100644
--- a/lisp/url/url-handlers.el
+++ b/lisp/url/url-handlers.el
@@ -1,7 +1,6 @@
1;;; url-handlers.el --- file-name-handler stuff for URL loading 1;;; url-handlers.el --- file-name-handler stuff for URL loading
2 2
3;; Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc. 3;; Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
4;; Copyright (c) 1993 - 1996 by William M. Perry <wmperry@cs.indiana.edu>
5 4
6;; Keywords: comm, data, processes, hypermedia 5;; Keywords: comm, data, processes, hypermedia
7 6
@@ -208,7 +207,7 @@ accessible."
208 ;; annotation which we could use as a hint of the locale in use 207 ;; annotation which we could use as a hint of the locale in use
209 ;; at the remote site. Not sure how/if that should be done. --Stef 208 ;; at the remote site. Not sure how/if that should be done. --Stef
210 (decode-coding-inserted-region 209 (decode-coding-inserted-region
211 start (point) buffer-file-name visit beg end replace))) 210 start (point) url visit beg end replace)))
212 (list url (length data)))) 211 (list url (length data))))
213 212
214(defun url-file-name-completion (url directory) 213(defun url-file-name-completion (url directory)
diff --git a/lisp/url/url-history.el b/lisp/url/url-history.el
new file mode 100644
index 00000000000..6a2d87cfbc1
--- /dev/null
+++ b/lisp/url/url-history.el
@@ -0,0 +1,199 @@
1;;; url-history.el --- Global history tracking for URL package
2
3;; Copyright (c) 1996 - 1999,2004 Free Software Foundation, Inc.
4
5;; Keywords: comm, data, processes, hypermedia
6
7;; This file is part of GNU Emacs.
8;;
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
23
24;;; Commentary:
25
26;;; Code:
27
28;; This can get a recursive require.
29;;(require 'url)
30(eval-when-compile (require 'cl))
31(require 'url-parse)
32(autoload 'url-do-setup "url")
33
34(defgroup url-history nil
35 "History variables in the URL package"
36 :prefix "url-history"
37 :group 'url)
38
39(defcustom url-history-track nil
40 "*Controls whether to keep a list of all the URLS being visited.
41If non-nil, url will keep track of all the URLS visited.
42If eq to `t', then the list is saved to disk at the end of each emacs
43session."
44 :type 'boolean
45 :group 'url-history)
46
47(defcustom url-history-file nil
48 "*The global history file for the URL package.
49This file contains a list of all the URLs you have visited. This file
50is parsed at startup and used to provide URL completion."
51 :type '(choice (const :tag "Default" :value nil) file)
52 :group 'url-history)
53
54(defcustom url-history-save-interval 3600
55 "*The number of seconds between automatic saves of the history list.
56Default is 1 hour. Note that if you change this variable outside of
57the `customize' interface after `url-do-setup' has been run, you need
58to run the `url-history-setup-save-timer' function manually."
59 :set (function (lambda (var val)
60 (set-default var val)
61 (and (featurep 'url)
62 (fboundp 'url-history-setup-save-timer)
63 (let ((def (symbol-function
64 'url-history-setup-save-timer)))
65 (not (and (listp def) (eq 'autoload (car def)))))
66 (url-history-setup-save-timer))))
67 :type 'integer
68 :group 'url-history)
69
70(defvar url-history-timer nil)
71
72(defvar url-history-list nil
73 "List of urls visited this session.")
74
75(defvar url-history-changed-since-last-save nil
76 "Whether the history list has changed since the last save operation.")
77
78(defvar url-history-hash-table nil
79 "Hash table for global history completion.")
80
81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
82
83;;;###autoload
84(defun url-history-setup-save-timer ()
85 "Reset the history list timer."
86 (interactive)
87 (ignore-errors
88 (cond ((fboundp 'cancel-timer) (cancel-timer url-history-timer))
89 ((fboundp 'delete-itimer) (delete-itimer url-history-timer))))
90 (setq url-history-timer nil)
91 (if url-history-save-interval
92 (setq url-history-timer
93 (cond
94 ((fboundp 'run-at-time)
95 (run-at-time url-history-save-interval
96 url-history-save-interval
97 'url-history-save-history))
98 ((fboundp 'start-itimer)
99 (start-itimer "url-history-saver" 'url-history-save-history
100 url-history-save-interval
101 url-history-save-interval))))))
102
103;;;###autoload
104(defun url-history-parse-history (&optional fname)
105 "Parse a history file stored in FNAME."
106 ;; Parse out the mosaic global history file for completions, etc.
107 (or fname (setq fname (expand-file-name url-history-file)))
108 (cond
109 ((not (file-exists-p fname))
110 (message "%s does not exist." fname))
111 ((not (file-readable-p fname))
112 (message "%s is unreadable." fname))
113 (t
114 (condition-case nil
115 (load fname nil t)
116 (error (message "Could not load %s" fname)))))
117 (if (not url-history-hash-table)
118 (setq url-history-hash-table (make-hash-table :size 31 :test 'equal))))
119
120(defun url-history-update-url (url time)
121 (setq url-history-changed-since-last-save t)
122 (puthash (if (vectorp url) (url-recreate-url url) url) time url-history-hash-table))
123
124;;;###autoload
125(defun url-history-save-history (&optional fname)
126 "Write the global history file into `url-history-file'.
127The type of data written is determined by what is in the file to begin
128with. If the type of storage cannot be determined, then prompt the
129user for what type to save as."
130 (interactive)
131 (or fname (setq fname (expand-file-name url-history-file)))
132 (cond
133 ((not url-history-changed-since-last-save) nil)
134 ((not (file-writable-p fname))
135 (message "%s is unwritable." fname))
136 (t
137 (let ((make-backup-files nil)
138 (version-control nil)
139 (require-final-newline t))
140 (save-excursion
141 (set-buffer (get-buffer-create " *url-tmp*"))
142 (erase-buffer)
143 (let ((count 0))
144 (maphash (function
145 (lambda (key value)
146 (while (string-match "[\r\n]+" key)
147 (setq key (concat (substring key 0 (match-beginning 0))
148 (substring key (match-end 0) nil))))
149 (setq count (1+ count))
150 (insert "(puthash \"" key "\""
151 (if (not (stringp value)) " '" "")
152 (prin1-to-string value)
153 " url-history-hash-table)\n")))
154 url-history-hash-table)
155 (goto-char (point-min))
156 (insert (format
157 "(setq url-history-hash-table (make-hash-table :size %d :test 'equal))\n"
158 (/ count 4)))
159 (goto-char (point-max))
160 (insert "\n")
161 (write-file fname))
162 (kill-buffer (current-buffer))))))
163 (setq url-history-changed-since-last-save nil))
164
165(defun url-have-visited-url (url)
166 (url-do-setup)
167 (gethash url url-history-hash-table nil))
168
169(defun url-completion-function (string predicate function)
170 (url-do-setup)
171 (cond
172 ((eq function nil)
173 (let ((list nil))
174 (maphash (function (lambda (key val)
175 (setq list (cons (cons key val)
176 list))))
177 url-history-hash-table)
178 (try-completion string (nreverse list) predicate)))
179 ((eq function t)
180 (let ((stub (concat "^" (regexp-quote string)))
181 (retval nil))
182 (maphash
183 (function
184 (lambda (url time)
185 (if (string-match stub url)
186 (setq retval (cons url retval)))))
187 url-history-hash-table)
188 retval))
189 ((eq function 'lambda)
190 (and url-history-hash-table
191 (gethash string url-history-hash-table)
192 t))
193 (t
194 (error "url-completion-function very confused."))))
195
196(provide 'url-history)
197
198;; arch-tag: fbbbaf63-db36-4e88-bc9f-2939aa93afb2
199;;; url-history.el ends here
diff --git a/lisp/url/url-https.el b/lisp/url/url-https.el
index 11b2593ea80..9631aeb18e4 100644
--- a/lisp/url/url-https.el
+++ b/lisp/url/url-https.el
@@ -1,4 +1,4 @@
1;;; url-https.el --- HTTP over SSL routines 1;;; url-https.el --- HTTP over SSL/TLS routines
2 2
3;; Copyright (c) 1999, 2004 Free Software Foundation, Inc. 3;; Copyright (c) 1999, 2004 Free Software Foundation, Inc.
4 4
@@ -30,6 +30,7 @@
30(require 'url-parse) 30(require 'url-parse)
31(require 'url-cookie) 31(require 'url-cookie)
32(require 'url-http) 32(require 'url-http)
33(require 'tls)
33 34
34(defconst url-https-default-port 443 "Default HTTPS port.") 35(defconst url-https-default-port 443 "Default HTTPS port.")
35(defconst url-https-asynchronous-p t "HTTPS retrievals are asynchronous.") 36(defconst url-https-asynchronous-p t "HTTPS retrievals are asynchronous.")
@@ -38,12 +39,11 @@
38(defmacro url-https-create-secure-wrapper (method args) 39(defmacro url-https-create-secure-wrapper (method args)
39 `(defun ,(intern (format (if method "url-https-%s" "url-https") method)) ,args 40 `(defun ,(intern (format (if method "url-https-%s" "url-https") method)) ,args
40 ,(format "HTTPS wrapper around `%s' call." (or method "url-http")) 41 ,(format "HTTPS wrapper around `%s' call." (or method "url-http"))
41 (condition-case () 42 (let ((url-gateway-method (condition-case ()
42 (require 'ssl) 43 (require 'ssl)
43 (error 44 (error 'tls))))
44 (error "HTTPS support could not find `ssl' library"))) 45 (,(intern (format (if method "url-http-%s" "url-http") method))
45 (let ((url-gateway-method 'ssl)) 46 ,@(remove '&rest (remove '&optional args))))))
46 ( ,(intern (format (if method "url-http-%s" "url-http") method)) ,@(remove '&rest (remove '&optional args))))))
47 47
48(url-https-create-secure-wrapper nil (url callback cbargs)) 48(url-https-create-secure-wrapper nil (url callback cbargs))
49(url-https-create-secure-wrapper file-exists-p (url)) 49(url-https-create-secure-wrapper file-exists-p (url))
diff --git a/lisp/url/url-irc.el b/lisp/url/url-irc.el
new file mode 100644
index 00000000000..a4b195f253f
--- /dev/null
+++ b/lisp/url/url-irc.el
@@ -0,0 +1,76 @@
1;;; url-irc.el --- IRC URL interface
2;; Keywords: comm, data, processes
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
25;;; IRC URLs are defined in http://www.w3.org/Addressing/draft-mirashi-url-irc-01.txt
26
27(require 'url-vars)
28(require 'url-parse)
29
30(defconst url-irc-default-port 6667 "Default port for IRC connections")
31
32(defcustom url-irc-function 'url-irc-zenirc
33 "*Function to actually open an IRC connection.
34Should be a function that takes several argument:
35 HOST - the hostname of the IRC server to contact
36 PORT - the port number of the IRC server to contact
37 CHANNEL - What channel on the server to visit right away (can be nil)
38 USER - What username to use
39PASSWORD - What password to use"
40 :type '(choice (const :tag "ZEN IRC" :value 'url-irc-zenirc)
41 (function :tag "Other"))
42 :group 'url)
43
44(defun url-irc-zenirc (host port channel user password)
45 (let ((zenirc-buffer-name (if (and user host port)
46 (format "%s@%s:%d" user host port)
47 (format "%s:%d" host port)))
48 (zenirc-server-alist
49 (list
50 (list host port password nil user))))
51 (zenirc)
52 (goto-char (point-max))
53 (if (not channel)
54 nil
55 (insert "/join " channel)
56 (zenirc-send-line))))
57
58;;;###autoload
59(defun url-irc (url)
60 (let* ((host (url-host url))
61 (port (string-to-int (url-port url)))
62 (pass (url-password url))
63 (user (url-user url))
64 (chan (url-filename url)))
65 (if (url-target url)
66 (setq chan (concat chan "#" (url-target url))))
67 (if (string-match "^/" chan)
68 (setq chan (substring chan 1 nil)))
69 (if (= (length chan) 0)
70 (setq chan nil))
71 (funcall url-irc-function host port chan user pass)
72 nil))
73
74(provide 'url-irc)
75
76;;; arch-tag: 2e5eecf8-9eb3-436b-9fbd-c26f2fb2bf3e
diff --git a/lisp/url/url-ldap.el b/lisp/url/url-ldap.el
new file mode 100644
index 00000000000..24a3ade4922
--- /dev/null
+++ b/lisp/url/url-ldap.el
@@ -0,0 +1,240 @@
1;;; url-ldap.el --- LDAP Uniform Resource Locator retrieval code
2;; Copyright (c) 1998 - 1999, 2004 Free Software Foundation, Inc.
3
4;; Keywords: comm, data, processes
5
6;; This file is part of GNU Emacs.
7;;
8;; GNU Emacs is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 2, or (at your option)
11;; any later version.
12;;
13;; GNU Emacs is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
19;; along with GNU Emacs; see the file COPYING. If not, write to the
20;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
22
23;;; Commentary:
24
25;;; Code:
26
27(require 'url-vars)
28(require 'url-parse)
29(require 'url-util)
30(require 'ldap)
31(autoload 'tls-certificate-information "tls")
32
33;; This has been implemented from RFC2255 'The LDAP URL Format' (Dec 1997)
34;;
35;; basic format is: ldap://host:port/dn?attributes?scope?filter?extensions
36;;
37;; Test URLs:
38;; ldap://ldap.itd.umich.edu/cn%3Dumbflabmanager%2C%20ou%3DUser%20Groups%2C%20ou%3DGroups%2C%20o%3DUniversity%20of%20Michigan%2C%20c%3DUS
39;; ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US
40;;
41;; For simple queries, I have verified compatibility with Netscape
42;; Communicator v4.5 under GNU/Linux.
43;;
44;; For anything _useful_ though, like specifying the attributes,
45;; scope, filter, or extensions, netscape claims the URL format is
46;; unrecognized. So I don't think it supports anything other than the
47;; defaults (scope=base,attributes=*,filter=(objectClass=*)
48
49(defconst url-ldap-default-port 389 "Default LDAP port.")
50(defalias 'url-ldap-expand-file-name 'url-default-expander)
51
52(defvar url-ldap-pretty-names
53 '(("l" . "City")
54 ("objectclass" . "Object Class")
55 ("o" . "Organization")
56 ("ou" . "Organizational Unit")
57 ("cn" . "Name")
58 ("sn" . "Last Name")
59 ("givenname" . "First Name")
60 ("mail" . "Email")
61 ("title" . "Title")
62 ("c" . "Country")
63 ("postalcode" . "ZIP Code")
64 ("telephonenumber" . "Phone Number")
65 ("facsimiletelephonenumber" . "Fax")
66 ("postaladdress" . "Mailing Address")
67 ("description" . "Notes"))
68 "*An assoc list mapping LDAP attribute names to pretty descriptions of them.")
69
70(defvar url-ldap-attribute-formatters
71 '(("mail" . (lambda (x) (format "<a href='mailto:%s'>%s</a>" x x)))
72 ("owner" . url-ldap-dn-formatter)
73 ("creatorsname" . url-ldap-dn-formatter)
74 ("jpegphoto" . url-ldap-image-formatter)
75 ("usercertificate" . url-ldap-certificate-formatter)
76 ("modifiersname" . url-ldap-dn-formatter)
77 ("namingcontexts" . url-ldap-dn-formatter)
78 ("defaultnamingcontext" . url-ldap-dn-formatter)
79 ("member" . url-ldap-dn-formatter))
80 "*An assoc list mapping LDAP attribute names to pretty formatters for them.")
81
82(defsubst url-ldap-attribute-pretty-name (n)
83 (or (cdr-safe (assoc (downcase n) url-ldap-pretty-names)) n))
84
85(defsubst url-ldap-attribute-pretty-desc (n v)
86 (if (string-match "^\\([^;]+\\);" n)
87 (setq n (match-string 1 n)))
88 (funcall (or (cdr-safe (assoc (downcase n) url-ldap-attribute-formatters)) 'identity) v))
89
90(defun url-ldap-dn-formatter (dn)
91 (concat "<a href='/"
92 (url-hexify-string dn)
93 "'>" dn "</a>"))
94
95(defun url-ldap-certificate-formatter (data)
96 (condition-case ()
97 (require 'ssl)
98 (error nil))
99 (let ((vals (if (fboundp 'ssl-certificate-information)
100 (ssl-certificate-information data)
101 (tls-certificate-information data))))
102 (if (not vals)
103 "<b>Unable to parse certificate</b>"
104 (concat "<table border=0>\n"
105 (mapconcat
106 (lambda (ava)
107 (format "<tr><td>%s</td><td>%s</td></tr>\n" (car ava) (cdr ava)))
108 vals "\n")
109 "</table>\n"))))
110
111(defun url-ldap-image-formatter (data)
112 (format "<img alt='JPEG Photo' src='data:image/jpeg;base64,%s'>"
113 (url-hexify-string (base64-encode-string data))))
114
115;; FIXME: This needs sorting out for the Emacs LDAP functions, specifically
116;; calls of ldap-open, ldap-close, ldap-search-internal
117;;;###autoload
118(defun url-ldap (url)
119 (save-excursion
120 (set-buffer (generate-new-buffer " *url-ldap*"))
121 (setq url-current-object url)
122 (insert "Content-type: text/html\r\n\r\n")
123 (if (not (fboundp 'ldap-search-internal))
124 (insert "<html>\n"
125 " <head>\n"
126 " <title>LDAP Not Supported</title>\n"
127 " <base href='" (url-recreate-url url) "'>\n"
128 " </head>\n"
129 " <body>\n"
130 " <h1>LDAP Not Supported</h1>\n"
131 " <p>\n"
132 " This version of Emacs does not support LDAP.\n"
133 " </p>\n"
134 " </body>\n"
135 "</html>\n")
136 (let* ((binddn nil)
137 (data (url-filename url))
138 (host (url-host url))
139 (port (url-port url))
140 (base-object nil)
141 (attributes nil)
142 (scope nil)
143 (filter nil)
144 (extensions nil)
145 (connection nil)
146 (results nil)
147 (extract-dn (and (fboundp 'function-max-args)
148 (= (function-max-args 'ldap-search-internal) 7))))
149
150 ;; Get rid of leading /
151 (if (string-match "^/" data)
152 (setq data (substring data 1)))
153
154 (setq data (mapcar (lambda (x) (if (/= (length x) 0) x nil)) (split-string data "\\?"))
155 base-object (nth 0 data)
156 attributes (nth 1 data)
157 scope (nth 2 data)
158 filter (nth 3 data)
159 extensions (nth 4 data))
160
161 ;; fill in the defaults
162 (setq base-object (url-unhex-string (or base-object ""))
163 scope (intern (url-unhex-string (or scope "base")))
164 filter (url-unhex-string (or filter "(objectClass=*)")))
165
166 (if (not (memq scope '(base one tree)))
167 (error "Malformed LDAP URL: Unknown scope: %S" scope))
168
169 ;; Convert to the internal LDAP support scoping names.
170 (setq scope (cdr (assq scope '((base . base) (one . onelevel) (sub . subtree)))))
171
172 (if attributes
173 (setq attributes (mapcar 'url-unhex-string (split-string attributes ","))))
174
175 ;; Parse out the exentions
176 (if extensions
177 (setq extensions (mapcar (lambda (ext)
178 (if (string-match "\\([^=]*\\)=\\(.*\\)" ext)
179 (cons (match-string 1 ext) (match-string 2 ext))
180 (cons ext ext)))
181 (split-string extensions ","))
182 extensions (mapcar (lambda (ext)
183 (cons (url-unhex-string (car ext))
184 (url-unhex-string (cdr ext))))
185 extensions)))
186
187 (setq binddn (cdr-safe (or (assoc "bindname" extensions)
188 (assoc "!bindname" extensions))))
189
190 ;; Now, let's actually do something with it.
191 (setq connection (ldap-open host (if binddn (list 'binddn binddn)))
192 results (if extract-dn
193 (ldap-search-internal connection filter base-object scope attributes nil t)
194 (ldap-search-internal connection filter base-object scope attributes nil)))
195
196 (ldap-close connection)
197 (insert "<html>\n"
198 " <head>\n"
199 " <title>LDAP Search Results</title>\n"
200 " <base href='" (url-recreate-url url) "'>\n"
201 " </head>\n"
202 " <body>\n"
203 " <h1>" (int-to-string (length results)) " matches</h1>\n")
204
205 (mapc (lambda (obj)
206 (insert " <hr>\n"
207 " <table border=1>\n")
208 (if extract-dn
209 (insert " <tr><th colspan=2>" (car obj) "</th></tr>\n"))
210 (mapc (lambda (attr)
211 (if (= (length (cdr attr)) 1)
212 ;; single match, easy
213 (insert " <tr><td>"
214 (url-ldap-attribute-pretty-name (car attr))
215 "</td><td>"
216 (url-ldap-attribute-pretty-desc (car attr) (car (cdr attr)))
217 "</td></tr>\n")
218 ;; Multiple matches, slightly uglier
219 (insert " <tr>\n"
220 (format " <td valign=top>")
221 (url-ldap-attribute-pretty-name (car attr)) "</td><td>"
222 (mapconcat (lambda (x)
223 (url-ldap-attribute-pretty-desc (car attr) x))
224 (cdr attr)
225 "<br>\n")
226 "</td>"
227 " </tr>\n")))
228 (if extract-dn (cdr obj) obj))
229 (insert " </table>\n"))
230 results)
231
232 (insert " <hr>\n"
233 " </body>\n"
234 "</html>\n")))
235 (current-buffer)))
236
237(provide 'url-ldap)
238
239;; arch-tag: 6230e21c-41ae-4174-bd83-82c835676fc8
240;;; url-ldap.el ends here
diff --git a/lisp/url/url-mailto.el b/lisp/url/url-mailto.el
new file mode 100644
index 00000000000..bcb6bad4179
--- /dev/null
+++ b/lisp/url/url-mailto.el
@@ -0,0 +1,131 @@
1;;; url-mail.el --- Mail Uniform Resource Locator retrieval code
2
3;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
4
5;; Keywords: comm, data, processes
6
7;; This file is part of GNU Emacs.
8;;
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
23
24;;; Commentary:
25
26;;; Code:
27
28(eval-when-compile (require 'cl))
29(require 'url-vars)
30(require 'url-parse)
31(require 'url-util)
32
33;;;###autoload
34(defun url-mail (&rest args)
35 (interactive "P")
36 (if (fboundp 'message-mail)
37 (apply 'message-mail args)
38 (or (apply 'mail args)
39 (error "Mail aborted"))))
40
41(defun url-mail-goto-field (field)
42 (if (not field)
43 (goto-char (point-max))
44 (let ((dest nil)
45 (lim nil)
46 (case-fold-search t))
47 (save-excursion
48 (goto-char (point-min))
49 (if (re-search-forward (regexp-quote mail-header-separator) nil t)
50 (setq lim (match-beginning 0)))
51 (goto-char (point-min))
52 (if (re-search-forward (concat "^" (regexp-quote field) ":") lim t)
53 (setq dest (match-beginning 0))))
54 (if dest
55 (progn
56 (goto-char dest)
57 (end-of-line))
58 (goto-char lim)
59 (insert (capitalize field) ": ")
60 (save-excursion
61 (insert "\n"))))))
62
63;;;###autoload
64(defun url-mailto (url)
65 "Handle the mailto: URL syntax."
66 (if (url-user url)
67 ;; malformed mailto URL (mailto://wmperry@gnu.org instead of
68 ;; mailto:wmperry@gnu.org
69 (url-set-filename url (concat (url-user url) "@" (url-filename url))))
70 (setq url (url-filename url))
71 (let (to args source-url subject func headers-start)
72 (if (string-match (regexp-quote "?") url)
73 (setq headers-start (match-end 0)
74 to (url-unhex-string (substring url 0 (match-beginning 0)))
75 args (url-parse-query-string
76 (substring url headers-start nil) t))
77 (setq to (url-unhex-string url)))
78 (setq source-url (url-view-url t))
79 (if (and url-request-data (not (assoc "subject" args)))
80 (setq args (cons (list "subject"
81 (concat "Automatic submission from "
82 url-package-name "/"
83 url-package-version)) args)))
84 (if (and source-url (not (assoc "x-url-from" args)))
85 (setq args (cons (list "x-url-from" source-url) args)))
86
87 (if (assoc "to" args)
88 (push to (cdr (assoc "to" args)))
89 (setq args (cons (list "to" to) args)))
90 (setq subject (cdr-safe (assoc "subject" args)))
91 (if (fboundp url-mail-command) (funcall url-mail-command) (mail))
92 (while args
93 (if (string= (caar args) "body")
94 (progn
95 (goto-char (point-max))
96 (insert (mapconcat 'identity (cdar args) "\n")))
97 (url-mail-goto-field (caar args))
98 (setq func (intern-soft (concat "mail-" (caar args))))
99 (insert (mapconcat 'identity (cdar args) ", ")))
100 (setq args (cdr args)))
101 ;; (url-mail-goto-field "User-Agent")
102;; (insert url-package-name "/" url-package-version " URL/" url-version)
103 (if (not url-request-data)
104 (progn
105 (set-buffer-modified-p nil)
106 (if subject
107 (url-mail-goto-field nil)
108 (url-mail-goto-field "subject")))
109 (if url-request-extra-headers
110 (mapconcat
111 (lambda (x)
112 (url-mail-goto-field (car x))
113 (insert (cdr x)))
114 url-request-extra-headers ""))
115 (goto-char (point-max))
116 (insert url-request-data)
117 ;; It seems Microsoft-ish to send without warning.
118 ;; Fixme: presumably this should depend on a privacy setting.
119 (if (y-or-n-p "Send this auto-generated mail? ")
120 (cond ((eq url-mail-command 'compose-mail)
121 (funcall (get mail-user-agent 'sendfunc) nil))
122 ;; otherwise, we can't be sure
123 ((fboundp 'message-send-and-exit)
124 (message-send-and-exit))
125 (t (mail-send-and-exit nil)))))
126 nil))
127
128(provide 'url-mailto)
129
130;; arch-tag: 7b7ad52e-8760-497b-9444-75fae14e34c5
131;;; url-mailto.el ends here
diff --git a/lisp/url/url-methods.el b/lisp/url/url-methods.el
new file mode 100644
index 00000000000..75d746f3e3f
--- /dev/null
+++ b/lisp/url/url-methods.el
@@ -0,0 +1,150 @@
1;;; url-methods.el --- Load URL schemes as needed
2
3;; Copyright (c) 1996,1997,1998,1999,2004 Free Software Foundation, Inc.
4
5;; Keywords: comm, data, processes, hypermedia
6
7;; This file is part of GNU Emacs.
8
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
23
24;;; Commentary:
25
26;;; Code:
27
28(eval-when-compile
29 (require 'cl))
30
31;; This loads up some of the small, silly URLs that I really don't
32;; want to bother putting in their own separate files.
33(require 'url-parse)
34
35(defvar url-scheme-registry (make-hash-table :size 7 :test 'equal))
36
37(defconst url-scheme-methods
38 '((default-port . variable)
39 (asynchronous-p . variable)
40 (expand-file-name . function)
41 (file-exists-p . function)
42 (file-attributes . function)
43 (parse-url . function)
44 (file-symlink-p . function)
45 (file-writable-p . function)
46 (file-directory-p . function)
47 (file-executable-p . function)
48 (directory-files . function)
49 (file-truename . function))
50 "Assoc-list of methods that each URL loader can provide.")
51
52(defconst url-scheme-default-properties
53 (list 'name "unknown"
54 'loader 'url-scheme-default-loader
55 'default-port 0
56 'expand-file-name 'url-identity-expander
57 'parse-url 'url-generic-parse-url
58 'asynchronous-p nil
59 'file-directory-p 'ignore
60 'file-truename (lambda (&rest args)
61 (url-recreate-url (car args)))
62 'file-exists-p 'ignore
63 'file-attributes 'ignore))
64
65(defun url-scheme-default-loader (url &optional callback cbargs)
66 "Signal an error for an unknown URL scheme."
67 (error "Unkown URL scheme: %s" (url-type url)))
68
69(defun url-scheme-register-proxy (scheme)
70 "Automatically find a proxy for SCHEME and put it in `url-proxy-services'."
71 (let* ((env-var (concat scheme "_proxy"))
72 (env-proxy (or (getenv (upcase env-var))
73 (getenv (downcase env-var))))
74 (cur-proxy (assoc scheme url-proxy-services))
75 (urlobj nil))
76
77 ;; Store any proxying information - this will not overwrite an old
78 ;; entry, so that people can still set this information in their
79 ;; .emacs file
80 (cond
81 (cur-proxy nil) ; Keep their old settings
82 ((null env-proxy) nil) ; No proxy setup
83 ;; First check if its something like hostname:port
84 ((string-match "^\\([^:]+\\):\\([0-9]+\\)$" env-proxy)
85 (setq urlobj (url-generic-parse-url nil)) ; Get a blank object
86 (url-set-type urlobj "http")
87 (url-set-host urlobj (match-string 1 env-proxy))
88 (url-set-port urlobj (string-to-number (match-string 2 env-proxy))))
89 ;; Then check if its a fully specified URL
90 ((string-match url-nonrelative-link env-proxy)
91 (setq urlobj (url-generic-parse-url env-proxy))
92 (url-set-type urlobj "http")
93 (url-set-target urlobj nil))
94 ;; Finally, fall back on the assumption that its just a hostname
95 (t
96 (setq urlobj (url-generic-parse-url nil)) ; Get a blank object
97 (url-set-type urlobj "http")
98 (url-set-host urlobj env-proxy)))
99
100 (if (and (not cur-proxy) urlobj)
101 (progn
102 (setq url-proxy-services
103 (cons (cons scheme (format "%s:%d" (url-host urlobj)
104 (url-port urlobj)))
105 url-proxy-services))
106 (message "Using a proxy for %s..." scheme)))))
107
108(defun url-scheme-get-property (scheme property)
109 "Get property of a URL SCHEME.
110Will automatically try to load a backend from url-SCHEME.el if
111it has not already been loaded."
112 (setq scheme (downcase scheme))
113 (let ((desc (gethash scheme url-scheme-registry)))
114 (if (not desc)
115 (let* ((stub (concat "url-" scheme))
116 (loader (intern stub)))
117 (condition-case ()
118 (require loader)
119 (error nil))
120 (if (fboundp loader)
121 (progn
122 ;; Found the module to handle <scheme> URLs
123 (url-scheme-register-proxy scheme)
124 (setq desc (list 'name scheme
125 'loader loader))
126 (dolist (cell url-scheme-methods)
127 (let ((symbol (intern-soft (format "%s-%s" stub (car cell))))
128 (type (cdr cell)))
129 (if symbol
130 (case type
131 (function
132 ;; Store the symbol name of a function
133 (if (fboundp symbol)
134 (setq desc (plist-put desc (car cell) symbol))))
135 (variable
136 ;; Store the VALUE of a variable
137 (if (boundp symbol)
138 (setq desc (plist-put desc (car cell)
139 (symbol-value symbol)))))
140 (otherwise
141 (error "Malformed url-scheme-methods entry: %S"
142 cell))))))
143 (puthash scheme desc url-scheme-registry)))))
144 (or (plist-get desc property)
145 (plist-get url-scheme-default-properties property))))
146
147(provide 'url-methods)
148
149;; arch-tag: 336863f8-5a07-4906-9be5-b3c6bcebbe67
150;;; url-methods.el ends here
diff --git a/lisp/url/url-misc.el b/lisp/url/url-misc.el
new file mode 100644
index 00000000000..ff2f1282137
--- /dev/null
+++ b/lisp/url/url-misc.el
@@ -0,0 +1,117 @@
1;;; url-misc.el --- Misc Uniform Resource Locator retrieval code
2;; Keywords: comm, data, processes
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996,1997,1998,1999,2002 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
25(require 'url-vars)
26(require 'url-parse)
27(autoload 'Info-goto-node "info" "" t)
28(autoload 'man "man" nil t)
29
30;;;###autoload
31(defun url-man (url)
32 "Fetch a Unix manual page URL."
33 (man (url-filename url))
34 nil)
35
36;;;###autoload
37(defun url-info (url)
38 "Fetch a GNU Info URL."
39 ;; Fetch an info node
40 (let* ((fname (url-filename url))
41 (node (url-unhex-string (or (url-target url) "Top"))))
42 (if (and fname node)
43 (Info-goto-node (concat "(" fname ")" node))
44 (error "Malformed url: %s" (url-recreate-url url)))
45 nil))
46
47(defun url-do-terminal-emulator (type server port user)
48 (terminal-emulator
49 (generate-new-buffer (format "%s%s" (if user (concat user "@") "") server))
50 (case type
51 (rlogin "rlogin")
52 (telnet "telnet")
53 (tn3270 "tn3270")
54 (otherwise
55 (error "Unknown terminal emulator required: %s" type)))
56 (case type
57 (rlogin
58 (if user
59 (list server "-l" user)
60 (list server)))
61 (telnet
62 (if user (message "Please log in as user: %s" user))
63 (if port
64 (list server port)
65 (list server)))
66 (tn3270
67 (if user (message "Please log in as user: %s" user))
68 (list server)))))
69
70;;;###autoload
71(defun url-generic-emulator-loader (url)
72 (let* ((type (intern (downcase (url-type url))))
73 (server (url-host url))
74 (name (url-user url))
75 (port (url-port url)))
76 (url-do-terminal-emulator type server port name))
77 nil)
78
79;;;###autoload
80(defalias 'url-rlogin 'url-generic-emulator-loader)
81;;;###autoload
82(defalias 'url-telnet 'url-generic-emulator-loader)
83;;;###autoload
84(defalias 'url-tn3270 'url-generic-emulator-loader)
85
86;; RFC 2397
87;;;###autoload
88(defun url-data (url)
89 "Fetch a data URL (RFC 2397)."
90 (let ((mediatype nil)
91 ;; The mediatype may need to be hex-encoded too -- see the RFC.
92 (desc (url-unhex-string (url-filename url)))
93 (encoding "8bit")
94 (data nil))
95 (save-excursion
96 (if (not (string-match "\\([^,]*\\)?," desc))
97 (error "Malformed data URL: %s" desc)
98 (setq mediatype (match-string 1 desc))
99 (if (and mediatype (string-match ";base64\\'" mediatype))
100 (setq mediatype (substring mediatype 0 (match-beginning 0))
101 encoding "base64"))
102 (if (or (null mediatype)
103 (eq ?\; (aref mediatype 0)))
104 (setq mediatype (concat "text/plain" mediatype)))
105 (setq data (url-unhex-string (substring desc (match-end 0)))))
106 (set-buffer (generate-new-buffer " *url-data*"))
107 (mm-disable-multibyte)
108 (insert (format "Content-Length: %d\n" (length data))
109 "Content-Type: " mediatype "\n"
110 "Content-Encoding: " encoding "\n"
111 "\n")
112 (if data (insert data))
113 (current-buffer))))
114
115(provide 'url-misc)
116
117;;; arch-tag: 8c544e1b-d8bc-40a6-b319-f1f37fef65a0
diff --git a/lisp/url/url-news.el b/lisp/url/url-news.el
new file mode 100644
index 00000000000..59364c9ccd0
--- /dev/null
+++ b/lisp/url/url-news.el
@@ -0,0 +1,135 @@
1;;; url-news.el --- News Uniform Resource Locator retrieval code
2;; Keywords: comm, data, processes
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996 - 1999, 2004 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24(require 'url-vars)
25(require 'url-util)
26(require 'url-parse)
27(require 'nntp)
28(autoload 'url-warn "url")
29(autoload 'gnus-group-read-ephemeral-group "gnus-group")
30(eval-when-compile (require 'cl))
31
32(defgroup url-news nil
33 "News related options"
34 :group 'url)
35
36(defun url-news-open-host (host port user pass)
37 (if (fboundp 'nnheader-init-server-buffer)
38 (nnheader-init-server-buffer))
39 (nntp-open-server host (list (string-to-int port)))
40 (if (and user pass)
41 (progn
42 (nntp-send-command "^.*\r?\n" "AUTHINFO USER" user)
43 (nntp-send-command "^.*\r?\n" "AUTHINFO PASS" pass)
44 (if (not (nntp-server-opened host))
45 (url-warn 'url (format "NNTP authentication to `%s' as `%s' failed"
46 host user))))))
47
48(defun url-news-fetch-message-id (host message-id)
49 (let ((buf (generate-new-buffer " *url-news*")))
50 (if (eq ?> (aref message-id (1- (length message-id))))
51 nil
52 (setq message-id (concat "<" message-id ">")))
53 (if (cdr-safe (nntp-request-article message-id nil host buf))
54 ;; Successfully retrieved the article
55 nil
56 (save-excursion
57 (set-buffer buf)
58 (insert "Content-type: text/html\n\n"
59 "<html>\n"
60 " <head>\n"
61 " <title>Error</title>\n"
62 " </head>\n"
63 " <body>\n"
64 " <div>\n"
65 " <h1>Error requesting article...</h1>\n"
66 " <p>\n"
67 " The status message returned by the NNTP server was:"
68 "<br><hr>\n"
69 " <xmp>\n"
70 (nntp-status-message)
71 " </xmp>\n"
72 " </p>\n"
73 " <p>\n"
74 " If you If you feel this is an error, <a href=\""
75 "mailto:" url-bug-address "\">send mail</a>\n"
76 " </p>\n"
77 " </div>\n"
78 " </body>\n"
79 "</html>\n"
80 "<!-- Automatically generated by URL v" url-version " -->\n"
81 )))
82 buf))
83
84(defun url-news-fetch-newsgroup (newsgroup host)
85 (declare (special gnus-group-buffer))
86 (if (string-match "^/+" newsgroup)
87 (setq newsgroup (substring newsgroup (match-end 0))))
88 (if (string-match "/+$" newsgroup)
89 (setq newsgroup (substring newsgroup 0 (match-beginning 0))))
90
91 ;; This saves us from checking new news if Gnus is already running
92 ;; FIXME - is it relatively safe to use gnus-alive-p here? FIXME
93 (if (or (not (get-buffer gnus-group-buffer))
94 (save-excursion
95 (set-buffer gnus-group-buffer)
96 (not (eq major-mode 'gnus-group-mode))))
97 (gnus))
98 (set-buffer gnus-group-buffer)
99 (goto-char (point-min))
100 (gnus-group-read-ephemeral-group newsgroup
101 (list 'nntp host
102 'nntp-open-connection-function
103 nntp-open-connection-function)
104 nil
105 (cons (current-buffer) 'browse)))
106
107;;;###autoload
108(defun url-news (url)
109 ;; Find a news reference
110 (let* ((host (or (url-host url) url-news-server))
111 (port (url-port url))
112 (article-brackets nil)
113 (buf nil)
114 (article (url-filename url)))
115 (url-news-open-host host port (url-user url) (url-password url))
116 (setq article (url-unhex-string article))
117 (cond
118 ((string-match "@" article) ; Its a specific article
119 (setq buf (url-news-fetch-message-id host article)))
120 ((string= article "") ; List all newsgroups
121 (gnus))
122 (t ; Whole newsgroup
123 (url-news-fetch-newsgroup article host)))
124 buf))
125
126;;;###autoload
127(defun url-snews (url)
128 (let ((nntp-open-connection-function (if (eq 'tls url-gateway-method)
129 nntp-open-tls-stream
130 nntp-open-ssl-stream)))
131 (url-news url)))
132
133(provide 'url-news)
134
135;;; arch-tag: 8975be13-04e8-4d38-bfff-47918e3ad311
diff --git a/lisp/url/url-nfs.el b/lisp/url/url-nfs.el
index d068341b1c2..3b834bba75f 100644
--- a/lisp/url/url-nfs.el
+++ b/lisp/url/url-nfs.el
@@ -1,7 +1,6 @@
1;;; url-nfs.el --- NFS URL interface 1;;; url-nfs.el --- NFS URL interface
2 2
3;; Copyright (c) 1996,97,98,1999,2004 Free Software Foundation, Inc. 3;; Copyright (c) 1996,1997,1998,1999,2004 Free Software Foundation, Inc.
4;; Copyright (c) 1996 by William M. Perry <wmperry@cs.indiana.edu>
5 4
6;; Keywords: comm, data, processes 5;; Keywords: comm, data, processes
7 6
diff --git a/lisp/url/url-parse.el b/lisp/url/url-parse.el
new file mode 100644
index 00000000000..97348ab5db2
--- /dev/null
+++ b/lisp/url/url-parse.el
@@ -0,0 +1,210 @@
1;;; url-parse.el --- Uniform Resource Locator parser
2
3;; Copyright (c) 1996,1997,1998,1999,2004 Free Software Foundation, Inc.
4
5;; Keywords: comm, data, processes
6
7;; This file is part of GNU Emacs.
8;;
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
23
24;;; Commentary:
25
26;;; Code:
27
28(require 'url-vars)
29
30(autoload 'url-scheme-get-property "url-methods")
31
32(defmacro url-type (urlobj)
33 `(aref ,urlobj 0))
34
35(defmacro url-user (urlobj)
36 `(aref ,urlobj 1))
37
38(defmacro url-password (urlobj)
39 `(aref ,urlobj 2))
40
41(defmacro url-host (urlobj)
42 `(aref ,urlobj 3))
43
44(defmacro url-port (urlobj)
45 `(or (aref ,urlobj 4)
46 (if (url-fullness ,urlobj)
47 (url-scheme-get-property (url-type ,urlobj) 'default-port))))
48
49(defmacro url-filename (urlobj)
50 `(aref ,urlobj 5))
51
52(defmacro url-target (urlobj)
53 `(aref ,urlobj 6))
54
55(defmacro url-attributes (urlobj)
56 `(aref ,urlobj 7))
57
58(defmacro url-fullness (urlobj)
59 `(aref ,urlobj 8))
60
61(defmacro url-set-type (urlobj type)
62 `(aset ,urlobj 0 ,type))
63
64(defmacro url-set-user (urlobj user)
65 `(aset ,urlobj 1 ,user))
66
67(defmacro url-set-password (urlobj pass)
68 `(aset ,urlobj 2 ,pass))
69
70(defmacro url-set-host (urlobj host)
71 `(aset ,urlobj 3 ,host))
72
73(defmacro url-set-port (urlobj port)
74 `(aset ,urlobj 4 ,port))
75
76(defmacro url-set-filename (urlobj file)
77 `(aset ,urlobj 5 ,file))
78
79(defmacro url-set-target (urlobj targ)
80 `(aset ,urlobj 6 ,targ))
81
82(defmacro url-set-attributes (urlobj targ)
83 `(aset ,urlobj 7 ,targ))
84
85(defmacro url-set-full (urlobj val)
86 `(aset ,urlobj 8 ,val))
87
88;;;###autoload
89(defun url-recreate-url (urlobj)
90 "Recreate a URL string from the parsed URLOBJ."
91 (concat (url-type urlobj) ":" (if (url-host urlobj) "//" "")
92 (if (url-user urlobj)
93 (concat (url-user urlobj)
94 (if (url-password urlobj)
95 (concat ":" (url-password urlobj)))
96 "@"))
97 (url-host urlobj)
98 (if (and (url-port urlobj)
99 (not (equal (url-port urlobj)
100 (url-scheme-get-property (url-type urlobj) 'default-port))))
101 (format ":%d" (url-port urlobj)))
102 (or (url-filename urlobj) "/")
103 (if (url-target urlobj)
104 (concat "#" (url-target urlobj)))
105 (if (url-attributes urlobj)
106 (concat ";"
107 (mapconcat
108 (function
109 (lambda (x)
110 (if (cdr x)
111 (concat (car x) "=" (cdr x))
112 (car x)))) (url-attributes urlobj) ";")))))
113
114;;;###autoload
115(defun url-generic-parse-url (url)
116 "Return a vector of the parts of URL.
117Format is:
118\[TYPE USER PASSWORD HOST PORT FILE TARGET ATTRIBUTES FULL\]"
119 (cond
120 ((null url)
121 (make-vector 9 nil))
122 ((or (not (string-match url-nonrelative-link url))
123 (= ?/ (string-to-char url)))
124 (let ((retval (make-vector 9 nil)))
125 (url-set-filename retval url)
126 (url-set-full retval nil)
127 retval))
128 (t
129 (save-excursion
130 (set-buffer (get-buffer-create " *urlparse*"))
131 (set-syntax-table url-parse-syntax-table)
132 (let ((save-pos nil)
133 (prot nil)
134 (user nil)
135 (pass nil)
136 (host nil)
137 (port nil)
138 (file nil)
139 (refs nil)
140 (attr nil)
141 (full nil)
142 (inhibit-read-only t))
143 (erase-buffer)
144 (insert url)
145 (goto-char (point-min))
146 (setq save-pos (point))
147 (if (not (looking-at "//"))
148 (progn
149 (skip-chars-forward "a-zA-Z+.\\-")
150 (downcase-region save-pos (point))
151 (setq prot (buffer-substring save-pos (point)))
152 (skip-chars-forward ":")
153 (setq save-pos (point))))
154
155 ;; We are doing a fully specified URL, with hostname and all
156 (if (looking-at "//")
157 (progn
158 (setq full t)
159 (forward-char 2)
160 (setq save-pos (point))
161 (skip-chars-forward "^/")
162 (setq host (buffer-substring save-pos (point)))
163 (if (string-match "^\\([^@]+\\)@" host)
164 (setq user (match-string 1 host)
165 host (substring host (match-end 0) nil)))
166 (if (and user (string-match "\\([^:]+\\):\\(.*\\)" user))
167 (setq pass (match-string 2 user)
168 user (match-string 1 user)))
169 (if (string-match ":\\([0-9+]+\\)" host)
170 (setq port (string-to-int (match-string 1 host))
171 host (substring host 0 (match-beginning 0))))
172 (if (string-match ":$" host)
173 (setq host (substring host 0 (match-beginning 0))))
174 (setq host (downcase host)
175 save-pos (point))))
176
177 (if (not port)
178 (setq port (url-scheme-get-property prot 'default-port)))
179
180 ;; Gross hack to preserve ';' in data URLs
181
182 (setq save-pos (point))
183
184 (if (string= "data" prot)
185 (goto-char (point-max))
186 ;; Now check for references
187 (skip-chars-forward "^#")
188 (if (eobp)
189 nil
190 (delete-region
191 (point)
192 (progn
193 (skip-chars-forward "#")
194 (setq refs (buffer-substring (point) (point-max)))
195 (point-max))))
196 (goto-char save-pos)
197 (skip-chars-forward "^;")
198 (if (not (eobp))
199 (setq attr (url-parse-args (buffer-substring (point) (point-max)) t)
200 attr (nreverse attr))))
201
202 (setq file (buffer-substring save-pos (point)))
203 (if (and host (string-match "%[0-9][0-9]" host))
204 (setq host (url-unhex-string host)))
205 (vector prot user pass host port file refs attr full))))))
206
207(provide 'url-parse)
208
209;; arch-tag: f338325f-71ab-4bee-93cc-78fb9a03d403
210;;; url-parse.el ends here
diff --git a/lisp/url/url-privacy.el b/lisp/url/url-privacy.el
new file mode 100644
index 00000000000..cb64cfbd4fc
--- /dev/null
+++ b/lisp/url/url-privacy.el
@@ -0,0 +1,81 @@
1;;; url-privacy.el --- Global history tracking for URL package
2;; Keywords: comm, data, processes, hypermedia
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996 - 1999 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
25(eval-when-compile (require 'cl))
26(require 'url-vars)
27
28(if (fboundp 'device-type)
29 (defalias 'url-device-type 'device-type)
30 (defun url-device-type (&optional device) (or window-system 'tty)))
31
32;;;###autoload
33(defun url-setup-privacy-info ()
34 (interactive)
35 (setq url-system-type
36 (cond
37 ((or (eq url-privacy-level 'paranoid)
38 (and (listp url-privacy-level)
39 (memq 'os url-privacy-level)))
40 nil)
41 ;; First, we handle the inseparable OS/Windowing system
42 ;; combinations
43 ((eq system-type 'Apple-Macintosh) "Macintosh")
44 ((eq system-type 'next-mach) "NeXT")
45 ((eq system-type 'windows-nt) "Windows-NT; 32bit")
46 ((eq system-type 'ms-windows) "Windows; 16bit")
47 ((eq system-type 'ms-dos) "MS-DOS; 32bit")
48 ((memq (url-device-type) '(win32 w32)) "Windows; 32bit")
49 ((eq (url-device-type) 'pm) "OS/2; 32bit")
50 (t
51 (case (url-device-type)
52 (x "X11")
53 (ns "OpenStep")
54 (tty "TTY")
55 (otherwise nil)))))
56
57 (setq url-personal-mail-address (or url-personal-mail-address
58 user-mail-address
59 (format "%s@%s" (user-real-login-name)
60 (system-name))))
61
62 (if (or (memq url-privacy-level '(paranoid high))
63 (and (listp url-privacy-level)
64 (memq 'email url-privacy-level)))
65 (setq url-personal-mail-address nil))
66
67 (setq url-os-type
68 (cond
69 ((or (eq url-privacy-level 'paranoid)
70 (and (listp url-privacy-level)
71 (memq 'os url-privacy-level)))
72 nil)
73 ((boundp 'system-configuration)
74 system-configuration)
75 ((boundp 'system-type)
76 (symbol-name system-type))
77 (t nil))))
78
79(provide 'url-privacy)
80
81;;; arch-tag: fdaf95e4-98f0-4680-94c3-f3eadafabe1d
diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el
index d4a3733eab5..5d1f73e0d5d 100644
--- a/lisp/url/url-util.el
+++ b/lisp/url/url-util.el
@@ -1,7 +1,6 @@
1;;; url-util.el --- Miscellaneous helper routines for URL library 1;;; url-util.el --- Miscellaneous helper routines for URL library
2 2
3;; Copyright (c) 1996,97,98,99,2001,2004 Free Software Foundation, Inc. 3;; Copyright (c) 1996,1997,1998,1999,2001,2004 Free Software Foundation, Inc.
4;; Copyright (c) 1993 - 1996 by William M. Perry <wmperry@cs.indiana.edu>
5 4
6;; Author: Bill Perry <wmperry@gnu.org> 5;; Author: Bill Perry <wmperry@gnu.org>
7;; Keywords: comm, data, processes 6;; Keywords: comm, data, processes
diff --git a/lisp/url/url-vars.el b/lisp/url/url-vars.el
new file mode 100644
index 00000000000..a33d8ba43e3
--- /dev/null
+++ b/lisp/url/url-vars.el
@@ -0,0 +1,431 @@
1;;; url-vars.el --- Variables for Uniform Resource Locator tool
2;; Keywords: comm, data, processes, hypermedia
3
4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5;;; Copyright (c) 1996,1997,1998,1999,2001,2004 Free Software Foundation, Inc.
6;;;
7;;; This file is part of GNU Emacs.
8;;;
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13;;;
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to the
21;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;;; Boston, MA 02111-1307, USA.
23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24
25(require 'mm-util)
26
27(defconst url-version "Emacs"
28 "Version number of URL package.")
29
30(defgroup url nil
31 "Uniform Resource Locator tool"
32 :version "21.4"
33 :group 'hypermedia)
34
35(defgroup url-file nil
36 "URL storage"
37 :prefix "url-"
38 :group 'url)
39
40(defgroup url-cache nil
41 "URL cache"
42 :prefix "url-"
43 :prefix "url-cache-"
44 :group 'url)
45
46(defgroup url-mime nil
47 "MIME options of URL"
48 :prefix "url-"
49 :group 'url)
50
51(defgroup url-hairy nil
52 "Hairy options of URL"
53 :prefix "url-"
54 :group 'url)
55
56
57(defvar url-current-object nil
58 "A parsed representation of the current url.")
59
60(defvar url-current-mime-headers nil
61 "A parsed representation of the MIME headers for the current url.")
62
63(mapcar 'make-variable-buffer-local
64 '(
65 url-current-object
66 url-current-referer
67 url-current-mime-headers
68 ))
69
70(defcustom url-honor-refresh-requests t
71 "*Whether to do automatic page reloads.
72These are done at the request of the document author or the server via
73the `Refresh' header in an HTTP response. If nil, no refresh
74requests will be honored. If t, all refresh requests will be honored.
75If non-nil and not t, the user will be asked for each refresh
76request."
77 :type '(choice (const :tag "off" nil)
78 (const :tag "on" t)
79 (const :tag "ask" 'ask))
80 :group 'url-hairy)
81
82(defcustom url-automatic-caching nil
83 "*If non-nil, all documents will be automatically cached to the local disk."
84 :type 'boolean
85 :group 'url-cache)
86
87;; Fixme: sanitize this.
88(defcustom url-cache-expired
89 (lambda (t1 t2) (>= (- (car t2) (car t1)) 5))
90 "*A function determining if a cached item has expired.
91It takes two times (numbers) as its arguments, and returns non-nil if
92the second time is 'too old' when compared to the first time."
93 :type 'function
94 :group 'url-cache)
95
96(defconst url-bug-address "bug-gnu-emacs@gnu.org"
97 "Where to send bug reports.")
98
99(defcustom url-personal-mail-address nil
100 "*Your full email address.
101This is what is sent to HTTP servers as the FROM field in an HTTP
102request."
103 :type '(choice (const :tag "Unspecified" nil) string)
104 :group 'url)
105
106(defcustom url-directory-index-file "index.html"
107 "*The filename to look for when indexing a directory.
108If this file exists, and is readable, then it will be viewed instead of
109using `dired' to view the directory."
110 :type 'string
111 :group 'url-file)
112
113;; Fixme: this should have a setter which calls url-setup-privacy-info.
114(defcustom url-privacy-level '(email)
115 "*How private you want your requests to be.
116HTTP has header fields for various information about the user, including
117operating system information, email addresses, the last page you visited, etc.
118This variable controls how much of this information is sent.
119
120This should a symbol or a list.
121Valid values if a symbol are:
122none -- Send all information
123low -- Don't send the last location
124high -- Don't send the email address or last location
125paranoid -- Don't send anything
126
127If a list, this should be a list of symbols of what NOT to send.
128Valid symbols are:
129email -- the email address
130os -- the operating system info
131lastloc -- the last location
132agent -- Do not send the User-Agent string
133cookie -- never accept HTTP cookies
134
135Samples:
136
137 (setq url-privacy-level 'high)
138 (setq url-privacy-level '(email lastloc)) ;; equivalent to 'high
139 (setq url-privacy-level '(os))
140
141::NOTE::
142This variable controls several other variables and is _NOT_ automatically
143updated. Call the function `url-setup-privacy-info' after modifying this
144variable."
145 :type '(radio (const :tag "None (you believe in the basic goodness of humanity)"
146 :value none)
147 (const :tag "Low (do not reveal last location)"
148 :value low)
149 (const :tag "High (no email address or last location)"
150 :value high)
151 (const :tag "Paranoid (reveal nothing!)"
152 :value paranoid)
153 (checklist :tag "Custom"
154 (const :tag "Email address" :value email)
155 (const :tag "Operating system" :value os)
156 (const :tag "Last location" :value lastloc)
157 (const :tag "Browser identification" :value agent)
158 (const :tag "No cookies" :value cookie)))
159 :group 'url)
160
161(defvar url-inhibit-uncompression nil "Do not do decompression if non-nil.")
162
163(defcustom url-uncompressor-alist '((".z" . "x-gzip")
164 (".gz" . "x-gzip")
165 (".uue" . "x-uuencoded")
166 (".hqx" . "x-hqx")
167 (".Z" . "x-compress")
168 (".bz2" . "x-bzip2"))
169 "*An alist of file extensions and appropriate content-transfer-encodings."
170 :type '(repeat (cons :format "%v"
171 (string :tag "Extension")
172 (string :tag "Encoding")))
173 :group 'url-mime)
174
175(defcustom url-mail-command (if (fboundp 'compose-mail)
176 'compose-mail
177 'url-mail)
178 "*This function will be called whenever url needs to send mail.
179It should enter a mail-mode-like buffer in the current window.
180The commands `mail-to' and `mail-subject' should still work in this
181buffer, and it should use `mail-header-separator' if possible."
182 :type 'function
183 :group 'url)
184
185(defcustom url-proxy-services nil
186 "*An alist of schemes and proxy servers that gateway them.
187Looks like ((\"http\" . \"hostname:portnumber\") ...). This is set up
188from the ACCESS_proxy environment variables."
189 :type '(repeat (cons :format "%v"
190 (string :tag "Protocol")
191 (string :tag "Proxy")))
192 :group 'url)
193
194(defcustom url-passwd-entry-func nil
195 "*Symbol indicating which function to call to read in a password.
196It will be set up depending on whether you are running EFS or ange-ftp
197at startup if it is nil. This function should accept the prompt
198string as its first argument, and the default value as its second
199argument."
200 :type '(choice (const :tag "Guess" :value nil)
201 (const :tag "Use Ange-FTP" :value ange-ftp-read-passwd)
202 (const :tag "Use EFS" :value efs-read-passwd)
203 (const :tag "Use Password Package" :value read-passwd)
204 (function :tag "Other"))
205 :group 'url-hairy)
206
207(defcustom url-standalone-mode nil
208 "*Rely solely on the cache?"
209 :type 'boolean
210 :group 'url-cache)
211
212(defvar url-mime-separator-chars (mapcar 'identity
213 (concat "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
214 "abcdefghijklmnopqrstuvwxyz"
215 "0123456789'()+_,-./=?"))
216 "Characters allowable in a MIME multipart separator.")
217
218(defcustom url-bad-port-list
219 '("25" "119" "19")
220 "*List of ports to warn the user about connecting to.
221Defaults to just the mail, chargen, and NNTP ports so you cannot be
222tricked into sending fake mail or forging messages by a malicious HTML
223document."
224 :type '(repeat (string :tag "Port"))
225 :group 'url-hairy)
226
227(defvar url-mime-content-type-charset-regexp
228 ";[ \t]*charset=\"?\\([^\"]+\\)\"?"
229 "Regexp used in parsing `Content-Type' for a charset indication.")
230
231(defvar url-request-data nil "Any data to send with the next request.")
232
233(defvar url-request-extra-headers nil
234 "A list of extra headers to send with the next request.
235Should be an assoc list of headers/contents.")
236
237(defvar url-request-method nil "The method to use for the next request.")
238
239;; FIXME!! (RFC 2616 gives examples like `compress, gzip'.)
240(defvar url-mime-encoding-string nil
241 "*String to send in the Accept-encoding: field in HTTP requests.")
242
243;; `mm-mime-mule-charset-alist' in Gnus 5.8/9 contains elements whose
244;; cars aren't valid MIME charsets/coding systems, at least in Emacs.
245;; This gets it correct by construction in Emacs. Fixme: DTRT for
246;; XEmacs -- its `coding-system-list' doesn't have the BASE-ONLY arg.
247(when (and (not (featurep 'xemacs))
248 (fboundp 'coding-system-list))
249 (setq mm-mime-mule-charset-alist
250 (apply
251 'nconc
252 (mapcar
253 (lambda (cs)
254 (when (and (coding-system-get cs 'mime-charset)
255 (not (eq t (coding-system-get cs 'safe-charsets))))
256 (list (cons (coding-system-get cs 'mime-charset)
257 (delq 'ascii
258 (coding-system-get cs 'safe-charsets))))))
259 (coding-system-list 'base-only)))))
260
261;; Perhaps the first few should actually be given decreasing `q's and
262;; the list should be trimmed significantly.
263;; Fixme: do something sane if we don't have `sort-coding-systems'
264;; (Emacs 20, XEmacs).
265(defun url-mime-charset-string ()
266 "Generate a list of preferred MIME charsets for HTTP requests.
267Generated according to current coding system priorities."
268 (if (fboundp 'sort-coding-systems)
269 (let ((ordered (sort-coding-systems
270 (let (accum)
271 (dolist (elt mm-mime-mule-charset-alist)
272 (if (mm-coding-system-p (car elt))
273 (push (car elt) accum)))
274 (nreverse accum)))))
275 (concat (format "%s;q=1, " (pop ordered))
276 (mapconcat 'symbol-name ordered ";q=0.5, ")
277 ";q=0.5"))))
278
279(defvar url-mime-charset-string (url-mime-charset-string)
280 "*String to send in the Accept-charset: field in HTTP requests.
281The MIME charset corresponding to the most preferred coding system is
282given priority 1 and the rest are given priority 0.5.")
283
284(defun url-set-mime-charset-string ()
285 (setq url-mime-charset-string (url-mime-charset-string)))
286;; Regenerate if the language environment changes.
287(add-hook 'set-language-environment-hook 'url-set-mime-charset-string)
288
289;; Fixme: set from the locale.
290(defcustom url-mime-language-string nil
291 "*String to send in the Accept-language: field in HTTP requests.
292
293Specifies the preferred language when servers can serve documents in
294several languages. Use RFC 1766 abbreviations, e.g.@: `en' for
295English, `de' for German. A comma-separated specifies descending
296order of preference. The ordering can be made explicit using `q'
297factors defined by HTTP, e.g. `de,en-gb;q=0.8,en;q=0.7'. `*' means
298get the first available language (as opposed to the default)."
299 :type '(radio
300 (const :tag "None (get default language version)" :value nil)
301 (const :tag "Any (get first available language version)" :value "*")
302 (string :tag "Other"))
303 :group 'url-mime
304 :group 'i18n)
305
306(defvar url-mime-accept-string nil
307 "String to send to the server in the Accept: field in HTTP requests.")
308
309(defvar url-package-version nil
310 "Version number of package using URL.")
311
312(defvar url-package-name nil "Version number of package using URL.")
313
314(defvar url-system-type nil
315 "What type of system we are on.")
316(defvar url-os-type nil
317 "What OS we are on.")
318
319(defcustom url-max-password-attempts 5
320 "*Maximum number of times a password will be prompted for.
321Applies when a protected document is denied by the server."
322 :type 'integer
323 :group 'url)
324
325(defcustom url-temporary-directory (or (getenv "TMPDIR") "/tmp")
326 "*Where temporary files go."
327 :type 'directory
328 :group 'url-file)
329
330(defcustom url-show-status t
331 "*Whether to show a running total of bytes transferred.
332Can cause a large hit if using a remote X display over a slow link, or
333a terminal with a slow modem."
334 :type 'boolean
335 :group 'url)
336
337(defvar url-using-proxy nil
338 "Either nil or the fully qualified proxy URL in use, e.g.
339http://www.domain.com/")
340
341(defcustom url-news-server nil
342 "*The default news server from which to get newsgroups/articles.
343Applies if no server is specified in the URL. Defaults to the
344environment variable NNTPSERVER or \"news\" if NNTPSERVER is
345undefined."
346 :type '(choice (const :tag "None" :value nil) string)
347 :group 'url)
348
349(defvar url-nonrelative-link
350 "\\`\\([-a-zA-Z0-9+.]+:\\)"
351 "A regular expression that will match an absolute URL.")
352
353(defcustom url-confirmation-func 'y-or-n-p
354 "*What function to use for asking yes or no functions.
355Possible values are `yes-or-no-p' or `y-or-n-p', or any function that
356takes a single argument (the prompt), and returns t only if a positive
357answer is given."
358 :type '(choice (const :tag "Short (y or n)" :value y-or-n-p)
359 (const :tag "Long (yes or no)" :value yes-or-no-p)
360 (function :tag "Other"))
361 :group 'url-hairy)
362
363(defcustom url-gateway-method 'native
364 "*The type of gateway support to use.
365Should be a symbol specifying how to get a connection from the local machine.
366
367Currently supported methods:
368`telnet': Run telnet in a subprocess to connect;
369`rlogin': Rlogin to another machine to connect;
370`socks': Connect through a socks server;
371`tls': Connect with TLS;
372`ssl': Connect with SSL (deprecated, use `tls' instead);
373`native': Connect directy."
374 :type '(radio (const :tag "Telnet to gateway host" :value telnet)
375 (const :tag "Rlogin to gateway host" :value rlogin)
376 (const :tag "Use SOCKS proxy" :value socks)
377 (const :tag "Use SSL/TLS for all connections" :value tls)
378 (const :tag "Use SSL for all connections (obsolete)" :value ssl)
379 (const :tag "Direct connection" :value native))
380 :group 'url-hairy)
381
382(defvar url-setup-done nil "Has setup configuration been done?")
383
384(defconst weekday-alist
385 '(("Sunday" . 0) ("Monday" . 1) ("Tuesday" . 2) ("Wednesday" . 3)
386 ("Thursday" . 4) ("Friday" . 5) ("Saturday" . 6)
387 ("Tues" . 2) ("Thurs" . 4)
388 ("Sun" . 0) ("Mon" . 1) ("Tue" . 2) ("Wed" . 3)
389 ("Thu" . 4) ("Fri" . 5) ("Sat" . 6)))
390
391(defconst monthabbrev-alist
392 '(("Jan" . 1) ("Feb" . 2) ("Mar" . 3) ("Apr" . 4) ("May" . 5) ("Jun" . 6)
393 ("Jul" . 7) ("Aug" . 8) ("Sep" . 9) ("Oct" . 10) ("Nov" . 11)
394 ("Dec" . 12)))
395
396(defvar url-lazy-message-time 0)
397
398;; Fixme: We may not be able to run SSL.
399(defvar url-extensions-header "Security/Digest Security/SSL")
400
401(defvar url-parse-syntax-table
402 (copy-syntax-table emacs-lisp-mode-syntax-table)
403 "*A syntax table for parsing URLs.")
404
405(modify-syntax-entry ?' "\"" url-parse-syntax-table)
406(modify-syntax-entry ?` "\"" url-parse-syntax-table)
407(modify-syntax-entry ?< "(>" url-parse-syntax-table)
408(modify-syntax-entry ?> ")<" url-parse-syntax-table)
409(modify-syntax-entry ?/ " " url-parse-syntax-table)
410
411(defvar url-load-hook nil
412 "*Hooks to be run after initalizing the URL library.")
413
414;;; Make OS/2 happy - yeeks
415;; (defvar tcp-binary-process-input-services nil
416;; "*Make OS/2 happy with our CRLF pairs...")
417
418(defconst url-working-buffer " *url-work")
419
420(defvar url-gateway-unplugged nil
421 "Non-nil means don't open new network connexions.
422This should be set, e.g. by mail user agents rendering HTML to avoid
423`bugs' which call home.")
424
425(defun url-vars-unload-hook ()
426 (remove-hook 'set-language-environment-hook 'url-set-mime-charset-string))
427
428(provide 'url-vars)
429
430;;; arch-tag: 29205e5f-c5ce-433c-8d5d-38cbaed64b49
431;;; url-vars.el ends here
diff --git a/lisp/url/url.el b/lisp/url/url.el
new file mode 100644
index 00000000000..f7b1b717681
--- /dev/null
+++ b/lisp/url/url.el
@@ -0,0 +1,269 @@
1;;; url.el --- Uniform Resource Locator retrieval tool
2
3;; Copyright (c) 1996,1997,1998,1999,2001,2004 Free Software Foundation, Inc.
4
5;; Author: Bill Perry <wmperry@gnu.org>
6;; Keywords: comm, data, processes, hypermedia
7
8;; This file is part of GNU Emacs.
9;;
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14;;
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19;;
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
24
25;;; Commentary:
26
27;; Registered URI schemes: http://www.iana.org/assignments/uri-schemes
28
29;;; Code:
30
31(eval-when-compile (require 'cl))
32;; Don't require CL at runtime if we can avoid it (Emacs 21).
33;; Otherwise we need it for hashing functions. `puthash' was never
34;; defined in the Emacs 20 cl.el for some reason.
35(if (fboundp 'puthash)
36 nil ; internal or CL is loaded
37 (defalias 'puthash 'cl-puthash)
38 (autoload 'cl-puthash "cl")
39 (autoload 'gethash "cl")
40 (autoload 'maphash "cl")
41 (autoload 'make-hash-table "cl"))
42
43(eval-when-compile
44 (require 'mm-decode)
45 (require 'mm-view))
46
47(require 'mailcap)
48(require 'url-vars)
49(require 'url-cookie)
50(require 'url-history)
51(require 'url-expand)
52(require 'url-privacy)
53(require 'url-methods)
54(require 'url-proxy)
55(require 'url-parse)
56(require 'url-util)
57
58;; Fixme: customize? convert-standard-filename?
59;;;###autoload
60(defvar url-configuration-directory "~/.url")
61
62(defun url-do-setup ()
63 "Setup the url package.
64This is to avoid conflict with user settings if URL is dumped with
65Emacs."
66 (unless url-setup-done
67
68 ;; Make OS/2 happy
69 ;;(push '("http" "80") tcp-binary-process-input-services)
70
71 (mailcap-parse-mailcaps)
72 (mailcap-parse-mimetypes)
73
74 ;; Register all the authentication schemes we can handle
75 (url-register-auth-scheme "basic" nil 4)
76 (url-register-auth-scheme "digest" nil 7)
77
78 (setq url-cookie-file
79 (or url-cookie-file
80 (expand-file-name "cookies" url-configuration-directory)))
81
82 (setq url-history-file
83 (or url-history-file
84 (expand-file-name "history" url-configuration-directory)))
85
86 ;; Parse the global history file if it exists, so that it can be used
87 ;; for URL completion, etc.
88 (url-history-parse-history)
89 (url-history-setup-save-timer)
90
91 ;; Ditto for cookies
92 (url-cookie-setup-save-timer)
93 (url-cookie-parse-file url-cookie-file)
94
95 ;; Read in proxy gateways
96 (let ((noproxy (and (not (assoc "no_proxy" url-proxy-services))
97 (or (getenv "NO_PROXY")
98 (getenv "no_PROXY")
99 (getenv "no_proxy")))))
100 (if noproxy
101 (setq url-proxy-services
102 (cons (cons "no_proxy"
103 (concat "\\("
104 (mapconcat
105 (lambda (x)
106 (cond
107 ((= x ?,) "\\|")
108 ((= x ? ) "")
109 ((= x ?.) (regexp-quote "."))
110 ((= x ?*) ".*")
111 ((= x ??) ".")
112 (t (char-to-string x))))
113 noproxy "") "\\)"))
114 url-proxy-services))))
115
116 ;; Set the password entry funtion based on user defaults or guess
117 ;; based on which remote-file-access package they are using.
118 (cond
119 (url-passwd-entry-func nil) ; Already been set
120 ((fboundp 'read-passwd) ; Use secure password if available
121 (setq url-passwd-entry-func 'read-passwd))
122 ((or (featurep 'efs) ; Using EFS
123 (featurep 'efs-auto)) ; or autoloading efs
124 (if (not (fboundp 'read-passwd))
125 (autoload 'read-passwd "passwd" "Read in a password" nil))
126 (setq url-passwd-entry-func 'read-passwd))
127 ((or (featurep 'ange-ftp) ; Using ange-ftp
128 (and (boundp 'file-name-handler-alist)
129 (not (featurep 'xemacs)))) ; ??
130 (setq url-passwd-entry-func 'ange-ftp-read-passwd))
131 (t
132 (url-warn
133 'security
134 "(url-setup): Can't determine how to read passwords, winging it.")))
135
136 (url-setup-privacy-info)
137 (run-hooks 'url-load-hook)
138 (setq url-setup-done t)))
139
140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
141;;; Retrieval functions
142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
143(defun url-retrieve (url callback &optional cbargs)
144 "Retrieve URL asynchronously and call CALLBACK with CBARGS when finished.
145The callback is called when the object has been completely retrieved, with
146the current buffer containing the object, and any MIME headers associated
147with it. URL is either a string or a parsed URL.
148
149Return the buffer URL will load into, or nil if the process has
150already completed."
151 (url-do-setup)
152 (url-gc-dead-buffers)
153 (if (stringp url)
154 (set-text-properties 0 (length url) nil url))
155 (if (not (vectorp url))
156 (setq url (url-generic-parse-url url)))
157 (if (not (functionp callback))
158 (error "Must provide a callback function to url-retrieve"))
159 (unless (url-type url)
160 (error "Bad url: %s" (url-recreate-url url)))
161 (let ((loader (url-scheme-get-property (url-type url) 'loader))
162 (url-using-proxy (if (url-host url)
163 (url-find-proxy-for-url url (url-host url))))
164 (buffer nil)
165 (asynch (url-scheme-get-property (url-type url) 'asynchronous-p)))
166 (if url-using-proxy
167 (setq asynch t
168 loader 'url-proxy))
169 (if asynch
170 (setq buffer (funcall loader url callback cbargs))
171 (setq buffer (funcall loader url))
172 (if buffer
173 (with-current-buffer buffer
174 (apply callback cbargs))))
175 (url-history-update-url url (current-time))
176 buffer))
177
178(defun url-retrieve-synchronously (url)
179 "Retrieve URL synchronously.
180Return the buffer containing the data, or nil if there are no data
181associated with it (the case for dired, info, or mailto URLs that need
182no further processing). URL is either a string or a parsed URL."
183 (url-do-setup)
184
185 (lexical-let ((retrieval-done nil)
186 (asynch-buffer nil))
187 (setq asynch-buffer
188 (url-retrieve url (lambda (&rest ignored)
189 (url-debug 'retrieval "Synchronous fetching done (%S)" (current-buffer))
190 (setq retrieval-done t
191 asynch-buffer (current-buffer)))))
192 (if (not asynch-buffer)
193 ;; We do not need to do anything, it was a mailto or something
194 ;; similar that takes processing completely outside of the URL
195 ;; package.
196 nil
197 (while (not retrieval-done)
198 (url-debug 'retrieval "Spinning in url-retrieve-synchronously: %S (%S)"
199 retrieval-done asynch-buffer)
200 ;; Quoth Stef:
201 ;; It turns out that the problem seems to be that the (sit-for
202 ;; 0.1) below doesn't actually process the data: instead it
203 ;; returns immediately because there is keyboard input
204 ;; waiting, so we end up spinning endlessly waiting for the
205 ;; process to finish while not letting it finish.
206
207 ;; However, raman claims that it blocks Emacs with Emacspeak
208 ;; for unexplained reasons. Put back for his benefit until
209 ;; someone can understand it.
210 ;; (sleep-for 0.1)
211 (sit-for 0.1))
212 asynch-buffer)))
213
214(defun url-mm-callback (&rest ignored)
215 (let ((handle (mm-dissect-buffer t)))
216 (save-excursion
217 (url-mark-buffer-as-dead (current-buffer))
218 (set-buffer (generate-new-buffer (url-recreate-url url-current-object)))
219 (if (eq (mm-display-part handle) 'external)
220 (progn
221 (set-process-sentinel
222 ;; Fixme: this shouldn't have to know the form of the
223 ;; undisplayer produced by `mm-display-part'.
224 (get-buffer-process (cdr (mm-handle-undisplayer handle)))
225 `(lambda (proc event)
226 (mm-destroy-parts (quote ,handle))))
227 (message "Viewing externally")
228 (kill-buffer (current-buffer)))
229 (display-buffer (current-buffer))
230 (mm-destroy-parts handle)))))
231
232(defun url-mm-url (url)
233 "Retrieve URL and pass to the appropriate viewing application."
234 (require 'mm-decode)
235 (require 'mm-view)
236 (url-retrieve url 'url-mm-callback nil))
237
238;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
239;;; Miscellaneous
240;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241(defvar url-dead-buffer-list nil)
242
243(defun url-mark-buffer-as-dead (buff)
244 (push buff url-dead-buffer-list))
245
246(defun url-gc-dead-buffers ()
247 (let ((buff))
248 (while (setq buff (pop url-dead-buffer-list))
249 (if (buffer-live-p buff)
250 (kill-buffer buff)))))
251
252(cond
253 ((fboundp 'display-warning)
254 (defalias 'url-warn 'display-warning))
255 ((fboundp 'warn)
256 (defun url-warn (class message &optional level)
257 (warn "(%s/%s) %s" class (or level 'warning) message)))
258 (t
259 (defun url-warn (class message &optional level)
260 (with-current-buffer (get-buffer-create "*URL-WARNINGS*")
261 (goto-char (point-max))
262 (save-excursion
263 (insert (format "(%s/%s) %s\n" class (or level 'warning) message)))
264 (display-buffer (current-buffer))))))
265
266(provide 'url)
267
268;; arch-tag: bc182f1f-d187-4f10-b961-47af2066579a
269;;; url.el ends here