From 0083b0739593d60f0673949cc57f85f18a883e75 Mon Sep 17 00:00:00 2001 From: Warren Dukes Date: Wed, 23 Jun 2004 03:33:35 +0000 Subject: now we avoid recursive symlinks on creating the db still needs to be implemented for updating git-svn-id: https://svn.musicpd.org/mpd/trunk@1622 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/directory.c | 116 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 28 deletions(-) (limited to 'src/directory.c') diff --git a/src/directory.c b/src/directory.c index 34efa27dd..2954e054e 100644 --- a/src/directory.c +++ b/src/directory.c @@ -69,10 +69,17 @@ typedef List DirectoryList; +typedef struct _DirectoryStat { + ino_t inode; + dev_t device; +} DirectoryStat; + typedef struct _Directory { char * utf8name; DirectoryList * subDirectories; SongList * songs; + struct _Directory * parent; + DirectoryStat * stat; } Directory; Directory * mp3rootDirectory = NULL; @@ -104,10 +111,9 @@ void deleteEmptyDirectoriesInDirectory(Directory * directory); void removeSongFromDirectory(Directory * directory, char * shortname); int addSubDirectoryToDirectory(Directory * directory, char * shortname, - char * name); + char * name, struct stat * st); -Directory * getDirectoryDetails(char * name, char ** shortname, - Directory ** parentDirectory); +Directory * getDirectoryDetails(char * name, char ** shortname); Directory * getDirectory(char * name); @@ -118,6 +124,8 @@ int updatePath(char * utf8path); void sortDirectory(Directory * directory); +int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device); + void clearUpdatePid() { directory_updatePid = 0; } @@ -240,7 +248,19 @@ int updateInit(FILE * fp, List * pathList) { return 0; } -Directory * newDirectory(char * dirname) { +DirectoryStat * newDirectoryStat(struct stat * st) { + DirectoryStat * ret = malloc(sizeof(DirectoryStat)); + ret->inode = st->st_ino; + ret->device = st->st_dev; + return ret; +} + +void freeDirectoryStatFromDirectory(Directory * dir) { + if(dir->stat) free(dir->stat); + dir->stat = NULL; +} + +Directory * newDirectory(char * dirname, Directory * parent) { Directory * directory; directory = malloc(sizeof(Directory)); @@ -249,6 +269,8 @@ Directory * newDirectory(char * dirname) { else directory->utf8name = NULL; directory->subDirectories = newDirectoryList(); directory->songs = newSongList(); + directory->stat = NULL; + directory->parent = parent; return directory; } @@ -257,6 +279,7 @@ void freeDirectory(Directory * directory) { freeDirectoryList(directory->subDirectories); freeSongList(directory->songs); if(directory->utf8name) free(directory->utf8name); + freeDirectoryStatFromDirectory(directory); free(directory); } @@ -326,7 +349,7 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) { } else { return addSubDirectoryToDirectory(directory,shortname, - name); + name, &st); } } @@ -427,7 +450,7 @@ Directory * addDirectoryPathToDB(char * utf8path, char ** shortname) { if(!findInList(parentDirectory->subDirectories,*shortname, &directory)) { - directory = newDirectory(utf8path); + directory = newDirectory(utf8path, parentDirectory); insertInList(parentDirectory->subDirectories,*shortname, directory); } @@ -475,9 +498,9 @@ int updatePath(char * utf8path) { if(NULL==path) return -1; /* if path is in the DB try to update it, or else delete it */ - if((directory = getDirectoryDetails(path,&shortname, - &parentDirectory))) - { + if((directory = getDirectoryDetails(path,&shortname))) { + parentDirectory = directory->parent; + /* if this update directory is successfull, we are done */ if((ret = updateDirectory(directory))>=0) { @@ -631,10 +654,41 @@ int exploreDirectory(Directory * directory) { return ret; } +int statDirectory(Directory * dir) { + struct stat st; + + if(myStat(dir->utf8name ? dir->utf8name : "", &st) < 0) return -1; + + dir->stat = newDirectoryStat(&st); + + return 0; +} + +int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device) { + while(parent) { + if(!parent->stat) { + if(statDirectory(parent) < 0) return -1; + } + if(parent->stat->inode == inode && + parent->stat->device == device) + { + return 1; + } + parent = parent->parent; + } + + return 0; +} + int addSubDirectoryToDirectory(Directory * directory, char * shortname, - char * name) + char * name, struct stat * st) { - Directory * subDirectory = newDirectory(name); + Directory * subDirectory; + + if(inodeFoundInParent(directory, st->st_ino, st->st_dev)) return 0; + + subDirectory = newDirectory(name, directory); + subDirectory->stat = newDirectoryStat(st); if(exploreDirectory(subDirectory)<1) { freeDirectory(subDirectory); @@ -660,7 +714,8 @@ int addToDirectory(Directory * directory, char * shortname, char * name) { return 1; } else if(S_ISDIR(st.st_mode)) { - return addSubDirectoryToDirectory(directory,shortname,name); + return addSubDirectoryToDirectory(directory, shortname, name, + &st); } DEBUG("addToDirectory: %s is not a directory or music\n",name); @@ -693,7 +748,7 @@ Directory * findSubDirectory(Directory * directory,char * name) { } Directory * getSubDirectory(Directory * directory, char * name, - char ** shortname, Directory ** parentDirectory) + char ** shortname) { Directory * subDirectory; int len; @@ -705,31 +760,24 @@ Directory * getSubDirectory(Directory * directory, char * name, if((subDirectory = findSubDirectory(directory,name))==NULL) return NULL; *shortname = name; - *parentDirectory = directory; len = 0; while(name[len]!='/' && name[len]!='\0') len++; while(name[len]=='/') len++; - return getSubDirectory(subDirectory,&(name[len]),shortname, - parentDirectory); + return getSubDirectory(subDirectory,&(name[len]),shortname); } -Directory * getDirectoryDetails(char * name, char ** shortname, - Directory ** parentDirectory) -{ +Directory * getDirectoryDetails(char * name, char ** shortname) { *shortname = NULL; - *parentDirectory = NULL; - return getSubDirectory(mp3rootDirectory,name,shortname,parentDirectory); + return getSubDirectory(mp3rootDirectory,name,shortname); } Directory * getDirectory(char * name) { char * shortname; - Directory * parentDirectory; - return getSubDirectory(mp3rootDirectory,name,&shortname, - &parentDirectory); + return getSubDirectory(mp3rootDirectory,name,&shortname); } int printDirectoryList(FILE * fp, DirectoryList * directoryList) { @@ -823,7 +871,7 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { } if(NULL==nextDirNode) { - subDirectory = newDirectory(name); + subDirectory = newDirectory(name, directory); insertInList(directory->subDirectories,key, (void *)subDirectory); } @@ -832,7 +880,7 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { nextDirNode = nextDirNode->nextNode; } else { - subDirectory = newDirectory(name); + subDirectory = newDirectory(name, directory); insertInListBeforeNode( directory->subDirectories, nextDirNode, @@ -900,7 +948,7 @@ int readDirectoryDB() { FILE * fp; struct stat st; - if(!mp3rootDirectory) mp3rootDirectory = newDirectory(NULL); + if(!mp3rootDirectory) mp3rootDirectory = newDirectory(NULL, NULL); while(!(fp=fopen(directory_db,"r")) && errno==EINTR); if(!fp) return -1; @@ -1213,6 +1261,17 @@ int countSongsIn(FILE * fp, char * name) { return count; } +void freeAllDirectoryStats(Directory * directory) { + ListNode * node = directory->subDirectories->firstNode; + + while(node != NULL) { + freeAllDirectoryStats(directory); + node = node->nextNode; + } + + freeDirectoryStatFromDirectory(directory); +} + unsigned long sumSongTimesIn(FILE * fp, char * name) { unsigned long dbPlayTime = 0; void * ptr = (void *)&dbPlayTime; @@ -1225,8 +1284,9 @@ unsigned long sumSongTimesIn(FILE * fp, char * name) { void initMp3Directory() { struct stat st; - mp3rootDirectory = newDirectory(NULL); + mp3rootDirectory = newDirectory(NULL, NULL); exploreDirectory(mp3rootDirectory); + freeAllDirectoryStats(mp3rootDirectory); stats.numberOfSongs = countSongsIn(stderr,NULL); stats.dbPlayTime = sumSongTimesIn(stderr,NULL); -- cgit v1.2.3