2009年12月20日日曜日

Makefile

小さいコードを書くときによく使うMakefileです。

カレントディレクトリーにある*.cファイルを全部コンパイル。"make print"でファイルの行数を出力。CFLAGSとLDFLAGSは用途により適当に修正します。下のコードはlibcurlを使うコードをmakeするときのものです。
PROGS = $(basename $(wildcard *.c))

CC = gcc
CFLAGS = -Wall -O2 `curl-config --cflags`
LDFLAGS = `curl-config --libs`

all: $(PROGS)

print:
wc -l *.c

clean:
$(RM) $(PROGS)


環境

OS: Linux
debian-lenny
make-3.81
 

2009年12月3日木曜日

(Code: sh) gtrans2

Google Translate を利用して露英翻訳するシェルスクリプトです。以前書いたコードを改良。
#!/bin/sh

PROG=`basename $0`

## check cmd
LIST="curl urie"
for CMD in $LIST ;do
TEST_CMD=`which $CMD`
if [ -z "$TEST_CMD" ] ; then
echo "$PROG: Error: we need command \"$CMD\"" >&2
exit 1
fi
done

## check arg
if [ -z "$1" ] ; then
echo "$PROG: Error: need an arg (Russian phrase)" >&2
exit 1
elif [ $# -gt 1 ] ; then
echo "$PROG: Error: too many args. need just an arg (Russian phrase)" >&2
exit 1
fi
TEXT="$1"


## body
UA='Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)'
URL=http://translate.google.com/translate_a/t
TEXT_URIE=`echo "$TEXT" | urie`

RESULT=`curl -Ss -m 10 -G -A "$UA" "$URL" -d client=t -d text="$TEXT_URIE" -d sl=ru -d tl=en`
TEST_CURL=$?
#echo "$RESULT" ##debug
if [ $TEST_CURL -ne 0 ] ; then
echo "$PROG: Error: curl failed" >&2
exit 1
fi

TEST_RESULT=`echo "$RESULT" | grep '"trans"'`
if [ -n "$TEST_RESULT" ] ; then ## for empty translation result {"src":"en"}
echo "$RESULT" | sed 's/.*"trans":"\([^"]*\)".*/\1/'
fi

  • urieで翻訳したいフレーズをURIエンコード

  • curlで翻訳したいフレーズをGETで送信

  • sedで結果をパース

UserAgentがcurlだと拒絶される、空だと翻訳結果がKOI8-Rで返ってきてUTF-8の環境でパースしづらくなるのでIEに偽装しています。UAがIEやFirefoxだとUTF-8で結果が返ってくるみたい。以前書いたコードと異なり"http://translate.google.com/"でなく"http://translate.google.com/translate_a/t"に翻訳したいフレーズを送信しています。
{"sentences":[{"trans":"short","orig":"короткий","translit":""}],"dict":[{"pos":"","terms":["s"]},{"pos":"adjective","terms":["short","brief","little","small","short","skimpy"]}],"src":"ru"}
こんな感じの翻訳結果をGoogleから受信できます。"http://translate.google.com/"のものより短い!パースし易い!!URIエンコーディングにCで書いたコマンド(urie)を使っています。GETで送信(curl -G)するとPOSTするより送信データーが69バイト短くて済むのでそうしてます。


テスト翻訳
$ ./gtrans 'здравств'
hello

$ ./gtrans 'я из Японии'
I'm from Japan

$ ./gtrans 'только хорошие умирают молодыми'
only the good die young

$ ./gtrans 'through ascii phrase'
through ascii phrase

$ ./gtrans ' '
(出力なし)

$ ./gtrans '誤って日本語を入力'
誤っ て 日本語 を 入力

$ ./gtrans `echo "えすじす" | iconv -t SJIS-WIN`
????????
まずまず動作。LANG=ja_JP.UTF-8のシェルでテスト翻訳しました。
文字コードが混在した環境で自動翻訳しようとすると翻訳フレーズごとに文字コードの自動判定も必要になりそう。ロシア版ポトリスではロシア語にCP1251、日本語にSJIS-WINが使われてるみたい。


環境

OS: Linux
debian-lenny
 

(Code: c) urie

URIエンコーディングを意図したコードです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BLOCK 1024*8


int main(int argc, char *argv[])
{
int n;
char buf[BLOCK + 1];
unsigned char *str = NULL;
int size_str = 0;

/* read stdin */
while (1) {
n = fread(buf ,1 , BLOCK, stdin);
if (n == 0) {
str = realloc(str, size_str + 1);
break;
} else if (n < 0) {
perror("fread");
return -1;
}
str = realloc(str, size_str + n);
memcpy(str + size_str, buf, n);
size_str += n;
}
*(str + size_str) = '\0';

/* uri encoding */
while (*str) {
printf("%%%02X", *str);
str++;
}

return 0;
}
実用には問題ないけどアスキーな文字までエンコードしてしまう。GLibのg_uri_escape_stringとか使えば、その辺キッチリできそう。
RFC読まなきゃ…と思って単純に"Uniform Resource Identifier"で検索したら20文献多すぎ挫折しました。


URIエンコーディング関連? RFC

2079 Definition of an X.500 Attribute Type and an Object Class to Hold
Uniform Resource Identifiers (URIs). M. Smith. January 1997. (Format:
TXT=8757 bytes) (Status: PROPOSED STANDARD)

2168 Resolution of Uniform Resource Identifiers using the Domain Name
System. R. Daniel, M. Mealling. June 1997. (Format: TXT=46528 bytes)
(Obsoleted by RFC3401, RFC3402, RFC3403, RFC3404) (Updated by
RFC2915) (Status: EXPERIMENTAL)

2396 Uniform Resource Identifiers (URI): Generic Syntax. T.
Berners-Lee, R. Fielding, L. Masinter. August 1998. (Format:
TXT=83639 bytes) (Obsoleted by RFC3986) (Updates RFC1808, RFC1738)
(Updated by RFC2732) (Status: DRAFT STANDARD)

2838 Uniform Resource Identifiers for Television Broadcasts. D.
Zigmond, M. Vickers. May 2000. (Format: TXT=11405 bytes) (Status:
INFORMATIONAL)

3305 Report from the Joint W3C/IETF URI Planning Interest Group:
Uniform Resource Identifiers (URIs), URLs, and Uniform Resource Names
(URNs): Clarifications and Recommendations. M. Mealling, Ed., R.
Denenberg, Ed.. August 2002. (Format: TXT=21793 bytes) (Status:
INFORMATIONAL)

3404 Dynamic Delegation Discovery System (DDDS) Part Four: The Uniform
Resource Identifiers (URI). M. Mealling. October 2002. (Format:
TXT=40124 bytes) (Obsoletes RFC2915, RFC2168) (Status: PROPOSED
STANDARD)

3617 Uniform Resource Identifier (URI) Scheme and Applicability
Statement for the Trivial File Transfer Protocol (TFTP). E. Lear.
October 2003. (Format: TXT=11848 bytes) (Status: INFORMATIONAL)

3761 The E.164 to Uniform Resource Identifiers (URI) Dynamic
Delegation Discovery System (DDDS) Application (ENUM). P. Faltstrom,
M. Mealling. April 2004. (Format: TXT=41559 bytes) (Obsoletes
RFC2916) (Status: PROPOSED STANDARD)

3969 The Internet Assigned Number Authority (IANA) Uniform Resource
Identifier (URI) Parameter Registry for the Session Initiation
Protocol (SIP). G. Camarillo. December 2004. (Format: TXT=12119
bytes) (Updates RFC3427) (Also BCP0099) (Status: BEST CURRENT
PRACTICE)

3986 Uniform Resource Identifier (URI): Generic Syntax. T.
Berners-Lee, R. Fielding, L. Masinter. January 2005. (Format:
TXT=141811 bytes) (Obsoletes RFC2732, RFC2396, RFC1808) (Updates
RFC1738) (Also STD0066) (Status: STANDARD)

4051 Additional XML Security Uniform Resource Identifiers (URIs). D.
Eastlake 3rd. April 2005. (Format: TXT=33368 bytes) (Status: PROPOSED
STANDARD)

4088 Uniform Resource Identifier (URI) Scheme for the Simple Network
Management Protocol (SNMP). D. Black, K. McCloghrie, J.
Schoenwaelder. June 2005. (Format: TXT=43019 bytes) (Status: PROPOSED
STANDARD)

4501 Domain Name System Uniform Resource Identifiers. S. Josefsson.
May 2006. (Format: TXT=20990 bytes) (Status: PROPOSED STANDARD)

4622 Internationalized Resource Identifiers (IRIs) and Uniform
Resource Identifiers (URIs) for the Extensible Messaging and Presence
Protocol (XMPP). P. Saint-Andre. July 2006. (Format: TXT=49968 bytes)
(Obsoleted by RFC5122) (Status: PROPOSED STANDARD)

4904 Representing Trunk Groups in tel/sip Uniform Resource Identifiers
(URIs). V. Gurbani, C. Jennings. June 2007. (Format: TXT=41027 bytes)
(Status: PROPOSED STANDARD)

4967 Dial String Parameter for the Session Initiation Protocol Uniform
Resource Identifier. B. Rosen. July 2007. (Format: TXT=12659 bytes)
(Status: PROPOSED STANDARD)

5017 MIB Textual Conventions for Uniform Resource Identifiers (URIs).
D. McWalter, Ed.. September 2007. (Format: TXT=14826 bytes) (Status:
PROPOSED STANDARD)

5122 Internationalized Resource Identifiers (IRIs) and Uniform
Resource Identifiers (URIs) for the Extensible Messaging and Presence
Protocol (XMPP). P. Saint-Andre. February 2008. (Format: TXT=55566
bytes) (Obsoletes RFC4622) (Status: PROPOSED STANDARD)

5341 The Internet Assigned Number Authority (IANA) tel Uniform
Resource Identifier (URI) Parameter Registry. C. Jennings, V.
Gurbani. September 2008. (Format: TXT=13944 bytes) (Updates RFC3966)
(Status: PROPOSED STANDARD)

5527 Combined User and Infrastructure ENUM in the e164.arpa Tree. M.
Haberler, O. Lendl, R. Stastny. May 2009. (Format: TXT=20733 bytes)
(Status: INFORMATIONAL)


環境

OS: Linux
debian-lenny
 

2009年12月1日火曜日

(Code: sh) gtrans

Google Translate を利用して露英翻訳するシェルスクリプトです。
#!/bin/sh

if [ -z "$1" ] ; then
  echo "Error: need an arg (Russian phrase)" >&2
  exit 1
elif [ $# -gt 1 ] ; then
  echo "Error: too many args. need just an arg (Russian phrase)" >&2
  exit 1
fi
TEXT="$1"

UA='Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)'
curl -Ss -m 10 -A "$UA" http://translate.google.com/ -d js=n -d prev=_t -d hl=en -d ie=UTF-8 -d text="$TEXT" -d file= -d sl=ru -d tl=en | awk 'NR == 8' | sed 's/.*<span id=result_box class="short_text"><[^>]\+>\([^/]\+\)<\/.*/\1/' | xmlstarlet unesc

  • curlで翻訳したいフレーズをPOST

  • awkとsedで結果をパース

  • xmlstarletで文字参照("&#39;"みたいなの)を解除

UserAgentがcurlだと拒絶される、空だと翻訳結果がKOI8-Rで返ってきてUTF-8の環境でパースしづらくなるのでIEに偽装しています。UAがIEやFirefoxだとUTF-8で結果が返ってくるみたい。


テスト翻訳
$ ./gtrans 'здравств'
hello

$ ./gtrans 'я из Японии'
I'm from Japan

$ ./gtrans 'только хорошие умирают молодыми'
only the good die young

$ ./gtrans
Error: need an arg (Russian phrase)

$ ./gtrans a b
Error: too many args. need just an arg (Russian phrase)
まずまず動いた!LANG=ja_JP.UTF-8のシェルでテスト翻訳しました。
ロシア版ポトリスのチャット自動翻訳に向け、ググル先生翻訳へPOSTするデーターの確認用に書いてみました。


環境

OS: Linux
debian-lenny
 

2009年11月30日月曜日

(Code: c) ChatLoggerのテスト

ロシア語のロギング結果。
22:54:57   [A****       ] зачем нам а*****
22:55:12   [К******    ] )
22:55:12   [W*****      ] он учит русский
22:55:19   [К******    ] молодец ))
22:55:57   [d********** ] )
22:56:05   [Д********  ] член.забыл ф4
22:56:31   [Д********  ] кышь
22:56:33   [К******    ] )))
22:56:35   [d********** ] гут
22:56:39   [W*****      ] ух
22:56:46   [h******     ] на нах
22:56:46   [К******    ] в попу)
22:56:47   [d********** ] ах ты
22:56:49   [a*****      ] только хорошие умирают молодыми
22:57:11   [К******    ] член )
22:57:16   [К******    ] да ты промохнёшся)
22:57:18   [h******     ] а***** заговорил по русски
22:57:20   [К******    ] член же()
22:57:22   [d********** ] бля
22:57:34   [К******    ] ))))воть и сё
22:57:39   [К******    ] хус меня не убй)
22:57:41   [d********** ] неа
22:57:42   [a*****      ] я японский
22:57:47   [a*****      ] я знаю только несколько слов
22:57:55   [h******     ] молодец
22:57:57   [a*****      ] прив!
22:57:59   [К******    ] хуй знаеш)?
22:58:04   [К******    ]  этоже японское слово)
22:58:07   [d********** ] бляяя
22:58:17   [К******    ] ))точно бля
22:58:22   [К******    ] ())))
22:58:28   [К******    ] чекист прям)
22:58:37   [d********** ] ты бы еще дуп добавил
22:59:31   [Д********  ] a***** как дела?
22:59:35   [h******     ] хуево
23:00:04   [a*****      ] извините, я знаю только несколько слов...
23:00:08   [Д********  ] )
23:00:14   [К******    ] хус а де военкомат находится?
23:00:21   [h******     ] на пабери 3
23:00:27   [К******    ] ужс)
23:01:45   [h******     ] =Р


 

