logdir = CNF_GetLogDir();
- if (!UTI_CreateDirAndParents(logdir)) {
- LOG(LOGS_ERR, LOGF_Logging, "Could not create directory %s", logdir);
- }
+ UTI_CreateDirAndParents(logdir, 0755, 0, 0);
}
/* ================================================== */
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; i<n_sources; i++) {
a = (sources[i]->ref_id) >> 24;
b = ((sources[i]->ref_id) >> 16) & 0xff;
fclose(out);
}
}
- } else {
- LOG(LOGS_ERR, LOGF_Sources, "Could not create directory %s", direc);
}
Free(filename);
}
#include "sysincl.h"
+#include "logging.h"
#include "memory.h"
#include "util.h"
#include "hash.h"
/* ================================================== */
static int
-create_dir(char *p)
+create_dir(char *p, mode_t mode, uid_t uid, gid_t gid)
{
int status;
struct stat buf;
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;
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;
}
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 */