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
This commit is contained in:
Warren Dukes 2004-06-23 03:33:35 +00:00
parent 8933f5d416
commit 0083b07395

View File

@ -69,10 +69,17 @@
typedef List DirectoryList; typedef List DirectoryList;
typedef struct _DirectoryStat {
ino_t inode;
dev_t device;
} DirectoryStat;
typedef struct _Directory { typedef struct _Directory {
char * utf8name; char * utf8name;
DirectoryList * subDirectories; DirectoryList * subDirectories;
SongList * songs; SongList * songs;
struct _Directory * parent;
DirectoryStat * stat;
} Directory; } Directory;
Directory * mp3rootDirectory = NULL; Directory * mp3rootDirectory = NULL;
@ -104,10 +111,9 @@ void deleteEmptyDirectoriesInDirectory(Directory * directory);
void removeSongFromDirectory(Directory * directory, char * shortname); void removeSongFromDirectory(Directory * directory, char * shortname);
int addSubDirectoryToDirectory(Directory * directory, char * shortname, int addSubDirectoryToDirectory(Directory * directory, char * shortname,
char * name); char * name, struct stat * st);
Directory * getDirectoryDetails(char * name, char ** shortname, Directory * getDirectoryDetails(char * name, char ** shortname);
Directory ** parentDirectory);
Directory * getDirectory(char * name); Directory * getDirectory(char * name);
@ -118,6 +124,8 @@ int updatePath(char * utf8path);
void sortDirectory(Directory * directory); void sortDirectory(Directory * directory);
int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device);
void clearUpdatePid() { void clearUpdatePid() {
directory_updatePid = 0; directory_updatePid = 0;
} }
@ -240,7 +248,19 @@ int updateInit(FILE * fp, List * pathList) {
return 0; 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 * directory;
directory = malloc(sizeof(Directory)); directory = malloc(sizeof(Directory));
@ -249,6 +269,8 @@ Directory * newDirectory(char * dirname) {
else directory->utf8name = NULL; else directory->utf8name = NULL;
directory->subDirectories = newDirectoryList(); directory->subDirectories = newDirectoryList();
directory->songs = newSongList(); directory->songs = newSongList();
directory->stat = NULL;
directory->parent = parent;
return directory; return directory;
} }
@ -257,6 +279,7 @@ void freeDirectory(Directory * directory) {
freeDirectoryList(directory->subDirectories); freeDirectoryList(directory->subDirectories);
freeSongList(directory->songs); freeSongList(directory->songs);
if(directory->utf8name) free(directory->utf8name); if(directory->utf8name) free(directory->utf8name);
freeDirectoryStatFromDirectory(directory);
free(directory); free(directory);
} }
@ -326,7 +349,7 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) {
} }
else { else {
return addSubDirectoryToDirectory(directory,shortname, return addSubDirectoryToDirectory(directory,shortname,
name); name, &st);
} }
} }
@ -427,7 +450,7 @@ Directory * addDirectoryPathToDB(char * utf8path, char ** shortname) {
if(!findInList(parentDirectory->subDirectories,*shortname, &directory)) if(!findInList(parentDirectory->subDirectories,*shortname, &directory))
{ {
directory = newDirectory(utf8path); directory = newDirectory(utf8path, parentDirectory);
insertInList(parentDirectory->subDirectories,*shortname, insertInList(parentDirectory->subDirectories,*shortname,
directory); directory);
} }
@ -475,9 +498,9 @@ int updatePath(char * utf8path) {
if(NULL==path) return -1; if(NULL==path) return -1;
/* 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 = getDirectoryDetails(path,&shortname))) {
&parentDirectory))) parentDirectory = directory->parent;
{
/* if this update directory is successfull, we are done */ /* if this update directory is successfull, we are done */
if((ret = updateDirectory(directory))>=0) if((ret = updateDirectory(directory))>=0)
{ {
@ -631,10 +654,41 @@ int exploreDirectory(Directory * directory) {
return ret; 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, 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) { if(exploreDirectory(subDirectory)<1) {
freeDirectory(subDirectory); freeDirectory(subDirectory);
@ -660,7 +714,8 @@ int addToDirectory(Directory * directory, char * shortname, char * name) {
return 1; return 1;
} }
else if(S_ISDIR(st.st_mode)) { 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); 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, Directory * getSubDirectory(Directory * directory, char * name,
char ** shortname, Directory ** parentDirectory) char ** shortname)
{ {
Directory * subDirectory; Directory * subDirectory;
int len; int len;
@ -705,31 +760,24 @@ Directory * getSubDirectory(Directory * directory, char * name,
if((subDirectory = findSubDirectory(directory,name))==NULL) return NULL; if((subDirectory = findSubDirectory(directory,name))==NULL) return NULL;
*shortname = name; *shortname = name;
*parentDirectory = directory;
len = 0; len = 0;
while(name[len]!='/' && name[len]!='\0') len++; while(name[len]!='/' && name[len]!='\0') len++;
while(name[len]=='/') len++; while(name[len]=='/') len++;
return getSubDirectory(subDirectory,&(name[len]),shortname, return getSubDirectory(subDirectory,&(name[len]),shortname);
parentDirectory);
} }
Directory * getDirectoryDetails(char * name, char ** shortname, Directory * getDirectoryDetails(char * name, char ** shortname) {
Directory ** parentDirectory)
{
*shortname = NULL; *shortname = NULL;
*parentDirectory = NULL;
return getSubDirectory(mp3rootDirectory,name,shortname,parentDirectory); return getSubDirectory(mp3rootDirectory,name,shortname);
} }
Directory * getDirectory(char * name) { Directory * getDirectory(char * name) {
char * shortname; char * shortname;
Directory * parentDirectory;
return getSubDirectory(mp3rootDirectory,name,&shortname, return getSubDirectory(mp3rootDirectory,name,&shortname);
&parentDirectory);
} }
int printDirectoryList(FILE * fp, DirectoryList * directoryList) { int printDirectoryList(FILE * fp, DirectoryList * directoryList) {
@ -823,7 +871,7 @@ void readDirectoryInfo(FILE * fp,Directory * directory) {
} }
if(NULL==nextDirNode) { if(NULL==nextDirNode) {
subDirectory = newDirectory(name); subDirectory = newDirectory(name, directory);
insertInList(directory->subDirectories,key, insertInList(directory->subDirectories,key,
(void *)subDirectory); (void *)subDirectory);
} }
@ -832,7 +880,7 @@ void readDirectoryInfo(FILE * fp,Directory * directory) {
nextDirNode = nextDirNode->nextNode; nextDirNode = nextDirNode->nextNode;
} }
else { else {
subDirectory = newDirectory(name); subDirectory = newDirectory(name, directory);
insertInListBeforeNode( insertInListBeforeNode(
directory->subDirectories, directory->subDirectories,
nextDirNode, nextDirNode,
@ -900,7 +948,7 @@ int readDirectoryDB() {
FILE * fp; FILE * fp;
struct stat st; struct stat st;
if(!mp3rootDirectory) mp3rootDirectory = newDirectory(NULL); if(!mp3rootDirectory) mp3rootDirectory = newDirectory(NULL, NULL);
while(!(fp=fopen(directory_db,"r")) && errno==EINTR); while(!(fp=fopen(directory_db,"r")) && errno==EINTR);
if(!fp) return -1; if(!fp) return -1;
@ -1213,6 +1261,17 @@ int countSongsIn(FILE * fp, char * name) {
return count; 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 sumSongTimesIn(FILE * fp, char * name) {
unsigned long dbPlayTime = 0; unsigned long dbPlayTime = 0;
void * ptr = (void *)&dbPlayTime; void * ptr = (void *)&dbPlayTime;
@ -1225,8 +1284,9 @@ unsigned long sumSongTimesIn(FILE * fp, char * name) {
void initMp3Directory() { void initMp3Directory() {
struct stat st; struct stat st;
mp3rootDirectory = newDirectory(NULL); mp3rootDirectory = newDirectory(NULL, NULL);
exploreDirectory(mp3rootDirectory); exploreDirectory(mp3rootDirectory);
freeAllDirectoryStats(mp3rootDirectory);
stats.numberOfSongs = countSongsIn(stderr,NULL); stats.numberOfSongs = countSongsIn(stderr,NULL);
stats.dbPlayTime = sumSongTimesIn(stderr,NULL); stats.dbPlayTime = sumSongTimesIn(stderr,NULL);