2009年11月29日日曜日

ロシア版ポトリスのDLが遅い原因

ゲームクライアントのダウンロードが遅いのはDNSラウンドロビン経由で応答のないサーバーにアクセスしてしまっているためだと分かりました。その調査レビューです。

結論から書くとこちらですぐにダウンロードできる! ※できなくなってるかもしれません


ことの発端

公式からダウンロードしようとすると異常に遅い!公式自体も落ちていることがあるみたい。

ダウンロードリンク -- ロシア版ポトリス公式
http://files.fortress2.ru/fotress2_v1.0.1_installer.exe

普通にゲームクライアントをダウンロードできるときもあるのですがリンクをクリックしてからダウンロードが始まるまで30分待たされたり、"Bad Request (Invalid Hostname)"と表示されたり挙動がまちまち…近くて遠い国、ロシアだからかなぁ?などと漠然と考えていたのですがもう少し具体的に調べてみました。


7IPへのDNSラウンドロビン

files.fortress2.ruのDNSレコードを取得してみる。
$ dig files.fortress2.ru
...
;; ANSWER SECTION:
files.fortress2.ru. 30804 IN A 92.241.170.96
files.fortress2.ru. 30804 IN A 92.241.170.101
files.fortress2.ru. 30804 IN A 92.241.170.104
files.fortress2.ru. 30804 IN A 81.177.139.5
files.fortress2.ru. 30804 IN A 81.177.139.22
files.fortress2.ru. 30804 IN A 81.177.139.23
files.fortress2.ru. 30804 IN A 92.241.170.90
...
7つのIPアドレスにDNSラウンドロビンされてることが分かった!負荷分散のためでしょうか。


