示例#1
0
void Inotify::RemoveAll()
{
  IN_WATCH_MAP::iterator it = m_watches.begin();
  while (it != m_watches.end()) {
    InotifyWatch* pW = (*it).second;
    inotify_rm_watch(m_fd, pW->GetMask());
    pW->m_wd = -1;
    pW->m_pInotify = NULL;
    it++;
  }
  
  m_watches.clear();
}
示例#2
0
//----------------------------------------------------------------------------------
void Monitor::addMonitor(IResourcePtr res, const std::string& file)
{
	// do only add a watcher if inotify already initialized
	if (!mInotify || !res.valid() || file.length() < 1) return;
	
	// we monitor only non-empty resources
	res.lockResource();
	{
		// create a watch descriptor
		try
		{
			// first check if such a watcher already exists
			InotifyWatch* watch = mInotify->FindWatch(file);
			
			if (watch == NULL)
			{
				watch = new InotifyWatch(file, IN_MODIFY);
				mInotify->Add(watch);
			}
			
			// add new watcher
			NR_Log(Log::LOG_PLUGIN, Log::LL_DEBUG, "dynamicResources: Monitor %s --> %s", res.getBase()->getResourceName().c_str(), file.c_str());
			
			// add the watcher into the map
			WatchData data;
			data.resource = res;
			data.watcher = watch;
			data.resourceName = res.getBase()->getResourceName();
			mWatchMap[watch->GetDescriptor()].push_back(data);
			
		}catch(InotifyException& e)
		{
			NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: Cannot add a monitor %s --> %s", res.getBase()->getResourceName().c_str(), file.c_str());
			NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: %s", e.GetMessage().c_str());
			return;
		}
		
	}
	res.unlockResource();
}
示例#3
0
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
{
  ssize_t len = 0;
  
  do {
    len = read(m_fd, m_buf, INOTIFY_BUFLEN);
  } while (fNoIntr && len == -1 && errno == EINTR);
  
  if (len < 0)
    throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
  
  ssize_t i = 0;
  while (i < len) {
    struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
    InotifyWatch* pW = FindWatch(pEvt->wd);
    if (pW != NULL && pW->IsEnabled()) {
      InotifyEvent evt(pEvt, pW);
      m_events.push_back(evt);
    }
    i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
  }
}
示例#4
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);
}
示例#5
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);
}
示例#6
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));
    }
}