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,32 @@ 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+ exit (0 );
122+ return ;
123+ }
124+
125+ if (!(entry = readdir (dir ))) {
126+ if (verbose ) {
127+ g_print ("_________________________\n" );
128+ g_print ("Invalid directory stream descriptor '%s'\n" , name );
129+ }
130+ closedir (dir );
131+ return ;
132+ }
133+
113134 do {
114135 if (entry -> d_type == DT_DIR ) {
115136 char path [1024 ];
@@ -143,7 +164,7 @@ int add_dir_to_watch(char *directory)
143164 if (!inotifytools_watch_recursively (directory , WR_EVENTS ) ) {
144165 fprintf (stderr , "%s\n" , strerror (inotifytools_error ()));
145166 exit (1 );
146-
167+
147168 }
148169 initially_register (directory , 0 );
149170 }
@@ -153,7 +174,7 @@ void handle_event(struct inotify_event *event)
153174{
154175 int ret ;
155176 gchar * absolute_path = g_build_path (G_DIR_SEPARATOR_S , inotifytools_filename_from_wd (event -> wd ), event -> name , NULL );
156-
177+
157178 if (event -> mask & IN_CLOSE_WRITE | event -> mask & IN_MOVED_TO ){
158179 if (g_file_test (absolute_path , G_FILE_TEST_IS_REGULAR )){
159180 pthread_t some_thread ;
@@ -167,7 +188,7 @@ void handle_event(struct inotify_event *event)
167188 }
168189 }
169190 }
170-
191+
171192 if (event -> mask & IN_MOVED_FROM | event -> mask & IN_DELETE ){
172193 pthread_t some_thread ;
173194 struct arg_struct args ;
@@ -179,23 +200,23 @@ void handle_event(struct inotify_event *event)
179200 pthread_join (some_thread , NULL );
180201 }
181202 }
182-
203+
183204 /* Too many FS events were received, some event notifications were potentially lost */
184205 if (event -> mask & IN_Q_OVERFLOW ){
185206 printf ("Warning: AN OVERFLOW EVENT OCCURRED\n" );
186207 }
187-
208+
188209 if (event -> mask & IN_IGNORED ){
189210 printf ("Warning: AN IN_IGNORED EVENT OCCURRED\n" );
190211 }
191-
212+
192213}
193214
194215int main (int argc , char * * argv ) {
195-
216+
196217 GError * error = NULL ;
197218 GOptionContext * context ;
198-
219+
199220 context = g_option_context_new ("" );
200221 g_option_context_add_main_entries (context , entries , NULL );
201222 // g_option_context_add_group (context, gtk_get_option_group (TRUE));
@@ -209,7 +230,7 @@ int main(int argc, char ** argv) {
209230 fprintf (stderr ,"Version: %s\n" , VERSION_NUMBER );
210231 exit (0 );
211232 }
212-
233+
213234 if ( !inotifytools_initialize ()){
214235 fprintf (stderr , "inotifytools_initialize error\n" );
215236 exit (1 );
@@ -223,7 +244,7 @@ int main(int argc, char ** argv) {
223244 gchar * global_systemd_file = "/usr/lib/systemd/user/appimaged.service" ;
224245 gchar * partial_path = g_strdup_printf ("autostart/appimagekit-appimaged.desktop" );
225246 gchar * destination = g_build_filename (g_get_user_config_dir (), partial_path , NULL );
226-
247+
227248 if (uninstall ){
228249 if (g_file_test (installed_appimaged_location , G_FILE_TEST_EXISTS ))
229250 fprintf (stderr , "* Please delete %s\n" , installed_appimaged_location );
@@ -232,8 +253,8 @@ int main(int argc, char ** argv) {
232253 fprintf (stderr , "* To remove all AppImage desktop integration, run\n" );
233254 fprintf (stderr , " find ~/.local/share -name 'appimagekit_*' -exec rm {} \\;\n\n" );
234255 exit (0 );
235- }
236-
256+ }
257+
237258 if (install != NULL ){
238259 if (((appimage_location != NULL )) && ((own_desktop_file_location != NULL ))){
239260 printf ("Running from within %s\n" , appimage_location );
@@ -283,7 +304,7 @@ int main(int argc, char ** argv) {
283304 exit (1 );
284305 }
285306 }
286-
307+
287308 add_dir_to_watch (user_bin_dir );
288309 add_dir_to_watch (g_build_filename (g_get_home_dir (), "/Downloads" , NULL ));
289310 add_dir_to_watch (g_build_filename (g_get_home_dir (), "/bin" , NULL ));
@@ -293,15 +314,15 @@ int main(int argc, char ** argv) {
293314 add_dir_to_watch (g_build_filename ("/run/archiso/img_dev/Applications" , NULL )); // Antergos Live media
294315 add_dir_to_watch (g_build_filename ("/opt" , NULL ));
295316 add_dir_to_watch (g_build_filename ("/usr/local/bin" , NULL ));
296-
317+
297318 struct inotify_event * event = inotifytools_next_event (-1 );
298319 while (event ) {
299320 if (verbose ){
300321 inotifytools_printf (event , "%w%f %e\n" );
301322 }
302- fflush (stdout );
323+ fflush (stdout );
303324 handle_event (event );
304- fflush (stdout );
325+ fflush (stdout );
305326 event = inotifytools_next_event (-1 );
306327 }
307328}
0 commit comments