int main(void)
{
    int i;
    pid_t pid;
    struct sigaction act;

    memset(&act, 0, sizeof(act));
    act.sa_handler = sig_usr1;
    sigaction(SIGUSR1, &act, NULL); 

    sp = (pid_t *)mmap(NULL, sizeof(pid_t) * 2,
        PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
        -1, 0);
    for(i = 0; i < 2; i++){
        if((pid = fork()) == 0)
            break;
        sp[i] = pid;
    }
    if(i == 0){ /* 1st child */
        while(1){
            disp_dir(".");
            pause();
        }
    }else if(i == 1){ /* 2nd child */
        watch_dir(".");
    }else{ /* parent */
        for(i = 0; i < 2; i++)
            wait(NULL);
    }

    return 0;
}
Esempio n. 2
0
int main(int argc, char **argv) {
  int inotify_fd;
  if (signal (SIGINT, signal_handler) == SIG_IGN) {
    signal (SIGINT, SIG_IGN);
  }
  inotify_fd = open_inotify_fd ();
  if (inotify_fd > 0) {
    queue_t q;
    q = queue_create(128);
    int wd;
    int index;
    wd = 0;
    printf("\n");
    for (index = 1; (index < argc) && (wd >= 0); index++) {
      wd = watch_dir (inotify_fd, argv[index], IN_ALL_EVENTS);
    }
    if (wd > 0) {
      process_inotify_events (q, inotify_fd);
    }
    printf ("\nTerminating\n");
    close_inotify_fd (inotify_fd);
    queue_destroy (q);
  }
  return 0;
}
Esempio n. 3
0
int watch_dir( struct monitor_t* mon, char* name, int recursive ) {

  struct stat fStat;
  if( stat( name, &fStat ) ) {
    perror( name );
    return 0;
  }

#ifdef DEBUG
  fprintf( stdout, "dir=[%s] ISREG=%d ISDIR=%d ISLNK=%d\n",
    name, S_ISREG( fStat.st_mode ), S_ISDIR( fStat.st_mode ), S_ISLNK( fStat.st_mode ) );
#endif

  int wd;
  wd = inotify_add_watch( mon->inotify_fd, name, IN_ALL_EVENTS );
  if( wd < 0 ) {
    perror( name );
    return 0;
  }
  mon->names[wd] = name;

  if( recursive && S_ISDIR( fStat.st_mode ) ) {
    DIR* pDir;
    struct dirent* pEnt;

    if( ( pDir = opendir( name ) ) == NULL ) {
      perror( name );
      return 0;
    }

    while( ( pEnt = readdir( pDir ) ) != NULL ) {
      if( !strncmp( ".", pEnt->d_name, 1 ) || !strncmp( "..", pEnt->d_name, 2 ) ) {
        continue;
      }

      char* eName = malloc( strlen( name ) + strlen( pEnt->d_name ) + 1 );
      sprintf( eName, "%s/%s", name, pEnt->d_name );

#ifdef DEBUG
      fprintf( stdout, "%s\n", eName );
#endif

      struct stat curStat;
      if( stat( eName, &curStat ) ) {
        perror( eName );
        return 0;
      }

      if( S_ISDIR( curStat.st_mode ) ) {
        watch_dir( mon, eName, recursive );
      } else {
        free( eName );
      }
    }
  }
  return 1;
}
Esempio n. 4
0
int add_all_folders(char *dirname,int type)
{
    struct dirent *ent = NULL;
    DIR *pDir;
    char temp_dir[1024];
    //int num ;
    int wd;

    wd = watch_dir (inotify_fd, dirname, MY_IN_ALL_EVENTS);

    pthread_mutex_lock(&mutex_allfolderlist);
    allfolderlist_tmp = (Folder *)malloc(sizeof(Folder));
    allfolderlist_tmp->type = type;
    allfolderlist_tmp->wd = wd;
    allfolderlist_tmp->name = (char *)malloc(sizeof(char)*(strlen(dirname)+1));
    strcpy(allfolderlist_tmp->name,dirname);
    allfolderlist_tmp->next = NULL;


    allfolderlist_tail->next = allfolderlist_tmp;
    allfolderlist_tail = allfolderlist_tmp;
    pthread_mutex_unlock(&mutex_allfolderlist);

    pDir=opendir(dirname);
    if(pDir != NULL )
    {
        while (NULL != (ent=readdir(pDir)))
        {
            if(!strcmp(ent->d_name,".") || !strcmp(ent->d_name,".."))
                continue;

            if( !strcmp(dirname,mount_path) && !strcmp(ent->d_name,"smartcloud") )
            {
                continue;
            }

            if(ent->d_type == DT_DIR)
            {
                memset(temp_dir,0,sizeof(temp_dir));
                sprintf(temp_dir,"%s/%s",dirname,ent->d_name);
                add_all_folders(temp_dir,type);

            }
        }
        closedir(pDir);
    }
    else
        printf("open %s fail \n",dirname);

    return wd;
}
Esempio n. 5
0
/*
 * Return a populated model.
 *
 * The result should be freed using g_object_unref.
 */
GtkListStore *
populated_model(char *dir)
{
	GtkListStore	*model;

	model = gtk_list_store_new(MODEL_CNT,
	    G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);

	if (populate(model, dir) == -1)
		errx(66, "failed to populate icon model from %s", dir);

	watch_dir(model, dir);

	return model;
}
Esempio n. 6
0
int main(int argc, char **argv)
{
    char root[512];
    char *dir;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <dir>\n", argv[0]);
        exit(1);
    }
    dir = argv[1];
    sprintf(root, "%s/%s", dirname(dir), basename(dir));
    _off = strlen(root) + 1;

    watch_dir(root, fcreat);
    return 0;
}
Esempio n. 7
0
File: fam.cpp Progetto: timn/fawkes
/** Watch a directory.
 * This adds the given directory recursively to this FAM.
 * @param dirpath path to directory to add
 */
