Added pndnotifyd to monitor the dirs in the search-path; will be adding to it to...
authorskeezix <skeezix@flotsam-vm.(none)>
Thu, 19 Feb 2009 18:32:18 +0000 (13:32 -0500)
committerskeezix <skeezix@flotsam-vm.(none)>
Thu, 19 Feb 2009 18:32:18 +0000 (13:32 -0500)
Makefile
apps/pndnotifyd.c [new file with mode: 0644]
include/pnd_notify.h
lib/pnd_notify.c

index 6113c61..f26f465 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ RANLIB = ranlib
 RM = rm
 
 # environment
-VPATH = lib test
+VPATH = lib test apps
 CFLAG_SO = -fPIC #-fPIC not always needed, but good to have
 CFLAGS = -Wall -I./include -g ${CFLAG_SO}
 
@@ -21,10 +21,10 @@ SOLIB1 = libpnd.so.1.0.1    # versioned name
 XMLOBJ = lib/tinyxml/tinystr.o lib/tinyxml/tinyxml.o lib/tinyxml/tinyxmlerror.o lib/tinyxml/tinyxmlparser.o
 ALLOBJ = pnd_conf.o pnd_container.o pnd_discovery.o pnd_pxml.o pnd_notify.o pnd_locate.o pnd_tinyxml.o
 
-all: ${SOLIB} ${LIB} conftest discotest notifytest locatetest
+all: ${SOLIB} ${LIB} conftest discotest notifytest locatetest pndnotifyd
 
 clean:
-       ${RM} -f ${ALLOBJ} ${XMLOBJ} ${LIB} ${SOLIB1} locatetest.o bin/locatetest conftest.o bin/conftest discotest.o bin/discotest bin/notifytest notifytest.o
+       ${RM} -f ${ALLOBJ} ${XMLOBJ} ${LIB} ${SOLIB1} locatetest.o bin/locatetest conftest.o bin/conftest discotest.o bin/discotest bin/notifytest notifytest.o bin/pndnotifyd pndnotifyd.o ${SOLIB}
 
 libpnd.a:      ${ALLOBJ} ${XMLOBJ}
        ${AR} r ${LIB} ${ALLOBJ} ${XMLOBJ}
@@ -32,6 +32,7 @@ libpnd.a:     ${ALLOBJ} ${XMLOBJ}
 
 libpnd.so.1:   ${ALLOBJ} ${XMLOBJ}
        ${CC} -shared -Wl,-soname,${SOLIB} -o ${SOLIB1} ${ALLOBJ} ${XMLOBJ}
+       ln -f -s ${SOLIB1} ${SOLIB}
 
 conftest:      conftest.o ${LIB}
        ${CC} -lstdc++ -o bin/conftest conftest.o libpnd.a
@@ -44,3 +45,6 @@ notifytest:   notifytest.o ${LIB}
 
 locatetest:    locatetest.o ${SOLIB1}
        ${CC} -lstdc++ -o bin/locatetest locatetest.o ${SOLIB1}
