VS2010で作ったバイナリはWinXPSP1以下では動かない

http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+201011/10110008.txt

http://www.ailight.jp/Blog/sha256/archive/2011/4/22/%E5%90%84VC%E4%BB%98%E5%B1%9E%E3%81%AECRT%E3%81%AEOS%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E7%8A%B6%E6%B3%81%20-%20Visual%20C

各VC付属のCRTのOSサポート状況をとりまとめました。

■Visual Studio .NET 2003
Windows 98, Windows Me,
Windows NT, Windows 2000, and Windows XP

■Visual Studio 2005
Windows 98, Windows Me,
Windows NT, Windows 2000, Windows XP, and Windows Server 2003

■Visual Studio 2008
Windows 9x のサポートを廃止
Windows 2000, Windows XP, Windows Server 2003, and Windows Vista

■Visual Studio 2010
Windows XP with SP2, Windows XP with SP3, Windows Server 2003 with SP1, Windows Server 2003 with SP2, Windows Vista, Windows Server 2008, and Windows 7

http://www9.plala.or.jp/oga/vs2010.html

最終更新時刻: 2011年05月02日

プログラミング用フォント Ricty

見やすそう。まだ使ってない。

プログラミング用フォント Ricty

http://save.sys.t.u-tokyo.ac.jp/~yusa/fonts/ricty.html

追記:

Windowsのアンチエイリアシング(ClearType)と相性が良くないらしく、あまりキレイにアンチエイリアスされない。気になるレベル。gdippとか入れれば良いらしいが試してない。

最終更新時刻: 2011年05月06日


PostgreSQL 9.0.3をインストール

CentOS 5.6(on さくらVPS)にPostgreSQL 9.0.3をインストールした。

# tar xvfz postgresql-9.0.3.tar.gz
# cd postgresql-9.0.3
# ./configure

起動スクリプトをコピーする。

# cp contrib/start-scripts/linux /etc/init.d/postgresql

起動スクリプトを書き換える。

#PGDATA="/usr/local/pgsql/data"
PGDATA="/var/pgsql/data"

起動スクリプトに実行権限をつけて自動起動するように登録する。

# chmod 755 /etc/init.d/postgresql
# chkconfig --add postgresql

起動ユーザ/グループを作成する。

# groupadd postgres
# useradd -g postgres -d /var/pgsql postgres

postgresユーザでデータベースを初期化する。

# su - postgres
$ mkdir /var/pgsql/data
$ /usr/local/pgsql/bin/initdb -D /var/pgsql/data -E UNICODE --no-locale

ここまででサービスの起動が可能となるため、rootユーザで起動させてみる。

# /etc/init.d/postgresql start

再度postgresユーザに変更。.bash_profileに環境変数の初期化処理を追記する。

export PATH="$PATH":/usr/local/pgsql/bin
export POSTGRES_HOME=/usr/local/pgsql
export PGLIB=$POSTGRES_HOME/lib
export PGDATA=/var/pgsql/data
export MANPATH="$MANPATH":$POSTGRES_HOME/man
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"$PGLIB"

確認を実施する。

$ psql -l
                              List of databases
   Name    |  Owner   | Encoding | Collation | Ctype |   Access privileges
-----------+----------+----------+-----------+-------+-----------------------
 postgres  | postgres | UTF8     | C         | C     |
 template0 | postgres | UTF8     | C         | C     | =c/postgres          +
           |          |          |           |       | postgres=CTc/postgres
 template1 | postgres | UTF8     | C         | C     | =c/postgres          +
           |          |          |           |       | postgres=CTc/postgres
(3 rows)

以上で完了。

最終更新時刻: 2011年05月06日

Twitterの公式リンクボタン

Twitterの公式リンクボタン

https://twitter.com/goodies/buttons#

最終更新時刻: 2011年05月06日

今回のブログへの移行で実現したかったこと

  • 各記事毎のコンテンツ化

コンテンツ化とざっくり括ったが以前の日記で実現できていなかったのは下記2点。

  1. バージョン管理
  2. 記事毎の固有のURL

上記のうち「記事毎のURL」についてはBlogKitで実現できた。

残るバージョン管理についてはプラグインでなんとかする予定。

最終更新時刻: 2011年05月06日

デザインセンスが良いブログ

随時更新予定。

以下、tDiary

