(trunk daemon) #2149: daemon's non-inotify watchdir fails on .torrents with old timestamps

This commit is contained in:
Charles Kerr 2009-06-05 17:02:29 +00:00
parent 3cbacf4202
commit bd0a4ab5bb
1 changed files with 38 additions and 10 deletions

View File

@ -9,7 +9,6 @@
*
* $Id:$
*/
#ifdef WITH_INOTIFY
#include <sys/inotify.h>
#include <sys/select.h>
@ -18,13 +17,14 @@
#include <sys/types.h> /* stat */
#include <sys/stat.h> /* stat */
#include <dirent.h> /* readdir */
#include <event.h> /* evbuffer */
#endif
#include <errno.h>
#include <string.h> /* strstr */
#include <libtransmission/transmission.h>
#include <libtransmission/utils.h> /* tr_buildPath */
#include <libtransmission/utils.h> /* tr_buildPath(), tr_inf() */
#include "watch.h"
struct dtr_watchdir
@ -36,6 +36,7 @@ struct dtr_watchdir
int inotify_fd;
#else /* readdir implementation */
time_t lastTimeChecked;
struct evbuffer * lastFiles;
#endif
};
@ -98,6 +99,7 @@ watchdir_update_impl( dtr_watchdir * w )
int len = read( fd, buf, sizeof( buf ) );
while (i < len) {
struct inotify_event * event = (struct inotify_event *) &buf[i];
tr_inf( "Found new .torrent file \"%s\" in watchdir \"%s\"", event->name, w->dir );
w->callback( w->session, w->dir, event->name );
i += EVENT_SIZE + event->len;
}
@ -112,15 +114,36 @@ watchdir_update_impl( dtr_watchdir * w )
#define WATCHDIR_POLL_INTERVAL_SECS 10
#define FILE_DELIMITER '\0'
static void
watchdir_new_impl( dtr_watchdir * w UNUSED )
{
tr_inf( "Using readdir to watch directory \"%s\"", w->dir );
w->lastFiles = evbuffer_new( );
}
static void
watchdir_free_impl( dtr_watchdir * w UNUSED )
watchdir_free_impl( dtr_watchdir * w )
{
/* NOOP */
evbuffer_free( w->lastFiles );
}
static void
add_file_to_list( struct evbuffer * buf, const char * filename, size_t len )
{
const char delimiter = FILE_DELIMITER;
evbuffer_add( buf, &delimiter, 1 );
evbuffer_add( buf, filename, len );
evbuffer_add( buf, &delimiter, 1 );
}
static tr_bool
is_file_in_list( struct evbuffer * buf, const char * filename, size_t len )
{
tr_bool in_list;
struct evbuffer * test = evbuffer_new( );
add_file_to_list( test, filename, len );
in_list = evbuffer_find( buf, EVBUFFER_DATA( test ), EVBUFFER_LENGTH( test ) );
evbuffer_free( test );
return in_list;
}
static void
watchdir_update_impl( dtr_watchdir * w )
@ -129,6 +152,7 @@ watchdir_update_impl( dtr_watchdir * w )
DIR * odir;
const time_t oldTime = w->lastTimeChecked;
const char * dirname = w->dir;
struct evbuffer * curFiles = evbuffer_new( );
if ( ( oldTime + WATCHDIR_POLL_INTERVAL_SECS < time( NULL ) )
&& !stat( dirname, &sb )
@ -139,23 +163,27 @@ watchdir_update_impl( dtr_watchdir * w )
for( d = readdir( odir ); d != NULL; d = readdir( odir ) )
{
char * filename;
size_t len;
if( !d->d_name || *d->d_name=='.' ) /* skip dotfiles */
continue;
if( !strstr( d->d_name, ".torrent" ) ) /* skip non-torrents */
continue;
/* if the file's changed since our last pass, try adding it */
filename = tr_buildPath( dirname, d->d_name, NULL );
if( !stat( filename, &sb ) && sb.st_mtime >= oldTime )
len = strlen( d->d_name );
add_file_to_list( curFiles, d->d_name, len );
/* if this file wasn't here last time, try adding it */
if( !is_file_in_list( w->lastFiles, d->d_name, len ) ) {
tr_inf( "Found new .torrent file \"%s\" in watchdir \"%s\"", d->d_name, w->dir );
w->callback( w->session, w->dir, d->d_name );
tr_free( filename );
}
}
closedir( odir );
w->lastTimeChecked = time( NULL );
evbuffer_free( w->lastFiles );
w->lastFiles = curFiles;
}
}