2008年1月30日水曜日

mutt 添付ファイル名がヘンテコリンな場合

muttでattachmentの画面で、ファイル名のサフィックス部分にスペース文字を含んでしまって、

I 2 ホゲホゲ定例_080130.p df [applica/pdf, base64, 32K]
とか、
I 2 ホゲホゲ定例_080130. p df [applica/pdf, base64, 32K]

こんな感じになる場合がありますねぇ~これって送り先が変なファイル名で送ってきているのか、mutt側の問題なのか、私には判定できませんがぁ。この場合添付ファイルを保存してWindowsにfview.tclで転送・表示させようとしても、サフィックスがこの有様だとうまく行きません。

付け焼刃ではありますが、fview.tclを修正して対応!
こんな感じのprocをつけたして、

proc validate_suffix {euc} {
regexp {\.([\w\s]+)$} $euc all sfx
regsub -all {\s+} $sfx {} sfx2
regsub $sfx $euc $sfx2 euc
return $euc
}

転送する直前にファイル名のサフィックスを訂正しておきます。

file rename -force $path [set path $path_valid]

こうしておくと、
ホゲホゲ定例_080130.p df
こんなのや、
ホゲホゲ定例_080130. p df
なのも↓
ホゲホゲ定例_080130.pdf
にファイル名を変更してからWindowsに転送できますので、対策完っとなりますねぇ。

2008年1月29日火曜日

mutt bindとmacro

.muttrcに下記のように書き込んでみますと、


bind pager \cd half-down
bind pager \cu half-up
macro pager + <enter-command>^aset<space>pager_index_lines=20^e\n
macro pager - <enter-command>^aset<space>pager_index_lines=6^e\n
macro pager = <enter-command>^aset<space>pager_index_lines=6^e\n

動作は簡単ですね。CTRL-Dでページのハーフダウン、CTRL-Uでページのハーフアップ。
+ でインデックス・ウィンドウの拡大、-や=で縮小。

.muttrcのここでのポイントは<space>って記法。ホントにスペースを打ち込むと,<enter-command>は1引数なので、そこで引数が切れたと判断されてしまいます。これを防いでいます。

2008年1月24日木曜日

screen bell_msgでバナー表示

screenのbell_msgって、結構色々と利用方法のアイディアが思いつきます。
「新着メールが届いたときbell_msgを鳴らす」の他にも、

「新着メールの確認スクリプトを作って、screenのbindに割り当て、bell_msgで表示」
「長時間JOBの終了をbell_msgで知らせる」

など考えちゃいますぅ。デフォルト5秒間しか表示されないbell_msgですが、screenのlastmsgコマンドで再表示できますから、bell_msgは端末の利用者になにかを知らせるには良い方法です。

さらにbell_msgの表示時間も自由に設定できますから(但し秒単位)、bell_msgだけで凝った"お知らせバナー"だって考えられますねぇ~:-)

やりすぎだとは思いますが、
#!/bin/csh -f

set msg=""
screen -X msgwait 1
screen -X msgminwait 0
foreach n (N e w " " M a i l)
set msg="${msg}${n}"
screen -X bell_msg " $msg"
screen -X bell
sleep 1
end
screen -X msgwait 5
screen -X msgminwait 1
screen -X bell_msg "$msg Comes!"
screen -X bell

これで、"New Mail" のメッセージを一文字ずつ、8秒間かかって表示していきます。それから"New Mail Comes!"と5秒間表示して消えます。ちょっとバナーっぽい表示にはできるんですが、不連続な表示と、CPUの状況で動作がぎこちないぃ~:-<
まあ、ホントに利用しようは思っていませんしぃ、こんなことも出来るのねぇ的サンプルです。もちろんbell_msgでは日本語表示できません。

2008年1月22日火曜日

日本語エディタ ng

ここで開発されている軽量版emacs風日本語エディタ。

「Ngとは、Nihongo micro Gnu emacsの略であり、決してNo Goodの略ではありません。一言でいうと、NgはGNU Emacsライクな小型日本語エディタです。 Ngは、吉田さんによって、1990年ごろ、 mg(micro GNU Emacs/これもmicro Emacsの改良版です)を改造する形で作られました。その後、多くの人達の協力によって、 Ng 1.3.1(最後の公式版)/1.3L(最も多く使われている版)まで改良、バージョンアップされました。その後、マシンパワーの増大、Demacsの登場、MS-DOS/Human68kの衰退等によって、 Ngが使われる機会は少なくなり、開発も下火になりました。

しかし、中にはNgを使い続ける輩(私もその一人です)もおり、そのような人達によって、便利な非公式パッチや、新しいOSへの移植などが作られました。
私もこれらのパッチを当てたり、自分でソースをいじったりしていました。
自分のためにNgに手をいれていく内に、Ng 1.3Lより便利になって(自画自賛)、新たな機種にも対応したので(私の力ではありませんが)、 Ngの新たなバージョンとして公開する事にしました。」とあります。

Emacs嫌いの私、その理由は「なんせ重いのよぉ」なのとCRTL押し続けたくない、のと、lispが嫌い、なことですぅ。で、軽量Emacsモドキのngです。日本語エディタとして目に付くのは、Emacsやvim、ne、そしてこのngなど、このくらいでしょうかぁ。vimを日本語エディタとして使わないのは、viは英語圏に最適化されている、つまり単語の区切りはスペースだっつーことを最大限利用したキーマップやコマンド体系になっているように感じられるから。これを日本語みたいに単語の区切りがハッキリしない言語へ適用してもメリットはあんまり無いっと思うぅ。「日本語」を扱う観点から考えるとなにもviでなくても良い。neを長らく使ってきたが、なにせ最大の欠点が「コピペで段落が乱れてしまう」ってことです。これは辛い。で、ngなワケです。

私C-xをscreenのプレフィックスに使っちゃってます:-P
で、コマンド・プレフィックスをC-rへ変更。C-zは「Ng をサスペンドするには、C-z をタイプします」なのですが、screenの元ではサスペンドはまず使いませんし、私はよくUndoと勘違いします。

makeは至って簡単で、linux用は、ln -s sys/sysv/Makefile .;make で完成し設定ファイルを cp dot.ng ~/.ng で置いておきます。

プレフィックス文字をCTRL-x から CTRL-rに変更するため、~/.ngへ下記を追加します。

(global-set-key "\^r" "c-x prefix")

ふぅ~、Emacsのlispとちょっと似ていますが、マニュアルが見当たらないので一苦労です。起動すると、おっ、コピペもバッチリ:-)

ne同様、ngって名前、短すぎますねぇ、ググるとノイズがひどい。

ターミナル(2) kterm

お仕事でログインしているマシーンにktermが無いっ。まぁ私はあまり困りませんが。

ktermっとは一体誰が開発しているのでしょう。ググるとpatchが沢山ありますねぇ、Cygwin用やらlinux用やら。特にフォント関係ではFAQとしてここが詳しいようです。

xset q でフォントパスを調べて使えそうなフォントを探すっ。きっと名前は kなんとか、kanji*とかねっ。で、その名前で、

$kterm -km euc -fk k14 -fn 7x14

こんな感じでktermを起動します。因みに-fk(漢字) -fn(英字) -km(漢字モードeuc/sjis)。
これでファイルの中身なんかはちゃんと見えますが、日本語ファイル名なんかをlsしても化けます。これは/bin/lsが日本語を通さないためでしょう。fdcloneなら表示してしまいます。

2008年1月20日日曜日

X Window 上でUSBキーボードから/や_を入力できない?

X Window 上でUSBキーボードから/や_を入力できないことがあります。.xmodmapを修正すれば良いのですが、日本語キーボード用の.xmodmapなんて大概どっかのWebで公開されているものを引っ張ってきたものを使ってたりして内容なんて見てませんでしたぁ:-)

