Ted Zlatanov <[email protected]> writes:
Hi Ted,
> Attached are imap-hash.el and tramp-imap.el, I worked on them this
> weekend.
Thanks for this. I've played a little bit with them (no real test yet).
> imap-hash.el lets you treat an IMAP mailbox as a hash. It lets you get
> individual keys' headers and body data (keys are message UIDs) or map a
> function across *all the messages in the mailbox*. The function is only
> called for those that match a given subject, but really I should be
> using SEARCH. So the library is not optimized for speed. Also, it does
> not handle invalid mailbox names gracefully yet. Consider it an alpha
> version.
Could you, please, add "(require 'assoc)"? It's not loaded by default.
> tramp-imap.el uses imap-hash.el to provide a Tramp interface to read and
> write files as messages in an IMAP mailbox. It's also an alpha version,
> but it will at least let you (given a valid IMAP mailbox) read and write
> directory contents. It uses EPG (thanks to Daiki Ueno's help) to
> encrypt the file contents when they are stored as messages.
As usual, I have some few patches :-)
* imaps didn't work for me any longer. I've patched
`tramp-imap-make-iht' until it worked ... maybe my sledge-hammer patch
could be done more elegant. There is still an error message in the
mini-buffer when opening the IMAP folder, but it doesn't seem to hurt.
* I have renamed `tramp-imap-handle-file-inode' to
`tramp-imap-get-file-inode'. tramp-*-handle-* function names shall be
reserved to basic file name operations implementation.
* I have used `tramp-current-host' to solve the problem of unresolved
vector in `tramp-imap-passphrase-callback-function'. That variable
was introduced in tramp.el for exactly this kind of problems.
* When you byte-compile tramp-imap.el, there is a warning about unknown
function `tramp-imap-get-message-headers'. No idea, what to do here.
My patch is appended.
I really would like to add tramp-imap.el to the CVS repository. I test
on different machines, and the current situation is inconvenient for
me. Do you agree for a checkin?
> Ted
Best regards, Michael.
*** /tmp/ediff21621-xQ 2009-09-22 16:49:14.000000000 +0200
--- /tmp/ediff21621L8W 2009-09-22 16:49:14.000000000 +0200
***************
*** 260,266 ****
"-rw-rw-rw-"
nil
uid
! 1)))
iht t)))
(defun tramp-imap-handle-write-region (start end filename &optional append visit lockname confirm)
--- 260,266 ----
"-rw-rw-rw-"
nil
uid
! 1)))
iht t)))
(defun tramp-imap-handle-write-region (start end filename &optional append visit lockname confirm)
***************
*** 275,281 ****
(tramp-error v 'file-error "File not overwritten")))
(tramp-flush-file-property v localname)
(let* ((old-buffer (current-buffer))
! (inode (tramp-imap-handle-file-inode filename))
(min 1)
(max (point-max))
;; make sure we have good start and end values
--- 275,281 ----
(tramp-error v 'file-error "File not overwritten")))
(tramp-flush-file-property v localname)
(let* ((old-buffer (current-buffer))
! (inode (tramp-imap-get-file-inode filename))
(min 1)
(max (point-max))
;; make sure we have good start and end values
***************
*** 290,298 ****
(with-current-buffer old-buffer
(buffer-substring-no-properties start end)))
(current-buffer)))
! (tramp-imap-put-file v
! temp-buffer
! (tramp-imap-file-name-name v)
inode)))
(when (eq visit t)
(set-visited-file-modtime))))
--- 290,298 ----
(with-current-buffer old-buffer
(buffer-substring-no-properties start end)))
(current-buffer)))
! (tramp-imap-put-file v
! temp-buffer
! (tramp-imap-file-name-name v)
inode)))
(when (eq visit t)
(set-visited-file-modtime))))
***************
*** 307,313 ****
(with-parsed-tramp-file-name filename nil
(if (not (file-exists-p filename))
(tramp-error
! v 'file-error "File '%s' not found on remote host" filename)
(let ((point (point))
size data)
(tramp-message v 4 "Fetching file %s..." filename)
--- 307,313 ----
(with-parsed-tramp-file-name filename nil
(if (not (file-exists-p filename))
(tramp-error
! v 'file-error "File `%s' not found on remote host" filename)
(let ((point (point))
size data)
(tramp-message v 4 "Fetching file %s..." filename)
***************
*** 339,346 ****
;; (cdr (nth 0 (tramp-imap-get-file-entries v localname))))
(cdr-safe (nth 0 (tramp-imap-get-file-entries v localname)))))
! (defun tramp-imap-handle-file-inode (filename &optional id-format)
! "Get inode equivalent (actually the UID) for Tramp-IMAP FILENAME."
(nth 10 (file-attributes filename)))
(defun tramp-imap-handle-file-executable-p (filename)
--- 339,346 ----
;; (cdr (nth 0 (tramp-imap-get-file-entries v localname))))
(cdr-safe (nth 0 (tramp-imap-get-file-entries v localname)))))
! (defun tramp-imap-get-file-inode (filename &optional id-format)
! "Get inode equivalent \(actually the UID) for Tramp-IMAP FILENAME."
(nth 10 (file-attributes filename)))
(defun tramp-imap-handle-file-executable-p (filename)
***************
*** 361,367 ****
((not (file-exists-p file)) nil)
(t (with-parsed-tramp-file-name (expand-file-name file) nil
(let ((iht (tramp-imap-make-iht v)))
! (imap-hash-rem (tramp-imap-handle-file-inode filename) iht))))))
;; TODO: fix this in tramp-imap-get-file-entries
(defun tramp-imap-handle-file-newer-than-file-p (file1 file2)
--- 361,367 ----
((not (file-exists-p file)) nil)
(t (with-parsed-tramp-file-name (expand-file-name file) nil
(let ((iht (tramp-imap-make-iht v)))
! (imap-hash-rem (tramp-imap-get-file-inode filename) iht))))))
;; TODO: fix this in tramp-imap-get-file-entries
(defun tramp-imap-handle-file-newer-than-file-p (file1 file2)
***************
*** 387,402 ****
tmpfile))))
(defun tramp-imap-put-file (vec filename-or-buffer &optional subject inode)
! "Write contents of FILENAME-OR-BUFFER to Tramp-IMAP file VEC with name SUBJECT.
When INODE is given, delete that old remote file after writing the new one
! (normally this is the old file with the same name)."
! (let ((iht (tramp-imap-make-iht vec)))
(imap-hash-put (list
(list (cons
'Subject
! (format
! "%s%s"
! tramp-imap-subject-marker
(or subject "no subject"))))
(cond ((bufferp filename-or-buffer)
(with-current-buffer filename-or-buffer
--- 387,404 ----
tmpfile))))
(defun tramp-imap-put-file (vec filename-or-buffer &optional subject inode)
! "Write contents of FILENAME-OR-BUFFER to Tramp-IMAP file VEC with name SUBJECT.
When INODE is given, delete that old remote file after writing the new one
! \(normally this is the old file with the same name)."
! ;; `tramp-current-host' is used in `tramp-imap-passphrase-callback-function'.
! (let ((tramp-current-host (tramp-file-name-real-host vec))
! (iht (tramp-imap-make-iht vec)))
(imap-hash-put (list
(list (cons
'Subject
! (format
! "%s%s"
! tramp-imap-subject-marker
(or subject "no subject"))))
(cond ((bufferp filename-or-buffer)
(with-current-buffer filename-or-buffer
***************
*** 408,435 ****
(defun tramp-imap-get-file (filename)
! ;; (debug (tramp-imap-handle-file-inode filename))
(with-parsed-tramp-file-name (expand-file-name filename) nil
(condition-case ()
! (let ((iht (tramp-imap-make-iht v))
! (inode (tramp-imap-handle-file-inode filename))
! (data (imap-hash-get (tramp-imap-handle-file-inode
! filename)
! iht t)))
(with-temp-buffer
(insert (nth 1 data))
;;(debug inode (buffer-string))
(tramp-imap-decode-buffer)))
(error (tramp-error
! v 'file-error "File '%s' could not be read" filename)))))
(defun tramp-imap-passphrase-callback-function (context key-id handback)
"Called by EPG to get a passphrase for Tramp-IMAP.
CONTEXT is the encryption/decryption EPG context.
HANDBACK is just carried through.
KEY-ID can be 'SYM or 'PIN among others."
! ;; TODO: Variable `v' is not declared!!! Existing due to side-effects only.
! (let* ((server (tramp-file-name-real-host v))
(port "tramp-imap") ; this is NOT the server password!
(auth-passwd
(auth-source-user-or-password "password" server port)))
--- 410,437 ----
(defun tramp-imap-get-file (filename)
! ;; (debug (tramp-imap-get-file-inode filename))
(with-parsed-tramp-file-name (expand-file-name filename) nil
(condition-case ()
! ;; `tramp-current-host' is used in
! ;; `tramp-imap-passphrase-callback-function'.
! (let* ((tramp-current-host (tramp-file-name-real-host v))
! (iht (tramp-imap-make-iht v))
! (inode (tramp-imap-get-file-inode filename))
! (data (imap-hash-get inode iht t)))
(with-temp-buffer
(insert (nth 1 data))
;;(debug inode (buffer-string))
(tramp-imap-decode-buffer)))
(error (tramp-error
! v 'file-error "File `%s' could not be read" filename)))))
(defun tramp-imap-passphrase-callback-function (context key-id handback)
"Called by EPG to get a passphrase for Tramp-IMAP.
CONTEXT is the encryption/decryption EPG context.
HANDBACK is just carried through.
KEY-ID can be 'SYM or 'PIN among others."
! (let* ((server tramp-current-host)
(port "tramp-imap") ; this is NOT the server password!
(auth-passwd
(auth-source-user-or-password "password" server port)))
***************
*** 532,545 ****
(defun tramp-imap-make-iht (vec &optional needed-subject)
"Translate the Tramp vector VEC to the imap-hash structure.
With NEEDED-SUBJECT, alters the imap-hash test accordingly."
! (let ((mbox (tramp-imap-file-name-mailbox vec))
! (server (tramp-file-name-real-host vec))
! (port (or (tramp-file-name-port vec) "imap")))
;; return the IHT with a test override to look for the subject marker
! (plist-put (imap-hash-make server port mbox)
! :test (format "^%s%s"
! tramp-imap-subject-marker
! (if needed-subject needed-subject "")))))
(provide 'tramp-imap)
;;; tramp-imap.el ends here
--- 534,550 ----
(defun tramp-imap-make-iht (vec &optional needed-subject)
"Translate the Tramp vector VEC to the imap-hash structure.
With NEEDED-SUBJECT, alters the imap-hash test accordingly."
! (let* ((mbox (tramp-imap-file-name-mailbox vec))
! (server (tramp-file-name-real-host vec))
! (ssl (string-equal (tramp-file-name-method vec) tramp-imaps-method))
! (port (or (tramp-file-name-port vec) (if ssl 993 143))))
;; return the IHT with a test override to look for the subject marker
! (plist-put
! (plist-put (imap-hash-make server port mbox)
! :test (format "^%s%s"
! tramp-imap-subject-marker
! (if needed-subject needed-subject "")))
! :ssl ssl)))
(provide 'tramp-imap)
;;; tramp-imap.el ends here
***************
*** 553,559 ****
;;; (tramp-imap-get-file-entries (tramp-dissect-file-name "/imap:yourhosthere.com:/test/") t)
;;; (tramp-imap-get-file-entries (tramp-dissect-file-name "/imap:yourhosthere.com:/test/welcommen") t)
;;; (tramp-imap-get-file-entries (tramp-dissect-file-name "/imap:yourhosthere.com:/test/welcommen") t t)
! ;;;(tramp-imap-handle-file-inode "/imap:yourhosthere.com:/test/welcome")
;;; (dired-copy-file "/etc/fstab" "/imap:yourhosthere.com:/test/welcome" t)
;;; (write-region 1 100 "/imap:yourhosthere.com:/test/welcome")
;;; (tramp-imap-get-file "/imap:yourhosthere.com:/test/welcome")
--- 558,564 ----
;;; (tramp-imap-get-file-entries (tramp-dissect-file-name "/imap:yourhosthere.com:/test/") t)
;;; (tramp-imap-get-file-entries (tramp-dissect-file-name "/imap:yourhosthere.com:/test/welcommen") t)
;;; (tramp-imap-get-file-entries (tramp-dissect-file-name "/imap:yourhosthere.com:/test/welcommen") t t)
! ;;;(tramp-imap-get-file-inode "/imap:yourhosthere.com:/test/welcome")
;;; (dired-copy-file "/etc/fstab" "/imap:yourhosthere.com:/test/welcome" t)
;;; (write-region 1 100 "/imap:yourhosthere.com:/test/welcome")
;;; (tramp-imap-get-file "/imap:yourhosthere.com:/test/welcome")
***************
*** 574,581 ****
;;;(file-exists-p "/imap:yourhosthere.com:/test/welcome2")
;;;(setq tramp-cache-data (make-hash-table :test 'equal))
;;;(tramp-imap-handle-file-attributes "/imap:yourhosthere.com:/test/welcome")
! ;;;(tramp-imap-handle-file-inode "/imap:yourhosthere.com:/test/welcommen")
! ;;;(tramp-imap-handle-file-inode "/imap:yourhosthere.com:/test/welcome")
;;;(file-writable-p "/imap:yourhosthere.com:/test/welcome2")
;;; (delete-file "/imap:yourhosthere.com:/test/welcome")
;;; (tramp-imap-get-file "/imap:yourhosthere.com:/test/welcommen")
--- 579,586 ----
;;;(file-exists-p "/imap:yourhosthere.com:/test/welcome2")
;;;(setq tramp-cache-data (make-hash-table :test 'equal))
;;;(tramp-imap-handle-file-attributes "/imap:yourhosthere.com:/test/welcome")
! ;;;(tramp-imap-get-file-inode "/imap:yourhosthere.com:/test/welcommen")
! ;;;(tramp-imap-get-file-inode "/imap:yourhosthere.com:/test/welcome")
;;;(file-writable-p "/imap:yourhosthere.com:/test/welcome2")
;;; (delete-file "/imap:yourhosthere.com:/test/welcome")
;;; (tramp-imap-get-file "/imap:yourhosthere.com:/test/welcommen")
_______________________________________________
Tramp-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/tramp-devel