ProFTPDとMySQLの仮想ホスティング構成

目的

  • ProFTPDのLocal/Remoteのエンコーディング指定を可能にするパッチ適用
  • MySQLと連携した仮想ホスティング(Linux上にユーザ登録しないでFTPユーザ作成)
  • ProFTPDにはQuotaも組み込み

本当はapt-getで出来るだけ簡単導入してProFTPDのパッチのみを適用する形にしたかったが、MySQLもビルドしないとうまくいかなったので、とりあえずはその作業内容を残します。

※以前の情報では何とか出来上がった手順を載せていましたが、玄箱PROを組みなおす機会があったのでこうしんしました。ポイントはconfigureやmakeに何か足りずに失敗したらwget直後からやり直すことですね・・・変にconfigureしたものやmakeしたものが残っていると何がうまくいって何がうまくいっていないのか分からなくなりました・・・

導入するバージョン

MySQL 4.1.21
ProFTPD 1.3.0

MySQLの導入

ビルドに必要なパッケージを導入してからの手順です。
# apt-get install make gcc g++ zlib1g-dev libcdk5-dev
# groupadd mysql
# useradd -g mysql -d /usr/local mysql
# cd /usr/local/src
# wget http://downloads.mysql.com/archives/mysql-4.1/mysql-4.1.21.tar.gz
# tar zxvf mysql-4.1.21.tar.gz
# cd mysql-4.1.21
#/mysql-4.1.21# ./configure \
 --with-charset=utf8 \
 --with-extra-charsets=all \
 --with-mysqld-user=mysql
# make
make終了まで2時間ほど待機。
make install には以下3つのパッケージが必要です。
# apt-get install autoconf2.13
# apt-get install automake1.4
# apt-get install libtool
# make install
# cp support-files/my-small.cnf /etc/my.cnf
# /usr/local/bin/mysql_install_db
# chmod -R 777 /usr/local/var

MySQLの初期設定

<password>にはrootとして使用するパスワードをmysqladminで設定します。
その後mysqlデータベースに接続します。
# su mysql
# /usr/local/bin/mysqld_safe &
# /usr/local/bin/mysqladmin -u root password <password>
# /usr/local/bin/mysql -u root -p mysql
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2 to server version: 4.1.21-log

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

mysql> DELETE FROM user WHERE password='';
Query OK, 3 rows affected (0.00 sec)

mysql> select user, host, password from mysql.user;
+------+-----------+-------------------------------------------+
| user | host      | password                                  |
+------+-----------+-------------------------------------------+
| root | localhost | *EX4858XB86EXA20BX33X0AECXE8AX108X56BX7FA |
+------+-----------+-------------------------------------------+
1 row in set (0.00 sec)

mysql> exit
Bye
# exit
システム起動時に自動実行されるようにupdate-rc.dで/etc/init.d/mysqlをdefaultsで登録する。
# cp /usr/local/src/mysql-4.1.21/support-files/mysql.server \
 /etc/init.d/mysql
# chmod +x /etc/init.d/mysql
# update-rc.d mysql defaults

ProFTPDの導入