いざ使えないとなると、とっても困るので、.xmodmapの内容についてちょっとだけっ。中身は、

keycode 数字 = キー

みたいになっていますので、例えば`_`が入力できなければ、そのキーコードが.xmodmapに書かれていないと思われます。
まずは、キーボードを打った時にX Window Systemへ伝わるキーコードをxevで調べます。xevを立ち上げて、`シフト+_`を打つと、

KeyPress event, ....
...... , keycode 211 (keysym 0x5c, backslash), ....
......

分け解らんメッセージですが、`シフト+_`はどうやら
「keycodeが211でbackslash付き」
と想像できます。これを.xmodmapへ書き込んでやりましょう。

keycode 211 = backslash underscore

Xをリスタートすると、`_`が打てるようになります。他のキーでも同様になっていますので、.xmodmapを自前で全て作成することができます(フツーやりませんけどねぇ、公開してくださっている方、ありがとう:-)

新着メールが届いたらscreenに知らせる -Xオプション

screen上で作業中に新着メールが届いたら、screenに知らせるっ、便利ですぅ。
動作中のscreenでコマンドを実行するには、screenの-Xオプションを使えば簡単に実現できますね。

screen -X bell_msg "New Mail New Mail!"
screen -X bell
これで現在起動しているscreen のWindowの右隅、ちぃっちゃくメッセージが5秒間出て消えます。

screenのセッションが現在のホスト上に複数立ち上がっていると-Xオプションがエラーを返します。
screenは、セッション名(sessionname)、WindowID(番号またはタイトル)で状態を管理しています。セッション名は、pid.tty.hostです(pidは省略可)。現在のホスト上にあるscreenのセッションリストは、screen -lsで表示されます(存在しない場合1を返します)。特定のセッションを選択してコマンドを送信するためには-Sオプションでセッション名を指定します。

screen -S pid.tty.host -X bell_msg "New Mail New Mail!"
sceen -S pid.tty.host -X bell

