...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

とある学生の仮想端末《ジョークコード》

とある高校にて


誰かがコンピュータ室にある1台のPCに,あるBASICプログラムを置いておいた.


しばらく経ち,ひとりの学生がそのプログラムの存在に気づき,
何気なく実行してみた.


すると,こともあろうに,FDDのアクセス音と,FDDのすべてのファイルを削除したことを示すメッセージが表示された!


びっくりした学生はファイル一覧を出そうとFILESと入力しエンターを叩いた.


しかし無情にもその結果は何もファイルがないというものだった.


なん・・・だと・・・と思いつつも,何気なく癖になっているbreakキーを押すと,何かのプログラムが終了された.
ここで学生は気づいた.


こ,このプログラムを作った奴は,実行した奴が不安になってファイルの存在を確認することまで読んでやがったのか!


その学生は完全にはめられた悔しさのあまり


その仮想環境を実現するプログラムから脱出する唯一の方法である「breakキーの押下」を無効にし,


十数回のエンターキーの押下の後に表示されるヒントから導かれるキーワードを入力しなければ絶対に終了しないようにして


そのプログラムをそっと元のプログラムに上書き保存して,置いておいたとさ.


めでたし,めでたし.


同じようなコンセプトのコード

import std.stdio;
import std.date;
import std.process;
import std.string;

import win32.windows;
import win32.winnt;

void main(string[] args)
{
	system("cls");
	
	if (args.length == 1)
	{
		stdout.writeln("日本語表示されてる?");
		stdout.writeln("コンソールから fungame 1 と入力して実行してね");
		stdin.readln();
		return;
	}
	
	
	win32.winnt.OSVERSIONINFO ver;
	ver.dwOSVersionInfoSize = win32.winnt.OSVERSIONINFO.sizeof;
	GetVersionEx(&ver);

	stdout.write(format(`Microsoft Windows [Version %d.%d.%d]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

C:\>cd C:\

C:\>del /F /Q *.*

`, cast(int)ver.dwMajorVersion, cast(int)ver.dwMinorVersion, cast(int)ver.dwBuildNumber));

	Sleep(2000);
	
	stdout.write(`C:\>`);

LOOP:

	string s = chomp(stdin.readln());
	
	if (s == "dir")
	{
		Time now = Time.localTime();
		
		ULARGE_INTEGER lpFreeBytesAvailable;
		ULARGE_INTEGER lpTotalNumberOfBytes;
		ULARGE_INTEGER lpTotalNumberOfFreeBytes;
		GetDiskFreeSpaceEx(`C:\`,
			&lpFreeBytesAvailable, &lpTotalNumberOfBytes, &lpTotalNumberOfFreeBytes);
		string totalDiskSpace = toCommaSeparatedString(lpTotalNumberOfBytes.QuadPart);
		
		stdout.write(format(` ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 4432-48DE です

 C:\ のディレクトリ

%04d/%02d/%02d  %02d:%02d    <DIR>			.
%04d/%02d/%02d  %02d:%02d    <DIR>			..
               0 個のファイル        0 バイト
               2 個のディレクトリ  %s バイトの空き領域
`,
		now.year, now.month, now.day, now.hour, now.minute,
		now.year, now.month, now.day, now.hour, now.minute,
		totalDiskSpace));
	}
	else if (s == "")
	{
	}
	else if (s == "cls")
	{
		system("cls");
		stdout.writeln();
	}
	else if (s == "help")
	{
		stdout.write(`特定のコマンドの詳細情報は、"HELP コマンド名" を入力してください
CLS      画面を消去します。
DIR      ディレクトリ中のファイルやサブディレクトリの一覧を表示します。
EXIT     CMD.EXE プログラム (コマンド インタープリタ) を終了します。
HELP     Windows コマンドのヘルプ情報を表示します。
VER      Windows のバージョンを表示するかもしれません。

ツールの詳細な情報については、オンライン ヘルプのコマンド ライン
リファレンスを参照してください。

`);
	}
	else if (s == "ver")
	{
		stdout.writeln("HA-HA-HA-");
		stdout.writeln("出口を見つけたようだね");
		stdout.writeln("おめでとう!");
		return;
	}
	else if (s == "exit")
	{
		static int count;
		count++;
		if (count % 2)
			stdout.writeln("...さがして...\n");
		else
			stdout.writeln("...ゴールを...\n");
	}
	else
	{
		stdout.write(`'` ~ split(s, " ")[0] ~ `' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

`);
	}

	stdout.write(`C:\>`);

	goto LOOP;
}

string toCommaSeparatedString(T)(T decimal)
{
	return toCommaSeparatedString(to!string(decimal));
}
string toCommaSeparatedString(T : string)(T decimal)
{
	if (decimal.length > 3)
		return toCommaSeparatedString(decimal[0..$-3]) ~ "," ~ decimal[$-3..$];
	else
		return decimal;
}
unittest
{
	assert("1,234,567,890" == toCommaSeparatedString(1234567890));
	assert("567,890" == toCommaSeparatedString(567890));
}


struct Time
{
	int year, month, day;
	int hour, minute, second;
	static Time localTime()
	{
		version (Windows)
		{
			SYSTEMTIME now;
			GetLocalTime(&now);
			Time t = {now.wYear, now.wMonth, now.wDay, now.wHour, now.wMinute, now.wSecond};
			return t;
		}
		else
		{
			static assert(false, "no implemented");
		}
	}
	string toString()
	{
		return format("%04d/%02d/%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
	}
	
	unittest
	{
		Time t = {2010, 12, 6, 15, 29, 31};
		assert(t.toString() == "2010/12/06 15:29:31");
	}
}

// http://dusers.dip.jp/modules/forum/index.php?topic_id=74#post_id305
import std.conv;
import std.stdio;
import std.string;
 
import core.stdc.locale;
import core.stdc.wchar_;
 
//import core.sys.windows.windows;

// LC_CTYPE をコンソール用に設定する.
shared static this()
{
	// druntimeの定数定義が間違っている
	version (Windows) enum LC_CTYPE = 2;
	version (linux	) enum LC_CTYPE = 0;
	version (OSX	) enum LC_CTYPE = 2;
	version (FreeBSD) enum LC_CTYPE = 2;
	version (Solaris) enum LC_CTYPE = 0;
 
	version (Windows)
		setlocale(LC_CTYPE, toStringz("." ~ to!string(GetConsoleOutputCP())));
	else
		setlocale(LC_CTYPE, "");
 
	fwide(stdin .getFP(), 1);
	fwide(stdout.getFP(), 1);
}