From: skeezix Date: Thu, 19 Feb 2009 18:32:18 +0000 (-0500) Subject: Added pndnotifyd to monitor the dirs in the search-path; will be adding to it to... X-Git-Tag: Release-2010-05/1~222 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d94d5f795c9b1a5fefd9f9df92e7b964cf5ff61;p=pandora-libraries.git Added pndnotifyd to monitor the dirs in the search-path; will be adding to it to emit .desktop files soon as well --- diff --git a/Makefile b/Makefile index 6113c61..f26f465 100644 --- 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 index 0000000..2197e87 --- /dev/null +++ b/apps/pndnotifyd.c @@ -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 // for stdio +#include // for exit() +#include // for exit() +#include +#include // for time() +#include // 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 ); +} diff --git a/include/pnd_notify.h b/include/pnd_notify.h index e9b6e7b..f83c6f9 100644 --- a/include/pnd_notify.h +++ b/include/pnd_notify.h @@ -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: diff --git a/lib/pnd_notify.c b/lib/pnd_notify.c index 0c99458..e77fe15 100644 --- a/lib/pnd_notify.c +++ b/lib/pnd_notify.c @@ -4,12 +4,19 @@ #include // for malloc, etc #include // for close +#define _XOPEN_SOURCE 500 +#define __USE_XOPEN_EXTENDED +#include /* 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 );