mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 14:40:26 -05:00
169 lines
4.4 KiB
C++
169 lines
4.4 KiB
C++
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <ert/util/util.h>
|
|
|
|
#include <dirent.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
uid_t util_get_entry_uid( const char * file ) {
|
|
stat_type buffer;
|
|
util_stat( file , &buffer);
|
|
return buffer.st_uid;
|
|
}
|
|
|
|
mode_t util_getmode( const char * file ) {
|
|
stat_type buffer;
|
|
util_stat( file , &buffer);
|
|
return buffer.st_mode;
|
|
}
|
|
|
|
|
|
|
|
bool util_chmod_if_owner( const char * filename , mode_t new_mode) {
|
|
stat_type buffer;
|
|
uid_t exec_uid = getuid();
|
|
util_stat( filename , &buffer );
|
|
|
|
if (exec_uid == buffer.st_uid) { /* OKAY - the current running uid is also the owner of the file. */
|
|
mode_t current_mode = buffer.st_mode & ( S_IRWXU + S_IRWXG + S_IRWXO );
|
|
if (current_mode != new_mode) {
|
|
chmod( filename , new_mode); /* No error check ... */
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false; /* No update performed. */
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
IFF the current uid is also the owner of the file the current
|
|
function will add the permissions specified in the add_mode variable
|
|
to the file.
|
|
|
|
The function simulates the "chmod +???" behaviour of the shell
|
|
command. If the mode of the file is changed the function will return
|
|
true, otherwise it will return false.
|
|
*/
|
|
|
|
|
|
|
|
bool util_addmode_if_owner( const char * filename , mode_t add_mode) {
|
|
stat_type buffer;
|
|
util_stat( filename , &buffer );
|
|
|
|
{
|
|
mode_t current_mode = buffer.st_mode & ( S_IRWXU + S_IRWXG + S_IRWXO );
|
|
mode_t target_mode = (current_mode | add_mode);
|
|
|
|
return util_chmod_if_owner( filename , target_mode );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
Implements shell chmod -??? behaviour.
|
|
*/
|
|
bool util_delmode_if_owner( const char * filename , mode_t del_mode) {
|
|
stat_type buffer;
|
|
util_stat( filename , &buffer );
|
|
|
|
{
|
|
mode_t current_mode = buffer.st_mode & ( S_IRWXU + S_IRWXG + S_IRWXO );
|
|
mode_t target_mode = (current_mode - (current_mode & del_mode));
|
|
|
|
return util_chmod_if_owner( filename , target_mode );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
Only removes the last component in path.
|
|
*/
|
|
void static util_clear_directory__( const char *path , bool strict_uid , bool unlink_root) {
|
|
if (util_is_directory(path)) {
|
|
DIR *dirH = opendir( path );
|
|
|
|
if (dirH != NULL) {
|
|
const uid_t uid = getuid();
|
|
struct dirent *dentry;
|
|
|
|
while ( (dentry = readdir(dirH)) != NULL) {
|
|
stat_type buffer;
|
|
mode_t mode;
|
|
const char * entry_name = dentry->d_name;
|
|
if ((strcmp(entry_name , ".") != 0) && (strcmp(entry_name , "..") != 0)) {
|
|
char * full_path = util_alloc_filename(path , entry_name , NULL);
|
|
|
|
if (lstat(full_path , &buffer) == 0) {
|
|
mode = buffer.st_mode;
|
|
|
|
if (S_ISDIR(mode))
|
|
/*
|
|
Recursively descending into sub directory.
|
|
*/
|
|
util_clear_directory__(full_path , strict_uid , true);
|
|
else if (S_ISLNK(mode))
|
|
/*
|
|
Symbolic links are unconditionally removed.
|
|
*/
|
|
unlink(full_path);
|
|
else if (S_ISREG(mode)) {
|
|
/*
|
|
It is a regular file - we remove it (if we own it!).
|
|
*/
|
|
if ((!strict_uid) || (buffer.st_uid == uid)) {
|
|
int unlink_return = unlink(full_path);
|
|
if (unlink_return != 0) {
|
|
/* Unlink failed - we don't give a shit. */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
free(full_path);
|
|
}
|
|
}
|
|
}
|
|
closedir(dirH);
|
|
|
|
/* Finish with clearing the root directory */
|
|
if (unlink_root) {
|
|
int rmdir_return = rmdir(path);
|
|
if (rmdir_return != 0) {
|
|
/* Unlink failed - we don't give a shit. */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
This function will clear away all the contents (including
|
|
subdirectories) in the directory @path.
|
|
|
|
If the parameter @strict_uid is set to true, the function will only
|
|
attempt to remove entries where the calling uid is also the owner
|
|
of the entry.
|
|
|
|
If the parameter @unlink_root is true the directory @path will also
|
|
be removed, otherwise it will be left as an empty directory.
|
|
|
|
The function will just go about deleting as much as it can; errors
|
|
are not signalled in any way!
|
|
|
|
The function is in util_getuid() because uid_t and getuid() are so
|
|
important elements of the function.
|
|
*/
|
|
|
|
|
|
void util_clear_directory(const char * path , bool strict_uid , bool unlink_root) {
|
|
util_clear_directory__( path , strict_uid , unlink_root );
|
|
}
|