2013年03月02日

Apache2.4系をソースからコンパイルする

aprが別途必要。2.4から分かれたらしい。面倒な…。
CentOS6にはaprが入ってはいるが、1.3.9で、apache2.4は1.4.0以降を要求するので、別に入れてやらねばならない。
PCREも要求されるので入れなければならない。
概ねこんな感じでいける。
wget http://ftp.riken.jp/net/apache//apr/apr-1.4.6.tar.gz
tar xvfz apr-1.4.6.tar.gz
cd apr-1.4.6
./configure
make
make install

wget http://ftp.riken.jp/net/apache//apr/apr-util-1.5.1.tar.gz
tar xvfz apr-util-1.5.1.tar.gz
cd apr-util-1.5.1
./configure --with-apr=/usr/local/apr
make
make install

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.32.tar.gz
tar xvfz pcre-8.32.tar.gz
cd pcre-8.32
./configure
make
make install

wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache//httpd/httpd-2.4.4.tar.gz
tar xvfz httpd-2.4.4.tar.gz
cd httpd-2.4.4
./configure --with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr \
--with-pcre=/usr/local
make
make install
posted by usoinfo at 01:05 | Comment(0) | Linux | このブログの読者になる | 更新情報をチェックする

2013年03月01日

MySQL5.6.10をソースからコンパイルしたらGooglemockがエラーだと言われた

CentOS6.3の32bit版で遭遇。
$ cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
(略)
:
-- Performing Test HAVE_PEERCRED - Success
-- Googlemock was not found. gtest-based unit tests will be disabled. You can run cmake . -DENABLE_DOWNLOADS=1 to automatically download and build required components from source.
-- If you are inside a firewall, you may need to use an http proxy: export http_proxy=http://foo.bar.com:80
言われた通り -DENABLE_DOWNLOADS=1 としてダウンロードを試みるも、
$ cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DENABLE_DOWNLOADS=1
(略)
:
-- ...
-- Successfully downloaded http://googlemock.googlecode.com/files/gmock-1.6.0.zip to /usr/local/mysql/src/mysql-5.6.10/source_downloads
CMake Error: Problem with tar_extract_all(): Invalid argument
CMake Error: Problem extracting tar: /usr/local/mysql/src/mysql-5.6.10/source_downloads/gmock-1.6.0.zip
-- Configuring incomplete, errors occurred!
おいおい…。
これは、手で展開して再度やると通るようだ。ダウンロード自体はできているので、さっきのエラーの所から
$ cd source_downloads/
$ unzip gmock-1.6.0.zip
$ cd ../
$ rm CMakeCache.txt
$ cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DENABLE_DOWNLOADS=1
(略)
:
-- GMOCK_SOURCE_DIR:/usr/local/mysql/src/mysql-5.6.10/source_downloads/gmock-1.6.0
-- GTEST_LIBRARIES:gmock;gtest
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/local/mysql/src/mysql-5.6.10
で、makeできる。やれやれである。
posted by usoinfo at 17:17 | Comment(0) | Linux | このブログの読者になる | 更新情報をチェックする

2013年01月29日

デバイスを引っこ抜いたらWindowsをシャットダウンするアプリ

 また、どこに需要があるのか不明なアプリを作ってしまったが…。デバイス接続状態を検出してWindowsを制御するアプリである。
これ

【そもそもは】
 携帯で再生した音楽を、WindowsPCのBluetoothでA2DPで受けて、スピーカーから再生するようにする(先日のやつを車から出してきて、シームレスに使おうという肚である)。で、使うと、間違いなくWindowsのシャットダウンを忘れて電気を無駄遣いするのが容易に予想される。そこで、Bluetoothのデバイスを監視して特定のペアリングが切れたらシャットダウンを発行するアプリがあればいいんじゃないかろうかと思いつく。で、探してみたけどどうもなさそうなので、じゃあ手っ取り早く作るかと思って、コードを書き始めた。
 だが、Bluetoothは(自作に)よくない。
 Bluetoothのスタックが何種類も(Microsoftのと、東芝のと、WIDCOMMのと、BlueSolielのと。他にもあるのかもしれん)あって、それぞれAPIもSDKも別である。簡単に使えるのはMSの標準で付いてるスタックだが、MSスタックではA2DPが食えない。家のはWIDCOMMスタックを入れてA2DPを動かしたが、当然MSのAPIでは扱えない。いちいちSDKをゲットしてドキュメントを読んで、結局WIDCOMM専用のアプリにしかならないと思うと気力が萎えて、沙汰止みとした。
 
