2008年5月30日金曜日

GPLライセンスについて整理

まず基本的なことはwikipediaを読む。

ここの記事もがんばって読むと詳しくなった気になれる。

あとは本家のよくある質問を読めば、いくつかの疑問は晴れる。

GNU General Public Licenseの日本語訳

以下はいろんなサイトを見て間違えそうな部分を自分用にメモ。

  • GPLライセンスのコードを利用して作ったソフトを商用利用(お金を取って売る)ことは可能(用途の制限がない)。
  • 課金して売ったとしても、そのソフト(とソースコード)の配布方法に制限をかけることができない。
  • ソフトを配布(頒布)する場合はソースコードも渡さなければならない(もしくは要求すれば渡すことを明示)。だから個人的に使用する場合はソースコードを公開する必要はない。誰もが手に入れる場所にソフトを公開(頒布)したら、誰もが手に入れる場所にソースコードを公開しないといけない(もしくは要求すれば渡すことを明示)。
  • Webアプリケーションの場合、カスタマイズしてサーバにインストールして利用するだけなら、例えサーバが外部に公開していようとソースコードを公開する必要はない。そのWebアプリケーションにログインするのに料金が発生しようとGPL違反にはならない。→配布(頒布)してないから
  • GPL準拠のWebアプリケーションをカスタマイズして販売(納品)する場合は、いくらで売っても構わないが、ソースコードを渡さないといけないし、そのWebアプリケーションもGPLとなる。→配布(頒布)しているから
  • どこまでを配布(頒布)しているとみなすかは議論が分かれるところ。個人的な解釈では、そのソフトを別の環境で起動できるな状態で公開するのが配布(頒布)だと思う。

自分の言葉で書いているので、間違っている部分があったら修正します。

その他のライセンスについてはここのブログにリンク集が。

<2009/7/22 追記>
ライセンス条項の日本語訳をまとめたサイトがあったので覚え書き。

OSI承認オープンソースライセンス 日本語参考訳

2008年5月29日木曜日

【CentOS】いらないデーモン(daemon)を削除する

私は昔からVine Linuxを使ってサーバ構築しますが、会社の推奨はCentOSらしいです。VMware上にCentOSをいれて開発してますが、CentOSをインストールした直後はいろいろよく分からないデーモンがたくさん動いていて精神上よくない。(気にしないのが一番よい。)

Vineのときはここにメモってますが、CentOSでいらないデーモンを削除しようとしても
# chkconfig --list
のあまりの多さに萎える。誰か一覧で作ってないかなと思ったら、ここにスクリプトが。他にも探せば出てくるかも。ここの人もがんばって調べてた。

一応、自分でいらないデーモンをメモってたので置いときます。
# yum remove <名前>
でアンインストールする一覧です。依存関係で他のソフトも一緒に消えることがあります。

名前 説明
sendmail メール配送サービス
cups 印刷制御サービス
ypbind NIS バインド情報を管理
nfs-utils NFSを利用するためのツール群。NFS関係のdaemonが消える
bluez-utils
bluez-gnome
bluez-libs
bluetoothを使うためのツール群。
dhcdbd DHCP D-BUSデーモン
pcsc-lite スマートカードを使うためのソフト
irda-utils 赤外線通信規格「irDA」を使った通信を実現するサービス
portmap

RPC関連のport mapper
NFSやNISを使用する場合に必要

2008年5月28日水曜日

Sambaの設定ファイルsmb.confメモ

ネットワーク内にLinuxを導入したらWindowsのファイル共有を使えると効率がいいので、Sambaをインストールして設定していますが、その設定ファイルsmb.confをメモのために置いときます。

インストールした直後はとりあえず/etc/samba/smb.confに次の記述して保存。

[Samba_Conf]
    comment = Samba config
    path = /etc/samba
    guest ok = No
    browseable = Yes
    write list = root

sambaのユーザにrootを追加

$ pdbedit -a root

追加したらsambaを再起動

$ /etc/rc.d/init.d/smb restart

そのあとWindowsからネットワーク経由でサーバにアクセス。

下に書いてあるsmb.confに上書きしてsambaを再起動。 日本語が含まれているので文字コードを注意。 再起動後はたまにsambaユーザが消えるので

$ pdbedit –L

で確認。いなかったらもう一回rootユーザを追加。

$ pdbedit -a root

sambaを自動起動させる。

$ chkconfig smb on

以下smb.confの中身

[global]

#動作モード
    smb ports = 139

#ユーザの認証する方法(user, server, domain, share)
    security = user

#Unix Windows互換機
    dos charset = CP932
    unix charset = UTF-8
    display charset = UTF-8
    #ファイルモードをウィンドウズ風に
    dos filemode = Yes
    dos filetimes = Yes
    dos filetime resolution = Yes

#NetBIOSサービス設定
    #sambaサーバのドメイン名またはワークグループ名を指定
    workgroup = WORKGROUP
    #エクスポローラで表示したときのコメントとして表示される
;    server string = Samba %v on %h (Start time:%T )
    server string = Samba %v
    #NetBIOS名を指定
    netbios name = pluto

#プリンタ機(プリンタの共有はしない)
    load printers = No
    disable spoolss = yes
