summaryrefslogtreecommitdiffstats
path: root/common_decode.cc
diff options
context:
space:
mode:
Diffstat (limited to 'common_decode.cc')
-rw-r--r--common_decode.cc44
1 files changed, 42 insertions, 2 deletions
diff --git a/common_decode.cc b/common_decode.cc
index 6b108c1..6ff3086 100644
--- a/common_decode.cc
+++ b/common_decode.cc
@@ -1,5 +1,5 @@
/* Tarlz - Archiver with multimember lzip compression
- Copyright (C) 2013-2020 Antonio Diaz Diaz.
+ Copyright (C) 2013-2021 Antonio Diaz Diaz.
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
@@ -17,6 +17,7 @@
#define _FILE_OFFSET_BITS 64
+#include <cerrno>
#include <climits>
#include <cstdio>
#include <cstdlib>
@@ -24,7 +25,7 @@
#include <ctime>
#include <string>
#include <vector>
-#include <pthread.h>
+#include <pthread.h> // for tarlz.h
#include <stdint.h>
#include <sys/stat.h>
@@ -198,3 +199,42 @@ bool check_skip_filename( const Cl_options & cl_opts,
}
return skip;
}
+
+
+mode_t get_umask()
+ {
+ static mode_t mask = 0; // read once, cache the result
+ static bool first_call = true;
+ if( first_call ) { first_call = false; mask = umask( 0 ); umask( mask );
+ mask &= S_IRWXU | S_IRWXG | S_IRWXO; }
+ return mask;
+ }
+
+
+bool make_path( const std::string & name )
+ {
+ const mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+ unsigned end = name.size(); // first slash before last component
+
+ while( end > 0 && name[end-1] == '/' ) --end; // remove trailing slashes
+ while( end > 0 && name[end-1] != '/' ) --end; // remove last component
+ while( end > 0 && name[end-1] == '/' ) --end; // remove more slashes
+
+ unsigned index = 0;
+ while( index < end )
+ {
+ while( index < end && name[index] == '/' ) ++index;
+ unsigned first = index;
+ while( index < end && name[index] != '/' ) ++index;
+ if( first < index )
+ {
+ const std::string partial( name, 0, index );
+ struct stat st;
+ if( stat( partial.c_str(), &st ) == 0 )
+ { if( !S_ISDIR( st.st_mode ) ) return false; }
+ else if( mkdir( partial.c_str(), mode ) != 0 && errno != EEXIST )
+ return false;
+ }
+ }
+ return true;
+ }