【思い直した】
 単にデバイスがあるかどうかが取りたいだけなのにになんでこんなに困難なんだと思っていたが、後日気がついた。
 Blutoothとかは関係なく、Windowsに接続されているデバイスを直接見れば何とかなるんじゃない?それだとBluetooth以外のデバイスにも対応できるし、その方が汎用じゃない?
 具体的には、SetupDiEnumDeviceInfoしてSetupDiGetDeviceRegistryPropertyして、さっきと今を比べたら、デバイス引っこ抜いたのが分かるんじゃない?

 と、いうわけで、ざくざくとアプリを作ってみた。
 特定のデバイスを引っこ抜いたり、接続したりした時に、それに反応して、シャットダウン/ログオフ/サスペンド/休止状態/パワーオフまたはユーザー定義アプリを実行する。
 定期的にデバイス一覧を取っては比較、デバイスのユニークネスは、SPDRP_CLASSGUIDSPDRP_HARDWAREIDの0番目で見る。従って、着脱時にデバイスマネージャーに出没して、HARDWAREIDがユニークなデバイスなら、使用可能のはずである。例えばUSBメモリースティックとかね。


 携帯をBluetoothをA2DPでペアリングすると、音量とかを操作するヤツがHIDデバイスで出没するので、こいつを捉えて初期の目標を達成した。他にどんな使い道があるのか分からないが、せっかく作ったので公開しておく。

ByDHalt デバイス接続状態を検出してWindowsを制御


 誰かの役に立てば幸い。

posted by usoinfo at 17:28 | Comment(1) | 開発 | このブログの読者になる | 更新情報をチェックする

2013年01月11日

電源連動音楽プレーヤー

 自動車の運転中に音楽を流すのに、長いことWindowsCEベースのPDAを使い、GetSystemPowerStatusで給電が止まったらサスペンドする自作ソフトを走らせて、エンジンが止まったら再生が止まりエンジンを掛けたら止まったところから再開されるようにしていたのだが、そのPDAが壊れてしまった。もう古いアーキテクチャであるから、中古市場にも格安のWinCEベースのデバイスは出回っていないので、調達することもできない。
 そんな古いものをいつまでも使っていたのは理由があって、自動車内で普通のメモリプレーヤーを使おうとしても、これがなかなかうまくないからである。してほしいことは単純で、エンジン切ったら止まり、エンジン掛けたらそこから再生してくれればいいのであるが、電源が切れたら再生を中断するようなメモリプレーヤーは、全然ないのである。これでは車から降りるときいちいち停止ボタンを押さなくてはならない。当然のように押し忘れるので、再生位置をロストして悲しいことになる。
 じゃあというので、Androidのアプリでそういうものがないのかと探したが、探し方が悪いのか、あんなに山のようにアプリがあるのに、給電が切断されたら一時停止、という、ごく簡単な機能を持つプレーヤーのアプリがないのである(イヤホンジャックを抜くと一時停止、というのはある。VideoLAN for Androidとか。)
 
 こうなれば是非もない、ないのならば自分で作るほかあるまい、ということで、Android用の電源状態に連動する音楽プレーヤーアプリを作った。ごくシンプルなプレーヤーである。自動車内で触らずに音楽を流す、という用途しか考えていない。ボタンがやたらとデカいのは、運転席上での操作が前提だからである。

