#include #include #include #include #include #include #include #include #include #include #define POLL_TIME_SEC 60 /* * Prints the usage string */ void usage(const char* _name); /* * Checks if the filepath is a directory or not * * Returns -1 on error; 0 on false; 1 on true */ int is_dir(const char* _filepath); /* * Executes the generation command * * Returns -1 on error; */ int execute_mindgen(const char* _dest_dir, const char* _filename, const char* _source_dir); /* * Executes the deletion command * * Returns -1 on error; */ int execute_delete(const char* _dir, const char* _filename); int main(int argc, char** argv) { int notify_fd; int watch_fd; int error; bool deleted; unsigned int buffer_size; char* buffer; int offset; // [name] [watch dir] [destination dir] if (argc < 3) { usage(argv[0]); return 1; } // Check dirs and permissions if (1 != is_dir(argv[1])) { usage(argv[0]); printf("Watch directory is not a folder, does not exist or there are not sufficient permissions.\n"); } if (1 != is_dir(argv[2])) { usage(argv[0]); printf("Destination directory is not a folder, does not exist or there are not sufficient permissions.\n"); } // inotify init notify_fd = inotify_init(); if (notify_fd < 0) { printf("BAD NOTIFY FD\n"); return -1; } // inotify add watch watch_fd = inotify_add_watch(notify_fd, argv[1], IN_DELETE | IN_DELETE_SELF | IN_CLOSE_WRITE); if (watch_fd < 0) { printf("BAD WATCH FD\n"); close(notify_fd); return -1; } deleted = false; while (!deleted) { // wait for event buffer_size = 0; while (0 == buffer_size) { sleep(POLL_TIME_SEC); error = ioctl(notify_fd, FIONREAD, &buffer_size); if (0 != error) { printf("BAD IOCTL\n"); return -1; } } // Create big enough buffer and read all data buffer = (char*)malloc(buffer_size); error = read(notify_fd, buffer, buffer_size); if (error != buffer_size) { printf("BAD BUFFER SIZE\n"); free(buffer); close(notify_fd); return -1; } // Read and process all events offset = 0; while (offset < buffer_size) { struct inotify_event* event = (struct inotify_event*)(buffer + offset); // on create/modify - mindgen if (0 != (event->mask & IN_CLOSE_WRITE)) { //printf("FILE WRITTEN TO: %s\n", event->name); execute_mindgen(argv[2], event->name, argv[1]); } // on delete - rm if (0 != (event->mask & IN_DELETE)) { //printf("DELETE: %s\n", event->name); execute_delete(argv[2], event->name); } // on delete_self - exit if (0 != (event->mask & IN_DELETE_SELF)) { printf("Watched folder deleted. Stopping.\n"); deleted = true; } offset += sizeof(struct inotify_event) + event->len; } free(buffer); buffer = NULL; } return 0; } void usage(const char* name) { if (NULL == name) { return; } printf("%s watch_dir dest_dir\n", name); } int is_dir(const char* filepath) { int result; struct stat file_stat; if (NULL == filepath) { return -1; } result = stat(filepath, &file_stat); if (0 == result) { if (S_ISDIR(file_stat.st_mode)) { result = 1; } } return result; } int execute_mindgen(const char* dest_dir, const char* filename, const char* source_dir) { int pid; int child_status; char source_fullname[strlen(source_dir) + strlen(filename) + 2]; char dest_fullname[strlen(dest_dir) + strlen(filename) + 7]; char* arglist[4]; pid = fork(); if (pid < 0) { printf("Error trying to generate html.\n"); return -1; } if (0 == pid) { strcpy(source_fullname, source_dir); strcat(source_fullname, "/"); strcat(source_fullname, filename); strcpy(dest_fullname, dest_dir); strcat(dest_fullname, "/"); strcat(dest_fullname, filename); strcat(dest_fullname, ".html"); arglist[0] = "mindgen"; arglist[1] = source_fullname; arglist[2] = dest_fullname; arglist[3] = NULL; //printf("%s %s %s\n", arglist[0], arglist[1], arglist[2]); execv("./mindgen", arglist); printf("Error generating html.\n"); return -1; } wait(&child_status); return 0; } int execute_delete(const char* dir, const char* filename) { int pid; int child_status; char fullname[strlen(dir) + strlen(filename) + 7]; char* arglist[3]; pid = fork(); if (pid < 0) { printf("Error trying to delete.\n"); return -1; } if (0 == pid) { strcpy(fullname, dir); strcat(fullname, "/"); strcat(fullname, filename); strcat(fullname, ".html"); arglist[0] = "rm"; arglist[1] = fullname; arglist[2] = NULL; //printf("%s %s\n", arglist[0], arglist[1]); execv("/bin/rm", arglist); printf("Error deleting.\n"); return -1; } wait(&child_status); return 0; }