;    printcap name = /etc/printcap
    printing = bsd
;    cups options = raw

#パスワード管理、同期
    #security = server, domainの際にパスワードを認証するサーバ
;    password server = miyan
;    password level = 8
;    username level = 8
    encrypt passwords = Yes
    username map = /etc/samba/smbusers
;    passdb backend = tdbsam
    unix password sync = Yes
    passwd program = /usr/bin/passwd %u
    passwd chat = *New*password* %n\n *ReType*new*password* %n\n *passwd:*all*authentication*tokens*updated*successfully*

#名前解決関係
    name resolve order = wins lmhosts bcast
;    local master = Yes
;    os level = 65
;    domain logons = Yes

#ブラウジング機能関係
    socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
;    interfaces = 192.168.12.2/24 192.168.13.2/24
;    remote browse sync = 192.168.3.25 192.168.5.255
;    remote announce = 192.168.1.255 192.168.2.44
;    domain master = No
;    preferred master = Yes

#WINS関係
    wins support = yes
;    wins server = w.x.y.z
;    wins proxy = Yes
    dns proxy = No

#ユーザ管理
    hosts allow = 192.168.0. 192.168.1. 127.
    hosts deny = ALL
;    guest account = pcguest
    #認証なしでアクセスしたいときはコメントをはずす
    #map to guest = bad user
    admin users = administrator root
    winbind uid = 10000-20000
    winbind gid = 10000-20000

#ログの設定
    log file = /var/log/samba/%m.log
    max log size = 50
;    include = /etc/samba/smb.conf.%m
;    preserve case = No
;    short preserve case = No
;    default case = lower
;    case sensitive = No
;    logon script = %m.bat
;    logon script = %U.bat
    logon path = \\%L\Profiles\%U
;    logon path = \\%L\%U\profile

#Windowsクライアントに時刻サーバとして提供するかどうか
    time server = yes

#その他
    idmap uid = 16777216-33554431
    idmap gid = 16777216-33554431
    template shell = /bin/false
    winbind use default domain = no

#以下 共有セクション
[homes]
    comment = %U's Home Directory
    read only = No
    browseable = No

#システムログファイル
[System_Log]
    comment = System log file
    path = /var/log
    guest ok = No
    browseable = Yes
    read only = Yes

#sambaの設定ファイル
[Samba_Conf]
    comment = Samba config
    path = /etc/samba
    guest ok = No
    browseable = Yes
    write list = root

#いろいろな設定ファイル
[Etc_Conf]
    comment = Etc config
    path = /etc
    guest ok = No
    browseable = Yes
    write list = root

#tempディレクトリ
[tmp]
    comment = Temp Directory
    path = /tmp
    guest ok = No
    browseable = Yes
    writable = Yes

#optディレクトリ
[opt]
    comment = OPTION Directory
    path = /opt
    guest ok = No
    browseable = Yes
    writable = Yes
    #for TortoiseSVN(subversion)
    create mask = 0644
    force create mode = 0600
    security mask = 0555
    force security mode = 0600

<2008/06/21 追記>
CentOSの場合は次のようにしたほうがいいかも。ファイルの文字コードは「utf-8n」で保存することを忘れずに。

#Unix Windows互換機
    dos charset = CP932
    unix charset = UTF-8
    display charset = UTF-8

<2008/11/08 追記>
LAN内からのアクセスしか認めないのようhosts allowとhosts denyの設定を変更。

<2008/12/09 追記>
Unix ユーザとのパスワード同期を有効にした。

<2009/04/11 追記>
認証しなくても共有フォルダにアクセスできるようにmap to guest を追記。コメントをはずすと認証なしでアクセス可能に。

<2009/08/07 追記>
いちいち書き換えるのが面倒だったので、charsetをeucJP-msをUTF-8に変更。あと、細かいところを自分が使いやすいように変更

<2009/09/02 追記>
次のようなエラーが出るので

[2009/09/01 09:01:05, 0] lib/util_sock.c:get_peer_addr(1224)
  getpeername failed. Error was 通信端点が接続されていません
[2009/09/01 09:01:05, 0] lib/util_sock.c:write_data(562)
  write_data: write failure in writing to client 192.168.0.88. Error 接続が相手からリセットされました

smb ports = 139を追加。

<2010/06/10 追記>
WindowsのTortoiseSVNと連携するときの設定を追加。詳細はこちらの記事を参照。

<2010/08/23 追記>
コマンドメモ
pdbedit -a <ユーザー名> :ユーザー追加
pdbesit -x <ユーザー名> :ユーザー削除
smbpasswd <ユーザー名> :パスワード変更

<2011/03/17 追記>
他のユーザーと共有して、TortoiseSVN(Subversion)を使うだけの設定を追記。新しく仮想マシンを追加したときはこの設定だけ変更することにした。

workgroup = VM
server string = Samba %v
netbios name = vm-server
hosts allow = 127. 192.168.

security = share
public = yes
guest only = yes
guest account = smbguest

load printers = no
; cups options = raw

[opt]
    comment = Option Directory
    path = /opt
    browseable = Yes
    writable = Yes
    #for TortoiseSVN(subversion)
    create mask = 0644
    force create mode = 0600
    security mask = 0555
    force security mode = 0600