cap_jp_net_usost_einterlockplayer_free.png


 シガーソケットからUSBを取るやつと電源ケーブルをつないで再生して、エンジンを切ると給電がオンからオフになるので再生を停止する。エンジンを掛けるとオフからオンになるので再生を再開する。これで停止ボタン押し忘れの呪いから解放されるはずである。 
 せっかく作ったので、今回GooglePlayにデベロッパー登録してアプリを公開してみた。



 デベロッパー登録は、$25かかるのな。なんかでアプリで収益をあげて、せめて登録料分くらいは取り返したいものだが。
posted by usoinfo at 19:14 | Comment(1) | 開発 | このブログの読者になる | 更新情報をチェックする

PHPでそのホストで実行中のプロセス一覧を取得(Linux)

バックグラウンドで処理をさせていた時など、特定のコマンドやらpidやらのプロセスがあるかどうかを調べたい時があるので、ぱぱっと。
function Unix_GetPidArray()
{
$ret = array();
$cmd = "/bin/ps -e -o pid,args";
$fp = popen($cmd, "r");
while( ($line = fgets($fp)) != false ){
$line = ltrim($line);
$pos = strpos($line, " ");
$pid = intval(substr($line, 0, $pos));
$args = substr($line, $pos+1);
if( $pid <= 0 ) continue;
$ret[] = array(
'pid' => $pid,
'args' => $args,
);
}
fclose($fp);
return $ret;
}
実行結果例
$r	= Unix_GetPidArray();
echo var_dump($r);
--
Array
(
[0] => Array
(
[pid] => 1
[args] => /sbin/init
)
[1] => Array
(
[pid] => 2
[args] => [kthreadd]
)
[2] => Array
(
[pid] => 3
[args] => [migration/0]
)
[3] => Array
(
[pid] => 4
[args] => [ksoftirqd/0]
)
...略
ps -eを実行した結果をバラして格納しているだけである。/bin/ps -e -o pid,args を実行してみて、[プロセスID]半角スペース[コマンド....]の書式になればそのまま使用可能。違ったときは環境に合わせて$cmdを調整。
応用で、プロセスID(int値)を与えるとそのpidがあるかどうか(ps -ef|grep 1111|wc -l 的なもの)、文字列を与えるとその文字列を持つコマンドのプロセスIDを列挙(ps -ef|grep ahoaho 的なもの)の関数。
function Unix_IsPidExisted($pid)
{
$ret = false;
$cmd = "/bin/ps -e -o pid";
$fp = popen($cmd, "r");
while( ($line = fgets($fp)) != false ){
if( intval(trim($line)) === $pid ){
$ret = true;
break;
}
}
fclose($fp);
return $ret;
}

function Unix_GetPidStringMatched($str)
{
$ret = array();
$cmd = "/bin/ps -e -o pid,args";
$fp = popen($cmd, "r");
while( ($line = fgets($fp)) != false ){
if( strpos($line, $str) === FALSE ) continue;
$ret[] = intval(substr(ltrim($line), 0, strpos(ltrim($line), " ")));
}
fclose($fp);
return $ret;
}

/*
実行例:

$ret = Unix_IsPidExisted(4566);
// PID 4566 が存在すれば true が返る

$ret = Unix_GetPidStringMatched('httpd');
// args に httpd を含むPIDを列挙した配列が返る

*/

タグ:Linux PHP
posted by usoinfo at 09:28 | Comment(1) | 開発 | このブログの読者になる | 更新情報をチェックする

2012年11月11日

CygwinのシェルスクリプトをWindowsのショートカットで実行

Cygwinで作成したシェルスクリプトをショートカット化してデスクトップ等に置きたい時に。
シェルのexeのlnkを作成して引数でスクリプトを与えるとできる。

  1. ショートカットの元は、Cygwinのbinの下のsh.exe(又はその他のシェルのexe)
  2. プロパティで「リンク先」に、「exeファイルのパス シェルスクリプトのパス」を書く
  3. シェルスクリプトのパスは /cygdrive/... で書き、スペースを含むなら"で囲む
  4. シェルスクリプト中のコマンド名でWindowsのコマンドとかぶるものはフルパスで指定する(findとか)
こんな感じで。
dump20121111-01.png
タグ:cygwin
posted by usoinfo at 08:32 | Comment(0) | Windows | このブログの読者になる | 更新情報をチェックする

2012年11月08日

指定ディレクトリ以下の特定のファイルを全てchmod/chown

いつも忘れてしまうのでメモ。
指定ディレクトリ以下の特定のファイルを全てchmodしたりchownしたりする。
find ./ -name \*.phps -type f -exec chmod 664 {} \;
posted by usoinfo at 06:43 | Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

2012年09月05日

mod_rewriteのRewriteMapでPHPのプログラムを使う

 現代の黒魔術、mod_rewriteは万能である。
 正規表現と置換だけでも万能だが、更に黒い魔術として、入力をユーザー独自のプログラムに渡して書き換えることができる、RewriteMapというのがある。

 厳密には、RewriteMapは独自プログラムに渡すと言うよりは、マップテーブルを用意しておいてそこから選ぶもので、その拡張機能としてプログラムに渡すというものがあるのだろう。まあ来歴はどうでもいいが、これを使うと正規表現では書けないような妙ちきりんな書き換えもできる。例えばUTF-8エンコードされたクエリーをデコードしてSJISに変えてまたエンコードしたものにする、とか、特定のファイルが存在していたら書き換え、とか。

 まず、Apacheのconfigファイルに例えばこのように書く。
RewriteEngine on
RewriteLock /tmp/rewritemap.lock
RewriteMap myprog prg:/usr/local/bin/url_rewriter.php
RewriteRule ^/rewrite/(.*)$ /test/${myprog:$1}
 RewriteLockはロックファイルの場所で、どこでも良い。但し、VirtualHostの中には置けないようなので、一番上に書く。
 "RewriteMap プログラム名 prg:プログラムのパス"で、プログラムの場所を指定し、RewriteRule中の ${プログラム名:入力} が、プログラムによって置換される。
 
 さて、問題のプログラムである。
 どういう仕組みになっているかと言うと、mod_rewrite側は標準入力に入力を入れてきて、プログラム側は標準出力に書き換え結果を出力する。のであるが、このプログラムは、Apacheの起動時に書き換え用のプロセスが1つ立ち上がり、プロセスはずっと走りっぱなしになっているのである。アクセス毎に起動されるわけではなく、プログラム中では、(一般的には)標準入力をブロッキングI/Oで読み続けるループにする必要があるのであった。
 従って例えば、url_rewriter.phpはこんな感じになる。
 
#!/usr/local/bin/php
<?php
$fin = fopen("php://stdin",'r');
while(!feof($fin)){
$read = fgets($fin);

$out = ここで$readに応じて書き換え処理...;

$fout = fopen("php://stdout",'w');
$out .= "\n";
fwrite($fout, $out);
fclose($fout);
}
fclose($fin);
// ※入出力はSTDINとechoを使ってもいいが、分かり易さでphp://とした。
?>
 mod_rewriteからは、stdinに入力内容+"\n"が来る。この入力をfgetsで取って、書き換えた結を"\n"で終端してstdoutに返す。終わったら次の入力に備える。と、こういう次第である。
posted by usoinfo at 21:13 | Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

2012年08月10日

MySQLで既存のテーブルのCREATE文を取得

既存のデータベース/テーブルの、CREATE文を取得する方法。メモってたCREATE文をロストしたとか、他人の作ったテーブルで中身がよくわからん、と言った時に使えるかも。(mysqldump を --no-data で走らせてもいいけどな)

・既存のデータベース中にどんなテーブルがあるか調べる
SHOW TABLES で、データベース内のあるテーブル名のリストが取れる。
mysql> SHOW TABLES;
+------------------------------------------+
| Tables_in_usodb |
+------------------------------------------+
| attacker_ahoaho |
| abyorn_hogehoge |
:
+------------------------------------------+
206 rows in set (0.01 sec)

mysql>

・テーブルのCREATE文を取得する
SHOW CREATE TABLE (tbl_name) で、そのテーブルのCREATE文が取れる。
mysql> SHOW CREATE TABLE zenra_config\G
*************************** 1. row ***************************
Table: zenra_config
Create Table: CREATE TABLE `zenra_config` (
`zenraid` varchar(64) CHARACTER SET sjis COLLATE sjis_bin NOT NULL,
`title` varchar(512) CHARACTER SET sjis COLLATE sjis_bin DEFAULT NULL,
`text` mediumblob,
`remark` varchar(512) CHARACTER SET sjis COLLATE sjis_bin DEFAULT NULL,
PRIMARY KEY (`zenraid`),
CONSTRAINT `fk_znrcfg_aid` FOREIGN KEY (`zenraid`) REFERENCES `zenra_pri` (`zenraid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=sjis
1 row in set (0.00 sec)

mysql>


・というわけで、この2つを使ってこんなスクリプトを書けば、データベース内のテーブルのCREATE文を浚ってくれる。
#!/bin/sh

# mysqlコマンドと引数
SCRIPT_MYSQL="mysql -p[YOUR_PASS] -u [YOUR_NAME] [YOUR_DB]"

# 出力ファイル
FILE_CREATES=tablecreatesql.txt

rm -f ${FILE_CREATES}

for t in `echo "SHOW TABLES" | ${SCRIPT_MYSQL}`
do
echo "SHOW CREATE TABLE $t\G" | ${SCRIPT_MYSQL} >> ${FILE_CREATES}
done
タグ:Linux MySQL
posted by usoinfo at 07:43 | Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

2012年08月06日

ffmpegで複数の動画ファイルを1つにつなげる

 先日、やたらと安いドライブレコーダーを買ったのである。3000円くらいの、こんな感じのドライブレコーダーのうちのひとつである。性能も機能もお値段なりだが、エンジン掛けると勝手に録画開始、エンジン切ると勝手に録画終了なので、案外便利である。

 さて、そのドライブレコーダーはファイル循環式で、最長15分経つと、ファイルが切れて次のファイルに行くようになっている。つまり、まず PICT001.AVI が録画され、15分後に PICT002.AVI に移る、という具合で、1時間走れば4本、2時間走れば8本の動画ファイルができあがる。そこで、このファイルを1つに繋げたいところであるが、動画編集をするソフトを使えばすぐだが、ソフトを買ってまでするほどのことでもないし、編集ソフトでやるのはいちいち操作が必要で面倒。できればコマンドラインでやってしまいたい。
 そこで、フリーのFFmpegを使って、複数の動画ファイルを1つにコンカチする手順。いろいろと試行錯誤の末、次のような手順に落ち着いた。
 
 1. まず、単純結合可能なmpgコンテナに、データを変換する
 例: PICT001.AVI, PICT002.AVI, PICT003.AVI があるとして、
ffmpeg -y -i PICT001.AVI -sameq PICT001.mpg
ffmpeg -y -i PICT002.AVI -sameq PICT002.mpg
ffmpeg -y -i PICT003.AVI -sameq PICT003.mpg

 2. mpg に変換したファイルをつなげる
 Linuxの人は cat でどうぞ。
copy /b PICT*.mpg temp.mpg

 3. このままだとタイムスタンプがおかしいらしいので、修正する
 この状態だと、ファイルの再生時間長などが正しく表示されない(VideoLANなどで見てみると分かる)。次のオプションでもう一度変換すると、正しくなるようである。
ffmpeg -y -i temp.mpg -same_quant -dts_delta_threshold 1 PICTALL.mpg
 
 4. 結合した修正済みデータを、希望のエンコーダーで変換する
 そのまま使うなら別にこのままでもよいが、映像:Xvid 1200k 15fps、音声:mp3 64kbps の例。
ffmpeg -y -i PICTALL.mpg -vcodec libxvid -b:v 1200k -r 15 \
-acodec libmp3lame -ab 64 -ar 44100 \
PICTXVID.avi

 あとは、PHP For Windowsあたりを使ってスクリプトを書けば、D&Dで結合+再変換まで自動で処理できるようになる。
 続きを読む
posted by usoinfo at 06:25 | Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする