/* 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 ); }
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 ); }
/* DoRM - perform RM on a specified file */ void DoRM( const char *f ) { iolist *fhead = NULL; iolist *ftail = NULL; iolist *tmp; iolist *dhead = NULL; iolist *dtail = NULL; char *bo; char fpath[_MAX_PATH]; char tmppath[_MAX_PATH]; int i; int j; int k; int l; size_t len; DIR *d; struct dirent *nd; char wild[_MAX_PATH]; char *err; void *crx = NULL; /* get file path prefix */ fpath[0] = 0; for( i = ( int ) strlen( f ); i >= 0; i-- ) { if( f[i] == ':' || f[i] == '\\' || f[i] == '/' ) { fpath[i + 1] = 0; for( j = i; j >= 0; j-- ) fpath[j] = f[j]; i = -1; } } d = OpenDirAll( f, wild ); if( d == NULL ) { PrintALineThenDrop( "File (%s) not found.", f ); if( !fflag ) { error_occured = 1; } return; } if( rxflag ) { err = FileMatchInit( &crx, wild ); if( err != NULL ) Die( "\"%s\": %s\n", err, wild ); } k = ( int ) strlen( fpath ); while( ( nd = readdir( d ) ) != NULL ) { FNameLower( nd->d_name ); if( rxflag ) { if( !FileMatch( crx, nd->d_name ) ) continue; } else { if( !FileMatchNoRx( nd->d_name, wild ) ) continue; } /* set up file name, then try to delete it */ l = ( int ) strlen( nd->d_name ); bo = tmppath; for( i = 0; i < k; i++ ) *bo++ = fpath[i]; for( i = 0; i < l; i++ ) *bo++ = nd->d_name[i]; *bo = 0; if( nd->d_attr & _A_SUBDIR ) { /* process a directory */ if( !IsDotOrDotDot( nd->d_name ) ) { if( rflag ) { /* build directory list */ len = strlen( tmppath ); tmp = MemAlloc( sizeof( iolist ) + len ); if( dtail == NULL ) dhead = tmp; else dtail->next = tmp; dtail = tmp; memcpy( tmp->name, tmppath, len + 1 ); } else { PrintALineThenDrop( "%s is a directory, use -r", tmppath ); error_occured = 1; } } } else if( ( nd->d_attr & _A_RDONLY ) && !fflag ) { PrintALineThenDrop( "%s is read-only, use -f", tmppath ); error_occured = 1; } else { /* build file list */ len = strlen( tmppath ); tmp = MemAlloc( sizeof( iolist ) + len ); if( ftail == NULL ) fhead = tmp; else ftail->next = tmp; ftail = tmp; memcpy( tmp->name, tmppath, len + 1 ); tmp->attr = nd->d_attr; } } closedir( d ); if( rxflag ) FileMatchFini( crx ); /* process any files found */ tmp = fhead; if( tmp == NULL && !fflag ) { PrintALineThenDrop( "File (%s) not found.", f ); error_occured = 1; } while( tmp != NULL ) { if( tmp->attr & _A_RDONLY ) chmod( tmp->name, PMODE_RW ); if( iflag ) { PrintALine( "Delete %s (y\\n)", tmp->name ); while( ( i = tolower( getch() ) ) != 'y' && i != 'n' ) ; DropALine(); if( i == 'y' ) remove( tmp->name ); } else { if( !sflag ) PrintALine( "Deleting file %s", tmp->name ); remove( tmp->name ); } ftail = tmp; tmp = tmp->next; MemFree( ftail ); } /* process any directories found */ if( rflag && ( tmp = dhead ) != NULL ) { while( tmp != NULL ) { RecursiveRM( tmp->name ); dtail = tmp; tmp = tmp->next; MemFree( dtail ); } } }