すべてのセッションにメッセージを送るには、
[hogemailyo]
#!/bin/csh -f
foreach s (`screen -ls|awk '{print $1;}'|grep "\.")
screen -S $s -X bell_msg "$*"
screen -S $s -X bell
end
こんな感じになります。

私はfetchmailが新着メールを受け取ったとき、procmailへ振り分けたりしていますので、

[procmail_with_screen_bell.shスクリプト]
#!/bin/csh -f
cat | procmail
foreach sss (`screen -ls | egrep '[0-9]+\..+\..+' | awk '{print $1}'`)
screen -S $sss -X bell_msg "New Mail Comes!"
screen -S $sss -X bell_msg
end

のようなprocmailのラッパ・スクリプトを作っておいて、fetchmailから新着メールを渡すように、.fetchmailrcのmdaの部分を

[.fetchmailrc内]
mda "procmail_with_screen_bell.sh"

としてしまいます。
これで、
fetchmailが新着メールを受け取り、procmail_with_screen_bell.shスクリプトへ渡す
procmail_with_screen_bell.shがprocmailへメールを渡す
procmail_with_screen_bell.shがscreenへメッセージを表示する


メールが届くと、左下にちぃッちゃく、"New Mail Comes!"と表示されますねぇ。

mutt POP3フォルダ

mutt 1.4辺りから、POP3 フォルダ機能がサポートされ、spoolfile設定に、pop3サーバを直接指定できるようになっています。

set spoolfile=pop://pophost.com:110/

同様にimapサーバも扱えます。

set spoolfile=imap://imaphost.com:143/

フツーのpop3アクセスの場合、
set spoolfile=~/Mail
set folder=+inbox

のようにして置いて、まずpop3サーバからメールをinboxへフェッチしてから閲覧していましたが、POP3フォルダはフェッチ無しで直接pop3サーバを見に行きます。当然ローカルディスクを使用しないので、既読/未読の状態を保存することがでません。

mutt attachファイルを特定の場所へ保存する

linux上でmuttを走らせてメールを読んでいて、doc添付メールを開こうと思う。このときlinux上のmuttで何が出来るでしょう?かつては意地でもdocファイルをlinuxで見えるようにしようとがんばってましたが、完全あきらめ。
で、Windows用のファイルなのだからWindowsで見れば良いでしょう、ってことにしてます。linux上で添付ファイルを保存する場所を一箇所に決めてしまい、いつも添付ファイルはo同じ場所へセーブしています。muttでは、下記のようにmacroを使って、

macro attach s <save-entry>^a~/.Mail/attached_files/^e
macro attach <return> <save-entry>^a~/.Mail/attached_files/^e\n

これで、添付ファイルの参照モードからリターン・キーやsキーに対してデフォルトの保存先がいつも一箇所になります。このmacroの定義記述は、
attachモードで
sキーを押すと
save-entry関数が呼ばれ
ctrl-aでミニバッファの先頭へ移動し
/.Mail/attached_files/とキー入力を擬似し
ctrl-eで行末へ移動し
改行を打つ
ところまでやってくれるmacroの定義です。

添付ファイルがいつも一箇所に保存されているので、fdcloneで、
fd ~/.Maildir/attached_files/
で参照できます。またfdcloneの.fd2rcに、

# launcher definition
launch ".html" "w3m %C"
launch ".htm" "w3m %C"
launch ".exe" "fview.tcl %C"
launch ".xls" "fview.tcl %C"
launch ".csv" "fview.tcl %C"
launch ".ppt" "fview.tcl %C"
launch ".doc" "fview.tcl %C"
launch ".pdf" "fview.tcl %C"
launch ".zip" "fview.tcl %C"
launch ".lzh" "fview.tcl %C"
launch ".cab" "fview.tcl %C"
launch ".jpg" "fview.tcl %C"
launch ".tif" "fview.tcl %C"
launch ".bmp" "fview.tcl %C"
launch ".gif" "fview.tcl %C"

と記述しておくと、ftp転送スクリプトへ選んだファイルが転送されます。

また、いちいち確認せずにWindowsへ転送してしまうためには、

macro attach <return> <save-entry>^a/svhome/ogurak/.Mail/attached_files/^e\n<shell-escape>^afview.tcl<space>~/.Mail/attached_files/^e\n

とするとリターンを打つと即座にWindows上で表示できます。
これは最初の<save-entry>でファイルを所定の場所へ保存後<shell-escape>で所定の場所で最新のファイルをWindowsへ転送・表示することになります。ここでのfview.tclはファイル名ではなく、ディレクトリを引数として最新のファイルを探し出して処理しています。

2008年1月18日金曜日

どこへいった? fetchmailのdaemon

linuxサーバセンタみたいな環境で数十台のlinuxを相手に仕事をしていると、使うlinuxマシーンを変えた時に「昨日Loginしていたマシーンっ、、どれだった?」状態になります。GNU Screenなんかで作業を保存していたりして、困るときがありますぅ。まあscreenの復帰はあきらめるとして、一番困るのはfetchmailのdaemonではないでしょうか。どっかで動いて、spoolにどんどんとメールが届くのは良いのですが、止めたくても止められない。

$ chmod 000 .fetchids

としてみてもダメ。勝手にchmod 700 .fetchidsに変更して使っちゃうぅ~。どこにいるのかいなぁ~私のfetchmail daemonクンは?
片っ端から知ってるlinuxマシーンへLoginして自分のfetchmail daemonを探す羽目にならないように、fetchmail daemonを起動する時はラッパを噛ませて起動したマシーンのipアドレスを保存しておきましょう。

#!/bin/csh -f
ifconfig | grep 'inet addr' > ~/.fetchmail.ip
fetchmail -U -s -d 600

こんなものを使っていますぅ、fetchmail自信、同じようなことをしているのでしょうか?

メール送信プログラム nbsmtp

sendmailを祖先とする沢山のsendmailクローン達。
ホント沢山いますよねぇ

exim
im

等使用経験があるのですが、最近はSMTP Auth対応のsmtpに出会う機会が増えています。ここでもimのimputにSMTP Authと無理やり会話させる修正など書いています。

nbsmtp
コレ簡単にSMTP Authと会話できるMTAです。
.muttrcに、
set sendmail="nbsmtp -d hogehoge.com -h smtp.hogehoge -f ogura.kenji@hogehoge.com -V"
って感じ。SMTP-Auth経由でメール送信できます。

~/.nbsmtprcにユーザ名とパスを書き込みます。
auth_user = user-hogehoge
auth_pass = pw-hogetta

chmod 600を忘れずに。

muttの弱点と克服

muttの弱点。
思うに1つありますねぇ。

「新規メールを書きながら、他のメールからコピペすることができない」

Windowsのメーラでは送信メールを書く場合、新規Windowが伴って作成されることが多いです。なので、他のメールを参照したり、コピペしたりは簡単。対してmuttはフツーに使うと、muttがエディタの終了を待ってしまいます。

[エディタ立上げ]→編集&保存→[送信確認]→[送信]

のフローでメール処理が進みますから、他のメールからコピペできないです。
ググっても良い解答はなかなか得られませんでした。

幾つか方法があるように思われます。
①別メールの参照用にmuttをもう一つ立ち上げる
②別メールの作成用にmuttをもう一つ立ち上げる
③別メールの参照機能をmuttに付加する(mutt改造)

③は重いので考えないっ。
②は別メールの作成といっても、全員返信やら、個別返信、転送、中継など色々な状況によってmuttは動きを変えます。別メールの作成用にmuttを立ち上げる時、いろんな立ち上げ方法を実装する必要が有りそうで、実現は難しいそうぅ。
ってことで①でしょうか。。。

単純にmuttを2つ立ち上げるのは、智慧が無いように思われるので、もう少しカッコよく、参照用またはメール作成用に別プロセスでmuttを立ち上げる方法を考えてみす。mutt(1.4)のコマンドラインオプションを見てみると下記。

引数なしに muttを実行すると Mutt はスプールメールボックスを読みに行きます。しかし、コマンドラインから指定してやることで他のメールボックスを読んだりコマンドラインから直接メールを送ったりすることも可能です。

-a メールにファイルを添付する
-b BCCのアドレスを指定
-c カーボンコピー (Cc) の宛先を指定する
-e 初期化ファイルが読まれた後に実行する設定コマンドを指定
-f 読み込むメールボックスを指定
-F 指定したファイルから初期化コマンドを読み込む
-h コマンドラインオプションについてのヘルプを表示
-H ドラフトとしてヘッダと本文を読み出すファイルを指定
-i メッセージ作成時に取り込むファイルを指定
-m デフォルトのメールボックスの種類を指定
-n システムの Muttrc を読まない
-p 延期していたメールを呼び出す
-R メールボックスを読み取り専用で開く
-s subject を指定 (空白を含むときは引用符で囲む)
-v バージョンとコンパイル時の定義を表示
-x mailx(1) の作成モードを真似る
-y mailboxes コマンドで指定されたファイルを含んだメニューを表示させる
-z メールボックスにメッセージが存在しないなら直ちに終了する
-Z 新しいメッセージのある最初のフォルダを開く、無いなら直ちに終了する

ほぅ~けっこうあるんですねぇ:-)

でっ、ちょっとだけ閃きましたぁ
muttがmコマンドやgコマンドでメール作成に取り掛かるとき、一時ファイルを作成し、このファイルを引数としてエディタ(set editot=プログラム で指定したもの)を起動します。エディタが終了してファイルがセーブされると、送信/保存の選択を聞いてきます。エディタが終了しても渡したファイルの内容に変化がないと、メール閲覧モードに移行します。なので、エディタとして例えば常に1を返すだけのtrueコマンドを使用すると、メール作成モードに入り、宛先とサブジェクトを指定した後すぐにメール閲覧モードに戻ってしまいます。
この動きを利用できそうです。エディタとして例えば下のようなスクリプト(hogetto)を指定します。

[editorhogex]
#!/bin/csh -f
xterm -e mutt -H $1 -e 'set editor=ne' &
sleep 1

上のhogettoスクリプトはメール作成モードの新しいmutt(-Hオプション)をxterm上で起動して、1秒待って終了します。なので元々のmuttは渡したファイルに変化がなかったのでメール作成モードを終了してメール閲覧モードへ戻ります。
メール作成モードで立ち上げたxterm上の新しいmuttは、一時ファイルを引数に与えて、エディタとしてこの場合`ne`を立ち上げます。

元々のmuttが作った一時ファイルを消去する前に新しいmuttがそれを確実に読み込んで立ち上がるために、sleep 1を入れて元々のmuttが動き出すまでに1秒の`待て`をいれてあります。

mutt -Hオプションは、与えられた一時ファイルからヘッダと本文をインクルードしますから、ヘッダ部分に宛先とサブジェクトが書かれていれば、それを用いてメールの雛型を作ってくれます。なので一時ファイルにヘッダを含めておく必要が有ります。このために、edit_header=yesとしておきます(muttのdefaultではedit_header=no)。

これで元々のmuttはメール参照モードへ戻り、新たにメール作成・送信用のmuttがxterm上で別ウィンドウとして立ち上がります。コピペも楽になりました。ここではxtermを使用していますが、ウィンドウマネージャとしてGNU screenを使用しているのであれば、-X オプションで立ち上がっているscreenへコマンドを送ることで別のセッションが作成できますね。またscreenは起動していると環境変数TERMにscreenを設定、環境変数STYに現在のscreenセッション名を設定してますので、この場合、

[editorhogescreen]
#!/bin/csh -f
if ($TERM == "screen") then
screen -S $STY -X screen mutt -H $1 -e 'set editor=ne'
else
ne $1
endif
sleep 1

このhogeronは、screenプロセスに対して、「screenを一面追加してそこでメール作成モードのmuttを起動させる」ことができます。screen の-Xオプションは即座にリターンしてきますので、この例では、&を付けてプロセスを分ける必要はありません。

一点、メール作成モードでmuttを立ち上げたとき、一時ファイルの内容から割り出した宛先でメール作成するかどうかをmuttが聞いてきます。これは不要なのですが。まぁリターンを2度叩くだけなので気にはなりませんが。

透明 Window その1

すけすけウィンドウ。
Windowsの世界ではWindows2Kぐらいから、 ここにもあるように透明なウィンドウが流行った時期がありましたねぇ。私もさんざっぱら色々試してみまて、「ほぅ~(^^)こんな感 じになんるんだぁ~」と。

結局、ウィンドウが重なって下の画面がうっすら見えるんだけど、3重、4重とウィンドウが重なると、なにがなにやらわっかりにく~いデスクトップになって しまったような。2重ぐらいが限度かなぁと思いました。相当大きなディスプレイなら3重4重でもイイかもしれませんね。まあ使い方の問題なのでしょう。

すけすけウィンドウの話題は未来的なコンピュータへの想像を掻き立てた面があります。新しいユーザインタフェースを感じさせるような。iPodに代表され るような新しいUIの出現をPC上でも予感させましたが、実際、すけすけ機能だけでは、斬新ってだけで、PC環境として成熟してゆくことは無かった気が します。

アイディアも色々ありますねぇ
①「タスクトレイアイコンの右クリックメニューから、半透明表示したいウィンドウの名前を選択する
②「ドラッグ操作で移動中のウィンドウだけを半透明表示する」
③「アクティブウィンドウ以外のウィンドウやダイアログを半透明表示にする」
④「画面の四隅にマウスポインタを動かすだけでアクティブウィンドウを半透明表示する」
⑤「ウィンド ウを広げた時に隠れてしまうデスクトップアイコンを、一時的にウィンドウの上に浮かび上がらせて表示し、クリックしやすくする」

ratpoisonなどの環境下では、④辺りが馴染むでしょうか。全画面表示の状況でマウスを四隅へ持っていくと半透明化して下のウィンドウがすけて見えるってこと。
ですが、X windowのクライアントはすけすけにはなりません。まあそうでしょうねぇ。無理があるのでしょう、きっとぉ。
telnet(PuTTY)を全画面で使用している場合は、ちゃんとすけますねっ。願わくば、
「四隅に持って行くだけでなく、何かのキーに透明化/解除を割り当てられると、ぴったり使用感になりそうです」が。rxvtでの「すける」とは単にデスクトップの背景を自分のウィンドウサイズ分切り取って自分の背景に設定しているだけみたいなのですが、この「④のすけすけ」は(っていうか、Windows2Kの透過機能は)全然違ってウィンドウの下で動作している他のアプリの様子が判ります。すばらしい。何か時間のかかる処理を待っている間、別の仕事を全画面表示で(-:やるには最適な感じですねぇ。
ところで、透明化したウィンドウをcapcapみたいな画面キャプチャソフトが無視してしまうのは困ったものですぅ、皆さんどうやってカッコいい画面をWebで公開しているのでしょうか。。。とほほぉぉ

すけすけ話しはまだまだ続きます。ToBeCotinued

2008年1月16日水曜日

ratpoison i18n: The Simplest Window Manager

こんなCUI Window Managerもあるんですねぇ。
ratpoison

「殺鼠剤」というだけあって、ひと癖もふた癖もあるウィンドウマネージャーなので万人にはおすすめできない。
* キーボードを叩くのが好きな人
* マウス操作は面倒だと思っている人
* Emacs使い
* GNU Screen大好きな人
* ウィンドウマネージャーをスクリプト言語で遠隔操縦するのが好きな人
* 変わったソフトを試すのが好きな人
っとあります。(まさに私のことではないかいなぁ、但しEmacsの部分は除く:-)

でもでも、結局X Windw上でごちゃごちゃやってるって感じですね。ratpoison以上に作者のShawn Bettsって人のほうに興味を惹かれます。だって紹介文が、
「GUI嫌い・マウス嫌いで有名なカナダ人プログラマ。マニア好みなフリーソフトウェアの作者」
ですよぉ:-o

で、インストール(on cygwin)。
ここからダウンロードして、

$ gunzip ratpoison-1.4.2.tar.gz
$ tar xvf ratpoison-1.4.2.tar
$ cd ratpoison-1.4.2
$ ./configure --x-includes=/usr/X11R6/include --x-libraries=/usr/X11R6/lib/
$ make
$ make install

と、なんなくmakeに成功。
.xinitrcを、

xhost +
xeyes &
xterm &
exec openbox "$@"

# exec openbox "$@"
exec ratpoison "$@"

としてXを起動する、、、おおぉデッカイ xeyes !続いてxterm がフルスクリーン!
巨大xeyesに睨まれてビックリしました(^|^)が、無事起動。

がっ。やっぱり下記の通り、

「ratpoisonは慣れれば十分実用的なウィンドウマネージャーなのだが、どうしても相性の悪いソフトは存在する。
  • たくさんのウィンドウを開くソフト。主にgimp
  • 最大化すると表示がゆがんでしまうソフト。主に画像ビューワ

前者の代表としてはgimpが有名である。 ratpoisonの天敵ともいえるgimpをどう対処するかについて述べる。」

とあるように、ratpoisonではつらいX プログラムもある、って、私のX プログラム(以下hogehoge)がまさにこれに当てはまってしまった。ん~っと、ここはXnestで乗り切るしかないねぇ~(だんだんツボにハマッテてきてないだろうかぁ:-o

Xnest -geometry 1024x768 -kb :1 &
DISPLAY=:1 openbox &
DISPLAY=:1 hogehoge &
(cshの場合は、
env
DISPLAY=:1 openbox &
env DISPLAY=:1 hogehoge &
)

これでhogehogeクンはopenboxの元、無事最大化されずにratpoisonの管理下に入れました。

2008年1月15日火曜日

Winodwsは X Protocolを理解しない 当たり前?

WindowsはX Protocolを理解しない。
当たり前すぎるけれど、理解したとしても不思議でもない。Windows上で走れるX Serverが市販ソフトとして存在すれけれど、なにもWindowsって名のWindow管理ソフトをインストールした上に更に、X Windows Serverって名のWindow管理ソフトをインストールするのも無駄といえば無駄。

WindowsがX Protocolをサポートして販売してくれると、ユーザとしてはウレシイ。ついでに日本語入力やらフォント環境やらも共通化ってのはどうでしょう。もっとウレシイ。そんでもってX Window向けに作ったプログラムがWindowsでも走れると更にプログラムの節約にもなる。

X Serverソフトが売れなくなるなんて心配する必要は無いでしょう?だって既に売れていないからねぇ。大概はcygwinで間に合っちゃう。高速な描画が必要なlinuxソフト(レイアウトやらグラフィックス)の場合、やっぱり最適化されたX Serverが必要だろうけど、ニッチ、ニッチ。この際、WindowsにX Protocol載せてくれないんでしょうか?

cygwin X の起動スクリプト.bat

cygwin Xを起動する場合、cygwin bashから、startx を起動するとcygwin bashのウィンドウが残ります。このウィンドウを終了させると Cygwin Xも終了してしまうぅ。ので最初のcygwin bashのウィンドウを残しておく必要がありそうなんですが、なんか目障りです:-<

まずは、startxスクリプト中のxinitを起動している部分を cygwin runで包みましょう。

xinit "$@"

run xinit "$@"

これでcygwin bashは不要になりますので、cygwin bashを起動する.batファイルを
@echo off
C:
chdir C:\cygwin\bin
bash --login -i C:\cygwin\home\ogurak\startx

こんな風に作っておくと、Windowsからこの.batを起動することでcygwin Xが立ち上がりますねぇ:-)
runコマンドに関して、

run コマンドはコンソール・ウィンドウを隠してプログラムを実行する Cygwin 独特のコマンドです。 Cygwin プログラムのほとんどはコンソール・モード・アプリケーション *14ですから,本来ならば,標準入出力のためのコンソール・ウィンドウがまとわりつきます。 run コマンドは,このコンソール・ウィンドウを隠して,あたかも GUI モード・アプリケーションのような見かけにします。 run コマンドはもともと Cygiwn 用 X11 プログラムのひとつでした。しかし,今年 (2005年) 11月に改編され, base カテゴリの独立パッケージになりました。今は X11 を導入しなくてもデフォルトでインストールされます。
などとあります。

てことで、更にこんなサンプルも・・・
@echo off
C:
chdir \cygwin\bin
run bash -l -c 'cd /usr/local/lib/pysol-4.81/src; python pysol.py --nosound'

なので、startxのように、startxを編集せんでも、start.batを
bash --login -i C:\cygwin\home\ogurak\startx

run bash --login C:\cygwin\usr\X11R6\bin\startx
としておけばOKです。

vim の vi互換モード

最近のlinuxディストリビューションで、viを起動するとvimが立ち上がりますよね。
でもvimは嫌いです。viなんてエディタ以上のことを期待してません。
高機能な環境みたいなものが必要ならEmacsenを使えばいい。で、vimのvi互換モードですが、

~/.exrc
に、
set tag=tags
set tabstop=4
set shiftwidth=4
set compatible
set backspace=0
set noswapfile

こんな指定を入れています。特に、
set noswapfile
を入れたことで、編集中に「ファイル名~」なファイルが作成されなくなります。
バックアップファイルが無くなって困ることがあるのでしょうか?私がつかいこなしていないだけでしょうかねぇ・・・

[Tips]viで制御文字を入力する。
ここから
Cntrl-V
に続けて制御文字を入力できます。
例えば、dos2unixと同じことが、
:%s/Cntrl-VEnter//
で可能です。

2008年1月13日日曜日

色々なプロセス構成

linux上で動くプログラムを書くことがお仕事だとして、screenやmutt、w3m、telnet、fdなどをcygwin上かlinux上か、どこで動ごかすと使い勝手は良いのだろうか?という疑問。
状況を整理してみますうぅ。

構成①として、
cygwin上で、bash→screen/mutt/w3m/telnet→linux上で、fd

また、私が推奨する構成②は、
windows上で、telnet→linux上で、screen/mutt/w3m/fd

構成①では、まず、Cygwinのターミナル(rxvtとかcygwin bashとか)を起動し、その上でscreenを起動します。screenからmuttやw3m、そしてtelnetでlinuxへ接続しfdを起動します。つまりメールやウェブはWindows上で動作させます。

対して、構成②は、まずPuTTYなどのWindowsのtelnetソフトでlinuxへ接続します。接続先のlinux上で、muttやw3mやfdを起動します。つまりtelnet以外は全てlinux上で動作させます。

構成①でも②でもあまり使い勝手に違いは無いのでしょうか?

screenはCtrl-Dでサスペンド、screen -rで復帰することができます。当たり前ですが、サスペンドしたscreenプロセスがdaemon化するなどの状態で生きていないと画面の復帰が出来ません(screenはdaemonとして行き続ける事で、対話動作のサブプロセスなどを制御しています)。例えば、cygwin bashから、rxvtを立ち上げてscreenを起動し、お仕事をして、中断のためCtrl-Dでサスペンド。もしその後でrxvtやcygwin bashを終了してしまうと、Ctrl-Dで中断しておいたはずのお仕事の続き画面がscreen -rで復帰できなくなります。cygwin bashを常に起動しておけばscreen -rで復帰できます。
linux上では、Ctrl-Dで中断したscreenプロセスがdaemon化してlinux上で生き続けている状態にありますので、telnetを切断しても、後程再接続すればscreen -rで続き画面を復帰できます。

linuxであろうがWindowsであろうが、システムの電源が落ちてしまえば、プロセステーブルは消えて無くなるので復帰できなくなることは同じなのですが、最近のlinuxサーバなど常時稼動が普通ですから、screenプロセスを生かしておくにはlinuxサーバ上が便利です。

一方、Cygwin上でmuttが走っていれば、ftpを経由した添付ファイルの転送など不要ですから便利です。

結局は、Windows用のプログラムを書くのか、linux用のプログラムを書くのか?ターゲット側でscreenを使用するのがよいようですねぇ

2008年1月12日土曜日

w3m

telnet先で動作させるページャ w3m。

w3mは「www(w3)を見る(m)」から命名されたそうです。ページャとしてhtmlを見る着想はとっても面白いです。xlsやらwordやらをhtmlへ変換して、見れるところだけw3mで見る、なんてことも出来ます。
lessがhtmlフォーマッティングをサポートした感覚です。

ここで開発されています。

ググればたくさんの情報が得られます。
ここ では、WordやExcelをw3mと絡めて表示させるヒントがあります。(って私のページですけど:0) xlHtml, pptHtml,wvHtml等など

w3mの~/.w3m/mailcapでエントリを追加することでw3mはリンク先のアドレスを判定して、対応するプログラムを呼び出すようになります。

こ れでMS-Officeが不要になるわけもありませんね、だってMS-Officeの文書には画像やらグラフやら、テキストベースではない表現が沢山入っ ていますし、第一ファイルの文字部分だけが見えるだけで編集は出来ません。だからlinux側で全てを完結するのは困難だと思えます。

しかし、大切なのはw3mがリンク先のファイルをテンポラリ場所へ保存してくれて、そのパスを外部プログラムへ渡してくれることですね。この機能を利用して、ファイルをftpでPCへ飛ばし、PC側で表示することが簡単に出来るわけです。
こ のブログにもあるような( ②linux側のftpクライアントスクリプト)ものを~/.w3m/mailcapに指定しておけば、w3mでpdfを見よ うとすると、ローカルにセーブされたファイルがPCへftp転送されて、PC上のAcrobatで表示される仕組みが簡単に作れる。たとえば、

application/* ②linux側のftpクライアントスクリプト %s

み たいなエントリを~/.w3m/mailcapに書き込めば良い。勿論PC側ではちょっと特別なftpd( ①PC側のftpdサーバスクリプト)を立ち上 げておく必要があるがぁ。上のエントリ で/*とあるのは強力だろう?だってPCで表示できそうなものは全てPCで表示するってわけだから。「だったらWebページもw3mではなく、PCで見れ ば?」とは考えないでほしいっ。PCで見る必要がないページはw3mで十分だと`私`は思っているから。。。

fdclone

telnet先で動作させるファイラーfdclone。
便利ですし、コンパイルで工夫する必要はまったくありません、Cygwin上でも動きます。
DOS時代のFDをlinuxのクローンとして作成されたものらしいです。

ここで開発されています。

ググればいろいろと情報はありますが、開発元のページですべて事足ります。
このファイラーは強力ですから、設定次第で色々な場面で大活躍します。日本語ファイル名も難なく表示しますし、.fd2rc次第です。

telnet(1) PuTTY

Windos telnetとしても選択肢は広いような狭いような。
Windows上で使用するtelnetの話です。

PuTTY

「すけすけ」telnetが可能です。"puttyjp"でググると情報が得られます(まずはここ)。 フルスクリー ン・モードがあって、完全にWindowsが見えなくなります(見えなく出来ます:-)。ALT-Enterでフルスクリーン・モードがトグルします。フルス クリーン・モードに入ったら、他のWindowsアプリとの切り替えに、ALT-Tabが便利でしょう。

これはターミナルソフトではないので、お仕事先linuxへ接続して使用します。安定感も日本語も問題なくスバラシイ。

ターミナル(1) rxvt 非X版

ターミナルとしても選択肢は広いような狭いような。
Windows上で使用するテキストターミナルの話です。

cmd(コマンドプ ロンプト)では話になりマシェ~ん。「すけすけターミナル」にあこがれますねぇ~背景が透けて見えるやつです。Enlightment をつかったカッコイイデスクトップのスクリーンショットがWebのあちこちに掲載されてます。ちょっと未来的な想像を掻き立ててくれます。理想のターミナ ルへの探索。

cygwinのbash
cygwinのrxvt.exe

Cygwin インストールが必要になります。まあbashは当たり前なので割愛。画面サイズが自由に変えられないので選択肢外です。rxvtはcygwin1.dll さえあれば動くので、bashから立ち上げではなくて、非X Windowモードでrxvtを使うことができます。一応「すけすけ」も実現できます。非X Windowモードって、ようするにbashを立ち上げずにエクスプローラからバイナリを直接クリックっです。

「すけすけ」設定は、cmdで
rxvt -xrm '*inheritPixmap=true'
!これでWindowsの背景画像の一部がターミナルの背景になります。単にターミナルの背景画像をWindowsのものと同じに指定して立ち上げたときとは全然見た目が異なりますから、ちょっと感動できますねぇ。
cygwinを入れた場所に依存しますが、バッチファイルは、
@echo off
C:\cygwin\bin\rxvt.exe -bg black -fg white -xrm '*inheritPixmap=true' -e /usr/bin/bash
でしょうか、上は私の例。
-fgで選ぶ色は「すけすけ」ターミナルの場合重要です。Windowsの背景が黒っぽいとまるで文字が見えなくなりますので、白っぽい-fgとしますね。逆もあります。

で、rxvtを起動して自分自身のWindowsにLoginしてみます。
$telnet 127.0.0.1
$ telnet 127.0.0.1
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

Server allows NTLM authentication only
Server has closed connection
Connection closed by foreign host.
$
と 「接続不可」応答が返ってきます。がポート25へ接続を試みたことは確認できます(本当に自分のPCに接続したいならここを参考に telnetdの設定を変更しましょう)。後はお仕事するマシーンへ接続すれば本業に移れます。

非X-Windowで動けるものはCygwinのバイナリの中にいくつもあるでしょうから、試してみても面白いでしょう。私はやってませんが、かたっぱしからクリックしてみて何が起こるのかなぁってことです。

で もCygwinのインストールは必要になりそうですから、結局はPC X WindowとMS-Windowsの両方がPC上にあることになります。なんか無駄に感じますねぇ。cygwin1.dll無しで(または含んでしまう ような)rxvt.exeもどこかにあるのでしょうが(簡単なことなのですが)。

2008年1月11日金曜日

解決したかったこと Windows vs linux

解決したかったことは、なんだったのか。
問題に目を奪われると、「結局なんだったんだ?」と自問自答しないと虚しい結末となる。このブログで何がわかるのか?ってことだ。

linuxマシーンのX Window System代わりにWindowsを使えないものだろうか?
ってのが始まりのように感じられる。UNIX時代からCUIで色んな仕事をしてきたけれど、X Windowが現れ、「ほぅ~便利なもんだ」と思い、X Windowのプログラムも仕事で沢山書きはじめた。まだWindows3.1の頃のお話だ。

そ して、MacOSが現れた。会社中がAppleコンピュータとAppleTalkの世界があった。Appleの上でもtelnetを使って、UNIXマ シーンへLoginして仕事していたなぁ。MacDrawも使いましたねぇ。ドキュメントをワープロで書いていた頃のお話。全部のワープロが消滅しまし た。

そしてWindows95が現れた。会社中がWindows95 PCとEtherに変わった。さてとこのWindows95が気に入らなかった。不安定の一言。Macとの対比があって「Macの方が使いやすいし頑丈 だ、Appleがんばれ~ぇ」。だけどMacの負けでしたね。MS-Office問題が発生したためです。電子メールでmS-Office文書が送りつけ られてきてはお手上げ状態です。仕事するにはWindows95が必要になりました。だけど95からtelnetしてお仕事してました。

そ してWindows2000とlinuxが現れました。WindowsNTはまぁ使いにくかったですがWindows2000はいたって親切設計!コレ でよいかぁと思わせるものです。ですがWindows2000からtelnetしてお仕事してました。そしてtelnet先がUNIXからlinuxへ変 わっていました。

つまり、私にはWindows上での開発話しが回ってこなかっただけのことではあるのですが、ずぅ~とtelnetで仕事してます。

でも不思議に思いませんかぁ?

「ウィンドウシステムが2つ、世の中に存在する必要性」
X Window systemとWindows2000

どっちにも良いところ・悪いところっあるでしょうが、似たり寄ったりのものです。
ホントに2つ必要でしょうかねぇ?

さ て、linux派はX Window上でMS-Officeの互換ソフトでなんとかなるんじゃぁないかと考えて、OpenOffice.orgへと進みますね。最近では MacOSX用にNeoOfficeなんてのもある。ヴェトナムで設計センタを立ち上げたとき、経費節減目的でOpenOfficeを導入しました。それ はそれで良いけれど、どのPCにもMS-Officeがインストールされている日本の状況で、OpenOffice使うのって、なんか無駄な気がしませ んっ?個人的なお小遣いの節約ならよい選択肢でしょう。でも仕事となると信頼性やら効率やら気になりますし、本業は経費削減ではありませんよねぇ~

このブログでは、(無理やりですが)メールをlinux上で読み書きすると仮定した時、一番便利な環境ってどんなものでしょうか、ってことが主題となっています。

mutt ja インストール

非rootでセットアップする。
~/bin/linux/以下にコマンドを配置
~/bin/linux/lib/以下にダイナミックライブラリを配置
~/bin/linux/lib/IM/以下にIMのperlのモジュール(.pm)を配置

(2) muttja, alien, slangのrpmを準備、muttはソース、alienはperl、slangはバイナリ。rpmmkは私のスクリプト。
ls
muttja-1.4-1SDRI.src.rpm
slang-1.4.5-11.i386.rpm
alien_8.56.tar.gz
rpmmk

・rpmmk でrpm/以下のディレクトリを事前に掘って(ダサイ)、バイナリを配置
rpmmk
cp alien_8.56.tar.gz rpm/RPMS/i386/
cp slang-1.4.5-11.i386.rpm rpm/RPMS/i386/

(3) muttjaはソースパッケージなのでバイナリを作る
rpmrebuild --rebuild muttja-1.4-1SDRI.src.rpm
cd rpm/RPMS/i386

・バイナリの展開とインストール
gtar xvzf alien_8.56.tar.gz
cd alien
./alien.pl -t ../muttja-1.4-1SDRI.i386.rpm
gtar xvzf muttja-1.4.tgz
cp usr/bin/mutt/* ~/bin/linux

(4) slangバイナリの展開
alien -t ../slang-1.4.5-11.i386.rpm
gtar xvzf slang-1.4.5.tgz

(5) ダイナミックライブラリの準備
cd usr/lib
ln -s libslang-utf8.so.1 libslang.so.1
cp libslang* ~/bin/linux/lib
setenv LD_LIBRARY_PATH /svhome/ogurak/bin/linux/lib:$LD_LIBRARY_PATH

(6) imputのインストール
gtar -xvzf im-148.tar.gz
cd im-148
./configure

#IM/Smtp.pmを編集して、IMをSMTP-AUTHに対応させる。
#まずはパスワードをutf-8に変換する
perl -MMIME::Base64 -e "print encode_base64('a0203718');"
YTAyMDM3MTg=
#このパスワードをsmtp_openするさいに認証タイプに続けて送信するようにpm 72行目に追加
&tcp_command(\*SMTPd, "AUTH LOGIN", '');
&tcp_command(\*SMTPd, "YTAyMDM3MTg=", '');
&tcp_command(\*SMTPd, "YTAyMDM3MTg=", '');
#pmをインストール
cp -r IM ~/bin/linux/lib

#imputがコピー先のSmtp.pmを参照するように13行目を変更する
use lib '/svhome/ogurak/work5/Package/im-148'; ###DELETE-ON-INSTALL###

use lib '/svhome/ogurak/bin/linux/lib'; ###DELETE-ON-INSTALL###

#これでIM本体は完成したのでimputをインストール
cp imput ~/bin/linux

#muttがimputを呼ぶときに、imput -- mail-addressとなっているのでimput.shで避ける

vi imput.sh
#!/bin/csh -f
set arguments=()
while($#argv > 0)
set a=$argv[1]
if ($a == '--') then
else
set arguments=($arguments $a)
endif
shift
end
cat - | imput $arguments
exit 0

cp imput.sh ~/bin/linux

Mozilla ThunderBird のメールボックスをlinuxへ移行する

ThunderBirdのメールボックスをlinux側でバックアップしたくなり、ThunderBird FAQを調べると、

Thunderbird のメールファイルは、プレーンテキストの標準的な「mbox」形式なので、たいていのメールクライアントでインポートできます。多くの商用メールクライア ントには、同じく「mbox」形式を使用している Eudora からメールをインポートできる機能が付いており、この機能を使って Thunderbird のメールファイルを読み込むことができるはずです。

Thunderbird のメールファイルは、プロファイル (プロファイルフォルダ を参照) の中にある Mail フォルダと (IMAP アカウントをお使いの場合) ImapMail フォルダにあります。メールフォルダ (受信トレイ、送信済みトレイなど) はそれぞれ 2 つのファイルとして保存されています。一つは (INBOX など) 拡張子の付いていないファイルで、(「mbox」形式の) メールファイルそのものです。もう一つは (INBOX.msf など) .msf という拡張子の付いたファイルで、メールファイルの見出し (メール要約ファイル) になっています。他のメールクライアントに、拡張子の付いていないファイルからメールをインポートさせてください。

他のプロファイルにメールを移行したい場合は、単純にメールファイルをそのプロファイルの Mail フォルダにコピーしてください。」

とある。「へぇ~linuxのmbox形式であったとはぁ」といまさらながら知る私でした。
ftpしてmuttで見てみよう。

$ mutt mbox1
Value too large for defined data type (errno = 75)

と落ちました。mbox1がデカすぎでしょうか、2GB以上あります。
ThunderBirdでもそうなのですが2GBオーバーのメールボックスを作ると動作が不安定になります、これっNetscapeの頃から変わっていないのでしょうか。

では、mbox形式をMaildir形式に変換。
ここをセーブ
このperlスクリプトは、

$ mbox2maildir
usage: mbox2maildir [ ]

らしいので、
$ mbox2maildir mbox1 maildir1

でmaildir1/new/以下に分離したファイルが出来上がります。

これで変換は終了。

screen VT100/ANSI 端末エミュレーション機能を持つ画面管理ソフトウェア

screenコマンドをJMで引くと、先頭に、

VT100/ANSI 端末エミュレーション機能を持つ画面管理ソフトウェア

と出る。termベースのWindowManagerだと言いたいところです。それほど便利。
が、ウィンドウ・マネージャって言葉、X WindowのWMを連想させてしまうので少々使いづらい面もありますね。

で、元来screenを使うのが好きです、私は。軽いし、作業状態を保存できるのが有り難いですよねぇ~
あるところで「今日はコレまで」って、^X^D打ってログアウト。。。翌朝はtelnetで接続して、screen -r 打って、昨晩の状況を復帰して続きを・・・

以下私の.screenrc

startup_message off
escape ^X^X # C-x C-x : send ^Z to process
vbell on

bind 'm' screen mutt
bind 'i' screen w3m -B
bind 'f' screen fd ~/.Mail/attached_files
bind 'C' screen w3m 'file:///cgi-bin/cal.cgi'

bind o focus
bind 2 split
bind 1 only

term vt100

簡単ですねぇ~これだけで複数の画面イメージを切り替え(^xpとか^xo)ながら作業ができます。意外と使われていないのでしょうか、それともscreenってコマンド名がググるのに障害となっているのでしょうか。
まあ今の時代、GUIが便利ですもんね!

この.screenrcでは、
デフォルトの^aエスケープを(^aは私的には打ち難いので)^xへ変更して、bindでキーマッピングをしています。
これで、screenから、mutt(^xm)とfd(^xf)とw3m(^xi)を新規画面で起動させることが出来ます。また、^x2で2画面分割、^x1で1画面に戻り、2画面のときのカーソル移動を^xoにしています。

日本語エディタ ne

linux/CUIの世界で、日本語エディタといえば、、、結構無い・・・
Emacsen, vimとかでしょうか?ググっても沢山情報は出てきますが、で、「結局どうするのが簡単か?」となると趣味やら経緯やら人それぞれですね。
何でも良いのですがEmacsenはscreenと相性が悪そうだし重い。ストールマンがオタク過ぎて意見を聞きたくない。vimはプログラム書くためのエディタでしょっ。ワープロとして使うのはねぇ・・・

screenと相性が良くて、軽くて、日本語がある程度正確に扱える、、、neを使ってます。Vzエディタと互換性を持つとかなんとか、、、どうでも良いのでキーマップ(~/.ne/key.vz)を書き換えてEmacsen風に。
ここがneのホーム?
これで十分ですね。
#それにしてもプログラム名がneとは、googleで探し難いのなんのって。

以下オリジナルのkey.vzを変更したものになります。

# エディタキーアサイン (Vzエディタライクな定義)
# 左にキー、:の右に実行する命令を書きます。
# キーは複数をまとめて指定する事もできます。
!R Key

^KW [F02] : file_toggle #62 カレントファイルの交換
^KT [F03] : file_select #63 カレントファイルの変更

[ESC]O : file_open #70 ファイルのオープン
[ESC]C : file_close #73 カレントファイルの編集終了
[ESC]L : file_copen #74 colse and open
[ESC]S : file_save #75 カレントファイルのセーブ
[ESC]Q : file_quit #77 プロファイル保存終了

[ESC]P : file_rename #82 ファイル名の変更
[ESC]W : file_profile #83 プロファイル情報セーブ

[ESC]U : file_undo #M7 カレントの編集のやり直し
[ESC]I : file_insert #M8 ファイルを挿入
[ESC]X : file_aclose #M9 全ファイルのクローズ


^P [UP] : cursor_up #05 カーソルを上へ
^N [DOWN] : cursor_down #06 カーソルを下へ
^H [LEFT] : cursor_left #07 カーソルを左へ
^L [RIGHT] : cursor_right #08 カーソルを右へ
# ^B \[LEFT] : cursor_tkprev #09 前のトークンへ
# ^W \[RIGHT] : cursor_tknext #10 次のトークンへ
^QS [HOME] ^[LEFT]: cursor_sleft #11 カーソルを行頭へ
^QD [END] ^[RIGHT]: cursor_sright #12 カーソルを行末へ

^U \[PGUP] : cursor_rup #31 ロールアップ
^D \[PGDN] : cursor_rdown #32 ロールダウン
^B [PGUP] \[UP] : cursor_pup #35 ページアップ
^F [PGDN] \[DOWN] : cursor_pdown #36 ページダウン
^QE ^[UP] : cursor_sup #39 カーソルを画面の一番上へ
^QX ^[DOWN] : cursor_sdown #40 カーソルを画面の一番下へ
^QR ^[PGUP] : cursor_top #41 カーソルをファイルの先頭へ
^QC ^[PGDN] : cursor_bottom #42 カーソルをファイルの末尾へ


^QP : jump_before #43 直前のカーソル位置
^QM : jump_mark #44 カーソル行マーク
^QJ : Jump_line #45 指定行ジャンプ

^K1 : jump_Mark 1 #M16 マーク #1~#4
^K2 : jump_Mark 2 #
^K3 : jump_Mark 3 #
^K4 : jump_Mark 4 #

^Q1 : Jump_before 1 #M17 マークジャンプ #1~#4
^Q2 : jump_before 2 #
^Q3 : Jump_before 3 #
^Q4 : Jump_before 4 #

^QG \[F10] : jump_tag #M18 タブジャンプ



[CR] : line_cr #04 改行

^Z : char_undo #20 削除文字のアンドゥ
^K : char_input #22 制御文字の入力

\[CR] : line_new #53 新しい行の挿入
^QL \[F02]U : line_undo #54 行編集の取消。


# ^H [BS] : del_bs #14 カーソル前の文字を削除
# ^G [DEL] : del_char #15 カーソル上の文字を削除
# ^QH \[BS] : del_tkprev #16 語の先頭まで削除
# ^T \[DEL] : del_tknext #17 語の終りまで削除
# ^QT ^[BS] : del_sleft #18 行頭まで削除
# ^QY ^[DEL] : del_sright #19 行末まで削除


^Y [F10] : block_start #46 ブロックモード
^X [F08] : block_cut #47 ブロックへ移動
# ^I [F09] : block_paste #48 ブロックから移動
^C \[F08] : block_yanc #49 ブロックへ複写
^V \[F09] : block_copy #50 ブロックから複写
^KY \[F02]C : block_kill #51 ブロックバッファの消去
^QB \[F02]B : block_chlast #52 ブロックのtop/end

^KD : block_dup #M19 カーソル行複写


^@ \[INS] : search_paging #30 ページングモード

^QF [F06] : search_in #55 検索文字列の入力
^QA [F07] : search_repl #56 文字列の置換
^QO : search_repl_redo #57 前回の置換の実行

^L [F05] : search_getword #M24検索文字列の連続取得



^_ ^\ : misc_kmacro #02 キーボードマクロ
^V [INS] : opt_set "OverWrite" #13 入力モードon/off
[ESC]E : misc_exec #78 シェルコマンドの実行
[ESC]G : misc_insert_output # コマンドの実行結果の取り込み

[F01] : menu_file #M2 ファイルメニュー
[F04] \[F01] : menu_opt #
^KI : opt_tab #M15 タブの切替え

[ESC]D : misc_redraw #

2008年1月10日木曜日

PC⇔Linux をtclの ftpd(tcllib)で繋ぐ

普段、仕事ではWindowsからtelnetでlinux接続がメイン。
だけどやはりWindowsで文書は管理したいし、メールの添付ファイルは99%MS-Officeで書かれているから、Windows使わないと。
なにせ、telnet上ではscreen + mutt + fdclone + w3mでほとんど全てのことをやっているから、Windows不要的感覚に囚われてしまう。
で、 telnet先のlinux上でmutt使ってメール読んでると、「付いて来た添付ファイルが開けん」ので、Windows上で改めてメールボックス 開いて、pdfとか表示させるはめになる。これもなんかバカらしいというか、マウス使うのが億劫というか、なんとも「全部linux上で」と世間でよくあ るlinuxかっこいい・症候群に瞬間、ハマルわけ。
「な~んか良い方法はないものか」と、さらに深くlinux症候群へ

これま で何度となく、PCとlinux間をftpで繋ぐ方法を考えたような。良い方法はなかなか無いものです。かつてftpmount(だったかな)って のを見たとき「good idea!」、そう感じたのを思い出します。結局安定感がないやら、日本語無視だったりで使い物にならなかった。

だけど今でも諦めていません・・というわけで。PC⇔linux結合をば、また考えています。

[方針]

①PC上でftpdを走らせる
②telnet先のlinuxでftpクライアントを使う

ま あ当たり前の状況ですが、①のPC上のftpサーバでは、転送されてきたファイルをWindows上で実行してしまうという細工をすると良いことがある と考えます。通常のftpサーバは転送されてきたファイルを所望の場所へ保存する機能を持ちますが、実行出来そうなファイルは開いて欲しいと。

linux上のftpクライアントがhoge.pdfをputしてきたら、.pdfに関連図けられた実行コマンドを探し出して、(ここではAcrobat)それを実行してPC画面に表示するということ。

簡単に実現したい。
①TCLのTCLLIBにあるftpdとftpパッケージをいじって使用します。
②PCではActiveStateのTCLをインストール
③linuxではtcllib.sourceforge.netからtcllibをインストール

tclilib のftpdサーバ/ftpクライアント・サンプルスクリプトを多少改造したのが下記2つのスクリプトになります。PC上のftpdサーバ側 スクリプトをActiveTCLのwish.exeに食わせると、例では7777ポートが接続可能になります。telnet先からはftpクライアントプ ログラムへ表示したいファイルを指定してあげると、WindowsPC上の適切なプログラム(Exce,WordやAcrobatなどなど)が立ち上がり ftp転送されてきたファイルを表示します。後はWindowsPC上での作業の世界ですね。

[①PC側のftpdサーバスクリプト]

#! /bin/sh
# -*- tcl -*- \
exec wish "$0" ${1+"$@"}
# Custom FTP daemon to talk WindowsPC and Linux.

package require Tcl 8.3
package require ftpd
package require log

variable docRoot {c://Tcl/tmp}
variable store_path {}

proc ftplog {level text} {
if {[string equal $level note]} {set level notice}
log::log $level $text
}
proc noauth {args} {
return 1
}
proc fakefs {cmd path args} {
# Use the standard unix fs, i.e. "::ftpd::fsFile::fs",
# but rewrite the incoming path
# to stay in the /tmp directory.

variable docRoot
set path [file join $docRoot [file tail $path]]
variable store_path $path
eval [linsert $args 0 ::ftpd::fsFile::fs $cmd $path]
}
proc exapp {s s2 f b name e} {
variable store_path
if {$store_path!={}} {
regsub -all -- {/} $store_path {\\} store_path
.name configure -text "Filename:$store_path"
} else {
.name configure -text "Filename:nothing"
}
if {$store_path!={} && [set app [get_appli $store_path]]!={}} {
.ftype configure -text "HelperApplication:$app"
if {[regexp {(exefile|batfile)} $app]} {
exec $store_path
} else {
exec $app $store_path
}
} else {
.ftype configure -text "HelperApplication:unknown"
}
set store_path {}
return 1
}
proc get_appli {path} {
set type {}
if {[set extension [file extension [file tail $path]]]!={}} {
if {[regexp {\S+=(.+)} [exec cmd /C assoc $extension] all assoc]} {
.assoc configure -text " Assoc-Command:$assoc"
if {[regexp {exefile} $assoc]} {return $assoc}
if {[regexp {batfile} $assoc]} {return $assoc}
if {[regexp {\S+=(.+)} [exec cmd /C ftype $assoc] all ftype]} {
regsub -all {\"} $ftype {} type
regsub -all {\\} $type {/} type
regexp -nocase -- {(^.*.exe)} $type all type
}
}
}
return $type
}

::ftpd::config -authUsrCmd noauth -authFileCmd noauth -fsCmd fakefs -logCmd ftplog -xferDoneCmd exapp
set ::ftpd::welcome {Welcome HOMEPC FTPd}
set ::ftpd::port 7777 ; # Listen on user port
set ::ftpd::cwd $docRoot

::ftpd::server

button .b -command "exit" -text {<>}
label .name -text " Filename:nothing"
label .assoc -text " Assoc-Command:nothing"
label .ftype -text " HelperApplication:unknown"
pack .b .name .assoc .ftype -side top
wm iconify .
wm title . "PC<=>Linux"

[②linux側のftpクライアントスクリプト]

#!/usr/bin/tclsh
package require ftp

# SAMPLE convmv : proc euc-jp2sjis {euc} { return [set sjis [lindex [exec convmv -f euc-jp -t shiftjis $euc |& grep mv] end]] }
proc euc-jp2sjis {euc} { return [exec echo $euc | nkf -s] }
proc latest_file {dir} {
set latest {}
if {[catch {set files [glob ${dir}/*]}]} {puts "Directory empty :$dir";return {}}
foreach f [set files $files] { if {[file isfile $f]} {set mtime([file mtime $f]) $f }}
return [set latest $mtime([lindex [lsort -decreasing -integer [array names mtime]] 0])]
}

if {[llength $argv]>0} {
set ip $env(REMOTEHOST)
set port 7777
while {[regexp -- {(-port\s+(\d+)|-ip\s+(\d+[\d\.]+))} $argv a 1]} {
regsub -- ${a} $argv {} argv
set argv [string trim $argv]
}
set path [join $argv]
if {[file isdirectory $path]} {
if {[set path [latest_file $path]]=={}} { exit 0 }
}
if {[file isfile $path]} {
set euc_path $path
set sjis_path [euc-jp2sjis $euc_path]
puts "ip=$ip port=$port path=$euc_path"
if {$euc_path != $sjis_path} {
file rename $euc_path $sjis_path
}
set path $sjis_path
} else {
set start_bat /tmp/start.bat
puts "creating $start_bat about $path"
set sb [open $start_bat w]
puts $sb "@echo off"
puts $sb "start $path"
close $sb
set path $start_bat
}
if {[set srv [::ftp::Open $ip no no -port $port]]>=0} {
::ftp::Put $srv $path
::ftp::Close $srv
} else {
puts "FTPservice unavailable"
}
if {[info exists euc_path] && $euc_path != $sjis_path} {
file rename $sjis_path $euc_path
} else {
file delete $start_bat
}
exit 1
}