Oct 30, 2007

[Misc] CAPTCHA の安全性についてメモ

CAPTCHA の安全性が話題になっているみたいなのでメモ。

凪瀬 Blog - はてなのCAPTCHAは簡単に破れる
http://blogs.wankuma.com/nagise/archive/2007/10/26/104428.aspx
Radium Software Development - Breaking CAPTCHAs with NNs
http://www.radiumsoftware.com/0611.html#061110
高木浩光@自宅の日記 - 飾りじゃないのよCAPTCHAは 〜前代未聞のCAPTCHAもどき
http://takagi-hiromitsu.jp/diary/20060810.html#p01
Wikipedia - CAPTCHA
http://ja.wikipedia.org/wiki/CAPTCHA

より安全な CAPTCHA とは?

はてなの CAPTCHA が問題視されているわけだが、「では一体どういう CAPTCHA がより安全なのだろう?」 という疑問が当然出てくる。
Breaking CAPTCHAs with NNsによると、

CAPTCHA 破りの工程は,画像から文字を1文字づつ切り出す「分割」 (segmentation) の段階と, 切り出した文字を1文字ごとに解析する「認識」 (recognition) の段階から構成されるが, このうちコンピュータにとって困難なのは「分割」の方であり,「認識」は比較的容易であるとされる。
Kumar らの研究の結果は,文字による視覚 CAPCHA に関して, 文字毎の「認識」を困難にさせることを意図した歪みやノイズには全く意味が無く, そのような労力は文字の「分割」を困難にさせる方へと注がれることが望ましいという結論を導き出している。
ということで、「分割」し難い CAPTCHA が安全であるという研究結果が発表されているそうだ。 その研究結果を直接参照してみると、何故「分割」がコンピュータにとって難しいのかが説明されている。
4.1 The segmentation problem
As a review, segmentation is difficult for the following reasons:
  1. Segmentation is computationally expensive. In order to find valid patterns, a recognizer must attempt recognition at many different candidate locations.
  2. The segmentation function is complex. To segment successfully, the system must learn to identify which patterns are valid among the set of all possible valid and non-valid patterns. This task is intrinsically more difficult than classification because the space of input is considerably larger. Unlike the space of valid patterns, the space of non-valid patterns is typically too vast to sample. This is a problem for many learning algorithms which yield too many false positives when presented non-valid patterns.
  3. Identifying valid characters among a set of valid and invalid candidates is a combinatorial problem. For example, correctly identifying which 8 characters among 20 candidates (assuming 12 false positives), has a 1 in 125,970 (20 choose 8) chances of success by random guessing.
より安全な CAPTCHA が具体的にどういうものかというと、同じ論文内では以下の様に提案されている。
4.2 Building better/harder HIPs
The idea is that the additional arcs are themselves good candidates for false characters. The previous segmentation attacks would fail on this HIP. Furthermore, simple change of fonts, distortions, or arc types would require extensive work for the attacker to adjust to.
[stronger captcha]
この方式のより詳細な情報が Building Segmentation Based Humanfriendly Human Interaction Proofs (HIPs) に記載されている。
Using Machine Learning to Break Visual Human Interaction Proofs (HIPs)
http://research.microsoft.com/~kumarc/pubs/chellapilla_nips04.pdf
Building Segmentation Based Humanfriendly Human Interaction Proofs (HIPs)
http://research.microsoft.com/~kumarc/pubs/chellapilla_hip05.pdf

CAPTCHA の実装(Java)

Wikipedia の CAPTCHA によると、CAPTCHA の Java 実装は結構あるようだ。

The JCAPTCHA Project
http://jcaptcha.sourceforge.net/
The reCAPTCHA Project
http://www.crt.realtors.org/projects/reCaptcha/
The simple CAPTCHA Project
http://simplecaptcha.sourceforge.net/
この中でどれがより安全だろうか?? JCAPTCHA の DoubleRandomListGimpyEngineCaptcha が分割しにくいように見えるけれど・・・。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 26, 2007

[Merlin] J2SE 1.4.2 EOL プロセス開始