正常なホストは1つだけ

この7つのIPアドレスのホストが正常にWEBサーバーとして動作してるか調べてみる。
$ nmap -PN -p T:80 92.241.170.96 92.241.170.101 92.241.170.104 81.177.139.5 81.177.139.22 81.177.139.23 92.241.170.90

Starting Nmap 5.00 ( http://nmap.org ) at 2009-11-29 22:24 JST
Interesting ports on 92.241.170.96:
PORT STATE SERVICE
80/tcp filtered http

Interesting ports on 92.241.170.101:
PORT STATE SERVICE
80/tcp filtered http

Interesting ports on 92.241.170.104:
PORT STATE SERVICE
80/tcp filtered http

Interesting ports on 81.177.139.5:
PORT STATE SERVICE
80/tcp open http

Interesting ports on 81.177.139.22:
PORT STATE SERVICE
80/tcp open http

Interesting ports on 81.177.139.23:
PORT STATE SERVICE
80/tcp filtered http

Interesting ports on 92.241.170.90:
PORT STATE SERVICE
80/tcp filtered http

Nmap done: 7 IP addresses (7 hosts up) scanned in 3.11 seconds
TCP80番ポートがopenなホスト=正常にWEBサーバーとして動作してるホストは、7つのうち2つ、81.177.139.5と81.177.139.22だけ!しかも、後者は"Bad Request (Invalid Hostname)"が返ってきてゲームクラアントのダウンロードができない状態でした。

つまり、正常なホストは1つだけでした。


まとめ

ホスト名"files.fortress2.ru"は7つのIPアドレスにDNSラウンドロビンされているが、そのうち1つのIPアドレス(81.177.139.5)のホストだけしか正常に動作してない、ということのようです。正常に動作してないホストのIPアドレスがWEBブラウザーにキャッシュされて困ってたみたい。

早い話が下のURLからならゲームクライアントのダウンロードがすぐに始まる。
※ダウンロードできなくなっているかもしれません

http://81.177.139.5/fotress2_v1.0.1_installer.exe

4game.ruの管理人さん、対応してくれ!…とロシア語でお願いできれば良いのだけれど。以前、別件でinfo@4game.ruに問い合わメールを送ったんですがリジェクトされました(gmailから送った)。文面は英語で書いたのだけどスパム扱いされたのだろうか…ロシアとロシア語に明るい方いらっしゃれば、ぜひ公式に問い合わせてみて頂けないでしょうか。


参考リンク

チープなDNSラウンドロビンは高価なロードバランサの座を奪い返せるか -- CNET Japan
http://japan.cnet.com/blog/neta/2006/08/10/dns_ecfc/

記事の趣旨は本件と異なるのですが参考になりました。

DNSラウンドロビン -- ウィキペディア(日本)
http://ja.wikipedia.org/wiki/DNS%E3%83%A9%E3%82%A6%E3%83%B3%E3%83%89%E3%83%AD%E3%83%93%E3%83%B3

負荷分散に使われる技術らしい。でも色々と問題点もあるみたい。


環境

OS: Linux
debian-lenny
dig-9.5.1-P3
nmap-5.00 (公式ソースmake)


以下は以前に書いたポトリスに関する記事です。

ロシアでポトリス
ロシアでポトリス2
Wineでロシアでポトリス
 

2009年11月25日水曜日

秘密Cookieの削除

FirefoxのアドオンBetterPrivacyを入れて秘密Cookieを削除してみたレビューです。

ブラウザーのFlashプラグインが勝手に保存・送信してしまう秘密Cookieとやらがあるらしいです。件のアドオンで秘密Cookieの調査、ブロック・許可設定ができる!ありがとうBetterPrivacy開発者。


入れてみた



めっちゃいっぱいあるし!いつも使う動画サイトや企業、趣味、他サイトの秘密Cookieがかなり古いものまで残ってました…


BettrPrivacyのインストール後に見られるchrome://bp/content/bphelp.htmlによると、

Flashの秘密CookieはLSO(Local Shared Object)と呼ばれていて
  • 永続的にずっと残る
  • 普通のCookieより大容量である (普通4KB、秘密100KBで25倍)
  • システム、ユーザー名を保存してる
らしいです。怖い秘密Cookie怖い。"Remove All LSOs"でとりあえず全部削除しました。その後Firefoxを再起動、自分の環境では問題なく動作しています。
すごくみえない敵と戦っている気分…

2月程前にけっこうニュースになってたみたい。

「Flash cookie」によるトラッキングが密かに行われている -- スラッシュドット・ジャパン
http://slashdot.jp/security/09/08/16/0141237.shtml

ユーザーが制御できない「秘密cookie」、半数強のサイトが利用 -- ITmedia
http://www.itmedia.co.jp/news/articles/0908/13/news017.html


参考リンク

BetterPrivacy公式
http://netticat.ath.cx/extensions.html

BetterPrivacy -- addons.mozilla.org
https://addons.mozilla.org/ja/firefox/addon/6623


環境

OS: Linux
debian-lenny
firefox-3.5.5
BetterPrivacy-1.45