home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
batch
/
cutils10.arj
/
RMPATH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-17
|
14KB
|
451 lines
/*+M, RmPath.c */
/************************************************************************/
/************************************************************************/
/* */
/* COPYRIGHT (C) G. KLYNE, 1991. All rights reserved. */
/* */
/* Permission to freely distribute this software, or use it */
/* for any purpose, is granted provided that no charge is */
/* levied for its distribution and this notice is retained */
/* in all copies of the source code. */
/* */
/************************************************************************/
/************************************************************************/
/* */
/* */
/* Module name : RmPath */
/* File name : RmPath.c */
/* */
/* */
/* AMENDMENT RECORD */
/* ================ */
/* */
/* 1. V01.0A 19-Feb-1991 Graham Klyne */
/* Program initially created. */
/* */
/* */
/* PROGRAM FUNCTION */
/* ================ */
/* */
/* This program is a simple DOS utility which removes all files */
/* in a directory, and attempts to remove all directories on the */
/* path to that directory. */
/* */
/* The exit code is: */
/* 0 No directory and/or file specified. */
/* 1 Files deleted but no directory specified. */
/* 2 Files deleted but no directories could be deleted. */
/* 3 Files and at least one directory removed. */
/* 4 Could not delete all files in directory. */
/* 6 Error in supplied path name. */
/* */
/* This program assumes that the current default directory does */
/* exist, and no attempt will be made to delete it. */
/* */
/* Any filename and extension (as opposed to directory name) on */
/* the command line is ignored: all files in the indicated */
/* directory are deleted (if possible). */
/* */
/* */
/************************************************************************/
/************************************************************************/
/*-M*/
/************************************************************************/
/* External declarations used */
/************************************************************************/
#define LINT_ARGS
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <io.h>
#include <dos.h>
/************************************************************************/
/* External entry points declared in this module */
/************************************************************************/
/* No external entry points */
/************************************************************************/
/* Local definitions */
/************************************************************************/
#define FALSE 0
#define TRUE 1
/************************************************************************/
/* Local type declarations */
/************************************************************************/
typedef struct FileDetail_str
{
char Context[21] ; /* Search context for "FindNextFile" */
char Attributes ; /* File attributes */
short int Time ; /* Time file written HHHHHMMMMMMSSSSS */
short int Date ; /* Date file written YYYYYYYMMMMDDDDD */
long int Size ; /* File size in bytes */
char Name[13] ; /* File name and extension */
}
FileDetail, *FileDetail_ptr ;
/************************************************************************/
/* Local variable declarations */
/************************************************************************/
/* No local variables */
/*+F*/
/************************************************************************/
/* *-FindFirstFile, Find first file matching given specification */
/************************************************************************/
/*
/* This function finds the first file matching a given specification.
/*
/* PARAMETERS
/* ----------
/* ReqPath points to a string containing the ambiguous file
/* name (including drive and path) to be matched.
/* ReqAttr indicates the types of files to be located:
/* 0x01 Include read-only files.
/* 0x02 Include hidden files.
/* 0x04 Include system files.
/* 0x08 Include volume identifier file.
/* 0x10 Include directory files.
/* Any combination of the above options may be
/* specified.
/* FilAttr points to a "FileDetail" structure which receives
/* additional information about the file, and other data
/* required by subsequent calls of "FindNextFile".
/* FilSize is the size of the supplied "FilBuff" buffer.
/* FilBuff points to a buffer which receives the filename
/* (including drive and path) as a NULL-terminated
/* string.
/*
/* RESULT
/* ------
/* The result returned is FALSE if no file is found, otherwise TRUE.
/*
/* NOTES
/* -----
/* This routine assumes that the current DTA and the supplied file
/* details structure both lie in the default data segment.
/*
/* If the serach is to include directories, the special files "."
/* and ".." may be returned.
/*
/*-F*/
int FindFirstFile
( const char *ReqPath, int ReqAttr,
FileDetail *FilAttr,
int FilSize, char *FilBuff )
{
union REGS InpRegs, OutRegs ;
int SaveDTA ;
int Status ;
int Length ;
int i ;
/*--------------------------------------------------------------*/
/* Copy file path to result buffer */
/*--------------------------------------------------------------*/
Status = FALSE ;
Length = strlen( ReqPath ) ;
while ( ( Length > 0 ) &&
( ReqPath[Length-1] != '\\' ) &&
( ReqPath[Length-1] != '/' ) ) Length-- ;
if ( Length+13 > FilSize )
{
printf( "RmPath: supplied path '%s' is too long\n", ReqPath ) ;
exit( 6 ) ;
}
strncpy( FilBuff, ReqPath, FilSize ) ;
FilBuff[Length] = '\0' ;
/*--------------------------------------------------------------*/
/* Save current DTA, and set new value */
/*--------------------------------------------------------------*/
InpRegs.x.ax = 0x2F00 ;
intdos( &InpRegs, &OutRegs ) ;
SaveDTA = OutRegs.x.bx ;
InpRegs.x.ax = 0x1A00 ;
InpRegs.x.dx = FP_OFF( FilAttr ) ;
intdos( &InpRegs, &OutRegs ) ;
/*--------------------------------------------------------------*/
/* Find file */
/*--------------------------------------------------------------*/
InpRegs.x.ax = 0x4E00 ;
InpRegs.x.cx = ReqAttr ;
InpRegs.x.dx = FP_OFF( ReqPath ) ;
intdos( &InpRegs, &OutRegs ) ;
if ( OutRegs.x.cflag == 0 ) Status = TRUE ;
/*--------------------------------------------------------------*/
/* Restore original DTA */
/*--------------------------------------------------------------*/
InpRegs.x.ax = 0x1A00 ;
InpRegs.x.dx = SaveDTA ;
intdos( &InpRegs, &OutRegs ) ;
/*--------------------------------------------------------------*/
/* Sort out result */
/*--------------------------------------------------------------*/
if ( Status )
{
i = 0 ;
while ( ( FilAttr->Name[i] != '\0' ) && ( i < 12 ) )
{
FilBuff[Length++] = FilAttr->Name[i++] ;
}
FilBuff[Length] = '\0' ;
}
return Status ;
} ; // End of function FindFirstFile
/*+F*/
/************************************************************************/
/* *-FindNextFile, Find next file matching given specification */
/************************************************************************/
/*
/* This function finds the next file matching a given specification,
/* following a previous call of "FindFirstFile" and possible calls
/* of this function.
/*
/* Attributes for the required files are carried over from the
/* original call of "FindFirstFile".
/*
/* PARAMETERS
/* ----------
/* ReqPath points to a string containing the ambiguous file
/* name (including drive and path) to be matched.
/* FilAttr points to a "FileDetail" structure which receives
/* additional information about the file, and other data
/* required by subsequent calls of "FindNextFile".
/* FilSize is the size of the supplied "FilBuff" buffer.
/* FilBuff points to a buffer which receives the filename
/* (including drive and path) as a NULL-terminated
/* string.
/*
/* RESULT
/* ------
/* The result returned is FALSE if no file is found, otherwise TRUE.
/*
/* NOTE
/* ----
/* This routine assumes that the current DTA and the supplied file
/* details structure both lie in the default data segment.
/*
/*-F*/
int FindNextFile
( const char *ReqPath,
FileDetail *FilAttr,
int FilSize, char *FilBuff )
{
union REGS InpRegs, OutRegs ;
int SaveDTA ;
int Status ;
int Length ;
int i ;
/*--------------------------------------------------------------*/
/* Copy file path to result buffer */
/*--------------------------------------------------------------*/
Status = FALSE ;
Length = strlen( ReqPath ) ;
while ( ( Length > 0 ) &&
( ReqPath[Length-1] != '\\' ) &&
( ReqPath[Length-1] != '/' ) ) Length-- ;
if ( Length+13 > FilSize )
{
printf( "RmPath: supplied path '%s' is too long\n", ReqPath ) ;
exit( 6 ) ;
}
strncpy( FilBuff, ReqPath, FilSize ) ;
FilBuff[Length] = '\0' ;
/*--------------------------------------------------------------*/
/* Save current DTA, and set new value */
/*--------------------------------------------------------------*/
InpRegs.x.ax = 0x2F00 ;
intdos( &InpRegs, &OutRegs ) ;
SaveDTA = OutRegs.x.bx ;
InpRegs.x.ax = 0x1A00 ;
InpRegs.x.dx = FP_OFF( FilAttr ) ;
intdos( &InpRegs, &OutRegs ) ;
/*--------------------------------------------------------------*/
/* Find file */
/*--------------------------------------------------------------*/
InpRegs.x.ax = 0x4F00 ;
intdos( &InpRegs, &OutRegs ) ;
if ( OutRegs.x.cflag == 0 ) Status = TRUE ;
/*--------------------------------------------------------------*/
/* Restore original DTA */
/*--------------------------------------------------------------*/
InpRegs.x.ax = 0x1A00 ;
InpRegs.x.dx = SaveDTA ;
intdos( &InpRegs, &OutRegs ) ;
/*--------------------------------------------------------------*/
/* Sort out result */
/*--------------------------------------------------------------*/
if ( Status )
{
i = 0 ;
while ( ( FilAttr->Name[i] != '\0' ) && ( i < 12 ) )
{
FilBuff[Length++] = FilAttr->Name[i++] ;
}
FilBuff[Length] = '\0' ;
}
return Status ;
} ; // End of function FindNextFile
/*+T*/
/************************************************************************/
/* *-main, Main Program */
/************************************************************************/
/*
/* This program reads commands from standard input and submits
/* them for execution, each in its own command shell.
/*
/*-T*/
void main( int argc, char *(argv[]), char *(envp[]) )
{
int Status ;
char DirPath[132] ;
char FilPath[144] ;
FileDetail FilAttr ;
int l ;
int r ;
/*--------------------------------------------------------------*/
/* Entry point here */
/*--------------------------------------------------------------*/
Status = 0 ;
if ( argc < 2 )
{
printf( "Usage: RmPath path\n"
" Remove all files in the indicated directory,\n"
" and remove all directories on the path.\n\n"
" Note: Any filename specified in 'path' is ignored:\n"
" removes ALL files in the given directory.\n" ) ;
printf( "\n"
"Exit status: 0: no file or directory specified.\n"
" 1: files deleted but no directory specified.\n"
" 2: files deleted but no directories removed.\n"
" 3: files and at least one directory removed.\n"
" 4: failed to delete all files in directory.\n"
" 6: error in supplied path.\n" ) ;
printf( "\n"
"Copyright (C) 1991 Graham Klyne. All rights reserved.\n" ) ;
exit( 0 ) ;
}
/*--------------------------------------------------------------*/
/* Copy path to local buffer and force '*.*' filename */
/*--------------------------------------------------------------*/
l = strlen( argv[1] ) ;
if ( l >= 128 )
{
printf( "RmPath: supplied path '%s' is too long\n", argv[1] ) ;
exit( 6 ) ;
}
strcpy( DirPath, argv[1] ) ;
while ( ( l > 0 ) &&
( DirPath[l-1] != '\\' ) &&
( DirPath[l-1] != '/' ) ) l-- ;
DirPath[l++] = '*' ;
DirPath[l++] = '.' ;
DirPath[l++] = '*' ;
DirPath[l++] = '\0' ;
/*--------------------------------------------------------------*/
/* Delete files in specified directory */
/*--------------------------------------------------------------*/
Status = FindFirstFile( DirPath, 0, &FilAttr, 144, FilPath ) ;
while ( Status )
{
r = remove( FilPath ) ;
if ( r != 0 )
{
printf( "Failed to delete file '%s'\n", FilPath ) ;
exit( 4 ) ;
}
Status = FindNextFile( DirPath, &FilAttr, 144, FilPath ) ;
}
/*--------------------------------------------------------------*/
/* Remove directories on path */
/*--------------------------------------------------------------*/
Status = 1 ; // No directory
while ( l > 0 )
{
while ( ( l > 0 ) &&
( DirPath[l] != '\\' ) &&
( DirPath[l] != '/' ) ) l-- ;
if ( l > 0 )
{
DirPath[l] = '\0' ;
r = rmdir( DirPath ) ;
if ( r != 0 )
{
if ( Status == 1 )
{
printf( "Failed to remove directory '%s'\n", DirPath ) ;
Status = 2 ;
}
break ;
}
Status = 3 ;
}
}
/*--------------------------------------------------------------*/
/* Exit */
/*--------------------------------------------------------------*/
exit( Status ) ;
} ; /* End of procedure main */
/************************************************************************/
/* End of module RmPath */
/************************************************************************/