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

Reply via email to