emacs の Wanderlust で ssh ポートフォワードを使う.

mew だと,デフォルトで ssh のポートフォワードに対応できているが, wanderlust は対応していないっぽい.むむ.

というわけで elisp の勉強がてら,mewの実装を参考に wanderlust 用のものを 作ってみた.

まずmewのソースを読む.

  • mewsshによるポートフォワードの処理は mew-ssh.el に書かれている
  • mew の共通関数は mew-func.el に書かれている
  • mew-ssh.el中の, ssh コマンドにてポートフォワード用のトンネルを掘る部分の要点をまとめると次のような感じになる.
    ;; プロセスを生成する
    (setq pro (apply 'start-process
	     name buf
             ssh "-x" "-v" "-L"
	    (format "%d:%s:%s" localport server   remoteport)
            (append args (list sshserver))))

    ;; ssh コマンドの出力を処理するコールバック関数(?)を登録
    ;; コールバック関数では,入力された文字列を処理して
    ;; トンネルの開通とか,認証失敗とかを判定し
    ;; その結果に応じて 状態変数 を更新する
    (set-process-filter pro 'mew-ssh-filter)

    ;; プロセス pro が死んだ場合の処理を行うコールバック関数(?)を
    ;; 登録する
    (set-process-sentinel pro 'mew-ssh-sentinel)

    ;; 状態変数 の状態が変わるまでポーリング
    ;; 実際には mew-rendezvous にて行われる処理 
    (while (null (mew-ssh-get-status pnm))
       (if mew-xemacs-p
	 (accept-process-output)
       (sit-for 0.1)
       ;; accept-process-output or sleep-for is not enough
       ;; どうもこの関数で,C-g などのイベント処理を行うみたい.
       (discard-input))))
  • C言語でいうところの printf デバックをする場合はつぎのような感じ.

mew-ssh.el より抜粋

(defun mew-ssh-debug (label string)
  (when (mew-debug 'net)
    (save-excursion
      (set-buffer (get-buffer-create mew-buffer-debug))
      (goto-char (point-max))
      (insert (format "\n<%s>\n%s\n" label string)))))

使うときは

  (mew-ssh-debug "らべる:" "文字列")

とまあ,色々調べた結果なんとか wanderlust での ポートフォワードに成功.うーん便利.でもコピペしまくりのコードなので公開はできないなぁ.