サーバのエンコーディングとクライアントのエンコーディングが指定できるmod_codeconvを組み込んでビルドします。
# apt-get install patch
# groupadd proftpd
# useradd -g proftpd -d /dev/null -s /usr/sbin/nologin proftpd
# cd /usr/local/src
# wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.0.tar.gz
# wget http://www.hakusan.tsg.ne.jp/tjkawa/software/misc/proftpd-iconv/\
pack/proftpd-1.3.0-iconv.patch.gz
# wget http://www.hayasoft.com/haya/linux/proftpd-nlst-patch/\
proftpd-1.3.0-nlst-ffftp.patch
# tar -zxvf proftpd-1.3.0.tar.gz
# gzip -d proftpd-1.3.0-iconv.patch.gz
# patch -p0 < proftpd-1.3.0-iconv.patch
# patch -p0 < proftpd-1.3.0-nlst-ffftp.patch
# cd /usr/local/src/proftpd-1.3.0
# ./configure --prefix=/usr/local \
--with-modules=mod_codeconv:mod_df\
:mod_sql:mod_sql_mysql:mod_quotatab:mod_quotatab_sql \
--with-libraries=/usr/local/lib/mysql \
--with-includes=/usr/local/include/mysql \
--disable-auth-pam
# make
# make install
導入されたproftpdに組み込まれたモジュールを確認します。mod_codeconv, mod_sql, mod_sql_mysql, mod_quotatab, mod_quotatab_sqlがあることを確認してください。
# proftpd -l
Compiled-in modules:
  mod_core.c
  mod_xfer.c
  mod_auth_unix.c
  mod_auth_file.c
  mod_auth.c
  mod_ls.c
  mod_log.c
  mod_site.c
  mod_delay.c
  mod_codeconv.c
  mod_df.c
  mod_sql.c
  mod_sql_mysql.c
  mod_quotatab.c
  mod_quotatab_sql.c
  mod_cap.c
# mkdir /var/log/proftpd
# chown -R proftpd:proftpd /var/log/proftpd/
# vi /etc/init.d/proftpd
proftpd起動用シェルを作成します。Debianのapt-getで導入されるシェルをそのまま使用します。
#!/bin/sh 

# Start the proftpd FTP daemon.

PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/proftpd
NAME=proftpd

# Defaults
RUN="yes"
OPTIONS=""

PIDFILE=`grep -i 'pidfile' /usr/local/etc/proftpd.conf | \
sed -e 's/pidfile[\t ]\+//i'`
if [ "x$PIDFILE" = "x" ];
then
    PIDFILE=/usr/local/var/proftpd.pid
fi

# Read config (will override defaults)
[ -r /etc/default/proftpd ] && . /etc/default/proftpd

trap "" 1
trap "" 15

#test -f $DAEMON || exit 0

#
# These compatibility funcs are here just for sarge backports.
# They will be removed post-etch.
#
log_daemon_msg() {
    echo -n "$1: $2"
}

log_end_msg() {
    if [ $1 -ne 0 ]; then
        echo " failed!"
    else
        echo "."
    fi
}

[ -f /lib/lsb/init-functions ] && . /lib/lsb/init-functions

#
# Servertype could be inetd|standalone|none.
# In all cases check against inetd and xinetd support.
#
if ! egrep -qi "^[[:space:]]*ServerType.*standalone" \
/usr/local/etc/proftpd.conf
then
    if [ $(dpkg-divert --list xinetd|wc -l) -eq 1 ] 
    then
        if egrep -qi "server[[:space:]]*=[[:space:]]*/usr/sbin/proftpd" \
        /etc/xinetd.conf 2>/dev/null || \
            egrep -qi "server[[:space:]]*=[[:space:]]*/usr/sbin/proftpd" \
            /etc/xinetd.d/* 2>/dev/null
        then
            RUN="no"
            INETD="yes"
        else
            if ! egrep -qi "^[[:space:]]*ServerType.*inetd" \
            /usr/local/etc/proftpd.conf
            then
                RUN="yes"
                INETD="no"
            else
                RUN="no"
                INETD="no"
            fi
        fi
    else
        if egrep -qi "^ftp.*/usr/sbin/proftpd" /etc/inetd.conf 2>/dev/null
        then
            RUN="no"
            INETD="yes"
        else
            if ! egrep -qi "^[[:space:]]*ServerType.*inetd" \
            /usr/local/etc/proftpd.conf
            then
                RUN="yes"
                INETD="no"
            else
                RUN="no"
                INETD="no"
            fi
        fi
    fi
fi

# /var/run could be on a tmpfs

[ ! -d /var/run/proftpd ] && mkdir /var/run/proftpd

start()
{
    log_daemon_msg "Starting ftp server" "$NAME"

    start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec $DAEMON \
    -- $OPTIONS  
    if [ $? != 0 ]; then
        log_end_msg 1
        exit 1
    else
        log_end_msg 0
    fi
}