# useradd -M -s /sbin/nologon smbguest

# chown smbguest /opt

2008年5月27日火曜日

【PHP】全角、半角を変換して統一させたい

PHPではmb_convert_kanaという便利な関数があり、全角/半角変換をしてくれます。マニュアルはここ

まだ使う機会はないですが、そのうち使うことになりそうなのでメモ。

2008年5月26日月曜日

【PHP】入力した値がShift-JISか判定する(文字コード判定)

データベースの文字コードがEUC-JPとかShift-JISとかだと、ユーザが入力したデータが文字化けしないでちゃんとデータベースに保存できるかチェックしたいときがあります。

PHPだとmb_check_encodingという便利な関数があるので、これでチェックすればいいやーと思っていましたが、実装してみるとうまく判定してくれず。ソースファイルの文字コードによって返値が変わってくる。例えば、UTF-8nのファイルに次のコードを記述して実行すると値はfalse。

var_dump( mb_check_encoding( '1', 'Shift-JIS')); //全角の1

これは正しい?使い方間違っている?

しょうがないので、mb_check_encodingはあきらめて、mb_convert_encodingを使って、一度チェックした文字コードに変換して、元に戻した結果が同じかどうかでチェックすることに。

こんな感じ↓

$sMoji = "1";
$sTemp = mb_convert_encoding($sMoji, 'Shift-JIS'); //変換
$sTemp = mb_convert_encoding($sTemp, 'UTF-8', 'Shift-JIS'); //元に戻す
if ($sMoji === $sTemp) {
    echo "Shift-JISで表現できる文字:$sMoji";
} else {
    echo "Shift-JISで表現できない文字:$sMoji";
}

ちなみにShift-JISで表現できない文字で有名なのが森鴎外の鴎(かもめ)がメでなくて品となっている「鷗」という文字。「かもめ」とか「おう」で変換すれば出てくる。

さらにmb_internal_encodingを使って現在の文字コードを取得すれば、汎用的になる。↓こんな感じかな。(試してはないです)

$sMoji = "1";
$sEncode = mb_internal_encoding();
$sTemp = mb_convert_encoding($sMoji, 'Shift-JIS', $sEncode); //変換
$sTemp = mb_convert_encoding($sTemp, $sEncode, 'Shift-JIS'); //元に戻す
if ($sMoji === $sTemp) {
    echo "Shift-JISで表現できる文字:$sMoji";
} else {
    echo "Shift-JISで表現できない文字:$sMoji";
}

<2008/07/03 追記>
「Shift-JIS」だと「Ⅱ」とかがShift-JISと判断してくれないので、「sjis-win」にした方がよいみたい。

2008年5月24日土曜日

Google八分?Googleのインデックスから削除された?

昨日おもむろに自分のブログを見ようと「se suganuma」とgoogleの検索窓から入力してみました。いつもならトップに自分のブログが出てきていましたが、この日はなぜか自分のブログが出てこない・・・。

2ページを見てみるとやっといつかのエントリーが出てきましたが、これはもしや噂に聞く「google八分?」と思い、google八分について調査しました。

ここに自分が本当にGoogle八分なのかの確認方法と対応方法が載っているので参考に。

Googleの検索窓に自分のブログのURLを記述して検索してみて、自分のブログが出てくればとりあえずGoogleのインデックスから削除されている訳ではないようです。このブログの場合もちゃんと表示されたので、Googleのインデックスから削除されてないことは分かりました。
GoogleのWebマスターツールにも登録してありますが、こっちを見ても特に変わったことはありませんでした。怪しいと思ったのは、

image

↑この記述があったので、このときになんか悪いサイトとして判断されたのかなーと思っています。

なんででしょうね?

Googleのウェブマスター向けガイドラインを読んで、心当たりがありそうなのは

  • 会社へのリンクがいっぱいあったので過剰なSEO対策として判断された?
  • 引用が著作権違反と判断された?もしくは誰かに通報された?

ぐらいかなー

とりあえずSEO対策で会社へのリンクをいっぱい付けてたのは削除してみました。

それが原因かは分からないですが、今日になって「se suganuma」で検索するとちゃんとトップに出てきてくれたので、時間が経てば元に戻るような気はしてます。

一時的なものだと祈りつつ・・・。

2008年5月23日金曜日

【PHP】【DOM】ノードをコピーする方法

PHPのDOMを使ってXMLを操作していると、別々に作ったDOMを一つのノードにまとめたい場合があります。cloneNodeとか使って簡単にできるかと思ったけど、ちょっとつまずいたのでメモ。

最初に書いたコード↓

$objDom2 = new DOMDocument();
$objDom2->encoding = 'UTF-8'; 
//文字化け対策.
$objDom2->formatOutput = true;  //字下げや空白を考慮してきれいに整形した出力を行う。.
$objNode = $objDom2->appendChild( $objDom2->createElement('copy') );
$objNode->appendChild( $objAddNode->cloneNode(true) );
echo $objDom2->saveXML();

単純にもう一つDOMドキュメントを作ってコピーしたいノードをcloneNodeを使って追加しようとしてる。しかし、これだと'Wrong Document Error'で怒られる・・・。JavaScriptだとできたのに・・・。

