On Mon, Jan 19, 2015 at 05:13:09PM +0100, David Coppa wrote:
> On Mon, Jan 19, 2015 at 12:06 AM, LÉVAI Dániel <l...@ecentrum.hu> wrote:
> 
> >> It might be better to look at the kqueue patch that FreeBSD are using.
> >
> > Now this seems to work for me on i386, at least. It applied almost
> > clean, but I've taken the liberty and removed the whitespace-only
> > changes from FreeBSD's diff(s). I'll be honest, it got a bit slower, but
> > this could very well be because of my rusty hard drives.
> >
> > Here is my diff:
> 
> I do not use MiniDLNA, but your diff below looks good and, if it
> works, then it's ok with me if Stuart wants to commit it.

There seems to be a missing bdep on the autostuffs.

> 
> ciao,
> David
> 
> >
> > Index: Makefile
> > ===================================================================
> > RCS file: /cvs/ports/multimedia/minidlna/Makefile,v
> > retrieving revision 1.10
> > diff -p -u -r1.10 Makefile
> > --- Makefile    3 Sep 2014 21:15:43 -0000       1.10
> > +++ Makefile    18 Jan 2015 22:45:10 -0000
> > @@ -3,6 +3,7 @@
> >  COMMENT=       lightweight DLNA/UPnP-AV media server
> >
> >  V=             1.1.4
> > +REVISION=      0
> >  DISTNAME=      minidlna-$V
> >  PKGNAME=       minidlna-$V
> >
> > @@ -34,9 +35,15 @@ LIB_DEPENDS= audio/flac \
> >                 graphics/jpeg \
> >                 graphics/libexif
> >
> > +AUTOCONF_VERSION= 2.69
> > +AUTOMAKE_VERSION= 1.14
> > +
> >  NO_TEST=       Yes
> >  E=             ${PREFIX}/share/examples/minidlna
> >
> > +post-patch:
> > +       @cd ${WRKSRC} && env AUTOCONF_VERSION=${AUTOCONF_VERSION} \
> > +           AUTOMAKE_VERSION=${AUTOMAKE_VERSION} ./autogen.sh
> >  post-install:
> >         ${INSTALL_DATA_DIR} $E
> >         ${INSTALL_DATA} ${WRKSRC}/minidlna.conf $E
> > Index: patches/patch-configure_ac
> > ===================================================================
> > RCS file: patches/patch-configure_ac
> > diff -N patches/patch-configure_ac
> > --- /dev/null   1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-configure_ac  18 Jan 2015 22:45:10 -0000
> > @@ -0,0 +1,12 @@
> > +$OpenBSD$
> > +--- configure.ac.orig  Tue Aug 26 23:09:22 2014
> > ++++ configure.ac       Sun Jan 18 22:45:07 2015
> > +@@ -481,7 +481,7 @@ AC_CHECK_LIB(vorbisfile, vorbis_comment_query,
> > + 
> > ################################################################################################################
> > + ### Header checks
> > +
> > +-AC_CHECK_HEADERS([arpa/inet.h asm/unistd.h endian.h machine/endian.h 
> > fcntl.h libintl.h locale.h netdb.h netinet/in.h stddef.h stdlib.h string.h 
> > sys/file.h sys/inotify.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h 
> > unistd.h])
> > ++AC_CHECK_HEADERS([arpa/inet.h asm/unistd.h endian.h machine/endian.h 
> > fcntl.h libintl.h locale.h netdb.h netinet/in.h stddef.h stdlib.h string.h 
> > sys/file.h sys/inotify.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h 
> > unistd.h sys/event.h])
> > +
> > + AC_CHECK_FUNCS(inotify_init, AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has 
> > inotify support]), [
> > +     AC_MSG_CHECKING([for __NR_inotify_init syscall])
> > Index: patches/patch-inotify_c
> > ===================================================================
> > RCS file: patches/patch-inotify_c
> > diff -N patches/patch-inotify_c
> > --- /dev/null   1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-inotify_c     18 Jan 2015 22:45:10 -0000
> > @@ -0,0 +1,569 @@
> > +$OpenBSD$
> > +--- inotify.c.orig     Sun Jan 18 22:45:24 2015
> > ++++ inotify.c  Sun Jan 18 22:45:27 2015
> > +@@ -15,9 +15,9 @@
> > +  * You should have received a copy of the GNU General Public License
> > +  * along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
> > +  */
> > + #include "config.h"
> > +
> > +-#ifdef HAVE_INOTIFY
> > ++#if defined(HAVE_INOTIFY) || defined(HAVE_SYS_EVENT_H)
> > + #include <stdio.h>
> > + #include <string.h>
> > + #include <stdlib.h>
> > +@@ -31,11 +31,16 @@
> > + #include <sys/time.h>
> > + #include <sys/resource.h>
> > + #include <poll.h>
> > ++#ifdef HAVE_INOTIFY
> > + #ifdef HAVE_SYS_INOTIFY_H
> > + #include <sys/inotify.h>
> > +-#else
> > ++#else /*HAVE_SYS_INOTIFY_H*/
> > + #include "linux/inotify.h"
> > + #include "linux/inotify-syscalls.h"
> > ++#endif /*HAVE_SYS_INOTIFY_H*/
> > ++#else
> > ++#include <sys/event.h>
> > ++#include <fcntl.h>
> > + #endif
> > + #include "libav.h"
> > +
> > +@@ -49,11 +54,13 @@
> > + #include "playlist.h"
> > + #include "log.h"
> > +
> > ++#ifdef HAVE_INOTIFY
> > + #define EVENT_SIZE  ( sizeof (struct inotify_event) )
> > + #define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )
> > + #define DESIRED_WATCH_LIMIT 65536
> > +
> > + #define PATH_BUF_SIZE PATH_MAX
> > ++#endif
> > +
> > + struct watch
> > + {
> > +@@ -86,13 +93,35 @@ add_watch(int fd, const char * path)
> > +       struct watch *nw;
> > +       int wd;
> > +
> > ++#ifdef HAVE_INOTIFY
> > +       wd = inotify_add_watch(fd, path, 
> > IN_CREATE|IN_CLOSE_WRITE|IN_DELETE|IN_MOVE);
> > +       if( wd < 0 )
> > +       {
> > +               DPRINTF(E_ERROR, L_INOTIFY, "inotify_add_watch(%s) [%s]\n", 
> > path, strerror(errno));
> > +               return -1;
> > +       }
> > ++#else /*HAVE_INOTIFY*/
> > ++      wd = open(path, O_RDONLY);
> > ++      if (wd == -1)
> > ++      {
> > ++              DPRINTF(E_ERROR, L_INOTIFY, 
> > "inotify_add_watch[kqueue,open](%s) [%s]\n", path, strerror(errno));
> > ++              return -1;
> > ++      }
> > +
> > ++      struct kevent ke;
> > ++      EV_SET(&ke, wd,
> > ++              EVFILT_VNODE,
> > ++              EV_ADD | EV_ENABLE | EV_CLEAR,
> > ++              NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND /*| NOTE_ATTRB*/,
> > ++              0, NULL);
> > ++
> > ++      if( kevent(fd, &ke, 1, NULL, 0, NULL) == -1 )
> > ++      {
> > ++              DPRINTF(E_ERROR, L_INOTIFY, "inotify_add_watch[kqueue](%s) 
> > [%s]\n", path, strerror(errno));
> > ++              return -1;
> > ++      }
> > ++#endif
> > ++
> > +       nw = malloc(sizeof(struct watch));
> > +       if( nw == NULL )
> > +       {
> > +@@ -125,7 +154,12 @@ remove_watch(int fd, const char * path)
> > +       for( w = watches; w; w = w->next )
> > +       {
> > +               if( strcmp(path, w->path) == 0 )
> > ++#ifdef HAVE_INOTIFY
> > +                       return(inotify_rm_watch(fd, w->wd));
> > ++#else
> > ++                      close(w->wd); /* kqueue cleans up events when 
> > handle dies*/
> > ++                      return(0);
> > ++#endif
> > +       }
> > +
> > +       return 1;
> > +@@ -145,15 +179,14 @@ next_highest(unsigned int num)
> > + int
> > + inotify_create_watches(int fd)
> > + {
> > +-      FILE * max_watches;
> > +-      unsigned int num_watches = 0, watch_limit;
> > ++      unsigned int num_watches = 0;
> > +       char **result;
> > +       int i, rows = 0;
> > +       struct media_dir_s * media_path;
> > +
> > +       for( media_path = media_dirs; media_path != NULL; media_path = 
> > media_path->next )
> > +       {
> > +-              DPRINTF(E_DEBUG, L_INOTIFY, "Add watch to %s\n", 
> > media_path->path);
> > ++              DPRINTF(E_DEBUG, L_INOTIFY, "Setting up monitoring on 
> > %s\n", media_path->path);
> > +               add_watch(fd, media_path->path);
> > +               num_watches++;
> > +       }
> > +@@ -165,7 +198,11 @@ inotify_create_watches(int fd)
> > +               num_watches++;
> > +       }
> > +       sqlite3_free_table(result);
> > +
> > ++#ifdef HAVE_INOTIFY
> > ++      FILE * max_watches;
> > ++      unsigned int watch_limit;
> > ++
> > +       max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r");
> > +       if( max_watches )
> > +       {
> > +@@ -194,16 +231,17 @@ inotify_create_watches(int fd)
> > +                       else
> > +                       {
> > +                               DPRINTF(E_WARN, L_INOTIFY, "WARNING: 
> > Inotify max_user_watches [%u] is low or close to the number of used watches 
> > [%u] "
> > +                                                       "and I do not have 
> > permission to increase this limit.  Please do so manually by "
> > +                                                       "writing a higher 
> > value into /proc/sys/fs/inotify/max_user_watches.\n", watch_limit, 
> > num_watches);
> > +                       }
> > +               }
> > +       }
> > +       else
> > +       {
> > +               DPRINTF(E_WARN, L_INOTIFY, "WARNING: Could not read inotify 
> > max_user_watches!  "
> > +                                       "Hopefully it is enough to cover %u 
> > current directories plus any new ones added.\n", num_watches);
> > +       }
> > ++#endif
> > +
> > +       return rows;
> > + }
> > +@@ -218,7 +256,11 @@ inotify_remove_watches(int fd)
> > +       while( w )
> > +       {
> > +               last_w = w;
> > ++#ifdef HAVE_INOTIFY
> > +               inotify_rm_watch(fd, w->wd);
> > ++#else
> > ++              close(w->wd); /*kqueue cleans up after fhandle dies*/
> > ++#endif
> > +               free(w->path);
> > +               rm_watches++;
> > +               w = w->next;
> > +@@ -261,10 +303,10 @@ int add_dir_watch(int fd, char * path, char * 
> > filename
> > +               while( (e = readdir(ds)) )
> > +               {
> > +                       if( strcmp(e->d_name, ".") == 0 ||
> > +                           strcmp(e->d_name, "..") == 0 )
> > +                               continue;
> > +                       if( (e->d_type == DT_DIR) ||
> > +                           (e->d_type == DT_UNKNOWN && 
> > resolve_unknown_type(dir, NO_MEDIA) == TYPE_DIR) )
> > +                               i += add_dir_watch(fd, dir, e->d_name);
> > +               }
> > +       }
> > +@@ -293,7 +335,10 @@ inotify_insert_file(char * name, const char * path)
> > +       media_types types = ALL_MEDIA;
> > +       struct media_dir_s * media_path = media_dirs;
> > +       struct stat st;
> > ++      struct timeval now;
> > +
> > ++      DPRINTF(E_DEBUG, L_INOTIFY, "inotify_insert_file: %s @ %s\n", name, 
> > path);
> > ++
> > +       /* Is it cover art for another file? */
> > +       if( is_image(path) )
> > +               update_if_album_art(path);
> > +@@ -357,6 +402,16 @@ inotify_insert_file(char * name, const char * path)
> > +       if( stat(path, &st) != 0 )
> > +               return -1;
> > +
> > ++      (void)gettimeofday(&now, NULL);
> > ++      while (now.tv_sec < st.st_mtime + 3)
> > ++      {
> > ++              DPRINTF(E_DEBUG, L_INOTIFY, "Sleeping until %s is stable 
> > for a few seconds ...\n", path);
> > ++              sleep(1);
> > ++              (void)gettimeofday(&now, NULL);
> > ++              if (stat(path, &st) != 0)
> > ++                      return -1;
> > ++      }
> > ++
> > +       ts = sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where 
> > PATH = '%q'", path);
> > +       if( !ts && is_playlist(path) && (sql_get_int_field(db, "SELECT ID 
> > from PLAYLISTS where PATH = '%q'", path) > 0) )
> > +       {
> > +@@ -386,9 +441,9 @@ inotify_insert_file(char * name, const char * path)
> > +
> > +               do
> > +               {
> > +-                      //DEBUG DPRINTF(E_DEBUG, L_INOTIFY, "Checking 
> > %s\n", parent_buf);
> > ++                      /*DEBUG DPRINTF(E_DEBUG, L_INOTIFY, "Checking 
> > %s\n", parent_buf);*/
> > +                       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 NULL", parent_buf);
> > +                       if( id )
> > +                       {
> > +                               if( !depth )
> > +@@ -446,6 +501,8 @@ inotify_insert_directory(int fd, char *name, const cha
> > +       struct media_dir_s* media_path;
> > +       struct stat st;
> > +
> > ++      DPRINTF(E_DEBUG, L_INOTIFY, "inotify_insert_directory: %s @ %s\n", 
> > name, path);
> > ++
> > +       if( access(path, R_OK|X_OK) != 0 )
> > +       {
> > +               DPRINTF(E_WARN, L_INOTIFY, "Could not access %s [%s]\n", 
> > path, strerror(errno));
> > +@@ -459,7 +516,7 @@ inotify_insert_directory(int fd, char *name, const cha
> > +
> > +       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)"
> > +                                   " where d.PATH = '%q' and REF_ID is 
> > NULL", dirname(parent_buf));
> > +       if( !id )
> > +               id = sqlite3_mprintf("%s", BROWSEDIR_ID);
> > +       insert_directory(name, path, BROWSEDIR_ID, id+2, 
> > get_next_available_id("OBJECTS", id));
> > +@@ -554,27 +611,25 @@ inotify_remove_file(const char * path)
> > +       {
> > +               sql_exec(db, "DELETE from PLAYLISTS where ID = %lld", 
> > detailID);
> > +               sql_exec(db, "DELETE from DETAILS where ID ="
> > +                            " (SELECT DETAIL_ID from OBJECTS where 
> > OBJECT_ID = '%s$%llX')",
> > +                        MUSIC_PLIST_ID, detailID);
> > +               sql_exec(db, "DELETE from OBJECTS where OBJECT_ID = 
> > '%s$%llX' or PARENT_ID = '%s$%llX'",
> > +                        MUSIC_PLIST_ID, detailID, MUSIC_PLIST_ID, 
> > detailID);
> > +       }
> > +       else
> > +       {
> > +               /* Delete the parent containers if we are about to empty 
> > them. */
> > +-              snprintf(sql, sizeof(sql), "SELECT PARENT_ID from OBJECTS 
> > where DETAIL_ID = %lld"
> > +-                                         " and PARENT_ID not like 
> > '64$%%'",
> > +-                                         (long long int)detailID);
> > ++              snprintf(sql, sizeof(sql), "SELECT PARENT_ID from OBJECTS 
> > where DETAIL_ID = %lld", (long long int)detailID);
> > +               if( (sql_get_table(db, sql, &result, &rows, NULL) == 
> > SQLITE_OK) )
> > +               {
> > +                       int i, children;
> > +                       for( i = 1; i <= rows; i++ )
> > +                       {
> > +                               /* If it's a playlist item, adjust the item 
> > count of the playlist */
> > +                               if( strncmp(result[i], MUSIC_PLIST_ID, 
> > strlen(MUSIC_PLIST_ID)) == 0 )
> > +                               {
> > +                                       sql_exec(db, "UPDATE PLAYLISTS set 
> > FOUND = (FOUND-1) where ID = %d",
> > +                                                atoi(strrchr(result[i], 
> > '$') + 1));
> > +                               }
> > +
> > +                               children = sql_get_int_field(db, "SELECT 
> > count(*) from OBJECTS where PARENT_ID = '%s'", result[i]);
> > +@@ -582,6 +637,8 @@ inotify_remove_file(const char * path)
> > +                                       continue;
> > +                               if( children < 2 )
> > +                               {
> > ++                                      sql_exec(db, "DELETE from DETAILS 
> > where ID ="
> > ++                                                                          
> >              " (SELECT DETAIL_ID from OBJECTS where OBJECT_ID = '%s')", 
> > result[i]);
> > +                                       sql_exec(db, "DELETE from OBJECTS 
> > where OBJECT_ID = '%s'", result[i]);
> > +
> > +                                       ptr = strrchr(result[i], '$');
> > +@@ -589,6 +646,8 @@ inotify_remove_file(const char * path)
> > +                                               *ptr = '\0';
> > +                                       if( sql_get_int_field(db, "SELECT 
> > count(*) from OBJECTS where PARENT_ID = '%s'", result[i]) == 0 )
> > +                                       {
> > ++                                              sql_exec(db, "DELETE from 
> > DETAILS where ID ="
> > ++                                                                          
> >                      " (SELECT DETAIL_ID from OBJECTS where OBJECT_ID = 
> > '%s')", result[i]);
> > +                                               sql_exec(db, "DELETE from 
> > OBJECTS where OBJECT_ID = '%s'", result[i]);
> > +                                       }
> > +                               }
> > +@@ -613,11 +672,13 @@ inotify_remove_directory(int fd, const char * path)
> > +       int64_t detailID = 0;
> > +       int rows, i, ret = 1;
> > +
> > ++      DPRINTF(E_DEBUG, L_INOTIFY, "inotify_remove_directory: %s\n", path);
> > ++
> > +       /* Invalidate the scanner cache so we don't insert files into 
> > non-existent containers */
> > +       valid_cache = 0;
> > +       remove_watch(fd, path);
> > +       sql = sqlite3_mprintf("SELECT ID from DETAILS where (PATH > '%q/' 
> > and PATH <= '%q/%c')"
> > +                             " or PATH = '%q'", path, path, 0xFF, path);
> > +       if( (sql_get_table(db, sql, &result, &rows, NULL) == SQLITE_OK) )
> > +       {
> > +               if( rows )
> > +@@ -639,6 +700,7 @@ inotify_remove_directory(int fd, const char * path)
> > +       return ret;
> > + }
> > +
> > ++#ifdef HAVE_INOTIFY
> > + void *
> > + start_inotify()
> > + {
> > +@@ -649,7 +711,7 @@ start_inotify()
> > +       int length, i = 0;
> > +       char * esc_name = NULL;
> > +       struct stat st;
> > +
> > +       pollfds[0].fd = inotify_init();
> > +       pollfds[0].events = POLLIN;
> > +
> > +@@ -664,13 +726,13 @@ start_inotify()
> > +       }
> > +       inotify_create_watches(pollfds[0].fd);
> > +       if (setpriority(PRIO_PROCESS, 0, 19) == -1)
> > +               DPRINTF(E_WARN, L_INOTIFY,  "Failed to reduce inotify 
> > thread priority\n");
> > +       sqlite3_release_memory(1<<31);
> > +       av_register_all();
> > +
> > +       while( !quitting )
> > +       {
> > +                 length = poll(pollfds, 1, timeout);
> > +               if( !length )
> > +               {
> > +                       if( next_pl_fill && (time(NULL) >= next_pl_fill) )
> > +@@ -708,12 +770,12 @@ start_inotify()
> > +                               snprintf(path_buf, sizeof(path_buf), 
> > "%s/%s", get_path_from_wd(event->wd), event->name);
> > +                               if ( event->mask & IN_ISDIR && (event->mask 
> > & (IN_CREATE|IN_MOVED_TO)) )
> > +                               {
> > +                                       DPRINTF(E_DEBUG, L_INOTIFY,  "The 
> > directory %s was %s.\n",
> > +                                               path_buf, (event->mask & 
> > IN_MOVED_TO ? "moved here" : "created"));
> > +                                       
> > inotify_insert_directory(pollfds[0].fd, esc_name, path_buf);
> > +                               }
> > +                               else if ( (event->mask & 
> > (IN_CLOSE_WRITE|IN_MOVED_TO|IN_CREATE)) &&
> > +                                         (lstat(path_buf, &st) == 0) )
> > +                               {
> > +                                       if( S_ISLNK(st.st_mode) )
> > +                                       {
> > +@@ -727,7 +789,7 @@ start_inotify()
> > +                                       else if( event->mask & 
> > (IN_CLOSE_WRITE|IN_MOVED_TO) && st.st_size > 0 )
> > +                                       {
> > +                                               if( (event->mask & 
> > IN_MOVED_TO) ||
> > +                                                   (sql_get_int_field(db, 
> > "SELECT TIMESTAMP from DETAILS where PATH = '%q'", path_buf) != 
> > st.st_mtime) )
> > +                                               {
> > +                                                       DPRINTF(E_DEBUG, 
> > L_INOTIFY, "The file %s was %s.\n",
> > +                                                               path_buf, 
> > (event->mask & IN_MOVED_TO ? "moved here" : "changed"));
> > +@@ -756,4 +818,234 @@ quitting:
> > +
> > +       return 0;
> > + }
> > ++#else
> > ++void *
> > ++start_kqueue()
> > ++{
> > ++      int global_kqueue_handle = -1;
> > ++
> > ++      global_kqueue_handle = kqueue();
> > ++      if ( global_kqueue_handle < 0 )
> > ++      {
> > ++              DPRINTF(E_ERROR, L_INOTIFY, "kqueue() failed: %s\n", 
> > strerror(errno));
> > ++              return 0;
> > ++      }
> > ++
> > ++      while( scanning )
> > ++      {
> > ++              if( quitting )
> > ++                      goto quitting;
> > ++
> > ++              DPRINTF(E_DEBUG, L_INOTIFY, "..waiting for scanning to 
> > complete...\n");
> > ++              sleep(1);
> > ++      }
> > ++
> > ++      DPRINTF(E_DEBUG, L_INOTIFY, "GOING WILD!\n");
> > ++
> > ++      inotify_create_watches(global_kqueue_handle);
> > ++      if (setpriority(PRIO_PROCESS, 0, 19) == -1)
> > ++              DPRINTF(E_WARN, L_INOTIFY,      "Failed to reduce kqueue 
> > thread priority\n");
> > ++      sqlite3_release_memory(1<<31);
> > ++      av_register_all();
> > ++
> > ++      while( !quitting )
> > ++      {
> > ++              struct kevent ke;
> > ++              if ( kevent(global_kqueue_handle, NULL, 0, &ke, 1, NULL) == 
> > -1 )
> > ++              {
> > ++                      DPRINTF(E_WARN, L_INOTIFY,      "kevent polling 
> > failure: %s\n", strerror(errno));
> > ++                      continue;
> > ++              }
> > ++
> > ++              /*DPRINTF(E_DEBUG, L_INOTIFY,   "GOT KEVENT:\n"
> > ++                      "ident=0x%X, filter=0x%X, flags=0x%X, fflags=0x%X, 
> > data=0x%X, udata=0x%X\n",
> > ++                      ke.ident, ke.filter, ke.flags, ke.fflags, ke.data, 
> > ke.udata);*/
> > ++
> > ++              char* dir_path = get_path_from_wd(ke.ident);
> > ++              if (dir_path == NULL)
> > ++              {
> > ++                      DPRINTF(E_ERROR, L_INOTIFY, "Path with FD=0x%X 
> > can't be resolved.\n", ke.ident);
> > ++                      continue;
> > ++              }
> > ++
> > ++              if (ke.fflags & NOTE_DELETE)
> > ++              {
> > ++                      DPRINTF(E_DEBUG, L_INOTIFY, "Path [%s] deleted.\n", 
> > dir_path);
> > ++                      inotify_remove_directory(ke.ident, dir_path);
> > ++              }
> > ++              else if ((ke.fflags & (NOTE_WRITE | NOTE_LINK)) == 
> > (NOTE_WRITE | NOTE_LINK))
> > ++              {
> > ++                      DPRINTF(E_DEBUG, L_INOTIFY, "Path [%s] content 
> > updated (directory).\n", dir_path);
> > ++
> > ++                      char * sql;
> > ++                      char **result;
> > ++                      int i, rows;
> > ++                      sql = sqlite3_mprintf("SELECT PATH from DETAILS 
> > where (PATH > '%q/' and PATH <= '%q/%c')"
> > ++                              " and SIZE = ''", dir_path, dir_path, 0xFF);
> > ++                      if( (sql_get_table(db, sql, &result, &rows, NULL) 
> > != SQLITE_OK) )
> > ++                      {
> > ++                              DPRINTF(E_WARN, L_INOTIFY, "Read state 
> > [%s]: Query failed, not updating\n", dir_path);
> > ++                              sqlite3_free(sql);
> > ++                              continue;
> > ++                      }
> > ++
> > ++                      for( i=1; i <= rows; i++ )
> > ++                      {
> > ++                              DPRINTF(E_DEBUG, L_INOTIFY, "Indexed 
> > content: %s\n", result[i]);
> > ++                              if (access(result[i], R_OK) == -1)
> > ++                              {
> > ++                                      /* actually, global_kqueue_handle 
> > is not used here */
> > ++                                      
> > inotify_remove_directory(global_kqueue_handle, result[i]);
> > ++                              }
> > ++                      }
> > ++
> > ++                      DIR* d;
> > ++                      struct dirent * entry;
> > ++                      d = opendir(dir_path);
> > ++                      if (!d)
> > ++                      {
> > ++                              DPRINTF(E_ERROR, L_INOTIFY, "Can't list 
> > [%s] (%s)\n", dir_path, strerror(errno));
> > ++                              continue;
> > ++                      }
> > ++
> > ++                      for ( entry = readdir(d); entry != NULL; entry = 
> > readdir(d) )
> > ++                      {
> > ++                              if ( (entry->d_type == DT_DIR) &&
> > ++                                      (strcmp(entry->d_name, "..") != 0) 
> > &&
> > ++                                      (strcmp(entry->d_name, ".") != 0) )
> > ++                              {
> > ++                                      char tmp_path[PATH_MAX];
> > ++                                      int result_path_len;
> > ++
> > ++                                      result_path_len = 
> > snprintf(tmp_path, PATH_MAX,
> > ++                                              "%s/%s", dir_path, 
> > entry->d_name);
> > ++                                      if (result_path_len >= PATH_MAX)
> > ++                                      {
> > ++                                              DPRINTF(E_ERROR, L_INOTIFY, 
> > "File path too long for %s!", entry->d_name);
> > ++                                              continue;
> > ++                                      }
> > ++
> > ++                                      DPRINTF(E_DEBUG, L_INOTIFY, 
> > "Walking %s\n", tmp_path);
> > ++                                      char found_flag = 0;
> > ++                                      for( i=1; i <= rows; i++ )
> > ++                                      {
> > ++                                              if (strcmp(result[i], 
> > tmp_path) == 0)
> > ++                                              {
> > ++                                                      found_flag = 1;
> > ++                                                      break;
> > ++                                              }
> > ++                                      }
> > ++
> > ++                                      if ( !found_flag )
> > ++                                      {
> > ++                                              char * esc_name = NULL;
> > ++                                              esc_name = 
> > modifyString(strdup(entry->d_name), "&", "&amp;amp;", 0);
> > ++                                              
> > inotify_insert_directory(global_kqueue_handle, esc_name, tmp_path);
> > ++                                              free(esc_name);
> > ++                                      }
> > ++                              }
> > ++                      }
> > ++
> > ++                      closedir(d);
> > ++
> > ++                      sqlite3_free_table(result);
> > ++                      sqlite3_free(sql);
> > ++              }
> > ++              else if (ke.fflags & NOTE_WRITE)
> > ++              {
> > ++                      DPRINTF(E_DEBUG, L_INOTIFY, "Path [%s] content 
> > updated (file).\n", dir_path);
> > ++
> > ++                      char * sql;
> > ++                      char **result;
> > ++                      int i, rows;
> > ++                      sql = sqlite3_mprintf("SELECT PATH from DETAILS 
> > where (PATH > '%q/' and PATH <= '%q/%c')"
> > ++                              " and SIZE <> ''", dir_path, dir_path, 
> > 0xFF);
> > ++                      if( (sql_get_table(db, sql, &result, &rows, NULL) 
> > != SQLITE_OK) )
> > ++                      {
> > ++                              DPRINTF(E_WARN, L_INOTIFY, "Read state 
> > [%s]: Query failed, not updating\n", dir_path);
> > ++                              sqlite3_free(sql);
> > ++                              continue;
> > ++                      }
> > ++
> > ++                      for( i=1; i <= rows; i++ )
> > ++                      {
> > ++                              DPRINTF(E_DEBUG, L_INOTIFY, "Indexed 
> > content: %s\n", result[i]);
> > ++                              if (access(result[i], R_OK) == -1) /*oops, 
> > our file is gone*/
> > ++                              {
> > ++                                      inotify_remove_file(result[i]);
> > ++                              }
> > ++                      }
> > ++
> > ++                      DIR* d;
> > ++                      struct dirent * entry;
> > ++                      d = opendir(dir_path);
> > ++                      if (!d)
> > ++                      {
> > ++                              DPRINTF(E_ERROR, L_INOTIFY, "Can't list 
> > [%s] (%s)\n", dir_path, strerror(errno));
> > ++                              continue;
> > ++                      }
> > ++
> > ++                      for ( entry = readdir(d); entry != NULL; entry = 
> > readdir(d) )
> > ++                      {
> > ++                              if ( (entry->d_type == DT_REG) ||
> > ++                                   (entry->d_type == DT_LNK) )
> > ++                              {
> > ++                                      char tmp_path[PATH_MAX];
> > ++                                      int result_path_len;
> > ++
> > ++                                      result_path_len = 
> > snprintf(tmp_path, PATH_MAX,
> > ++                                              "%s/%s", dir_path, 
> > entry->d_name);
> > ++                                      if (result_path_len >= PATH_MAX)
> > ++                                      {
> > ++                                              DPRINTF(E_ERROR, L_INOTIFY, 
> > "File path too long for %s!", entry->d_name);
> > ++                                              continue;
> > ++                                      }
> > ++
> > ++                                      DPRINTF(E_DEBUG, L_INOTIFY, 
> > "Walking %s\n", tmp_path);
> > ++
> > ++                                      char found_flag = 0;
> > ++                                      for( i=1; i <= rows; i++ )
> > ++                                      {
> > ++                                              if (strcmp(result[i], 
> > tmp_path) == 0)
> > ++                                              {
> > ++                                                      found_flag = 1;
> > ++                                                      break;
> > ++                                              }
> > ++                                      }
> > ++
> > ++                                      if ( !found_flag )
> > ++                                      {
> > ++                                              char * esc_name = NULL;
> > ++                                              struct stat st;
> > ++
> > ++                                              if( stat(tmp_path, &st) != 
> > 0 )
> > ++                                              {
> > ++                                                      DPRINTF(E_ERROR, 
> > L_INOTIFY, "'%s' disappeared!", tmp_path);
> > ++                                                      continue;
> > ++                                              }
> > ++
> > ++                                              esc_name = 
> > modifyString(strdup(entry->d_name), "&", "&amp;amp;", 0);
> > ++                                              if ( S_ISDIR(st.st_mode) )
> > ++                                                      
> > inotify_insert_directory(global_kqueue_handle, esc_name, tmp_path);
> > ++                                              else
> > ++                                                      
> > inotify_insert_file(esc_name, tmp_path);
> > ++                                              free(esc_name);
> > ++                                      }
> > ++                              }
> > ++                      }
> > ++
> > ++                      closedir(d);
> > ++
> > ++                      sqlite3_free_table(result);
> > ++                      sqlite3_free(sql);
> > ++              }
> > ++      }
> > ++      inotify_remove_watches(global_kqueue_handle);
> > ++quitting:
> > ++
> > ++      return 0;
> > ++}
> > + #endif
> > ++
> > ++#endif // defined(HAVE_INOTIFY) || defined(HAVE_SYS_EVENT_H)
> > ++
> > Index: patches/patch-inotify_h
> > ===================================================================
> > RCS file: patches/patch-inotify_h
> > diff -N patches/patch-inotify_h
> > --- /dev/null   1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-inotify_h     18 Jan 2015 22:45:10 -0000
> > @@ -0,0 +1,14 @@
> > +$OpenBSD$
> > +--- inotify.h.orig     Tue Aug 26 23:09:22 2014
> > ++++ inotify.h  Sun Jan 18 22:45:07 2015
> > +@@ -4,4 +4,10 @@ inotify_remove_file(const char * path);
> > +
> > + void *
> > + start_inotify();
> > ++#elif defined(HAVE_SYS_EVENT_H)
> > ++int
> > ++inotify_remove_file(const char* path);
> > ++
> > ++void *
> > ++start_kqueue();
> > + #endif
> > Index: patches/patch-metadata_c
> > ===================================================================
> > RCS file: patches/patch-metadata_c
> > diff -N patches/patch-metadata_c
> > --- /dev/null   1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-metadata_c    18 Jan 2015 22:45:10 -0000
> > @@ -0,0 +1,12 @@
> > +$OpenBSD$
> > +--- metadata.c.orig    Tue Aug 26 23:09:22 2014
> > ++++ metadata.c Sun Jan 18 22:45:07 2015
> > +@@ -149,7 +149,7 @@ check_for_captions(const char *path, int64_t detailID)
> > +
> > +       if (ret == 0)
> > +       {
> > +-              sql_exec(db, "INSERT into CAPTIONS"
> > ++              sql_exec(db, "INSERT OR REPLACE into CAPTIONS"
> > +                            " (ID, PATH) "
> > +                            "VALUES"
> > +                            " (%lld, %Q)", detailID, file);
> > Index: patches/patch-minidlna_c
> > ===================================================================
> > RCS file: patches/patch-minidlna_c
> > diff -N patches/patch-minidlna_c
> > --- /dev/null   1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-minidlna_c    18 Jan 2015 22:45:10 -0000
> > @@ -0,0 +1,43 @@
> > +$OpenBSD$
> > +--- minidlna.c.orig    Tue Aug 26 23:09:22 2014
> > ++++ minidlna.c Sun Jan 18 22:45:07 2015
> > +@@ -46,6 +46,7 @@
> > +  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
> > THE
> > +  * POSSIBILITY OF SUCH DAMAGE.
> > +  */
> > ++#define FD_SETSIZE 8192
> > + #include <stdlib.h>
> > + #include <unistd.h>
> > + #include <string.h>
> > +@@ -376,6 +377,7 @@ rescan:
> > +               open_db(&db);
> > +               if (*scanner_pid == 0) /* child (scanner) process */
> > +               {
> > ++                      DPRINTF(E_DEBUG, L_GENERAL, "Starting scanner in 
> > forked child\n");
> > +                       start_scanner();
> > +                       sqlite3_close(db);
> > +                       log_close();
> > +@@ -384,6 +386,7 @@ rescan:
> > +               }
> > +               else if (*scanner_pid < 0)
> > +               {
> > ++                      DPRINTF(E_DEBUG, L_GENERAL, "Starting scanner in 
> > parent\n");
> > +                       start_scanner();
> > +               }
> > + #else
> > +@@ -1047,6 +1050,15 @@ main(int argc, char **argv)
> > +                                                   "Inotify will be 
> > disabled.\n");
> > +               else if (pthread_create(&inotify_thread, NULL, 
> > start_inotify, NULL) != 0)
> > +                       DPRINTF(E_FATAL, L_GENERAL, "ERROR: 
> > pthread_create() failed for start_inotify. EXITING\n");
> > ++      }
> > ++#elif defined(HAVE_SYS_EVENT_H)
> > ++      if( GETFLAG(INOTIFY_MASK) )
> > ++      {
> > ++              if (!sqlite3_threadsafe() || sqlite3_libversion_number() < 
> > 3005001)
> > ++                      DPRINTF(E_ERROR, L_GENERAL, "SQLite library is not 
> > threadsafe!  "
> > ++                      "Kqueue will be disabled.\n");
> > ++              else if (pthread_create(&inotify_thread, NULL, 
> > start_kqueue, NULL) != 0)
> > ++                      DPRINTF(E_FATAL, L_GENERAL, "ERROR: 
> > pthread_create() failed for start_kqueue. EXITING\n");
> > +       }
> > + #endif
> > +       smonitor = OpenAndConfMonitorSocket();
> > Index: patches/patch-minidlna_conf
> > ===================================================================
> > RCS file: /cvs/ports/multimedia/minidlna/patches/patch-minidlna_conf,v
> > retrieving revision 1.4
> > diff -p -u -r1.4 patch-minidlna_conf
> > --- patches/patch-minidlna_conf 11 Jun 2014 00:26:59 -0000      1.4
> > +++ patches/patch-minidlna_conf 18 Jan 2015 22:45:10 -0000
> > @@ -28,7 +28,7 @@ default directories, plus we don't use i
> >
> >   # set this to merge all media_dir base contents into the root container
> >   # note: the default is no
> > -@@ -25,22 +26,18 @@ media_dir=/opt
> > +@@ -25,22 +26,22 @@ media_dir=/opt
> >   #friendly_name=My DLNA Server
> >
> >   # set this if you would like to specify the directory where you want 
> > MiniDLNA to store its database and album art cache
> > @@ -47,10 +47,10 @@ default directories, plus we don't use i
> >   # this should be a list of file names to check for when searching for 
> > album art
> >   # note: names should be delimited with a forward slash ("/")
> >   
> > album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg
> > --
> > --# set this to no to disable inotify monitoring to automatically discover 
> > new files
> > --# note: the default is yes
> > --inotify=yes
> > +
> > + # set this to no to disable inotify monitoring to automatically discover 
> > new files
> > + # note: the default is yes
> > + inotify=yes
> >
> >   # set this to yes to enable support for streaming .jpg and .mp3 files to 
> > a TiVo supporting HMO
> >   enable_tivo=no
> > Index: patches/patch-upnpevents_c
> > ===================================================================
> > RCS file: patches/patch-upnpevents_c
> > diff -N patches/patch-upnpevents_c
> > --- /dev/null   1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-upnpevents_c  18 Jan 2015 22:45:10 -0000
> > @@ -0,0 +1,14 @@
> > +$OpenBSD$
> > +--- upnpevents.c.orig  Tue Aug 26 23:09:22 2014
> > ++++ upnpevents.c       Sun Jan 18 22:45:07 2015
> > +@@ -417,6 +417,10 @@ void upnpevents_selectfds(fd_set *readset, fd_set *wri
> > + {
> > +       struct upnp_event_notify * obj;
> > +       for(obj = notifylist.lh_first; obj != NULL; obj = 
> > obj->entries.le_next) {
> > ++              if (obj->s > FD_SETSIZE)
> > ++                      DPRINTF(E_FATAL, L_HTTP,
> > ++                          "upnpevents_selectfds: file descriptor %d too 
> > big for select, limit is %d\n",
> > ++                          obj->s, FD_SETSIZE);
> > +               DPRINTF(E_DEBUG, L_HTTP, "upnpevents_selectfds: %p %d %d\n",
> > +                      obj, obj->state, obj->s);
> > +               if(obj->s >= 0) {
> >
> >
> > Comments, tests?
> >
> >
> > Daniel
> >
> > --
> > LÉVAI Dániel
> > PGP key ID = 0x83B63A8F
> > Key fingerprint = DBEC C66B A47A DFA2 792D  650C C69B BE4C 83B6 3A8F
> >
> 
> 
> 
> -- 
> "If you try a few times and give up, you'll never get there. But if
> you keep at it... There's a lot of problems in the world which can
> really be solved by applying two or three times the persistence that
> other people will."
>                 -- Stewart Nelson
> 

-- 
Antoine

Reply via email to