/*
	dskvf.c
	lcc dskvf -ltinymain.obj -lintlib
*/
#define PROGRAM   "ボリュームネームと空き容量"
#define VERSION   "V0.02"
#define FIRSTDATE "94/11/04"
#define FINALDATE "95/02/07"
#define USAGE     "" \
" usage1: dskvf [drive[:]]\n" \
" usage2: dskvf [drive[:]] [-v vol] [-f nnn<kb>]\n" \
" usage3: dskvf [drive[:]] [-v vol1 [vol2] [vol3].. ]"

#define MAIN

#define ulong unsigned long
#define uint unsigned short
#define byte unsigned char
#define ON 1
#define OFF 0

#include "calo.h"
#include <string.h>
#include <ctype.h>
#include <dos.h>

void dskrep( char dv,char *n,ulong a,ulong b,ulong c,ulong d );
int far hrde(unsigned deverror, unsigned errcode, unsigned far *devhdr);

unsigned herrd,herrc;

int main( int argc, char *argv[] ){

	ulong fr = 0;
	char *voln[10];
	int vlmax = 0;
	char dv = NULL,vd = OFF,db = OFF;
	char pn[20];
	int ret;

	struct find_t fnbuf[1];
        struct diskfree_t frb[1];

	int i;

	_harderr(&hrde);

	for( i = 1 ; i < argc ; i++ ){
		if( argv[i][0]=='-' || argv[i][0]=='/' ) {
			switch ( argv[i][1] ) {
			case 'v':
			case 'V':
				do{
					if( i == argc ) break;
					voln[vlmax++] = argv[++i];
				}while( argv[i][0] != '-' && argv[i][0] != '/' );
				i--;
				vlmax--;
				break;
			case 'f':
			case 'F':
				fr = atol( argv[++i] );
				break;
			case 'r':
			case 'R':
				vd = ON;
				break;
			case 'd':
			case 'D':
				db = ON;
				break;
			case 'h':
			case 'H':
			case '?':
				usage( argv[0] );
			default:
				break;
			/*	if( i == 1 ) dv = toupper( argv[i][0] ); */
			/*	if( i == 1 )
					dv = ( argv[i][0] >= 'a' ?
						argv[i][0]-0x20 : argv[i][0] );
				else usage( argv[0] );
			*/
			}
			continue;
		}

		if( i == 1 )
			dv = ( argv[i][0] >= 'a' ? /* toupper */
				argv[i][0]-0x20 : argv[i][0] );
	}
	
#ifdef DEBUG
	for( i = 0 ; i < vlmax ; i++ ) printf("%s ",voln[i]);
	printf("-f:%d\n",fr);
#endif 

	if( vd == ON ){
		strcpy(pn,"a:*.*");
		for( i = 26 ; i > 0 ; i-- ){
			*pn = i + 'A' - 1;
			if( _dos_findfirst( pn , _A_VOLID , fnbuf) == 0 ){
				printf("%s/ '%s'\n",pn,fnbuf->name);
				if( strcmp("VDISK",fnbuf->name) == 0 ) break;
			}
		}
		printf("ret %c %d\n",*pn,i);
		return i;
	}

	/* ボリュームラベルを読む */
	if( ( pn[1] = NULL, pn[0] = dv ) == NULL ){
		strcpy( pn , "*.*" );
		{
		/* カレントドライブの取得 */
		unsigned dd;
		_dos_getdrive( &dd );
		dv = dd + 'A' - 1;
		}
	}
	else  strcat( pn , ":*.*" );
	if( _dos_findfirst( pn , _A_VOLID , fnbuf) != 0 ){
#ifdef DEBUG
		fprintf(stderr,"herrc %d herrd %d\n",herrc,herrd);
		fputs( pn , stderr );
#endif 
		if( herrc != 0 ) perror( argv[0] );
	}

	/* ディスク容量を調べる */
	/* 65535 cluster より多くは駄目 msdosの制限? */
	if( herrc == 0 )
	if( _dos_getdiskfree( dv -'A'+1 , frb ) != 0 ){
#ifdef DEBUG
		fprintf( stderr, "dv:[%02x]\n",dv );
#endif 
	}

	{
	/* ピリオドをキャンセル */
	char *pp;
	pp = pn;
	for( i = 0 ; fnbuf->name[i] != NULL ; i++ ){
		if( i != 8 ) 
			*pp++ = fnbuf->name[i];
	}
	*pp = NULL;
	}

	/* usage1 */
	if( vlmax == 0 && fr == 0 )
		dskrep(dv,pn,frb->total_clusters,frb->avail_clusters,frb->sectors_per_cluster,frb->bytes_per_sector);

	/* usage3 */
	for( ret = vlmax ; ret >= 1 ; ret-- ){
		if(strcmp(voln[ret-1],pn)==0)
			break;
	}
	/* usage2 */
	if( ret == 1 || vlmax == 0 && fr > 0 ){
		ulong frl;
		frl = frb->avail_clusters * frb->sectors_per_cluster * frb->bytes_per_sector / 1024L ;
		if( frl >  fr ) ret = 2;
		if( frl == fr ) ret = 1;
		if( frl <  fr ) ret = 0;
	}
	if( db == ON )
		fprintf(stderr,"'%s' return code %d\n",pn,ret);
	return( ret );
}

void dskrep( char dv,char *n,ulong a,ulong b,ulong c,ulong d ){
	printf("Volumelabel: %c-drive '%s'\n",dv,n);
	if( d == 0 ){
		puts("使用不可");
		exit(0);
	}
	/* 65535 cluster より多くは駄目 msdosの制限? */
	if( a == 65535 ) printf("%9s","?????");
	else printf("%9ld",a);
	printf(": 総クラスタ数\n");
	printf("%9ld: 使用可能クラスタ数\n",b);
	printf("%9ld: クラスタあたりのセクタ数\n",c);
	printf("%9ld: セクタあたりのバイト数\n",d);
	printf("%9ld: 空き容量(kb)\n",b*c*d/1024L);
	exit(0);
}


int far hrde(unsigned deverror, unsigned errcode, unsigned far *devhdr){
	herrd = deverror;
	herrc = errcode;
	return _HARDERR_FAIL;
}
