directory: remove shortname arguments everywhere
It was a huge confusing mess of parameter passing around and around. Add a few extra assertions to ensure we're handling parent/child relationships properly.
This commit is contained in:
parent
8bb96d46e8
commit
71b332601a
121
src/directory.c
121
src/directory.c
@ -62,8 +62,7 @@ static pthread_t update_thr;
|
|||||||
static int directory_updateJobId;
|
static int directory_updateJobId;
|
||||||
|
|
||||||
static enum update_return
|
static enum update_return
|
||||||
addToDirectory(Directory * directory,
|
addToDirectory(Directory * directory, const char *name);
|
||||||
const char *shortname, const char *name);
|
|
||||||
|
|
||||||
static void freeDirectory(Directory * directory);
|
static void freeDirectory(Directory * directory);
|
||||||
|
|
||||||
@ -77,17 +76,10 @@ static void removeSongFromDirectory(Directory * directory,
|
|||||||
const char *shortname);
|
const char *shortname);
|
||||||
|
|
||||||
static enum update_return addSubDirectoryToDirectory(Directory * directory,
|
static enum update_return addSubDirectoryToDirectory(Directory * directory,
|
||||||
const char *shortname,
|
|
||||||
const char *name, struct stat *st);
|
const char *name, struct stat *st);
|
||||||
|
|
||||||
static Directory *getDirectoryDetails(const char *name,
|
|
||||||
const char **shortname);
|
|
||||||
|
|
||||||
static Directory *getDirectory(const char *name);
|
static Directory *getDirectory(const char *name);
|
||||||
|
|
||||||
static Song *getSongDetails(const char *file, const char **shortnameRet,
|
|
||||||
Directory ** directoryRet);
|
|
||||||
|
|
||||||
static enum update_return updatePath(const char *utf8path);
|
static enum update_return updatePath(const char *utf8path);
|
||||||
|
|
||||||
static void sortDirectory(Directory * directory);
|
static void sortDirectory(Directory * directory);
|
||||||
@ -235,8 +227,8 @@ static void deleteEmptyDirectoriesInDirectory(Directory * directory)
|
|||||||
dirvec_destroy(dv);
|
dirvec_destroy(dv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum update_return updateInDirectory(Directory * directory,
|
static enum update_return
|
||||||
const char *shortname, const char *name)
|
updateInDirectory(Directory * directory, const char *name)
|
||||||
{
|
{
|
||||||
Song *song;
|
Song *song;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -245,8 +237,10 @@ static enum update_return updateInDirectory(Directory * directory,
|
|||||||
return UPDATE_RETURN_ERROR;
|
return UPDATE_RETURN_ERROR;
|
||||||
|
|
||||||
if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) {
|
if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) {
|
||||||
|
const char *shortname = mpd_basename(name);
|
||||||
|
|
||||||
if (!(song = songvec_find(&directory->songs, shortname))) {
|
if (!(song = songvec_find(&directory->songs, shortname))) {
|
||||||
addToDirectory(directory, shortname, name);
|
addToDirectory(directory, name);
|
||||||
return UPDATE_RETURN_UPDATED;
|
return UPDATE_RETURN_UPDATED;
|
||||||
} else if (st.st_mtime != song->mtime) {
|
} else if (st.st_mtime != song->mtime) {
|
||||||
LOG("updating %s\n", name);
|
LOG("updating %s\n", name);
|
||||||
@ -257,11 +251,11 @@ static enum update_return updateInDirectory(Directory * directory,
|
|||||||
} else if (S_ISDIR(st.st_mode)) {
|
} else if (S_ISDIR(st.st_mode)) {
|
||||||
Directory *subdir = dirvec_find(&directory->children, name);
|
Directory *subdir = dirvec_find(&directory->children, name);
|
||||||
if (subdir) {
|
if (subdir) {
|
||||||
|
assert(directory == subdir->parent);
|
||||||
directory_set_stat(subdir, &st);
|
directory_set_stat(subdir, &st);
|
||||||
return updateDirectory(subdir);
|
return updateDirectory(subdir);
|
||||||
} else {
|
} else {
|
||||||
return addSubDirectoryToDirectory(directory, shortname,
|
return addSubDirectoryToDirectory(directory, name, &st);
|
||||||
name, &st);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,8 +305,7 @@ removeDeletedFromDirectory(char *path_max_tmp, Directory * directory)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Directory *addDirectoryPathToDB(const char *utf8path,
|
static Directory *addDirectoryPathToDB(const char *utf8path)
|
||||||
const char **shortname)
|
|
||||||
{
|
{
|
||||||
char path_max_tmp[MPD_PATH_MAX];
|
char path_max_tmp[MPD_PATH_MAX];
|
||||||
char *parent;
|
char *parent;
|
||||||
@ -324,16 +317,14 @@ static Directory *addDirectoryPathToDB(const char *utf8path,
|
|||||||
if (strlen(parent) == 0)
|
if (strlen(parent) == 0)
|
||||||
parentDirectory = (void *)mp3rootDirectory;
|
parentDirectory = (void *)mp3rootDirectory;
|
||||||
else
|
else
|
||||||
parentDirectory = addDirectoryPathToDB(parent, shortname);
|
parentDirectory = addDirectoryPathToDB(parent);
|
||||||
|
|
||||||
if (!parentDirectory)
|
if (!parentDirectory)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*shortname = utf8path + strlen(parent);
|
if ((directory = dirvec_find(&parentDirectory->children, utf8path))) {
|
||||||
while (*(*shortname) && *(*shortname) == '/')
|
assert(parentDirectory == directory->parent);
|
||||||
(*shortname)++;
|
} else {
|
||||||
|
|
||||||
if (!(directory = dirvec_find(&parentDirectory->children, utf8path))) {
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (myStat(utf8path, &st) < 0 ||
|
if (myStat(utf8path, &st) < 0 ||
|
||||||
inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev))
|
inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev))
|
||||||
@ -346,12 +337,12 @@ static Directory *addDirectoryPathToDB(const char *utf8path,
|
|||||||
|
|
||||||
/* if we're adding directory paths, make sure to delete filenames
|
/* if we're adding directory paths, make sure to delete filenames
|
||||||
with potentially the same name */
|
with potentially the same name */
|
||||||
removeSongFromDirectory(parentDirectory, *shortname);
|
removeSongFromDirectory(parentDirectory, mpd_basename(directory->path));
|
||||||
|
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Directory *addParentPathToDB(const char *utf8path, const char **shortname)
|
static Directory *addParentPathToDB(const char *utf8path)
|
||||||
{
|
{
|
||||||
char *parent;
|
char *parent;
|
||||||
char path_max_tmp[MPD_PATH_MAX];
|
char path_max_tmp[MPD_PATH_MAX];
|
||||||
@ -362,15 +353,11 @@ static Directory *addParentPathToDB(const char *utf8path, const char **shortname
|
|||||||
if (strlen(parent) == 0)
|
if (strlen(parent) == 0)
|
||||||
parentDirectory = (void *)mp3rootDirectory;
|
parentDirectory = (void *)mp3rootDirectory;
|
||||||
else
|
else
|
||||||
parentDirectory = addDirectoryPathToDB(parent, shortname);
|
parentDirectory = addDirectoryPathToDB(parent);
|
||||||
|
|
||||||
if (!parentDirectory)
|
if (!parentDirectory)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*shortname = utf8path + strlen(parent);
|
|
||||||
while (*(*shortname) && *(*shortname) == '/')
|
|
||||||
(*shortname)++;
|
|
||||||
|
|
||||||
return (Directory *) parentDirectory;
|
return (Directory *) parentDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +366,6 @@ static enum update_return updatePath(const char *utf8path)
|
|||||||
Directory *directory;
|
Directory *directory;
|
||||||
Directory *parentDirectory;
|
Directory *parentDirectory;
|
||||||
Song *song;
|
Song *song;
|
||||||
const char *shortname;
|
|
||||||
char *path = sanitizePathDup(utf8path);
|
char *path = sanitizePathDup(utf8path);
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
enum update_return ret = UPDATE_RETURN_NOUPDATE;
|
enum update_return ret = UPDATE_RETURN_NOUPDATE;
|
||||||
@ -389,7 +375,7 @@ static enum update_return updatePath(const char *utf8path)
|
|||||||
return UPDATE_RETURN_ERROR;
|
return UPDATE_RETURN_ERROR;
|
||||||
|
|
||||||
/* if path is in the DB try to update it, or else delete it */
|
/* if path is in the DB try to update it, or else delete it */
|
||||||
if ((directory = getDirectoryDetails(path, &shortname))) {
|
if ((directory = getDirectory(path))) {
|
||||||
parentDirectory = directory->parent;
|
parentDirectory = directory->parent;
|
||||||
|
|
||||||
/* if this update directory is successfull, we are done */
|
/* if this update directory is successfull, we are done */
|
||||||
@ -411,17 +397,17 @@ static enum update_return updatePath(const char *utf8path)
|
|||||||
ret = UPDATE_RETURN_UPDATED;
|
ret = UPDATE_RETURN_UPDATED;
|
||||||
/* don't return, path maybe a song now */
|
/* don't return, path maybe a song now */
|
||||||
}
|
}
|
||||||
} else if ((song = getSongDetails(path, &shortname, &parentDirectory))) {
|
} else if ((song = getSongFromDB(path))) {
|
||||||
|
parentDirectory = song->parentDir;
|
||||||
if (!parentDirectory->stat
|
if (!parentDirectory->stat
|
||||||
&& statDirectory(parentDirectory) < 0) {
|
&& statDirectory(parentDirectory) < 0) {
|
||||||
free(path);
|
free(path);
|
||||||
return UPDATE_RETURN_NOUPDATE;
|
return UPDATE_RETURN_NOUPDATE;
|
||||||
}
|
}
|
||||||
/* if this song update is successfull, we are done */
|
/* if this song update is successful, we are done */
|
||||||
else if (0 == inodeFoundInParent(parentDirectory->parent,
|
else if (!inodeFoundInParent(parentDirectory->parent,
|
||||||
parentDirectory->inode,
|
parentDirectory->inode,
|
||||||
parentDirectory->device)
|
parentDirectory->device) &&
|
||||||
&& song &&
|
|
||||||
isMusic(get_song_url(path_max_tmp, song), &mtime, 0)) {
|
isMusic(get_song_url(path_max_tmp, song), &mtime, 0)) {
|
||||||
free(path);
|
free(path);
|
||||||
if (song->mtime == mtime)
|
if (song->mtime == mtime)
|
||||||
@ -430,13 +416,13 @@ static enum update_return updatePath(const char *utf8path)
|
|||||||
return UPDATE_RETURN_UPDATED;
|
return UPDATE_RETURN_UPDATED;
|
||||||
else {
|
else {
|
||||||
removeSongFromDirectory(parentDirectory,
|
removeSongFromDirectory(parentDirectory,
|
||||||
shortname);
|
song->url);
|
||||||
return UPDATE_RETURN_UPDATED;
|
return UPDATE_RETURN_UPDATED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if updateDirectory fails, means we should delete it */
|
/* if updateDirectory fails, means we should delete it */
|
||||||
else {
|
else {
|
||||||
removeSongFromDirectory(parentDirectory, shortname);
|
removeSongFromDirectory(parentDirectory, song->url);
|
||||||
ret = UPDATE_RETURN_UPDATED;
|
ret = UPDATE_RETURN_UPDATED;
|
||||||
/* don't return, path maybe a directory now */
|
/* don't return, path maybe a directory now */
|
||||||
}
|
}
|
||||||
@ -447,13 +433,13 @@ static enum update_return updatePath(const char *utf8path)
|
|||||||
* name or vice versa, we need to add it to the db
|
* name or vice versa, we need to add it to the db
|
||||||
*/
|
*/
|
||||||
if (isDir(path) || isMusic(path, NULL, 0)) {
|
if (isDir(path) || isMusic(path, NULL, 0)) {
|
||||||
parentDirectory = addParentPathToDB(path, &shortname);
|
parentDirectory = addParentPathToDB(path);
|
||||||
if (!parentDirectory || (!parentDirectory->stat &&
|
if (!parentDirectory || (!parentDirectory->stat &&
|
||||||
statDirectory(parentDirectory) < 0)) {
|
statDirectory(parentDirectory) < 0)) {
|
||||||
} else if (0 == inodeFoundInParent(parentDirectory->parent,
|
} else if (0 == inodeFoundInParent(parentDirectory->parent,
|
||||||
parentDirectory->inode,
|
parentDirectory->inode,
|
||||||
parentDirectory->device)
|
parentDirectory->device)
|
||||||
&& addToDirectory(parentDirectory, shortname, path)
|
&& addToDirectory(parentDirectory, path)
|
||||||
== UPDATE_RETURN_UPDATED) {
|
== UPDATE_RETURN_UPDATED) {
|
||||||
ret = UPDATE_RETURN_UPDATED;
|
ret = UPDATE_RETURN_UPDATED;
|
||||||
}
|
}
|
||||||
@ -506,7 +492,7 @@ static enum update_return updateDirectory(Directory * directory)
|
|||||||
if (directory->path)
|
if (directory->path)
|
||||||
utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8),
|
utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8),
|
||||||
dirname, strlen(dirname));
|
dirname, strlen(dirname));
|
||||||
if (updateInDirectory(directory, utf8, path_max_tmp) > 0)
|
if (updateInDirectory(directory, path_max_tmp) > 0)
|
||||||
ret = UPDATE_RETURN_UPDATED;
|
ret = UPDATE_RETURN_UPDATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,7 +531,7 @@ static enum update_return exploreDirectory(Directory * directory)
|
|||||||
if (directory->path)
|
if (directory->path)
|
||||||
utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8),
|
utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8),
|
||||||
dirname, strlen(dirname));
|
dirname, strlen(dirname));
|
||||||
if (addToDirectory(directory, utf8, path_max_tmp) ==
|
if (addToDirectory(directory, path_max_tmp) ==
|
||||||
UPDATE_RETURN_UPDATED)
|
UPDATE_RETURN_UPDATED)
|
||||||
ret = UPDATE_RETURN_UPDATED;
|
ret = UPDATE_RETURN_UPDATED;
|
||||||
}
|
}
|
||||||
@ -583,7 +569,6 @@ static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum update_return addSubDirectoryToDirectory(Directory * directory,
|
static enum update_return addSubDirectoryToDirectory(Directory * directory,
|
||||||
mpd_unused const char *shortname,
|
|
||||||
const char *name, struct stat *st)
|
const char *name, struct stat *st)
|
||||||
{
|
{
|
||||||
Directory *subDirectory;
|
Directory *subDirectory;
|
||||||
@ -605,8 +590,7 @@ static enum update_return addSubDirectoryToDirectory(Directory * directory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum update_return
|
static enum update_return
|
||||||
addToDirectory(Directory * directory,
|
addToDirectory(Directory * directory, const char *name)
|
||||||
const char *shortname, const char *name)
|
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@ -617,15 +601,16 @@ addToDirectory(Directory * directory,
|
|||||||
|
|
||||||
if (S_ISREG(st.st_mode) &&
|
if (S_ISREG(st.st_mode) &&
|
||||||
hasMusicSuffix(name, 0) && isMusic(name, NULL, 0)) {
|
hasMusicSuffix(name, 0) && isMusic(name, NULL, 0)) {
|
||||||
Song *song = newSong(shortname, SONG_TYPE_FILE, directory);
|
Song *song;
|
||||||
if (!song)
|
const char *shortname = mpd_basename(name);
|
||||||
return UPDATE_RETURN_ERROR;
|
|
||||||
|
if (!(song = newSong(shortname, SONG_TYPE_FILE, directory)))
|
||||||
|
return -1;
|
||||||
songvec_add(&directory->songs, song);
|
songvec_add(&directory->songs, song);
|
||||||
LOG("added %s\n", name);
|
LOG("added %s\n", name);
|
||||||
return UPDATE_RETURN_UPDATED;
|
return UPDATE_RETURN_UPDATED;
|
||||||
} else if (S_ISDIR(st.st_mode)) {
|
} else if (S_ISDIR(st.st_mode)) {
|
||||||
return addSubDirectoryToDirectory(directory, shortname, name,
|
return addSubDirectoryToDirectory(directory, name, &st);
|
||||||
&st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("addToDirectory: %s is not a directory or music\n", name);
|
DEBUG("addToDirectory: %s is not a directory or music\n", name);
|
||||||
@ -646,8 +631,7 @@ int isRootDirectory(const char *name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Directory *getSubDirectory(Directory * directory, const char *name,
|
static Directory *getSubDirectory(Directory * directory, const char *name)
|
||||||
const char **shortname)
|
|
||||||
{
|
{
|
||||||
Directory *cur = directory;
|
Directory *cur = directory;
|
||||||
Directory *found = NULL;
|
Directory *found = NULL;
|
||||||
@ -664,6 +648,7 @@ static Directory *getSubDirectory(Directory * directory, const char *name,
|
|||||||
*locate = '\0';
|
*locate = '\0';
|
||||||
if (!(found = dirvec_find(&cur->children, duplicated)))
|
if (!(found = dirvec_find(&cur->children, duplicated)))
|
||||||
break;
|
break;
|
||||||
|
assert(cur == found->parent);
|
||||||
cur = found;
|
cur = found;
|
||||||
if (!locate)
|
if (!locate)
|
||||||
break;
|
break;
|
||||||
@ -673,24 +658,12 @@ static Directory *getSubDirectory(Directory * directory, const char *name,
|
|||||||
|
|
||||||
free(duplicated);
|
free(duplicated);
|
||||||
|
|
||||||
if (found && (!(*shortname = strrchr(found->path, '/'))))
|
|
||||||
*shortname = found->path;
|
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Directory *getDirectoryDetails(const char *name, const char **shortname)
|
|
||||||
{
|
|
||||||
*shortname = NULL;
|
|
||||||
|
|
||||||
return getSubDirectory(mp3rootDirectory, name, shortname);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Directory *getDirectory(const char *name)
|
static Directory *getDirectory(const char *name)
|
||||||
{
|
{
|
||||||
const char *shortname;
|
return getSubDirectory(mp3rootDirectory, name);
|
||||||
|
|
||||||
return getSubDirectory(mp3rootDirectory, name, &shortname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int printDirectoryList(struct client *client, struct dirvec *dv)
|
static int printDirectoryList(struct client *client, struct dirvec *dv)
|
||||||
@ -736,10 +709,7 @@ static void writeDirectoryInfo(FILE * fp, Directory * directory)
|
|||||||
|
|
||||||
for (i = 0; i < children->nr; ++i) {
|
for (i = 0; i < children->nr; ++i) {
|
||||||
Directory *cur = children->base[i];
|
Directory *cur = children->base[i];
|
||||||
const char *base = strrchr(cur->path, '/');
|
const char *base = mpd_basename(cur->path);
|
||||||
|
|
||||||
base = base ? base + 1 : cur->path;
|
|
||||||
assert(*base);
|
|
||||||
|
|
||||||
retv = fprintf(fp, DIRECTORY_DIR "%s\n", base);
|
retv = fprintf(fp, DIRECTORY_DIR "%s\n", base);
|
||||||
if (retv < 0) {
|
if (retv < 0) {
|
||||||
@ -1045,8 +1015,7 @@ void initMp3Directory(void)
|
|||||||
stats.dbPlayTime = sumSongTimesIn(NULL);
|
stats.dbPlayTime = sumSongTimesIn(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Song *getSongDetails(const char *file, const char **shortnameRet,
|
Song *getSongFromDB(const char *file)
|
||||||
Directory ** directoryRet)
|
|
||||||
{
|
{
|
||||||
Song *song = NULL;
|
Song *song = NULL;
|
||||||
Directory *directory;
|
Directory *directory;
|
||||||
@ -1068,21 +1037,13 @@ static Song *getSongDetails(const char *file, const char **shortnameRet,
|
|||||||
goto out;
|
goto out;
|
||||||
if (!(song = songvec_find(&directory->songs, shortname)))
|
if (!(song = songvec_find(&directory->songs, shortname)))
|
||||||
goto out;
|
goto out;
|
||||||
|
assert(song->parentDir == directory);
|
||||||
|
|
||||||
if (shortnameRet)
|
|
||||||
*shortnameRet = song->url;
|
|
||||||
if (directoryRet)
|
|
||||||
*directoryRet = directory;
|
|
||||||
out:
|
out:
|
||||||
free(duplicated);
|
free(duplicated);
|
||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
|
|
||||||
Song *getSongFromDB(const char *file)
|
|
||||||
{
|
|
||||||
return getSongDetails(file, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t getDbModTime(void)
|
time_t getDbModTime(void)
|
||||||
{
|
{
|
||||||
return directory_dbModTime;
|
return directory_dbModTime;
|
||||||
|
Loading…
Reference in New Issue
Block a user