+
+pndnotifyd:    pndnotifyd.o ${SOLIB1}
+       ${CC} -lstdc++ -o bin/pndnotifyd pndnotifyd.o ${SOLIB1}
diff --git a/apps/pndnotifyd.c b/apps/pndnotifyd.c
new file mode 100644 (file)
index 0000000..2197e87
--- /dev/null
@@ -0,0 +1,140 @@
+
+/* pndnotifyd - a daemon whose job is to monitor searchpaths for app changes (appearing, disappearing, changing).
+ * If a change is found, the discovery code is invoked and apps registered for the launchers to see
+ *
+ */
+
+// TODO: for daemon mode, need to detach from the terminal
+// TODO: Catch HUP and reparse config
+
+#include <stdio.h> // for stdio
+#include <unistd.h> // for exit()
+#include <stdlib.h> // for exit()
+#include <string.h>
+#include <time.h> // for time()
+#include <ctype.h> // for isdigit()
+
+#include "pnd_conf.h"
+#include "pnd_container.h"
+#include "pnd_apps.h"
+#include "pnd_notify.h"
+#include "../lib/pnd_pathiter.h"
+
+static unsigned char g_daemon_mode = 0;
+
+int main ( int argc, char *argv[] ) {
+  pnd_notify_handle nh;
+  char *configpath;
+  char *appspath;
+  char *searchpath;
+  int i;
+
+  unsigned int interval_secs = 60;
+
+  /* iterate across args
+   */
+  for ( i = 1; i < argc; i++ ) {
+
+    if ( argv [ i ][ 0 ] == '-' && argv [ i ][ 1 ] == 'd' ) {
+      //printf ( "Going daemon mode. Silent running.\n" );
+      g_daemon_mode = 1;
+    } else if ( isdigit ( argv [ i ][ 0 ] ) ) {
+      interval_secs = atoi ( argv [ i ] );
+    } else {
+      printf ( "%s [-d] [##]\n", argv [ 0 ] );
+      printf ( "-d\tDaemon mode; detach from terminal, chdir to /tmp, suppress output. Optional.\n" );
+      printf ( "##\tA numeric value is interpreted as number of seconds between checking for filesystem changes. Default %u.\n",
+              interval_secs );
+      exit ( 0 );
+    }
+
+  }
+
+  if ( ! g_daemon_mode ) {
+    printf ( "Interval between checks is %u seconds\n", interval_secs );
+  }
+
+  /* parse configs
+   */
+
+  // attempt to fetch a sensible default searchpath for configs
+  configpath = pnd_conf_query_searchpath();
+
+  // attempt to fetch the apps config to pick up a searchpath
+  pnd_conf_handle apph;
+
+  apph = pnd_conf_fetch_by_id ( pnd_conf_apps, configpath );
+
+  if ( apph ) {
+    appspath = pnd_conf_get_as_char ( apph, PND_APPS_KEY );
+
+    if ( ! appspath ) {
+      appspath = PND_APPS_SEARCHPATH;
+    }
+
+  } else {
+    // couldn't find a useful app search path so use the default
+    appspath = PND_APPS_SEARCHPATH;
+  }
+
+  if ( ! g_daemon_mode ) {
+    printf ( "Apps searchpath is '%s'\n", appspath );
+  }
+
+  /* set up notifies
+   */
+  searchpath = appspath;
+
+  nh = pnd_notify_init();
+
+  if ( ! nh ) {
+    if ( ! g_daemon_mode ) {
+      printf ( "INOTIFY failed to init.\n" );
+    }
+    exit ( -1 );
+  }
+
+  if ( ! g_daemon_mode ) {
+    printf ( "INOTIFY is up.\n" );
+  }
+
+  SEARCHPATH_PRE
+  {
+
+    pnd_notify_watch_path ( nh, buffer, PND_NOTIFY_RECURSE );
+
+    if ( ! g_daemon_mode ) {
+      printf ( "Watching path '%s' and its descendents.\n", buffer );
+    }
+
+  }
+  SEARCHPATH_POST
+
+  /* daemon main loop
+   */
+  while ( 1 ) {
+
+    // need to rediscover?
+    if ( pnd_notify_rediscover_p ( nh ) ) {
+
+      // by this point, the watched directories have notified us that something of relevent
+      // has occurred; we should be clever, but we're not, so just re-brute force the
+      // discovery and spit out .desktop files..
+      if ( ! g_daemon_mode ) {
+       printf ( "Time to re-discover!\n" );
+      }
+
+      // lets not eat up all the CPU
+      // should use an alarm or select() or something
+      sleep ( interval_secs );
+
+    } // need to rediscover?
+
+  } // while
+
+  /* shutdown
+   */
+  pnd_notify_shutdown ( nh );
+
+  return ( 0 );
+}
index e9b6e7b..f83c6f9 100644 (file)
@@ -17,6 +17,13 @@ pnd_notify_handle pnd_notify_init ( void );
  */
 void pnd_notify_shutdown ( pnd_notify_handle h );
 
+/* register a path to watch
+ * Pass in a path to register it for watching; note that should you wish children
+ * directories to be watched as well you should set the recursive flag.
+ */
+#define PND_NOTIFY_RECURSE 1
+void pnd_notify_watch_path ( pnd_notify_handle h, char *fullpath, unsigned int flags );
+
 /* rescan_p (rescan predicate) -- wil return TRUE (>0) when the notify is reporting
  * that we should do a re-discovery against the paths.
  * NOTE:
index 0c99458..e77fe15 100644 (file)
@@ -4,12 +4,19 @@
 #include <stdlib.h>         // for malloc, etc
 #include <unistd.h>         // for close
 
+#define _XOPEN_SOURCE 500
+#define __USE_XOPEN_EXTENDED
+#include <ftw.h> /* for nftw, tree walker */
+
 #include "pnd_notify.h"
+#include "pnd_pathiter.h"
 
 typedef struct {
   int fd;              // notify API file descriptor
 } pnd_notify_t;
 
+static int notify_handle;
+
 static void pnd_notify_hookup ( int fd );
 
 pnd_notify_handle pnd_notify_init ( void ) {
@@ -45,6 +52,43 @@ void pnd_notify_shutdown ( pnd_notify_handle h ) {
   return;
 }
 
+static int pnd_notify_callback ( const char *fpath, const struct stat *sb,
+                                int typeflag, struct FTW *ftwbuf )
+{
+
+  // only include directories
+  if ( ! ( typeflag & FTW_D ) ) {
+    return ( 0 ); // continue the tree walk
+  }
+
+  //printf ( "Implicitly watching dir '%s'\n", fpath );
+
+  inotify_add_watch ( notify_handle, fpath, IN_CREATE | IN_DELETE | IN_UNMOUNT );
+
+  return ( 0 ); // continue the tree walk
+}
+
+void pnd_notify_watch_path ( pnd_notify_handle h, char *fullpath, unsigned int flags ) {
+  pnd_notify_t *p = (pnd_notify_t*) h;
+
+  inotify_add_watch ( p -> fd, fullpath, IN_CREATE | IN_DELETE | IN_UNMOUNT );
+
+  if ( flags & PND_NOTIFY_RECURSE ) {
+
+    notify_handle = p -> fd;
+
+    nftw ( fullpath,             // path to descend
+          pnd_notify_callback,  // callback to do processing
+          10,                   // no more than X open fd's at once
+          FTW_PHYS );           // do not follow symlinks
+
+    notify_handle = -1;
+
+  } // recurse
+
+  return;
+}
+
 static void pnd_notify_hookup ( int fd ) {
 
   inotify_add_watch ( fd, "./testdata", IN_CREATE | IN_DELETE | IN_UNMOUNT );