J2SE 1.4.2 EOL かい?? 早い! 早いよ!!

J2SE 1.4.2 は Sun のサポート終了 (End of Life, EOL) のプロセスを開始しました。 EOL 移行期間は 2006 年 12 月 11 日から次のバージョンである Java SE 7 の提供開始 (現時点では 2008 年 夏の予定) までです。この掲示をもってユーザの皆様は、 最新リリースである Java SE 6 への移行を開始する必要があります。

[J2SE 1.4.2 EOL announce]

Sun Develper Network - J2SE 1.4.2
http://java.sun.com/j2se/1.4.2/ja/
Java Technology EOL Policy
http://java.sun.com/products/archive/eol.policy.html
JPCERT/CC REPORT 2007-10-24 - 今週のひとくちメモ J2SE 1.4.2 のサポート終了
http://www.jpcert.or.jp/wr/2007/wr074101.html#Memo

Posted in Merlin | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 25, 2007

[Misc] NetCommons にチャレンジ

NetCommons とは

NetCommons というのは

このサイトは国立情報学研究所が次世代情報共有基盤システムとして開発したNetCommonsの公式サイトです。
NetCommonsはCMS(Contents Management System)とLMS(Learning Management System) とグループウェアを統合したコミュニティウェアです。NetCommonsによって簡単に構築できるサイトとして、 次のようなものが挙げられます。
  • e-ラーニングサイト
  • NPOやNGOのためのバーチャルオフィス
  • 共同研究・学会活動のポータルサイト兼グループウェア
  • オフィス用グループウェア
  • ソーシャルネットワークサービス
というものだそうだ。Xoops ベースで構築されているとのこと。 LMS のシステムは今まで触ったことが無かったので試してみた。
NetCommons
http://www.netcommons.org/

NetCommons のインストール

NetCommons には MySQL, PHP, Apache Web Server が必要。 それだけ揃えてしまえば、後は tar ball を拾ってきてインストーラを実行するだけ。 以下は Debian Etch 環境にインストールしたときのメモ。

環境の準備

MySQL 5, PHP5 をインストール。Apache Web Server は 2.x がインストール済みだったのでそのまま利用。

# apt-get install mysql-server-5.0 php5 php5-mysql libapache2-mod-php5
Reading package lists... Done
Building dependency tree... Done

# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.0.32-Debian_7etch1-log Debian etch distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database netcommons;
Query OK, 1 row affected (0.00 sec)

mysql> grant all on netcommons.* to netcommons identified by 'netcommons';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> exit       
Bye

# cp /etc/php5/apache2/php.ini /etc/php5/apache2/php.ini.original
# vi /etc/php5/apache2/php.ini
# diff /etc/php5/apache2/php.ini.original /etc/php5/apache2/php.ini
599c599
< ;extension=mysql.so
---
> extension=mysql.so

# /etc/init.d/apache2 restart
Forcing reload of web server (apache2)... waiting .

#

NetCommons の設置

NetCommons をダウンロードしてきて設置。 *.php ファイルが EUC-JP の CRLF になっていたので EUC-JP の LF に変換した。

# wget http://www.netcommons.org/modules/cabinet/downloadnum_add.php?
path=%2Fcabinet%2F3%2F%A5%B3%A5%A2%A5%D1%A5%C3%A5%B1%A1%BC%A5%B8%CD%
D1%2FNetCommons-1.1.2%2FNetCommons-1.1.2.tar.gz&file_id=1941
[1] 2621

# tar zxvf ./NetCommons-1.1.2.tar.gz 
./NetCommons-1.1.2/
./NetCommons-1.1.2/html/

# cd ./NetCommons-1.1.2
# cp -r ./html ./html.converted
# cd ./html
# for i in `find . -name '*.php'`; do nkf -Lu -e $i > ../html.converted/$i; done
# mv ./NetCommons-1.1.2/html.converted /var/www/netcommons
# chmod 777 -R /var/www/netcommons/uploads/ /var/www/netcommons/cache/ 
/var/www/netcommons/templates_c/ /var/www/netcommons/themes/

