"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "monitor.c" between
minidlna-1.2.1.tar.gz and minidlna-1.3.0.tar.gz

About: ReadyMedia (formerly known as MiniDLNA) is a simple media server software, with the aim of being fully compliant with DLNA/UPnP-AV clients.

monitor.c  (minidlna-1.2.1):monitor.c  (minidlna-1.3.0)
skipping to change at line 22 skipping to change at line 22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>. * along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <libgen.h> #include <libgen.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
skipping to change at line 106 skipping to change at line 107
return ++num; return ++num;
} }
static void static void
raise_watch_limit(unsigned int limit) raise_watch_limit(unsigned int limit)
{ {
FILE *max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r+"); FILE *max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r+");
if (!max_watches) if (!max_watches)
return; return;
if (!limit) if (!limit)
fscanf(max_watches, "%u", &limit); {
if (fscanf(max_watches, "%10u", &limit) < 1)
limit = 8192;
rewind(max_watches);
}
fprintf(max_watches, "%u", next_highest(limit)); fprintf(max_watches, "%u", next_highest(limit));
fclose(max_watches); fclose(max_watches);
} }
static int int
add_watch(int fd, const char * path) add_watch(int fd, const char * path)
{ {
struct watch *nw; struct watch *nw;
int wd; int wd;
wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELETE|IN_MO VE); wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELETE|IN_MO VE);
if( wd < 0 && errno == ENOSPC) if( wd < 0 && errno == ENOSPC)
{ {
raise_watch_limit(0); raise_watch_limit(0);
wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELE TE|IN_MOVE); wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELE TE|IN_MOVE);
} }
if( wd < 0 ) if( wd < 0 )
{ {
DPRINTF(E_ERROR, L_INOTIFY, "inotify_add_watch(%s) [%s]\n", path, strerror(errno)); DPRINTF(E_ERROR, L_INOTIFY, "inotify_add_watch(%s) [%s]\n", path, strerror(errno));
return -1; return (errno);
} }
nw = malloc(sizeof(struct watch)); nw = malloc(sizeof(struct watch));
if( nw == NULL ) if( nw == NULL )
{ {
DPRINTF(E_ERROR, L_INOTIFY, "malloc() error\n"); DPRINTF(E_ERROR, L_INOTIFY, "malloc() error\n");
return -1; return (ENOMEM);
} }
nw->wd = wd; nw->wd = wd;
nw->next = NULL; nw->next = NULL;
nw->path = strdup(path); nw->path = strdup(path);
if( watches == NULL ) if( watches == NULL )
{ {
watches = nw; watches = nw;
} }
if( lastwatch != NULL ) if( lastwatch != NULL )
{ {
lastwatch->next = nw; lastwatch->next = nw;
} }
lastwatch = nw; lastwatch = nw;
return wd; DPRINTF(E_INFO, L_INOTIFY, "Added watch to %s [%d]\n", path, wd);
return (0);
} }
static int static int
remove_watch(int fd, const char * path) remove_watch(int fd, const char * path)
{ {
struct watch *w; struct watch *w;
for( w = watches; w; w = w->next ) for( w = watches; w; w = w->next )
{ {
if( strcmp(path, w->path) == 0 ) if( strcmp(path, w->path) == 0 )
skipping to change at line 342 skipping to change at line 348
{ {
char file[PATH_MAX]; char file[PATH_MAX];
strncpyt(file, path, sizeof(file)); strncpyt(file, path, sizeof(file));
strip_ext(file); strip_ext(file);
return sql_get_text_field(db, "SELECT PATH from DETAILS where (PATH > '%q .' and PATH <= '%q.z')" return sql_get_text_field(db, "SELECT PATH from DETAILS where (PATH > '%q .' and PATH <= '%q.z')"
" and MIME glob 'video/*' limit 1", file, f ile); " and MIME glob 'video/*' limit 1", file, f ile);
} }
static int int
monitor_insert_file(const char *name, const char *path) monitor_insert_file(const char *name, const char *path)
{ {
int len; int len;
char *last_dir; char *last_dir;
char *path_buf; char *path_buf;
char *base_name; char *base_name;
char *base_copy; char *base_copy;
char *parent_buf = NULL; char *parent_buf = NULL;
char *id = NULL; char *id = NULL;
char video[PATH_MAX]; char video[PATH_MAX];
skipping to change at line 473 skipping to change at line 479
if (ret == 1 && (mtype & TYPE_PLAYLIST)) if (ret == 1 && (mtype & TYPE_PLAYLIST))
{ {
next_pl_fill = time(NULL) + 120; // Schedule a playlist s can for 2 minutes from now. next_pl_fill = time(NULL) + 120; // Schedule a playlist s can for 2 minutes from now.
//DEBUG DPRINTF(E_MAXDEBUG, L_INOTIFY, "Playlist scan sc heduled for %s", ctime(&next_pl_fill)); //DEBUG DPRINTF(E_MAXDEBUG, L_INOTIFY, "Playlist scan sc heduled for %s", ctime(&next_pl_fill));
} }
sqlite3_free(id); sqlite3_free(id);
} }
return depth; return depth;
} }
static bool
check_notsparse(const char *path)
#if HAVE_DECL_SEEK_HOLE
{
int fd;
bool rv;
if ((fd = open(path, O_RDONLY)) == -1)
return (false);
if (lseek(fd, 0, SEEK_HOLE) == lseek(fd, 0, SEEK_END))
rv = true;
else
rv = false;
close(fd);
return (rv);
}
#else
{
struct stat st;
return (stat(path, &st) == 0 && (st.st_blocks << 9 >= st.st_size));
}
#endif
int int
monitor_insert_directory(int fd, char *name, const char * path) monitor_insert_directory(int fd, char *name, const char * path)
{ {
DIR * ds; DIR * ds;
struct dirent * e; struct dirent * e;
char *id, *parent_buf, *esc_name; char *id, *parent_buf, *esc_name;
char path_buf[PATH_MAX]; char path_buf[PATH_MAX];
enum file_types type = TYPE_UNKNOWN; enum file_types type = TYPE_UNKNOWN;
media_types dir_types; media_types dir_types;
struct stat st;
if( access(path, R_OK|X_OK) != 0 ) if( access(path, R_OK|X_OK) != 0 )
{ {
DPRINTF(E_WARN, L_INOTIFY, "Could not access %s [%s]\n", path, st rerror(errno)); DPRINTF(E_WARN, L_INOTIFY, "Could not access %s [%s]\n", path, st rerror(errno));
return -1; return -1;
} }
if( sql_get_int_field(db, "SELECT ID from DETAILS where PATH = '%q'", pat h) > 0 ) if( sql_get_int_field(db, "SELECT ID from DETAILS where PATH = '%q'", pat h) > 0 )
{ {
fd = 0; fd = 0;
if (!GETFLAG(RESCAN_MASK)) if (!GETFLAG(RESCAN_MASK))
skipping to change at line 507 skipping to change at line 536
parent_buf = strdup(path); parent_buf = strdup(path);
id = sql_get_text_field(db, "SELECT OBJECT_ID from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)" id = sql_get_text_field(db, "SELECT OBJECT_ID from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)"
" WHERE d.PATH = '%q' and REF_ID is N ULL", dirname(parent_buf)); " WHERE d.PATH = '%q' and REF_ID is N ULL", dirname(parent_buf));
if( !id ) if( !id )
id = sqlite3_mprintf("%s", BROWSEDIR_ID); id = sqlite3_mprintf("%s", BROWSEDIR_ID);
insert_directory(name, path, BROWSEDIR_ID, id+2, get_next_availab le_id("OBJECTS", id)); insert_directory(name, path, BROWSEDIR_ID, id+2, get_next_availab le_id("OBJECTS", id));
sqlite3_free(id); sqlite3_free(id);
free(parent_buf); free(parent_buf);
} }
#ifdef HAVE_WATCH
if( fd > 0 ) if( fd > 0 )
{ add_watch(fd, path);
#ifdef HAVE_INOTIFY #endif
int wd = add_watch(fd, path);
if( wd == -1 )
{
DPRINTF(E_ERROR, L_INOTIFY, "add_watch() failed\n");
}
else
{
DPRINTF(E_INFO, L_INOTIFY, "Added watch to %s [%d]\n", pa
th, wd);
}
#endif
}
dir_types = valid_media_types(path); dir_types = valid_media_types(path);
ds = opendir(path); ds = opendir(path);
if( !ds ) if( !ds )
{ {
DPRINTF(E_ERROR, L_INOTIFY, "opendir failed! [%s]\n", strerror(er rno)); DPRINTF(E_ERROR, L_INOTIFY, "opendir failed! [%s]\n", strerror(er rno));
return -1; return -1;
} }
while( (e = readdir(ds)) ) while( !quitting && (e = readdir(ds)) )
{ {
if( e->d_name[0] == '.' ) if( e->d_name[0] == '.' )
continue; continue;
esc_name = escape_tag(e->d_name, 1); esc_name = escape_tag(e->d_name, 1);
snprintf(path_buf, sizeof(path_buf), "%s/%s", path, e->d_name); snprintf(path_buf, sizeof(path_buf), "%s/%s", path, e->d_name);
switch( e->d_type ) switch( e->d_type )
{ {
case DT_DIR: case DT_DIR:
case DT_REG: case DT_REG:
case DT_LNK: case DT_LNK:
case DT_UNKNOWN: case DT_UNKNOWN:
type = resolve_unknown_type(path_buf, dir_types); type = resolve_unknown_type(path_buf, dir_types);
default: default:
break; break;
} }
if( type == TYPE_DIR ) if( type == TYPE_DIR )
{ {
monitor_insert_directory(fd, esc_name, path_buf); monitor_insert_directory(fd, esc_name, path_buf);
} }
else if( type == TYPE_FILE ) else if( type == TYPE_FILE && check_notsparse(path_buf)) {
{ monitor_insert_file(esc_name, path_buf);
if( (stat(path_buf, &st) == 0) && (st.st_blocks<<9 >= st.
st_size) )
{
monitor_insert_file(esc_name, path_buf);
}
} }
free(esc_name); free(esc_name);
} }
closedir(ds); closedir(ds);
return 0; return 0;
} }
int int
monitor_remove_directory(int fd, const char * path) monitor_remove_directory(int fd, const char * path)
{ {
char * sql; char * sql;
char **result; char **result;
int64_t detailID = 0; int64_t detailID = 0;
int rows, i, ret = 1; int rows, i, ret = 1;
/* Invalidate the scanner cache so we don't insert files into non-existen t containers */ /* Invalidate the scanner cache so we don't insert files into non-existen t containers */
valid_cache = 0; valid_cache = 0;
#ifdef HAVE_INOTIFY
if( fd > 0 ) if( fd > 0 )
{ {
#ifdef HAVE_INOTIFY
remove_watch(fd, path); remove_watch(fd, path);
#endif
} }
#endif
sql = sqlite3_mprintf("SELECT ID from DETAILS where (PATH > '%q/' and PAT H <= '%q/%c')" sql = sqlite3_mprintf("SELECT ID from DETAILS where (PATH > '%q/' and PAT H <= '%q/%c')"
" or PATH = '%q'", path, path, 0xFF, path); " or PATH = '%q'", path, path, 0xFF, path);
if( (sql_get_table(db, sql, &result, &rows, NULL) == SQLITE_OK) ) if( (sql_get_table(db, sql, &result, &rows, NULL) == SQLITE_OK) )
{ {
if( rows ) if( rows )
{ {
for( i=1; i <= rows; i++ ) for( i=1; i <= rows; i++ )
{ {
detailID = strtoll(result[i], NULL, 10); detailID = strtoll(result[i], NULL, 10);
sql_exec(db, "DELETE from DETAILS where ID = %lld ", detailID); sql_exec(db, "DELETE from DETAILS where ID = %lld ", detailID);
skipping to change at line 635 skipping to change at line 650
while( GETFLAG(SCANNING_MASK) ) while( GETFLAG(SCANNING_MASK) )
{ {
if( quitting ) if( quitting )
goto quitting; goto quitting;
sleep(1); sleep(1);
} }
inotify_create_watches(pollfds[0].fd); inotify_create_watches(pollfds[0].fd);
if (setpriority(PRIO_PROCESS, 0, 19) == -1) if (setpriority(PRIO_PROCESS, 0, 19) == -1)
DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread prio rity\n"); DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread prio rity\n");
sqlite3_release_memory(1<<31); sqlite3_release_memory(1<<31);
av_register_all(); lav_register_all();
while( !quitting ) while( !quitting )
{ {
int timeout = -1; int timeout = -1;
if (next_pl_fill) if (next_pl_fill)
{ {
time_t diff = next_pl_fill - time(NULL); time_t diff = next_pl_fill - time(NULL);
if (diff < 0) if (diff < 0)
timeout = 0; timeout = 0;
else else
skipping to change at line 672 skipping to change at line 687
else else
DPRINTF(E_ERROR, L_INOTIFY, "read failed!\n"); DPRINTF(E_ERROR, L_INOTIFY, "read failed!\n");
} }
else else
{ {
length = read(pollfds[0].fd, buffer, BUF_LEN); length = read(pollfds[0].fd, buffer, BUF_LEN);
buffer[BUF_LEN-1] = '\0'; buffer[BUF_LEN-1] = '\0';
} }
i = 0; i = 0;
while( i < length ) while( !quitting && i < length )
{ {
struct inotify_event * event = (struct inotify_event *) & buffer[i]; struct inotify_event * event = (struct inotify_event *) & buffer[i];
if( event->len ) if( event->len )
{ {
if( *(event->name) == '.' ) if( *(event->name) == '.' )
{ {
i += EVENT_SIZE + event->len; i += EVENT_SIZE + event->len;
continue; continue;
} }
esc_name = modifyString(strdup(event->name), "&", "&amp;amp;", 0); esc_name = modifyString(strdup(event->name), "&", "&amp;amp;", 0);
 End of changes. 19 change blocks. 
33 lines changed or deleted 46 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)