signal()
{

    if [ "$1" = "stop" ]; then
        SIGNAL="TERM"
        log_daemon_msg "Stopping ftp server" "$NAME"
    else
        if [ "$1" = "reload" ]; then
            SIGNAL="HUP"
            log_daemon_msg "Reloading ftp server" "$NAME"
        else
            echo "ERR: wrong parameter given to signal()"
            exit 1
        fi
    fi
    if [ -f "$PIDFILE" ]; then
        start-stop-daemon --stop --signal $SIGNAL --quiet --pidfile \
        "$PIDFILE"
        if [ $? = 0 ]; then
            log_end_msg 0
        else
            SIGNAL="KILL"
            start-stop-daemon --stop --signal $SIGNAL --quiet \
            --pidfile "$PIDFILE"
            if [ $? != 0 ]; then
                log_end_msg 1
                [ $2 != 0 ] || exit 0
            else
                log_end_msg 0
            fi
        fi
        if [ "$SIGNAL" = "KILL" ]; then
                rm -f "$PIDFILE"
        fi
    else
        log_end_msg 0
    fi
}

case "$1" in
    start)
        if [ "x$RUN" = "xyes" ] ; then
            start
        else
            if [ "x$INETD" = "xyes" ] ; then
                echo "ProFTPd is started from inetd/xinetd."
            else 
                echo "ProFTPd warning: cannot start neither \
                in standalone nor in inetd/xinetd mode. Check \
                your configuration."
            fi
        fi
        ;;

    force-start)
        if [ "x$INETD" = "xyes" ] ; then
            echo "Warning: ProFTPd is started from inetd/xinetd \
            (trying to start anyway)."
        fi
        start
        ;;

    stop)
        if [ "x$RUN" = "xyes" ] ; then
            signal stop 0
        else
            if [ "x$INETD" = "xyes" ] ; then
                echo "ProFTPd is started from inetd/xinetd."
            else 
                echo "ProFTPd warning: cannot start neither \
                in standalone nor in inetd/xinetd mode. Check \
                your configuration."
            fi
        fi
        ;;

    force-stop)
        if [ "x$INETD" = "xyes" ] ; then
            echo "Warning: ProFTPd is started from inetd/xinetd \
            (trying to kill anyway)."
        fi
        signal stop 0
        ;;

    reload)
        signal reload 0
        ;;

    force-reload|restart)
        if [ "x$RUN" = "xyes" ] ; then
            signal stop 1
            sleep 2
            start
        else
            if [ "x$INETD" = "xyes" ] ; then
                echo "ProFTPd is started from inetd."
            else 
                echo "ProFTPd warning: cannot start neither \
                in standalone nor in inetd/xinetd mode. Check \
                your configuration."
            fi
        fi
        ;;

    *)
        echo "Usage: /etc/init.d/$NAME {start|force-start|stop|\
        force-stop|reload|restart|force-reload}"
        exit 1
        ;;
esac

exit 0