最終更新時刻: 2011年05月16日

このブログのTODO

未完了

  • 画像アップロード(別システムで構築)
  • コメントシステムの導入

完了

  • タイトルが全文検索に含まれない。
    • estraier-register.rbの改修
  • バージョン管理
    • バックエンドにGitを用いたプラグインを試験運用開始(2011/05/13)
最終更新時刻: 2011年09月16日

dddavをVS2010でコンパイル

dddavのプロジェクト(当初は確かVC++6.0で作成)をVisualStudio2010でコンパイルしようとしたところ下記エラーが発生してコンパイルできなかった。

c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\atlcore.h(35): fatal error C1189: #error :  This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended.

対処法としては下記をstdafx.hに書き加えて完了。

#define WINVER 0x0500
#define _WIN32_WINNT 0x0500

上記ではWindows2000 OSを対象としてるんだけど実際はWindowsXP OS以降でしか動作しないので、0x0501でもいいのかもしれない。

ソース:

http://msdn.microsoft.com/ja-jp/library/6sehtctf.aspx

最終更新時刻: 2011年05月09日

IP Messengerで通信できない件

ipmsgがたまに通信できなくなる(メンバーが見えなくなる、メッセージが送信/受信できない)件。

複数NIC(仮想化ソフト等のインストールにより)で発生する可能性あり。

最近のバージョンではNIC指定ができるからそれで解決できるかも。

http://blog.kumacchi.com/2007/09/vmwareplayeripmsg.html

ここ数年使って、自分や自分の周りで発生してたけどコレが原因っぽい。

最終更新時刻: 2011年05月09日

ツイートするかブログに書くかの基準

書き捨てるものはTwitter、残したいものはブログ。

リアルタイム性が求められるか否か、は近いけど違う。

そもそもリアルタイムに不特定多数に発信したいことがない。

最終更新時刻: 2011年05月09日

dddav 0.0.17.0をリリースした

http://www.mylab.jp/program/dddav/

約1年ぶりにリリース。

開発環境をVC++8.0からVC++10に移行して一個バグつぶし。

0.0.17.0(2011-05-10)

* 不具合修正
** 接続できないサイトに接続しようとした場合にプロセスが終了できない不具合を修正
* 仕様変更
** 動作環境がWindows XP SP2以降になりました。開発環境をVisual Studio 2010にしたためです。

開発環境が変わったので動作環境からWindows XPSP2未満が外れてしまった。 (Win98/Win2000/WinXPSP1など)

最終更新時刻: 2011年05月14日

linuxでUTF8が文字化け

bash_profileに下記を加えておく。毎回のことなので覚書。

export LANG="ja_JP.UTF-8"

で、.bash_profileを反映させる。

$ . ~/.bash_profile
最終更新時刻: 2011年05月13日

msysgit+BASIC認証の不具合と回避策

msysgitでBASIC認証を使ったページからcloneしようとすると途中でBASIC認証が効かなくなってcloneできなかった。

LinuxのGitクライアントからは問題なくcloneできる。

使用したバージョンは下記。

Git-1.7.4-preview20110204.exe
msysGit-fullinstall-1.7.4-preview20110204.exe

その時のエラーメッセージは下記。(URLは例)

error: The requested URL returned error: 401 (curl_result = 22, http_code = 401,
 sha1 = 3f00ca6fd69c2fe3fff8fefe8c46c8d8c2379b89)
error: Unable to find 3f00ca6fd69c2fe3fff8fefe8c46c8d8c2379b89 under http://dav.example.com/exsample.git
Cannot obtain needed commit 3f00ca6fd69c2fe3fff8fefe8c46c8d8c2379b89
while processing commit a250db46bf02c5a27a73ac01e629f69d1f8d9d28.
error: Fetch failed.

Webサーバ側のログを見ると、最初はBASIC認証使っているのに、途中からなぜか認証せずにアクセスしようとして取得に失敗している。

回避策はURLにBASIC認証のユーザ名を含めてあげること。(URLは例)

http://ユーザ名@dav.example.com/example.com
最終更新時刻: 2011年05月16日

PHP用の最薄DBアクセスクラス作った

PHPのDBアクセスクラス(PostgreSQL用)を書いた。

コンセプトは「薄い」ラッパークラスであること。

