home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 */