調べてみるとimportNodeを使って、現在のDOMドキュメントに関連づけを変更しないと追加できないみたい。

修正したコード↓

$objDom2 = new DOMDocument();
$objDom2->encoding = 'UTF-8';
//文字化け対策.
$objDom2->formatOutput = true;  //字下げや空白を考慮してきれいに整形した出力を行う。.
$objNode = $objDom2->appendChild( $objDom2->createElement('copy') );
$objNewNode = $objDom2->importNode( $objAddNode, true );
$objNode->appendChild( $objNewNode );
echo $objDom2->saveXML();

JavaScriptのDOMになれてるとなかなか気付かないかも。

2008年5月22日木曜日

【PHP】XMLReaderでXMLを高速に処理をする

ここここでDOMとSimpleXMLについて書きましたが、調べていくうちに目にとまるようになったのがXMLReaderなるもの。

XMLReaderを使うとread()を行うたびに階層(ノード)単位で読み込んでいくので、すべてのXMLを読み込まなくても、必要な階層(ノード)に辿りついた時点で処理を行えます。そのため、大きなXMLファイルを扱う場合などメモリの消費を抑えることができ、高速に処理ができるようです。

ここにサンプルコードがあるのでメモ。マニュアルはここ

XMLReaderはPHP5.1.0以上であればデフォルトで組み込まれているので、インストールは不要。

大量のデータをXMLでやり取りする場合は必須となりそう。

2008年5月21日水曜日

【PHP】SimpleXMLを使ってXMLを直感的に操作

ここの続き。PHP5のDOMでXMLを操作するときにXpathの記述方法のめんどくささに萎える。JavaScriptみたいにselectSingleNodeとかselectNodesとか書きたくなるけど、これができない。

DOMXpathを使うとこんな感じ

$objDom = new DOMDocument();
$objDom->preserveWhiteSpace = false; //余分な空白を取り除く.
$objDom->load('sample.xml');

$objXpath = new DOMXPath($objDom);
$sQuery = '//root/comment';
$objSelectNodes = $objXpath->query($sQuery);
echo $objSelectNodes->item(0)->nodeValue;

echo $objSelect->item(0)->getAttribute('id');

Xpathを記述しようと思うだけで別のオブジェクトを生成しないといけないので、非常にめんどくさい。

こういう場合はSimpleXMLを使うと非常に分かりやすくなる。上のコードをSimpleXMLを使って書くとこんな感じ

$objDom = new DOMDocument();
$objDom->preserveWhiteSpace = false; //余分な空白を取り除く.
$objDom->load('sample.xml');

//SimpleXMLの方が扱いやすいので変換.
$objXml = simplexml_import_dom($objDom);
$sQuery = '/root/comment';
$objSelectNodes = $objXml->xpath($sQuery); //配列で返る.
echo $objSelectNodes[0];       //nodeValueへの参照.
echo $objSelectNodes[0]['id']; //id属性への参照.

ここまでのコード量は変わらない・・・けど、ここからさらにxpathで別エレメントをselectして記述していくと違いが分かってくる。SimpleXMLの場合はノードを連想配列で返してくれるので、nodeValueへの参照と属性への参照が直感的に扱えて分かりやすい。

ただXMLファイルを読み込むときはpreserveWhiteSpaceみたいなことができないみたいなので、DOMとSimpleXMLを組み合わせた方がよさそう。

2008年5月20日火曜日

【PHP】DOMを使ってXMLを操作(導入インストール編)

PHPでXMLを扱いときによく使われるのがDOM

気をつけないといけないのがPHP4とPHP5では使用するメソッド名がかなり違うので、システム構築する際は環境をちゃんと確認しないといけない。どっちでも動くように作り込むのはかなり大変そう・・・。参考

PHP4:DOM XML関数
$dom = domxml_open_file($xmlfilename);

PHP5:DOM Function
$dom = new DOMDocument;
$rtn = $dom->load($xmlfilename);

ちなみにインストールは簡単でPHP5の場合
# yum install php-xml
# service httpd reload
で終了。

phpinfoで確認するとDOMの項目が表示されている。

JavascriptでDOMを使ったことがあるなら、PHP5のメソッドは見慣れたものばかりなのでプログラムは(比較的)作りやすい。
なぜならPHP5で標準DOMインターフェイスに対応したから。参考
でもXpathを使った記述方法は、JavaScriptに比べめんどくさい。その辺はSimpleXMLと組み合わせて使うと幸せになれる。
これについてはまた後日書きます。
PHP4で作りたいときはここのマニュアルを参考に。
PHP5はこっち

XMLを読み込むサンプルコード

$objDom = new DOMDocument(); 
$objDom->preserveWhiteSpace = false; //余分な空白を取り除く. 
if ($objDom->load('sample.xml')) {
     return $objDom;
}
 else {
     return null; 
}

preserveWhiteSpaceはインデント部分の余分な空白を取り除いてくれるので、空白で悩まされなくていい。ファイルに書き出すときのサンプルコード

