예제 #1
0
int main(int argc, char ** argv) 
{   
               
        // initialize and watch the entire directory tree from the current working
        // directory downwards for all events
        if ( !inotifytools_initialize() || !inotifytools_watch_recursively( "/proc/acpi/ac_adapter/AC/", IN_ALL_EVENTS ) )
        {
                fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
                return -1;
        }
        // set time format to 24 hour time, HH:MM:SS
        inotifytools_set_printf_timefmt( "%T" );
        // Output all events as "<timestamp> <path> <events>"
        struct inotify_event * event = inotifytools_next_event( -1 );
        if ( event ) 
        {
                inotifytools_printf( event, "%T %w%f %e\n" );
                event = inotifytools_next_event( -1 );
        }        
        // Configure userspace as the scaling governor in ACPI 
        write_line(ACPI_GOVERNOR_FILE, "userspace");       
        
        
        // Start past/mdp/avgn/maxperf/maxlife 
       
        // Start phoronix-test-suite benchmark mdp 
    
        start_pts(argv[2]);
        start_dvs_program(argv[1]); 
}
예제 #2
0
파일: notify.c 프로젝트: Ironlenny/fsnotify
int notify_addWatch (char const * path, int notify_events) {
    if ( !inotifytools_initialize () ||
	 !inotifytools_watch_file ( path, notify_events ) ) {
    fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
  }
    return 1;
}
예제 #3
0
int main(int argc, char* argv[]) {
	const char* wd = argc > 1? argv[1]: ".";
	char fmt[80];
	unsigned long trig = IN_CLOSE_WRITE;

	if (getenv(DIR_WATCH_FMT)){
		strcpy(fmt, getenv(DIR_WATCH_FMT));
		strcat(fmt, "\n");
	}else{
		strcpy(fmt, "%T %w%f %e\n"); 
	}
	if (getenv(DIR_WATCH_EVENT)){
		trig = strtoul(getenv(DIR_WATCH_EVENT), 0, 0);
	}

        // initialize and watch the entire directory tree from the current working
        // directory downwards for all events
        if ( !inotifytools_initialize()
          || !inotifytools_watch_recursively( wd, trig) ) {
                fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
                return -1;
        }

        // set time format to 24 hour time, HH:MM:SS
        inotifytools_set_printf_timefmt( "%T" );

        // Output all events as "<timestamp> <path> <events>"
        struct inotify_event * event = inotifytools_next_event( -1 );
        while ( event ) {
                inotifytools_printf( event, fmt );
		fflush(stdout);
                event = inotifytools_next_event( -1 );
        }
	return 0;
}
예제 #4
0
void tst_inotifytools_snprintf()
{
    ENTER
    verify((0 == mkdir(TEST_DIR, 0700)) || (EEXIST == errno));
    verify(inotifytools_initialize());
    verify(inotifytools_watch_file(TEST_DIR, IN_CLOSE));

#define BUFSZ 2048
#define RESET do { \
        memset(buf, 0, BUFSZ); \
        memset(test_event, 0, sizeof(struct inotify_event)); \
        test_event->wd = inotifytools_wd_from_filename( TEST_DIR "/"); \
        verify( test_event->wd >= 0 ); \
        inotifytools_set_printf_timefmt(0); \
    } while(0)

    char buf[BUFSZ];
    char event_buf[4096];
    struct inotify_event *test_event = (struct inotify_event *)event_buf;

    RESET;
    test_event->mask = IN_ACCESS;
    inotifytools_snprintf(buf, 1024, test_event, "Event %e %.e on %w %f %T");
    verify2(!strcmp(buf, "Event ACCESS ACCESS on " TEST_DIR "/  "), buf);

    RESET;
    test_event->mask = IN_ACCESS | IN_DELETE;
    inotifytools_snprintf(buf, 1024, test_event, "Event %e %.e on %w %f %T");
    verify2(!strcmp(buf, "Event ACCESS,DELETE ACCESS.DELETE on " TEST_DIR "/  ")
            || !strcmp(buf, "Event DELETE,ACCESS DELETE.ACCESS on " TEST_DIR "/  "), buf);

    RESET;
    test_event->mask = IN_MODIFY;
    inotifytools_snprintf(buf, 10, test_event, "Event %e %.e on %w %f %T");
    verify2(!strcmp(buf, "Event MODI"), buf);

    RESET;
    test_event->mask = IN_ACCESS;
    strcpy(test_event->name, "my_great_file");
    test_event->len = strlen(test_event->name) + 1;
    inotifytools_snprintf(buf, 1024, test_event, "Event %e %.e on %w %f %T");
    verify2(!strcmp(buf, "Event ACCESS ACCESS on " TEST_DIR "/ my_great_file "), buf);

    RESET;
    test_event->mask = IN_ACCESS;
    inotifytools_set_printf_timefmt("%D%% %H:%M");
    {
        char expected[1024];
        char timestr[1024];
        time_t now = time(0);
        strftime(timestr, 1024, "%D%% %H:%M", localtime(&now));
        snprintf(expected, 1024, "Event ACCESS ACCESS on %s/  %s", TEST_DIR, timestr);
        inotifytools_snprintf(buf, 1024, test_event, "Event %e %.e on %w %f %T");
        verify2(!strcmp(buf, expected), buf);
    }

