そのディレクトリが書き込み可能か否か

あるディレクトリが書き込み可能(ハードディスク)か、そうでないか(追記不可にしたCDやDVD)か、を確かめる関数。
やっていることは、実際にランダムな名前のファイルを作ろうとして、出来たか出来なかったかを確かめる。

00.txt

*define
game
*start
click
end

system.lua

-- is writable

function is_writable(dir)
	dir = dir or ""
	local file = ""
	local fullpath = ""
	while true do
		file = random_string()
		if dir == "" then
			fullpath = file
		else
			fullpath = dir.."\\"..file
		end
		if not fileexist(fullpath) then break end
	end
	local fh = io.open(fullpath, 'w')
	if io.type(fh) ~= "file" then return false end
	fh:write(os.date())
	fh:close()
	os.remove(fullpath)
	return true
end

function fileexist(file)
	if type(file) ~= "string" then return false end
	if file == "" then return false end
	local fh = io.open(file)
	if io.type(fh) ~= "file" then return false end
	fh:close()
	return true
end

function random_string(length)
	if type(length) == "nil" then length = 8 end
	if type(length) ~= "number" then length = 8 end
	length = math.floor(length)
	if length < 1 then length = 8 end
	local res = {}
	for i = 1, length do
		table.insert(res, string.char(math.floor(math.random()*26)+97))
	end
	return table.concat(res)
end

-- 動作テスト。導入する時は削除するべし。
if is_writable() then
	NSOkBox("書き込めます。", "lua")
else
	NSOkBox("書き込めません。", "lua")
end

解説

is_writable(string)は、ディレクトリ名を与えると、そのディレクトリが書き込み可能かそうでないかをbooleanで返す関数。
fileexist()とrandom_string()の二つの関数に依存している。
引数無で呼んだ場合は、カレント・ディレクトリになる。

用途

移動なし起動の変化球 - 永字八法みたいな。
一般的なNScripter等を使った同人ソフトは、「インストールは、CDの中身をフォルダごとハードディスクに移動。アンインストールは、フォルダ毎削除」と言う仕様だが、これを「CDから起動、セーブデータのみをハードディスクに保存」と言う仕様にすることはなんとかできそう。
ただし、フォルダ全移動にも対応するため、カレントディレクトリや、あるいはユーザーが指定したディレクトリが書き込み可能かどうかをチェックする必要はある。この関数はそのために使える。
実際にこれをCDに焼き、追記禁止にしてから実行すると、書き込めないようになっているのがわかる。