$objDom = new DOMDocument();
$objDom->encoding = 'UTF-8';   //文字化け対策.
$objDom->formatOutput = true;  //字下げや空白を考慮してきれいに整形した出力を行う。.
$objRoot = $objDom->appendChild( $objDom->createElement('root') );
$objComment = $objRoot->appendChild( $objDom->createElement('comment') ); 
$objComment->appendChild( $objDom->createCDATASection('CDATAセクション') );
$objDom->save('sample.xml');

できるXMLはこんな感じ↓ image

2008年5月19日月曜日

【PHP】YouTubeの新APIを使って動画をアップロードする

YouTubeの新しくなったAPIを調査中。2008/3/13のニュース記事

Googleが公開しているドキュメントに従ってサンプルコードを流用して書いていけばとりあえず動画の投稿はできた。

まずはここからZend Frameworkをダウンロードしてくる。現在の最新は1.5.2。使うのはlibrary/Zend以下のファイル群。実際に動かすときには、このlibraryにパスが通っている必要がある。こういう方法とか

開発中の最新バージョンがほしい場合はここを参考にsubversionクライアントを使って取得する。私の場合はこれで取得。

次にYouTube APIで必要な開発コードを取得する。ここから。

YouTubeでアカウントを登録してない場合は登録する。

とりあえずAPIを使って投稿したいだけならば、ここにZendが作ったサンプルコードが置いてあるので、これを使うだけでも動作確認はできる。

しかし、このコードだとユーザが自分のアカウントを入力しないといけない。実現したかったのは共通のアカウントを使っての動画投稿(いちいちアカウントを入力しない)。

以下、実際のコードです。これを実行するとファイルを参照するフォームが表示されるので、ファイル選択後→uploadボタンクリックで投稿できるはず。とりあえずはここまで。

<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_YouTube');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');

$sDeveloperKey = 'AI39...'; //YouTubeAPIの開発コード
$sAccount = 'account'; //YouTubeアカウント名
$sPassword = 'password'; //YouTubeログインパスワード

$sMovieTitle = 'My Test Movie'; //アップロードする動画のタイトル
$sDescription = 'My description'; //動画の説明文
$sTags = 'cars, funny'; //タグ
$sNextUrl = 'http://test.net/test.php'; //アップロード後に遷移する画面

$authenticationURL= 'https://www.google.com/youtube/accounts/ClientLogin';
$httpClient = Zend_Gdata_ClientLogin::getHttpClient(
    $username = $sAccount,
    $password = $sPassword,
    $service = 'youtube',
    $client = null,
    $source = 'gwiki', // a short string identifying your application
    $loginToken = null,
    $loginCaptcha = null,
    $authenticationURL);
$httpClient->setHeaders('X-GData-Key', "key=${sDeveloperKey}");
$yt = new Zend_Gdata_YouTube($httpClient);
// create a Zend_Gdata_YouTube_VideoEntry
$myVideoEntry= new Zend_Gdata_YouTube_VideoEntry();

// set up media group as in the example above
$mediaGroup = $yt->newMediaGroup();
$mediaGroup->title = $yt->newMediaTitle()->setText($sMovieTitle);
$mediaGroup->description = $yt->newMediaDescription()->setText($sDescription);

// note the different schemes for categories and developer tags
$categoryScheme = 'http://gdata.youtube.com/schemas/2007/categories.cat';
$developerTagScheme = 'http://gdata.youtube.com/schemas/2007/developertags.cat';

$mediaGroup->category = array( 
    $yt->newMediaCategory()->setText('Autos')->setScheme($categoryScheme),
    $yt->newMediaCategory()->setText('mydevelopertag')->setScheme($developerTagScheme),
    $yt->newMediaCategory()->setText('anotherdevelopertag')->setScheme($developerTagScheme)
    );

// set keywords, please note that they cannot contain white-space
$mediaGroup->keywords = $yt->newMediaKeywords()->setText($sTags);
$myVideoEntry->mediaGroup = $mediaGroup;

$tokenHandlerUrl = 'http://gdata.youtube.com/action/GetUploadToken';
$tokenArray = $yt->getFormUploadToken($myVideoEntry, $tokenHandlerUrl);
$tokenValue = $tokenArray['token'];
$postUrl = $tokenArray['url'];

// place to redirect user after upload
$nextUrl = $sNextUrl;

// build the form
$form = '<form action="'. $postUrl .'?nexturl='. $nextUrl .
        '" method="post" enctype="multipart/form-data">'.
        '<input name="file" type="file"/>'.
        '<input name="token" type="hidden" value="'. $tokenValue .'"/>'.
        '<input value="Upload Video File" type="submit" />'.
        '</form>';

echo $form;
?>

2008年5月16日金曜日

VisualSourceSafe(VSS)での改行コード問題

バージョン管理システムにVSSを使っていて、linux用のシステム開発をしていると改行コードがおかしくなっていることに気付くことがあります。改行コード「LF」で作成したファイルをチェックインしてチェックアウトすると「CR+LF」なっている・・・。

エディタによっては気付かないことも多いですが、秀丸とかは賢いので「LF」と「CR+LF」が混じっている環境でも、それなりに表示してくれるらしいです。私の使っているxyzzyだと「^M」でおかしいところを表示してくれるので気付きました。

