225 |
(error "copy-file: file %s already exists" newname)) |
(error "copy-file: file %s already exists" newname)) |
226 |
|
|
227 |
; (with-parsed-tramp-file-name newname nil |
; (with-parsed-tramp-file-name newname nil |
228 |
(let (user host path) |
(let (user host localname) |
229 |
(with-parsed-tramp-file-name newname l |
(with-parsed-tramp-file-name newname l |
230 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
231 |
(save-excursion |
(save-excursion |
232 |
(let ((share (tramp-smb-get-share path)) |
(let ((share (tramp-smb-get-share localname)) |
233 |
(file (tramp-smb-get-path path t))) |
(file (tramp-smb-get-localname localname t))) |
234 |
(unless share |
(unless share |
235 |
(error "Target `%s' must contain a share name" filename)) |
(error "Target `%s' must contain a share name" filename)) |
236 |
(tramp-smb-maybe-open-connection user host share) |
(tramp-smb-maybe-open-connection user host share) |
250 |
(unless (file-exists-p directory) |
(unless (file-exists-p directory) |
251 |
(error "Cannot delete non-existing directory `%s'" directory)) |
(error "Cannot delete non-existing directory `%s'" directory)) |
252 |
; (with-parsed-tramp-file-name directory nil |
; (with-parsed-tramp-file-name directory nil |
253 |
(let (user host path) |
(let (user host localname) |
254 |
(with-parsed-tramp-file-name directory l |
(with-parsed-tramp-file-name directory l |
255 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
256 |
(save-excursion |
(save-excursion |
257 |
(let ((share (tramp-smb-get-share path)) |
(let ((share (tramp-smb-get-share localname)) |
258 |
(dir (tramp-smb-get-path (file-name-directory path) t)) |
(dir (tramp-smb-get-localname (file-name-directory localname) t)) |
259 |
(file (file-name-nondirectory path))) |
(file (file-name-nondirectory localname))) |
260 |
(tramp-smb-maybe-open-connection user host share) |
(tramp-smb-maybe-open-connection user host share) |
261 |
(if (and |
(if (and |
262 |
(tramp-smb-send-command user host (format "cd \"%s\"" dir)) |
(tramp-smb-send-command user host (format "cd \"%s\"" dir)) |
273 |
(unless (file-exists-p filename) |
(unless (file-exists-p filename) |
274 |
(error "Cannot delete non-existing file `%s'" filename)) |
(error "Cannot delete non-existing file `%s'" filename)) |
275 |
; (with-parsed-tramp-file-name filename nil |
; (with-parsed-tramp-file-name filename nil |
276 |
(let (user host path) |
(let (user host localname) |
277 |
(with-parsed-tramp-file-name filename l |
(with-parsed-tramp-file-name filename l |
278 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
279 |
(save-excursion |
(save-excursion |
280 |
(let ((share (tramp-smb-get-share path)) |
(let ((share (tramp-smb-get-share localname)) |
281 |
(dir (tramp-smb-get-path (file-name-directory path) t)) |
(dir (tramp-smb-get-localname (file-name-directory localname) t)) |
282 |
(file (file-name-nondirectory path))) |
(file (file-name-nondirectory localname))) |
283 |
(unless (file-exists-p filename) |
(unless (file-exists-p filename) |
284 |
(error "Cannot delete non-existing file `%s'" filename)) |
(error "Cannot delete non-existing file `%s'" filename)) |
285 |
(tramp-smb-maybe-open-connection user host share) |
(tramp-smb-maybe-open-connection user host share) |
297 |
"Like `directory-files' for tramp files." |
"Like `directory-files' for tramp files." |
298 |
(setq directory (directory-file-name (expand-file-name directory))) |
(setq directory (directory-file-name (expand-file-name directory))) |
299 |
; (with-parsed-tramp-file-name directory nil |
; (with-parsed-tramp-file-name directory nil |
300 |
(let (user host path) |
(let (user host localname) |
301 |
(with-parsed-tramp-file-name directory l |
(with-parsed-tramp-file-name directory l |
302 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
303 |
(save-excursion |
(save-excursion |
304 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
305 |
(file (tramp-smb-get-path path nil)) |
(file (tramp-smb-get-localname localname nil)) |
306 |
(entries (tramp-smb-get-file-entries user host share file))) |
(entries (tramp-smb-get-file-entries user host share file))) |
307 |
;; Just the file names are needed |
;; Just the file names are needed |
308 |
(setq entries (mapcar 'car entries)) |
(setq entries (mapcar 'car entries)) |
312 |
(delete nil |
(delete nil |
313 |
(mapcar (lambda (x) (when (string-match match x) x)) |
(mapcar (lambda (x) (when (string-match match x) x)) |
314 |
entries)))) |
entries)))) |
315 |
;; Make absolute paths if necessary |
;; Make absolute localnames if necessary |
316 |
(when full |
(when full |
317 |
(setq entries |
(setq entries |
318 |
(mapcar (lambda (x) |
(mapcar (lambda (x) |
331 |
(cons x (file-attributes |
(cons x (file-attributes |
332 |
(if full x (concat (file-name-as-directory directory) x))))) |
(if full x (concat (file-name-as-directory directory) x))))) |
333 |
(directory-files directory full match nosort))) |
(directory-files directory full match nosort))) |
334 |
|
|
335 |
(defun tramp-smb-handle-file-attributes (filename &optional nonnumeric) |
(defun tramp-smb-handle-file-attributes (filename &optional nonnumeric) |
336 |
"Like `file-attributes' for tramp files. |
"Like `file-attributes' for tramp files. |
337 |
Optional argument NONNUMERIC means return user and group name |
Optional argument NONNUMERIC means return user and group name |
338 |
rather than as numbers." |
rather than as numbers." |
339 |
; (with-parsed-tramp-file-name filename nil |
; (with-parsed-tramp-file-name filename nil |
340 |
(let (user host path) |
(let (user host localname) |
341 |
(with-parsed-tramp-file-name filename l |
(with-parsed-tramp-file-name filename l |
342 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
343 |
(save-excursion |
(save-excursion |
344 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
345 |
(file (tramp-smb-get-path path nil)) |
(file (tramp-smb-get-localname localname nil)) |
346 |
(entries (tramp-smb-get-file-entries user host share file)) |
(entries (tramp-smb-get-file-entries user host share file)) |
347 |
(entry (and entries |
(entry (and entries |
348 |
(assoc (file-name-nondirectory file) entries))) |
(assoc (file-name-nondirectory file) entries))) |
368 |
(defun tramp-smb-handle-file-directory-p (filename) |
(defun tramp-smb-handle-file-directory-p (filename) |
369 |
"Like `file-directory-p' for tramp files." |
"Like `file-directory-p' for tramp files." |
370 |
; (with-parsed-tramp-file-name filename nil |
; (with-parsed-tramp-file-name filename nil |
371 |
(let (user host path) |
(let (user host localname) |
372 |
(with-parsed-tramp-file-name filename l |
(with-parsed-tramp-file-name filename l |
373 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
374 |
(save-excursion |
(save-excursion |
375 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
376 |
(file (tramp-smb-get-path path nil)) |
(file (tramp-smb-get-localname localname nil)) |
377 |
(entries (tramp-smb-get-file-entries user host share file)) |
(entries (tramp-smb-get-file-entries user host share file)) |
378 |
(entry (and entries |
(entry (and entries |
379 |
(assoc (file-name-nondirectory file) entries)))) |
(assoc (file-name-nondirectory file) entries)))) |
384 |
(defun tramp-smb-handle-file-exists-p (filename) |
(defun tramp-smb-handle-file-exists-p (filename) |
385 |
"Like `file-exists-p' for tramp files." |
"Like `file-exists-p' for tramp files." |
386 |
; (with-parsed-tramp-file-name filename nil |
; (with-parsed-tramp-file-name filename nil |
387 |
(let (user host path) |
(let (user host localname) |
388 |
(with-parsed-tramp-file-name filename l |
(with-parsed-tramp-file-name filename l |
389 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
390 |
(save-excursion |
(save-excursion |
391 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
392 |
(file (tramp-smb-get-path path nil)) |
(file (tramp-smb-get-localname localname nil)) |
393 |
(entries (tramp-smb-get-file-entries user host share file))) |
(entries (tramp-smb-get-file-entries user host share file))) |
394 |
(and entries |
(and entries |
395 |
(member (file-name-nondirectory file) (mapcar 'car entries)) |
(member (file-name-nondirectory file) (mapcar 'car entries)) |
399 |
"Like `file-local-copy' for tramp files." |
"Like `file-local-copy' for tramp files." |
400 |
(with-parsed-tramp-file-name filename nil |
(with-parsed-tramp-file-name filename nil |
401 |
(save-excursion |
(save-excursion |
402 |
(let ((share (tramp-smb-get-share path)) |
(let ((share (tramp-smb-get-share localname)) |
403 |
(file (tramp-smb-get-path path t)) |
(file (tramp-smb-get-localname localname t)) |
404 |
(tmpfil (tramp-make-temp-file))) |
(tmpfil (tramp-make-temp-file))) |
405 |
(unless (file-exists-p filename) |
(unless (file-exists-p filename) |
406 |
(error "Cannot make local copy of non-existing file `%s'" filename)) |
(error "Cannot make local copy of non-existing file `%s'" filename)) |
421 |
(defun tramp-smb-handle-file-name-all-completions (filename directory) |
(defun tramp-smb-handle-file-name-all-completions (filename directory) |
422 |
"Like `file-name-all-completions' for tramp files." |
"Like `file-name-all-completions' for tramp files." |
423 |
; (with-parsed-tramp-file-name directory nil |
; (with-parsed-tramp-file-name directory nil |
424 |
(let (user host path) |
(let (user host localname) |
425 |
(with-parsed-tramp-file-name directory l |
(with-parsed-tramp-file-name directory l |
426 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
427 |
(save-match-data |
(save-match-data |
428 |
(save-excursion |
(save-excursion |
429 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
430 |
(file (tramp-smb-get-path path nil)) |
(file (tramp-smb-get-localname localname nil)) |
431 |
(entries (tramp-smb-get-file-entries user host share file))) |
(entries (tramp-smb-get-file-entries user host share file))) |
432 |
|
|
433 |
(all-completions |
(all-completions |
451 |
(defun tramp-smb-handle-file-writable-p (filename) |
(defun tramp-smb-handle-file-writable-p (filename) |
452 |
"Like `file-writable-p' for tramp files." |
"Like `file-writable-p' for tramp files." |
453 |
; (with-parsed-tramp-file-name filename nil |
; (with-parsed-tramp-file-name filename nil |
454 |
(let (user host path) |
(let (user host localname) |
455 |
(with-parsed-tramp-file-name filename l |
(with-parsed-tramp-file-name filename l |
456 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
457 |
(save-excursion |
(save-excursion |
458 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
459 |
(file (tramp-smb-get-path path nil)) |
(file (tramp-smb-get-localname localname nil)) |
460 |
(entries (tramp-smb-get-file-entries user host share file)) |
(entries (tramp-smb-get-file-entries user host share file)) |
461 |
(entry (and entries |
(entry (and entries |
462 |
(assoc (file-name-nondirectory file) entries)))) |
(assoc (file-name-nondirectory file) entries)))) |
474 |
;; this function is called with a non-directory ... |
;; this function is called with a non-directory ... |
475 |
(setq filename (file-name-as-directory filename))) |
(setq filename (file-name-as-directory filename))) |
476 |
; (with-parsed-tramp-file-name filename nil |
; (with-parsed-tramp-file-name filename nil |
477 |
(let (user host path) |
(let (user host localname) |
478 |
(with-parsed-tramp-file-name filename l |
(with-parsed-tramp-file-name filename l |
479 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
480 |
(save-match-data |
(save-match-data |
481 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
482 |
(file (tramp-smb-get-path path nil)) |
(file (tramp-smb-get-localname localname nil)) |
483 |
(entries (tramp-smb-get-file-entries user host share file))) |
(entries (tramp-smb-get-file-entries user host share file))) |
484 |
|
|
485 |
;; Delete dummy "" entry, useless entries |
;; Delete dummy "" entry, useless entries |
486 |
(setq entries |
(setq entries |
487 |
(if (file-directory-p filename) |
(if (file-directory-p filename) |
488 |
(delq (assoc "" entries) entries) |
(delq (assoc "" entries) entries) |
489 |
;; We just need the only and only entry FILENAME. |
;; We just need the only and only entry FILENAME. |
527 |
(unless (file-name-absolute-p dir) |
(unless (file-name-absolute-p dir) |
528 |
(setq dir (concat default-directory dir))) |
(setq dir (concat default-directory dir))) |
529 |
; (with-parsed-tramp-file-name dir nil |
; (with-parsed-tramp-file-name dir nil |
530 |
(let (user host path) |
(let (user host localname) |
531 |
(with-parsed-tramp-file-name dir l |
(with-parsed-tramp-file-name dir l |
532 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
533 |
(save-match-data |
(save-match-data |
534 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
535 |
(ldir (file-name-directory dir))) |
(ldir (file-name-directory dir))) |
536 |
;; Make missing directory parts |
;; Make missing directory parts |
537 |
(when (and parents share (not (file-directory-p ldir))) |
(when (and parents share (not (file-directory-p ldir))) |
548 |
(unless (file-name-absolute-p directory) |
(unless (file-name-absolute-p directory) |
549 |
(setq ldir (concat default-directory directory))) |
(setq ldir (concat default-directory directory))) |
550 |
; (with-parsed-tramp-file-name directory nil |
; (with-parsed-tramp-file-name directory nil |
551 |
(let (user host path) |
(let (user host localname) |
552 |
(with-parsed-tramp-file-name directory l |
(with-parsed-tramp-file-name directory l |
553 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
554 |
(save-match-data |
(save-match-data |
555 |
(let* ((share (tramp-smb-get-share path)) |
(let* ((share (tramp-smb-get-share localname)) |
556 |
(file (tramp-smb-get-path path nil))) |
(file (tramp-smb-get-localname localname nil))) |
557 |
(when (file-directory-p (file-name-directory directory)) |
(when (file-directory-p (file-name-directory directory)) |
558 |
(tramp-smb-maybe-open-connection user host share) |
(tramp-smb-maybe-open-connection user host share) |
559 |
(tramp-smb-send-command user host (format "mkdir \"%s\"" file))) |
(tramp-smb-send-command user host (format "mkdir \"%s\"" file))) |
581 |
(error "rename-file: file %s already exists" newname)) |
(error "rename-file: file %s already exists" newname)) |
582 |
|
|
583 |
; (with-parsed-tramp-file-name newname nil |
; (with-parsed-tramp-file-name newname nil |
584 |
(let (user host path) |
(let (user host localname) |
585 |
(with-parsed-tramp-file-name newname l |
(with-parsed-tramp-file-name newname l |
586 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
587 |
(save-excursion |
(save-excursion |
588 |
(let ((share (tramp-smb-get-share path)) |
(let ((share (tramp-smb-get-share localname)) |
589 |
(file (tramp-smb-get-path path t))) |
(file (tramp-smb-get-localname localname t))) |
590 |
(tramp-smb-maybe-open-connection user host share) |
(tramp-smb-maybe-open-connection user host share) |
591 |
(tramp-message-for-buffer |
(tramp-message-for-buffer |
592 |
nil tramp-smb-method user host |
nil tramp-smb-method user host |
613 |
filename)) |
filename)) |
614 |
(error "File not overwritten"))) |
(error "File not overwritten"))) |
615 |
; (with-parsed-tramp-file-name filename nil |
; (with-parsed-tramp-file-name filename nil |
616 |
(let (user host path) |
(let (user host localname) |
617 |
(with-parsed-tramp-file-name filename l |
(with-parsed-tramp-file-name filename l |
618 |
(setq user l-user host l-host path l-path)) |
(setq user l-user host l-host localname l-localname)) |
619 |
(save-excursion |
(save-excursion |
620 |
(let ((share (tramp-smb-get-share path)) |
(let ((share (tramp-smb-get-share localname)) |
621 |
(file (tramp-smb-get-path path t)) |
(file (tramp-smb-get-localname localname t)) |
622 |
(curbuf (current-buffer)) |
(curbuf (current-buffer)) |
623 |
;; We use this to save the value of `last-coding-system-used' |
;; We use this to save the value of `last-coding-system-used' |
624 |
;; after writing the tmp file. At the end of the function, |
;; after writing the tmp file. At the end of the function, |
666 |
|
|
667 |
;; Internal file name functions |
;; Internal file name functions |
668 |
|
|
669 |
(defun tramp-smb-get-share (path) |
(defun tramp-smb-get-share (localname) |
670 |
"Returns the share name of PATH." |
"Returns the share name of LOCALNAME." |
671 |
(save-match-data |
(save-match-data |
672 |
(when (string-match "^/?\\([^/]+\\)/" path) |
(when (string-match "^/?\\([^/]+\\)/" localname) |
673 |
(match-string 1 path)))) |
(match-string 1 localname)))) |
674 |
|
|
675 |
(defun tramp-smb-get-path (path convert) |
(defun tramp-smb-get-localname (localname convert) |
676 |
"Returns the file name of PATH. |
"Returns the file name of LOCALNAME. |
677 |
If CONVERT is non-nil exchange \"/\" by \"\\\\\"." |
If CONVERT is non-nil exchange \"/\" by \"\\\\\"." |
678 |
(save-match-data |
(save-match-data |
679 |
(let ((res path)) |
(let ((res localname)) |
680 |
|
|
681 |
(setq |
(setq |
682 |
res (if (string-match "^/?[^/]+/\\(.*\\)" res) |
res (if (string-match "^/?[^/]+/\\(.*\\)" res) |
697 |
|
|
698 |
;; Share names of a host are cached. It is very unlikely that the |
;; Share names of a host are cached. It is very unlikely that the |
699 |
;; shares do change during connection. |
;; shares do change during connection. |
700 |
(defun tramp-smb-get-file-entries (user host share path) |
(defun tramp-smb-get-file-entries (user host share localname) |
701 |
"Read entries which match PATH. |
"Read entries which match LOCALNAME. |
702 |
Either the shares are listed, or the `dir' command is executed. |
Either the shares are listed, or the `dir' command is executed. |
703 |
Only entries matching the path are returned. |
Only entries matching the localname are returned. |
704 |
Result is a list of (PATH MODE SIZE MONTH DAY TIME YEAR)." |
Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)." |
705 |
(save-excursion |
(save-excursion |
706 |
(save-match-data |
(save-match-data |
707 |
(let ((base (or (and (> (length path) 0) |
(let ((base (or (and (> (length localname) 0) |
708 |
(string-match "\\([^/]+\\)$" path) |
(string-match "\\([^/]+\\)$" localname) |
709 |
(regexp-quote (match-string 1 path))) |
(regexp-quote (match-string 1 localname))) |
710 |
"")) |
"")) |
711 |
res entry) |
res entry) |
712 |
(set-buffer (tramp-get-buffer nil tramp-smb-method user host)) |
(set-buffer (tramp-get-buffer nil tramp-smb-method user host)) |
719 |
(tramp-smb-send-command |
(tramp-smb-send-command |
720 |
user host |
user host |
721 |
(format "dir %s" |
(format "dir %s" |
722 |
(if (zerop (length path)) "" (concat "\"" path "*\""))))) |
(if (zerop (length localname)) "" (concat "\"" localname "*\""))))) |
723 |
(goto-char (point-min)) |
(goto-char (point-min)) |
724 |
;; Loop the listing |
;; Loop the listing |
725 |
(unless (re-search-forward tramp-smb-errors nil t) |
(unless (re-search-forward tramp-smb-errors nil t) |
780 |
(defun tramp-smb-read-file-entry (share) |
(defun tramp-smb-read-file-entry (share) |
781 |
"Parse entry in SMB output buffer. |
"Parse entry in SMB output buffer. |
782 |
If SHARE is result, entries are of type dir. Otherwise, shares are listed. |
If SHARE is result, entries are of type dir. Otherwise, shares are listed. |
783 |
Result is the list (PATH MODE SIZE MTIME)." |
Result is the list (LOCALNAME MODE SIZE MTIME)." |
784 |
(let ((line (buffer-substring (point) (tramp-point-at-eol))) |
(let ((line (buffer-substring (point) (tramp-point-at-eol))) |
785 |
path mode size month day hour min sec year mtime) |
localname mode size month day hour min sec year mtime) |
786 |
|
|
787 |
(if (not share) |
(if (not share) |
788 |
|
|
789 |
; Read share entries |
; Read share entries |
790 |
(when (string-match "^\\s-+\\(\\S-+\\)\\s-+Disk" line) |
(when (string-match "^\\s-+\\(\\S-+\\)\\s-+Disk" line) |
791 |
(setq path (match-string 1 line) |
(setq localname (match-string 1 line) |
792 |
mode "dr-xr-xr-x" |
mode "dr-xr-xr-x" |
793 |
size 0)) |
size 0)) |
794 |
|
|
847 |
line (substring line 0 (- (1+ (length (match-string 2 line)))))) |
line (substring line 0 (- (1+ (length (match-string 2 line)))))) |
848 |
(return)) |
(return)) |
849 |
|
|
850 |
;; path |
;; localname |
851 |
(if (string-match "^\\s-+\\(\\S-\\(.*\\S-\\)?\\)\\s-+$" line) |
(if (string-match "^\\s-+\\(\\S-\\(.*\\S-\\)?\\)\\s-+$" line) |
852 |
(setq path (match-string 1 line)) |
(setq localname (match-string 1 line)) |
853 |
(return)))) |
(return)))) |
854 |
|
|
855 |
(when (and path mode size) |
(when (and localname mode size) |
856 |
(setq mtime |
(setq mtime |
857 |
(if (and sec min hour day month year) |
(if (and sec min hour day month year) |
858 |
(encode-time |
(encode-time |
860 |
(cdr (assoc (downcase month) tramp-smb-parse-time-months)) |
(cdr (assoc (downcase month) tramp-smb-parse-time-months)) |
861 |
year) |
year) |
862 |
'(0 0))) |
'(0 0))) |
863 |
(list path mode size mtime)))) |
(list localname mode size mtime)))) |
864 |
|
|
865 |
;; Inodes don't exist for SMB files. Therefore we must generate virtual ones. |
;; Inodes don't exist for SMB files. Therefore we must generate virtual ones. |
866 |
;; Used in `find-buffer-visiting'. |
;; Used in `find-buffer-visiting'. |