void
FileAlterationMonitor::watch_dir(const char *dirpath)
{
#ifdef HAVE_INOTIFY
  DIR *d = opendir(dirpath);
  if ( d == NULL ) {
    throw Exception(errno, "Failed to open dir %s", dirpath);
  }

  uint32_t mask = IN_MODIFY | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF;
  int iw;

  //LibLogger::log_debug("FileAlterationMonitor", "Adding watch for %s", dirpath);
  if ( (iw = inotify_add_watch(__inotify_fd, dirpath, mask)) >= 0) {
    __inotify_watches[iw] = dirpath;

    dirent *de;
    while ( (de = readdir(d)) ) {
      std::string fp = std::string(dirpath) + "/" + de->d_name;
      struct stat st;
      if ( stat(fp.c_str(), &st) == 0 ) {
        if ( (de->d_name[0] != '.') && S_ISDIR(st.st_mode) ) {
	  try {
	    watch_dir(fp.c_str());
	  } catch (Exception &e) {
	    closedir(d);
	    throw;
	  }
	//} else {
	  //LibLogger::log_debug("SkillerExecutionThread", "Skipping file %s", fp.c_str());	  
	}
      } else {
	//LibLogger::log_debug("FileAlterationMonitor",
	//		     "Skipping watch on %s, cannot stat (%s)",
	//		     fp.c_str(), strerror(errno));
      }
    }
  } else {
    throw Exception(errno, "FileAlterationMonitor: cannot add watch for %s", dirpath);
  }

  closedir(d);
#endif
}
Esempio n. 8
0
int watch_dir (int fd, const char *dir)
{
	int *wd;
	char *dir_dup;
	DIR *fdir;
	struct dirent *dir_entry;
	char new_dir[PATH_MAX];
	no_watch_dir (fd, dir, 0);
	wd = (int *) malloc (sizeof (int));
	*wd = inotify_add_watch (fd, dir,
		IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM |
		IN_MOVED_TO | IN_CLOSE_WRITE);
	if (*wd < 0)
	{
		perror ("inotify_add_watch");
		exit (2);
	}
	else
	{
		dir_dup = strdup (dir);
		g_hash_table_insert (wds, wd, (gpointer) dir_dup);
		g_hash_table_insert (folders, (gpointer) dir_dup, wd);
	}
	if ((fdir = opendir (dir)) != NULL)
	{
		while ((dir_entry = readdir (fdir)) != NULL)
		{
			if (dir_entry->d_type == DT_DIR &&
				strcmp (dir_entry->d_name, ".") &&
				strcmp (dir_entry->d_name, ".."))
			{
				new_dir[0] = '\0';
				strcat (new_dir, dir);
				strcat (new_dir, "/");
				strcat (new_dir, dir_entry->d_name);
				watch_dir (fd, new_dir);
			}
		}
		closedir (fdir);
	}
	return *wd;
}
Esempio n. 9
0
int main(int argc, char *argv[])
{
    char *dir, root[512];

    if (argc < 3) {
        printf("Usage: %s <dir> <ns>\n", basename(argv[0]));
        exit(-1);
    }
    dir = argv[1];
    _ns = argv[2];

    sprintf(root, "%s/%s", dirname(dir), basename(dir));
    _offset = strlen(root) + 1;

    asc_init(&_as);
    watch_dir(root, fcreat);
    asc_exit(&_as);

    return 0;
}
Esempio n. 10
0
/*
 * Set up the window: build the interface, connect the signals, insert the
 * file icons.
 */
