Inotify recursively how to do this?

I need to print events in a folder with several subfolders. how to do it recursively? Print the C ++ code. I am stuck!! Each time evet appears, I need to open a subfolder, take the file and copy it to another directory. I do not want to list all the subfolders every 2 seconds and find the files, if any. Ineffective. I need to use a folder with a monitor. Please, help

The director I want to control has several subfolders. Each subfolder has a different subfolder, which may contain a file at a time. MainFolder-> Subfolders-> each subfolder-> subfolder β†’ file.

Here is the code I have for this point:

/* */ #include <pthread.h> #include <unistd.h> #include <iostream> #include <sys/inotify.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/inotify.h> #include <vector> #include <string> #include <stdio.h> #include <stdlib.h> #include <pthread.h> using namespace std; vector<string> SS; void *print_message_function( void *ptr ); int main(int argc, char **argv ){ pthread_t t1; int fd,fd1,wd,wd1,i=0,i1=0,len=0,len1=0; int length; char pathname[100],buf[1024],buf1[1024]; int data; struct inotify_event *event; char *message1 = "Thread 1"; FILE *fr; // fd=inotify_init1(IN_NONBLOCK);//--rewrite fd = inotify_init(); /* watch /test directory for any activity and report it back to me */ wd=inotify_add_watch(fd,"/home/MainFoder/",IN_ALL_EVENTS); // int flag=0; // char*ev=""; //wd=inotifytools_watch_recursively_with_exclude("/home/MainFolder/",IN_ALL_EVENTS); while(1) { //sleep(30); //read 1024 bytes of events from fd into buf i=0; len=read(fd,buf,1024); while(i<len){ event=(struct inotify_event *) &buf[i]; /* watch /test directory for any activity and report it back to me */ /* check for changes */ { if((event->mask & IN_OPEN) ||(event->mask & IN_CREATE)) { printf("\n %s :was opened\n",event->name); SS.push_back(event->name); } } /* update index to start of next event */ i+=sizeof(struct inotify_event)+event->len; } vector<string>::const_iterator cii; for(cii=SS.begin(); cii!=SS.end(); cii++) { wd1 = watch_from_filename(*ci); } /* vector<string>::const_iterator cii; for(cii=SS.begin(); cii!=SS.end(); cii++) { cout <<"HERE:"<< *cii << endl; } */ int iret1, iret2; /* Create independent threads each of which will execute function */ iret1 = pthread_create( &t1, NULL, print_message_function, (void*) message1); } } void *print_message_function( void *ptr ) { vector<string>::const_iterator cii; for(cii=SS.begin(); cii!=SS.end(); cii++) { cout <<"HERE:"<< *cii << endl; std::string path=exec } } 
+4
source share
5 answers

This working Github example does what you are looking for: inotify-example.cpp

In CREATE events, the current wd (view descriptor) is added to the Watch object, as well as the indify_event wd and name components, (see sample). The class includes wd and name lookup methods in several ways.

This snippet shows how the CREATE / DELETE events are handled:

  if ( event->mask & IN_CREATE ) { current_dir = watch.get(event->wd); if ( event->mask & IN_ISDIR ) { new_dir = current_dir + "/" + event->name; wd = inotify_add_watch( fd, new_dir.c_str(), WATCH_FLAGS ); watch.insert( event->wd, event->name, wd ); total_dir_events++; printf( "New directory %s created.\n", new_dir.c_str() ); } else { total_file_events++; printf( "New file %s/%s created.\n", current_dir.c_str(), event->name ); } } else if ( event->mask & IN_DELETE ) { if ( event->mask & IN_ISDIR ) { new_dir = watch.erase( event->wd, event->name, &wd ); inotify_rm_watch( fd, wd ); total_dir_events--; printf( "Directory %s deleted.\n", new_dir.c_str() ); } else { current_dir = watch.get(event->wd); total_file_events--; printf( "File %s/%s deleted.\n", current_dir.c_str(), event->name ); } } 
+2
source

You can do this in two steps:

  • Find all the changes that interest you in the root directory, plus (if not already included) creations ( IN_CREATE ).
  • If the creation is a directory, follow its entire algorithm.
+1
source

