start of background scanning

This commit is contained in:
Ron Pedde 2004-03-08 19:21:03 +00:00
parent 13a5b089c0
commit cff316a742
7 changed files with 116 additions and 27 deletions

View File

@ -13,7 +13,7 @@ DBFILE=db-memory.c
endif endif
if COND_NEED_STRCASESTR if COND_NEED_STRCASESTR
STRCASESTR=strcasestr.c STRCASESTR=strcasestr.c strcasestr.h
endif endif
if COND_NEED_STRSEP if COND_NEED_STRSEP
@ -41,7 +41,7 @@ mt_daapd_SOURCES = main.c daapd.h rend.h uici.c uici.h webserver.c \
EXTRA_DIST = mdns/mDNS.c mdns/mDNSClientAPI.h mdns/mDNSDebug.h mdns/mDNSPosix.c \ EXTRA_DIST = mdns/mDNS.c mdns/mDNSClientAPI.h mdns/mDNSDebug.h mdns/mDNSPosix.c \
mdns/mDNSUNP.c mdns/mDNSPlatformFunctions.h mdns/mDNSPosix.h mdns/mDNSUNP.h \ mdns/mDNSUNP.c mdns/mDNSPlatformFunctions.h mdns/mDNSPosix.h mdns/mDNSUNP.h \
rend-howl.c rend-posix.c rend-osx.c strcasestr.c strsep.c db-memory.c \ rend-howl.c rend-posix.c rend-osx.c strcasestr.c strsep.c db-memory.c \
db-gdbm.c db-gdbm.c strcasestr.h

View File

@ -171,7 +171,7 @@ int db_init(char *parameters) {
db_version_no=1; db_version_no=1;
db_song_count=0; db_song_count=0;
/* count the actual songs... */ /* count the actual songs and build the playlists */
tmp_data=gdbm_firstkey(db_songs); tmp_data=gdbm_firstkey(db_songs);
MEMNOTIFY(tmp_data.dptr); MEMNOTIFY(tmp_data.dptr);
@ -560,7 +560,7 @@ int db_add(MP3FILE *pmp3) {
ppacked->time_modified=ppacked->time_added; ppacked->time_modified=ppacked->time_added;
ppacked->time_played=0; ppacked->time_played=0;
if(gdbm_store(db_songs,dkey,*pnew,GDBM_INSERT)) { if(gdbm_store(db_songs,dkey,*pnew,GDBM_REPLACE)) {
log_err(0,"Error inserting file %s in database\n",pmp3->fname); log_err(0,"Error inserting file %s in database\n",pmp3->fname);
} }
@ -789,6 +789,7 @@ int db_playlist_items_enum_end(void) {
return pthread_rwlock_unlock(&db_rwlock); return pthread_rwlock_unlock(&db_rwlock);
} }
/* /*
* db_find * db_find
* *
@ -901,3 +902,33 @@ char *db_get_playlist_name(int playlistid) {
return name; return name;
} }
/*
* db_exists
*
* Check if a particular ID exists or not
*/
int db_exists(int id) {
/* this is wrong and expensive */
MP3FILE *pmp3;
pmp3=db_find(id);
return pmp3 ? 1 : 0;
}
/*
* db_last_modified
*
* See when the file was last updated in the database
*/
int db_last_modified(int id) {
MP3FILE *pmp3;
pmp3=db_find(id);
if(!pmp3)
return 0;
return pmp3->time_modified;
}

View File

@ -629,3 +629,29 @@ char *db_get_playlist_name(int playlistid) {
pthread_rwlock_unlock(&db_rwlock); pthread_rwlock_unlock(&db_rwlock);
return name; return name;
} }
/*
* db_exists
*
* Check if a particular id is in the database
*/
int db_exists(int id) {
MP3FILE *pmp3;
pmp3=db_find(id);
return pmp3 ? 1 : 0;
}
/*
* db_last_modified
*
* See when the file was modified (according to the database)
*
* This is merely a stub for the in-memory db
*/
int db_last_modified(int id) {
return 0;
}

View File

@ -55,4 +55,8 @@ extern int db_playlist_items_enum_end(void);
extern char *db_get_playlist_name(int playlistid); extern char *db_get_playlist_name(int playlistid);
/* For persistant databases only */
extern int db_exists(int id);
extern int db_last_modified(int id);
#endif /* _DB_MEMORY_H_ */ #endif /* _DB_MEMORY_H_ */

