home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 1
/
FREEWARE.BIN
/
ms_dos
/
gap
/
gap.c
next >
Wrap
Text File
|
1989-10-17
|
11KB
|
517 lines
/*
* gap.exe
* display information of disk space use efficiency
* 1988 Sey
* 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
*/
#define VERSION "1.3 "
#include <stdio.h>
#include <dos.h>
#include <io.h>
#include <fcntl.h>
#include <dir.h>
#include <ctype.h>
long clussize,clususe,filesize;
long simclussize = 0,simclususe = 0;
int rank_anal = 0,ext_anal = 0,dir_anal = 0;
int freq[10];
long rank[10];
void
usage()
{
printf( "GAP - display cluster gap ver.%s (C) 1988-9 Sey\n"
"usage : GAP <drive> [<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[65];
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 */
/*
* filesearch - search files and do indicated analysis
* returns number of files in the directory
*/
int
filesearch(char *path)
{
struct ffblk ffblk;
int done,files;
char searchpath[MAXPATH];
files = 0;
strcpy(searchpath,path);
strcat(searchpath,"\\*.*");
done = findfirst(searchpath,&ffblk,
FA_DIREC|FA_RDONLY|FA_HIDDEN|FA_SYSTEM);
while(!done)
{
files++;
if( !(ffblk.ff_attrib & FA_DIREC) )
{
filesize += ffblk.ff_fsize;
if( simclussize )
simclususe +=
((ffblk.ff_fsize + simclussize - 1)
/ simclussize) * simclussize;
if( rank_anal && ffblk.ff_fsize )
{
int j;
for( j = 9; j >= 0; j-- )
if( rank[j] >= clussize -
(ffblk.ff_fsize + clussize - 1) %
clussize - 1 )
{
freq[j]++;
break;
}
}
if( ext_anal )
add_ext_list(ffblk.ff_name,
clussize - (ffblk.ff_fsize + clussize - 1) %
clussize - 1 );
if( dir_anal )
add_dir_list(path,
clussize - (ffblk.ff_fsize + clussize - 1) %
clussize - 1 );
}
else if( strcmp(ffblk.ff_name,".")
&& strcmp(ffblk.ff_name,"..") )
{
long subfiles;
strcpy(searchpath,path);
strcat(searchpath,"\\");
strcat(searchpath,ffblk.ff_name);
subfiles = filesearch(searchpath);
if( simclussize )
simclususe +=
((subfiles * 32 + simclussize - 1)
/ simclussize) * simclussize;
if( rank_anal )
freq[0]++;
if( ext_anal )
add_ext_list(ffblk.ff_name,
((subfiles * 32 + clussize - 1)
/ clussize) * clussize );
if( dir_anal )
add_dir_list(path,
((subfiles * 32 + clussize - 1)
/ clussize) * clussize );
}
done = findnext(&ffblk);
}
return( files );
}
/* end filesearch */
/*
* diskstat - display and set fundamental information of the drive
*/
void
diskstat(char *drive)
{
struct dfree dfree;
getdfree( toupper(*drive) - '@',&dfree );
clussize = dfree.df_bsec;
clussize *= dfree.df_sclus;
clususe = dfree.df_total - dfree.df_avail;
clususe *= clussize;
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,dfree.df_bsec,dfree.df_sclus,clussize,dfree.df_total
,dfree.df_avail,dfree.df_total-dfree.df_avail);
}
/* end diskstat */
/*
* disp_... - display each infomation
*/
void
disp_gap()
{
double eff;
eff = (double)filesize / (double)clususe;
printf( "USED CLUSTERS SIZE: %10ld bytes\n"
"TOTAL FILE SIZE : %10ld bytes\n"
"USE EFFICIENCY : %10.2f %%\n"
"GAP : %10ld bytes\n"
,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 */
/*
* main routine
*/
main(int ac,char *av[])
{
int j;
char drive[3];
if( ac != 2 && ac != 3 )
usage();
strcpy( drive,av[1] );
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;
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(drive);
disp_gap();
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 */