int monitor() { // Buffer for File Descriptor char buffer[EVENT_BUF_LEN]; // inotify_event of the event struct inotify_event *event = NULL; // The path of touched directory or file char *path = NULL; int len; // Wait for events while (len = read(fd, buffer, EVENT_BUF_LEN)) { if (len < 0) { printf("Read() error"); return -1; } // index of the event into file descriptor int i = 0; while (i < len) { // inotify_event of the event event = (struct inotify_event*) &buffer[i]; // Build the full path of the directory or symbolic link LIST_NODE *node = get_from_wd(event->wd); if (node != NULL) { WD_DATA *wd_data = (WD_DATA *) node->data; path = malloc(sizeof(char) * (strlen(wd_data->path) + strlen(event->name) + 2)); strcpy(path, wd_data->path); strcat(path, event->name); strcat(path, "/"); } else continue; // IN_CREATE Event if (event->mask & IN_CREATE) { // Check if it is a folder. If yes watch it if (event->mask & IN_ISDIR) watch(path, 0); else { // check if it is a link. if yes watch it. DIR *dir_stream = opendir(path); if (dir_stream != NULL) { // resolve symbolic link char *realpath = resolve_real_path(path); watch(realpath, 1); } closedir(dir_stream); } } // IN_DELETE event else if (event->mask & IN_DELETE) { // Starts build the full path of the // Check if it is a folder. If yes unwatch it if (event->mask & IN_ISDIR) unwatch(path); else { // Resolve the real path of the symbolic link char* resolved = resolve_real_path(path); printf("PATH TO DELETE: %s\n", resolved); } } // Next event i += EVENT_SIZE + event->len; } } return 0; }
void watch(char *path, bool is_link) { // Add initial path to the watch list LIST_NODE *node = get_from_path(path); if (node == NULL) node = add_to_watch_list(path); // Searchs and increments the reference counter // of the link in list_link if (is_link) add_to_link_list(node); // Temporary list to perform breath-first-search LIST *list = list_init(); list_push(list, (void *) path); // Traverse directory DIR *dir_stream; struct dirent *dir; while (list->first != NULL) { // Directory to watch char *p = (char*) list_pop(list); // Traverse directory dir_stream = opendir(p); while (dir = readdir(dir_stream)) { if (dir->d_type == DT_DIR && strcmp(dir->d_name, ".") == 1 && strcmp(dir->d_name, "..") == 1) { char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 2)); strcpy(path_to_watch, p); strcat(path_to_watch, dir->d_name); strcat(path_to_watch, "/"); // Add to the watch list if (get_from_path(path_to_watch) == NULL) add_to_watch_list(path_to_watch); // Continue directory traversing list_push(list, (void*) path_to_watch); } // Resolve symbolic link else if (dir->d_type == DT_LNK) { char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 1)); strcpy(path_to_watch, p); strcat(path_to_watch, dir->d_name); char *real_path = resolve_real_path(path_to_watch); // Test for: // 1. is a real path // 2. is a directory if (real_path != NULL && opendir(real_path) != NULL) { // Add to the watch list if it's not present LIST_NODE *node = get_from_path(real_path); if (node == NULL) node = add_to_watch_list(real_path); // Searchs and increments the reference counter // of the link in list_link add_to_link_list(node); // Continue directory traversing list_push(list, (void*) real_path); } } } closedir(dir_stream); } // Free memory list_free(list); }
void watch(char *path, bool is_link) { /* Add initial path to the watch list */ LIST_NODE *node = get_from_path(path); if (node == NULL) node = add_to_watch_list(path, is_link); /* Temporary list to perform breath-first-search */ LIST *list = list_init(); list_push(list, (void *) path); /* Traverse directory */ DIR *dir_stream; struct dirent *dir; while (list->first != NULL) { /* Directory to watch */ char *p = (char*) list_pop(list); /* Traverse directory */ dir_stream = opendir(p); while (dir = readdir(dir_stream)) { if (dir->d_type == DT_DIR && strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0) { char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 2)); strcpy(path_to_watch, p); strcat(path_to_watch, dir->d_name); strcat(path_to_watch, "/"); /* Add to the watch list with is_link = 0 because is a folder */ if (get_from_path(path_to_watch) == NULL) add_to_watch_list(path_to_watch, 0); /** * XXX: [it] prima di inserire path_to_watch * in `list` sarebbe opportuto controllare che * non sia gia' stata inserita in passato da un qualche ln * che, risolto, puntava ad essa * prima di inserire questo controllo bisogna assicurarsi che sia * effettivamente necessario per evetitare spreco di risorse. * Ad ogni modo senza, effettuerebbe cicli inutili ma non dovrebbe essere compromessa * la stabilita'. */ /* Continue directory traversing */ list_push(list, (void*) path_to_watch); } /* Resolve symbolic link */ else if (dir->d_type == DT_LNK) { char *path_to_watch = (char*) malloc(sizeof(char) * (strlen(p) + strlen(dir->d_name) + 1)); strcpy(path_to_watch, p); strcat(path_to_watch, dir->d_name); char *real_path = resolve_real_path(path_to_watch); /** * Test for: * 1. is a real path * 2. is a directory */ if (real_path != NULL && opendir(real_path) != NULL) { /** * If it's not present add to the watch list with is_link = 1, * because is pointed by a symbolic link. */ LIST_NODE *node = get_from_path(real_path); if (node == NULL) node = add_to_watch_list(real_path, 1); /** * Otherwise path_to_watch is a symbolic_link that point * to real_path, so add path_to_watch in links LIST in node->data */ WD_DATA *wd_data = (WD_DATA*) node->data; wd_data->symbolic_link = 1; list_push(wd_data->links, (char*) path_to_watch); /* Continue directory traversing */ list_push(list, (void*) real_path); } } } closedir(dir_stream); } list_free(list); }
/** * MAIN */ int main(int argc, char *argv[]) { if (argc == 1) { help(); return -1; } // Handle command line arguments while (argc > 1) { // Parsing '-' options if (argv[1][0] == '-') { // Single option switch (argv[1][1]) { case 'c': // Move at command if (argc > 2) { ++argv; --argc; } else { help(); return -1; } // Check for a valid command if (strcmp(argv[1], "") == 0 || argv[1][0] == '-') { help(); return -1; } // Store command command = malloc(sizeof(char) * strlen(argv[1]) + 1); strcpy(command, argv[1]); break; case 'l': // Enable syslog be_syslog = 1; break; case 'v': // Be verbose be_verbose = 1; break; case 'V': // Print version and exit printf("%s - Version: %s\n", program_name, program_version); return 0; case 'n': be_easter = 1; break; case 'h': default: help(); return -1; } } else { // Directory to watch??? // A command is specified??? if (argc != 2 || command == NULL) { help(); return -1; } // Check if the path isn't empty if (strcmp(argv[1],"") == 0) { help(); return -1; } // Check if the path has the final slash if (argv[1][strlen(argv[1])-1] != '/') { path = (char*) malloc(sizeof(char) * (strlen(argv[1]) + 2)); strcpy(path, argv[1]); strcat(path, "/"); // Check if it is a directory DIR *dir = opendir(path); if (dir == NULL) { help(); return -1; } closedir(dir); } else { path = (char*) malloc(sizeof(char) * strlen(argv[1])); strcpy(path, argv[1]); } // Check if the path is absolute or not. if( path[0] != '/' ) { char *real_path = resolve_real_path(path); free(path); path = real_path; } } // Next argument --argc; ++argv; } if (path == NULL) { help(); return -1; } // File descriptor inotify fd = inotify_init(); // List of all watch directories list_wd = list_init(); // List of all symbolic links list_link = list_init(); // Watch the path watch(path, 0); // Start monitoring return monitor(); }
/** * MAIN */ int main(int argc, char *argv[]) { if (argc == 1) { help(); return -1; } /* Handle command line arguments */ while (argc > 1) { /* Parsing '-' options */ if (argv[1][0] == '-') { /* Single option */ switch (argv[1][1]) { case 'c': /* Move at command */ if (argc > 2) { ++argv; --argc; } else { help(); return -1; } /* Check for a valid command */ if (strcmp(argv[1], "") == 0 || argv[1][0] == '-') { help(); return -1; } /* Store command */ command = malloc(sizeof(char) * strlen(argv[1]) + 1); strcpy(command, argv[1]); break; case 'l': /* Enable syslog */ be_syslog = 1; break; case 'v': /* Be verbose */ be_verbose = 1; break; case 'V': /* Print version and exit */ printf("%s - Version: %s\n", program_name, program_version); return 0; case 'n': be_easter = 1; break; case 'h': default: help(); return -1; } } else { /* Check if errors occurred */ if (argc != 2 || command == NULL) { help(); return -1; } /* Check if the path isn't empty */ if (strcmp(argv[1], "") == 0) { help(); return -1; } /* Check if the path has the final slash */ if (argv[1][strlen(argv[1])-1] != '/') { path = (char*) malloc(sizeof(char) * (strlen(argv[1]) + 2)); strcpy(path, argv[1]); strcat(path, "/"); /* Is a dir? */ DIR *dir = opendir(path); if (dir == NULL) { help(); return -1; } closedir(dir); } else { path = (char*) malloc(sizeof(char) * strlen(argv[1])); strcpy(path, argv[1]); } /* Check if the path is absolute or not */ if( path[0] != '/' ) { char *real_path = resolve_real_path(path); free(path); path = real_path; } } /* Next argument */ --argc; ++argv; } if (path == NULL) { help(); return -1; } /* File descriptor inotify */ fd = inotify_init(); /* List of all watch directories */ list_wd = list_init(); /* Watch the path */ watch(path, 0); /* DEBUG */ printf("\nlist_watched:\n"); print_list(list_wd); /* Start monitoring */ return monitor(); }