« 2004年01月 | メイン | 2004年03月 »

2004年02月29日

Perl でデータベースを操作する実験

Windows 上の Perl でデータベースを操作するには DBI モジュールか、OLE 経由で ADO を使うことができる。どちらが便利なのかまだ自分には分からないのだが、とりあえずローカルコンピュータ上でアクセスのデータベースを OLE 経由の ADO で操作するサンプルを以下に書いておく。
接続のところを変えれば SQL server でも使えるはずである。

データベース作成、テーブル作成、データ挿入の例
# アクセスのデータベース操作の例
# アクセスのデータベース hoge.mdb を作り、
# hoge.mdb に接続して、テーブルを作成、データを挿入。
# Windows 2000 pro, Access 2003 で動作確認を行った。

use Win32::OLE;
$connStr="Provider=Microsoft.Jet.OLEDB.4.0;";
$connStr.="Data Source=hoge.mdb;";

# アクセスのデータベース作成

$objCat=Win32::OLE->new("ADOX.Catalog");
$objCat->Create($connStr);
$objCat=undef();

#アクセスのデータベースへの接続
$objDB=Win32::OLE->new("ADODB.Connection");
$objDB->Open($connStr);

# テーブル作成
$cmd=$objDB->Execute(
    "Create Table seito(id int, name Char(20))" );

# データ挿入
$cmd=$objDB->Execute(
    "Insert into seito values(11,'蘇我 馬子')"  );
$cmd=$objDB->Execute(
    "Insert into seito values(12,'中臣 鎌子')"  );

# 接続を閉じる
$objDB->Close();
$objDB=undef();

データ読み出しの例
#  データベース操作の例
#  カレントディレクトリの hoge.mdb から
#  foo テーブルのデータを読みだす。
#  Windows 2000 pro, Access 2003 で動作確認を行った。

use Win32::OLE;

#アクセスのデータベースへの接続
$connStr="Provider=Microsoft.Jet.OLEDB.4.0;";
$connStr.="Data Source=hoge.mdb;";
$objDB=Win32::OLE->new("ADODB.Connection");
$objDB->Open($connStr);

# データ読み出し
$rs=$objDB->Execute("select id,name from seito");
while(!$rs->EOF){
	print "$rs->{Fields}->{id}->{Value},";
	print " $rs->{Fields}->{name}->{Value}\n";
	$rs->MoveNext();
}
$rs->Close();

# 接続を閉じる
$objDB->Close();
$objDB=undef();

投稿者 augustus : 18:52 | コメント (2) | トラックバック

2004年02月22日

Wake up on LAN の実験

管理しているPCが離れたところにあったり、数が多かったりすると、電源を入れるだけでも結構大変である。多くの作業を自動化するように工夫していて、電源を入れるところだけは手動というのも悔しい。
そういうときに使えるのが Wake up on LAN。文字通り LAN 経由で、PCを起こしてくれる。

方法としては、マジックパケットと呼ばれるパケットをターゲットのPCに届けてやれば良いらしい。
http://www3.jpn.hp.com/CPO_TC/pc/doc/34602.pdf によるとマジックパケットというのは、6個の FF(16進)のあと、MACアドレスを16回以上繰り返したものだそうである。

Perl によるスクリプトがhttp://adlib.rsch.tuis.ac.jp/~akira/unix/にあった。

自分用に書き直したのが、以下のスクリプト。複数のPCをターゲットにするよう書きかえるのも簡単である。(MAC address と Broadcast IP address を書き換えてから試してみてほしい。)
use Socket;
#
# wake up on LAN
#

# ターゲットの MAC address と Broadcast IP address
$ret=wakeup_on_lan("00-11-22-33-44-55", "10.255.255.255");
print $ret if $ret;

#
# wakeup_on_lan(MACアドレス, ブロードキャストアドレス)
# エラーのときはエラーの内容を示す文字列を返す。
# エラーでないときは空文字列を返す。
sub wakeup_on_lan{ 
    my($mac_address, $broadcast_address)=@_;
    my($macstr, $remote_port,$proto,$iaddr,$paddr,$pac);
    # MAC address decode
    $mac_address=~s/-//g;
    $macstr=pack("H12", $mac_address);
    # Magic Packet create
    $pac = "\xff\xff\xff\xff\xff\xff";
    for($i=0; $i<20;$i++) {
        $pac .=$macstr;
    }
    # open socket
    $remote_port="7";
    $proto=getprotobyname('udp');
    socket(S, PF_INET, SOCK_DGRAM, $proto) 
        or return "ERROR at open socket: $!";
    setsockopt(S, SOL_SOCKET, SO_BROADCAST,1) 
        or return "ERROR at sockopt: $!";
    # send Magic Packet
    $iaddr=inet_aton($broadcast_address) 
        or return "ERROR at get broadcast address: $!";
    $paddr=sockaddr_in($remote_port,$iaddr) 
        or return "ERROR at make broadcast: $!";
    send(S,$pac,0,$paddr) 
        or return "ERROR at send broadcast:$!";
    return("");
}