I wrote the code for you. Now you need to make only one change to this code. Just specify the path to your directory in the main function.

 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/inotify.h> #include <limits.h> #include<sys/stat.h> #include<dirent.h> #include<time.h> #include<string.h> #include<unistd.h> #define MAX_EVENTS 1024 /*Max. number of events to process at one go*/ #define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/ #define EVENT_SIZE ( sizeof (struct inotify_event) ) /*size of one event*/ #define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/ void monitor(char *); int evnt_mon(char *); void main() { if(fork()==0) evnt_mon("./usssb");// give path of your directory which you want to monitor monitor("./usssb");// give path of your directory which you want to monitor while(1); } void monitor(char * rt_dir) { struct stat st; DIR *dirp; struct dirent *dp; char str[100][100]={ }; char temp[100]; char str1[500]=" "; int i=0,j=0,src_ret=9,src_ret1=9; strcpy(str1,rt_dir); dirp=opendir(str1); if(dirp==NULL) { perror("opendir"); return; } while(1) { dp=readdir(dirp); if(dp==NULL) break; if((strcmp(dp->d_name,".\0")==0) || (strcmp(dp->d_name,"..")==0)) continue; if((dp->d_type==DT_DIR)&&((strcmp(dp->d_name,".")!=0)&&(strcmp(dp->d_name,"..")!=0))) { strcat(str[i],str1); strcat(str[i],"/"); strcat(str[i],dp->d_name); if(fork()==0) { evnt_mon(str[i]); } i++; } } closedir(dirp); if(i>0) { for(j=0;j<i;j++) { monitor(str[j]); } } } int evnt_mon(char *argv) { int length, i = 0, wd; int fd; char buffer[BUF_LEN]; /* Initialize Inotify*/ fd = inotify_init(); if ( fd < 0 ) { perror( "Couldn't initialize inotify"); } /* add watch to starting directory */ wd = inotify_add_watch(fd, argv, IN_CREATE | IN_MODIFY | IN_DELETE); if (wd == -1) { printf("Couldn't add watch to %s\n",argv); } else { printf("Watching:: %s\n",argv); } /* do it forever*/ while(1) { i = 0; length = read( fd, buffer, BUF_LEN ); if ( length < 0 ) { perror( "read" ); } while ( i < length ) { struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; if ( event->len ) { if ( event->mask & IN_CREATE) { if (event->mask & IN_ISDIR) { printf( "The directory %s was Created in %s.\n", event->name,argv ); if(fork()==0) { char p[100]=" "; strcpy(p,argv); strcat(p,"/"); strcat(p,event->name); evnt_mon(p); } } else printf( "The file %s was Created with WD %d\n", event->name, event->wd ); } if ( event->mask & IN_MODIFY) { if (event->mask & IN_ISDIR) printf( "The directory %s was modified.\n", event->name ); else printf( "The file %s was modified with WD %d\n", event->name, event->wd ); } if ( event->mask & IN_DELETE) { if (event->mask & IN_ISDIR) printf( "The directory %s was deleted from %s.\n", event->name,argv ); else printf( "The file %s was deleted with WD %d\n", event->name, event->wd ); } i += EVENT_SIZE + event->len; } } } /* Clean up*/ inotify_rm_watch( fd, wd ); close( fd ); return 0; } 
+1
source

To solve the problem indicated by the ribara ("hole" :)). one possible solution that I can think of is that we can make a combination of "polling the directory" and "using inotify" ... i.e. every time a directory is found (directory only, do not do this for files):

  • add checkpoint for newly discovered directory to inotify
  • 'poll' (or 'scan') a newly discovered directory (man readdir ()) to see if there are already created files (files, directories). Perhaps these are the ones that are missing.

Please note that in order to create a β€œsealed” case, it is important that the order of the above steps is important. you need to add the observation point first, and not scan ... This ensures that the element is picked up by "scanning" or "inotizing" or both. In this case, you may also need to know about duplicate devices. that is, the same element can be obtained both by scanning and inotify

0
source

You can use fanotify API. It allows you to control the full mount. The only downside is that you need to be root.

0
source

Source: https://habr.com/ru/post/957933/


All Articles