static GtkWidget *
prepare_window(char *dir, struct geometry *geometry, struct state *d)
{
	GtkBuilder	*builder;
	GtkWidget	*icons, *window, *directory_close, *file_open;
	GtkWidget	*directory_up, *directory_open, *help_about;
	GtkListStore	*model;

	builder = gtk_builder_new_from_file(INTERFACE_PATH);
	window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
	icons = GTK_WIDGET(gtk_builder_get_object(builder, "icons"));
	directory_up = GTK_WIDGET(gtk_builder_get_object(builder, "directory-up-menu-item"));
	directory_open = GTK_WIDGET(gtk_builder_get_object(builder, "directory-open-menu-item"));
	directory_close = GTK_WIDGET(gtk_builder_get_object(builder, "directory-close-menu-item"));
	file_open = GTK_WIDGET(gtk_builder_get_object(builder, "file-open-menu-item"));
	help_about = GTK_WIDGET(gtk_builder_get_object(builder, "help-about-menu-item"));

	d->icon_view = GTK_ICON_VIEW(icons);

	g_object_unref(builder);

	gtk_window_set_default_size(GTK_WINDOW(window), geometry->w,
	    geometry->h);
	gtk_window_move(GTK_WINDOW(window), geometry->x, geometry->y);
	gtk_window_set_title(GTK_WINDOW(window), dir);

	model = gtk_list_store_new(MODEL_CNT,
	    G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);
	if (populate(model, dir) == -1)
		err(66, "failed to populate icon model from %s", dir);

	watch_dir(model, dir);

	gtk_icon_view_set_text_column(GTK_ICON_VIEW(icons), 0);
	gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icons), 1);
	gtk_icon_view_set_model(GTK_ICON_VIEW(icons), GTK_TREE_MODEL(model));
	g_object_unref(model);

	gtk_widget_set_sensitive(directory_up, strlen(d->dir) > 1);

	/* Drag */
	gtk_drag_source_set(icons, GDK_BUTTON1_MASK,
	    dnd_targets, TARGET_COUNT,
	    GDK_ACTION_COPY | GDK_ACTION_MOVE);
	gtk_drag_source_add_text_targets(icons);
	gtk_drag_source_add_uri_targets(icons);
	g_signal_connect(icons, "drag-begin", G_CALLBACK(on_icons_drag_begin), d);
	g_signal_connect(icons, "drag-data-get", G_CALLBACK(on_icons_drag_data_get), d);
	g_signal_connect(icons, "drag-end", G_CALLBACK(on_icons_drag_end), d);

	/* Drop */
	gtk_drag_dest_set(icons, GTK_DEST_DEFAULT_ALL,
	    dnd_targets, TARGET_COUNT,
	    GDK_ACTION_COPY | GDK_ACTION_MOVE);
	gtk_drag_dest_add_text_targets(icons);
	gtk_drag_dest_add_uri_targets(icons);
	g_signal_connect(icons, "drag-motion", G_CALLBACK(on_icons_drag_motion), d);
	g_signal_connect(icons, "drag-leave", G_CALLBACK(on_icons_data_leave), d);
	g_signal_connect(icons, "drag-data-received", G_CALLBACK(on_icons_drag_data_received), d);

	/* Activations */
	g_signal_connect(icons, "item-activated", G_CALLBACK(on_icons_item_activated), d);
	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
	g_signal_connect(window, "configure-event", G_CALLBACK(on_window_configure_event), dir);
	g_signal_connect(directory_up, "activate", G_CALLBACK(on_directory_up_menu_item_activate), d);
	g_signal_connect(directory_open, "activate", G_CALLBACK(on_directory_open_menu_item_activate), d);
	g_signal_connect(directory_close, "activate", G_CALLBACK(gtk_main_quit), NULL);
	g_signal_connect(file_open, "activate", G_CALLBACK(on_file_open_menu_item_activate), d);
	g_signal_connect(help_about, "activate", G_CALLBACK(on_help_about_menu_item_activate), NULL);
	g_signal_connect(icons, "button-press-event", G_CALLBACK(on_icons_button_press_event), d);

	return window;
}
Esempio n. 11
0
int inotifyStart()
{
    int inotify_fd;
    int i;
    //Folders allfolderlist;

    keep_running = 1;
    need_restart_inotify = 0;
    add_new_watch_item = 0;

    /* First we open the inotify dev entry */
    inotify_fd = open_inotify_fd ();
    if (inotify_fd > 0)
    {

        queue_t q;
        q = queue_create (128);

        int wd;

        wd = 0;

        memset(&allfolderlist,0,sizeof(Folders));

        //printf("list num is %d\n",pathlist.number);

        for( i = 0 ; i < pathlist.number; i++)
        {
            //printf("list is %s\n",pathlist.folderlist[i].name);
            get_all_folders(pathlist.folderlist[i].name,&allfolderlist,allfolderlist.number);
        }

       //for( i = 0 ; i < number; i++)uploadFile


        //strcpy(allfolderlist.folderlist[0].name,dirname);
        //allfolderlist.number = 1;



        printf("\n");
        for( i = 0; (i<allfolderlist.number) && (wd >= 0);i++)
        {
            wd = watch_dir (inotify_fd, allfolderlist.folderlist[i].name, IN_ALL_EVENTS);
            //printf("minitor path is %s\n",allfolderlist.folderlist[i].name);
        }

        if (wd > 0)
        {

            process_inotify_events (q, inotify_fd);
        }
        printf ("\nTerminating\n");
        close_inotify_fd (inotify_fd);
        queue_destroy (q);

        if(need_restart_inotify == 1)
            inotifyStart();
    }
    return 0;
}
Esempio n. 12
0
File: main.c Progetto: l3ib/fsniper
int main(int argc, char** argv)
{
    int ifd, len = 0, i = 0, selectret = 0, maxfd, retryselect, pid;
    char buf[BUF_LEN]; 
    char *configdir;
    char *pidfilename;
    char *statusfilename;
    char *statusbin;
    char *error_str;
    char *version_str = PACKAGE_STRING;
    char *pbuf;
    char *filename;
    FILE *pidfile;
    FILE *statusfile;
    fd_set set;
    struct inotify_event *event;
    struct argument *argument = argument_new();
    struct pipe_list *pipe_list_cur;
    struct stat file_stat;
    struct watchnode *node;

    /* alloc pipe list */
    pipe_list_head = malloc(sizeof(struct pipe_list));
    pipe_list_head->next = NULL;

    /* set up signals for exiting/reaping */ 
    signal(SIGINT, &handle_quit_signal); 
    signal(SIGTERM, &handle_quit_signal);
    signal(SIGCHLD, &handle_child_signal);
    signal(SIGHUP, &handle_hup_signal);


    /* add command line arguments */
    argument_register(argument, "help", "Prints this help text.", 0);
    argument_register(argument, "version", "Prints version information.", 0);
    argument_register(argument, "daemon", "Run as a daemon.", 0);
    argument_register(argument, "verbose", "Turns on debug text.", 0);
    argument_register(argument, "sync", "Sync mode (for debugging).", 0);
    argument_register(argument, "log-to-stdout", "Deprecated, use \"--log-to=stdout\" instead", 0);
    argument_register(argument, "log-to", "Log messages with specified way. "
#ifdef USE_SYSLOG
                                "Can be: stdout, file, syslog. \"file\" by default.", 1);
#else
                                "Can be: stdout, file. \"file\" by default.", 1);
