Beispiel #1
0
//----------------------------------------------------------------------------------
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;
}
Beispiel #2
0
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);
    }
  }
}
Beispiel #3
0
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");
    }
}
Beispiel #5
0
/**
 * 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;
     }
}
Beispiel #6
0
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);
}
Beispiel #7
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(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);
}
Beispiel #8
0
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();
          }
        }
      }
    }
  }
}
Beispiel #9
0
/**
 * \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;
}
Beispiel #10
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);
}
Beispiel #11
0
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));
    }
}