View File

@ -38,6 +38,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <netinet/in.h> /* htons and friends */
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@ -46,6 +47,7 @@
#include "err.h" #include "err.h"
#include "mp3-scanner.h" #include "mp3-scanner.h"
#include "playlist.h" #include "playlist.h"
#include "strcasestr.h"
/* /*
* Typedefs * Typedefs
@ -68,6 +70,8 @@ int scan_br_table[] = {
0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0 0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0
}; };
int scan_mode_foreground=1;
char *scan_winamp_genre[] = { char *scan_winamp_genre[] = {
"Blues", // 0 "Blues", // 0
"Classic Rock", "Classic Rock",
@ -226,7 +230,7 @@ char *scan_winamp_genre[] = {
/* /*
* Forwards * Forwards
*/ */
int scan_foreground(char *path); int scan_path(char *path);
int scan_gettags(char *file, MP3FILE *pmp3); int scan_gettags(char *file, MP3FILE *pmp3);
int scan_get_mp3tags(char *file, MP3FILE *pmp3); int scan_get_mp3tags(char *file, MP3FILE *pmp3);
int scan_get_aactags(char *file, MP3FILE *pmp3); int scan_get_aactags(char *file, MP3FILE *pmp3);
@ -250,37 +254,42 @@ void scan_music_file(char *path, struct dirent *pde, struct stat *psb);
int scan_init(char *path) { int scan_init(char *path) {
int err; int err;
scan_mode_foreground=0;
if(db_is_empty()) { if(db_is_empty()) {
scan_mode_foreground=1;
if(db_start_initial_update()) if(db_start_initial_update())
return -1; return -1;
}
DPRINTF(ERR_DEBUG,"%s scanning for MP3s in %s\n",
scan_mode_foreground ? "Foreground" : "Background",
path);
DPRINTF(ERR_DEBUG,"Scanning for MP3s in %s\n",path); err=scan_path(path);
err=scan_foreground(path);
if(scan_mode_foreground)
if(db_end_initial_update()) if(db_end_initial_update())
return -1; return -1;
} else {
/* do deferred updating */ scan_mode_foreground=0;
return ENOTSUP;
}
return err; return err;
} }
/* /*
* scan_foreground * scan_path
* *
* Do a brute force scan of a path, finding all the MP3 files there * Do a brute force scan of a path, finding all the MP3 files there
*/ */
int scan_foreground(char *path) { int scan_path(char *path) {
DIR *current_dir; DIR *current_dir;
char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* overcommit for solaris */ char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* overcommit for solaris */
struct dirent *pde; struct dirent *pde;
int err; int err;
char mp3_path[PATH_MAX]; char mp3_path[PATH_MAX];
struct stat sb; struct stat sb;
int modified_time;
if((current_dir=opendir(path)) == NULL) { if((current_dir=opendir(path)) == NULL) {
return -1; return -1;
@ -312,7 +321,7 @@ int scan_foreground(char *path) {
if(sb.st_mode & S_IFDIR) { /* dir -- recurse */ if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
DPRINTF(ERR_DEBUG,"Found dir %s... recursing\n",pde->d_name); DPRINTF(ERR_DEBUG,"Found dir %s... recursing\n",pde->d_name);
scan_foreground(mp3_path); scan_path(mp3_path);
} else { } else {
DPRINTF(ERR_DEBUG,"Processing file\n"); DPRINTF(ERR_DEBUG,"Processing file\n");
/* process the file */ /* process the file */
@ -322,7 +331,16 @@ int scan_foreground(char *path) {
scan_static_playlist(path, pde, &sb); scan_static_playlist(path, pde, &sb);
} else if (strcasestr(config.extensions, } else if (strcasestr(config.extensions,
(char*)&pde->d_name[strlen(pde->d_name) - 4])) { (char*)&pde->d_name[strlen(pde->d_name) - 4])) {
scan_music_file(path,pde,&sb);
/* only scan if it's been changed, or empty db */
modified_time=sb.st_mtime;
if((scan_mode_foreground) ||
!db_exists(sb.st_ino) ||
db_last_modified(sb.st_ino) < modified_time) {
scan_music_file(path,pde,&sb);
} else {
DPRINTF(ERR_DEBUG,"Skipping file... not modified\n");
}
} }
} }
} }
@ -471,6 +489,7 @@ int scan_get_aactags(char *file, MP3FILE *pmp3) {
char current_atom[4]; char current_atom[4];
char *current_data; char *current_data;
unsigned short us_data; unsigned short us_data;
int len;
if(!(fin=fopen(file,"rb"))) { if(!(fin=fopen(file,"rb"))) {
DPRINTF(ERR_INFO,"Cannot open file %s for reading\n",file); DPRINTF(ERR_INFO,"Cannot open file %s for reading\n",file);
@ -504,8 +523,12 @@ int scan_get_aactags(char *file, MP3FILE *pmp3) {
if(fread(current_atom,1,4,fin) != 4) if(fread(current_atom,1,4,fin) != 4)
break; break;
current_data=(char*)malloc(current_size - 7); /* extra byte */ len=current_size-7; /* for ill-formed too-short tags */
memset(current_data,0x00,current_size - 7); if(len < 22)
len=22;
current_data=(char*)malloc(len); /* extra byte */
memset(current_data,0x00,len);
if(fread(current_data,1,current_size-8,fin) != current_size-8) if(fread(current_data,1,current_size-8,fin) != current_size-8)
break; break;
@ -812,7 +835,7 @@ int scan_getfileinfo(char *file, MP3FILE *pmp3) {
if(!pmp3->song_length) /* could have gotten it from the tag */ if(!pmp3->song_length) /* could have gotten it from the tag */
pmp3->song_length=time_seconds; pmp3->song_length=time_seconds;
} else { } else {
/* should really scan forward to next sync frame */ /* FIXME: should really scan forward to next sync frame */
fclose(infile); fclose(infile);
DPRINTF(ERR_DEBUG,"Could not find sync frame\n"); DPRINTF(ERR_DEBUG,"Could not find sync frame\n");
return -1; return -1;

View File

@ -89,6 +89,9 @@
Change History (most recent first): Change History (most recent first):
$Log$ $Log$
Revision 1.16 2004/03/08 19:21:03 rpedde
start of background scanning
Revision 1.15 2004/03/02 01:35:31 rpedde Revision 1.15 2004/03/02 01:35:31 rpedde
fix domain fix domain
@ -240,15 +243,13 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
switch (status) { switch (status) {
case mStatus_NoError: case mStatus_NoError:
DPRINTF(ERR_DEBUG,"Callback: %##s Name Registered\n", DPRINTF(ERR_DEBUG,"Callback: Name Registered\n");
thisRegistration->RR_SRV.resrec.name.c);
// Do nothing; our name was successfully registered. We may // Do nothing; our name was successfully registered. We may
// get more call backs in the future. // get more call backs in the future.
break; break;
case mStatus_NameConflict: case mStatus_NameConflict:
DPRINTF(ERR_WARN,"Callback: %##s Name Conflict\n", DPRINTF(ERR_WARN,"Callback: Name Conflict\n");
thisRegistration->RR_SRV.resrec.name.c);
// In the event of a conflict, this sample RegistrationCallback // In the event of a conflict, this sample RegistrationCallback
// just calls mDNS_RenameAndReregisterService to automatically // just calls mDNS_RenameAndReregisterService to automatically
@ -266,8 +267,7 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
break; break;
case mStatus_MemFree: case mStatus_MemFree:
DPRINTF(ERR_WARN,"Callback: %##s Memory Free\n", DPRINTF(ERR_WARN,"Callback: Memory Free\n");
thisRegistration->RR_SRV.resrec.name.c);
// When debugging is enabled, make sure that thisRegistration // When debugging is enabled, make sure that thisRegistration
// is not on our gServiceList. // is not on our gServiceList.
@ -287,8 +287,7 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
break; break;
default: default:
DPRINTF(ERR_WARN,"Callback: %##s Unknown Status %d\n", DPRINTF(ERR_WARN,"Callback: Unknown Status %d\n",status);
thisRegistration->RR_SRV.resrec.name.c, status);
break; break;
} }
} }

6
src/strcasestr.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _STRCASESTR_H_
#define _STRCASESTR_H_
extern char * strcasestr(char* haystack, char* needle);
#endif