summaryrefslogtreecommitdiffstats
path: root/zupdate.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--zupdate.cc53
1 files changed, 27 insertions, 26 deletions
diff --git a/zupdate.cc b/zupdate.cc
index 64ca0d3..0d03b65 100644
--- a/zupdate.cc
+++ b/zupdate.cc
@@ -35,6 +35,10 @@
#include <sys/wait.h>
#if defined __MSVCRT__ || defined __OS2__
#include <io.h>
+#if defined __MSVCRT__
+#include <direct.h>
+#define mkdir(name,mode) _mkdir(name)
+#endif
#endif
#include "arg_parser.h"
@@ -96,24 +100,21 @@ void show_help()
" --lz=<command> set compressor and options for lzip format\n"
" --xz=<command> set compressor and options for xz format\n"
" --zst=<command> set compressor and options for zstd format\n"
- "\nValid formats for option '-M' are 'bz2', 'gz', 'lz', 'xz', and 'zst'.\n" );
+ "\nValid formats for option '-M' are 'bz2', 'gz', 'xz', and 'zst'.\n" );
show_help_addr();
}
-void extract_srcdir_name( const std::string & name, std::string & srcdir )
+/* if name contains slash(es), copy name into srcdir up to the last slash,
+ removing a leading dot followed by slash(es) */
+void extract_dirname( const std::string & name, std::string & srcdir )
{
- if( name.empty() || name == "." ) return; // leave srcdir empty
- if( name[name.size()-1] == '/' ) // remove last slash
- { srcdir.assign( name, 0, name.size() - 1 ); return; }
- struct stat st;
- if( stat( name.c_str(), &st ) == 0 && S_ISDIR( st.st_mode ) )
- { srcdir = name; return; }
-
- unsigned size = 0; // size of srcdir without last slash nor basename
- for( unsigned i = name.size(); i > 0; --i )
- if( name[i-1] == '/' ) { size = i - 1; break; }
- if( size > 0 ) srcdir.assign( name, 0, size );
+ unsigned i = 0;
+ unsigned j = name.size();
+ if( j >= 2 && name[0] == '.' && name[1] == '/' ) // remove leading "./"
+ for( i = 2; i < j && name[i] == '/'; ) ++i;
+ while( j > i && name[j-1] != '/' ) --j; // remove last component if any
+ if( j > i ) srcdir.assign( name, i, j - i );
}
@@ -214,7 +215,7 @@ int zupdate_file( const std::string & name, const char * const lzip_name,
if( srcdir.size() && name.compare( 0, srcdir.size(), srcdir ) != 0 )
internal_error( "srcdir mismatch." );
rname = destdir;
- if( rname[rname.size()-1] != '/' && name[srcdir.size()] != '/' )
+ if( rname.end()[-1] != '/' && name[srcdir.size()] != '/' )
rname += '/';
rname.append( name, srcdir.size(), name.size() - srcdir.size() -
std::strlen( extension_from( eindex ) ) );
@@ -395,16 +396,16 @@ int main( const int argc, const char * const argv[] )
const Arg_parser::Option options[] =
{
- { '0', 0, Arg_parser::no },
- { '1', 0, Arg_parser::no },
- { '2', 0, Arg_parser::no },
- { '3', 0, Arg_parser::no },
- { '4', 0, Arg_parser::no },
- { '5', 0, Arg_parser::no },
- { '6', 0, Arg_parser::no },
- { '7', 0, Arg_parser::no },
- { '8', 0, Arg_parser::no },
- { '9', 0, Arg_parser::no },
+ { '0', 0, Arg_parser::no },
+ { '1', 0, Arg_parser::no },
+ { '2', 0, Arg_parser::no },
+ { '3', 0, Arg_parser::no },
+ { '4', 0, Arg_parser::no },
+ { '5', 0, Arg_parser::no },
+ { '6', 0, Arg_parser::no },
+ { '7', 0, Arg_parser::no },
+ { '8', 0, Arg_parser::no },
+ { '9', 0, Arg_parser::no },
{ 'd', "destdir", Arg_parser::yes },
{ 'e', "expand-extensions", Arg_parser::no },
{ 'f', "force", Arg_parser::no },
@@ -424,7 +425,7 @@ int main( const int argc, const char * const argv[] )
{ lz_opt, "lz", Arg_parser::yes },
{ xz_opt, "xz", Arg_parser::yes },
{ zst_opt, "zst", Arg_parser::yes },
- { 0, 0, Arg_parser::no } };
+ { 0, 0, Arg_parser::no } };
const Arg_parser parser( argc, argv, options );
if( parser.error().size() ) // bad option
@@ -488,7 +489,7 @@ int main( const int argc, const char * const argv[] )
while( true )
{
std::string srcdir; // dirname to be replaced by destdir
- if( destdir.size() ) extract_srcdir_name( filenames.front(), srcdir );
+ if( destdir.size() ) extract_dirname( filenames.front(), srcdir );
while( next_filename( filenames, input_filename, error, recursive, true ) )
{
int tmp = zupdate_file( input_filename, lzip_name, lzip_args2, srcdir,