どうやら日本語(2byte文字)の直後の改行コードがおかしくなるみたいなので、日本語で終わる行は「.」(ドット)を追記して改行するルールで開発しているところもあるみたいです。

改行コードが混在しているのは気持ち悪いですが、システム的には問題なく動作するようです。ここの人も愚痴っていた。

バージョン管理システムはSubversionの方がよいかもね。Visual Studioと連携できるし。ここ

ちなみにCRは「Carriage Return : 行頭復帰」。LFは「Line Feed : 改行」の略。参考

2008年5月15日木曜日

pgAdminで更新処理ができない!?

pgAdminでダミーのデータを挿入しようとテーブルを右クリック→データビューで開いてみると、あれれ・・・更新ができない。なんでだろーと思いましたが、ちゃんとpgAdminが教えてくれていました。

image

プライマリキーがないテーブルはpgAdminで更新できないみたいです。

2008年5月14日水曜日

PostgreSQLのロック(Lock)モード

ここでデータベースの行ロックとテーブルロックについて書きましたが、実際selectとかupdateのコマンドを送ったときにどういうロック状態になるか調べたのでメモ。

PostgreSQL(8.3.1)のみ。ここにあるのを表にしただけ。

注意点としては、これらのロックモードはテーブルレベルで保持しているため、例えばROW EXCLUSIVEモードは同じテーブルの別の行に対しては競合しないが、同じ行に対しての更新処理に関しては、後にモードを取得しようとしたコマンドが待たされる。

ロックモード 説明 競合するモード コマンド
ACCESS SHARE 最も制限の弱いロックモード ACCESS EXCLUSIVE SELECT
ROW SHARE 行単位に共有ロック EXCLUSIVE,
ACCESS EXCLUSIVE
SELECT FOR UPDATE
ROW EXCLUSIVE 行単位に排他ロック SHARE,
SHARE ROW EXCLUSIVE,
EXCLUSIVE,
ACCESS EXCLUSIVE
UPDATE,
DELETE,
INSERT
SHARE UPDATE EXCLUSIVE 同時実行されるスキーマの変更およびVACUUM コマンドの実行から、テーブルを保護 SHARE UPDATE EXCLUSIVE,
SHARE,
SHARE ROW EXCLUSIVE,
EXCLUSIVE、
ACCESS EXCLUSIVE
(FULLなしの)VACUUM
SHARE テーブル全体に共有ロック ROW EXCLUSIVE,
SHARE ROW EXCLUSIVE、EXCLUSIVE、
ACCESS EXCLUSIVE
CREATE INDEX
SHARE ROW EXCLUSIVE 同時1個のトランザクションのみ取得可能 ROW EXCLUSIVE、SHARE、
SHARE ROW EXCLUSIVE、EXCLUSIVE、
ACCESS EXCLUSIVE
 
EXCLUSIVE テーブル全体に排他ロック(selectのみ可能) ROW SHARE、
ROW EXCLUSIVE,
SHARE,
SHARE ROW EXCLUSIVE,
EXCLUSIVE,
ACCESS EXCLUSIVE
 
ACCESS EXCLUSIVE 最も制限の強いロックモード。同時に起こる全ての操作からロックしたテーブルを保 護 全てのモード ALTER TABLE, DROP TABLE, VACUUM

さらにロック処理やトランザクションについて知りたい場合は、ここの事務員の方の説明がわかりやすい。MVCCVACUUMについても例を交えて説明されているので、一度は読んどくといいかも。

2008年5月13日火曜日

データベースの行ロックとテーブルロック

Oracle, SQL server, PostgreSQL, MySQLなどのリレーショナルデータベースはロックという機能をサポートしていて、複数ユーザによる同じデータへのアクセスを保証しています。

ですが、各データベースでロックの仕組みは微妙な違いがあります。この辺の違いを理解していないとバッチ処理などで一つのトランザクションで大量のデータ更新を行う際に、はまりやすくなります。

↓表にしてみましたが、どれも基本行ロックで、明示的にテーブルロックにするなどのコマンドは用意されているので、ロック状態は任意に設定できます。

データベース ロック 備考
Oracle 行ロック どれだけロックが増えても行ロック。その分メモリを食う。参考
SQL Server 行ロック→テーブルロック
システムのリソースが少なくなると行ロックからテーブルロックに自動的に変更(ロックエスカレーション機能)。参考MSDN
SQL Server 2005 と Oracle 10g の真実
PostgreSQL 行ロック メモリ上に変更された行の情報を記憶しないので同時にロックできる行数に上限はない。ただしテーブルに書き込むため、定期的にVACUUMしてあげないといけない。
8.3では自動でVACUUMしてくれるらしい。wikipedia
MySQL MyISAM:テーブルロック
InnoDB:行ロックとテーブルロック
MyISAMとInnoDB
詳細はこちら

行ロックの利点と欠点がMySQLのサイトにあったのでメモ

ほとんどの場合ロックを気にしなくても大丈夫ですが、IDの採番はちゃんとロックしないと重複したIDとなる場合がありえる(めったない)。

ちゃんとロックしないと駄目でしたー
とか
この処理のおかげで他の処理はみんなタイムアウト!
というのは運用後に発覚する場合がほとんどなので、はまると痛い。

2008年5月12日月曜日