NetCommons のインストール

"http://example.com/netcommons/" にアクセスしてインストーラを起動する。

[NetCommons installer(0)] [NetCommons installer(1)] [NetCommons installer(2)]

NetCommons インストールの後片付け

インストーラの削除と設定ファイルの権限変更を行う。

# rm -rf /var/www/netcommons/install/
# chmod 444 /var/www/netcommons/mainfile.php 
# 

NetCommons にアクセス

"http://example.com/netcommons/" にアクセスする。 とりあえずインストール時に設定した管理者でログイン。 とりあえずは動いたが、何故か管理室に入ることが出来なかった。 NETCOMMONS_SYSTEM_PATH というグローバル変数(?) がセットされていないのだが・・・。 何故?? (面倒なので調べていないw)

[NetCommons Home]

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 24, 2007

[WebService] PlaceEngine API にチャレンジ

PlaceEngine とは

PlaceEngine は、Wi-Fi 機器を使って簡単に現在位置を推定してくれるソフトウェア。 以前 Mac OS X にインストールして放置してあったのだけれど、API があるということを知ったので早速試してみた。

PlaceEngine
http://www.placeengine.com/
PlaceEngine 技術資料
http://www.placeengine.com/doc
PlaceEngine API ローカルアプリケーションプログラミング
http://www.placeengine.com/doc/tutl

サンプルコード

サンプルコードは、PlaceEngine API ローカルアプリケーションプログラミングとほとんど同じ。 Mac OS X 版では LocalDB 機能(ローカルに位置情報を記録する機能) は使用できないということなので、PlaceEngine サーバに位置情報を問い合わせるサンプルだけ試してみた。

サンプルアプリを作成するためには、

  1. ここ から PlaceEngine クライアントをダウンロードし、インストールする。ここでは 2007/10/24 現在最新の o070531 を使用するものとする。 [PlaceEngine version]
  2. PlaceEngine を起動する。
  3. ここで PlaceEngine API アプリケーションキーを取得する。
の準備が必要。 PlaceEngine API は直接 PlaceEngine サーバに問い合わせるわけではなく、ローカルの PlaceEngine クライアントに問い合わせるものなので、PlaceEngine クライアントがローカルで起動していないと動作しない。

サンプルを動作させると PlaceEngine がセキュリティ警告ダイアログを表示する。 実行しても安全だと思う場合は YES をクリックする。
[PlaceEngine warning]

