home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR4
/
ZEROFI.ZIP
/
ZEROFILE.MOD
< prev
next >
Wrap
Text File
|
1993-06-16
|
6KB
|
220 lines
MODULE Zerofile;
IMPORT FIO, Lib, Str;
FROM IO IMPORT WrStr, WrLn;
TYPE
PathType = ARRAY [0..80] OF CHAR;
VAR
verbose, recursive_scan: BOOLEAN;
errorlevel: SHORTCARD;
path: PathType;
PROCEDURE Wr( s: ARRAY OF CHAR );
BEGIN
WrStr( s );
WrLn
END Wr;
PROCEDURE Banner;
BEGIN
Wr('Zerofile - by P. Below, 1993, Freeware');
Wr('- Search a directory for files of zero length - ');
WrLn;
END Banner;
PROCEDURE Usage;
BEGIN
Banner;
Wr('Usage: zerofile [pathname] [/S] [/Q] [/?]');
WrLn;
Wr('pathname is either the name of a directory or a filespec. If the latter,');
Wr('the filename part may contain wildcards. If pathname is omitted, zerofile');
Wr('will search the current drive.');
WrLn;
Wr('Switches:');
Wr(' /S : search recursively through all subdirectories, if pathname is');
Wr(' a directory.');
Wr(' /Q : quiet, do not display anything on screen.');
Wr(' /? or any other switch will yield this information.');
WrLn;
Wr('Zerofile will return errorlevel 1 if a file with zero length is found,');
Wr('errorlevel 255 if it gets an invalid pathname and 0 otherwise.');
END Usage;
PROCEDURE GetCurrentPath( VAR path: ARRAY OF CHAR );
VAR
drive: ARRAY [0..2] OF CHAR;
BEGIN
drive[0] := CHR( FIO.GetDrive() - 1 + SHORTCARD('A'));
drive[1] := ':';
FIO.GetDir( 0, path );
IF path[0] # '\' THEN
drive[2] := '\'
ELSE
drive[2] := 0C
END;
Str.Prepend( path, drive );
END GetCurrentPath;
PROCEDURE Truncate( VAR path: PathType );
VAR i: CARDINAL;
BEGIN
(* remove the filename part from path *)
i := Str.Length( path );
LOOP
IF i = 0 THEN EXIT END;
DEC( i );
IF (path[i] = ':') OR (path[i] = '\') THEN EXIT END;
path[i] := 0C;
END
END Truncate;
PROCEDURE DotDir( name: FIO.PathTail ): BOOLEAN;
(* returns true, id name is either '.' or '..'. Modula-2 cannot
compare an array of char to a char because these are not compatible
types! *)
BEGIN
RETURN (name[0] = '.') AND ((name[1] = 0C) OR (name[1] = '.'));
END DotDir;
PROCEDURE ScanParams;
VAR
i : CARDINAL;
str : PathType;
BEGIN
FOR i := 1 TO Lib.ParamCount() DO
Lib.ParamStr( str, i ); (* get parameter *)
Str.Caps( str ); (* convert to upper case *)
IF str[0] = '/' THEN (* test for switch *)
CASE str[1] OF (* evaluate switch *)
'S' : recursive_scan := TRUE;
| 'Q' : verbose := FALSE;
ELSE
(* anything else gives the help info and terminates *)
Usage;
errorlevel := 255;
RETURN
END;
ELSE
(* anything not a switch is taken to be a pathname *)
path := str;
END;
END; (* FOR *)
END ScanParams;
PROCEDURE ScanForZerofiles ( VAR path: PathType );
VAR
dir : FIO.DirEntry;
done: BOOLEAN;
BEGIN
done := NOT FIO.ReadFirstEntry( path, FIO.FileAttr{}, dir );
IF FIO.IOresult() <> 0 THEN
(* invalid pathname. give error message if verbose mode *)
IF verbose THEN
WrStr('Invalid pathname: ');
Wr( path );
END;
errorlevel := 255;
done := TRUE
END;
WHILE NOT done DO
IF dir.size = 0 THEN
errorlevel := 1;
IF verbose THEN
Truncate( path );
WrStr( path );
WrStr( dir.Name );
Wr(' has zero bytes length.');
END;
done := TRUE
ELSE
done := NOT FIO.ReadNextEntry( dir );
END;
END; (* WHILE *)
END ScanForZerofiles;
PROCEDURE ScanDirectory( path: PathType );
VAR
dir : FIO.DirEntry;
done: BOOLEAN;
BEGIN
(* path has a directory name, append wildcard *.* filespec for scan *)
IF path[Str.Length(path)-1] <> '\' THEN
Str.Append( path, '\' )
END;
Str.Append( path, '*.*' );
(* scan directory for zero byte files *)
ScanForZerofiles( path );
(* if we did not find any and recursive scan was requested, search for
subdirectories and scan any found *)
IF recursive_scan AND (errorlevel = 0) THEN
done := NOT FIO.ReadFirstEntry( path, FIO.FileAttr{FIO.directory},
dir );
WHILE NOT done DO
IF (FIO.directory IN dir.attr) AND NOT DotDir(dir.Name) THEN
(* found a subdirectory. remove *.* from path and add the subdirs
name instead; then call this procedure recursively *)
Truncate( path );
Str.Append( path, dir.Name );
ScanDirectory( path );
END;
IF errorlevel = 0 THEN
done := NOT FIO.ReadNextEntry( dir )
ELSE
done := TRUE
END;
END; (* WHILE *)
END; (* IF *)
END ScanDirectory;
PROCEDURE ScanFiles( VAR path: PathType );
VAR
dir: FIO.DirEntry;
BEGIN
IF verbose THEN
Banner
END;
IF FIO.Exists( path ) THEN
(* valid filename given *)
IF FIO.ReadFirstEntry( path, FIO.FileAttr{}, dir ) AND
(dir.size = 0) THEN
errorlevel := 1;
END
ELSE
(* directory name assumed, if wildcards present, disable recursive
scan *)
IF (Str.CharPos( path, '*' ) < MAX( CARDINAL )) OR
(Str.CharPos( path, '?' ) < MAX( CARDINAL )) THEN
recursive_scan := FALSE;
ScanForZerofiles( path );
ELSE
ScanDirectory( path );
END;
END;
END ScanFiles;
BEGIN
FIO.IOcheck := FALSE; (* don't terminate on I/O errors *)
verbose := TRUE;
recursive_scan:= FALSE;
errorlevel:= 0;
path:= '';
ScanParams;
IF errorlevel = 0 THEN
IF Str.Length( path ) = 0 THEN
(* no path given, scan current directory *)
GetCurrentPath( path );
END;
ScanFiles( path );
END;
IF (errorlevel = 0) AND verbose THEN
Wr('No files with zero bytes length were found.');
END;
Lib.SetReturnCode( errorlevel );
END Zerofile.