diff --git a/src/conf.c b/src/conf.c index e209ad5f..ed8bfc0a 100644 --- a/src/conf.c +++ b/src/conf.c @@ -75,6 +75,7 @@ static pthread_mutex_t conf_mutex = PTHREAD_MUTEX_INITIALIZER; #define CONF_T_STRING 1 #define CONF_T_EXISTPATH 2 /** a path that must exist */ #define CONF_T_MULTICOMMA 3 /** multiple entries separated by commas */ +#define CONF_T_MULTIPATH 4 /** multiple comma separated paths */ typedef struct _CONF_ELEMENTS { int required; @@ -104,7 +105,7 @@ static CONF_ELEMENTS conf_elements[] = { { 1, 0, CONF_T_EXISTPATH,"general","web_root" }, { 0, 0, CONF_T_INT,"general","port" }, { 0, 0, CONF_T_STRING,"general","admin_pw" }, - { 1, 0, CONF_T_MULTICOMMA,"general","mp3_dir" }, + { 1, 0, CONF_T_MULTIPATH,"general","mp3_dir" }, { 0, 1, CONF_T_EXISTPATH,"general","db_dir" }, { 0, 0, CONF_T_STRING,"general","db_type" }, { 0, 0, CONF_T_EXISTPATH,"general","db_parms" }, /* this isn't right */ @@ -318,6 +319,8 @@ int _conf_exists(LL_HANDLE pll, char *section, char *key) { int _conf_verify_element(char *section, char *key, char *value) { CONF_ELEMENTS *pce; + int index; + char **valuearray; pce = _conf_get_keyinfo(section, key); if(!pce) { @@ -341,6 +344,20 @@ int _conf_verify_element(char *section, char *key, char *value) { return CONF_E_SUCCESS; return CONF_E_INTEXPECTED; break; + + case CONF_T_MULTIPATH: + if(_conf_split(value,",",&valuearray) >= 0) { + index = 0; + while(valuearray[index]) { + if(!_conf_existdir(valuearray[index])) { + _conf_dispose_split(valuearray); + return CONF_E_PATHEXPECTED; + } + index++; + } + _conf_dispose_split(valuearray); + } + break; case CONF_T_EXISTPATH: if(!_conf_existdir(value)) @@ -705,6 +722,7 @@ int conf_read(char *file) { key_type = pce->type; switch(key_type) { + case CONF_T_MULTIPATH: case CONF_T_MULTICOMMA: /* first, see if we already have a tree... */ pli = ll_fetch_item(pllcurrent,term); @@ -1024,7 +1042,7 @@ int conf_set_string(char *section, char *key, char *value, int verify) { key_type = pce->type; /* apply the config change, if necessary */ - if(key_type != CONF_T_MULTICOMMA) { + if((key_type != CONF_T_MULTICOMMA) && (key_type != CONF_T_MULTIPATH)) { /* let's apply it */ polditem = _conf_fetch_item(conf_main,section,key); if(polditem) @@ -1071,7 +1089,7 @@ int conf_set_string(char *section, char *key, char *value, int verify) { section_ll = psection->value.as_ll; } /* have the section, now add it */ - if(key_type == CONF_T_MULTICOMMA) { + if((key_type == CONF_T_MULTICOMMA) || (key_type == CONF_T_MULTIPATH)) { if((err = ll_create(&temp_ll)) != LL_E_SUCCESS) { DPRINTF(E_FATAL,L_CONF,"conf_set_string: could not create ll\n"); } @@ -1095,7 +1113,7 @@ int conf_set_string(char *section, char *key, char *value, int verify) { } } else { /* we have the item, let's update it */ - if(key_type == CONF_T_MULTICOMMA) { + if((key_type == CONF_T_MULTICOMMA) || (key_type = CONF_T_MULTIPATH)) { /* delete whatever is there, then add from commas */ ll_destroy(pitem->value.as_ll); if(ll_create(&pitem->value.as_ll) != LL_E_SUCCESS) { diff --git a/src/main.c b/src/main.c index 985dceb4..9f1b1a19 100644 --- a/src/main.c +++ b/src/main.c @@ -182,6 +182,7 @@ int main_auth(WS_CONNINFO *pwsc, char *username, char *password) { void usage(char *program) { printf("Usage: %s [options]\n\n",program); printf("Options:\n"); + printf(" -a Set cwd to app dir before starting\n"); printf(" -d Debuglevel (0-9)\n"); printf(" -D Debug modules\n"); printf(" -m Disable mDNS\n"); @@ -230,6 +231,7 @@ int main(int argc, char *argv[]) { char **mp3_dir_array; char *servername, *iface; int index; + int appdir = 0; char txtrecord[255]; @@ -239,13 +241,17 @@ int main(int argc, char *argv[]) { int err; char *perr=NULL; + char *apppath; config.use_mdns=1; err_setlevel(1); config.foreground=0; - while((option=getopt(argc,argv,"D:d:c:P:mfrysiuv")) != -1) { + while((option=getopt(argc,argv,"D:d:c:P:mfrysiuva")) != -1) { switch(option) { + case 'a': + appdir = 1; + break; case 'd': err_setlevel(atoi(optarg)); break; @@ -318,6 +324,15 @@ int main(int argc, char *argv[]) { config.stats.start_time=start_time=(int)time(NULL); config.stop=0; + /* set appdir first, that way config resolves relative to appdir */ + if(appdir) { + apppath = os_apppath(argv[0]); + DPRINTF(E_INF,L_MAIN,"Changing cwd to %s\n",apppath); + chdir(apppath); + free(apppath); + configfile="mt-daapd.conf"; + } + if(conf_read(configfile) != CONF_E_SUCCESS) { fprintf(stderr,"Error reading config file (%s)\n",configfile); exit(EXIT_FAILURE); diff --git a/src/os-unix.c b/src/os-unix.c index 51eb0a69..1ed3e762 100644 --- a/src/os-unix.c +++ b/src/os-unix.c @@ -48,6 +48,10 @@ #include #include +#ifdef MAC +#include "CoreFoundation/CoreFoundation.h" +#endif + #include "conf.h" #include "err.h" #include "daapd.h" @@ -466,3 +470,26 @@ int os_islocaladdr(char *hostaddr) { return FALSE; } + +#ifdef MAC +char *os_apppath(char *parm) { + CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef, + kCFURLPOSIXPathStyle); + const char *pathPtr = CFStringGetCStringPtr(macPath, + CFStringGetSystemEncoding()); + + return strdup(pathPtr); +} +#else +char *os_apppath(char *parm) { + char path[MAX_PATH]; + + realpath(param,path); + if(strrchr(path,'/')) { + *strrchr(path,'/') = '/0'; + } + + return strdup(path); +} +#endif diff --git a/src/os-win32.c b/src/os-win32.c index 00386f0e..515748d1 100644 --- a/src/os-win32.c +++ b/src/os-win32.c @@ -627,6 +627,18 @@ char *os_configpath(void) { return os_config_file; } +/** + * get the path of the executable. Caller must free. + * + */ +char *os_apppath(char *junk) { + char app_path[MAX_PATH]; + + GetModuleFileName(NULL,app_path,MAX_PATH); + return strdup(app_path); +} + + /** * Determine if an address is local or not * diff --git a/src/os.h b/src/os.h index 5a229868..86e3a7a3 100644 --- a/src/os.h +++ b/src/os.h @@ -40,6 +40,7 @@ extern int os_unload(void *handle); /* misc */ extern int os_islocaladdr(char *hostaddr); +extern char *os_apppath(char *parm); #ifdef WIN32