package jp.in_vitro.codelets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Codelet {

    private static final String KEY = "aNR3HYXx1jzYqw24...";
    private static final String URL_RTAGJS = "http://localhost:5448/rtagjs";
    private static final String URL_LOC = "http://www.placeengine.com/api/loc";
    private final long t;

    public Codelet() {
        super();

        System.setProperty("http.nonProxyHosts", "localhost");
        this.t = System.currentTimeMillis() / 1000;
    }

    public Loc getLoc() throws IOException {
        Rtag rtag = this.getRtag(t);

        if (rtag.getNumap() > 0) {
            String locRequest = URL_LOC + "?t=" + this.t + "&rtag="
                    + rtag.getRtag() + "&appk=" + KEY + "&fmt=json";
            StringBuilder locResponse = sendHttpRequest(new URL(locRequest));
            return parseLocResponse(locResponse);
        }
        return null;
    }

    protected Loc parseLocResponse(final StringBuilder response) {
        Loc location = new Loc();

        response.deleteCharAt(0);
        String responseAsString = new String(response);
        String param[] = responseAsString.split(",");
        String param2[] = responseAsString.split("\\{");

        if (param.length >= 4 && param2.length >= 2) {
            location.setLon(param[0]);
            location.setLat(param[1]);

            String info[] = param2[1].substring(0, param2[1].length() - 1)
                    .split(",");
            for (int i = 0; i < info.length; i++) {
                String tk[] = info[i].split(":");
                String name = tk[0].substring(1, tk[0].length() - 1);
                String value = tk[1];
                if ("addr".equals(name)) {
                    location.setAddr(value);
                } else if ("msg".equals(name)) {
                    location.setMsg(value);
                } else if ("floor".equals(name)) {
                    location.setFloor(value);
                } else if ("t".equals(name)) {
                    location.setT(value);
                }
            }
        }
        return location;
    }

    protected void printLoc(final Loc loc) {
        System.out.println("Longitude(経度) : " + loc.getLon());
        System.out.println("Latitude(緯度)  : " + loc.getLat());
        System.out.println("Address(住所)   : " + loc.getAddr());
        System.out.println("Floor          : " + loc.getFloor());
        System.out.println("Message        : " + loc.getMsg());
    }

    public Rtag getRtag(final long t) throws IOException {
        String rtagRequest = URL_RTAGJS + "?t=" + this.t + "&appk=" + KEY;
        StringBuilder rtagResponse = sendHttpRequest(new URL(rtagRequest));
        Rtag rtag = this.parseRtagResponse(rtagResponse);
        return rtag;
    }

    protected Rtag parseRtagResponse(final StringBuilder response) {
        Rtag rtag = new Rtag();

        String splitRtagjsResponse[] = response.substring(9,
                response.length() - 2).split(", *");
        String r = splitRtagjsResponse[0].substring(1, splitRtagjsResponse[0]
                .length() - 1);
        int numap = Integer.parseInt(splitRtagjsResponse[1]);
        String t = splitRtagjsResponse[2];

        rtag.setRtag(r);
        rtag.setNumap(numap);
        rtag.setT(t);

        return rtag;
    }

    protected StringBuilder sendHttpRequest(final URL url) throws IOException {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        try {
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            reader = new BufferedReader(new InputStreamReader(connection
                    .getInputStream(), "UTF-8"));
            StringBuilder response = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            return response;
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    }

    public static void main(final String[] args) throws Exception {
        Codelet me = new Codelet();
        Loc loc = me.getLoc();
        me.printLoc(loc);
    }

    public static class Rtag {

        private String rtag;
        private int numap;
        private String t;

        public Rtag() {
            super();
        }
        public String getRtag() {
            return this.rtag;
        }
        public void setRtag(final String rtag) {
            this.rtag = rtag;
        }
        public int getNumap() {
            return this.numap;
        }
        public void setNumap(final int numap) {
            this.numap = numap;
        }
        public String getT() {
            return this.t;
        }
        public void setT(final String t) {
            this.t = t;
        }
    }

    public static class Loc {
        private String lat;
        private String lon;
        private String addr;
        private String msg;
        private String floor;
        private String t;

        public Loc() {
            super();
        }

        public String getLat() {
            return this.lat;
        }
        public void setLat(final String lat) {
            this.lat = lat;
        }
        public String getLon() {
            return this.lon;
        }
        public void setLon(final String lon) {
            this.lon = lon;
        }
        public String getAddr() {
            return this.addr;
        }
        public void setAddr(final String addr) {
            this.addr = addr;
        }
        public String getMsg() {
            return this.msg;
        }
        public void setMsg(final String msg) {
            this.msg = msg;
        }
        public String getFloor() {
            return this.floor;
        }
        public void setFloor(final String floor) {
            this.floor = floor;
        }
        public String getT() {
            return this.t;
        }
        public void setT(final String t) {
            this.t = t;
        }
    }
}

サンプルコードの実行結果

Longitude(経度) : 13*.******
Latitude(緯度)  : 3*.******
Address(住所)   : '東京都************'
Floor          : null
Message        : '位置が取得できました'

Posted in WebService | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 23, 2007

[Library] jMock で java.sql.Connection のモックオブジェクト生成にチャレンジ

JMock で java.sql.Connection のモックオブジェクト作成に挑戦してみた。 ・・・と言っても、まだ jMock のサンプルを眺めただけ。

jMock
http://www.jmock.org/

サンプルコード - その1

とりあえず基礎の基礎。 単純な java.sql.Connection のモックオブジェクトを作成してみた。 example1 はテスト成功パターン。example2 はテスト失敗パターン。

package jp.in_vitro.codelets.jmock;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.jmock.Expectations;
import org.jmock.Mockery;

public class Codelet {

    public static void main(String[] args) throws SQLException {
        Codelet me = new Codelet();
        me.example0();
        me.example1();
    }

    protected void example0() throws SQLException {
        Mockery context = new Mockery();
        final Connection connection = context.mock(Connection.class);
        context.checking(new Expectations() {
            {
                one(connection).close();
            }
        });

        connection.close();
        context.assertIsSatisfied();
    }

    protected void example1() throws SQLException {
        Mockery context = new Mockery();
        final Connection connection = context.mock(Connection.class);
        context.checking(new Expectations() {
            {
                one(connection).close();
            }
        });

        // connection.close();
        context.assertIsSatisfied();
    }
}

サンプルコード - その2

次に java.sql.Connection から java.sql.Statement を返してみた。 とりあえず指定した java.sql.Statement を java.sql.Connection#createStatement から返すことに成功。

package jp.in_vitro.codelets.jmock;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.jmock.Expectations;
import org.jmock.Mockery;

public class Codelet {

    public static void main(String[] args) throws SQLException {
        Codelet me = new Codelet();
        me.example2();
    }

    protected void example2() throws SQLException {
        Mockery context = new Mockery();
        final Connection connection = context.mock(Connection.class);
        final Statement expected = context.mock(Statement.class);
        context.checking(new Expectations() {
            {
                one(connection).createStatement();
                will(returnValue(expected));
            }
        });

        Statement actual = connection.createStatement();
        System.out.println("expected: " + expected + "@" + expected.hashCode());
        System.out.println("actual: " + actual + "@" + actual.hashCode());
        context.assertIsSatisfied();
    }
}

Posted in Library | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 22, 2007

[Misc] 各社携帯の XHTML 対応状況メモ

NTT Docomo, AU, Softbank mobile の XHTML 対応状況を調べたのでメモ。

NTT Docomo

「端末スペック一覧」ページに XHTML の対応状況が記載されている。

XHTML Basic 1.1
http://www.w3.org/TR/xhtml-basic/
作ろう i モードコンテンツ
http://www.nttdocomo.co.jp/service/imode/make/
端末スペック一覧
http://www.nttdocomo.co.jp/service/imode/make/content/spec/index.html
iモード対応XHTMLの考え方
http://www.nttdocomo.co.jp/service/imode/make/content/xhtml/outline/s1.html

AU

「XHTML 対応機種」ページによると

「XHTML」で表記されたコンテンツを、作成者の意図どおりのデザインで閲覧するには、WAP2.0ブラウザ搭載端末で表示する必要があります。HDMLブラウザ搭載端末では、HDML標準対応となり、「XHTML」コンテンツに関しては、EZサーバによるコンテンツ変換機能を使用し「XHTML → HDML」の変換を行って表示することになります。
ということだそうだ。WAP2.0ブラウザ搭載状況は「機種別情報一覧」ページに記載されている。
技術情報
http://www.au.kddi.com/ezfactory/tec/index.html
XHTML 対応機種
http://www.au.kddi.com/ezfactory/howtoxhtml/02.html
機種別情報一覧
http://www.au.kddi.com/ezfactory/tec/spec/new_win/ezkishu.html

Softbank mobile

「ウェブ技術資料 - 概要編」によると

1.2 サービス世代
以降、回線交換のみに対応する端末を C 型端末と呼称し、パケット交換サービス(PDC-P)にも対応する端末を P 型端末と呼称し、3G サービスに対応する端末を W 型端末、WAP/MMS サービスに対応する端末を 3GC 型端末と呼称する。

1.3.1. ウェブ
・コンテンツは HTML(Hyper Text Markup Language) もしくは MML(Mobile Markup Language), XHTML で記述する。ただし、MML は C 型および P 型端末でのみ利用可能であり、 XHTML は W 型、3GC 型端末でのみ利用可能である。
だそうだ。3G サービス対応端末、WAP/MMS サービス対応端末で表示可能ということのようだ。 ・・・残念なことに、3G サービス対応端末、WAP/MMS サービス対応端末の情報は見当たらなかった。
Softbank Developers Support Site
http://developers.softbankmobile.co.jp/dp/
ウェブ技術資料 - 概要編
http://www2.developers.softbankmobile.co.jp/dp/tool_dl/download.php?docid=110&companyid=
ウェブ技術資料 - XHTML 編
http://www2.developers.softbankmobile.co.jp/dp/tool_dl/download.php?docid=135&companyid=
端末情報
http://developers.softbankmobile.co.jp/dp/tech_svc/info/

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 16, 2007

[Apple] Pathway メモ

[Pathway]

Pathway は Wikipedia ビューア。 Wikipedia の関連付けられたエントリからエントリへ渡り歩きながら必要な知識を得ることができる。 これは便利。

Pathway is an app designed to solve the aforementioned problems. Its aim is to help you discover Wikipedia without having to worry whether you’ll have enough time to read everything you want, or if you’ll get lost.

It accomplishes this by presenting you with a graphical “network” representation of your visited article pages. A node represents an article, a connection between two nodes means, of course, that you’ve gone from the first article to the second one. You can save the network you’ve created to disk and recover it.
Pathway
http://pathway.screenager.be/
About Pathway
http://pathway.screenager.be/about-pathway/

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 14, 2007

[Apple] Shrook メモ

[Shrook]

Shrook は Mac OS X 用の RSS Reader。 しばらく Vienna を使用していたのだが、唐突に Feed の読み込みをしてくれなくなった。 どうも過去のエントリデータが破損した模様。 機能的には満足していたのだが、どうも動作がもっさりしていたこともあり Shrook を試してみることにした。 さて、データ量が増えてきたときにどうなることやら・・・。

Shrook
http://www.utsire.com/shrook/

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 13, 2007

[Misc] SSL 証明書のインストール時に X509_check_private_key:key values mismatch エラー

Apache Web Server 2.2.6 に SSL 証明書をインストールしたときに不思議なエラーに遭遇した。

[warn] RSA server certificate CommonName (CN) `hoge.example.com' does NOT match server name!?
[error] Unable to configure RSA server private key
[error] SSL Library Error: 185073780 error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch
何のことはない、間違って別サーバの SSL 証明書を使っていただけだった(^^;
  # openssl x509 -noout -text -in ./server.crt
で SSL 証明書の内容を確認したら別サーバのものであることが一瞬で判明。 正しい SSL 証明書を持ってきたらすぐに解決。やれやれ。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 10, 2007

[Apple] ImageMagick を Mac OS X にインストール

ImageMagick を Mac OS X にインストールした際のメモ。 メモと言っても、MacPorts を使っているので大したことはやっていない。

ImageMagick: Convert, Edit, and Compose Images
http://www.imagemagick.org/

MacPorts を使って ImageMagick をインストール

$ sudo port install ImageMagick

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

[Apple] ImageMagick を Mac OS X にインストール

ImageMagick を Mac OS X にインストールした際のメモ。 メモと言っても、MacPorts を使っているので大したことはやっていない。

ImageMagick: Convert, Edit, and Compose Images
http://www.imagemagick.org/

MacPorts を使って ImageMagick をインストール

$ sudo port install ImageMagick

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 09, 2007

[Apple] MacPorts を Mac OS X にインストール

MacPorts を Mac OS X にインストールした際のメモ。

MacPorts
http://www.macports.org/

MacPorts のインストール

  1. MacPorts のサイトから dmg ファイルを拾ってくる。
  2. dmg をマウントし、インストーラを実行。後はウィザードの指示通り。
  3. /Users/me/.bashrc を編集。以下を追加する。
    export PATH=/opt/local/bin:/opt/local/sbin/:$PATH
    export MANPATH=/opt/local/man:$MANPATH
    
  4. MacPorts の初期設定。
    $ sudo port -d selfupdate
    $ sudo port -d sync
    

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |