/*****************************************************************************/
/* ＳＴＫ外部コマンド：ディスク */
/*****************************************************************************/

#include <stdio.h>
#include <direct.h>
#include <doslibm.h>
#include <io.h>
#include <error.h>
#include "defines.h"
#include "stk.h"

/*****************************************************************************/

static int Sdisk(NSTACK nstk[],int mode)
/* ディスク系処理１ */
/* ret : 0:成功 , <>0:失敗 */
{
static int (*funcs[])()={ /* 関数の配列：新技術だ！ */
	/* int func(name) */
	unlink,chdir,mkdir,rmdir
};
int ret;
unchar *name;
	switch (mode) {
	    default:
		if ((name=Cadrs(NN0))==NULL) return(NULLERR);
		switch (mode) {
		    case 0:// name(NADRS/NSTR1:0) DELETE → ret(0)
		    case 1:// name(NADRS/NSTR1:0) CHDIR  → ret(0)
		    case 2:// name(NADRS/NSTR1:0) MKDIR  → ret(0)
		    case 3:// name(NADRS/NSTR1:0) RMDIR  → ret(0)
			ret=funcs[mode](name);
			break;
		    case 4:// old(NADRS/NSTR1:1) new(NADRS/NSTR1:0) RENAME → ret(0)
			{ // new=name
			unchar *old;
			if ((old=Cadrs(NN1))==NULL) return(NULLERR);
			ret=rename(old,name);
			}
			break;
		}
		NN0=(long)(ret==-1? errno:0);
		break;
	
	    case 5:/* drv(0) CHDRV → ret(0) */
		/* drv : 0=A: , 1=B: ... */
		ret=(int)NN0;
		NN0=(CHGDRV(ret)>ret? 0:1);
		break;
	    case 6:/* drv(0) DFREE → size(0) */
		/* drv : 0=A: , 1=B: ... */
		/* size<0 : error */
		{ struct FREEINF dsk;
		NN0=DSKFRE((int)NN0+1,&dsk);
		}
		break;
	    case 7:/* GETDRV → drv(0) */
		/* drv : 0=A: , 1=B: ... */
		NN0=CURDRV();
		break;
	    case 8:/* work(0:NADRS) GETDIR → ret(0) */
		{ unchar dir[MAXPATH];
		name=getcwd(dir,MAXPATH);
		if ((ret=ARYStoreB(&NS0,dir,0))) return(ret);
		}
		NN0=(name==NULL);
		break;
	}
	return(NOK);
}

/*****************************************************************************/

static int Sfiles(NSTACK nstk[],int mode)
/* ファイルサーチ */
{
_FILBUF *fbuff;
long ret;
	fbuff=(_FILBUF *)NN0; // FILES以外用
	switch (mode) {
		case 0: /* _FILBUF fbuff STRING (NADRS:2)
				fname(NADRS/NSTR1:1) atrb(0) FILES → ret(0) */
			/* ret : 1=発見 , 0=発見できず */
			if (ARYsize(&NS2)<sizeof(_FILBUF)) return(ARSZOVER);
			{ unchar *fname;
			if ((fname=Cadrs(NN1))==NULL) return(NULLERR);
			NN0=(FILES((_FILBUF *)NN2,fname,(int)NN0)>=0);
			}
			break;
		
		case 2: /* fname(1:NADRS) fbuff(NADRS:0) FILES.NAME → なし */
			return(ARYStoreB(&NS1,fbuff->name,0));
		
		case 1: /* fbuff(NADRS:0) NFILES → ret(0) */
			/* ret : 1=発見 , 0=発見できず */
			NN0=(NFILES(fbuff)>=0);
			break;
		case 3: /* fbuff(NADRS:0) FILES.ATRB → atrb(0) */
			NN0=fbuff->atr;
			// retに一旦代入してからNN0=retで入れようが、このように直接NS0
			// に入れようがサイズは変わらない。そこでわかりやすいほうを取る。
			break;
		case 4: /* fbuff(NADRS:0) FILES.LEN → len(0) */
			NN0=fbuff->filelen;
			break;
		case 5: /* fbuff(NADRS:0) FILES.TIME → time(0) */
			NN0=fbuff->time;
			break;
		case 6: /* fbuff(NADRS:0) FILES.DATE → date(0) */
			NN0=fbuff->date;
			break;
	}
	return(NOK);
}

/*****************************************************************************/

static int Sdconst(NSTACK nstk[],int mode)
/* ディスク系定数 */
{
static int dconst[]={
	 sizeof(_FILBUF)
	,MAXPATH,MAXFILE,MAXEXT,MAXDIR,MAXDRIVE
	,FA_ARCH,FA_DIREC,FA_RONLY,FA_HIDE,FA_SYS,FA_VOL
};
	NN0=(long)dconst[mode];
	return(NOK);
}

/*****************************************************************************/
/* コマンドテーブル */

STKCOM dsktbl[]={
	 {NULL		,NULL	,TNONE,0,0}
	// ファイル・ドライブ・ディレクトリ操作
	,{"DELETE"	,Sdisk	,TSTR1,1,0}	/* ファイル削除 */
	,{"CHDIR"	,Sdisk	,TSTR1,1,1}	/* ディレクトリ移動 */
	,{"MKDIR"	,Sdisk	,TSTR1,1,2}	/* ディレクトリ作成 */
	,{"RMDIR"	,Sdisk	,TSTR1,1,3}	/* ディレクトリ削除 */
	,{"RENAME"	,Sdisk	,TSTR1 TSTR1,1,4}/* ファイル名変更 */
	,{"CHDRV"	,Sdisk	,TNUM ,1,5}	/* ドライブ移動 */
	,{"DFREE"	,Sdisk	,TNUM ,1,6}	/* ディスク空き容量 */
	,{"GETDRV"	,Sdisk	,TNONE,1,7}	/* カレントドライブ取得 */
	,{"GETDIR"	,Sdisk	,TADRS,1,8}	/* カレントディレクトリ取得 */
	// ファイルサーチ
	,{"FILES"	,Sfiles	,TNUM TSTR1 TADRS,1,0}	/* ﾌｧｲﾙｻｰﾁ(最初) */
	,{"NFILES"	,Sfiles	,TADRS,1,1}	/* ファイルサーチ（継続）*/
	,{"FILES.NAME"	,Sfiles	,TADRS TADRS,0,2}/* ファイル名 */
	,{"FILES.ATRB"	,Sfiles	,TADRS,1,3}	/* ファイル属性 */
	,{"FILES.LEN"	,Sfiles	,TADRS,1,4}	/* ファイル長 */
	,{"FILES.TIME"	,Sfiles	,TADRS,1,5}	/* ファイル作成時刻 */
	,{"FILES.DATE"	,Sfiles	,TADRS,1,6}	/* ファイル作成日付 */
	// 必要なワークエリアの大きさを返す
	,{"FILBUF"	,Sdconst,TNONE,1,0}
	,{"MAXPATH"	,Sdconst,TNONE,1,1}
	,{"MAXFILE"	,Sdconst,TNONE,1,2}
	,{"MAXEXT"	,Sdconst,TNONE,1,3}
	,{"MAXDIR"	,Sdconst,TNONE,1,4}
	,{"MAXDRIVE"	,Sdconst,TNONE,1,5}
	// ファイル系定数
	,{"FA_ARCH"	,Sdconst,TNONE,1,6}
	,{"FA_DIREC"	,Sdconst,TNONE,1,7}
	,{"FA_RONLY"	,Sdconst,TNONE,1,8}
	,{"FA_HIDE"	,Sdconst,TNONE,1,9}
	,{"FA_SYS"	,Sdconst,TNONE,1,10}
	,{"FA_VOL"	,Sdconst,TNONE,1,11}
	,{NULL		,NULL	,TNONE,0,0}
};

/*****************************************************************************/