#endif

    if ((error_str = argument_parse(argument, argc, argv))) {
	fprintf(stderr, "Error in arguments: %s", error_str);
	free(error_str);
	return -1;
    }

    if (argument_exists(argument, "help")) {
	char *help_txt = argument_get_help_text(argument);
	printf("%s", help_txt);
	free(help_txt);
	return 0;
    }

    if (argument_exists(argument, "version")) {
	printf("%s\n", version_str);
	return 0;
    }

    if (argument_exists(argument, "verbose")) {
	verbose = 1;
    }

    if (argument_exists(argument, "daemon") && fork())
	return 0;

    if (argument_exists(argument, "sync"))
	syncmode = 1;


    if (argument_exists(argument, "log-to-stdout"))
        fprintf(stderr, "Warning, this option is deprecated, " \
                        "please use new syntax: \"--log-to=stdout\".\n");

    logtype = LOG_FILE;
    if (argument_exists(argument, "log-to") && \
        (log_arg = argument_get_value(argument, "log-to")) != NULL)
    {
        if      (strcmp(log_arg, "stdout") == 0)
            logtype = LOG_STDOUT;
#ifdef USE_SYSLOG
        else if (strcmp(log_arg, "syslog") == 0)
            logtype = LOG_SYS;
#endif
        else /* logtype already set to 'file' above */
            fprintf(stderr, "Warning, selected unknown logging type. " \
                            "Will use \"--log-to=file\" instead.\n");
    }

    /* get config dir (must free this) */
    configdir = get_config_dir();	

    /* if a config file has not been specified, use default */
    if (argument_get_extra(argument))
    {
	configfile = strdup(argument_get_extra(argument));
    }
    else
    {
	configfile = malloc (strlen(configdir) + strlen ("/config") + 1);
	sprintf(configfile, "%s/config", configdir);
    }

    argument_free(argument);
    free(configdir);

    if (access(configfile, R_OK) != 0)
    {
	fprintf(stderr, "error: could not open config file: %s\n", configfile);
	return -1;
    }

    /* create a pid file */
    pidfilename = get_pid_filename();
	
    if (stat(pidfilename, &file_stat) == 0) /* pidfile exists */
    {
	pidfile = fopen(pidfilename, "r");
		
	if (fscanf(pidfile, "%d", &pid) == 1) /* pidfile has a pid inside */
	{
	    char *binaryname;
	    char *scanformat; 
	    if ((binaryname = strrchr(argv[0], '/')) != NULL)
	    {
		binaryname++;
	    }
	    else
	    {
		binaryname = argv[0];
	    }

	    scanformat = malloc(strlen("Name:   %") + strlen(binaryname) + strlen("s") + 1);
	    statusfilename = malloc(strlen("/proc/") + 6 + strlen("/status") + 1);
	    sprintf(statusfilename, "/proc/%d/status", pid);

	    if (stat(statusfilename, &file_stat) != 0) /* write pid file if the process no longer exists */
	    {
		write_pid_file(pidfilename);
	    }
	    else /* process exists, so check owner and binary name */
	    {
		statusfile = fopen(statusfilename, "r");
		statusbin = malloc(strlen(binaryname) + 2); /* the binary name may start with "fsniper" but be longer */
		sprintf(scanformat, "Name:   %%%ds", strlen(binaryname) + 1);
		fscanf(statusfile, scanformat, statusbin);
		free(statusfilename);
		fclose(statusfile);
		fclose(pidfile);
				
		if (strcmp(binaryname, statusbin) == 0 && file_stat.st_uid == getuid())
		    /* exit if the process is fsniper and is owned by the current user */
		{
		    printf("%s: already running instance found with pid %d. exiting.\n", binaryname, pid);
		    exit(1);
		}
		else /* the pid file contains an old pid, one that isn't fsniper, or one not owned by the current user */
		{
		    write_pid_file(pidfilename);
		}
	    }
	}
	else /* pidfile is invalid */
	{
	    fclose(pidfile);
	    write_pid_file(pidfilename);
	}
    }
    else /* the pidfile doesn't exist */
    {
	write_pid_file(pidfilename);
    }
    free(pidfilename);

    /* start up log */
    if (!log_open())
    {
	fprintf(stderr, "Error: could not start log.\n");
	return -1;
    }

    ifd = inotify_init();
    if (ifd < 0)
    {
	perror("inotify_init");
	return -1;
    }

    if (verbose) log_write("Parsing config file: %s\n", configfile);
    config = keyval_parse_file(configfile);

    if ((error_str = keyval_get_error())) {
        fprintf(stderr, "%s", error_str);
        free(error_str);
        exit(1);
    }

    validate_config(config);

    /* add nodes to the inotify descriptor */
    g_watchnode = add_watches(ifd);

    /* wait for events and then handle them */
    while (1)
    {		
	/* set up fds and max */
	FD_ZERO(&set);
	FD_SET(ifd, &set);
	maxfd = ifd;
	for (pipe_list_cur = pipe_list_head->next; pipe_list_cur; pipe_list_cur = pipe_list_cur->next)
	{
	    FD_SET(pipe_list_cur->pfd[0], &set);
	    if (pipe_list_cur->pfd[0] > maxfd)
		maxfd = pipe_list_cur->pfd[0];
	}

	retryselect = 1;
	while (retryselect)
	{
	    /* use select to get activity on any of the fds */
	    selectret = select(maxfd + 1, &set, NULL, NULL, NULL);

	    if (selectret == -1)
	    {
		if (errno == EINTR)
		    retryselect = 1;
		else
		    handle_quit_signal(-2);
	    } else
		retryselect = 0;
	}
		
	/* handle any events on the inotify fd */
	if (FD_ISSET(ifd, &set))
	{
	    len = read(ifd, buf, BUF_LEN);
	    while (i < len)
	    {
		event = (struct inotify_event *) &buf[i];
		if (event->len && (event->mask & IN_CLOSE_WRITE || event->mask & IN_MOVED_TO))
		{
		    /* if sync mode, just call handle_exec */
		    if (syncmode == 1)
		    {
			handle_event(event, fileno(_logfd));
		    }
		    else
		    {
			/* create new pipe_list entry */
			for (pipe_list_cur = pipe_list_head; pipe_list_cur->next != NULL; pipe_list_cur = pipe_list_cur->next) {}

			pipe_list_cur->next = malloc(sizeof(struct pipe_list));
			pipe_list_cur->next->next = NULL;

			/* create pipe */
			pipe(pipe_list_cur->next->pfd);

			if (fork() == 0) 
			{
			    /* child, close 0 */
			    close(pipe_list_cur->next->pfd[0]);					
			    log_close();
			    signal(SIGINT, &handle_child_quit_signal);
			    signal(SIGTERM, &handle_child_quit_signal);
			    handle_event(event, pipe_list_cur->next->pfd[1]);
			} else {
			    /* parent, close 1 */
			    close(pipe_list_cur->next->pfd[1]);
			}
		    }
		}
                else if (event->len && (event->mask & IN_CREATE && event->mask & IN_ISDIR))
                {
                    for (node = g_watchnode->next; node; node = node->next)
                        if (node->wd == event->wd)
                            break;

                    if (node)
                    {
                        /* combine the name inotify gives with the full path to the file */
                        filename = malloc(strlen(node->path) + strlen("/") + strlen(event->name) + 1);
                        sprintf(filename, "%s/%s", node->path, event->name);
                        watch_dir(node, ifd, strdup(filename), node->section);
                        free(filename);
                    }
                }
		else if (event->len && (event->mask & IN_DELETE && event->mask & IN_ISDIR))
                {
                    for (node = g_watchnode->next; node; node = node->next)
                        if (node->wd == event->wd)
                            break;

                    if (node)
                    {
                        /* combine the name inotify gives with the full path to the file */
                        filename = malloc(strlen(node->path) + strlen("/") + strlen(event->name) + 1);
                        sprintf(filename, "%s/%s", node->path, event->name);
                        unwatch_dir(filename, ifd);
                        free(filename);
                    }
                }
                i += EVENT_SIZE + event->len;
            }
	    i = 0;
	}
		
	/* now lets see if we have any pipe activity */
	pipe_list_cur = pipe_list_head->next;
	while (pipe_list_cur)
	{
	    if (FD_ISSET(pipe_list_cur->pfd[0], &set))
	    {
		len = read(pipe_list_cur->pfd[0], buf, BUF_LEN);
		if (len == 0)
		{
		    close(pipe_list_cur->pfd[0]);
		    /* remove this item from the list */
		    pipe_list_cur = pipe_list_remove(pipe_list_head, pipe_list_cur);
					
		} else {
		    /* print it somewhere */
		    pbuf = malloc(len + 1);
		    snprintf(pbuf, len, "%s", buf);
		    log_write("%s\n", pbuf);
		    free(pbuf);
		    pipe_list_cur = pipe_list_cur->next;
		}
	    } else {
		pipe_list_cur = pipe_list_cur->next;

	    }


	}
    }
}
Esempio n. 13
0
int main (int argc, char **argv)
{
	int done=0;
	int fd;
	char dir[PATH_MAX];
	char *dir_watch;

	if (argc <= 1)
	{
		fprintf (stderr, "%s <folder>\n", basename (argv[0]));
		exit (1);
	}

	dir_watch = strdup (argv[1]);
	wds = g_hash_table_new_full (g_int_hash, g_int_equal, free, free);
	folders = g_hash_table_new (g_str_hash, g_str_equal);

	fd = inotify_init();
	if (fd < 0)
	{
        perror ("inotify_init");
		exit (1);
	}
	watch_dir (fd, dir_watch);

	struct timeval time;
	fd_set rfds, irfds;
	int ret;


	/* zero-out the fd_set */
	FD_ZERO (&rfds);

	/* add the inotify fd to the fd_set */
	FD_SET (fd, &rfds);
	irfds = rfds;
	while (!done)
	{
		/* timeout after five seconds */
		time.tv_sec = 5;
		time.tv_usec = 0;
		rfds = irfds;
		ret = select (fd + 1, &rfds, NULL, NULL, &time);
		if (ret < 0)
		{
			perror ("select");
			exit (1);
		}
		else if (!ret)
			continue;
		else if (FD_ISSET (fd, &rfds))
		{
			/* inotify events are available! */
			char buf[BUF_LEN];
			int len, i = 0, retry = 1;
			while (retry)
			{
				retry = 0;
				len = read (fd, buf, BUF_LEN);
				i=0;
				if (len < 0)
				{
					if (errno == EINTR)
					{
						retry = 1;
						continue;
					}
					else
					{
						perror ("read");
						exit (1);
					}
				}
				else if (!len)
					fprintf (stderr, "BUF_LEN too small?\n");
				else while (i < len)
				{
					struct inotify_event *event;

					event = (struct inotify_event *) &buf[i];
					if (event->mask & IN_ISDIR)
					{
						strcpy (dir, g_hash_table_lookup (wds, &(event->wd)));
						if (event->len)
						{
							strcat (dir, "/");
							strcat (dir, event->name);
						}
						if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO)
							watch_dir (fd, dir);
						if (event->mask & IN_DELETE || event->mask & IN_MOVED_FROM)
							no_watch_dir (fd, dir, 1);
					}
					else
					{
						if (event->mask & IN_CLOSE_WRITE)
						{
							/* new file */
							strcpy (dir, g_hash_table_lookup (wds, &(event->wd)));
							if (event->len)
							{
								strcat (dir, "/");
								strcat (dir, event->name);
							}
							printf ("%s\n", dir);
							fflush (stdout);
						}
						else if (event->mask & IN_IGNORED)
						{
							const char *dir_ignored = g_hash_table_lookup (wds, &(event->wd));
							if (dir_ignored)
							{
								if (strcmp (dir_ignored, dir_watch) == 0)
									done = 1;
							}
						}

					}
					i += EVENT_SIZE + event->len;
				}
			}
		}
	}

	g_hash_table_destroy (folders);
	g_hash_table_foreach (wds, close_wd, &fd);
	g_hash_table_destroy (wds);


	close (fd);
	free (dir_watch);
	return 0;
}
Esempio n. 14
0
File: fam.cpp Progetto: timn/fawkes
/** Process events.
 * Call this when you want file events to be processed.
 * @param timeout timeout in milliseconds to wait for an event, 0 to just check
 * and no wait, -1 to wait forever until an event is received
 */
