/* start of mainline */ int main( int argc, char *argv[] ) { int i; int ch; DIR *d; /* process options */ while( ( ch = GetOpt( &argc, argv, "firRsvX", usageMsg ) ) != -1 ) { switch( ch ) { case 'f': fflag = TRUE; iflag = FALSE; break; case 'i': iflag = TRUE; fflag = FALSE; break; case 'R': case 'r': rflag = TRUE; break; case 's': sflag = TRUE; break; case 'v': sflag = FALSE; break; case 'X': rxflag = TRUE; break; } } if( argc < 2 ) Quit( usageMsg, "No filename/directory specified\n" ); StartPrint(); /* process -r option */ if( rflag ) { for( i = 1; i < argc; i++ ) { if( strcmp( argv[i], rxflag ? "*" : "*.*" ) == 0 ) RecursiveRM( "." ); else { d = FileNameWild( argv[i], rxflag ) ? NULL : opendir( argv[i] ); if( d != NULL ) { if( !( d->d_attr & _A_SUBDIR ) ) { closedir( d ); if( fflag ) DoRM( argv[i] ); else PrintALineThenDrop( "%s is not a directory.", argv[i] ); } else { closedir( d ); RecursiveRM( argv[i] ); } } else if( !fflag ) { PrintALineThenDrop( "Directory %s not found.", argv[i] ); error_occured = 1; } } } } else { /* run through all specified files */ for( i = 1; i < argc; i++ ) DoRM( argv[i] ); } DropALine(); return( error_occured ); }
/* RecursiveRM - do an RM recursively on all files */ void RecursiveRM( const char *dir ) { int i; char fname[_MAX_PATH]; /* purge the files */ strcpy( fname, dir ); strcat( fname, ( rxflag ) ? "/*" : "/*.*" ); DoRM( fname ); /* purge the directory */ if( iflag ) { PrintALine( "Delete directory %s (y\\n)", dir ); while( ( i = tolower( getch() ) ) != 'y' && i != 'n' ) ; DropALine(); } else i = 'y'; if( i == 'y' ) DoRMdir( dir ); }
static int ProcRm( char *cmd ) { char buffer[_MAX_PATH]; int retval = 0; /* gather options */ for( ;; ) { while( isspace( *cmd ) ) ++cmd; if( *cmd != '-' ) break; ++cmd; while( isalpha( *cmd ) ) { switch( *cmd++ ) { case 'f': fflag = true; break; case 'R': case 'r': rflag = true; break; case 'v': sflag = false; break; default: return( 1 ); } } } if( rflag ) { /* process -r option */ while( (cmd = GetString( cmd, buffer )) != NULL ) { if( strcmp( buffer, MASK_ALL_ITEMS ) == 0 ) { int rc = RecursiveRM( "." ); if( rc != 0 ) { retval = rc; } } else if( strpbrk( buffer, WILD_METAS ) != NULL ) { // wild cards is not processed for directories continue; } else { struct stat buf; if( stat( buffer, &buf ) == 0 ) { if( S_ISDIR( buf.st_mode ) ) { int rc = RecursiveRM( buffer ); if( rc != 0 ) { retval = rc; } } else { int rc = DoRM( buffer ); if( rc != 0 ) { retval = rc; } } } } } } else { /* run through all specified files */ while( (cmd = GetString( cmd, buffer )) != NULL ) { int rc = DoRM( buffer ); if( rc != 0 ) { retval = rc; } } } return( retval ); }
/* DoRM - perform RM on a specified file */ static int DoRM( const char *f ) { iolist *tmp; iolist *dhead = NULL; iolist *dtail = NULL; char fpath[_MAX_PATH]; char fname[_MAX_PATH]; char *fpathend; size_t i; size_t j; size_t len; DIR *d; struct dirent *nd; int rc; int retval = 0; /* separate file name to path and file name parts */ len = strlen( f ); for( i = len; i > 0; --i ) { char ch = f[i - 1]; if( ch == '/' || ch == '\\' || ch == ':' ) { break; } } j = i; /* if no path then use current directory */ if( i == 0 ) { fpath[i++] = '.'; fpath[i++] = '/'; } else { memcpy( fpath, f, i ); } fpathend = fpath + i; *fpathend = '\0'; #ifdef __UNIX__ memcpy( fname, f + j, len - j + 1 ); #else if( strcmp( f + j, MASK_ALL_ITEMS ) == 0 ) { fname[0] = '*'; fname[1] = '\0'; } else { memcpy( fname, f + j, len - j + 1 ); } #endif d = opendir( fpath ); if( d == NULL ) { Log( false, "File (%s) not found.\n", f ); return( ENOENT ); } while( (nd = readdir( d )) != NULL ) { #ifdef __UNIX__ struct stat buf; if( fnmatch( fname, nd->d_name, FNM_PATHNAME | FNM_NOESCAPE ) == FNM_NOMATCH ) #else if( fnmatch( fname, nd->d_name, FNM_PATHNAME | FNM_NOESCAPE | FNM_IGNORECASE ) == FNM_NOMATCH ) #endif continue; /* set up file name, then try to delete it */ len = strlen( nd->d_name ); memcpy( fpathend, nd->d_name, len ); fpathend[len] = 0; len += i + 1; #ifdef __UNIX__ stat( fpath, &buf ); if( S_ISDIR( buf.st_mode ) ) { #else if( nd->d_attr & _A_SUBDIR ) { #endif /* process a directory */ if( IsDotOrDotDot( nd->d_name ) ) continue; if( rflag ) { /* build directory list */ tmp = Alloc( offsetof( iolist, name ) + len ); tmp->next = NULL; if( dtail == NULL ) { dhead = tmp; } else { dtail->next = tmp; } dtail = tmp; memcpy( tmp->name, fpath, len ); } else { Log( false, "%s is a directory, use -r\n", fpath ); retval = EACCES; } #ifdef __UNIX__ } else if( access( fpath, W_OK ) == -1 && errno == EACCES && !fflag ) { #else } else if( (nd->d_attr & _A_RDONLY) && !fflag ) { #endif Log( false, "%s is read-only, use -f\n", fpath ); retval = EACCES; } else { rc = remove_item( fpath, false ); if( rc != 0 ) { retval = rc; } } } closedir( d ); /* process any directories found */ for( tmp = dhead; tmp != NULL; tmp = dhead ) { dhead = tmp->next; rc = RecursiveRM( tmp->name ); if( rc != 0 ) { retval = rc; } free( tmp ); } return( retval ); } /* RecursiveRM - do an RM recursively on all files */ static int RecursiveRM( const char *dir ) { int rc; int rc2; char fname[_MAX_PATH]; /* purge the files */ strcpy( fname, dir ); strcat( fname, "/" MASK_ALL_ITEMS ); rc = DoRM( fname ); /* purge the directory */ rc2 = remove_item( dir, true ); if( rc == 0 ) rc = rc2; return( rc ); }