diff --git a/albumart.c b/albumart.c index c4cc5c9..c2d6447 100644 --- a/albumart.c +++ b/albumart.c @@ -37,7 +37,7 @@ int art_cache_exists(const char * orig_path, char ** cache_file) { - asprintf(cache_file, DB_PATH "/art_cache%s", orig_path); + asprintf(cache_file, "%s/art_cache%s", db_path, orig_path); strcpy(strchr(*cache_file, '\0')-4, ".jpg"); return (!access(*cache_file, F_OK)); diff --git a/genconfig.sh b/genconfig.sh index f266ff2..7a0f24e 100755 --- a/genconfig.sh +++ b/genconfig.sh @@ -143,7 +143,7 @@ echo "#define OS_URL \"${OS_URL}\"" >> ${CONFIGFILE} echo "" >> ${CONFIGFILE} echo "/* full path of the file database */" >> ${CONFIGFILE} -echo "#define DB_PATH \"${DB_PATH}\"" >> ${CONFIGFILE} +echo "#define DEFAULT_DB_PATH \"${DB_PATH}\"" >> ${CONFIGFILE} echo "" >> ${CONFIGFILE} echo "/* Comment the following line to use home made daemonize() func instead" >> ${CONFIGFILE} diff --git a/log.c b/log.c index fbc686e..d40e9ab 100644 --- a/log.c +++ b/log.c @@ -122,7 +122,7 @@ log_err(int level, enum _log_facility facility, char *fname, int lineno, char *f time_t t; struct tm *tm; - if (level && level>log_level[facility]) + if (level && level>log_level[facility] && level>E_FATAL) return; if (!log_fp) diff --git a/minidlna.c b/minidlna.c index b2fa542..850f3e2 100644 --- a/minidlna.c +++ b/minidlna.c @@ -197,10 +197,19 @@ getfriendlyname(char * buf, int len) #endif } -void +int open_db(void) { - if( sqlite3_open(DB_PATH "/files.db", &db) != SQLITE_OK ) + char path[PATH_MAX]; + int new_db = 0; + + snprintf(path, sizeof(path), "%s/files.db", db_path); + if( access(path, F_OK) != 0 ) + { + new_db = 1; + make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); + } + if( sqlite3_open(path, &db) != SQLITE_OK ) { DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to open sqlite database! Exiting...\n"); } @@ -209,6 +218,7 @@ open_db(void) sql_exec(db, "pragma journal_mode = OFF"); sql_exec(db, "pragma synchronous = OFF;"); sql_exec(db, "pragma default_cache_size = 8192;"); + return new_db; } /* init phase : @@ -385,6 +395,18 @@ init(int argc, char * * argv) } } break; + case UPNPDBDIR: + path = realpath(ary_options[i].value, real_path); + if( !path ) + path = (ary_options[i].value); + make_dir(path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); + if( access(path, F_OK) != 0 ) + { + DPRINTF(E_FATAL, L_GENERAL, "Database path not accessible! [%s]\n", path); + break; + } + strncpy(db_path, path, PATH_MAX); + break; case UPNPINOTIFY: if( (strcmp(ary_options[i].value, "yes") != 0) && !atoi(ary_options[i].value) ) CLEARFLAG(INOTIFY_MASK); @@ -533,7 +555,8 @@ init(int argc, char * * argv) runtime_vars.port = 0; // triggers help display break; case 'R': - system("rm -rf " DB_PATH); // triggers a full rescan + snprintf(real_path, sizeof(real_path), "rm -rf %s", db_path); + system(real_path); break; case 'V': printf("Version " MINIDLNA_VERSION "\n"); @@ -596,7 +619,10 @@ init(int argc, char * * argv) #ifdef READYNAS log_init("/var/log/upnp-av.log", "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn"); #else - log_init(DB_PATH "/minidlna.log", "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn"); + if( access(db_path, F_OK) != 0 ) + make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); + sprintf(real_path, "%s/minidlna.log", db_path); + log_init(real_path, "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn"); #endif } @@ -618,7 +644,7 @@ init(int argc, char * * argv) { #ifdef READYNAS snprintf(presentationurl, PRESENTATIONURL_MAX_LEN, - "https://%s/admin/", lan_addr[0].str); + "http://%s/admin/", lan_addr[0].str); #else snprintf(presentationurl, PRESENTATIONURL_MAX_LEN, "http://%s:%d/", lan_addr[0].str, runtime_vars.port); @@ -694,14 +720,7 @@ main(int argc, char * * argv) #endif LIST_INIT(&upnphttphead); - if( access(DB_PATH, F_OK) != 0 ) - { - char *db_path = strdup(DB_PATH); - make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); - free(db_path); - new_db = 1; - } - open_db(); + new_db = open_db(); if( !new_db ) { updateID = sql_get_int_field(db, "SELECT UPDATE_ID from SETTINGS"); @@ -717,8 +736,10 @@ main(int argc, char * * argv) DPRINTF(E_WARN, L_GENERAL, "Database version mismatch; need to recreate...\n"); } sqlite3_close(db); - unlink(DB_PATH "/files.db"); - system("rm -rf " DB_PATH "/art_cache"); + char *cmd; + asprintf(&cmd, "rm -rf %s/files.db %s/art_cache", db_path, db_path); + system(cmd); + free(cmd); open_db(); if( CreateDatabase() != 0 ) { diff --git a/minidlna.conf b/minidlna.conf index 352c14b..5a93936 100644 --- a/minidlna.conf +++ b/minidlna.conf @@ -16,6 +16,9 @@ media_dir=/opt # set this if you want to customize the name that shows up on your clients #friendly_name=My DLNA Server +# set this if you would like to specify the directory where you want MiniDLNA to store its database and album art cache +#db_dir=/var/cache/minidlna + # this should be a list of file names to check for when searching for album art # note: names should be delimited with a forward slash ("/") album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg diff --git a/options.c b/options.c index e654c60..144b1a2 100644 --- a/options.c +++ b/options.c @@ -33,6 +33,7 @@ static const struct { { UPNPMEDIADIR, "media_dir"}, { UPNPALBUMART_NAMES, "album_art_names"}, { UPNPINOTIFY, "inotify" }, + { UPNPDBDIR, "db_dir" }, { ENABLE_TIVO, "enable_tivo" }, { ENABLE_DLNA_STRICT, "strict_dlna" } }; diff --git a/options.h b/options.h index ae0b80f..4d9ceb2 100644 --- a/options.h +++ b/options.h @@ -26,6 +26,7 @@ enum upnpconfigoptions { UPNPMEDIADIR, /* directory to search for UPnP-A/V content */ UPNPALBUMART_NAMES, /* list of '/'-delimited file names to check for album art */ UPNPINOTIFY, /* enable inotify on the media directories */ + UPNPDBDIR, /* base directory to store the database, log files, and album art cache */ ENABLE_TIVO, /* enable support for streaming images and music to TiVo */ ENABLE_DLNA_STRICT /* strictly adhere to DLNA specs */ }; diff --git a/upnpglobalvars.c b/upnpglobalvars.c index d35fad8..c6eade7 100644 --- a/upnpglobalvars.c +++ b/upnpglobalvars.c @@ -12,6 +12,7 @@ */ #include #include +#include #include "config.h" #include "upnpglobalvars.h" @@ -43,6 +44,7 @@ struct lan_addr_s lan_addr[MAX_LAN_ADDR]; sqlite3 * db; char dlna_no_conv[] = "DLNA.ORG_OP=01;DLNA.ORG_CI=0"; char friendly_name[FRIENDLYNAME_MAX_LEN]; +char db_path[PATH_MAX] = DEFAULT_DB_PATH; struct media_dir_s * media_dirs = NULL; struct album_art_name_s * album_art_names = NULL; struct client_cache_s clients[CLIENT_CACHE_SLOTS]; diff --git a/upnpglobalvars.h b/upnpglobalvars.h index 5f71fd0..20f7cd8 100644 --- a/upnpglobalvars.h +++ b/upnpglobalvars.h @@ -116,6 +116,7 @@ extern sqlite3 *db; extern char dlna_no_conv[]; #define FRIENDLYNAME_MAX_LEN (64) extern char friendly_name[]; +extern char db_path[]; extern struct media_dir_s * media_dirs; extern struct album_art_name_s * album_art_names; extern struct client_cache_s clients[CLIENT_CACHE_SLOTS]; diff --git a/utils.c b/utils.c index c199d19..c08284c 100644 --- a/utils.c +++ b/utils.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include "minidlnatypes.h" +#include "log.h" int ends_with(const char * haystack, const char * needle) @@ -198,7 +200,7 @@ make_dir(char * path, mode_t mode) } while (1); - printf("make_dir: cannot create directory '%s'", path); + DPRINTF(E_WARN, L_GENERAL, "make_dir: cannot create directory '%s'\n", path); return -1; }