ちなみに目的は未だにPEAR DBを使ってたサイトの改修。

最薄のラッパーを書こうとすると自然にこうなる。逆にこれ以上をやるならMDB2とかADOdbとかPDO使えばいいと思われ。

なぜ車輪の再開発したかというと

  • DBアクセスの抽象化はしておきたかった
  • レンサバだとPDO使えない可能性がある
  • (動作が)軽い
  • (容量が)軽い
  • ファイル数を増やさずに済む。この1ファイルだけ。

使い方

<?php

require_once 'database.php';

$db = new Database
$res = $db->connect('host=db.example.com dbname=hoge user=hoge password=******');
if($res === false){
  echo 'db connect error!';
  exit;
}

// プリペアドクエリの場合
$res = $db->execute('SELECT * FROM people WHERE name=$1', array('hajime'));
// プリペアドクエリじゃない場合
// $res = $db->query("SELECT * FROM people WHERE name='hajime'");
if($res === false){
  echo 'query error!';
  exit;
}

while(($data = $db->fetch()) !== false){
  print_r($data);
}

クラスのソース

<?php

class Database
{
    private $_handle = null;
    private $_resource = null;

    function connect($connection_string)
    {
        $this->_resource = null;
        $this->_handle = @pg_connect($connection_string);
        if($this->_handle === false){
            $this->_handle = NULL;
            return false;
        }

        return true;
    }

    function query($sql)
    {
        $this->_resource = null;
        $res = @pg_query($this->_handle, $sql);
        if($res === false){
            return false;
        }

        $this->_resource = $res;

        return true;
    }

    function execute($sql, $params = array())
    {
        $this->_resource = null;
        $res = @pg_prepare($this->_handle, '', $sql);
        if(!$res){
            return false;
        }

        $res = @pg_execute($this->_handle, '', $params);
        if($res === false){
            return false;
        }

        $this->_resource = $res;

        return true;
    }

    function fetch()
    {
        return @pg_fetch_assoc($this->_resource);
    }

    function getOne($sql, $params = array())
    {
        $res = $this->execute($sql, $params);
        if($res === false){
            return false;
        }

        foreach($this->fetch() as $v){
            return $v;
        }

        return false;
    }

    function getRow($sql, $params = array())
    {
        $res = $this->execute($sql, $params);
        if($res === false){
            return false;
        }

        return $this->fetch();
    }

    function affectedRows()
    {
        return @pg_affected_rows($this->_resource);
    }

    function getLastError()
    {
        return @pg_last_error($this->_resource);
    }
}
最終更新時刻: 2011年05月17日

文章の書き方

文章力とか日本語に関するサイト。

どちらもIIJの山本和彦さんによるもの。

最終更新時刻: 2011年05月23日

iPhoneのツイッタークライアントを「SOICHA/j」に乗り換えた

iPhoneのツイッタークライアントを「SOICHA/j」に乗り換えた。

今までは「hootsuite for iPhone」だった。

特に不満があったから変えたわけではなく、SOICHAのUIのほうが好みだった。

SOICHA/j for Twitter

画像の説明

最終更新時刻: 2011年05月24日

ActiveDirectoryのパスワードでBASIC認証させる

ActiveDirectoryのパスワードでBASIC認証させるApache設定の覚書。

ApacheのLDAP認証モジュールを使用する。

Apacheのコンパイル時に下記のようにオプションを付ける。多いな。全部必要じゃないかも。

./configure --with-ldap --enable-ldap --enable-authnz-ldap --with-ldap-include=/usr/include --with-ldap-lib=/usr/lib/

.htaccessやhttpd.confに下記のように記述。

AuthType Basic
AuthName "ActiveDirectory Auth"
AuthBasicProvider ldap
AuthLDAPURL "ldap://ad1.domain.example.com:389 ad2.domain.example.com:389/OU=hoge,DC=domain,DC=example,DC=com?sAMAccountName?sub?(objectClass=*)"
AuthLDAPBindDN "domain\apache"
AuthLDAPBindPassword "********"
AuthzLDAPAuthoritative Off
Require ldap-group CN=groupname,OU=groups,DC=domain,DC=example,DC=com
# require ldap-user "miyauchi"

