Added pndnotifyd to monitor the dirs in the search-path; will be adding to it to...
[pandora-libraries.git] / apps / pndnotifyd.c
1
2 /* pndnotifyd - a daemon whose job is to monitor searchpaths for app changes (appearing, disappearing, changing).
3  * If a change is found, the discovery code is invoked and apps registered for the launchers to see
4  *
5  */
6
7 // TODO: for daemon mode, need to detach from the terminal
8 // TODO: Catch HUP and reparse config
9
10 #include <stdio.h> // for stdio
11 #include <unistd.h> // for exit()
12 #include <stdlib.h> // for exit()
13 #include <string.h>
14 #include <time.h> // for time()
15 #include <ctype.h> // for isdigit()
16
17 #include "pnd_conf.h"
18 #include "pnd_container.h"
19 #include "pnd_apps.h"
20 #include "pnd_notify.h"
21 #include "../lib/pnd_pathiter.h"
22
23 static unsigned char g_daemon_mode = 0;
24
25 int main ( int argc, char *argv[] ) {
26   pnd_notify_handle nh;
27   char *configpath;
28   char *appspath;
29   char *searchpath;
30   int i;
31
32   unsigned int interval_secs = 60;
33
34   /* iterate across args
35    */
36   for ( i = 1; i < argc; i++ ) {
37
38     if ( argv [ i ][ 0 ] == '-' && argv [ i ][ 1 ] == 'd' ) {
39       //printf ( "Going daemon mode. Silent running.\n" );
40       g_daemon_mode = 1;
41     } else if ( isdigit ( argv [ i ][ 0 ] ) ) {
42       interval_secs = atoi ( argv [ i ] );
43     } else {
44       printf ( "%s [-d] [##]\n", argv [ 0 ] );
45       printf ( "-d\tDaemon mode; detach from terminal, chdir to /tmp, suppress output. Optional.\n" );
46       printf ( "##\tA numeric value is interpreted as number of seconds between checking for filesystem changes. Default %u.\n",
47                interval_secs );
48       exit ( 0 );
49     }
50
51   }
52
53   if ( ! g_daemon_mode ) {
54     printf ( "Interval between checks is %u seconds\n", interval_secs );
55   }
56
57   /* parse configs
58    */
59
60   // attempt to fetch a sensible default searchpath for configs
61   configpath = pnd_conf_query_searchpath();
62
63   // attempt to fetch the apps config to pick up a searchpath
64   pnd_conf_handle apph;
65
66   apph = pnd_conf_fetch_by_id ( pnd_conf_apps, configpath );
67
68   if ( apph ) {
69     appspath = pnd_conf_get_as_char ( apph, PND_APPS_KEY );
70
71     if ( ! appspath ) {
72       appspath = PND_APPS_SEARCHPATH;
73     }
74
75   } else {
76     // couldn't find a useful app search path so use the default
77     appspath = PND_APPS_SEARCHPATH;
78   }
79
80   if ( ! g_daemon_mode ) {
81     printf ( "Apps searchpath is '%s'\n", appspath );
82   }
83
84   /* set up notifies
85    */
86   searchpath = appspath;
87
88   nh = pnd_notify_init();
89
90   if ( ! nh ) {
91     if ( ! g_daemon_mode ) {
92       printf ( "INOTIFY failed to init.\n" );
93     }
94     exit ( -1 );
95   }
96
97   if ( ! g_daemon_mode ) {
98     printf ( "INOTIFY is up.\n" );
99   }
100
101   SEARCHPATH_PRE
102   {
103
104     pnd_notify_watch_path ( nh, buffer, PND_NOTIFY_RECURSE );
105
106     if ( ! g_daemon_mode ) {
107       printf ( "Watching path '%s' and its descendents.\n", buffer );
108     }
109
110   }
111   SEARCHPATH_POST
112
113   /* daemon main loop
114    */
115   while ( 1 ) {
116
117     // need to rediscover?
118     if ( pnd_notify_rediscover_p ( nh ) ) {
119
120       // by this point, the watched directories have notified us that something of relevent
121       // has occurred; we should be clever, but we're not, so just re-brute force the
122       // discovery and spit out .desktop files..
123       if ( ! g_daemon_mode ) {
124         printf ( "Time to re-discover!\n" );
125       }
126
127       // lets not eat up all the CPU
128       // should use an alarm or select() or something
129       sleep ( interval_secs );
130
131     } // need to rediscover?
132
133   } // while
134
135   /* shutdown
136    */
137   pnd_notify_shutdown ( nh );
138
139   return ( 0 );
140 }