【Linux】ログイン認証にLdapを設定する

ネットワーク内にLDAPサーバがあるなら、ユーザ認証はそれを使った方が楽なので、LinuxでLDAPサーバを参照するためのメモ。

コマンドは
# authconfig
または
# authconfig-tui
でコマンドラインで設定できるツールが起動する。vineの場合はauthconfig、centosの場合はauthconfig-tuiだった。

image

↑のようにLDAPを使用するとLDAP認証を使用にチェックして次へ。

image

LDAPサーバのアドレスとベースDNを設定すれば完了。

再起動する必要はないので、logoutして誰かLDAPユーザでログインしてみる。

2008年5月10日土曜日

Linuxのディレクトリ構成

Linuxに外からソフトやドキュメントを持ってきたとき、どこのディレクトリに配置したらいいか迷うときがあります。なので、Linuxのディレクトリ構成についてのメモ。

ここを読めばまるっと解決。

Linuxのディレクトリ構成はFHS(Filesystem Hierarchy Standard)という名で定義されているらしい。↓ここから転載。

image

image

image

2008年5月9日金曜日

Xampp For Linux(Lampp)でサーバ構築と設定

Linuxでサーバを構築する際にapache, mysql, phpなどのいわゆる「LAMP」を個別にインストール設定してもよいですが、Xampp for Linuxを使うと有名なライブラリ(PEARやGDやmbstringなど)を一括でインストールしてくれるので便利です。

既にapacheがインストールされている場合は停止、削除しときましょう。

ダウンロード、インストールの仕方はここを参照。

ちなみに私はFirefoxでダウンロードしようとしたら途中で失敗してしまいました。(なぜ?)

動かすだけならとっても簡単。ただMySQLの管理者(root)にパスワードが設定してなかったり、FTPで外からアクセスできたりとセキュリティはざるになっているので、ファイヤーウォールの設定や各configファイルの設定は適切に行う必要があります。このブログに少し書いてあります。

セキュリティ関連の設定もそのうち書こうかな・・・

以下は起動時に自動で立ち上がるようにする設定です。

# cp /opt/lampp/lampp /etc/rc.d/init.d/
# chkconfig --add lampp

 

<2009/04/10 追記>
初期設定。まずは起動
# /etc/rc.d/init.d/lampp start

デフォルトでProFTPDは起動させない
# /etc/rc.d/init.d/lampp stopftp

デフォルトでSSLは使わない
# /etc/rc.d/init.d/lampp stopssl

デフォルトでmysqlは起動させない
# vi /etc/rc.d/init.d/lampp
startmysqlで検索してコメントアウト
# $0 startmysql %

apacheユーザを追加(ログインできないようにする)(home directoryも作らない)
# useradd -M -s /sbin/nologin apache

すでにapacheユーザがいるかどうかは
# less /etc/passwd
で確認。

グループは自動でapacheグループが作られる。
# less /etc/group
で確認。

/opt/lampp/etc/httpd.confのUserとGroupをnobodyからapacheに変更する。変更したら再起動。
# /etc/rc.d/init.d/lampp restart

apacheの起動ユーザを変えるとxamppのデフォルトページにアクセスできなくなるので、もしアクセスしたい場合は権限を設定。
# cd /opt/lampp/htdocs/xampp
# chown apache *.tmp

セキュリティのスクリプトを実行してセキュリティ強化
# /etc/rc.d/init.d/lampp security

