ftpのMDTMの挙動に関する話だったのか。

少し前からlftpのmirrorがうまく動かない原因を探していた
前に調べてあたりを付けたのが「サイズが同じだとアップロードしない」という問題。
オプションのせいかな、と思って-nとか--ignore-sizeを試してみたが、結局のところこれではなかったらしい。

-nはともかく、--ignore-sizeというのは「更新されたかどうかを調べるのにsizeを判断材料に使わない」ということなので、これではsizeが同じだろうと違おうとダメらしい。同様に--ignore-timeも。これなんか、timeが違ってもsizeが同じなら動作しないわけだから、今回の解決には至らなかった。

対象となるファイルをいろいろtouchして頑張ってみると、ファイルを9時間未来にすると更新されたと判定されることが判明。ということは、ローカルのファイルの時間判定を間違っているか、リモートのファイルの時間判定を間違っているかのどちらか、という線が強い。

manpageを見ると、ftp:timezoneという設定があることが判明、しかもこれ、デフォルトはGMTだった。ここを-9とかjstとかJSTとか(勢い余って)+9とかしても、lsによる結果は変わらないが、cls -lによる結果は変わることがわかった。これをなんとかいじればmirrorでなんとかなるか?と思ったが結局ダメだった。やるに事欠いて+18とか-18とかやってみたけどまったくうまく動かない。

じゃああれか?まさかローカルのファイルの時刻判定を間違っているのか?とソースを眺めて時刻判定を探す。c++なんてまともにいじらないから追っかけるのが大変だったよ、と思いつつ結局ただstatでmtimeのエポック秒を取り出していることだけが判明。まあ普通はそうするよね。

エポック秒ということは基本的にはGMTで比較しているわけだ*1。やっぱりリモートか。ということでリモートのファイル一覧を取るあたりをいろんな方向から眺めることに。とはいうものの変な動きをしているところは見つからない。

いまいちどgoogleでlftp,timezone,mirrorあたりのキーワードを使って探すが日本語のサイトにはそれらしい情報がない。まあ探しているうちにlftpでコマンドを実行する際の-eと-cの違いなんかがわかってそれは興味深かったけど*2

英語で探すと出てくるのがこのMLアーカイブ。うーん?「MDTMを使うとファイルの最終更新日時がGMTで返ってくるよ」って書かれているのが気になる。そういえばさっきこの辺のFTP接続に関する説明とかこの辺のPASVモードに関する説明を見てつないでみたときに、MDTMコマンド試してみたんだが、なんかJSTで結果が返ってきてなかったか?

MDTM,GMT,localtimeとかあたりの検索キーワードでgoogle検索すると、どうもこの辺の動作はGMTが基本だけど、localtimeな実装もあり得ない話ではないらしい。ということはもしかしてlftpはMDTM実装をGMT決めうちでやってるのかな?と思ってftpclass.ccを見たらその中のConvertFtpDateの中で案の定UTC決めうちで変換やってることがわかった。まあこれはこれで正しいんだろうな。

ということで、MDTMを使わない設定(set ftp:use-mdtm no)にして、さらにtimezoneを-9にする形(set ftp:timezone -9)で*3、設定したら普通に動いた。

結局ここまで見ないといけないとなると、perlあたりでNet::Ftpとか使って自作しちゃった方が早いかもしれないよなあ。出来合いだとこういうときに疲れる。

*1:実際のGMTとは確か閏秒の関係でずれてるんだよね?違ったっけ?まあいいや、そこは今回の話とは違う

*2:-eはquitを実行する必要があり、-cはquitを実行しなくてもコマンドの最後でquitする

*3:なんでだかわからないが、jstとかJSTとかだとうまく動かない。まあ何か設定の仕方がまずいんだろうな