home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FreeWare Collection 2
/
FreeSoftwareCollection2pd199x-jp.img
/
ms_dos
/
gap
/
gap.c
next >
Wrap
Text File
|
1990-06-14
|
14KB
|
641 lines
/*
* gap.exe
* display information of disk space use efficiency
* (C) 1988,9 Sey
* on Turbo C / ver.1.4 or later on LSIC86
* lcc gap.c -lmathlib
* 1988/10/13 1.0
* 10/14 1.1 simulation added
* 10/19 1.2 rank,extention and directory analysis added
* 10/24 1.2a 1 bug fixed
* 1989/ 2/22 1.2b 1 bug fixed
* 3/ 5 1.3 real number available for simulation cluster
* size
* 9/13 1.4 check JOINed directory
* any directory allowed for search object
* 1990/ 3/21 1.4a/T LSIC863.12B2->3.20B1 / test option
*/
#ifdef TEST
#define VERSION "1.4T"
#else
#define VERSION "1.4a"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <ctype.h>
#include <jctype.h>
#define MAXPATH 80
#define MAXDIR 64
long clussize,clususe = 0,filesize = 0;
long simclussize = 0,simclususe = 0;
int rank_anal = 0,ext_anal = 0,dir_anal = 0;
int freq[10];
long rank[10];
#ifdef TEST
int test = 0; /* for testing */
#endif
void
usage()
{
printf( "GAP - display cluster gap ver.%s (C) 1988-9 Sey\n"
"usage : GAP <directory> [<options>]\n"
" <options> : <num> - gap simulation for <num>K bytes"
" cluster\n"
" R - file distribution for gap Rank\n"
" D - gap distribution for Directory\n"
" E - gap distribution for file Extention\n"
"GAP will help you to revive your hard disk."
" GOOD LUCK!\n"
,VERSION);
exit(1);
}
/* end usage */
void
fatal(char *msg)
{
fprintf(stderr,"gap : %s\n",msg);
exit(1);
}
/* end fatal */
void
option_error(void)
{
fprintf(stderr,"gap : unknown option\n\n");
usage();
}
/* end option_error */
/*
* structures and operators for file EXTENSION analysis
*/
struct ext_list
{
char ext[4];
int count;
long gap;
struct ext_list *next;
};
typedef struct ext_list EXT_LIST;
EXT_LIST ext_list0 = { "",0,0,NULL };
EXT_LIST *elp0 = &ext_list0;
int nel = 0;
char
*ext(char *filename)
{
char *p = filename;
while( *p )
if( *p++ == '.' )
break;
return( p );
}
/* end ext */
void
add_ext_list(char *name,long gap)
{
int found = 0;
EXT_LIST *elp,*elp2;
for( elp = elp0; elp->next != NULL; elp = elp->next )
if( strcmp(elp->ext,ext(name)) == 0 )
{
elp->count++;
elp->gap += gap;
found = 1;
break;
}
if( !found )
{
if( (elp2 = (EXT_LIST *)malloc(sizeof(EXT_LIST))) == NULL )
fatal("not enough memory");
strcpy(elp2->ext,ext(name));
elp2->count = 1;
elp2->gap = gap;
elp2->next = elp0;
elp0 = elp2;
nel++;
}
}
/* end add_ext_list */
int
extcmp(EXT_LIST **elpp1,EXT_LIST **elpp2)
{
long gapdiff;
gapdiff = (*elpp1)->gap - (*elpp2)->gap;
if( gapdiff > 0 ) return( -1 );
else if( gapdiff == 0 ) return( 0 );
else return( 1 );
}
/* end extcmp */
void
sort_ext_list()
{
int j;
EXT_LIST *elp,**ela;
if( (ela = (EXT_LIST **)malloc(nel * sizeof(EXT_LIST *))) == NULL )
fatal("not enough memory");
for( j = 0,elp = elp0; elp->next != NULL; j++,elp = elp->next )
ela[j] = elp;
qsort( ela,nel,sizeof(EXT_LIST *),extcmp );
for( j = 0; j < nel - 1; j++ )
ela[j]->next = ela[j+1];
elp0 = ela[0];
ela[nel - 1]->next = &ext_list0;
}
/* end sort_ext_list */
/*
* structures and operators for DIRECTORY analysis
*/
struct dir_list
{
char dir[MAXDIR];
int count;
long gap;
struct dir_list *next;
};
typedef struct dir_list DIR_LIST;
DIR_LIST dir_list0 = { "",0,0,NULL };
DIR_LIST *dlp0 = &dir_list0;
int ndl = 0;
void
add_dir_list(char *name,long gap)
{
int found = 0;
DIR_LIST *dlp,*dlp2;
for( dlp = dlp0; dlp->next != NULL; dlp = dlp->next )
if( strcmp(dlp->dir,name) == 0 )
{
dlp->count++;
dlp->gap += gap;
found = 1;
break;
}
if( !found )
{
if( (dlp2 = (DIR_LIST *)malloc(sizeof(DIR_LIST))) == NULL )
fatal("not enough memory");
strcpy(dlp2->dir,name);
dlp2->count = 1;
dlp2->gap = gap;
dlp2->next = dlp0;
dlp0 = dlp2;
ndl++;
}
}
/* end add_dir_list */
int
dircmp(DIR_LIST **dlpp1,DIR_LIST **dlpp2)
{
long gapdiff;
gapdiff = (*dlpp1)->gap - (*dlpp2)->gap;
if( gapdiff > 0 ) return( -1 );
else if( gapdiff == 0 ) return( 0 );
else return( 1 );
}
/* end dircmp */
void
sort_dir_list()
{
int j;
DIR_LIST *dlp,**dla;
if( (dla = (DIR_LIST **)malloc(ndl * sizeof(DIR_LIST *))) == NULL )
fatal("not enough memory");
for( j = 0,dlp = dlp0; dlp->next != NULL; j++,dlp = dlp->next )
dla[j] = dlp;
qsort( dla,ndl,sizeof(DIR_LIST *),dircmp );
for( j = 0; j < ndl - 1; j++ )
dla[j]->next = dla[j+1];
dlp0 = dla[0];
dla[ndl - 1]->next = &dir_list0;
}
/* end sort_dir_list */
/*
* physical - convert logical(JOIN,SUBST) to physical path name
*/
char
*physical(char *path)
{
static char ret[MAXPATH];
union REGS r;
r.h.ah = 0x30;
intdos(&r,&r);
if( r.h.al < 3 ) /* if DOS 2.x */
{
strcpy(ret,path);
return(ret);
}
r.h.ah = 0x60;
r.x.si = (unsigned)path;
r.x.di = (unsigned)ret;
intdos(&r,&r);
return(ret);
}
/* end physical */
/*
* filesearch - search files and do indicated analysis
* returns number of files in the directory
*/
int
filesearch(char *path)
{
struct find_t find_t;
int done,files;
char searchpath[MAXPATH];
char *physpath;
files = 0;
#ifdef TEST
if( test )
printf("searching for %s\n",path);
#endif
strcpy(searchpath,path);
physpath = physical(searchpath);
if( *physpath != *searchpath ) /* JOINed */
{
#ifdef TEST
if( test )
printf("%s may be a JOINed directory --> skipped\n",searchpath);
#endif
return(2); /* . and .. (JOINed directory must to be empty) */
}
if( searchpath[strlen(searchpath) - 1] == '\\' )
strcat(searchpath,"*.*");
else
strcat(searchpath,"\\*.*");
done = _dos_findfirst(searchpath
,_A_SUBDIR|_A_RDONLY|_A_HIDDEN|_A_SYSTEM,&find_t);
while(!done)
{
files++;
if( !(find_t.attrib & _A_SUBDIR) )
{
#ifdef TEST
if( test )
printf(" %s\n",find_t.name);
#endif
filesize += find_t.size;
clususe += ((find_t.size + clussize - 1) / clussize) * clussize;
if( simclussize )
simclususe +=
((find_t.size + simclussize - 1)
/ simclussize) * simclussize;
if( rank_anal && find_t.size )
{
int j;
for( j = 9; j >= 0; j-- )
if( rank[j] >= clussize -
(find_t.size + clussize - 1) %
clussize - 1 )
{
freq[j]++;
break;
}
}
if( ext_anal )
add_ext_list(find_t.name,
clussize - (find_t.size + clussize - 1) %
clussize - 1 );
if( dir_anal )
add_dir_list(path,
clussize - (find_t.size + clussize - 1) %
clussize - 1 );
}
else if( strcmp(find_t.name,".")
&& strcmp(find_t.name,"..") )
{
long subfiles;
strcpy(searchpath,path);
if( searchpath[strlen(searchpath) - 1] != '\\' )
strcat(searchpath,"\\");
strcat(searchpath,find_t.name);
subfiles = filesearch(searchpath);
clususe += ((subfiles * 32 + clussize - 1) / clussize) * clussize;
if( simclussize )
simclususe +=
((subfiles * 32 + simclussize - 1)
/ simclussize) * simclussize;
if( rank_anal )
freq[0]++;
if( ext_anal )
add_ext_list(find_t.name,
((subfiles * 32 + clussize - 1)
/ clussize) * clussize );
if( dir_anal )
add_dir_list(path,
((subfiles * 32 + clussize - 1)
/ clussize) * clussize );
}
done = _dos_findnext(&find_t); /* dialect of LSIC86 */
}
return( files );
}
/* end filesearch */
/*
* diskstat - display and set fundamental information of a drive
*/
void
diskstat(char *drive)
{
struct diskfree_t diskfree_t; /* dialect of LSIC86 */
_dos_getdiskfree( toupper(*drive) - '@',&diskfree_t );
/* dialect of LSIC86 */
clussize = diskfree_t.bytes_per_sector;
clussize *= diskfree_t.sectors_per_cluster;
printf( "DRIVE : %s\n"
"BYTES / SECTOR : %10u\n"
"SECTORS / CLUSTER : %10u\n"
"CLUSTER SIZE : %10ld bytes\n"
"TOTAL CLUSTERS : %10u\n"
"FREE CLUSTERS : %10u\n"
"USED CLUSTERS : %10u\n"
,drive
,diskfree_t.bytes_per_sector
,diskfree_t.sectors_per_cluster
,clussize
,diskfree_t.total_clusters
,diskfree_t.avail_clusters
,diskfree_t.total_clusters - diskfree_t.avail_clusters);
}
/* end diskstat */
/*
* disp_... - display each infomation
*/
void
disp_gap(char *path)
{
double eff;
eff = (double)filesize / (double)clususe;
printf( "SEARCH PATH : %s\n"
"USED CLUSTERS : %10u\n"
"USED CLUSTERS SIZE: %10ld bytes\n"
"TOTAL FILE SIZE : %10ld bytes\n"
"USE EFFICIENCY : %10.2f %%\n"
"GAP : %10ld bytes\n"
,path,(unsigned)(clususe / clussize),clususe
,filesize,eff*100,clususe-filesize);
}
/* end disp_gap */
void
disp_simulation()
{
double simeff;
simeff = (double)filesize / (double)simclususe;
printf( "\n**** simulation ****\n"
"CLUSTER SIZE : %10ld bytes\n"
"USED CLUSTERS SIZE: %10ld bytes\n"
"TOTAL FILE SIZE : %10ld bytes\n"
"USE EFFICIENCY : %10.2f %%\n"
"GAP : %10ld bytes\n"
"ADVANTAGE : %10ld bytes\n"
,simclussize,simclususe,filesize,simeff*100
,simclususe-filesize,clususe-simclususe);
}
/* end disp_simulation */
void
disp_rank_anal()
{
int j;
printf( "\n**** file distribution for gap rank ****\n"
" gap rank : files gap rank : files\n"
"-----------:------- -----------:-------\n" );
for( j = 0; j < 5; j++ )
printf( " - %6ld : %5d - %6ld : %5d\n",
rank[j],freq[j],rank[j+5],freq[j+5] );
}
/* end disp_rank_anal */
void
disp_ext_anal()
{
EXT_LIST *elp;
long gapsum = 0;
int countsum = 0;
sort_ext_list();
printf( "\n**** gap distribution for file extension ****\n"
" ext : files gap average\n"
"-----:---------------------------------------\n" );
for( elp = elp0; elp->next != NULL; elp = elp->next )
{
printf( ".%-3s : %5d %10ld (%6.2f %%) %10ld\n",
elp->ext,elp->count,elp->gap,
(double)elp->gap / (clususe - filesize) * 100,
elp->gap / elp->count );
countsum += elp->count;
gapsum += elp->gap;
}
printf( "-----:---------------------------------------\n"
"total: %5d %10ld (%6.2f %%) %10ld\n",
countsum,gapsum,(double)gapsum / (clususe - filesize) * 100,
gapsum / countsum );
}
/* end disp_ext_anal */
void
disp_dir_anal()
{
DIR_LIST *dlp;
long gapsum = 0;
int countsum = 0;
sort_dir_list();
printf( "\n**** gap distribution for directory ****\n"
" directory\n"
" : files gap average\n"
"-----:---------------------------------------\n" );
for( dlp = dlp0; dlp->next != NULL; dlp = dlp->next )
{
printf( " %s\n"
" : %5d %10ld (%6.2f %%) %10ld\n",
dlp->dir,dlp->count,dlp->gap,
(double)dlp->gap / (clususe - filesize) * 100,
dlp->gap / dlp->count );
countsum += dlp->count;
gapsum += dlp->gap;
}
printf( "-----:---------------------------------------\n"
"total: %5d %10ld (%6.2f %%) %10ld\n",
countsum,gapsum,(double)gapsum / (clususe - filesize) * 100,
gapsum / countsum );
}
/* end disp_dir_anal */
double
strtof(char *str,char **endp)
{
double x = 0.,y = 1.;
int base = 10;
char sign;
char *p = str;
if( *p == '+' || *p == '-' )
sign = *p++;
if( isdigit(*p) )
{
x = *p++ - '0';
while( isdigit(*p) )
x = base * x + *p++ - '0';
if( *p == '.' )
{
p++;
while( isdigit(*p) )
{
y /= base;
x += y * (*p++ - '0');
}
}
}
if( sign == '-' )
x = - x;
*endp = p;
return( x );
}
/* end strtof */
unsigned
setdisk(unsigned driveno)
{
unsigned drives;
_dos_setdrive(driveno,&drives); /* dialect of LSIC86 */
return( drives );
}
/* end setdisk */
void
splitdrive(char *path,char *drive)
{
unsigned driveno;
if( path[1] == ':' )
{
drive[0] = path[0];
}
else
{
_dos_getdrive(&driveno);
drive[0] = '@' + driveno;
}
drive[1] = ':';
drive[2] = '\0';
}
/* end splitdrive */
char
*strupr(char *str)
{
char *p;
for( p = str; *p; p++ )
{
if( iskanji(*p) && iskanji2(*(p + 1)) )
p++;
else
*p = toupper(*p);
}
return(str);
}
/* end strupr */
/*
* main routine
*/
main(int ac,char *av[])
{
int j;
char drive[3],path[MAXPATH];
if( ac != 2 && ac != 3 )
usage();
strcpy(path,av[1]);
if( path[strlen(path) - 1] == ':' )
strcat(path,"\\");
strcpy(path,physical(path));
splitdrive(path,drive);
if( toupper(*drive) - '@' < 1 ||
toupper(*drive) - '@' > setdisk(0xff) )
fatal("not available drive");
if( ac == 3 )
{
char *p;
for( p = av[2]; *p; )
if( isdigit(*p) )
simclussize = strtof(p,&p) * 1024;
else
switch( toupper(*p++) )
{
case 'R': rank_anal = 1; break;
case 'E': ext_anal = 1; break;
case 'D': dir_anal = 1; break;
#ifdef TEST
case 'T': test = 1; break;
#endif
default: option_error();
}
}
diskstat(drive);
if( rank_anal )
for( j = 0; j < 10; j++ )
{
freq[j] = 0;
rank[j] = clussize * (10 - j) / 10;
}
fprintf(stderr,"...working...\r");
filesearch(path);
disp_gap(path);
if( simclussize )
disp_simulation();
if( rank_anal )
disp_rank_anal();
if( dir_anal )
disp_dir_anal();
if( ext_anal )
disp_ext_anal();
}
/* end main */
/* end gap.c */