# chmod +x /etc/init.d/proftpd
# update-rc.d proftpd defaults
# mkdir /var/lock/subsys/
# touch /var/lock/subsys/proftpd
# ln -s /usr/local/sbin/proftpd /usr/sbin/proftpd
# vi /usr/local/etc/proftpd/proftpd.conf
proftpd.confを編集して下記をファイル上部に貼り付けます。
CharsetLocal                    UTF-8
CharsetRemote                   CP932
ServerIdent                     on ""
RootLogin                       off
ListOptions                     "-la"
DefaultRoot                     ~ !wheel
RequireValidShell               off
UseReverseDNS                   off
IdentLookups                    off
TimesGMT                        off
TimeoutIdle                     600
TimeoutLogin                    300
TimeoutNoTransfer               600
TimeoutStalled                  600
ShowSymlinks                    on
MaxClientsPerHost               2
MaxHostsPerUser                 1
LogFormat allinfo "%t :  %u (%a [%h]) : [%s], %T, %m (%f)"
LogFormat write   "%t : %u : %F (%a)"
LogFormat read    "%t : %u : %F (%a)"
LogFormat auth    "%t : %u (%a [%h])"
ExtendedLog /var/log/proftpd/all.log   ALL   allinfo
ExtendedLog /var/log/proftpd/write.log WRITE write
ExtendedLog /var/log/proftpd/read.log  READ  read
ExtendedLog /var/log/proftpd/auth.log  AUTH  auth
<Directory /*>
  AllowOverwrite                on
  AllowStoreRestart             on
  AllowRetrieveRestart          on
</Directory>
ファイルの最後にMySQLとの連携とQuotaの設定を追加します。Anonymousブロックは必要に応じてコメントしておきます。
<IfModule mod_sql_mysql.c>
    SQLAuthenticate     users
    SQLConnectInfo      proftpd@localhost:3306 proftpd proftpd
    SQLAuthTypes        Crypt
    SQLUserInfo         users userid password uid gid homedir shell
    SQLGroupInfo        groups groupname gid members
    AuthOrder           mod_sql.c
</IfModule>
<IfModule mod_quotatab.c>
    QuotaEngine         on
    QuotaLog            /var/log/proftpd/quota-log
    QuotaLimitTable     sql:/get-quota-limit
    QuotaTallyTable     sql:/get-quota-tally/update-quota-tally/\
        insert-quota-tally
    
    SQLNamedQuery       get-quota-limit SELECT "userid, quota_type, \
        per_session, limit_type, bytes_in_avail, bytes_out_avail, \
        bytes_xfer_avail, files_in_avail, files_out_avail, \
        files_xfer_avail FROM quotalimits WHERE userid = '%{0}' \
        AND quota_type = '%{1}'"
    
    SQLNamedQuery       get-quota-tally SELECT "userid, quota_type, \
        bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, \
        files_out_used, files_xfer_used FROM quotatallies WHERE \
        userid = '%{0}' AND quota_type = '%{1}'"
    
    SQLNamedQuery       update-quota-tally UPDATE "bytes_in_used = \
        bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, \
        bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = \
        files_in_used + %{3}, files_out_used = files_out_used + %{4}, \
        files_xfer_used = files_xfer_used + %{5} WHERE userid = '%{6}' \
        AND quota_type = '%{7}'" quotatallies
    
    SQLNamedQuery       insert-quota-tally INSERT "%{0}, %{1}, %{2}, \
        %{3}, %{4}, %{5}, %{6}, %{7}" quotatallies
    
    QuotaLock           /tmp/proftpd-quota-lock
    QuotaShowQuotas     on
    QuotaDisplayUnits   Gb
    QuotaDirectoryTally on
</IfModule>

仮想ユーザの登録

仮想ユーザをproftpdデータベースに登録します。
# chown -R mysql:mysql /usr/local/var/
# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 55 to server version: 4.1.21-log

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

mysql> create database proftpd;
mysql> CREATE TABLE groups (
    groupname VARCHAR(30) NOT NULL ,
    gid SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1000,
    members varchar(255) default NULL,
    PRIMARY KEY ( groupname ),
    UNIQUE KEY gid (gid)
);

mysql> CREATE TABLE users (
    userid varchar(30) NOT NULL,
    password varchar(30) NOT NULL,
    uid SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1000,
    gid SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1000,
    homedir varchar(255) default NULL,
    shell varchar(255) default '/bin/true',
    PRIMARY KEY (userid),
    UNIQUE KEY uid (uid)
);

mysql> CREATE TABLE quotalimits (
    userid VARCHAR(30) NOT NULL,
    quota_type ENUM("user", "group", "class", "all") NOT NULL,
    per_session ENUM("false", "true") DEFAULT 'true' NOT NULL,
    limit_type ENUM("soft", "hard") DEFAULT 'soft' NOT NULL,
    bytes_in_avail FLOAT DEFAULT '0' NOT NULL,
    bytes_out_avail FLOAT DEFAULT '0' NOT NULL,
    bytes_xfer_avail FLOAT DEFAULT '0' NOT NULL,
    files_in_avail INT UNSIGNED DEFAULT '0' NOT NULL,
    files_out_avail INT UNSIGNED DEFAULT '0' NOT NULL,
    files_xfer_avail INT UNSIGNED DEFAULT '0' NOT NULL
);

mysql> CREATE TABLE quotatallies (
    userid VARCHAR(30) NOT NULL,
    quota_type ENUM("user", "group", "class", "all") DEFAULT 'user' NOT NULL,
    bytes_in_used FLOAT DEFAULT '0' NOT NULL, 
    bytes_out_used FLOAT DEFAULT '0' NOT NULL, 
    bytes_xfer_used FLOAT DEFAULT '0' NOT NULL, 
    files_in_used INT UNSIGNED DEFAULT '0' NOT NULL, 
    files_out_used INT UNSIGNED DEFAULT '0' NOT NULL, 
    files_xfer_used INT UNSIGNED DEFAULT '0' NOT NULL
);
mysql> GRANT SELECT,UPDATE,INSERT ON proftpd.* 
    TO proftpd@localhost IDENTIFIED BY 'proftpd';
mysql> INSERT INTO groups VALUES ('testgroup',1000,'');
mysql> INSERT INTO users VALUES (
    'testuser',encrypt('testuser'),1001,1000,'/var/ftpdata','/bin/true');
mysql> INSERT INTO quotalimits VALUES (
    'testuser','user','false','hard', 524288000,0,0,0,0,0);
ProFTPdを起動してFTPで接続確認を行います。
# /etc/init.d/mysql restart
# /etc/init.d/proftpd restart

ルータ配下の玄箱PROでFTPサーバ提供する際のNAT問題

  • 玄箱PROはルータ配下で稼動し割り当てられているIPアドレスはプライベートアドレス
  • グローバルアドレスが割り当てられているルータからはポート番号(21)指定で玄箱PROへポート転送
  • 家庭内のプライベートアドレスからFTP接続
  • インターネット越しのグローバルIPアドレスからのFTP接続
  • インターネット越しかつルータ配下のプライベートアドレスからのFTP接続
これらを実現するための設定がProFTPDでは可能であるようです。
proftpd.confに以下の設定を追加します。
MasqueradeAddress    <domain-name | global-ipaddr>
PassivePorts         <min-port-number> <max-port-number>
私の環境ではDynamicDNSを使用しているので登録されているドメイン名を<domain-name | global-ipaddr>に設定しました。これでStandalone時は起動時にIPアドレスを取得する動作をします。常時稼動でIPアドレスの動的変更に対応する場合はinetdにした方が良さそうです。
ポート番号はPassive接続で使用するポートの最小と最大で参考程度に私は10020 10034と15ほど取って設定しました。(MaxInstancesを15に設定したので)
この設定にあわせてPassice接続を受け付けるためにルータのポート転送設定に10020-10034を追加します。

追加したproftpd.confの設定でPASVコマンドに対してMasqueradeAddressで指定したアドレスで応答されるようになるため、プライベートアドレスを返されて接続先が分からない、といった状況にならなくなります。
あとはルータに設定したポート転送で玄箱PROに転送されてくればPassive接続完了です。

ただし、この設定ではPassive接続するとグローバルアドレスで応答されるため、家庭内ではPassive接続できません。Port接続のみ可能となります。
中ではPort接続、外ではPassive接続という使い分けになります。

関連パッケージ

KUROBOX-PRO:~# apt-get install libcdk5-dev
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  libc6-dev libcdk5 libncurses5-dev linux-kernel-headers
Suggested packages:
  glibc-doc manpages-dev
Recommended packages:
  gcc c-compiler
The following NEW packages will be installed:
  libc6-dev libcdk5 libcdk5-dev libncurses5-dev linux-kernel-headers
0 upgraded, 5 newly installed, 0 to remove and 15 not upgraded.
1 not fully installed or removed.
Need to get 1856kB/5843kB of archives.
After unpacking 27.1MB of additional disk space will be used.
Do you want to continue [Y/n]?

KUROBOX-PRO:~# apt-get install gcc
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  binutils cpp cpp-4.1 gcc-4.1 libssp0
Suggested packages:
  binutils-doc cpp-doc gcc-4.1-locales make manpages-dev autoconf automake1.9 libtool
  flex bison gdb gcc-doc gcc-4.1-doc
Recommended packages:
  libmudflap0-dev
The following NEW packages will be installed:
  binutils cpp cpp-4.1 gcc gcc-4.1 libssp0
0 upgraded, 6 newly installed, 0 to remove and 15 not upgraded.
Need to get 16.6kB/4915kB of archives.
After unpacking 12.3MB of additional disk space will be used.
Do you want to continue [Y/n]?

KUROBOX-PRO:~# apt-get install make
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  make-doc-non-dfsg
The following NEW packages will be installed:
  make
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/381kB of archives.
After unpacking 1229kB of additional disk space will be used.

KUROBOX-PRO:~# apt-get install make
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  make-doc-non-dfsg
The following NEW packages will be installed:
  make
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/381kB of archives.
After unpacking 1229kB of additional disk space will be used.

KUROBOX-PRO:~# apt-get install g++
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  g++-4.1 libstdc++6-4.1-dev
Suggested packages:
  gcc-4.1-doc libstdc++6-4.1-doc
The following NEW packages will be installed:
  g++ g++-4.1 libstdc++6-4.1-dev
0 upgraded, 3 newly installed, 0 to remove and 15 not upgraded.
Need to get 3408kB of archives.
After unpacking 11.7MB of additional disk space will be used.
Do you want to continue [Y/n]?

KUROBOX-PRO:~# apt-get install zlib1g-dev
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  zlib1g-dev
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/410kB of archives.
After unpacking 602kB of additional disk space will be used.

KUROBOX-PRO:/usr/local/src# apt-get install patch
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  diff-doc
The following NEW packages will be installed:
  patch
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/101kB of archives.
After unpacking 197kB of additional disk space will be used.
KUROBOX-PRO:~# apt-get install autoconf2.13
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  autoconf m4
Suggested packages:
  autobook autoconf-archive gnu-standards autoconf-doc
Recommended packages:
  automaken automake1.4
The following NEW packages will be installed:
  autoconf autoconf2.13 m4
0 upgraded, 3 newly installed, 0 to remove and 15 not upgraded.
Need to get 976kB of archives.
After unpacking 3547kB of additional disk space will be used.
Do you want to continue [Y/n]?

KUROBOX-PRO:~# apt-get install automake1.4
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  autotools-dev
The following NEW packages will be installed:
  automake1.4 autotools-dev
0 upgraded, 2 newly installed, 0 to remove and 15 not upgraded.
Need to get 333kB of archives.
After unpacking 1163kB of additional disk space will be used.
Do you want to continue [Y/n]?

KUROBOX-PRO:~# apt-get install libtool
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  libtool-doc automaken g77 fortran77-compiler gcj
Recommended packages:
  libltdl3-dev
The following NEW packages will be installed:
  libtool
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 328kB of archives.
After unpacking 950kB of additional disk space will be used.
Get:1 http://ftp.jaist.ac.jp etch/main libtool 1.5.22-4 [328kB]
Fetched 328kB in 0s (679kB/s)
Selecting previously deselected package libtool.
(Reading database ... 17513 files and directories currently installed.)
Unpacking libtool (from .../libtool_1.5.22-4_arm.deb) ...
Setting up libtool (1.5.22-4) ...
KUROBOX-PRO:/usr/local/src#


最終更新日:2007-05-29
最終更新:2007年05月29日 14:00