void
FileAlterationMonitor::process_events(int timeout)
{
#ifdef HAVE_INOTIFY
  // Check for inotify events
  __interrupted = false;
  std::map<std::string, unsigned int> events;

  pollfd ipfd[2];
  ipfd[0].fd = __inotify_fd;
  ipfd[0].events = POLLIN;
  ipfd[0].revents = 0;
  ipfd[1].fd = __pipe_fds[0];
  ipfd[1].events = POLLIN;
  ipfd[1].revents = 0;
  int prv = poll(ipfd, 2, timeout);
  if ( prv == -1 ) {
    if ( errno != EINTR ) {
      //LibLogger::log_error("FileAlterationMonitor",
	//		   "inotify poll failed: %s (%i)",
	//		   strerror(errno), errno);
    } else {
      __interrupted = true;
    }
  } else while ( !__interrupted && (prv > 0) ) {
    // Our fd has an event, we can read
    if ( ipfd[0].revents & POLLERR ) {      
      //LibLogger::log_error("FileAlterationMonitor", "inotify poll error");
    } else if (__interrupted) {
      // interrupted
      return;
    } else {
      // must be POLLIN
      int bytes = 0, i = 0;

      if ((bytes = read(__inotify_fd, __inotify_buf, __inotify_bufsize)) != -1) {
	while (!__interrupted && (i < bytes)) {
	  struct inotify_event *event = (struct inotify_event *) &__inotify_buf[i];

	  if (event->mask & IN_IGNORED) {
	    i += sizeof(struct inotify_event) + event->len;
	    continue;
	  }

	  bool valid = true;
	  if (! (event->mask & IN_ISDIR)) {
	    for (__rxit = __regexes.begin(); __rxit != __regexes.end(); ++__rxit) {
              if (event->len > 0 &&
		  (regexec(*__rxit, event->name, 0, NULL, 0) == REG_NOMATCH))
	      {
		valid = false;
		break;
	      }
	    }
	  }

	  if ( valid ) {
	    if (event->len == 0) {
	      if (__inotify_watches.find(event->wd) != __inotify_watches.end()) {
		if (events.find(__inotify_watches[event->wd]) != events.end()) {
		  events[__inotify_watches[event->wd]] |= event->mask;
		} else {
		  events[__inotify_watches[event->wd]]  = event->mask;
		}
	      }
	    } else {
	      if (events.find(event->name) != events.end()) {
		events[event->name] |= event->mask;
	      } else {
		events[event->name]  = event->mask;
	      }
	    }
	  }

	  if (event->mask & IN_DELETE_SELF) {
	    //printf("Watched %s has been deleted", event->name);
	    __inotify_watches.erase(event->wd);
	    inotify_rm_watch(__inotify_fd, event->wd);
	  }

	  if (event->mask & IN_CREATE) {
	    // Check if it is a directory, if it is, watch it
	    std::string fp = __inotify_watches[event->wd] + "/" + event->name;
	    if (  (event->mask & IN_ISDIR) && (event->name[0] != '.') ) {
	      /*
	      LibLogger::log_debug("FileAlterationMonitor",
				   "Directory %s has been created, "
				   "adding to watch list", event->name);
	      */
	      try {
		watch_dir(fp.c_str());
	      } catch (Exception &e) {
		//LibLogger::log_warn("FileAlterationMonitor", "Adding watch for %s failed, ignoring.", fp.c_str());
		//LibLogger::log_warn("FileAlterationMonitor", e);
	      }
	    }
	  }

	  i += sizeof(struct inotify_event) + event->len;
	}

      }
    }

    // Give some time to wait for related events to pipe in, we still
    // do not guarantee to merge them all, but we do a little better
    usleep(1000);
    prv = poll(ipfd, 2, 0);
  }

  std::map<std::string, unsigned int>::const_iterator e;
  for (e = events.begin(); e != events.end(); ++e) {
    //LibLogger::log_warn("FileAlterationMonitor", "Event %s %x",
    //			e->first.c_str(), e->second);
    for (__lit = __listeners.begin(); __lit != __listeners.end(); ++__lit) {
      (*__lit)->fam_event(e->first.c_str(), e->second);
    }
  }

#else
  //LibLogger::log_error("FileAlterationMonitor",
//		       "inotify support not available, but "
//		       "process_events() was called. Ignoring.");
  throw Exception("FileAlterationMonitor: inotify support not available, "
		  "but process_events() was called.");
#endif
}
Esempio n. 15
0
/* This method does the work of determining what happened,
   then allows us to act appropriately
 */
