diff --git a/logging.c b/logging.c index 37fb572..8257a8b 100644 --- a/logging.c +++ b/logging.c @@ -306,9 +306,7 @@ LOG_CreateLogFileDir(void) logdir = CNF_GetLogDir(); - if (!UTI_CreateDirAndParents(logdir)) { - LOG(LOGS_ERR, LOGF_Logging, "Could not create directory %s", logdir); - } + UTI_CreateDirAndParents(logdir, 0755, 0, 0); } /* ================================================== */ diff --git a/sources.c b/sources.c index 8ae1e6c..56a8cca 100644 --- a/sources.c +++ b/sources.c @@ -1092,7 +1092,7 @@ SRC_DumpSources(void) direc_len = strlen(direc); file_len = direc_len + 24; filename = MallocArray(char, file_len); /* a bit of slack */ - if (UTI_CreateDirAndParents(direc)) { + if (UTI_CreateDirAndParents(direc, 0755, 0, 0)) { for (i=0; iref_id) >> 24; b = ((sources[i]->ref_id) >> 16) & 0xff; @@ -1108,8 +1108,6 @@ SRC_DumpSources(void) fclose(out); } } - } else { - LOG(LOGS_ERR, LOGF_Sources, "Could not create directory %s", direc); } Free(filename); } diff --git a/util.c b/util.c index 89379d9..08d3110 100644 --- a/util.c +++ b/util.c @@ -29,6 +29,7 @@ #include "sysincl.h" +#include "logging.h" #include "memory.h" #include "util.h" #include "hash.h" @@ -897,7 +898,7 @@ UTI_SetQuitSignalsHandler(void (*handler)(int)) /* ================================================== */ static int -create_dir(char *p) +create_dir(char *p, mode_t mode, uid_t uid, gid_t gid) { int status; struct stat buf; @@ -906,27 +907,39 @@ create_dir(char *p) status = stat(p, &buf); if (status < 0) { - if (errno == ENOENT) { - /* Try to create directory */ - status = mkdir(p, 0755); - return status; - } else { - return status; + if (errno != ENOENT) { + LOG(LOGS_ERR, LOGF_Util, "Could not access %s : %s", p, strerror(errno)); + return 0; } + } else { + if (S_ISDIR(buf.st_mode)) + return 1; + LOG(LOGS_ERR, LOGF_Util, "%s is not directory", p); + return 0; } - if (!S_ISDIR(buf.st_mode)) { - return -1; + /* Create the directory */ + if (mkdir(p, mode) < 0) { + LOG(LOGS_ERR, LOGF_Util, "Could not create directory %s : %s", p, strerror(errno)); + return 0; } - return 0; + /* Change its ownership if requested */ + if ((uid || gid) && chown(p, uid, gid) < 0) { + LOG(LOGS_ERR, LOGF_Util, "Could not change ownership of %s : %s", p, strerror(errno)); + /* Don't leave it there with incorrect ownership */ + rmdir(p); + return 0; + } + + return 1; } /* ================================================== */ /* Return 0 if the directory couldn't be created, 1 if it could (or already existed) */ int -UTI_CreateDirAndParents(const char *path) +UTI_CreateDirAndParents(const char *path, mode_t mode, uid_t uid, gid_t gid) { char *p; int i, j, k, last; @@ -942,30 +955,26 @@ UTI_CreateDirAndParents(const char *path) p[i++] = path[k++]; if (path[k] == '/' || !path[k]) { - p[i] = 0; - - if (create_dir(p) < 0) { - Free(p); - return 0; - } - - if (!path[k]) { - /* End of the string */ - break; - } - - /* Check whether its a trailing / or group of / */ + /* Check whether its end of string, a trailing / or group of / */ last = 1; - j = k + 1; + j = k; while (path[j]) { if (path[j] != '/') { - k = j - 1; /* Pick up a / into p[] thru the assignment at the top of the loop */ + /* Pick up a / into p[] thru the assignment at the top of the loop */ + k = j - 1; last = 0; break; } j++; } + p[i] = 0; + + if (!create_dir(p, last ? mode : 0755, last ? uid : 0, last ? gid : 0)) { + Free(p); + return 0; + } + if (last) break; } diff --git a/util.h b/util.h index a01b7aa..4b4efe4 100644 --- a/util.h +++ b/util.h @@ -130,7 +130,10 @@ extern int UTI_DecodePasswordFromText(char *key); extern int UTI_SetQuitSignalsHandler(void (*handler)(int)); -/* Create a directory and any parent directories that don't exist */ -extern int UTI_CreateDirAndParents(const char *path); +/* Create a directory with a specified mode (umasked) and set its uid/gid + (if not 0). Create also any parent directories that don't exist with mode + 755 and default uid/gid. Returns 1 if created or already exists (even with + different mode/uid/gid), 0 otherwise. */ +extern int UTI_CreateDirAndParents(const char *path, mode_t mode, uid_t uid, gid_t gid); #endif /* GOT_UTIL_H */