diff options
| author | Michael Albinus | 2013-10-16 15:16:53 +0200 |
|---|---|---|
| committer | Michael Albinus | 2013-10-16 15:16:53 +0200 |
| commit | f19da8ad3fad7c8b762b58c599ad366b6e59e932 (patch) | |
| tree | 3cf08e6aeaedf65683a1cbee1aad480ca122cf6c | |
| parent | 17b9dc45a7cc3284351066ecad1895ae17d27484 (diff) | |
| download | emacs-f19da8ad3fad7c8b762b58c599ad366b6e59e932.tar.gz emacs-f19da8ad3fad7c8b762b58c599ad366b6e59e932.zip | |
* net/tramp-smb.el (tramp-smb-acl-program): New customer option.
(tramp-smb-errors): Add error messages.
(tramp-smb-actions-with-acl): New defconst.
(tramp-smb-file-name-handler-alist) [set-file-acl]: Add handler.
(tramp-smb-action-with-acl, tramp-smb-handle-set-file-acl): New defuns.
(tramp-smb-handle-file-acl): Rewrite, using "smbcacls".
(tramp-smb-handle-file-attributes): Simplify test for "stat" capability.
(tramp-smb-get-stat-capability): Fix tests.
| -rw-r--r-- | lisp/ChangeLog | 11 | ||||
| -rw-r--r-- | lisp/net/tramp-smb.el | 177 |
2 files changed, 171 insertions, 17 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 134219a16d3..ea8d936cf4c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2013-10-16 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * net/tramp-smb.el (tramp-smb-acl-program): New customer option. | ||
| 4 | (tramp-smb-errors): Add error messages. | ||
| 5 | (tramp-smb-actions-with-acl): New defconst. | ||
| 6 | (tramp-smb-file-name-handler-alist) [set-file-acl]: Add handler. | ||
| 7 | (tramp-smb-action-with-acl, tramp-smb-handle-set-file-acl): New defuns. | ||
| 8 | (tramp-smb-handle-file-acl): Rewrite, using "smbcacls". | ||
| 9 | (tramp-smb-handle-file-attributes): Simplify test for "stat" capability. | ||
| 10 | (tramp-smb-get-stat-capability): Fix tests. | ||
| 11 | |||
| 1 | 2013-10-16 Dima Kogan <dima@secretsauce.net> (tiny change) | 12 | 2013-10-16 Dima Kogan <dima@secretsauce.net> (tiny change) |
| 2 | 13 | ||
| 3 | * progmodes/subword.el (subword-capitalize): Fix Stefan's mess | 14 | * progmodes/subword.el (subword-capitalize): Fix Stefan's mess |
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 03ad62be0a5..1daf19b47ac 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el | |||
| @@ -75,6 +75,12 @@ | |||
| 75 | :group 'tramp | 75 | :group 'tramp |
| 76 | :type 'string) | 76 | :type 'string) |
| 77 | 77 | ||
| 78 | (defcustom tramp-smb-acl-program "smbcacls" | ||
| 79 | "Name of SMB acls to run." | ||
| 80 | :group 'tramp | ||
| 81 | :type 'string | ||
| 82 | :version "24.4") | ||
| 83 | |||
| 78 | (defcustom tramp-smb-conf "/dev/null" | 84 | (defcustom tramp-smb-conf "/dev/null" |
| 79 | "Path of the smb.conf file. | 85 | "Path of the smb.conf file. |
| 80 | If it is nil, no smb.conf will be added to the `tramp-smb-program' | 86 | If it is nil, no smb.conf will be added to the `tramp-smb-program' |
| @@ -129,11 +135,14 @@ call, letting the SMB client use the default one." | |||
| 129 | "NT_STATUS_DIRECTORY_NOT_EMPTY" | 135 | "NT_STATUS_DIRECTORY_NOT_EMPTY" |
| 130 | "NT_STATUS_DUPLICATE_NAME" | 136 | "NT_STATUS_DUPLICATE_NAME" |
| 131 | "NT_STATUS_FILE_IS_A_DIRECTORY" | 137 | "NT_STATUS_FILE_IS_A_DIRECTORY" |
| 138 | "NT_STATUS_HOST_UNREACHABLE" | ||
| 132 | "NT_STATUS_IMAGE_ALREADY_LOADED" | 139 | "NT_STATUS_IMAGE_ALREADY_LOADED" |
| 140 | "NT_STATUS_INVALID_LEVEL" | ||
| 133 | "NT_STATUS_IO_TIMEOUT" | 141 | "NT_STATUS_IO_TIMEOUT" |
| 134 | "NT_STATUS_LOGON_FAILURE" | 142 | "NT_STATUS_LOGON_FAILURE" |
| 135 | "NT_STATUS_NETWORK_ACCESS_DENIED" | 143 | "NT_STATUS_NETWORK_ACCESS_DENIED" |
| 136 | "NT_STATUS_NOT_IMPLEMENTED" | 144 | "NT_STATUS_NOT_IMPLEMENTED" |
| 145 | "NT_STATUS_NO_LOGON_SERVERS" | ||
| 137 | "NT_STATUS_NO_SUCH_FILE" | 146 | "NT_STATUS_NO_SUCH_FILE" |
| 138 | "NT_STATUS_NO_SUCH_USER" | 147 | "NT_STATUS_NO_SUCH_USER" |
| 139 | "NT_STATUS_OBJECT_NAME_COLLISION" | 148 | "NT_STATUS_OBJECT_NAME_COLLISION" |
| @@ -178,6 +187,16 @@ This list is used for tar-like copy of directories. | |||
| 178 | 187 | ||
| 179 | See `tramp-actions-before-shell' for more info.") | 188 | See `tramp-actions-before-shell' for more info.") |
| 180 | 189 | ||
| 190 | (defconst tramp-smb-actions-with-acl | ||
| 191 | '((tramp-password-prompt-regexp tramp-action-password) | ||
| 192 | (tramp-wrong-passwd-regexp tramp-action-permission-denied) | ||
| 193 | (tramp-smb-errors tramp-action-permission-denied) | ||
| 194 | (tramp-process-alive-regexp tramp-smb-action-with-acl)) | ||
| 195 | "List of pattern/action pairs. | ||
| 196 | This list is used for smbcacls actions. | ||
| 197 | |||
| 198 | See `tramp-actions-before-shell' for more info.") | ||
| 199 | |||
| 181 | ;; New handlers should be added here. | 200 | ;; New handlers should be added here. |
| 182 | (defconst tramp-smb-file-name-handler-alist | 201 | (defconst tramp-smb-file-name-handler-alist |
| 183 | '(;; `access-file' performed by default handler. | 202 | '(;; `access-file' performed by default handler. |
| @@ -235,7 +254,7 @@ See `tramp-actions-before-shell' for more info.") | |||
| 235 | (make-symbolic-link . tramp-smb-handle-make-symbolic-link) | 254 | (make-symbolic-link . tramp-smb-handle-make-symbolic-link) |
| 236 | (process-file . tramp-smb-handle-process-file) | 255 | (process-file . tramp-smb-handle-process-file) |
| 237 | (rename-file . tramp-smb-handle-rename-file) | 256 | (rename-file . tramp-smb-handle-rename-file) |
| 238 | (set-file-acl . ignore) | 257 | (set-file-acl . tramp-smb-handle-set-file-acl) |
| 239 | (set-file-modes . tramp-smb-handle-set-file-modes) | 258 | (set-file-modes . tramp-smb-handle-set-file-modes) |
| 240 | (set-file-selinux-context . ignore) | 259 | (set-file-selinux-context . ignore) |
| 241 | (set-file-times . ignore) | 260 | (set-file-times . ignore) |
| @@ -648,22 +667,83 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." | |||
| 648 | method user host | 667 | method user host |
| 649 | (tramp-run-real-handler 'expand-file-name (list localname)))))) | 668 | (tramp-run-real-handler 'expand-file-name (list localname)))))) |
| 650 | 669 | ||
| 670 | (defun tramp-smb-action-with-acl (proc vec) | ||
| 671 | "Read ACL data from connection buffer." | ||
| 672 | (when (not (memq (process-status proc) '(run open))) | ||
| 673 | ;; Accept pending output. | ||
| 674 | (while (tramp-accept-process-output proc 0.1)) | ||
| 675 | (with-current-buffer (tramp-get-connection-buffer vec) | ||
| 676 | ;; There might be a hidden password prompt. | ||
| 677 | (widen) | ||
| 678 | (tramp-message vec 10 "\n%s" (buffer-string)) | ||
| 679 | (goto-char (point-min)) | ||
| 680 | (while (and (not (eobp)) (not (looking-at "^REVISION:"))) | ||
| 681 | (forward-line) | ||
| 682 | (delete-region (point-min) (point))) | ||
| 683 | (while (and (not (eobp)) (looking-at "^.+:.+")) | ||
| 684 | (forward-line)) | ||
| 685 | (delete-region (point) (point-max)) | ||
| 686 | (throw 'tramp-action 'ok)))) | ||
| 687 | |||
| 651 | (defun tramp-smb-handle-file-acl (filename) | 688 | (defun tramp-smb-handle-file-acl (filename) |
| 652 | "Like `file-acl' for Tramp files." | 689 | "Like `file-acl' for Tramp files." |
| 653 | (with-parsed-tramp-file-name filename nil | 690 | (with-parsed-tramp-file-name filename nil |
| 654 | (with-tramp-file-property v localname "file-acl" | 691 | (with-tramp-file-property v localname "file-acl" |
| 655 | (when (tramp-smb-send-command | 692 | (when (executable-find tramp-smb-acl-program) |
| 656 | v (format "getfacl \"%s\"" (tramp-smb-get-localname v))) | 693 | |
| 657 | (with-current-buffer (tramp-get-connection-buffer v) | 694 | (setq tramp-current-method (tramp-file-name-method v) |
| 658 | (goto-char (point-min)) | 695 | tramp-current-user (tramp-file-name-user v) |
| 659 | (while (looking-at "^#") | 696 | tramp-current-host (tramp-file-name-real-host v)) |
| 660 | (forward-line) | 697 | |
| 661 | (delete-region (point-min) (point))) | 698 | (let* ((real-user (tramp-file-name-real-user v)) |
| 662 | (goto-char (point-max)) | 699 | (real-host (tramp-file-name-real-host v)) |
| 663 | (delete-blank-lines) | 700 | (domain (tramp-file-name-domain v)) |
| 664 | (when (> (point-max) (point-min)) | 701 | (port (tramp-file-name-port v)) |
| 665 | (tramp-compat-funcall | 702 | (share (tramp-smb-get-share v)) |
| 666 | 'substring-no-properties (buffer-string)))))))) | 703 | (localname (tramp-compat-replace-regexp-in-string |
| 704 | "\\\\" "/" (tramp-smb-get-localname v))) | ||
| 705 | (args (list (concat "//" real-host "/" share) "-E"))) | ||
| 706 | |||
| 707 | (if (not (zerop (length real-user))) | ||
| 708 | (setq args (append args (list "-U" real-user))) | ||
| 709 | (setq args (append args (list "-N")))) | ||
| 710 | |||
| 711 | (when domain (setq args (append args (list "-W" domain)))) | ||
| 712 | (when port (setq args (append args (list "-p" port)))) | ||
| 713 | (when tramp-smb-conf | ||
| 714 | (setq args (append args (list "-s" tramp-smb-conf)))) | ||
| 715 | (setq | ||
| 716 | args | ||
| 717 | (append args (list (shell-quote-argument localname) "2>/dev/null"))) | ||
| 718 | |||
| 719 | (unwind-protect | ||
| 720 | (with-temp-buffer | ||
| 721 | ;; Set the transfer process properties. | ||
| 722 | (tramp-set-connection-property | ||
| 723 | v "process-name" (buffer-name (current-buffer))) | ||
| 724 | (tramp-set-connection-property | ||
| 725 | v "process-buffer" (current-buffer)) | ||
| 726 | |||
| 727 | ;; Use an asynchronous processes. By this, password | ||
| 728 | ;; can be handled. | ||
| 729 | (let ((p (apply | ||
| 730 | 'start-process | ||
| 731 | (tramp-get-connection-name v) | ||
| 732 | (tramp-get-connection-buffer v) | ||
| 733 | tramp-smb-acl-program args))) | ||
| 734 | |||
| 735 | (tramp-message | ||
| 736 | v 6 "%s" (mapconcat 'identity (process-command p) " ")) | ||
| 737 | (tramp-compat-set-process-query-on-exit-flag p nil) | ||
| 738 | (tramp-process-actions p v nil tramp-smb-actions-with-acl) | ||
| 739 | (tramp-message v 6 "\n%s" (buffer-string)) | ||
| 740 | (when (> (point-max) (point-min)) | ||
| 741 | (tramp-compat-funcall | ||
| 742 | 'substring-no-properties (buffer-string))))) | ||
| 743 | |||
| 744 | ;; Reset the transfer process properties. | ||
| 745 | (tramp-set-connection-property v "process-name" nil) | ||
| 746 | (tramp-set-connection-property v "process-buffer" nil))))))) | ||
| 667 | 747 | ||
| 668 | (defun tramp-smb-handle-file-attributes (filename &optional id-format) | 748 | (defun tramp-smb-handle-file-attributes (filename &optional id-format) |
| 669 | "Like `file-attributes' for Tramp files." | 749 | "Like `file-attributes' for Tramp files." |
| @@ -672,7 +752,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." | |||
| 672 | (with-parsed-tramp-file-name filename nil | 752 | (with-parsed-tramp-file-name filename nil |
| 673 | (with-tramp-file-property | 753 | (with-tramp-file-property |
| 674 | v localname (format "file-attributes-%s" id-format) | 754 | v localname (format "file-attributes-%s" id-format) |
| 675 | (if (and (tramp-smb-get-share v) (tramp-smb-get-stat-capability v)) | 755 | (if (tramp-smb-get-stat-capability v) |
| 676 | (tramp-smb-do-file-attributes-with-stat v id-format) | 756 | (tramp-smb-do-file-attributes-with-stat v id-format) |
| 677 | ;; Reading just the filename entry via "dir localname" is not | 757 | ;; Reading just the filename entry via "dir localname" is not |
| 678 | ;; possible, because when filename is a directory, some | 758 | ;; possible, because when filename is a directory, some |
| @@ -1180,6 +1260,68 @@ target of the symlink differ." | |||
| 1180 | (tramp-compat-delete-directory filename 'recursive) | 1260 | (tramp-compat-delete-directory filename 'recursive) |
| 1181 | (delete-file filename))))) | 1261 | (delete-file filename))))) |
| 1182 | 1262 | ||
| 1263 | (defun tramp-smb-handle-set-file-acl (filename acl-string) | ||
| 1264 | "Like `set-file-acl' for Tramp files." | ||
| 1265 | (with-parsed-tramp-file-name filename nil | ||
| 1266 | (when (and (stringp acl-string) (executable-find tramp-smb-acl-program)) | ||
| 1267 | |||
| 1268 | (setq tramp-current-method (tramp-file-name-method v) | ||
| 1269 | tramp-current-user (tramp-file-name-user v) | ||
| 1270 | tramp-current-host (tramp-file-name-real-host v)) | ||
| 1271 | (tramp-set-file-property v localname "file-acl" 'undef) | ||
| 1272 | |||
| 1273 | (let* ((real-user (tramp-file-name-real-user v)) | ||
| 1274 | (real-host (tramp-file-name-real-host v)) | ||
| 1275 | (domain (tramp-file-name-domain v)) | ||
| 1276 | (port (tramp-file-name-port v)) | ||
| 1277 | (share (tramp-smb-get-share v)) | ||
| 1278 | (localname (tramp-compat-replace-regexp-in-string | ||
| 1279 | "\\\\" "/" (tramp-smb-get-localname v))) | ||
| 1280 | (args (list (concat "//" real-host "/" share) "-E" "-S" | ||
| 1281 | (tramp-compat-replace-regexp-in-string | ||
| 1282 | "\n" "," acl-string)))) | ||
| 1283 | |||
| 1284 | (if (not (zerop (length real-user))) | ||
| 1285 | (setq args (append args (list "-U" real-user))) | ||
| 1286 | (setq args (append args (list "-N")))) | ||
| 1287 | |||
| 1288 | (when domain (setq args (append args (list "-W" domain)))) | ||
| 1289 | (when port (setq args (append args (list "-p" port)))) | ||
| 1290 | (when tramp-smb-conf | ||
| 1291 | (setq args (append args (list "-s" tramp-smb-conf)))) | ||
| 1292 | (setq | ||
| 1293 | args | ||
| 1294 | (append args (list (shell-quote-argument localname) "2>/dev/null"))) | ||
| 1295 | |||
| 1296 | (unwind-protect | ||
| 1297 | (with-temp-buffer | ||
| 1298 | ;; Set the transfer process properties. | ||
| 1299 | (tramp-set-connection-property | ||
| 1300 | v "process-name" (buffer-name (current-buffer))) | ||
| 1301 | (tramp-set-connection-property | ||
| 1302 | v "process-buffer" (current-buffer)) | ||
| 1303 | |||
| 1304 | ;; Use an asynchronous processes. By this, password can | ||
| 1305 | ;; be handled. | ||
| 1306 | (let ((p (apply | ||
| 1307 | 'start-process | ||
| 1308 | (tramp-get-connection-name v) | ||
| 1309 | (tramp-get-connection-buffer v) | ||
| 1310 | tramp-smb-acl-program args))) | ||
| 1311 | |||
| 1312 | (tramp-message | ||
| 1313 | v 6 "%s" (mapconcat 'identity (process-command p) " ")) | ||
| 1314 | (tramp-compat-set-process-query-on-exit-flag p nil) | ||
| 1315 | (tramp-process-actions p v nil tramp-smb-actions-with-acl) | ||
| 1316 | (tramp-message v 6 "\n%s" (buffer-string)) | ||
| 1317 | ;; Success. | ||
| 1318 | (tramp-set-file-property v localname "file-acl" acl-string) | ||
| 1319 | t)) | ||
| 1320 | |||
| 1321 | ;; Reset the transfer process properties. | ||
| 1322 | (tramp-set-connection-property v "process-name" nil) | ||
| 1323 | (tramp-set-connection-property v "process-buffer" nil)))))) | ||
| 1324 | |||
| 1183 | (defun tramp-smb-handle-set-file-modes (filename mode) | 1325 | (defun tramp-smb-handle-set-file-modes (filename mode) |
| 1184 | "Like `set-file-modes' for Tramp files." | 1326 | "Like `set-file-modes' for Tramp files." |
| 1185 | (with-parsed-tramp-file-name filename nil | 1327 | (with-parsed-tramp-file-name filename nil |
| @@ -1543,11 +1685,12 @@ Result is the list (LOCALNAME MODE SIZE MTIME)." | |||
| 1543 | (defun tramp-smb-get-stat-capability (vec) | 1685 | (defun tramp-smb-get-stat-capability (vec) |
| 1544 | "Check, whether the SMB server supports the STAT command." | 1686 | "Check, whether the SMB server supports the STAT command." |
| 1545 | ;; When we are not logged in yet, we return nil. | 1687 | ;; When we are not logged in yet, we return nil. |
| 1546 | (if (let ((p (tramp-get-connection-process vec))) | 1688 | (if (and (tramp-smb-get-share vec) |
| 1547 | (and p (processp p) (memq (process-status p) '(run open)))) | 1689 | (let ((p (tramp-get-connection-process vec))) |
| 1690 | p (processp p) (memq (process-status p) '(run open)))) | ||
| 1548 | (with-tramp-connection-property | 1691 | (with-tramp-connection-property |
| 1549 | (tramp-get-connection-process vec) "stat-capability" | 1692 | (tramp-get-connection-process vec) "stat-capability" |
| 1550 | (tramp-smb-send-command vec "stat .")))) | 1693 | (tramp-smb-send-command vec "stat \"/\"")))) |
| 1551 | 1694 | ||
| 1552 | 1695 | ||
| 1553 | ;; Connection functions. | 1696 | ;; Connection functions. |