/* 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 ); } } }
/* * recursiveCp - copy a file to a directory (recursively entered) * * source_head points to a buffer of size _MAX_PATH that ends with a ':' * or a FILESEP. * source_tail points to the null terminator of source_head. * source_wild is the filename/pattern to append to source_head to get the * names of the file(s) to copy. * dest_head points to a buffer of size _MAX_PATH that ends with a ':' * or a FILESEP * dest_tail points to the null terminator of dest_head. * * Note that the buffers source_head/dest_head are passed down the * recursion to save stack space. */ static void recursiveCp( char *source_head, char *source_tail, char *source_wild, char *dest_head, char *dest_tail ) { DIR *directory; struct dirent *nextdirentry; void *crx = NULL; char *new_source_tail; char *new_dest_tail; pathCopy( source_head, source_tail, "*.*" ); directory = opendir( source_head ); if( directory == NULL ) { DropPrintALine( "file \"%s\" not found", source_head ); return; } if( rxflag ) { char *err = FileMatchInit( &crx, source_wild ); if( err != NULL ) { Die( "\"%s\": %s\n", err, source_wild ); } } /* * loop through all files */ while( ( nextdirentry = readdir( directory ) ) != NULL ) { /* * set up file name, then try to copy it */ FNameLower( nextdirentry->d_name ); if( rxflag ) { if( !FileMatch( crx, nextdirentry->d_name ) ) { continue; } } else { if( !FileMatchNoRx( nextdirentry->d_name, source_wild ) ) { continue; } } new_source_tail = pathCopy( source_head, source_tail, nextdirentry->d_name ); new_dest_tail = pathCopy( dest_head, dest_tail, nextdirentry->d_name ); if( nextdirentry->d_attr & _A_SUBDIR ) { if( !IsDotOrDotDot( nextdirentry->d_name ) && rflag ) { int rc; rc = mkdir( dest_head ); if( !rc ) { DirCnt++; } if( !sflag ) { if( rc ) { PrintALineThenDrop( "directory %s already exists", dest_head ); } else { PrintALineThenDrop( "created new directory %s", dest_head ); } } new_dest_tail = pathCopy( dest_head, new_dest_tail, FILESEPSTR ); new_source_tail = pathCopy( source_head, new_source_tail, FILESEPSTR ); recursiveCp( source_head, new_source_tail, rxflag ? "*" : "*.*", dest_head, new_dest_tail ); } } else { CopyOneFile( dest_head, source_head ); } } closedir( directory ); if( rxflag ) { FileMatchFini( crx ); } } /* DoCP */
/* * getDir - get current directory list (no sorting) */ static vi_rc getDir( char *dname, bool want_all_dirs ) { DIR *d; struct dirent *nd; direct_ent *tmp; int i, j, len; char wild[FILENAME_MAX]; char path[FILENAME_MAX]; char ch; bool is_subdir; vi_rc rc; /* * initialize for file scan */ len = strlen( dname ); for( i = len - 1; i >= 0; i-- ) { if( dname[i] == '/' || dname[i] == '\\' || dname[i] == ':' ) { break; } } for( j = 0; j < i + 1; j++ ) { path[j] = dname[j]; } path[i + 1] = 0; if( i >= 0 ) { ch = path[i]; } else { ch = 0; } for( j = i + 1; j <= len; j++ ) { wild[j - i - 1] = dname[j]; } rc = FileMatchInit( wild ); if( rc != ERR_NO_ERR ) { return( rc ); } #ifndef __UNIX__ if( ch != '\\' && ch != '/' && ch != ':' && ch != 0 ) { strcat( path, FILE_SEP_STR ); } strcat( path, ALL_FILES_WILD_CARD ); #else if( ch == 0 ) { path[0] = '.'; path[1] = 0; } #endif for( i = 0; i < DirFileCount; i++ ) { MemFree2( &DirFiles[i] ); } DirFileCount = 0; d = opendir( path ); if( d == NULL ) { FileMatchFini(); return( ERR_FILE_NOT_FOUND ); } /* * loop through all directory entries */ while( (nd = readdir( d )) != NULL ) { if( DirFileCount >= MAX_FILES ) { break; } is_subdir = FALSE; #if defined( __QNX__ ) if( nd->d_stat.st_mode & S_IFDIR ) { is_subdir = TRUE; } #elif defined( __UNIX__ ) { struct stat st; stat( nd->d_name, &st ); if( st.st_mode & S_IFDIR ) { is_subdir = TRUE; } } #else if( nd->d_attr & _A_SUBDIR ) { is_subdir = TRUE; } #endif if( !(want_all_dirs && is_subdir) ) { if( !FileMatch( nd->d_name ) ) { continue; } } len = strlen( nd->d_name ); DirFiles[DirFileCount] = MemAlloc( sizeof( direct_ent ) + len ); tmp = DirFiles[DirFileCount]; GetFileInfo( tmp, nd, path ); memcpy( tmp->name, nd->d_name, len + 1 ); FileLower( tmp->name ); DirFileCount++; } FileMatchFini(); closedir( d ); return( ERR_NO_ERR ); } /* getDir */