recursive.cc (zutils-1.8.tar.lz) | : | recursive.cc (zutils-1.9.tar.lz) | ||
---|---|---|---|---|
/* Zutils - Utilities dealing with compressed files | /* Zutils - Utilities dealing with compressed files | |||
Copyright (C) 2009-2019 Antonio Diaz Diaz. | Copyright (C) 2009-2020 Antonio Diaz Diaz. | |||
This program is free software: you can redistribute it and/or modify | This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | (at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | */ | |||
// Returns true if full_name is a regular file with an enabled extension | /* Returns true if full_name is a regular file with an enabled extension | |||
// or (a link to) a directory. | or (a link to) a directory. */ | |||
bool test_full_name( const std::string & full_name, const struct stat * stp, | bool test_full_name( const std::string & full_name, const struct stat * stp, | |||
const bool follow ) | const bool follow ) | |||
{ | { | |||
struct stat st, st2; | struct stat st, st2; | |||
if( follow && stat( full_name.c_str(), &st ) != 0 ) return false; | if( follow && stat( full_name.c_str(), &st ) != 0 ) return false; | |||
if( !follow && lstat( full_name.c_str(), &st ) != 0 ) return false; | if( !follow && lstat( full_name.c_str(), &st ) != 0 ) return false; | |||
if( S_ISREG( st.st_mode ) ) // regular file | if( S_ISREG( st.st_mode ) ) // regular file | |||
return enabled_format( extension_format( extension_index( full_name ) ) ); | return enabled_format( extension_format( extension_index( full_name ) ) ); | |||
if( !S_ISDIR( st.st_mode ) ) return false; | if( !S_ISDIR( st.st_mode ) ) return false; | |||
skipping to change at line 44 | skipping to change at line 44 | |||
{ | { | |||
while( i > 0 && prev_dir[i-1] != '/' ) --i; | while( i > 0 && prev_dir[i-1] != '/' ) --i; | |||
if( i == 0 ) break; | if( i == 0 ) break; | |||
if( i > 1 ) --i; // remove trailing slash except at root dir | if( i > 1 ) --i; // remove trailing slash except at root dir | |||
prev_dir.resize( i ); | prev_dir.resize( i ); | |||
if( stat( prev_dir.c_str(), &st2 ) != 0 || !S_ISDIR( st2.st_mode ) || | if( stat( prev_dir.c_str(), &st2 ) != 0 || !S_ISDIR( st2.st_mode ) || | |||
( st.st_ino == st2.st_ino && st.st_dev == st2.st_dev ) ) | ( st.st_ino == st2.st_ino && st.st_dev == st2.st_dev ) ) | |||
{ loop = true; break; } | { loop = true; break; } | |||
} | } | |||
if( loop ) // full_name already visited or above tree | if( loop ) // full_name already visited or above tree | |||
show_file_error( full_name.c_str(), "warning: Recursive directory loop" ); | show_file_error( full_name.c_str(), "warning: Recursive directory loop." ); | |||
return !loop; // (link to) directory | return !loop; // (link to) directory | |||
} | } | |||
// Returns in input_filename the next filename. | /* Returns in input_filename the next filename, or "." for stdin. | |||
("." was chosen because it is not a valid filename). | ||||
Sets 'error' to true if a directory fails to open. */ | ||||
bool next_filename( std::list< std::string > & filenames, | bool next_filename( std::list< std::string > & filenames, | |||
std::string & input_filename, bool & error, | std::string & input_filename, bool & error, | |||
const int recursive, const bool ignore_stdin = false, | const int recursive, const bool ignore_stdin = false, | |||
const bool no_messages = false ) | const bool no_messages = false ) | |||
{ | { | |||
while( !filenames.empty() ) | while( !filenames.empty() ) | |||
{ | { | |||
input_filename = filenames.front(); | input_filename = filenames.front(); | |||
filenames.pop_front(); | filenames.pop_front(); | |||
if( input_filename.empty() || input_filename == "-" ) | if( input_filename == "-" ) | |||
{ | { | |||
if( ignore_stdin ) continue; | if( ignore_stdin ) continue; | |||
input_filename.clear(); return true; | input_filename = "."; return true; | |||
} | } | |||
struct stat st; | struct stat st; | |||
if( stat( input_filename.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) ) | if( stat( input_filename.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) ) | |||
{ | { | |||
if( recursive ) | if( recursive ) | |||
{ | { | |||
DIR * const dirp = opendir( input_filename.c_str() ); | DIR * const dirp = opendir( input_filename.c_str() ); | |||
if( !dirp ) | if( !dirp ) | |||
{ | { | |||
if( !no_messages ) | if( !no_messages ) | |||
End of changes. 8 change blocks. | ||||
19 lines changed or deleted | 21 lines changed or added |