void handle_event(queue_entry_t event, int fd)
{
	/* If the event was associated with a filename, we will store it here */
	char *cur_event_filename = NULL;
	char *cur_event_file_or_dir = NULL;
	/* This is the watch descriptor the event occurred on */
	int cur_event_wd = event->inot_ev.wd;
	int cur_event_cookie = event->inot_ev.cookie;
	unsigned long flags;
	time_t t;
	struct tm *tmptr; 

	char query[69535];
	char time_str[80];
	char filename[1024];
	char file_content[65535];

	int len;
	char * end;

	FILE *fp; 

	time(&t);
	tmptr = localtime(&t);
	strftime(time_str, sizeof(time_str), "%F %T", tmptr);

	if(event->inot_ev.len){
		cur_event_filename = event->inot_ev.name;
	}
	if(event->inot_ev.mask & IN_ISDIR){
		cur_event_file_or_dir = "Dir";
	} else {
		cur_event_file_or_dir = "File";
		sprintf(filename, "%s/%s", inotify_struct[cur_event_wd].dir_name, cur_event_filename);
	}
	sprintf(filename, "%s/%s", inotify_struct[cur_event_wd].dir_name, cur_event_filename); 
	flags = event->inot_ev.mask & ~(IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED );

	/* Perform event dependent handler routines */
	/* The mask is the magic that tells us what file operation occurred */
	switch (event->inot_ev.mask & (IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED)) {
		/* File was accessed */
		case IN_ACCESS:
			printf ("ACCESS: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd);
			//syslog(LOG_INFO, "ACCESS: %s \"%s\"\n", cur_event_file_or_dir, filename);
			break;
			/* File was modified */
		case IN_MODIFY:
			printf ("MODIFY: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd); 
			char *p = strrchr(filename, '.');
			if(p && (strcmp(p, file_suf) == 0) && check_md5_file(filename, cur_event_wd)){
				if (!(fp = fopen(filename,"rb"))) {
					printf("Can not open %s this file!\n",filename);
				}
				len = fread(file_content, 1, 65535, fp);
				fclose(fp);
				memset(query, '\0', 1024); 
				sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, content) values ('%s', %d, '%s', '%s', '%s', '%s', ", host_name, pid, filename, cur_event_file_or_dir, "MODIFY", time_str);
				end = query;
				end += strlen(query);
				*end++ = '\'';
				end += mysql_real_escape_string(&mysql, end, file_content, len);
				*end++ = '\'';
				*end++ = ')';
				*end++ = ';';
				mysql_real_query(&mysql, query, (unsigned int)(end - query));
				printf("%s\n",query);
			} else {
				sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time) values ('%s', %d, '%s', '%s', '%s', '%s')", host_name, pid, filename, cur_event_file_or_dir, "MODIFY", time_str);
				printf("%s\n",query);
				mysql_query(&mysql, query);
			}
			//print_inotify_struct(cur_event_wd);
			break;

			/* File changed attributes */
		case IN_ATTRIB:
			printf("ATTRIB: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd);
			break;

			/* File open for writing was closed */
		case IN_CLOSE_WRITE:
			printf("CLOSE_WRITE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd);
			break;

			/* File open read-only was closed */
		case IN_CLOSE_NOWRITE:
			printf("CLOSE_NOWRITE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd);
			break;

			/* File was opened */
		case IN_OPEN:
			printf ("OPEN: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd);
			break;

			/* File was moved from X */
		case IN_MOVED_FROM:
			printf ("MOVED_FROM: %s \"%s\" on WD #%i. Cookie=%d\n", cur_event_file_or_dir, filename, cur_event_wd, cur_event_cookie);
			sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, cookie) values ('%s', %d, '%s', '%s', '%s', '%s', %d);", host_name, pid, filename, cur_event_file_or_dir, "MOVE_FROM", time_str, cur_event_cookie);
			mysql_query(&mysql, query);

			if( event->inot_ev.mask & IN_ISDIR ){
			} else {
				char *p = strrchr(filename, '.');
				if(p && (strcmp(p, file_suf) == 0)){
					delete_file_hash(filename, cur_event_wd);
					//print_inotify_struct(cur_event_wd);
				}
			} 
			break;

			/* File was moved to X */
		case IN_MOVED_TO:
			printf ("MOVED_TO: %s \"%s\" on WD #%i. Cookie=%d\n", cur_event_file_or_dir, filename, cur_event_wd, cur_event_cookie);
			sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, cookie) values ('%s', %d, '%s', '%s', '%s', '%s', %d);", host_name, pid, filename, cur_event_file_or_dir, "MOVE_TO", time_str, cur_event_cookie);
			mysql_query(&mysql, query);
			if ( event->inot_ev.mask & IN_ISDIR ){ 
			} else {
				char *p = strrchr(filename, '.');
				if(p && (strcmp(p, file_suf) == 0)){
					add_file_hash(filename, cur_event_wd);
					//print_inotify_struct(cur_event_wd);
				}
			}
			break;

			/* Subdir or file was deleted */
		case IN_DELETE:
			printf ("DELETE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, filename, cur_event_wd);
			sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time) values ('%s', %d, '%s', '%s', '%s', '%s');", host_name, pid, filename, cur_event_file_or_dir, "DELETE", time_str);
			mysql_query(&mysql, query);

			if(event->inot_ev.mask & IN_ISDIR){
			} else {
				char *p = strrchr(filename, '.');
				if(p && (strcmp(p, file_suf) == 0)){
					delete_file_hash(filename, cur_event_wd);
					//print_inotify_struct(cur_event_wd);
				}
			}
			break;

			/* Subdir or file was created */
		case IN_CREATE:
			printf ("CREATE: %s \"%s\"\n", cur_event_file_or_dir, filename);	

			if ( event->inot_ev.mask & IN_ISDIR ){       
				watch_dir (fd, filename, IN_MODIFY | IN_MOVE | IN_CREATE | IN_DELETE );
			} else {
				char *p = strrchr(filename, '.');
				if(p && (strcmp(p, file_suf) == 0)){
					add_file_hash(filename, cur_event_wd);
					print_inotify_struct(cur_event_wd);
					if (!(fp = fopen(filename,"rb"))) {
						printf("Can not open %s this file!\n",filename);
					}
					len = fread(file_content, 1, 65535, fp);
					fclose(fp);
					memset(query, '\0', 1024); 
					sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time, content) values ('%s', %d, '%s', '%s', '%s', '%s', ", host_name, pid, filename, cur_event_file_or_dir, "CREATE", time_str);
					end = query;
					end += strlen(query);
					*end++ = '\'';
					end += mysql_real_escape_string(&mysql, end, file_content, len);
					*end++ = '\'';
					*end++ = ')';
					mysql_real_query(&mysql, query, (unsigned int)(end - query));
					printf("%s\n",query);
					break;
				}  
			}
			sprintf(query, "insert into file (hostname, pid, file_name, file_type, action, time) values ('%s', %d, '%s', '%s', '%s', '%s');", host_name, pid, filename, cur_event_file_or_dir, "CREATE", time_str);
			mysql_query(&mysql, query);

			break;

			/* Watched entry was deleted */
		case IN_DELETE_SELF:
			printf ("DELETE_SELF: %s \"%s\" on WD #%i\n",cur_event_file_or_dir, filename, cur_event_wd);
			break;

			/* Watched entry was moved */
		case IN_MOVE_SELF:
			printf ("MOVE_SELF: %s \"%s\" on WD #%i\n",cur_event_file_or_dir, filename, cur_event_wd);
			break;

			/* Backing FS was unmounted */
		case IN_UNMOUNT:
			printf ("UNMOUNT: %s \"%s\" on WD #%i\n",cur_event_file_or_dir, filename, cur_event_wd);
			break;

			/* Too many FS events were received without reading them
			   some event notifications were potentially lost.  */
		case IN_Q_OVERFLOW:
			printf ("Warning: AN OVERFLOW EVENT OCCURRED: \n");
			break;

			/* Watch was removed explicitly by inotify_rm_watch or automatically
			   because file was deleted, or file system was unmounted.  */
		case IN_IGNORED:
			watched_items--;
			printf ("IGNORED: WD #%d\n", cur_event_wd);
			printf("Watching = %d items\n",watched_items); 
			break;

			/* Some unknown message received */
		default:
			printf ("UNKNOWN EVENT \"%X\" OCCURRED for file \"%s\" on WD #%i\n",
					event->inot_ev.mask, cur_event_filename, cur_event_wd);
			break;
	}
	/* If any flags were set other than IN_ISDIR, report the flags */
	if (flags & (~IN_ISDIR))
	{
		flags = event->inot_ev.mask;
		printf ("Flags=%lX\n", flags);
	}
}
Esempio n. 16
0
int main (int argc, char **argv)
{
  /* This is the file descriptor for the inotify watch */
  int inotify_fd;

  keep_running = 1;

  /* Set a ctrl-c signal handler */
  if (signal (SIGINT, signal_handler) == SIG_IGN)
    {
      /* Reset to SIG_IGN (ignore) if that was the prior state */
      signal (SIGINT, SIG_IGN);
    }

  /* First we open the inotify dev entry */
  inotify_fd = open_inotify_fd ();
  if (inotify_fd > 0)
    {

      /* We will need a place to enqueue inotify events,
         this is needed because if you do not read events
         fast enough, you will miss them. This queue is 
         probably too small if you are monitoring something
         like a directory with a lot of files and the directory 
         is deleted.
       */
      queue_t q;
      q = queue_create (128);

      /* This is the watch descriptor returned for each item we are 
         watching. A real application might keep these for some use 
         in the application. This sample only makes sure that none of
         the watch descriptors is less than 0.
       */
      int wd;


      /* Watch all events (IN_ALL_EVENTS) for the directories and 
         files passed in as arguments.
         Read the article for why you might want to alter this for 
         more efficient inotify use in your app.      
       */
      int index;
      wd = 0;
      printf("\n");
      for (index = 1; (index < argc) && (wd >= 0); index++) 
	{
	  wd = watch_dir (inotify_fd, argv[index], IN_ALL_EVENTS);
	  /*wd = watch_dir (inotify_fd, argv[index], IN_ALL_EVENTS & ~(IN_CLOSE | IN_OPEN) ); */
	}

      if (wd > 0) 
	{
	  /* Wait for events and process them until a 
             termination condition is detected
           */
	  process_inotify_events (q, inotify_fd);
	}
      printf ("\nTerminating\n");

      /* Finish up by closing the fd, destroying the queue,
         and returning a proper code
       */
      close_inotify_fd (inotify_fd);
      queue_destroy (q);
    }
  return 0;
}
Esempio n. 17
0
static int  inotify_test(void)
{
	int inotify_fd;
	DIR *director_watch;
	struct dirent *de;


	inotify_fd = open_inotify_fd();
	if (inotify_fd > 0) {
		/* We will need a place to enqueue inotify events,
		   this is needed because if you do not read events
		   fast enough, you will miss them. This queue is
		   probably too small if you are monitoring something
		   like a directory with a lot of files and the directory
		   is deleted.
		*/
		queue_t q;
		q = queue_create(128);

		/* This is the watch descriptor returned for each item we are
	           watching. A real application might keep these for some use
	           in the application. This sample only makes sure that none of
	           the watch descriptors is less than 0.
	        */


		/* Watch all events (IN_ALL_EVENTS) for the directories and
	           files passed in as arguments.
	           Read the article for why you might want to alter this for
	           more efficient inotify use in your app.
	        */
		int index;
		wd = 0;
		printf("\n");
		/* for (index = 1; (index < argc) && wd >= 0); index++) { */
		/* 	wd = watch_dir(inotify_fd, argv[index], IN_ALL_EVENTS); */
		/* } */

		director_watch = opendir(WATCH_PATH);
		if (director_watch == 0)
			return;
		while((de = readdir(director_watch)) != 0) {
			if(bad_name(de->d_name))
				   continue;
			snprintf(busname, sizeof busname, "%s/%s", WATCH_PATH, de->d_name);		  

			int wd = watch_dir(inotify_fd, busname, IN_DELETE | IN_CREATE);
			if (wd > 0){
				LOG("chiplua add %s", busname);
			}
			process_inotify_events(q, inotify_fd);
		}	     
		return 0;
	}
	
	/* wd = watch_dir(inotify_fd, WATCH_PATH, IN_DELETE | IN_CREATE); */
	/* if (wd > 0) { */
	/* 	/\* Wait for events and process them until a */
	/* 	   temination condition is detected. */
	/* 	*\/ */
	/* 	process_inotify_events(q, inotify_fd); */
	/* } */
	/* printf("\nTerminating\n"); */

	/* /\* Finish up by closing the fd, destroying the queue, */
	/*    and returning a proper code. */
	/* *\/ */
	/* close_inotify_fd(inotify_fd); */
	/*queue_destroy(q); */
	
}