マジックパケットの送り先が1台なのにブロードキャストを使うには理由がある。 届きさえすれば、ブロードキャストでなくてもよいのだが、arp テーブルがクリアされたりしていると届かない。ブロードキャストを使えば、そういうことは気にしなくて良くなる。
UDP の port 7 を使っているが、実験してみると port 番号は適当で良いようだ。

ターゲットの MAC アドレスが必要になるが、電源が入っているときに ping を飛ばしてから arp コマンドを使って、arp -a とやれば簡単に調べられる。

がんばれば、LAN だけでなくインターネット経由で Wake up on LAN を行うこともできるらしい。
http://bb.watch.impress.co.jp/column/shimizu/2003/09/16/

投稿者 augustus : 05:54 | コメント (0)

2004年02月21日

Perl の Net::Ping モジュール

ping といえばネットワーク的に繋がっているかどうかを確かめるための定番ツールだが、Net::Ping モジュールはそれと同様の機能をもつ Perl のモジュールである。

例えば、 192.168.0.1 に ping を飛ばして返事があれば、何かの処理をする例はこんな感じ。
use Net::Ping;
$host="192.168.0.1";
$timeout=0.1;
$p = Net::Ping->new("icmp");
if $p->ping($host, $timeout){
	print "$host is alive.\n";
}
$p->close();


もうちょっと複雑にしてみる。次は
192.168.0.11 から 192.168.0.40 の範囲に ping を飛ばしてから arp コマンドによって mac address を取得するスクリプト。
use Net::Ping;
$timeout=0.1;
$p = Net::Ping->new("icmp");
@host=map("192.168.0.$_", 11..41);
for $host (@host){
    $p->ping($host, $timeout);
}
$p->close();
open(CMD, "arp -a|") or die "cannot exec arp";
print grep($_!~/invalid/, <CMD>);
close(CMD);

投稿者 augustus : 12:05 | コメント (0) | トラックバック

2004年02月14日

フォルダリダイレクトに必要なNTFSアクセス権

1月に学校のシステムの大幅入替があって、Windows NT 4.0 から Windows 2003 Server + XP professional に変えている。セットアップ等は業者さんがやってくれているのだが、まだいろいろ不具合が残っている。

昨日何気なくクライアントPCのイベントログを覗いてみると、Application Data フォルダーのリダイレクトに失敗したというエラーの山。
試行錯誤の結果分かったのだが、Application Data フォルダーの該当ユーザのアクセス権がフルコントロールでないとエラーになるようだ。フォルダリダイレクトのためには共有のアクセス権にフルコントロールが必要なことは知っていたのだが、NTFSのアクセス権もフルコントロールが必要だったとは知らなかった。
各ユーザの Application Data フォルダーのアクセス権を cacls.exe を使って書換えるスクリプトを用意すれば解決するだろう。

家に帰ってから調べてみるとマイクロソフトのページにちゃんと書いてあった。

イベントログにはこれに関連した気持ち悪い警告が残っている。これも上述のマイクロソフトのページに書いてあることで解決すればいいなあ。

投稿者 augustus : 08:51 | コメント (2) | トラックバック

2004年02月08日

google の マイナス検索

アクセス解析を見ていると(少なくともうちに来る人には)マイナス検索はほとんど使われていないようだ。

google の検索窓に複数のキーワードを書くと、それは and として扱われる。たとえば、
ローマ 帝国 とすると、「ローマ」と「帝国」の両方を含むページにマッチする。単一のキーワードで検索するよりも、探したいページを絞り込むことができて便利だ。

キーワードの前に -(マイナス)をつけると、「そのキーワードを含まない」という意味になるので、検索結果から邪魔なものを排除するのに使える。たとえば、Windows の Explorer のオプションを調べたいとき、
explorer オプション とすると、Internet Explorer について書いたページが多数マッチして邪魔だが、
explorer オプション -internet とすることによって、それらを除くことができる。
このように、検索結果の中に予定外の邪魔なページが多数含まれているとき、マイナス検索を使って絞込みを行うのは有効だ。

投稿者 augustus : 10:32 | コメント (2) | トラックバック