mirror of
https://github.com/martijnvanbrummelen/nwipe.git
synced 2026-02-20 13:42:14 +00:00
Added testfile probe to check if destination directory is writable
This commit is contained in:
115
src/nwipe.c
115
src/nwipe.c
@@ -77,9 +77,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define NWIPE_PDF_DIR_MODE ( S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH )
|
||||
/* -> 0755: rwx for owner, r-x for group and others */
|
||||
|
||||
int terminate_signal;
|
||||
int user_abort;
|
||||
int global_wipe_status;
|
||||
@@ -99,11 +96,62 @@ int devnamecmp( const void* a, const void* b )
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
static int nwipe_ensure_directory( const char* path )
|
||||
#define NWIPE_PDF_DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
|
||||
/* -> 0755: rwx for owner, r-x for group and others */
|
||||
|
||||
/* Helper: try to create and remove a temporary file inside the directory.
|
||||
* This catches cases where access(path, W_OK) passes (especially as root)
|
||||
* but the underlying filesystem does not allow creating regular files,
|
||||
* e.g. /proc or other pseudo/readonly filesystems.
|
||||
*/
|
||||
static int nwipe_probe_directory_writable( const char *path )
|
||||
{
|
||||
const char *suffix = "/.nwipe_pdf_testXXXXXX";
|
||||
size_t path_len = strlen( path );
|
||||
size_t suffix_len = strlen( suffix );
|
||||
size_t total_len = path_len + suffix_len + 1; /* +1 for '\0' */
|
||||
|
||||
char *tmpl = (char *)malloc( total_len );
|
||||
if( tmpl == NULL )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR,
|
||||
"Failed to allocate memory to probe PDFreportpath '%s'.",
|
||||
path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Build template "<path>/.nwipe_pdf_testXXXXXX" */
|
||||
snprintf( tmpl, total_len, "%s%s", path, suffix );
|
||||
|
||||
int fd = mkstemp( tmpl );
|
||||
if( fd < 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR,
|
||||
"PDFreportpath '%s' is not writable (cannot create test file): %s.",
|
||||
path, strerror( errno ) );
|
||||
free( tmpl );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Successfully created a temporary file, now clean it up. */
|
||||
close( fd );
|
||||
if( unlink( tmpl ) != 0 )
|
||||
{
|
||||
/* Not fatal for our check, but log it anyway. */
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"Failed to remove temporary test file '%s' in PDFreportpath '%s': %s.",
|
||||
tmpl, path, strerror( errno ) );
|
||||
}
|
||||
|
||||
free( tmpl );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nwipe_ensure_directory( const char *path )
|
||||
{
|
||||
struct stat st;
|
||||
char* tmp;
|
||||
char* p;
|
||||
char *tmp;
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
if( path == NULL || path[0] == '\0' )
|
||||
@@ -112,32 +160,23 @@ static int nwipe_ensure_directory( const char* path )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Special case: current directory.
|
||||
* Historically nwipe called access(".", W_OK), so we keep that behavior. */
|
||||
if( strcmp( path, "." ) == 0 )
|
||||
{
|
||||
if( access( path, W_OK ) != 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "PDFreportpath '%s' is not writable: %s.", path, strerror( errno ) );
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 1. First try: does the path already exist? */
|
||||
if( stat( path, &st ) == 0 )
|
||||
{
|
||||
/* Path exists; make sure it's a directory. */
|
||||
if( !S_ISDIR( st.st_mode ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "PDFreportpath '%s' exists but is not a directory.", path );
|
||||
nwipe_log( NWIPE_LOG_ERROR,
|
||||
"PDFreportpath '%s' exists but is not a directory.",
|
||||
path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check that we can write into it. */
|
||||
if( access( path, W_OK ) != 0 )
|
||||
/* Even if access() says it's writable (especially as root),
|
||||
* we still probe by actually creating a test file. */
|
||||
if( nwipe_probe_directory_writable( path ) != 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "PDFreportpath '%s' is not writable: %s.", path, strerror( errno ) );
|
||||
/* Detailed error already logged. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -148,17 +187,21 @@ static int nwipe_ensure_directory( const char* path )
|
||||
/* stat() failed: if this is not "does not exist", propagate the error. */
|
||||
if( errno != ENOENT )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "Failed to stat PDFreportpath '%s': %s.", path, strerror( errno ) );
|
||||
nwipe_log( NWIPE_LOG_ERROR,
|
||||
"Failed to stat PDFreportpath '%s': %s.",
|
||||
path, strerror( errno ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 2. Directory does not exist -> create it recursively (mkdir -p style). */
|
||||
|
||||
len = strlen( path );
|
||||
tmp = (char*) malloc( len + 1 );
|
||||
tmp = (char *)malloc( len + 1 );
|
||||
if( tmp == NULL )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "Failed to allocate memory to create PDFreportpath '%s'.", path );
|
||||
nwipe_log( NWIPE_LOG_ERROR,
|
||||
"Failed to allocate memory to create PDFreportpath '%s'.",
|
||||
path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -186,9 +229,7 @@ static int nwipe_ensure_directory( const char* path )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR,
|
||||
"Failed to create directory '%s' for PDFreportpath '%s': %s.",
|
||||
tmp,
|
||||
path,
|
||||
strerror( errno ) );
|
||||
tmp, path, strerror( errno ) );
|
||||
free( tmp );
|
||||
return -1;
|
||||
}
|
||||
@@ -203,25 +244,17 @@ static int nwipe_ensure_directory( const char* path )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR,
|
||||
"Failed to create directory '%s' for PDFreportpath '%s': %s.",
|
||||
tmp,
|
||||
path,
|
||||
strerror( errno ) );
|
||||
tmp, path, strerror( errno ) );
|
||||
free( tmp );
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
free( tmp );
|
||||
|
||||
/* 3. Final sanity check: ensure the path now exists, is a directory and writable. */
|
||||
if( stat( path, &st ) != 0 || !S_ISDIR( st.st_mode ) )
|
||||
/* 3. Final sanity check: ensure the path is writable by probing with a file. */
|
||||
if( nwipe_probe_directory_writable( path ) != 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "PDFreportpath '%s' could not be verified as a directory after creation.", path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( access( path, W_OK ) != 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "PDFreportpath '%s' is not writable after creation: %s.", path, strerror( errno ) );
|
||||
/* Detailed error already logged. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user