2010/03/27
mnews
随分と長い間 mnews というソフトウェアを愛用している。
名前の通り、元々は Net News Reader として開発されたのだが、
MUA としての機能も備わっていて割と使いやすいので、
随分と以前より(1990年代の中盤頃から)愛用している。
最近はあまりメンテナンスもされていない様なのだが、
たまにネットで公開されている機能拡張用のパッチを適用したり、
自分でも簡単な改造をしながら長年愛用してきた。
今ではオリジナルにはない mime マルチパートメイルの送受信機能なども加わり、
今時の MUA としては最低限の機能は備える程度には機能が充実している。
最近は UNICODE で送られてくるメイルも増えて来たので、
UNICODE メイルを表示するためのパッチを適用し、
ついでに html メイルを lynx などのテキストベイスのブラウザで
表示する機能を追加した。
これで現状必要と思われる機能はほぼ網羅したと思われ、
届くメイルのほぼ全てを閲覧する事が出来るようになった(多分)。
まだまだ mnews を愛用できそうで嬉しい限りだ。
2010/03/18
GtkTwitter
FreeBSD 上で動作する twitter クライアントの GtkTwitter は 起動するたびにアカウント情報を入力する必要があり面倒だったので、 アカウント情報をファイルに保存して再利用するためのパッチを作成してみた。
自分が使う事だけを考えて適当に作ったので、
パスワードの暗号化すらしておらず、
シンタックスもセマンティックスもチェックしていない。
ただ単にアカウント情報を保存して再利用するだけの機能のみ。
ホームディレクトリに .gtktwitter があれば
保存されたアカウント情報を利用する。
$HOME/.gtktwitter がなければ
従来通りアカウント情報の入力ダイアログを表示し、
入力されたアカウント情報は $HOME/.gtktwitter に保存される。
$HOME/.gtktwitter は以下の書式なので、
アカウント情報は vi (1) を利用して入力する事も可能である。
勿論 cat (1) や echo (1) でも可。
ファイル中のスペースは文字そのものとして解釈されるので注意する事。
mail=ID pass=パスワード
diff -rc gtktwitter-0.0.4.orig/gtktwitter.c gtktwitter-0.0.4/gtktwitter.c
*** gtktwitter-0.0.4.orig/gtktwitter.c 2007-05-10 00:50:02.000000000 +0900
--- gtktwitter-0.0.4/gtktwitter.c 2010-03-18 20:15:01.000000000 +0900
***************
*** 724,729 ****
--- 724,783 ----
return FALSE;
}
+ #define CONFIG_FILE ".gtktwitter"
+
+ static gboolean getconfig(GtkWidget *window)
+ {
+
+ gchar *config;
+ char buff[1024],
+ *m = NULL,
+ *p = NULL;
+ FILE *fp;
+ gboolean ret = FALSE;
+
+ if((config = g_strdup_printf("%s/%s", getenv("HOME"), CONFIG_FILE))){
+ if((fp = fopen(config, "r"))){
+ while(fgets(buff, sizeof(buff), fp))
+ if(!strncmp(buff, "mail=", 5))
+ m = strdup(buff+5);
+ else if(!strncmp(buff, "pass=", 5))
+ p = strdup(buff+5);
+ fclose(fp);
+ }
+ g_free(config);
+
+ if(m && p){
+ g_object_set_data(G_OBJECT(window), "mail", m);
+ g_object_set_data(G_OBJECT(window), "pass", p);
+ ret = TRUE;
+ }
+ }
+
+ return (ret);
+
+ }
+
+ static void putconfig(const char *m, const char *p)
+ {
+
+ gchar *config;
+ FILE *fp;
+
+ if((config = g_strdup_printf("%s/%s", getenv("HOME"), CONFIG_FILE))){
+ if((fp = fopen(config, "w"))){
+ fprintf(fp, "mail=%s\n", m);
+ fprintf(fp, "pass=%s\n", p);
+ fclose(fp);
+ }
+ g_free(config);
+
+ }
+
+ return;
+
+ }
+
/**
* login dialog func
*/
***************
*** 735,740 ****
--- 789,798 ----
GtkWidget* pass = NULL;
gboolean ret = FALSE;
+ if(getconfig(window)){
+ ret = TRUE;
+ }
+ else{
/* login dialog */
dialog = gtk_dialog_new();
gtk_dialog_add_buttons(GTK_DIALOG(dialog),
***************
*** 804,812 ****
--- 862,873 ----
char* pass_text = (char*)gtk_entry_get_text(GTK_ENTRY(pass));
g_object_set_data(G_OBJECT(window), "mail", strdup(mail_text));
g_object_set_data(G_OBJECT(window), "pass", strdup(pass_text));
+ putconfig(mail_text, pass_text);
ret = TRUE;
}
+ }
+ if(dialog)
gtk_widget_destroy(dialog);
return ret;
}
2010/02/10
ディスプレイカードの温度表示
ディスプレイカードの温度上昇が原因と思われる
表示不正が稀に発生するので、
ディスプレイカードの温度を取得して表示してみた。
取得した温度は普段利用しているデスクトップ環境で常時表示している
GKrellM (1)
のセンサー表示部分に多少無理やり表示してしまう事にする。
GKrellM (1) は mbmon (1) をデーモンとして起動しておくと
mbmon (1) から取得した3種類の温度を表示できるので、
mbmon (1) を改造して3番目の温度を
ディスプレイカードの温度に変更してしまうというのが
「多少無理やり」な方法だ。
ディスプレイカードに nVidia の GeForce を使用しているので、
温度は nvidia-settings (1) の
--query オプションを利用すると取得できる。
まずは mbmon (1) のソースを改造し
nvidia-settings (1) を popen (3) で呼び出してみると
確にディスプレイカードの温度は取得できるのだが、
温度取得のたびに nvidia-settings (1) コマンドが起動されるので
システムリソースに負荷がかかり過ぎてしまう。
そこで nvidia-settings (1) のソースに付属している
サンプルプログラムを調べてみると、
割と簡単にディスプレイカードの温度を取得できる事が判ったので
mbmon (1) から直接ディスプレイカードの温度を取得する。
まずは、必要となる NVCtrl.h、NVCtrlLib.h、
libXNVCtrl.a の3ファイルを準備するために、
nvidia-settings をコンパイルする。
ports/x11/nvidia-settings で make (1) を実行すると、
ports/x11/nvidia-settings/work/nvidia-settings-1.0/src/libXNVCtrl
に上記3ファイルが作成される。
次に mbmon (1) を修正してプログラムをインストールする。
ports/sysutils/mbmon ディレクトリで
make configure まで実行した後で以下のパッチを適用し、
上記3ファイルを prts/sysutils/mbmon/work/xmbmon205にコピーして
make (1)すると
ディスプレイカードの温度を取得できる mbmon (1) ができる。
この mbmon (1) をデーモンとして起動すると
GKrellM (1) のセンサー表示部分の
温度表示の 3番目にディスプレイカードの温度が表示できる。
diff -rcN xmbmon205.orig/Makefile xmbmon205/Makefile
*** xmbmon205.orig/Makefile 2010-02-10 15:42:38.000000000 +0900
--- xmbmon205/Makefile 2010-02-10 15:45:16.000000000 +0900
***************
*** 25,30 ****
--- 25,34 ----
LIBS= -lm
LIBSX=$(LIBS) -L/usr/X11R6/lib -lXt -lSM -lICE -lX11
+ INCLUDES+= -I. -I/usr/X11R6/include
+ LIBS+= -L. -lXNVCtrl -L/usr/X11R6/lib -lXext -lX11
+ DEFS+= -DNVHACK
+
#CC=/compat/linux/usr/bin/gcc
CC=cc
CFLAGS+=$(INCLUDES) $(DEFS)
diff -rcN xmbmon205.orig/mbmon.c xmbmon205/mbmon.c
*** xmbmon205.orig/mbmon.c 2010-02-10 15:31:52.000000000 +0900
--- xmbmon205/mbmon.c 2010-02-10 15:17:02.000000000 +0900
***************
*** 36,41 ****
--- 36,47 ----
# include <sys/sysctl.h>
#endif
+ #ifdef NVHACK
+ #include <X11/Xlib.h>
+ #include "NVCtrl.h"
+ #include "NVCtrlLib.h"
+ #endif
+
#include "mbmon.h"
static const char *MyName = "mbmon";
***************
*** 510,515 ****
--- 516,536 ----
getTemp(&temp1, &temp2, &temp3);
+ #ifdef NVHACK
+ {
+
+ Display *dpy;
+ int temp;
+
+ if((dpy = XOpenDisplay(NULL))){
+ if(XNVCTRLQueryAttribute(dpy, 0, 0, NV_CTRL_GPU_CORE_TEMPERATURE, &temp))
+ temp3 = temp;
+ XCloseDisplay(dpy);
+ }
+
+ }
+ #endif
+
/* get fan speeds */
getFanSp(&rot1, &rot2, &rot3);
2010/01/14
MyJVN チェッカーサービス
JVN - Japan Vulnerability Notes - が
セキュリティ設定チェッカ、バージョンチェッカのサービスを実施している。
これらのサービスは Microsoft Windows 専用のサービスなのだが、
Windows の機能である USB メモリ自動実行機能の設定の確認や、
インストールされている Adobe Reader や Flash Player などの
バージョンをチェックしてくれる。
最近は GENO/Gumblar と呼ばれているマルウェアなど
悪意のあるソフトウェアによる Web サイトの改ざんなどが話題になっているが、
そういった悪意のソフトウェアによる被害を防ぐための一つの足がかりとして
こういったツールも積極的に利用すると良いだろう。
2009/10/16
php からのディスクアクセス
php だという時点で既にアレなんだが…php からディレクトリにある全ファイルの一覧を取得する処理のパフォーマンスを exec()、popen()、opendir() を利用した処理で比較してみる。
方法は単純にテスト用のディレクトリに 500 ファイルを用意して、 それぞれの関数を使用してファイル名一覧を取得する処理を 10 回実行した場合の処理速度を計測する。
| exec("ls -1") | 0.774762 |
| popen("ls -1") | 0.865914 |
| opendir() | 0.136642 |
外部 shell を実行しないので opendir() が早いだろうとは予想していたが、
これほど差が出るとは思わなかった。
パフォーマンスを優先する場合は勿論だが、
余計なプロセスを生成しないので opendir() が地球に優しい様だ。
1<? 2 3 $func = array("byexec", "bypopen", "byopendir"); 4 5 for($i=0; $i<3; $i++){ 6 $dist = array(); 7 $start[$i] = gett(); 8 for($j=0; $j<100; $j++) 9 $dist[$j] = $func[$i]("/tmp/test"); 10 $end[$i] = gett(); 11 12 printf("%-10s:%f\n", $func[$i], $end[$i] - $start[$i]); 13 } 14 15 function byexec($dir) 16 { 17 18 exec("ls -1 $dir", $output); 19 20 return($output); 21 22 } 23 24 function bypopen($dir) 25 { 26 27 if(($fp = popen("ls -1 $dir", "r"))){ 28 while($buf = fgets($fp)) 29 $output[] = trim($buf); 30 pclose($fp); 31 32 } 33 34 return($output); 35 36 } 37 38 function byopendir($dir) 39 { 40 41 if($dir = dir($dir)){ 42 while($file = $dir->read()) 43 $outout[] = trim($file); 44 $dir->close(); 45 } 46 47 } 48 49 function gett() 50 { 51 52 $t = gettimeofday(); 53 return((float)($t['sec'] + $t['usec'] / 1000000.0)); 54 55 } 56 57?>
ついでにシェルの glob なパターン指定を利用して 指定した文字列にマッチするファイル名の一覧取得を行う場合のテストもしてみた。
20090219000 から 20090219499 までの500個のファイルの中から、 200902192?? にマッチするファイル名の一覧取得で時間を計測してみる。
| exec("ls -1 200902192??") | 0.883770 |
| popen("ls -1 200902192??") | 0.902392 |
| opendir()→preg_match("/200902192../") | 0.188792 |
| glob("/200902192../") | 0.203928 |
exec()、popen() が遅いのは相変わらずだが、
preg_match()の呼出しが意外に早かったのが驚き。
正規表現のマッチ処理って基本的に相当時間がかかる筈なんだが…
glob() はファイルシステムに自分でアクセスしてる様なので早い。
複雑なパターン指定が必要ならpreg_match()の方が柔軟だが、
シェルに渡せる程度のパターン指定なら glob() を利用するのが
可読性やメンテナンス性と性能が両立できて良いのかも?
2009/08/20
Namazu
Namazu はオープンソースの全文検索システムで、
メイリングリストの検索やサイト内検索用のツールとして
様々な Web Site で利用されている。
2004年12月に公表されたその Namazu のセキュリティ・ホールである
「Namazu におけるクロスサイト・スクリプティングの脆弱性」の
対策を適用していないサイトが
非常に多く見受けられるそうだ。
もう4年半も前の脆弱性を対策せずに放置しているのは、
今の世の中では単なるサイト管理の怠慢では済まされない問題だと思う。
なぜなら、これらの脆弱性が悪用された場合に
ユーザのブラウザ上で任意のスクリプトが実行されてしまう事で、
最悪な場合フィッシング詐欺などの踏み台に使われてしまう可能性があるから。
管理者はもっと責任をもってサイトの管理を行うべきじゃないのか?
2009/07/03
ファイルのオーバーライド
通常のパイプ動作するフィルタコマンドでは
元ファイルを直接オーバライドできない。
例えば sort (1) の -o オプションの様に
元ファイルのオーバライド指定ができる
(この動作をスポンジ動作というらしい)もの以外での処理について。
一番簡単で誰でも思いつくのが一時ファイルを利用するやりかた。
$ command < foo.dat > foo.new $ mv foo.new foo.datこの方法だと command の実行中に割込が発生したりすると 一時ファイルが残ってしまい美しくない。
$ cat foo.dat | ( sleep 1; command > foo.dat)この方法だと sleep (1) の時間がうっとおしく、 データ量や command の速度などによって失敗する場合もありうる。
$ (rm foo.dat; command > foo.dat) < foo.dat若干判りづらいのだがこれで確実に成功する。
先行する rm (1) は必須である。 rm (1) がない場合は外側のシェルが '<' により O_RDONLY で open (2) するファイルと 内側のシェルが '>' により O_RDONLY|O_TRUNC で open (2) するファイルの inode が等しいので OS は同一ファイルと見做し、 command の標準入力は O_TRUC により truncate されたファイルとなってしまう。
対して rm (1) がある場合は外側のシェルが O_RDONLY で open (2) するファイルと 内側のシェルが O_RDONLY|O_TRUNC で open (2) するファイルの inode が異なるので O_TRUNC による truncate は影響を受けない。
2009/06/18
SIGPIPE
1#!/bin/sh 2 : 3if ${any_command} | grep -q "${word}" 4then 5 :
linux 上で実行しているこの様なシェルスクリプトの ${any_commnand} がたまに異常終了している事がある。
気になって調べてみると SIGPIPE を受信してエラー終了している様だ。
grep (1) のマニュアルを調べてみると
Exit immediately with zero status if any match is found, even if an error was detected.
man grep
と明記してあるので grep (1) が先に終了してしまったので、 ${any_command} に SIGPIPE が送信されているらしい。
スクリプト中で grep -q は割と多用すると思うが、
こんな落とし穴もあるので気をつけなくては。
そもそも grep (1) なんてよく使うコマンドだから
かえってマニュアルを熟読しないだろうし、
だからこの様な BUG が潜む原因にもなっていると思う。
というか実は常識的な話だったりする?
2009/05/18
The myth of unix security
Kaspersky 社のブログ によると、 FreeBSD や Linux をターゲットとしたマルウェアが発見されたとの事です。
It’s often argued that *nix systems are secure, and there are’t any viruses or malware for such systems. This hasn’t been true for a long time, as two recently detected malicious programs prove.
Kaspersky 社の Blog より
超適当に翻訳してみると、 『多くの場合、unix システムはセキュリティを確保しているので、 ウィルスやマルウェアはありえないと主張されていた。 これらの事は既に真実ではない事が最近検出された2種類の悪意あるプログラム により証明されている。』 みたいな事が言われている。
今回は通常の perl スクリプトと FreeBSD や Linux 上で実行可能な 暗号化された perl スクリプトの 2 種類のマルウェアが発見されたらしく、 それぞれ迷惑メイルを送信する「ボット」や、 セキュリティソフト風の怪しいソフトウェアを販売するための 詐欺サイトを宣伝・販売するウェブサイトを構築してしまうらしい。
Windows に比較すれば FreeBSD や Linux の方が多少は安全ではあるが、
それはあくまでも相対的な比較においての安全であり
絶対的に安全という訳ではない。
そんな事はちょっと考えてみれば常識だろって位の事だと思うのだが、
一部では「Linux だから安全っ」みたいな事を妄信している人がいる様だ。
自分だけが被害に遭うだけならそれでも全然構わないのだが、
マルウェアに侵入を許してしまうと迷惑メイルの発信源になったり、
他のコンピュータへの攻撃の足掛かりになったりする事で、
他人にも迷惑を及ぼす危険性があるので是非とも心を改めて欲しい。
まぁ、人に迷惑をかけるなって事ですね。
コンピュータである以上「絶対に安全」なんてあり得ない事なので、
ちゃんとセキュリティ情報などには気を配り、
万全の対策をしなくてはならないのはもはや常識の範疇だと思う。
2009/04/09
POSIX.2 標準仕様のシェルによる変数展開
シェルスクリプトを作成する際に
シェル変数に値を代入したり参照したりする事は頻繁に発生するが、
シェル変数の展開にも便利な使い方がある。
basename (1) や dirname (1) と同様な動作が
シェルの組込みとして利用できるので資源の節約にもつながり、
上手に利用すると可読性の高いスクリプトが作成できる。
機能一覧
| ${parameter:-word} | デフォルト値への置換 |
| ${parameter:=word} | デフォルト値の代入 |
| ${parameter:?[word]} | 値の検査とエラー |
| ${parameter:+word} | 代替値の使用 |
| ${#parameter} | 文字列長の取得 |
| ${parameter%word} | 最短後置パターンの削除 |
| ${parameter%%word} | 最長後置パターンの削除 |
| ${parameter#word} | 最短前置パターンの削除 |
| ${parameter##word} | 最長前置パターンの削除 |
デフォルト値への置換
- ${parameter:-word}
${parameter} が NULL の場合 word に置換される。
$ echo ${foo}
$ echo ${foo:-FOO}
FOO
$ echo ${foo}
$ foo=BAR
$ echo ${foo:-FOO}
BAR
デフォルト値の代入
- ${parameter:=word}
${parameter} が NULL の場合 word に置換され、 かつ parameter に代入される。
$ echo ${foo}
$ echo ${foo:=FOO}
FOO
$ echo ${foo}
FOO
$ echo ${foo:=BAR}
FOO
値の検査とエラー
- ${parameter:?[word]}
${parameter} が NULL の場合 word が指定されていればその値を、 指定されていない場合はデフォルトの値を表示し、 非対話実行されているシェルをエラー終了させる。
$ echo ${foo}
$ echo ${foo:?value not set}
value not set
代替値の使用
- ${parameter:+word}
${parameter} が NULL 以外の場合 word に置換される
$ echo ${foo:+FOO}
$ echo ${foo}
$ foo=BAR
$ echo ${foo}
BAR
$ echo ${foo:+FOO}
FOO
文字列長の取得
- ${#parameter}
${parameter} の文字列としての長さに置換される
$ echo ${foo}
$ echo ${#foo}
0
$ foo=FOO
$ echo ${foo}
FOO
$ echo ${#foo}
3
最短後置パターンの削除
- ${parameter%word}
${parameter} の右から word で示されるパターンの最短部分を削除する
$ foo=/foo/bar/baz
$ echo ${foo%/*}
/foo/bar
$ foo=foo.c
$ echo ${foo%.*}
foo
$ foo=foo
$ echo ${foo%.*}
foo
最長後置パターンの削除
- ${parameter%%word}
${parameter} の右から word で示されるパターンの最長部分を削除する
$ foo=foo.example.com
$ echo ${foo%%.*}
foo
$ foo=http://www.example.com:8888/
$ echo ${foo%%:*}
http
$ foo=foo
$ echo ${foo%%.*}
foo
最短前置パターンの削除
- ${parameter#word}
${parameter} の左から word で示されるパターンの最短部分を削除する
$ foo=foo.c
$ echo ${foo#*.}
c
$ foo=foo.example.com
$ echo ${foo#*.}
example.com
$ foo=foo
$ echo ${foo#*.}
foo
最長前置パターンの削除
- ${parameter##word}
${parameter} の左から word で示されるパターンの最長部分を削除する
$ foo=foo.example.com
$ echo ${foo##*.}
com
$ foo=/foo/bar/baz
$ echo ${foo##*/}
baz
$ foo=foo
$ echo ${foo##*.}
foo


