ISOマウントCGI


isomounter.jpg

ホームサーバ内の動画を見るのにLT−H90DTVから共有(samba)を見ているが、DVDをイメージ化したISOファイルに一部直接再生できない場合がある。この場合、スマホのターミナルからSSHでログインし、ISOファイルのマウントコマンドを入力して・・・とごにょごにょするといけるが、ちょっと面倒なので、上記画像のように、スマホでISOファイルの一覧を表示し、簡単にマウント/アンマウントできるcgiをさくっと作ってみた。いつもの通り適当なperlですが勘弁してください。

1、sudo設定

cgiは普通apacheユーザーで動作しているのでそのままでは、sudoでマウントできない。

visudoで設定ファイルを開き

## Same thing without a password

apache  ALL=(ALL)       NOPASSWD: ALL

でパスワードを聞かれないようにし、
apache ALL=/sbin/mount /home/common/play(マウントディレクトリを設定)
で特定のディレクトリのみマウントを許可。
※この辺りはセキュリティに関係してくるので、ポリシーをよく考えて設定してください。
あとは下記cgiを設置すれば動くはず。
(オリジナルのjqm-custom.jsファイルは、jquerymobileのページ移動ajax機能をoffにしているだけです)
ISOファイルがあるディレクトリ。
$isoDIR
マウントするディレクトリ(sudoパーミッションで設定したディレクトリ。あらかじめコマンドで作成しておく)
$mountDIR
#! /usr/bin/perl
use strict;
use CGI;
my $isoDIR = '/home/common/dvd';
my $mountDIR = '/home/common/play';
my $q = new CGI;
#表示
print $q->header(-charset=>'utf-8');
print <<HEADPRINT;
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>ISOマウンター</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="/js/jqm-custom.js"></script>
<script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
</head>
<body>
<div data-role="page" id="index">
<div data-role="header" data-position="inline">
<h1>ISOマウンター</h1>
<a href="./mount.cgi" data-role="button" data-icon="home" data-theme="a">トップ</a>
<a href="./mount.cgi?mode=umount" data-icon="minus">解除</a>
</div>
<div data-role="content">
HEADPRINT
#モード選択
if ( $q->param('mode') eq 'mount') {
print "<div><a href =\"./mount.cgi?mode=umount\" data-role=\"button\">マウント解除</a></div>\n";
&isoMount($mountDIR);
} elsif ($q->param('mode') eq 'umount') {
&isoUmount($mountDIR);
} else {
print "<ul data-role=\"listview\"  data-dividertheme=\"a\">\n";
&isoFilelist($isoDIR);
print "</ul>\n";
}
print <<FOOTERPRINT;
</div>
<div data-role="footer">
<h4>&copy; turbomaru</h4>
</div>
</div>
</body>
</html>
FOOTERPRINT
#-------------------------------------------#
#クリックしたISOファイルをマウント
#-------------------------------------------#
sub isoMount{
my $dir = shift;
if( $q->param('isofilename') ){
my $ret = system("sudo mount -t iso9660 -o loop " . $q->param('isofilename') . " " . $dir );
if ( $ret == 0 ){
print "<p>";
print $q->param('isofilename') . "を" .$dir . "にマウントしました。";
print "</p>";
} elsif ( $ret == 8192 ){
print  "<p>" . $q->param('isofilename') . "は既にマウントされています。</p>";
} else {
print  "<p>" . $q->param('isofilename') . "をマウントできませんでした。($ret)</p>";
}
} else {
print "<p>ISOファイルが指定されていません。</p>";
}
}
#-------------------------------------------#
#ISOファイルをアンマウント
#-------------------------------------------#
sub isoUmount{
my $dir = shift;
my $ret = system("sudo umount " . $dir );
if ( $ret == 0 ){
print "<p>";
print  $dir ."のマウントを解除しました。";
print "</p>";
} else {
print "<p>マウント解除できませんでした。$dir フォルダが空であれば、既に解除されています。($ret)</p>";
}
}
#-------------------------------------------#
#ディレクトリ配下のISOファイルを表示
#-------------------------------------------#
sub isoFilelist{
my $dir = shift;
my @list = ();
#ファイル一覧を取得
opendir(DIR, $dir) or die("<p>ディレクトリが開けません。:$dir ($!)</p>\n");
@list = readdir(DIR);
closedir(DIR);
my $buff;
foreach my $file (sort @list){
next if( $file =~ /^\.{1,2}$/ );
if( -d "$dir/$file" ){
print "<li data-role=\"list-divider\">$file</li>\n";
isoFilelist("$dir/$file");
} else {
if( $file =~ /ISO$/i  ){ # 拡張子がISOのファイルのみ表示
my $buff =  "<li><a href=\"./mount.cgi?mode=mount&isofilename=" . $dir . "/" . $file . "\">$file</a></li>\n";
print $buff;
}
}
}
}

投稿者: ちゅう たろう

ネットワーク・サーバー周りをちょっと知っているだけの普通の人です。