autocreate directories from config file

This commit is contained in:
Ron Pedde
2006-03-26 04:55:59 +00:00
parent e1a1c7f18a
commit abee2d9792
6 changed files with 89 additions and 345 deletions

View File

@@ -47,6 +47,7 @@
#include "err.h"
#include "ll.h"
#include "daapd.h"
#include "os.h"
/** Globals */
//static int ecode;
@@ -79,7 +80,7 @@ static void _conf_lock(void);
static void _conf_unlock(void);
static int _conf_write(FILE *fp, LL *pll, int sublevel, char *parent);
static CONF_ELEMENTS *_conf_get_keyinfo(char *section, char *key);
static int _conf_makedir(char *path);
static int _conf_makedir(char *path, char *user);
static int _conf_existdir(char *path);
static CONF_ELEMENTS conf_elements[] = {
@@ -90,7 +91,7 @@ static CONF_ELEMENTS conf_elements[] = {
{ 1, 0, CONF_T_STRING,"general","mp3_dir" },
{ 0, 1, CONF_T_EXISTPATH,"general","db_dir" },
{ 0, 0, CONF_T_STRING,"general","db_type" },
{ 0, 0, CONF_T_STRING,"general","db_parms" },
{ 0, 0, CONF_T_EXISTPATH,"general","db_parms" }, /* this isn't right */
{ 0, 0, CONF_T_INT,"general","debuglevel" },
{ 1, 0, CONF_T_STRING,"general","servername" },
{ 0, 0, CONF_T_INT,"general","rescan_interval" },
@@ -119,11 +120,10 @@ static CONF_ELEMENTS conf_elements[] = {
* @returns TRUE on success, FALSE otherwise
*/
int _conf_makedir(char *path) {
int _conf_makedir(char *path,char *user) {
char *token, *next_token;
char *pathdup;
char path_buffer[PATH_MAX];
int err;
int retval = FALSE;
DPRINTF(E_DBG,L_CONF,"Creating %s\n",path);
@@ -140,19 +140,20 @@ int _conf_makedir(char *path) {
if((strlen(path_buffer) + strlen(token)) < PATH_MAX) {
strcat(path_buffer,"/");
strcat(path_buffer,token);
/* FIXME: this is wrong -- it should really be 0700 owned by
* the runas user. That would require some os_ indirection
*/
DPRINTF(E_DBG,L_CONF,"Making %s\n",path_buffer);
if((mkdir(path_buffer,0777)) && (errno != EEXIST)) {
err=errno;
free(pathdup);
errno=err;
DPRINTF(E_LOG,L_CONF,"Could not make dirctory %s: %s\n",
path_buffer,strerror(errno));
return FALSE;
}
if(!_conf_existdir(path_buffer)) {
/* FIXME: this is wrong -- it should really be 0700 owned by
* the runas user. That would require some os_ indirection
*/
DPRINTF(E_DBG,L_CONF,"Making %s\n",path_buffer);
if((mkdir(path_buffer,0700)) && (errno != EEXIST)) {
free(pathdup);
DPRINTF(E_LOG,L_CONF,"Could not make dirctory %s: %s\n",
path_buffer,strerror(errno));
return FALSE;
}
os_chown(path_buffer,user);
}
retval = TRUE;
}
}
@@ -285,9 +286,11 @@ int _conf_exists(LL_HANDLE pll, char *section, char *term) {
*/
int _conf_verify(LL_HANDLE pll) {
LL_ITEM *pi = NULL;
LL_ITEM *ptemp = NULL;
CONF_ELEMENTS *pce;
int is_valid=TRUE;
char resolved_path[PATH_MAX];
char *user;
/* first, walk through the elements and make sure
* all required elements are there */
@@ -309,21 +312,35 @@ int _conf_verify(LL_HANDLE pll) {
}
}
if(pce->type == CONF_T_EXISTPATH) {
/* first, need to resolve */
/* first, need to resolve */
pi = _conf_fetch_item(pll,pce->section, pce->term);
if(pi) {
memset(resolved_path,0,sizeof(resolved_path));
if(pi->value.as_string) {
realpath(pi->value.as_string,resolved_path);
free(pi->value.as_string);
pi->value.as_string = strdup(resolved_path);
}
/* now, should verify it exists */
if(!_conf_existdir(resolved_path)) {
if(!_conf_makedir(resolved_path)) {
is_valid=0;
DPRINTF(E_LOG,L_CONF,"Can't make path %s, invalid config.\n",
resolved_path);
DPRINTF(E_SPAM,L_CONF,"Found %s/%s as %s... checking\n",
pce->section, pce->term, pi->value.as_string);
/* verify it exists, creating it if necessary */
if(!_conf_existdir(pi->value.as_string)) {
user = "nobody";
ptemp = _conf_fetch_item(pll, "general", "runas");
if(ptemp) {
user = ptemp->value.as_string;
}
if(!_conf_makedir(pi->value.as_string,user)) {
is_valid=0;
DPRINTF(E_LOG,L_CONF,"Can't make path %s, invalid config.\n",
resolved_path);
}
}
if(_conf_existdir(pi->value.as_string)) {
realpath(pi->value.as_string,resolved_path);
free(pi->value.as_string);
pi->value.as_string = strdup(resolved_path);
DPRINTF(E_SPAM,L_CONF,"Resolved to %s\n",resolved_path);
}
}
}
@@ -520,7 +537,6 @@ int conf_read(char *file) {
/* this is an inline comment */
snprintf(keybuffer,sizeof(keybuffer),"in_%s_%s",
section_name,term);
DPRINTF(E_SPAM,L_CONF,"Adding %s: %s\n",keybuffer,comment);
ll_add_string(pllcomment,keybuffer,comment);
comment = NULL;
}
@@ -529,8 +545,6 @@ int conf_read(char *file) {
/* we had some preceding comments */
snprintf(keybuffer,sizeof(keybuffer),"pre_%s_%s",
section_name, term);
DPRINTF(E_SPAM,L_CONF,"Adding %s: %s\n",keybuffer,
prev_comments);
ll_add_string(pllcomment,keybuffer,prev_comments);
prev_comments[0] = '\0';
current_comment_length=0;
@@ -550,7 +564,6 @@ int conf_read(char *file) {
if(!comment)
comment = "";
DPRINTF(E_SPAM,L_CONF,"found comment: %s\n",comment);
/* add to prev comments */
while((current_comment_length + (int)strlen(comment) + 2 >=
@@ -578,8 +591,6 @@ int conf_read(char *file) {
current_comment_length += 2; /* windows, worst case */
}
}
DPRINTF(E_SPAM,L_CONF,"Current comment block: \n%s\n",prev_comments);
}
}
@@ -727,9 +738,6 @@ char *conf_alloc_string (char *section, char *key, char *dflt) {
conf_get_string(section, key, dflt, NULL, &size);
out = (char *)malloc(size * sizeof(char));
if(!out)
DPRINTF(E_FATAL,L_CONF,"Malloc failure\n");
if(conf_get_string (section, key, dflt, out, &size) != CONF_E_SUCCESS)
return NULL;

View File

@@ -190,6 +190,40 @@ int os_syslog(int level, char *msg) {
}
/**
* os-specific chown
*
*
*/
extern int os_chown(char *path, char *user) {
struct passwd *pw=NULL;
DPRINTF(E_DBG,L_MISC,"Chowning %s to %s\n",path,user);
/* drop privs */
if(getuid() == (uid_t)0) {
if(atoi(user)) {
pw=getpwuid((uid_t)atoi(user)); /* doh! */
} else {
pw=getpwnam(user);
}
if(pw) {
if(initgroups(user,pw->pw_gid) != 0 ||
chown(path, pw->pw_uid, pw->pw_gid) != 0) {
DPRINTF(E_LOG,L_MISC,"Couldn't chown %s, gid=%d, uid=%d\n",
user,pw->pw_gid, pw->pw_uid);
return FALSE;
}
} else {
DPRINTF(E_LOG,L_MISC,"Couldn't lookup user %s for chown\n",user);
return FALSE;
}
}
DPRINTF(E_DBG,L_MISC,"Success!\n");
return TRUE;
}
/**
* Fork and exit. Stolen pretty much straight from Stevens.

View File

@@ -126,6 +126,14 @@ int os_syslog(int level, char *msg) {
return elog_message(level, msg);
}
/**
* change the owner of a file to a specific user. This is
* ignored on windows
*/
extern int os_chown(char *path, char *user) {
return TRUE;
}
int os_register(void) {
service_register();

View File

@@ -31,6 +31,7 @@ extern void os_deinit(void);
extern int os_opensyslog(void);
extern int os_closesyslog(void);
extern int os_syslog(int level, char *msg);
extern int os_chown(char *path, char *user);
#ifdef WIN32
# include "os-win32.h"