11/**************************************************************************
2- *
2+ *
33 * Copyright (c) 2004-16 Simon Peter
4- *
4+ *
55 * All Rights Reserved.
6- *
6+ *
77 * Permission is hereby granted, free of charge, to any person obtaining a copy
88 * of this software and associated documentation files (the "Software"), to deal
99 * in the Software without restriction, including without limitation the rights
1010 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111 * copies of the Software, and to permit persons to whom the Software is
1212 * furnished to do so, subject to the following conditions:
13- *
13+ *
1414 * The above copyright notice and this permission notice shall be included in
1515 * all copies or substantial portions of the Software.
16- *
16+ *
1717 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323 * THE SOFTWARE.
24- *
24+ *
2525 **************************************************************************/
2626
2727#ident "AppImage by Simon Peter, http://appimage.org/"
2828
2929/*
30- * Optional daempon to watch directories for AppImages
30+ * Optional daempon to watch directories for AppImages
3131 * and register/unregister them with the system
32- *
32+ *
3333 * TODO (feel free to send pull requests):
3434 * - Switch to https://developer.gnome.org/gio/stable/GFileMonitor.html (but with subdirectories)
3535 * which would drop the dependency on libinotifytools.so.0
36- * - Add and remove subdirectories on the fly at runtime -
36+ * - Add and remove subdirectories on the fly at runtime -
3737 * see https://github.com/paragone/configure-via-inotify/blob/master/inotify/src/inotifywatch.c
3838 */
3939
4040#include <stdio.h>
41+ #include <errno.h>
4142#include <string.h>
4243#include <stdlib.h>
4344#include <unistd.h>
@@ -75,8 +76,8 @@ static GOptionEntry entries[] =
7576#define EXCLUDE_CHUNK 1024
7677#define WR_EVENTS (IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF)
7778
78- /* Run the actual work in treads;
79- * pthread allows to pass only one argument to the thread function,
79+ /* Run the actual work in treads;
80+ * pthread allows to pass only one argument to the thread function,
8081 * hence we use a struct as the argument in which the real arguments are */
8182struct arg_struct {
8283 char * path ;
@@ -104,12 +105,31 @@ void initially_register(const char *name, int level)
104105{
105106 DIR * dir ;
106107 struct dirent * entry ;
107-
108- if (!(dir = opendir (name )))
109- fprintf (stderr , "opendir error\n" );
110- if (!(entry = readdir (dir )))
111- fprintf (stderr , "readdir error\n" );
112-
108+
109+ if (!(dir = opendir (name ))) {
110+ if (verbose ) {
111+ if (errno == EACCES ) {
112+ g_print ("_________________________\n" );
113+ g_print ("Permission denied on dir '%s'\n" , name );
114+ }
115+ else {
116+ g_print ("_________________________\n" );
117+ g_print ("Failed to open dir '%s'\n" , name );
118+ }
119+ }
120+ closedir (dir );
121+ return ;
122+ }
123+
124+ if (!(entry = readdir (dir ))) {
125+ if (verbose ) {
126+ g_print ("_________________________\n" );
127+ g_print ("Invalid directory stream descriptor '%s'\n" , name );
128+ }
129+ closedir (dir );
130+ return ;
131+ }
132+
113133 do {
114134 if (entry -> d_type == DT_DIR ) {
115135 char path [1024 ];
@@ -143,7 +163,7 @@ int add_dir_to_watch(char *directory)
143163 if (!inotifytools_watch_recursively (directory , WR_EVENTS ) ) {
144164 fprintf (stderr , "%s\n" , strerror (inotifytools_error ()));
145165 exit (1 );
146-
166+
147167 }
148168 initially_register (directory , 0 );
149169 }
@@ -153,7 +173,7 @@ void handle_event(struct inotify_event *event)
153173{
154174 int ret ;
155175 gchar * absolute_path = g_build_path (G_DIR_SEPARATOR_S , inotifytools_filename_from_wd (event -> wd ), event -> name , NULL );
156-
176+
157177 if (event -> mask & IN_CLOSE_WRITE | event -> mask & IN_MOVED_TO ){
158178 if (g_file_test (absolute_path , G_FILE_TEST_IS_REGULAR )){
159179 pthread_t some_thread ;
@@ -167,7 +187,7 @@ void handle_event(struct inotify_event *event)
167187 }
168188 }
169189 }
170-
190+
171191 if (event -> mask & IN_MOVED_FROM | event -> mask & IN_DELETE ){
172192 pthread_t some_thread ;
173193 struct arg_struct args ;
@@ -179,23 +199,23 @@ void handle_event(struct inotify_event *event)
179199 pthread_join (some_thread , NULL );
180200 }
181201 }
182-
202+
183203 /* Too many FS events were received, some event notifications were potentially lost */
184204 if (event -> mask & IN_Q_OVERFLOW ){
185205 printf ("Warning: AN OVERFLOW EVENT OCCURRED\n" );
186206 }
187-
207+
188208 if (event -> mask & IN_IGNORED ){
189209 printf ("Warning: AN IN_IGNORED EVENT OCCURRED\n" );
190210 }
191-
211+
192212}
193213
194214int main (int argc , char * * argv ) {
195-
215+
196216 GError * error = NULL ;
197217 GOptionContext * context ;
198-
218+
199219 context = g_option_context_new ("" );
200220 g_option_context_add_main_entries (context , entries , NULL );
201221 // g_option_context_add_group (context, gtk_get_option_group (TRUE));
@@ -209,7 +229,7 @@ int main(int argc, char ** argv) {
209229 fprintf (stderr ,"Version: %s\n" , VERSION_NUMBER );
210230 exit (0 );
211231 }
212-
232+
213233 if ( !inotifytools_initialize ()){
214234 fprintf (stderr , "inotifytools_initialize error\n" );
215235 exit (1 );
@@ -223,7 +243,7 @@ int main(int argc, char ** argv) {
223243 gchar * global_systemd_file = "/usr/lib/systemd/user/appimaged.service" ;
224244 gchar * partial_path = g_strdup_printf ("autostart/appimagekit-appimaged.desktop" );
225245 gchar * destination = g_build_filename (g_get_user_config_dir (), partial_path , NULL );
226-
246+
227247 if (uninstall ){
228248 if (g_file_test (installed_appimaged_location , G_FILE_TEST_EXISTS ))
229249 fprintf (stderr , "* Please delete %s\n" , installed_appimaged_location );
@@ -232,8 +252,8 @@ int main(int argc, char ** argv) {
232252 fprintf (stderr , "* To remove all AppImage desktop integration, run\n" );
233253 fprintf (stderr , " find ~/.local/share -name 'appimagekit_*' -exec rm {} \\;\n\n" );
234254 exit (0 );
235- }
236-
255+ }
256+
237257 if (install != NULL ){
238258 if (((appimage_location != NULL )) && ((own_desktop_file_location != NULL ))){
239259 printf ("Running from within %s\n" , appimage_location );
@@ -283,7 +303,7 @@ int main(int argc, char ** argv) {
283303 exit (1 );
284304 }
285305 }
286-
306+
287307 add_dir_to_watch (user_bin_dir );
288308 add_dir_to_watch (g_build_filename (g_get_home_dir (), "/Downloads" , NULL ));
289309 add_dir_to_watch (g_build_filename (g_get_home_dir (), "/bin" , NULL ));
@@ -293,15 +313,15 @@ int main(int argc, char ** argv) {
293313 add_dir_to_watch (g_build_filename ("/run/archiso/img_dev/Applications" , NULL )); // Antergos Live media
294314 add_dir_to_watch (g_build_filename ("/opt" , NULL ));
295315 add_dir_to_watch (g_build_filename ("/usr/local/bin" , NULL ));
296-
316+
297317 struct inotify_event * event = inotifytools_next_event (-1 );
298318 while (event ) {
299319 if (verbose ){
300320 inotifytools_printf (event , "%w%f %e\n" );
301321 }
302- fflush (stdout );
322+ fflush (stdout );
303323 handle_event (event );
304- fflush (stdout );
324+ fflush (stdout );
305325 event = inotifytools_next_event (-1 );
306326 }
307327}
0 commit comments