以下の点は自分の環境に合わせる

  • ActiveDirectoryに認証用のユーザ(上記例ではapache)を作っておく。
  • ドメイン名はdomainと仮定。
  • 認証サーバがad1.domain.example.com、ad2.domain.example.comの2台あると仮定。
  • groupnameグループに属するユーザを許可している。

上記はApache2.2の場合。2.0以前とは異なる点があるので注意。

上記の例だと2.0ではldap-groupではなくgroupを使う。AuthBasicProviderディレクティブが不要。

LDAP認証を使う場合、Kerberos認証使った自動ログオンほど利便性はない。

その代わりに対応しないブラウザでも使えるというメリットがある。

最終更新時刻: 2011年05月26日

tDiaryの日記データをGitに登録するプラグイン

tDiaryのデータを日別でGitに登録するプラグインを作った。

使い方

  1. プラグインディレクトリ(例: plugin)にgit-register.rbを設置。
  2. プラグインディレクトリにja/git-register.rb、en/git-register.rbを設置。
  3. tdiary.confにリポジトリを指定(リポジトリの場所を/var/git-respoと仮定)
    1. @options["git.repository_dir"] = "/var/git-repos"
  4. リポジトリを作成(Apacheの起動ユーザをapacheと仮定)
    1. mkdir /var/git-repos
    2. cd /var/git-repos
    3. git init
    4. git config user.name "自分の名前"
    5. git config user.email "メールアドレス"
    6. chown apache.apache -R /var/git-repos
  5. リポジトリに一括commit(tDiaryのインストールディレクトリを/var/www/tdiaryと仮定)
    1. cd /var/www/tdiary
    2. ruby --encoding=UTF-8 git-register.rb

できること

  • 今までの日記データを一括commit
  • 日記更新毎にgitにcommit

残念ながら今のところ履歴表示機能はない。誰か作って下さい。

後、BlogKitでしかテストしてません。

git-register.rbの中身は下記。

#!/usr/bin/env ruby
# git-register.rb
#
# Copyright (C) 2011 hajime miyauchi <hajime.miyauchi@gmail.com>
# You can redistribute it and/or modify it under GPL2.
#

mode = ""
if $0 == __FILE__
        require 'cgi'
        ARGV << '' # dummy argument against cgi.rb offline mode.
        @cgi = CGI::new
        mode = "CMD"
else
        mode = "PLUGIN"
end

if mode == "PLUGIN"
	add_body_leave_proc do |date|
	end
end

unless $tdiary_git_register_loaded
$tdiary_git_register_loaded ||= true

if mode == "CMD"
	tdiary_path = "."
	tdiary_conf = "."
	$stdout.sync = true

	def usage
		puts "git-register.rb"
		puts " register to git index files from tDiary's database."
		puts " usage: ruby --encoding=UTF-8 git-register.rb [-p <tDiary directory>] [-c <tdiary.conf directory>]"
		exit
	end

	require 'getoptlong'
	parser = GetoptLong::new
	parser.set_options(['--path', '-p', GetoptLong::REQUIRED_ARGUMENT], ['--conf', '-c', GetoptLong::REQUIRED_ARGUMENT])
	begin
		parser.each do |opt, arg|
			case opt
			when '--path'
				tdiary_path = arg
			when '--conf'
				tdiary_conf = arg
			end
		end
	rescue
		usage
		exit( 1 )
	end

	tdiary_conf = tdiary_path unless tdiary_conf
	Dir::chdir( tdiary_conf )

	begin
		$:.unshift tdiary_path
		require "#{tdiary_path}/tdiary"
	rescue LoadError
		$stderr.puts "git-register.rb: cannot load tdiary.rb. <#{tdiary_path}/tdiary>\n"
		$stderr.puts " usage: ruby --encoding=UTF-8 git-register.rb [-p <tDiary directory>] [-c <tdiary.conf directory>]"
		exit( 1 )
	end
end

