From 2e420db19cab6bf7849db02bf6b99e6bc58c40df Mon Sep 17 00:00:00 2001 From: Warren Dukes Date: Fri, 16 Apr 2004 00:41:56 +0000 Subject: remove directory mtime from db! also, only reReadDB and write DB on update if something was actually updated git-svn-id: https://svn.musicpd.org/mpd/trunk@780 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- TODO | 4 -- src/directory.c | 179 ++++++++++++++++++++++++++++++++++++++------------------ src/ls.c | 3 +- src/ls.h | 2 +- 4 files changed, 125 insertions(+), 63 deletions(-) diff --git a/TODO b/TODO index 123089429..3d76e2091 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,4 @@ 1) non-blocking (for other clients) update - n) mpd command for rereading db - o) rewrite update functions to indicate if something was updated, then - when update process returns, indicate wheater db was updated - and should be reread by parent process p) set error: in status when an error occurs during update 2) cleanup main() diff --git a/src/directory.c b/src/directory.c index 95f4f9bf2..726eae241 100644 --- a/src/directory.c +++ b/src/directory.c @@ -59,13 +59,16 @@ #define DIRECTORY_SEARCH_TITLE "title" #define DIRECTORY_SEARCH_FILENAME "filename" +#define DIRECTORY_UPDATE_EXIT_NOUPDATE 0 +#define DIRECTORY_UPDATE_EXIT_UPDATE 1 +#define DIRECTORY_UPDATE_EXIT_ERROR 2 + typedef List DirectoryList; typedef struct _Directory { char * utf8name; DirectoryList * subDirectories; SongList * songs; - time_t mtime; /* modification time */ } Directory; Directory * mp3rootDirectory = NULL; @@ -107,7 +110,7 @@ Directory * getDirectory(char * name); Song * getSongDetails(char * file, char ** shortnameRet, Directory ** directoryRet); -void updatePath(char * utf8path); +int updatePath(char * utf8path); void sortDirectory(Directory * directory); @@ -129,12 +132,20 @@ void directory_sigChldHandler(int pid, int status) { "non-TERM signal: %i\n", WTERMSIG(status)); } - else if(!WIFSIGNALED(status) && - WEXITSTATUS(status)==EXIT_SUCCESS) - { - DEBUG("direcotry_sigChldHandler: " - "updated db succesffully\n"); - directory_reReadDB = 1; + else if(!WIFSIGNALED(status)) { + switch(WEXITSTATUS(status)) + { + case DIRECTORY_UPDATE_EXIT_UPDATE: + directory_reReadDB = 1; + DEBUG("direcotry_sigChldHandler: " + "updated db\n"); + case DIRECTORY_UPDATE_EXIT_NOUPDATE: + DEBUG("direcotry_sigChldHandler: " + "update exitted succesffully\n"); + break; + default: + ERROR("error updating db\n"); + } } clearUpdatePid(); } @@ -167,6 +178,7 @@ int updateInit(FILE * fp, List * pathList) { directory_updatePid = fork(); if(directory_updatePid==0) { /* child */ + int dbUpdated = 0; clearPlayerPid(); unblockSignals(); @@ -181,19 +193,34 @@ int updateInit(FILE * fp, List * pathList) { ListNode * node = pathList->firstNode; while(node) { - updatePath(node->key); + switch(updatePath(node->key)) { + case 1: + dbUpdated = 1; + break; + case 0: + break; + default: + exit(DIRECTORY_UPDATE_EXIT_ERROR); + } node = node->nextNode; } } - else if(updateDirectory(mp3rootDirectory)<0) exit(EXIT_FAILURE); + else { + if((dbUpdated = updateDirectory(mp3rootDirectory))<0) { + exit(DIRECTORY_UPDATE_EXIT_ERROR); + } + } + + if(!dbUpdated) exit(DIRECTORY_UPDATE_EXIT_NOUPDATE); + /* ignore signals since we don't want them to corrupt the db*/ ignoreSignals(); if(writeDirectoryDB()<0) { ERROR("problems writing music db file, \"%s\"\n", directory_db); - exit(EXIT_FAILURE); + exit(DIRECTORY_UPDATE_EXIT_ERROR); } - exit(EXIT_SUCCESS); + exit(DIRECTORY_UPDATE_EXIT_UPDATE); } else if(directory_updatePid < 0) { unblockSignals(); @@ -214,7 +241,7 @@ int updateInit(FILE * fp, List * pathList) { return 0; } -Directory * newDirectory(char * dirname, time_t mtime) { +Directory * newDirectory(char * dirname) { Directory * directory; directory = malloc(sizeof(Directory)); @@ -223,8 +250,6 @@ Directory * newDirectory(char * dirname, time_t mtime) { else directory->utf8name = NULL; directory->subDirectories = newDirectoryList(); directory->songs = newSongList(); - if(mtime<0) isDir(dirname,&(directory->mtime)); - else directory->mtime = mtime; return directory; } @@ -271,6 +296,11 @@ void deleteEmptyDirectoriesInDirectory(Directory * directory) { } } +/* return values: + -1 -> error + 0 -> no error, but nothing updated + 1 -> no error, and stuff updated + */ int updateInDirectory(Directory * directory, char * shortname, char * name) { time_t mtime; void * song; @@ -279,19 +309,24 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) { if(isMusic(name,&mtime)) { if(0==findInList(directory->songs,shortname,&song)) { addToDirectory(directory,shortname,name); + return 1; } else if(mtime!=((Song *)song)->mtime) { LOG("updating %s\n",name); if(updateSongInfo((Song *)song)<0) { removeSongFromDirectory(directory,shortname); } + return 1; } } - else if(isDir(name,&mtime)) { + else if(isDir(name)) { if(findInList(directory->subDirectories,shortname,(void **)&subDir)) { - updateDirectory((Directory *)subDir); + if(updateDirectory((Directory *)subDir)>0) return 1; } - else addSubDirectoryToDirectory(directory,shortname,name); + else { + addSubDirectoryToDirectory(directory,shortname,name); + return 1; + } } return 0; @@ -308,6 +343,7 @@ int removeDeletedFromDirectory(Directory * directory) { char * utf8; ListNode * node; ListNode * tmpNode; + int ret = 0; cwd[0] = '.'; cwd[1] = '\0'; @@ -336,10 +372,11 @@ int removeDeletedFromDirectory(Directory * directory) { while(node) { tmpNode = node->nextNode; if(findInList(entList,node->key,&name)) { - if(!isDir((char *)name,NULL)) { + if(!isDir((char *)name)) { LOG("removing directory: %s\n",(char*)name); deleteFromList(directory->subDirectories, node->key); + ret = 1; } } else { @@ -347,6 +384,7 @@ int removeDeletedFromDirectory(Directory * directory) { if(directory->utf8name) LOG("%s/",directory->utf8name); LOG("%s\n",node->key); deleteFromList(directory->subDirectories,node->key); + ret = 1; } node = tmpNode; } @@ -357,17 +395,19 @@ int removeDeletedFromDirectory(Directory * directory) { if(findInList(entList,node->key,(void **)&name)) { if(!isMusic(name,NULL)) { removeSongFromDirectory(directory,node->key); + ret = 1; } } else { removeSongFromDirectory(directory,node->key); + ret = 1; } node = tmpNode; } freeList(entList); - return 0; + return ret; } Directory * addDirectoryPathToDB(char * utf8path, char ** shortname) { @@ -415,61 +455,88 @@ Directory * addParentPathToDB(char * utf8path, char ** shortname) { return (Directory *)parentDirectory; } -void updatePath(char * utf8path) { +/* return values: + -1 -> error + 0 -> no error, but nothing updated + 1 -> no error, and stuff updated + */ +int updatePath(char * utf8path) { Directory * directory; Directory * parentDirectory; Song * song; char * shortname; char * path = sanitizePathDup(utf8path); + time_t mtime; + int ret = 0; - if(NULL==path) return; + 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 this update directory is successfull, we are done */ - if(updateDirectory(directory)==0) + if((ret = updateDirectory(directory))>=0) { free(path); sortDirectory(directory); - return; + return ret; } /* we don't want to delete the root directory */ else if(directory == mp3rootDirectory) { free(path); - return; + return 0; } /* if updateDirectory fials, means we should delete it */ else { LOG("removing directory: %s\n",path); deleteFromList(parentDirectory->subDirectories, shortname); + ret = 1; + /* don't return, path maybe a song now*/ } } else if((song = getSongDetails(path,&shortname,&parentDirectory))) { /* if this song update is successfull, we are done */ - if(song && updateSongInfo(song)==0) { + if(song && isMusic(song->utf8file,&mtime)) { free(path); - return; + if(song->mtime==mtime) return 0; + else if(updateSongInfo(song)==0) return 1; + else { + removeSongFromDirectory(parentDirectory, + shortname); + return 1; + } } /* if updateDirectory fials, means we should delete it */ - else removeSongFromDirectory(parentDirectory,shortname); + else { + removeSongFromDirectory(parentDirectory,shortname); + ret = 1; + /* don't return, path maybe a directory now*/ + } } /* path not found in the db, see if it actually exists on the fs. * Also, if by chance a directory was replaced by a file of the same * name or vice versa, we need to add it to the db */ - if(isDir(path,NULL) || isMusic(path,NULL)) { + if(isDir(path) || isMusic(path,NULL)) { parentDirectory = addParentPathToDB(path,&shortname); addToDirectory(parentDirectory,shortname,path); sortDirectory(parentDirectory); + ret = 1; } free(path); + + return ret; } +/* return values: + -1 -> error + 0 -> no error, but nothing updated + 1 -> no error, and stuff updated + */ int updateDirectory(Directory * directory) { DIR * dir; char cwd[2]; @@ -477,12 +544,13 @@ int updateDirectory(Directory * directory) { char * s; char * utf8; char * dirname = directory->utf8name; + int ret = 0; cwd[0] = '.'; cwd[1] = '\0'; if(dirname==NULL) dirname=cwd; - removeDeletedFromDirectory(directory); + if(removeDeletedFromDirectory(directory)>0) ret = 1; if((dir = opendir(rmp2amp(utf8ToFsCharset(dirname))))==NULL) return -1; @@ -500,16 +568,14 @@ int updateDirectory(Directory * directory) { sprintf(s,"%s/%s",directory->utf8name,utf8); } else s = strdup(utf8); - updateInDirectory(directory,utf8,s); + if(updateInDirectory(directory,utf8,s)>0) ret = 1; free(utf8); free(s); } closedir(dir); - if(directory->utf8name) isDir(directory->utf8name,&(directory->mtime)); - - return 0; + return ret; } int exploreDirectory(Directory * directory) { @@ -557,7 +623,7 @@ int exploreDirectory(Directory * directory) { Directory * addSubDirectoryToDirectory(Directory * directory, char * shortname, char * name) { - Directory * subDirectory = newDirectory(name,-1); + Directory * subDirectory = newDirectory(name); insertInList(directory->subDirectories,shortname,subDirectory); exploreDirectory(subDirectory); @@ -566,7 +632,7 @@ Directory * addSubDirectoryToDirectory(Directory * directory, char * shortname, } int addToDirectory(Directory * directory, char * shortname, char * name) { - if(isDir(name,NULL)) { + if(isDir(name)) { addSubDirectoryToDirectory(directory,shortname,name); return 0; } @@ -685,7 +751,6 @@ void writeDirectoryInfo(FILE * fp, Directory * directory) { while(node!=NULL) { subDirectory = (Directory *)node->data; myfprintf(fp,"%s%s\n",DIRECTORY_DIR,node->key); - myfprintf(fp,"%s%li\n",DIRECTORY_MTIME,(long)subDirectory->mtime); writeDirectoryInfo(fp,subDirectory); node = node->nextNode; } @@ -703,7 +768,6 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { char * key; Directory * subDirectory; char * name; - time_t mtime; int strcmpRet; ListNode * nextDirNode = directory->subDirectories->firstNode; ListNode * nodeTemp; @@ -712,21 +776,20 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { if(0==strncmp(DIRECTORY_DIR,buffer,strlen(DIRECTORY_DIR))) { key = strdup(&(buffer[strlen(DIRECTORY_DIR)])); if(myFgets(buffer,bufferSize,fp)<0) { - ERROR("Error reading db\n"); - exit(EXIT_FAILURE); - } - if(strncmp(DIRECTORY_MTIME,buffer,strlen(DIRECTORY_MTIME))) { - ERROR("Error reading db\n"); - ERROR("%s\n",buffer); - exit(EXIT_FAILURE); - } - mtime = atoi(&(buffer[strlen(DIRECTORY_BEGIN)])); - if(myFgets(buffer,bufferSize,fp)<0) { - ERROR("Error reading db\n"); + ERROR("Error reading db, fgets\n"); exit(EXIT_FAILURE); } + /* for compatibility with db's prior to 0.11 */ + if(0==strncmp(DIRECTORY_MTIME,buffer, + strlen(DIRECTORY_MTIME))) + { + if(myFgets(buffer,bufferSize,fp)<0) { + ERROR("Error reading db, fgets\n"); + exit(EXIT_FAILURE); + } + } if(strncmp(DIRECTORY_BEGIN,buffer,strlen(DIRECTORY_BEGIN))) { - ERROR("Error reading db\n"); + ERROR("Error reading db at line: %s\n",buffer); exit(EXIT_FAILURE); } name = strdup(&(buffer[strlen(DIRECTORY_BEGIN)])); @@ -740,17 +803,16 @@ void readDirectoryInfo(FILE * fp,Directory * directory) { } if(NULL==nextDirNode) { - subDirectory = newDirectory(name,mtime); + subDirectory = newDirectory(name); insertInList(directory->subDirectories,key, (void *)subDirectory); } else if(strcmpRet == 0) { subDirectory = (Directory *)nextDirNode->data; - subDirectory->mtime = mtime; nextDirNode = nextDirNode->nextNode; } else { - subDirectory = newDirectory(name,mtime); + subDirectory = newDirectory(name); insertInListBeforeNode( directory->subDirectories, nextDirNode, @@ -817,7 +879,7 @@ int writeDirectoryDB() { int readDirectoryDB() { FILE * fp; - if(!mp3rootDirectory) mp3rootDirectory = newDirectory(NULL,0); + if(!mp3rootDirectory) mp3rootDirectory = newDirectory(NULL); while(!(fp=fopen(directory_db,"r")) && errno==EINTR); if(!fp) return -1; @@ -829,7 +891,7 @@ int readDirectoryDB() { int foundVersion = 0; if(myFgets(buffer,bufferSize,fp)<0) { - ERROR("Error reading db\n"); + ERROR("Error reading db, fgets\n"); exit(EXIT_FAILURE); } if(0==strcmp(DIRECTORY_INFO_BEGIN,buffer)) { @@ -898,6 +960,11 @@ int readDirectoryDB() { return 0; } +/* return values: + -1 -> error + 0 -> no error, but nothing updated + 1 -> no error, and stuff updated + */ int updateMp3Directory(FILE * fp) { if(updateDirectory(mp3rootDirectory)<0) { ERROR("problems updating music db\n"); @@ -1134,7 +1201,7 @@ unsigned long sumSongTimesIn(FILE * fp, char * name) { void initMp3Directory() { struct stat st; - mp3rootDirectory = newDirectory(NULL,0); + mp3rootDirectory = newDirectory(NULL); exploreDirectory(mp3rootDirectory); stats.numberOfSongs = countSongsIn(stderr,NULL); stats.dbPlayTime = sumSongTimesIn(stderr,NULL); diff --git a/src/ls.c b/src/ls.c index 556b68d79..6b9b46ed1 100644 --- a/src/ls.c +++ b/src/ls.c @@ -179,12 +179,11 @@ int hasMp3Suffix(char * utf8file) { return hasSuffix(utf8file,"mp3"); } -int isDir(char * utf8name, time_t * mtime) { +int isDir(char * utf8name) { struct stat st; if(stat(rmp2amp(utf8ToFsCharset(utf8name)),&st)==0) { if(S_ISDIR(st.st_mode)) { - if(mtime) *mtime = st.st_mtime; return 1; } } diff --git a/src/ls.h b/src/ls.h index 03cbb8d11..2f724d08f 100644 --- a/src/ls.h +++ b/src/ls.h @@ -28,7 +28,7 @@ int lsPlaylists(FILE * fp, char * utf8path); int isFile(char * utf8file, time_t * mtime); -int isDir(char * utf8name, time_t * mtime); +int isDir(char * utf8name); int isPlaylist(char * utf8file); -- cgit v1.2.3