wakatonoの戯れメモ

はてなダイアリーから引っ越してきました。

久々のQuick Hack公開

IRCサーバソフトウェアのQuick Hackです.
ネタはngircdのirc.c.

  • 何故作ったか?

ローカルで使うIRCサーバ上を流れるメッセージをもれなく取得してみたかった(含むPriv).

  • 使い方
    • 後ろのほうで示した変更を,ngircdのirc.cに対して適用したあと,Makefile中のCFLAGSに -DS_SPLINT_S を追加指定の上コンパイル
    • 標準出力にPRIVMSGコマンドで処理される情報やクライアントの情報等がだらだら出力されるので,それをリダイレクトなりなんなりして記録する.

動作確認は,Ubuntu 14.04 LTS 上で行ってます(ngircdも,Ubuntu 14.04 で入るもののソースパッケージを持ってきて改造してます).

…write(1, buf, buflen)みたいな感じで書いてますが,これは「ファイル記述子1に対し,bufに入ってるアドレスからbuflenバイトだけ書き込みを行う」という意味です.本来は


fd = open()
write(fd, buf, buflen)

みたいに,ファイルを(既存のものを使うなり新規作成するなりして)openの上,open時に得られたファイル記述子を使うのは,単純にわざわざファイルを作成してとかいうのをアプリケーション内で書きたくなかったから.とりあえずこうしておけば,書き出すことはできます.

  • ハマったところ

S_SPLINT_Sが定義されていないと,CLIENT構造体がvoid *になるため,何の情報も得られないということに気がつくのに20分くらいかかったところ.

まぁ,久々にQuick Hackするとこんなもんです.


/**
* Handler for the IRC "PRIVMSG" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_PRIVMSG(CLIENT *Client, REQUEST *Req)
{
// wakatono
int args;
int rc;
char time_sec[20];
char time_usec[20];

struct timeval temptime;
struct timezone temptz;
rc = gettimeofday(&temptime, &temptz);
if(rc == 0)
{
sprintf(time_sec, "%d", temptime.tv_sec);
sprintf(time_usec, "%d", temptime.tv_usec);
write(1, "success", 7);
write(1, " ", 2);
}
write(1, time_sec, strlen(time_sec));
write(1, ".", 1);
write(1, time_usec, strlen(time_usec));
write(1, " ", 2);
write(1, Client->id, strlen(Client->id));
write(1, " ", 2);
write(1, Client->user, strlen(Client->user));
write(1, " ", 2);
write(1, Client->info, strlen(Client->info));
write(1, " ", 2);
write(1, Client->host, strlen(Client->host));
write(1, " ", 2);
for(args = 0; args < Req->argc; args ++)
{
write(1, Req->argv[args], strlen(Req->argv[args]));
write(1, " ", 2);
}
write(1, "\n", 1);
return Send_Message(Client, Req, CLIENT_USER, true);
} /* IRC_PRIVMSG */