module ::TDiary
	#
	# Register
	#
	class GitRegister < TDiaryBase
		def initialize(repository_dir, diary)
			@repository_dir = repository_dir
			@diary = diary
			@date = diary.date
		end

		def execute()
			dir = @date.strftime("#{@repository_dir}%Y%m/")
			Dir::mkdir( dir ) unless FileTest::directory?( dir )

			td2_file = @date.strftime("#{dir}%Y%m%d.td2")
			fh = File::open(td2_file, 'w')

			fh.puts( "Date: #{@date}" )
			fh.puts( "Title: #{@diary.title}" )
			fh.puts( "Last-Modified: #{@diary.last_modified.to_i}" )
			fh.puts( "Visible: #{@diary.visible? ? 'true' : 'false'}" )
			fh.puts( "Format: #{@diary.style}" )
			fh.puts
			fh.puts( @diary.to_src.gsub( /\r/, '' ).gsub( /\n\./, "\n.." ) )

			fh.close

			# commit
			require 'shellwords'

			msg = "#{ENV['REMOTE_ADDR']} - #{ENV['REMOTE_HOST']}"

			Dir.chdir("#{@repository_dir}") do
				td2_file2 = @date.strftime("%Y%m/%Y%m%d.td2")
				system("git add -- #{Shellwords.shellescape(td2_file2)}".untaint)
				system("git commit -q -m \"#{msg}\" -- #{Shellwords.shellescape(td2_file2)}".untaint)
			end
		end

		protected

		def mode; 'day'; end
		def cookie_name; ''; end
		def cookie_mail; ''; end

		def convert(str)
			str
		end
	end

	#
	# Main
	#
	class GitRegisterMain < TDiaryBase
		def initialize(conf)
			super(CGI::new, 'day.rhtml', conf)
		end

		def execute(out = $stdout)
			require 'fileutils'
			repository_dir = @conf['git.repository_dir']
			calendar
			@years.keys.sort.reverse_each do |year|
				out << "(#{year.to_s}/) "
				@years[year.to_s].sort.reverse_each do |month|
					@io.transaction(Time::local(year.to_i, month.to_i)) do |diaries|
						diaries.sort.reverse_each do |day, diary|
							out << diary.date.strftime('%m%d ')
							GitRegister.new(repository_dir, diary).execute
						end
						false
					end
				end
			end
		end
	end
end

if mode == "CMD"
	begin
		require 'cgi'
		if TDiary::Config.instance_method(:initialize).arity > 0
			# for tDiary 2.1 or later
			cgi = CGI.new
			conf = TDiary::Config::new(cgi)
		else
			# for tDiary 2.0 or earlier
			conf = TDiary::Config::new
		end
		conf.header = ''
		conf.footer = ''
		conf.show_comment = true
		conf.hide_comment_form = true
		conf.show_nyear = false
		def conf.bot?; true; end
		TDiary::GitRegisterMain.new(conf).execute
	rescue
		print $!, "\n"
		$@.each do |v|
			print v, "\n"
		end
		exit( 1 )
	end

	puts
else
	add_update_proc do
		conf = @conf.clone
		conf.header = ''
		conf.footer = ''
		conf.show_comment = true
		conf.hide_comment_form = true
		conf.show_nyear = false
		def conf.bot?; true; end

		repository_dir = @conf['git.repository_dir']
		diary = @diaries[@date.strftime('%Y%m%d')]

		TDiary::GitRegister.new(repository_dir, diary).execute
	end

	if !@conf['git.hideconf'] && (@mode == 'conf' || @mode == 'saveconf')
		args = ['git_register', @git_register_conf_label]
		args << 'update' if TDIARY_VERSION > '2.1.3'
		add_conf_proc(*args) do
			str = <<-HTML
<h3 class="subtitle">#{@git_register_conf_header}</h3>
<p>
<label for="git_register_rebuild"><input id="git_register_rebuild" type="checkbox" name="git_register_rebuild" value="1">
#{@git_register_conf_description}</label>
</p>
HTML
			if @mode == 'saveconf'
				if @cgi.valid?( 'git_register_rebuild' )
					str << '<p>The following diaries were registered.</p>'
					out = ''
					TDiary::GitRegisterMain.new(@conf).execute(out)
					str << "<p>#{out}</p>"
				end
			end
			str
		end
	end
end

end # $tdiary_git_register_loaded

# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End:

en/git-register.rbの中身

@estraier_register_conf_label = 'Git'
@estraier_register_conf_header = 'commit all'
@estraier_register_conf_description = 'To commit all, check the box and submit \'OK\'.'

ja/git-register.rbの中身

@git_register_conf_label = 'Git'
@git_register_conf_header = 'Gitへ再登録'
@git_register_conf_description = 'Gitへ再登録する場合はOKを押してください'
最終更新時刻: 2012年08月31日