//---------------------------------------------------------------------------------- Result Monitor::update() { if (!mInotify) return OK; //printf("update\n"); // wait for inotify events try{ mInotify->WaitForEvents(true); }catch(InotifyException& e) { NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: INotify Monitor cannot get events!"); NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: %s", e.GetMessage().c_str()); return OK; } //printf("ok\n"); // now extract events until there are no more of them InotifyEvent event; while(mInotify->GetEventCount() > 0) { // get event try { // get event mInotify->GetEvent(&event); std::list<WatchData>& data = mWatchMap[event.GetDescriptor()]; // go through a list and update all resource combined with them std::list<WatchData>::iterator it = data.begin(); for (; it != data.end(); it++) { if (it->resource.valid()) { // do only reloading on non-empty resources it->resource.lockResource(); NR_Log(Log::LOG_PLUGIN, Log::LL_DEBUG, "dynamicResources: Monitored %s resource was modified!", it->resourceName.c_str()); //it->resource.getBase()->reload(); it->resource.getBase()->setResourceDirty(true); it->resource.unlockResource(); }else{ NR_Log(Log::LOG_PLUGIN, Log::LL_WARNING, "dynamicResources: Monitored %s resource is not valid!", it->resourceName.c_str()); } } } catch(InotifyException& e) { NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: Cannot retrieve INotify-Event !"); NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: %s", e.GetMessage().c_str()); return OK; } } return OK; }
void UserTable::OnEventDirectory(const InotifyEvent& rEvt, InotifyWatch* pWatch, IncronTabEntry* pEntry) { if (rEvt.IsType(IN_ISDIR)) { std::string sDirectoryPath = pWatch->GetPath() + "/" + IncronTabEntry::GetSafePath(rEvt.GetName()); if (rEvt.IsType(IN_DELETE) || rEvt.IsType(IN_MOVED_FROM)) { RemoveWatch(sDirectoryPath); } } }
void NotifyWorker::startWatching() { QLOG_TRACE() << "inotify starting"; try { Inotify notify; int32_t watch_mask = (IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO); QByteArray dir_str = watch_dir.toLocal8Bit(); InotifyWatch iw(dir_str.data(), watch_mask); notify.Add(iw); for(;;) { notify.WaitForEvents(); QLOG_TRACE() << "iNotify event received"; size_t count = notify.GetEventCount(); while(count > 0) { InotifyEvent event; bool got_event = notify.GetEvent(&event); if(got_event) { FileEvent e; std::string s; event.DumpTypes(s); e.type = QString::fromUtf8(s.c_str()); e.cookie = event.GetCookie(); e.name = QString(event.GetName().c_str()); if(!e.type.contains("IN_ISDIR")) { emit fEvent(e); } } count--; } } } catch(InotifyException e) { QLOG_WARN() << "Inotify failed to start: " + QString::fromStdString(e.GetMessage()); } }
void PcdWatcherClient::getEvents() { try { notify.WaitForEvents(); size_t count = notify.GetEventCount(); InotifyEvent event; bool got_event; std::string filename; std::string filepath; for (int i = 0; i < count; i++) { got_event = notify.GetEvent(&event); if (got_event) { filename = event.GetName(); filepath = directory + "/" + filename; ROS_INFO("Event detected, new file %s created", filepath.c_str()); goal.newFilepath = filepath; ros::Duration(4.0).sleep(); actionClient.sendGoal(goal); } } } catch (InotifyException &e) { ROS_WARN("Inotify exception occured: %s", e.GetMessage().c_str()); } catch (std::exception &e) { ROS_WARN("STL exception occured: %s", e.what()); } catch (...) { ROS_WARN("Uknown exception occured"); } }
/** * Tell the observer to watch the given folder. * Then, the observer will process all the rules * * @param string path the path to be watched * @param vector<Rule> the list of rules to be checked */ void Observer::observe(string path, vector<Rule*> rules){ this->_observing[path] = true; try { Inotify notify; InotifyWatch watch(path, IN_CREATE); notify.Add(watch); cout << "Start observing for changes in " << path << endl; while (this->_observing[path]) { notify.WaitForEvents(); size_t count = notify.GetEventCount(); while (count > 0) { InotifyEvent event; bool got_event = notify.GetEvent(&event); if (got_event) { string mask_str; event.DumpTypes(mask_str); string filename = event.GetName(); this->run_rules(rules, path + '/' + filename, mask_str); } count--; } } } catch (InotifyException &e) { cerr << "Inotify exception occured: " << e.GetMessage() << endl; } catch (exception &e) { cerr << "STL exception occured: " << e.what() << endl; } catch (...) { cerr << "unknown exception occured" << endl; } }
void EventDispatcher::DispatchEvent(InotifyEvent& rEvt) { if (m_pIn == NULL) return; InotifyWatch* pW = rEvt.GetWatch(); if (pW == NULL) return; UserTable* pT = FindTable(pW); if (pT == NULL) return; pT->OnEvent(rEvt); }
void UserTable::OnEvent(InotifyEvent& rEvt) { InotifyWatch* pW = rEvt.GetWatch(); IncronTabEntry* pE = FindEntry(pW); // no entry found - this shouldn't occur if (pE == NULL) return; // discard event if user has no access rights to watch path if (!(m_fSysTable || MayAccess(pW->GetPath(), DONT_FOLLOW(rEvt.GetMask())))) return; std::string cmd; const std::string& cs = pE->GetCmd(); size_t pos = 0; size_t oldpos = 0; size_t len = cs.length(); while ((pos = cs.find('$', oldpos)) != std::string::npos) { if (pos < len - 1) { size_t px = pos + 1; if (cs[px] == '$') { cmd.append(cs.substr(oldpos, pos-oldpos+1)); oldpos = pos + 2; } else { cmd.append(cs.substr(oldpos, pos-oldpos)); if (cs[px] == '@') { // base path cmd.append(IncronTabEntry::GetSafePath(pW->GetPath())); oldpos = pos + 2; } else if (cs[px] == '#') { // file name cmd.append(IncronTabEntry::GetSafePath(rEvt.GetName())); oldpos = pos + 2; } else if (cs[px] == '%') { // mask symbols std::string s; rEvt.DumpTypes(s); cmd.append(s); oldpos = pos + 2; } else if (cs[px] == '&') { // numeric mask char s[11]; snprintf(s, sizeof(s), "%u", (unsigned) rEvt.GetMask()); cmd.append(s); oldpos = pos + 2; } else { oldpos = pos + 1; } } } else { cmd.append(cs.substr(oldpos, pos-oldpos)); oldpos = pos + 1; } } cmd.append(cs.substr(oldpos)); int argc; char** argv; if (!PrepareArgs(cmd, argc, argv)) { syslog(LOG_ERR, "cannot prepare command arguments"); return; } if (m_fSysTable) syslog(LOG_INFO, "(system::%s) CMD (%s)", m_user.c_str(), cmd.c_str()); else syslog(LOG_INFO, "(%s) CMD (%s)", m_user.c_str(), cmd.c_str()); if (pE->IsNoLoop()) pW->SetEnabled(false); if (m_maxForks > 0 && s_procMap.size() >= m_maxForks) { // time to wait for a forked process to finish before we continue int status; pid_t res = wait(&status); UserTable::ClearProcess(res); } pid_t pid = fork(); if (pid == 0) { // for system table if (m_fSysTable) { if (execvp(argv[0], argv) != 0) // exec failed { syslog(LOG_ERR, "cannot exec process: %s", strerror(errno)); _exit(1); } } else { // for user table RunAsUser(argv); } } else if (pid > 0) { ProcData_t pd; if (pE->IsNoLoop()) { pd.onDone = on_proc_done; pd.pWatch = pW; } else { pd.onDone = NULL; pd.pWatch = NULL; } s_procMap.insert(PROC_MAP::value_type(pid, pd)); // Remove watches if it's a directory OnEventDirectory(rEvt, pW, pE); } else { if (pE->IsNoLoop()) pW->SetEnabled(true); syslog(LOG_ERR, "cannot fork process: %s", strerror(errno)); } CleanupArgs(argc, argv); }
void EventDispatcher::ProcessMgmtEvents() { m_pIn->WaitForEvents(true); InotifyEvent e; while (m_pIn->GetEvent(e)) { if (e.GetWatch() == m_pSys) { if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) { syslog(LOG_CRIT, "base directory destroyed, exitting"); g_fFinish = true; } else if (!e.GetName().empty()) { SUT_MAP::iterator it = g_ut.find(IncronCfg::BuildPath(m_pSys->GetPath(), e.GetName())); if (it != g_ut.end()) { UserTable* pUt = (*it).second; if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) { syslog(LOG_INFO, "system table %s changed, reloading", e.GetName().c_str()); pUt->Dispose(); pUt->Load(); } else if (e.IsType(IN_MOVED_FROM) || e.IsType(IN_DELETE)) { syslog(LOG_INFO, "system table %s destroyed, removing", e.GetName().c_str()); delete pUt; g_ut.erase(it); } } else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) { syslog(LOG_INFO, "system table %s created, loading", e.GetName().c_str()); UserTable* pUt = new UserTable(this, e.GetName(), true); g_ut.insert(SUT_MAP::value_type(IncronTab::GetSystemTablePath(e.GetName()), pUt)); pUt->Load(); } } } else if (e.GetWatch() == m_pUser) { if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) { syslog(LOG_CRIT, "base directory destroyed, exitting"); g_fFinish = true; } else if (!e.GetName().empty()) { SUT_MAP::iterator it = g_ut.find(IncronCfg::BuildPath(m_pUser->GetPath(), e.GetName())); if (it != g_ut.end()) { UserTable* pUt = (*it).second; if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) { syslog(LOG_INFO, "table for user %s changed, reloading", e.GetName().c_str()); pUt->Dispose(); pUt->Load(); } else if (e.IsType(IN_MOVED_FROM) || e.IsType(IN_DELETE)) { syslog(LOG_INFO, "table for user %s destroyed, removing", e.GetName().c_str()); delete pUt; g_ut.erase(it); } } else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) { if (UserTable::CheckUser(e.GetName().c_str())) { syslog(LOG_INFO, "table for user %s created, loading", e.GetName().c_str()); UserTable* pUt = new UserTable(this, e.GetName(), false); g_ut.insert(SUT_MAP::value_type(IncronTab::GetUserTablePath(e.GetName()), pUt)); pUt->Load(); } } } } } }
/** * \param[in] argc argument count * \param[in] argv argument array * \return 0 on success, 1 on error * * \attention In daemon mode, it finishes immediately. */ int main(int argc, char** argv) { openlog(INCRON_DAEMON_NAME, INCRON_LOG_OPTS, INCRON_LOG_FACIL); syslog(LOG_NOTICE, "starting service (version %s, built on %s %s)", INCRON_VERSION, __DATE__, __TIME__); try { Inotify in; in.SetNonBlock(true); EventDispatcher ed(&in); try { load_tables(&in, &ed); } catch (InotifyException e) { int err = e.GetErrorNumber(); syslog(LOG_CRIT, "%s: (%i) %s", e.GetMessage().c_str(), err, strerror(err)); syslog(LOG_NOTICE, "stopping service"); closelog(); return 1; } signal(SIGTERM, on_signal); signal(SIGINT, on_signal); signal(SIGCHLD, on_signal); if (DAEMON) daemon(0, 0); uint32_t wm = IN_CLOSE_WRITE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_UNMOUNT; InotifyWatch watch(INCRON_TABLE_BASE, wm); in.Add(watch); syslog(LOG_NOTICE, "ready to process filesystem events"); InotifyEvent e; struct pollfd pfd; pfd.fd = in.GetDescriptor(); pfd.events = (short) POLLIN; pfd.revents = (short) 0; while (!g_fFinish) { int res = poll(&pfd, 1, -1); if (res > 0) { in.WaitForEvents(true); } else if (res < 0) { if (errno != EINTR) throw InotifyException("polling failed", errno, NULL); } UserTable::FinishDone(); while (in.GetEvent(e)) { if (e.GetWatch() == &watch) { if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) { syslog(LOG_CRIT, "base directory destroyed, exitting"); g_fFinish = true; } else if (!e.GetName().empty()) { SUT_MAP::iterator it = g_ut.find(e.GetName()); if (it != g_ut.end()) { UserTable* pUt = (*it).second; if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) { syslog(LOG_INFO, "table for user %s changed, reloading", e.GetName().c_str()); pUt->Dispose(); pUt->Load(); } else if (e.IsType(IN_MOVED_FROM) || e.IsType(IN_DELETE)) { syslog(LOG_INFO, "table for user %s destroyed, removing", e.GetName().c_str()); delete pUt; g_ut.erase(it); } } else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) { if (check_user(e.GetName().c_str())) { syslog(LOG_INFO, "table for user %s created, loading", e.GetName().c_str()); UserTable* pUt = new UserTable(&in, &ed, e.GetName()); g_ut.insert(SUT_MAP::value_type(e.GetName(), pUt)); pUt->Load(); } } } } else { ed.DispatchEvent(e); } } } } catch (InotifyException e) { int err = e.GetErrorNumber(); syslog(LOG_CRIT, "*** unhandled exception occurred ***"); syslog(LOG_CRIT, " %s", e.GetMessage().c_str()); syslog(LOG_CRIT, " error: (%i) %s", err, strerror(err)); } syslog(LOG_NOTICE, "stopping service"); closelog(); return 0; }
void UserTable::OnEvent(InotifyEvent& rEvt) { InotifyWatch* pW = rEvt.GetWatch(); IncronTabEntry* pE = FindEntry(pW); // no entry found - this shouldn't occur if (pE == NULL) return; // discard event if user has no access rights to watch path if (!(m_fSysTable || MayAccess(pW->GetPath(), DONT_FOLLOW(rEvt.GetMask())))) return; std::string cmd; const std::string& cs = pE->GetCmd(); size_t pos = 0; size_t oldpos = 0; size_t len = cs.length(); while ((pos = cs.find('$', oldpos)) != std::string::npos) { if (pos < len - 1) { size_t px = pos + 1; if (cs[px] == '$') { cmd.append(cs.substr(oldpos, pos-oldpos+1)); oldpos = pos + 2; } else { cmd.append(cs.substr(oldpos, pos-oldpos)); if (cs[px] == '@') { // base path cmd.append(pW->GetPath()); oldpos = pos + 2; } else if (cs[px] == '#') { // file name cmd.append(rEvt.GetName()); oldpos = pos + 2; } else if (cs[px] == '%') { // mask symbols std::string s; rEvt.DumpTypes(s); cmd.append(s); oldpos = pos + 2; } else if (cs[px] == '&') { // numeric mask char* s; asprintf(&s, "%u", (unsigned) rEvt.GetMask()); cmd.append(s); free(s); oldpos = pos + 2; } else { oldpos = pos + 1; } } } else { cmd.append(cs.substr(oldpos, pos-oldpos)); oldpos = pos + 1; } } cmd.append(cs.substr(oldpos)); int argc; char** argv; if (!PrepareArgs(cmd, argc, argv)) { syslog(LOG_ERR, "cannot prepare command arguments"); return; } if (m_fSysTable) syslog(LOG_INFO, "(system::%s) CMD (%s)", m_user.c_str(), cmd.c_str()); else syslog(LOG_INFO, "(%s) CMD (%s)", m_user.c_str(), cmd.c_str()); if (pE->IsNoLoop()) pW->SetEnabled(false); pid_t pid = fork(); if (pid == 0) { // for system table if (m_fSysTable) { if (execvp(argv[0], argv) != 0) // exec failed { syslog(LOG_ERR, "cannot exec process: %s", strerror(errno)); _exit(1); } } else { // for user table struct passwd* pwd = getpwnam(m_user.c_str()); if ( pwd == NULL // user not found || setgid(pwd->pw_gid) != 0 // setting GID failed || setuid(pwd->pw_uid) != 0 // setting UID failed || execvp(argv[0], argv) != 0) // exec failed { syslog(LOG_ERR, "cannot exec process: %s", strerror(errno)); _exit(1); } } } else if (pid > 0) { ProcData_t pd; if (pE->IsNoLoop()) { pd.onDone = on_proc_done; pd.pWatch = pW; } else { pd.onDone = NULL; pd.pWatch = NULL; } s_procMap.insert(PROC_MAP::value_type(pid, pd)); } else { if (pE->IsNoLoop()) pW->SetEnabled(true); syslog(LOG_ERR, "cannot fork process: %s", strerror(errno)); } CleanupArgs(argc, argv); }
void UserTable::OnEvent(InotifyEvent& rEvt) { InotifyWatch* pW = rEvt.GetWatch(); InCronTabEntry* pE = FindEntry(pW); if (pE == NULL) return; std::string cmd; const std::string& cs = pE->GetCmd(); size_t pos = 0; size_t oldpos = 0; size_t len = cs.length(); while ((pos = cs.find('$', oldpos)) != std::string::npos) { if (pos < len - 1) { size_t px = pos + 1; if (cs[px] == '$') { cmd.append(cs.substr(oldpos, pos-oldpos+1)); oldpos = pos + 2; } else if (cs[px] == '@') { cmd.append(cs.substr(oldpos, pos-oldpos)); cmd.append(pW->GetPath()); oldpos = pos + 2; } else if (cs[px] == '#') { cmd.append(cs.substr(oldpos, pos-oldpos)); cmd.append(rEvt.GetName()); oldpos = pos + 2; } else { cmd.append(cs.substr(oldpos, pos-oldpos)); oldpos = pos + 1; } } else { cmd.append(cs.substr(oldpos, pos-oldpos)); oldpos = pos + 1; } } cmd.append(cs.substr(oldpos)); int argc; char** argv; if (!PrepareArgs(cmd, argc, argv)) { syslog(LOG_ERR, "cannot prepare command arguments"); return; } syslog(LOG_INFO, "(%s) CMD (%s)", m_user.c_str(), cmd.c_str()); pid_t pid = fork(); if (pid == 0) { struct passwd* pwd = getpwnam(m_user.c_str()); if (pwd == NULL) _exit(1); if (setuid(pwd->pw_uid) != 0) _exit(1); if (execvp(argv[0], argv) != 0) { _exit(1); } } else if (pid > 0) { } else { syslog(LOG_ERR, "cannot fork process: %s", strerror(errno)); } }