#undef BUFSZ
    EXIT
}
예제 #5
0
파일: watcher.c 프로젝트: kendersec/ADBLink
// Watcher
void *watcher(void *path) {
	char * moved_from = 0;
	int events = IN_CREATE | IN_MOVED_TO | IN_MOVED_FROM | IN_DELETE | IN_MODIFY;

	int plen = strlen((char *) path);

	// initialize and watch the entire directory tree from the current working
	// directory downwards for all events
	if (!inotifytools_initialize() || !inotifytools_watch_recursively(path,
			events)) {
		fprintf(stderr, "%s\n", strerror(inotifytools_error()));
		return -1;
	} else {
		fprintf(stderr, "Watching %s\n", (char *) path);
	}

	// set time format to 24 hour time, HH:MM:SS
	inotifytools_set_printf_timefmt("%T");

	// Output all events as "<timestamp> <path> <events>"
	struct inotify_event * event = inotifytools_next_event(-1);
	while (event) {
		inotifytools_printf(event, "%T %w%f %e\n");

		// For recursivity
		if ((event->mask & IN_CREATE) || (!moved_from && (event->mask
				& IN_MOVED_TO))) {
			// New file - if it is a directory, watch it
			static char * new_file;

			nasprintf(&new_file, "%s%s", inotifytools_filename_from_wd(
							event->wd), event->name);
			//ACTION
			if(isdir(new_file)) {
				int fd;
				char buf[4096];
				snprintf(buf, sizeof buf, "shell:mkdir \"%s\%s\"", fdir(
					inotifytools_filename_from_wd(event->wd), plen), event->name);
				fd = adb_connect(buf);
				adb_read(fd, buf, 4096);
				if (fd < 0) {
					fprintf(stderr,"error: %s\n", adb_error());
					return -1;
				}
				adb_close(fd);
			} else {
				do_sync_push(new_file, fdir(inotifytools_filename_from_wd(
					event->wd), plen), 0);
			}

			if (isdir(new_file) && !inotifytools_watch_recursively(new_file,
					events)) {
				fprintf(stderr, "Couldn't watch new directory %s: %s\n",
						new_file, strerror(inotifytools_error()));
			}
			free(new_file);
		} // IN_CREATE
		else if (event->mask & IN_MOVED_FROM) {
예제 #6
0
/*
    We need to poll the file watching mechanism at some low frequency.  Since
    we already have an internal timing system, we can use it to perform the poll
    instead of rolling another clock internal to the FileWatcher.
*/
FileWatcherImpl :: FileWatcherImpl() {
    if(!inotifytools_initialize()) {
        //ERROR initializing inotifytools
        //int err = inotifytools_error();
        printf("Couldn't initialize inotify.  Are you running Linux 2.6.13 or later, and was the\n option enabled when your kernel was compiled?  If so, \n something mysterious has gone wrong.");
        return;
    }
    enable();
}
예제 #7
0
파일: main.cpp 프로젝트: aalex/tempi
/*
 * libinotifytools example program.
 * Compile with g++ -linotifytools example.c
 */
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        std::cout << "Usage: ./run filename" << std::endl;
        return 1;
    }
    std::string fileName(argv[1]);

    if (! inotifytools_initialize())
    {
        std::cerr << "ERROR: "; // calling inotifytools_initialize(): ";
        std::cerr << strerror(inotifytools_error()) << std::endl;
        return 1;
    }
    int event_types = IN_CLOSE_WRITE; // IN_MODIFY

    std::cout << "Will watch file \"" << fileName << "\"." << std::endl;
    if (! inotifytools_watch_file(fileName.c_str(), event_types))
    {
        std::cerr << "ERROR: "; // << calling inotifytools_watch_file(\"" <<
        //    fileName << "\", " << event_types << "): ";
        std::cerr << strerror(inotifytools_error()) << std::endl;
        return 1;
    }

    //// set time format to 24 hour time, HH:MM:SS
    inotifytools_set_printf_timefmt((char *) "%T");

    // Output all events as "<timestamp> <path> <events>"
    struct inotify_event *event = NULL;
    std::cout << "watching file \"" << fileName << "\"..." << std::endl;
    while (true)
    {
        event = inotifytools_next_event(0); // 0 = non-blocking
        if (event)
        {
            std::cout << "EVENT: ";
            inotifytools_printf(event, (char *) "%T %w%f %e\n");
        }
        else
        {
            std::cout << "no event...\n";
        }
        event = NULL;
        // std::cout << "zzz ";
        //sleep(1);
    }
    return 0;
}
예제 #8
0
/*
 * libinotifytools example program.
 * Compile with gcc -linotifytools example.c
 */
int main() {
    // initialize and watch the entire directory tree from the current working
    // directory downwards for all events
    if ( !inotifytools_initialize()
            || !inotifytools_watch_recursively( ".", IN_ALL_EVENTS ) ) {
        fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
        return -1;
    }

    // set time format to 24 hour time, HH:MM:SS
    inotifytools_set_printf_timefmt( "%T" );

    // Output all events as "<timestamp> <path> <events>"
    struct inotify_event * event = inotifytools_next_event( -1 );
    while ( event ) {
        inotifytools_printf( event, "%T %w%f %e\n" );
        event = inotifytools_next_event( -1 );
    }
}
예제 #9
0
int
gfpm_icmonitor_init (void)
{
	if (!inotifytools_initialize())
	{
		inited = FALSE;
		return -1;
	}

	if (!inotifytools_watch_recursively(MON_DIR, IN_ALL_EVENTS))
	{
		inited = FALSE;
		return -1;
	}

	inited = TRUE;

	return 0;
}
예제 #10
0
void watch_limit()
{
    ENTER
    verify((0 == mkdir(TEST_DIR, 0700)) || (EEXIST == errno));

    INFO("Warning, this test may take a while\n");
#define INNER_LIMIT 16000
#define OUTER_LIMIT 5

    verify(inotifytools_initialize());
    inotifytools_initialize_stats();

    for (int j = 0; j < OUTER_LIMIT; ++j)
    {
        char fn[1024];
        int max = 0;
        for (int i = 0; i < INNER_LIMIT; ++i)
        {
            snprintf(fn, 1023, "%s/%d", TEST_DIR, i);
            int fd = creat(fn, 0700);
            verify(-1 != fd);
            verify(0 == close(fd));
            int ret = inotifytools_watch_file(fn, IN_ALL_EVENTS);
            verify(ret || inotifytools_error() == ENOSPC);
            if (ret)
            {
                max = i + 1;
                int wd = inotifytools_wd_from_filename(fn);
                verify(wd > 0);
                verify(!strcmp(fn, inotifytools_filename_from_wd(wd)));
            }
        }

        compare(inotifytools_get_num_watches(), max);

        for (int i = 0; i < max; ++i)
        {
            snprintf(fn, 1023, "%s/%d", TEST_DIR, i);
            verify(inotifytools_remove_watch_by_filename(fn));
        }
    }
    EXIT
}
예제 #11
0
void basic_watch_info()
{
    ENTER
    verify(inotifytools_initialize());
    verify(inotifytools_watch_file("/", IN_CLOSE));
    compare(inotifytools_wd_from_filename("/"), 1);
    compare(inotifytools_wd_from_filename("foobar"), -1);
    verify(!strcmp(inotifytools_filename_from_wd(1), "/"));
    verify(inotifytools_remove_watch_by_filename("/"));
    compare(inotifytools_wd_from_filename("/"), -1);
    compare(inotifytools_filename_from_wd(1), 0);
    verify(inotifytools_watch_file("/", IN_CLOSE));
    compare(inotifytools_wd_from_filename("/"), 2);
    compare(inotifytools_wd_from_filename("foobar"), -1);
    verify(!strcmp(inotifytools_filename_from_wd(2), "/"));
    verify(inotifytools_remove_watch_by_wd(2));
    compare(inotifytools_wd_from_filename("/"), -1);
    compare(inotifytools_filename_from_wd(2), 0);
    EXIT
}
예제 #12
0
int main(int argc, char ** argv)
{
	events = 0;
	int timeout = 0;
	int verbose = 0;
	zero = 0;
	int recursive = 0;
	char * fromfile = 0;
	sort = -1;
	done = false;
	char * regex = NULL;
	char * iregex = NULL;

	signal( SIGINT, handle_impatient_user );

	// Parse commandline options, aborting if something goes wrong
	if ( !parse_opts( &argc, &argv, &events, &timeout, &verbose, &zero, &sort,
	                 &recursive, &fromfile, &regex, &iregex ) ) {
		return EXIT_FAILURE;
	}

	if (
		(regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED) ) ||
		(iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED|
		                                                        REG_ICASE))
	) {
		fprintf(stderr, "Error in `exclude' regular expression.\n");
		return EXIT_FAILURE;
	}

	if ( !inotifytools_initialize() ) {
		fprintf(stderr, "Couldn't initialize inotify.  Are you running Linux "
		                "2.6.13 or later, and was the\n"
		                "CONFIG_INOTIFY option enabled when your kernel was "
		                "compiled?  If so, \n"
		                "something mysterious has gone wrong.  Please e-mail "
		                PACKAGE_BUGREPORT "\n"
		                " and mention that you saw this message.\n");
		return EXIT_FAILURE;
	}

	// Attempt to watch file
	// If events is still 0, make it all events.
	if ( !events )
		events = IN_ALL_EVENTS;

	FileList list = construct_path_list( argc, argv, fromfile );

	if (0 == list.watch_files[0]) {
		fprintf(stderr, "No files specified to watch!\n");
		return EXIT_FAILURE;
	}

	unsigned int num_watches = 0;
	unsigned int status;
	fprintf( stderr, "Establishing watches...\n" );
  int i;
	for ( i = 0; list.watch_files[i]; ++i ) {
		char const *this_file = list.watch_files[i];
		if ( recursive && verbose ) {
			fprintf( stderr, "Setting up watch(es) on %s\n", this_file );
		}

		if ( recursive ) {
			status = inotifytools_watch_recursively_with_exclude(
			                               this_file,
			                               events,
			                               list.exclude_files );
		}
		else {
			status = inotifytools_watch_file( this_file, events );
		}
		if ( !status ) {
			if ( inotifytools_error() == ENOSPC ) {
				fprintf(stderr, "Failed to watch %s; upper limit on inotify "
				                "watches reached!\n", this_file );
				fprintf(stderr, "Please increase the amount of inotify watches "
				        "allowed per user via `/proc/sys/fs/inotify/"
				        "max_user_watches'.\n");
			}
			else {
				fprintf(stderr, "Failed to watch %s: %s\n", this_file,
				        strerror( inotifytools_error() ) );
			}
			return EXIT_FAILURE;
		}
		if ( recursive && verbose ) {
			fprintf( stderr, "OK, %s is now being watched.\n", this_file );
		}
	}
	num_watches = inotifytools_get_num_watches();

	if ( verbose ) {
		fprintf( stderr, "Total of %d watches.\n",
		         num_watches );
	}
	fprintf( stderr, "Finished establishing watches, now collecting statistics.\n" );

	if ( timeout && verbose ) {
		fprintf( stderr, "Will listen for events for %d seconds.\n", timeout );
	}

	signal( SIGINT, handle_signal );
	signal( SIGHUP, handle_signal );
	signal( SIGTERM, handle_signal );
	if ( timeout ) {
		signal( SIGALRM, handle_signal );
		alarm( timeout );
	}
        signal( SIGUSR1, print_info_now );

	inotifytools_initialize_stats();
	// Now wait till we get event
	struct inotify_event * event;
	char * moved_from = 0;

	do {
		event = inotifytools_next_event( 0 );
		if ( !event ) {
			if ( !inotifytools_error() ) {
				return EXIT_TIMEOUT;
			}
			else if ( inotifytools_error() != EINTR ) {
				fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
				return EXIT_FAILURE;
			}
			else {
				continue;
			}
		}

		// if we last had MOVED_FROM and don't currently have MOVED_TO,
		// moved_from file must have been moved outside of tree - so unwatch it.
		if ( moved_from && !(event->mask & IN_MOVED_TO) ) {
			if ( !inotifytools_remove_watch_by_filename( moved_from ) ) {
				fprintf( stderr, "Error removing watch on %s: %s\n",
				         moved_from, strerror(inotifytools_error()) );
			}
			free( moved_from );
			moved_from = 0;
		}

		if ( recursive ) {
			if ((event->mask & IN_CREATE) ||
			    (!moved_from && (event->mask & IN_MOVED_TO))) {
				// New file - if it is a directory, watch it
				static char * new_file;

				nasprintf( &new_file, "%s%s",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );

				if ( isdir(new_file) &&
				    !inotifytools_watch_recursively( new_file, events ) ) {
					fprintf( stderr, "Couldn't watch new directory %s: %s\n",
					         new_file, strerror( inotifytools_error() ) );
				}
				free( new_file );
			} // IN_CREATE
			else if (event->mask & IN_MOVED_FROM) {
				nasprintf( &moved_from, "%s%s/",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );
				// if not watched...
				if ( inotifytools_wd_from_filename(moved_from) == -1 ) {
					free( moved_from );
					moved_from = 0;
				}
			} // IN_MOVED_FROM
			else if (event->mask & IN_MOVED_TO) {
				if ( moved_from ) {
					static char * new_name;
					nasprintf( &new_name, "%s%s/",
					           inotifytools_filename_from_wd( event->wd ),
					           event->name );
					inotifytools_replace_filename( moved_from, new_name );
					free( moved_from );
					moved_from = 0;
				} // moved_from
			}
		}

	} while ( !done );
        return print_info();
}
예제 #13
0
파일: notify.c 프로젝트: Ironlenny/fsnotify
int notify_removeWatch (char const * path) {
  inotifytools_initialize ();
  inotifytools_remove_watch_by_filename (path);
  return 1;
}
예제 #14
0
int main(int argc, char ** argv)
{
	int events = 0;
        int orig_events;
	bool monitor = false;
	int quiet = 0;
	unsigned long int timeout = 0;
	int recursive = 0;
	bool csv = false;
	bool daemon = false;
	bool syslog = false;
	char * format = NULL;
	char * timefmt = NULL;
	char * fromfile = NULL;
	char * outfile = NULL;
	char * regex = NULL;
	char * iregex = NULL;
	pid_t pid;
    int fd;

	// Parse commandline options, aborting if something goes wrong
	if ( !parse_opts(&argc, &argv, &events, &monitor, &quiet, &timeout,
	                 &recursive, &csv, &daemon, &syslog, &format, &timefmt,
                         &fromfile, &outfile, &regex, &iregex) ) {
		return EXIT_FAILURE;
	}

	if ( !inotifytools_initialize() ) {
		fprintf(stderr, "Couldn't initialize inotify.  Are you running Linux "
		                "2.6.13 or later, and was the\n"
		                "CONFIG_INOTIFY option enabled when your kernel was "
		                "compiled?  If so, \n"
		                "something mysterious has gone wrong.  Please e-mail "
		                PACKAGE_BUGREPORT "\n"
		                " and mention that you saw this message.\n");
		return EXIT_FAILURE;
	}

	if ( timefmt ) inotifytools_set_printf_timefmt( timefmt );
	if (
		(regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED) ) ||
		(iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED|
		                                                        REG_ICASE))
	) {
		fprintf(stderr, "Error in `exclude' regular expression.\n");
		return EXIT_FAILURE;
	}


	if ( format ) validate_format(format);

	// Attempt to watch file
	// If events is still 0, make it all events.
	if (events == 0)
		events = IN_ALL_EVENTS;
        orig_events = events;
        if ( monitor && recursive ) {
                events = events | IN_CREATE | IN_MOVED_TO | IN_MOVED_FROM;
        }

	FileList list = construct_path_list( argc, argv, fromfile );

	if (0 == list.watch_files[0]) {
		fprintf(stderr, "No files specified to watch!\n");
		return EXIT_FAILURE;
	}


    // Daemonize - BSD double-fork approach
	if ( daemon ) {

		pid = fork();
	        if (pid < 0) {
			fprintf(stderr, "Failed to fork1 whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
	        if (pid > 0) {
			_exit(0);
	        }
		if (setsid() < 0) {
			fprintf(stderr, "Failed to setsid whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
		signal(SIGHUP,SIG_IGN);
	        pid = fork();
	        if (pid < 0) {
	                fprintf(stderr, "Failed to fork2 whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
	        if (pid > 0) {
	                _exit(0);
	        }
		if (chdir("/") < 0) {
			fprintf(stderr, "Failed to chdir whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }

		// Redirect stdin from /dev/null
	        fd = open("/dev/null", O_RDONLY);
		if (fd != fileno(stdin)) {
			dup2(fd, fileno(stdin));
			close(fd);
		}

		// Redirect stdout to a file
	        fd = open(outfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
		if (fd < 0) {
                        fprintf( stderr, "Failed to open output file %s\n", outfile );
                        return EXIT_FAILURE;
                }
		if (fd != fileno(stdout)) {
			dup2(fd, fileno(stdout));
			close(fd);
		}

        // Redirect stderr to /dev/null
		fd = open("/dev/null", O_WRONLY);
	        if (fd != fileno(stderr)) {
	                dup2(fd, fileno(stderr));
	                close(fd);
	        }

        } else if (outfile != NULL) { // Redirect stdout to a file if specified
		fd = open(outfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
		if (fd < 0) {
			fprintf( stderr, "Failed to open output file %s\n", outfile );
			return EXIT_FAILURE;
		}
		if (fd != fileno(stdout)) {
			dup2(fd, fileno(stdout));
			close(fd);
		}
        }

        if ( syslog ) {
		openlog ("inotifywait", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON);
        }

	if ( !quiet ) {
		if ( recursive ) {
			output_error( syslog, "Setting up watches.  Beware: since -r "
				"was given, this may take a while!\n" );
		} else {
			output_error( syslog, "Setting up watches.\n" );
		}
	}

	// now watch files
	for ( int i = 0; list.watch_files[i]; ++i ) {
		char const *this_file = list.watch_files[i];
		if ( (recursive && !inotifytools_watch_recursively_with_exclude(
		                        this_file,
		                        events,
		                        list.exclude_files ))
		     || (!recursive && !inotifytools_watch_file( this_file, events )) ){
			if ( inotifytools_error() == ENOSPC ) {
				output_error( syslog, "Failed to watch %s; upper limit on inotify "
				                "watches reached!\n", this_file );
				output_error( syslog, "Please increase the amount of inotify watches "
				        "allowed per user via `/proc/sys/fs/inotify/"
				        "max_user_watches'.\n");
			}
			else {
				output_error( syslog, "Couldn't watch %s: %s\n", this_file,
				        strerror( inotifytools_error() ) );
			}
			return EXIT_FAILURE;
		}
	}

	if ( !quiet ) {
		output_error( syslog, "Watches established.\n" );
	}

	// Now wait till we get event
	struct inotify_event * event;
	char * moved_from = 0;

	do {
		event = inotifytools_next_event( timeout );
		if ( !event ) {
			if ( !inotifytools_error() ) {
				return EXIT_TIMEOUT;
			}
			else {
				output_error( syslog, "%s\n", strerror( inotifytools_error() ) );
				return EXIT_FAILURE;
			}
		}

		if ( quiet < 2 && (event->mask & orig_events) ) {
			if ( csv ) {
				output_event_csv( event );
			}
			else if ( format ) {
				inotifytools_printf( event, format );
			}
			else {
				inotifytools_printf( event, "%w %,e %f\n" );
			}
		}

		// if we last had MOVED_FROM and don't currently have MOVED_TO,
		// moved_from file must have been moved outside of tree - so unwatch it.
		if ( moved_from && !(event->mask & IN_MOVED_TO) ) {
			if ( !inotifytools_remove_watch_by_filename( moved_from ) ) {
				output_error( syslog, "Error removing watch on %s: %s\n",
				         moved_from, strerror(inotifytools_error()) );
			}
			free( moved_from );
			moved_from = 0;
		}

		if ( monitor && recursive ) {
			if ((event->mask & IN_CREATE) ||
			    (!moved_from && (event->mask & IN_MOVED_TO))) {
				// New file - if it is a directory, watch it
				static char * new_file;

				nasprintf( &new_file, "%s%s",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );

				if ( isdir(new_file) &&
				    !inotifytools_watch_recursively( new_file, events ) ) {
					output_error( syslog, "Couldn't watch new directory %s: %s\n",
					         new_file, strerror( inotifytools_error() ) );
				}
				free( new_file );
			} // IN_CREATE
			else if (event->mask & IN_MOVED_FROM) {
				nasprintf( &moved_from, "%s%s/",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );
				// if not watched...
				if ( inotifytools_wd_from_filename(moved_from) == -1 ) {
					free( moved_from );
					moved_from = 0;
				}
			} // IN_MOVED_FROM
			else if (event->mask & IN_MOVED_TO) {
				if ( moved_from ) {
					static char * new_name;
					nasprintf( &new_name, "%s%s/",
					           inotifytools_filename_from_wd( event->wd ),
					           event->name );
					inotifytools_replace_filename( moved_from, new_name );
					free( moved_from );
					moved_from = 0;
				} // moved_from
			}
		}

		fflush( NULL );

	} while ( monitor );

	// If we weren't trying to listen for this event...
	if ( (events & event->mask) == 0 ) {
		// ...then most likely something bad happened, like IGNORE etc.
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}