XAMPP: Quick security check...
XAMPP: Your XAMPP pages are NOT secured by a password.
XAMPP: Do you want to set a password? [yes] (デフォルトページのパスワードを設定するか)
XAMPP: Password:
XAMPP: Password (again):
XAMPP: Password protection active. Please use 'lampp' as user name!
XAMPP: MySQL is accessable via network.
XAMPP: Normaly that's not recommended. Do you want me to turn it off? [yes] (MySQLへ外部ネットワークから遮断するか)
XAMPP: Turned off.
XAMPP: MySQL has to run before I can check the security.
XAMPP: MySQL has to run before I can check the security.
XAMPP: The FTP password for user 'nobody' is still set to 'lampp'.
XAMPP: (But you didn't use ProFTPD so this is not critical.)
XAMPP: Do you want to change the password? [yes] no (ProFTPDのnobodyユーザーのパスワードを変更するか)
XAMPP: Done.

この辺は適宜設定。

 

<2011/04/07 追加>
useraddのcommandにhome directoryを作成しないoptionを追加。

2008年5月8日木曜日

【CentOS】yumで追加パッケージ群DAG(RPMforge)を追加する

CentOSをデフォルトでインストールした状態だと、yumで検索するリポジトリには、多くの有名なソフトが登録されていません。たとえばffmpegとか。

そこで多くのサードパーティ製パッケージを供給しているDAG(RPMforge)をyumの検索するリポジトリに追加します。詳しく知りたい人はここで(英語)。

追加するのは簡単。下記コマンドを実行するだけ。CentOS5.i386の場合。最新バージョンはここを参照して確認。

rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm

実行すると/etc/yum.repos.d/に
rpmforge.repo
mirrors-rpmforge
が作成され、yum updateをやれば最新のリポジトリに更新される。


< 2012/04/10 Modified >
Installの方法は下記Siteが参考になる。

 

< Related Posts >

2008年5月7日水曜日

【PostgreSQL】CentOSでPostgreSQLを設定

以下yumでインストールした場合。

設定ファイルの場所は/var/lib/pgsql/data/pg_hba.conf

<ユーザの作成>
インストール直後はユーザ「postgres」がデータベースのスーパーユーザになっているのでpostgresに切り替えて作業
# su postgres

次のコマンドでユーザ「sa」を作成
# createuser --createdb --no-adduser --pwprompt sa
引数の意味はなんとなく分かると思うけど、ここに説明があります。

削除するときは
# dropuser sa

ユーザの一覧をみたいときは
# psql
postgres=# select * from pg_user;

ここまでできたらpgAdminを使って「sa」でログインし、リモートで管理した方が楽。手動でコマンドを書きたいときはここを参考に。

リモートで接続できない場合は、設定ファイルで許可してないか、ポートが開いていない。ファイヤーウォールの設定は
# system-config-securitylevel-tui
を使う。ここを参考に。
Other portsに5432:tcpと記述すればOK.
設定後、同じコマンドで見てみると↓のように設定されている。

image

<2008/5/24 追記>
インストールした直後では外部から接続できないようにPostgreSQLが設定されている場合があるので、ここを参考に /var/lib/pgsql/data/postgresql.conf のlisten_addresses='*'にする。

あとクライアントの認証方法が/var/lib/pgsql/data/pg_hba.confに記述されているので、外からはユーザ名とパスワードを使って認証するので下記のように設定する。

host all all 192.168.0.0/24 md5

これは192.168.0.0~192.168.0.255までパスワードを使ってのログインを許可する設定。IPアドレスの表記法についてはwikipediaで。

2008年5月2日金曜日

【PHP】XML-RPCを使ってサーバの機能を呼び出す

XML-RPCとはXMLを使った遠隔手順呼び出し(Remote Procedure Call)を行うためのプロトコル(取り決め)です。詳しくはWikipediaで。よく分からない人はここを読んだほうがいいです。

実際に試してみる方法ですが、Windows環境ならばXamppをインストールすればPEARのXML-RPCパッケージも同時にインストールされるので、手軽に試すことができます。

Linux環境の場合はPEARのXML-RPCパッケージがインストールしてあるか確認が必要です。

あとはここにあるサンプルコードを参考にすれば動作確認ができます。

ほとんど同じですが、私が書いたのも置いときます。クライアント側のソースにデバッグモードにするのと3秒でタイムアウトにする処理が入ってます。

●サーバ側(呼び出される側)のソース

<?php
require_once 'XML/RPC/Server.php';

$map = array("sample.sumAndDifference" => array("function" => "foo"));
$s = new XML_RPC_Server($map);

function foo ($params) {
    global $XML_RPC_erruser; // import user errcode value
    $p1 = $params->getParam(0);
    $p2 = $params->getParam(1);
    $v1 = $p1->scalarval();
    $v2 = $p2->scalarval();
    $value = new XML_RPC_Value($v1+$v2, "int");
    return new XML_RPC_Response($value);
}
?>

●クライアント側(呼び出し側)のソース

<html>
<head>
<title>XML-RPC PHP Demo</title>
</head>
<body>
<h1>XML-RPC PHP Demo</h1>
<textarea style="height:500px;width:500px;">
<?php
require_once 'XML/RPC.php';
$GLOBALS['XML_RPC_defencoding'] = "UTF-8";

//クライアントの作成
$c = new XML_RPC_client( '/xmlrpc/xmlrpc_srv.php', 'localhost', 80 );
$c->setDebug(1);
//メッセージ作成
$params = array(new XML_RPC_Value( 5, 'int' ), new XML_RPC_Value( 3, 'int' ));
$message = new XML_RPC_Message('sample.sumAndDifference',$params);

//メッセージ送信
$response = $c->send($message, 3);

// Process the response.
if (!$response->faultCode()) {
    $v = $response->value();
    print "Value: ". $v->scalarval() ."<br>";
    print "The XML received:<blockquote>" . $response->serialize();
    print "</blockquote>";
}else{
    print "Fault Code:   " . $response->faultCode()   . "<br>";
    print "Fault Reason: " . $response->faultString() . "<br>";
}

?>
</textarea>
</body></html>

ちょっとはまったのは、クライアント側でサーバ側のリソースを指定するときに頭にスラッシュをつけないと、「400 Bad Request」で返ってくる。404ではないので、記述方法が違うのかとか、Apacheの設定が違うのかとか別の方に走ってしまった。

動作環境:Xampp 1.6.6a

2008年5月1日木曜日

【PHP】Docblockコメントの書き方

Docblockとは/**と*/で囲まれたドキュメント用のコメントブロックです。これを規約に従って記述すると、みんなが読みやすく、phpDocumentorなどで自動ドキュメント生成もできます。

サンプルはPEAR(ペア)のコーディング規約を参考に。

ここが詳しく説明されています。英語が大丈夫ならここ

(// {{{ および // }}} ) って折り畳みマーカだったのね。

Related Posts Plugin for WordPress, Blogger...

Blog Archives