* net/tramp-cmds.el (tramp-cleanup-connection): Clean up
[bpt/emacs.git] / lisp / net / tramp-cmds.el
CommitLineData
9c13938d
MA
1;;; tramp-cmds.el --- Interactive commands for Tramp
2
ab422c4d 3;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
9c13938d
MA
4
5;; Author: Michael Albinus <michael.albinus@gmx.de>
6;; Keywords: comm, processes
bd78fa1d 7;; Package: tramp
9c13938d
MA
8
9;; This file is part of GNU Emacs.
10
874a927a 11;; GNU Emacs is free software: you can redistribute it and/or modify
9c13938d 12;; it under the terms of the GNU General Public License as published by
874a927a
GM
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
9c13938d
MA
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
874a927a 22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
9c13938d
MA
23
24;;; Commentary:
25
40ba43b4 26;; This package provides all interactive commands which are related
9c13938d
MA
27;; to Tramp.
28
29;;; Code:
30
31(require 'tramp)
32
b74f0d96 33;; Pacify byte-compiler.
f95527c8
MA
34(defvar reporter-eval-buffer)
35(defvar reporter-prompt-for-summary-p)
b74f0d96 36
9c13938d
MA
37(defun tramp-list-tramp-buffers ()
38 "Return a list of all Tramp connection buffers."
39 (append
40 (all-completions
41 "*tramp" (mapcar 'list (mapcar 'buffer-name (buffer-list))))
42 (all-completions
43 "*debug tramp" (mapcar 'list (mapcar 'buffer-name (buffer-list))))))
44
45(defun tramp-list-remote-buffers ()
46 "Return a list of all buffers with remote default-directory."
47 (delq
48 nil
49 (mapcar
50 (lambda (x)
4c1f03ef 51 (with-current-buffer x (when (tramp-tramp-file-p default-directory) x)))
9c13938d
MA
52 (buffer-list))))
53
c6f2191f 54;;;###tramp-autoload
6480194c 55(defun tramp-cleanup-connection (vec &optional keep-debug keep-password)
9c13938d 56 "Flush all connection related objects.
6480194c
MA
57This includes password cache, file cache, connection cache,
58buffers. KEEP-DEBUG non-nil preserves the debug buffer.
59KEEP-PASSWORD non-nil preserves the password cache.
9c13938d
MA
60When called interactively, a Tramp connection has to be selected."
61 (interactive
62 ;; When interactive, select the Tramp remote identification.
63 ;; Return nil when there is no Tramp connection.
64 (list
65 (let ((connections
66 (mapcar
67 (lambda (x)
726f0272
MA
68 (tramp-make-tramp-file-name
69 (tramp-file-name-method x)
70 (tramp-file-name-user x)
71 (tramp-file-name-host x)
72 (tramp-file-name-localname x)))
b08104a0 73 (tramp-list-connections)))
9c13938d
MA
74 name)
75
76 (when connections
77 (setq name
78 (completing-read
79 "Enter Tramp connection: " connections nil t
80 (try-completion "" connections)))
4c1f03ef 81 (and (tramp-tramp-file-p name) (tramp-dissect-file-name name))))
6480194c 82 nil nil))
9c13938d
MA
83
84 (if (not vec)
85 ;; Nothing to do.
86 (message "No Tramp connection found.")
87
355204dd
MA
88 ;; Cleanup `tramp-current-connection'. Otherwise, we would be
89 ;; suppressed in the test suite.
90 (setq tramp-current-connection nil)
91
9c13938d 92 ;; Flush password cache.
6480194c 93 (unless keep-password (tramp-clear-passwd vec))
9c13938d
MA
94
95 ;; Flush file cache.
e09349c5 96 (tramp-flush-directory-property vec "")
9c13938d
MA
97
98 ;; Flush connection cache.
2fe4b125
MA
99 (when (processp (tramp-get-connection-process vec))
100 (delete-process (tramp-get-connection-process vec))
101 (tramp-flush-connection-property (tramp-get-connection-process vec)))
9d7cb26e 102 (tramp-flush-connection-property vec)
9c13938d
MA
103
104 ;; Remove buffers.
105 (dolist
106 (buf (list (get-buffer (tramp-buffer-name vec))
6480194c
MA
107 (unless keep-debug
108 (get-buffer (tramp-debug-buffer-name vec)))
9c13938d
MA
109 (tramp-get-connection-property vec "process-buffer" nil)))
110 (when (bufferp buf) (kill-buffer buf)))))
111
6d95bd46
MA
112;;;###tramp-autoload
113(defun tramp-cleanup-this-connection ()
114 "Flush all connection related objects of the current buffer's connection."
115 (interactive)
4c1f03ef 116 (and (tramp-tramp-file-p default-directory)
6d95bd46
MA
117 (tramp-cleanup-connection
118 (tramp-dissect-file-name default-directory 'noexpand))))
119
4bc3c53d 120;;;###tramp-autoload
9c13938d
MA
121(defun tramp-cleanup-all-connections ()
122 "Flush all Tramp internal objects.
123This includes password cache, file cache, connection cache, buffers."
124 (interactive)
125
6f77e7d7
MA
126 ;; Unlock Tramp.
127 (setq tramp-locked nil)
128
9c13938d 129 ;; Flush password cache.
0d5852cf 130 (tramp-compat-funcall 'password-reset)
9c13938d
MA
131
132 ;; Flush file and connection cache.
133 (clrhash tramp-cache-data)
134
135 ;; Remove buffers.
136 (dolist (name (tramp-list-tramp-buffers))
137 (when (bufferp (get-buffer name)) (kill-buffer name))))
138
4bc3c53d 139;;;###tramp-autoload
9c13938d
MA
140(defun tramp-cleanup-all-buffers ()
141 "Kill all remote buffers."
142 (interactive)
143
144 ;; Remove all Tramp related buffers.
145 (tramp-cleanup-all-connections)
146
147 ;; Remove all buffers with a remote default-directory.
148 (dolist (name (tramp-list-remote-buffers))
149 (when (bufferp (get-buffer name)) (kill-buffer name))))
150
a4aeb9a4
MA
151;; Tramp version is useful in a number of situations.
152
0f34aa77 153;;;###tramp-autoload
a4aeb9a4
MA
154(defun tramp-version (arg)
155 "Print version number of tramp.el in minibuffer or current buffer."
156 (interactive "P")
157 (if arg (insert tramp-version) (message tramp-version)))
158
159;; Make the `reporter` functionality available for making bug reports about
160;; the package. A most useful piece of code.
161
162(autoload 'reporter-submit-bug-report "reporter")
163
4bc3c53d 164;;;###tramp-autoload
a4aeb9a4
MA
165(defun tramp-bug ()
166 "Submit a bug report to the Tramp developers."
167 (interactive)
168 (require 'reporter)
169 (catch 'dont-send
170 (let ((reporter-prompt-for-summary-p t))
171 (reporter-submit-bug-report
172 tramp-bug-report-address ; to-address
173 (format "tramp (%s)" tramp-version) ; package name and version
4bc3c53d
MA
174 (sort
175 (delq nil (mapcar
176 (lambda (x)
177 (and x (boundp x) (cons x 'tramp-reporter-dump-variable)))
178 (append
179 (mapcar 'intern (all-completions "tramp-" obarray 'boundp))
180 ;; Non-tramp variables of interest.
181 '(shell-prompt-pattern
182 backup-by-copying
183 backup-by-copying-when-linked
184 backup-by-copying-when-mismatch
185 backup-by-copying-when-privileged-mismatch
186 backup-directory-alist
187 bkup-backup-directory-info
188 password-cache
189 password-cache-expiry
190 remote-file-name-inhibit-cache
191 file-name-handler-alist))))
192 (lambda (x y) (string< (symbol-name (car x)) (symbol-name (car y)))))
a4aeb9a4
MA
193
194 'tramp-load-report-modules ; pre-hook
195 'tramp-append-tramp-buffers ; post-hook
a2f93a5f 196 (tramp-compat-funcall
af9ff9e8
MA
197 (if (functionp 'propertize) 'propertize 'progn)
198 "\n" 'display "\
a4aeb9a4
MA
199Enter your bug report in this message, including as much detail
200as you possibly can about the problem, what you did to cause it
201and what the local and remote machines are.
202
203If you can give a simple set of instructions to make this bug
204happen reliably, please include those. Thank you for helping
205kill bugs in Tramp.
206
6fa5052f
MA
207Before reproducing the bug, you might apply
208
209 M-x tramp-cleanup-all-connections
210
211This allows to investigate from a clean environment. Another
212useful thing to do is to put
a4aeb9a4 213
8fbcce2d 214 (setq tramp-verbose 9)
a4aeb9a4 215
865fe16f 216in your init file and to repeat the bug. Then, include the
a4aeb9a4
MA
217contents of the *tramp/foo* buffer and the *debug tramp/foo*
218buffer in your bug report.
219
220--bug report follows this line--
19b50424 221")))))
a4aeb9a4
MA
222
223(defun tramp-reporter-dump-variable (varsym mailbuf)
4bc3c53d 224 "Pretty-print the value of the variable in symbol VARSYM."
a4aeb9a4
MA
225 (let* ((reporter-eval-buffer (symbol-value 'reporter-eval-buffer))
226 (val (with-current-buffer reporter-eval-buffer
227 (symbol-value varsym))))
228
229 (if (hash-table-p val)
230 ;; Pretty print the cache.
231 (set varsym (read (format "(%s)" (tramp-cache-print val))))
4bc3c53d 232 ;; There are non-7bit characters to be masked.
a4aeb9a4 233 (when (and (boundp 'mm-7bit-chars)
4bc3c53d 234 (stringp val)
a4aeb9a4
MA
235 (string-match
236 (concat "[^" (symbol-value 'mm-7bit-chars) "]") val))
237 (with-current-buffer reporter-eval-buffer
4bc3c53d 238 (set varsym (format "(base64-decode-string \"%s\")"
a4aeb9a4
MA
239 (base64-encode-string val))))))
240
241 ;; Dump variable.
0d5852cf 242 (tramp-compat-funcall 'reporter-dump-variable varsym mailbuf)
a4aeb9a4
MA
243
244 (unless (hash-table-p val)
245 ;; Remove string quotation.
246 (forward-line -1)
247 (when (looking-at
248 (concat "\\(^.*\\)" "\"" ;; \1 "
249 "\\((base64-decode-string \\)" "\\\\" ;; \2 \
250 "\\(\".*\\)" "\\\\" ;; \3 \
251 "\\(\")\\)" "\"$")) ;; \4 "
252 (replace-match "\\1\\2\\3\\4")
253 (beginning-of-line)
4bc3c53d 254 (insert " ;; Variable encoded due to non-printable characters.\n"))
a4aeb9a4
MA
255 (forward-line 1))
256
257 ;; Reset VARSYM to old value.
258 (with-current-buffer reporter-eval-buffer
259 (set varsym val))))
260
261(defun tramp-load-report-modules ()
262 "Load needed modules for reporting."
a4aeb9a4
MA
263 ;; We load message.el and mml.el from Gnus.
264 (if (featurep 'xemacs)
265 (progn
266 (load "message" 'noerror)
267 (load "mml" 'noerror))
268 (require 'message nil 'noerror)
269 (require 'mml nil 'noerror))
0d5852cf
MA
270 (tramp-compat-funcall 'message-mode)
271 (tramp-compat-funcall 'mml-mode t))
a4aeb9a4
MA
272
273(defun tramp-append-tramp-buffers ()
274 "Append Tramp buffers and buffer local variables into the bug report."
a4aeb9a4
MA
275 (goto-char (point-max))
276
277 ;; Dump buffer local variables.
13c366c9 278 (insert "\nlocal variables:\n================")
a4aeb9a4
MA
279 (dolist (buffer
280 (delq nil
281 (mapcar
4f91a816
SM
282 (lambda (b)
283 (when (string-match "\\*tramp/" (buffer-name b)) b))
a4aeb9a4
MA
284 (buffer-list))))
285 (let ((reporter-eval-buffer buffer)
a4aeb9a4
MA
286 (elbuf (get-buffer-create " *tmp-reporter-buffer*")))
287 (with-current-buffer elbuf
288 (emacs-lisp-mode)
289 (erase-buffer)
13c366c9 290 (insert (format "\n;; %s\n(setq-local\n" (buffer-name buffer)))
a4aeb9a4 291 (lisp-indent-line)
13c366c9
MA
292 (dolist
293 (varsym
294 (sort
295 (append
296 (mapcar
297 'intern
298 (all-completions "tramp-" (buffer-local-variables buffer)))
299 ;; Non-tramp variables of interest.
300 '(default-directory))
301 'string<))
302 (tramp-compat-funcall 'reporter-dump-variable varsym elbuf))
a4aeb9a4
MA
303 (lisp-indent-line)
304 (insert ")\n"))
305 (insert-buffer-substring elbuf)))
306
22b300de
MA
307 ;; Dump load-path shadows.
308 (insert "\nload-path shadows:\n==================\n")
309 (ignore-errors
957b3189
MA
310 (mapc
311 (lambda (x) (when (string-match "tramp" x) (insert x "\n")))
312 (split-string (tramp-compat-funcall 'list-load-path-shadows t) "\n")))
22b300de 313
a4aeb9a4
MA
314 ;; Append buffers only when we are in message mode.
315 (when (and
316 (eq major-mode 'message-mode)
317 (boundp 'mml-mode)
318 (symbol-value 'mml-mode))
319
320 (let ((tramp-buf-regexp "\\*\\(debug \\)?tramp/")
0d5852cf 321 (buffer-list (tramp-compat-funcall 'tramp-list-tramp-buffers))
a4aeb9a4
MA
322 (curbuf (current-buffer)))
323
324 ;; There is at least one Tramp buffer.
325 (when buffer-list
8bdfa064 326 (switch-to-buffer (list-buffers-noselect nil))
a4aeb9a4
MA
327 (delete-other-windows)
328 (setq buffer-read-only nil)
329 (goto-char (point-min))
330 (while (not (eobp))
6e060cee 331 (if (re-search-forward tramp-buf-regexp (point-at-eol) t)
a4aeb9a4
MA
332 (forward-line 1)
333 (forward-line 0)
334 (let ((start (point)))
335 (forward-line 1)
336 (kill-region start (point)))))
337 (insert "
338The buffer(s) above will be appended to this message. If you
339don't want to append a buffer because it contains sensitive data,
340or because the buffer is too large, you should delete the
341respective buffer. The buffer(s) will contain user and host
342names. Passwords will never be included there.")
343
344 (when (>= tramp-verbose 6)
345 (insert "\n\n")
346 (let ((start (point)))
347 (insert "\
348Please note that you have set `tramp-verbose' to a value of at
349least 6. Therefore, the contents of files might be included in
350the debug buffer(s).")
351 (add-text-properties start (point) (list 'face 'italic))))
352
353 (set-buffer-modified-p nil)
354 (setq buffer-read-only t)
355 (goto-char (point-min))
356
357 (if (y-or-n-p "Do you want to append the buffer(s)? ")
358 ;; OK, let's send. First we delete the buffer list.
359 (progn
360 (kill-buffer nil)
8bdfa064 361 (switch-to-buffer curbuf)
a4aeb9a4 362 (goto-char (point-max))
a2f93a5f 363 (insert (tramp-compat-funcall 'propertize "\n" 'display "\n\
a4aeb9a4
MA
364This is a special notion of the `gnus/message' package. If you
365use another mail agent (by copying the contents of this buffer)
19b50424 366please ensure that the buffers are attached to your email.\n\n"))
a4aeb9a4 367 (dolist (buffer buffer-list)
0d5852cf
MA
368 (tramp-compat-funcall
369 'mml-insert-empty-tag 'part 'type "text/plain"
370 'encoding "base64" 'disposition "attachment" 'buffer buffer
371 'description buffer))
a4aeb9a4
MA
372 (set-buffer-modified-p nil))
373
374 ;; Don't send. Delete the message buffer.
375 (set-buffer curbuf)
376 (set-buffer-modified-p nil)
377 (kill-buffer nil)
378 (throw 'dont-send nil))))))
379
380(defalias 'tramp-submit-bug 'tramp-bug)
381
0f34aa77
MA
382(add-hook 'tramp-unload-hook
383 (lambda () (unload-feature 'tramp-cmds 'force)))
384
9c13938d
MA
385(provide 'tramp-cmds)
386
387;;; TODO:
388
389;; * Clean up unused *tramp/foo* buffers after a while. (Pete Forman)
a4aeb9a4 390;; * WIBNI there was an interactive command prompting for Tramp
9c13938d
MA
391;; method, hostname, username and filename and translates the user
392;; input into the correct filename syntax (depending on the Emacs
0f34aa77 393;; flavor) (Reiner Steib)
9c13938d
MA
394;; * Let the user edit the connection properties interactively.
395;; Something like `gnus-server-edit-server' in Gnus' *Server* buffer.
9c13938d
MA
396
397;;; tramp-cmds.el ends here