Пример #1
0
/**
 * \param[in] pEd event dispatcher 
 */
void free_tables(EventDispatcher* pEd)
{
  pEd->Clear();
  
  SUT_MAP::iterator it = g_ut.begin();
  while (it != g_ut.end()) {
    UserTable* pUt = (*it).second;
    delete pUt;
    it++;
  }
  
  g_ut.clear();
}
Пример #2
0
/**
 * Loaded tables are registered for processing events.
 * 
 * \param[in] pIn inotify object
 * \param[in] pEd inotify event dispatcher
 * 
 * \throw InotifyException thrown if base table directory cannot be read
 */
void load_tables(Inotify* pIn, EventDispatcher* pEd) throw (InotifyException)
{
  DIR* d = opendir(INCRON_TABLE_BASE);
  if (d == NULL)
    throw InotifyException("cannot open table directory", errno);
  
  syslog(LOG_NOTICE, "loading user tables");
    
  struct dirent* pDe = NULL;
  while ((pDe = readdir(d)) != NULL) {
    std::string un(pDe->d_name);
    if (pDe->d_type == DT_REG && un != "." && un != "..") {
      if (check_user(pDe->d_name)) {
        syslog(LOG_INFO, "loading table for user %s", pDe->d_name);
        UserTable* pUt = new UserTable(pIn, pEd, un);
        g_ut.insert(SUT_MAP::value_type(un, pUt));
        pUt->Load();
      }
      else {
        syslog(LOG_WARNING, "table for invalid user %s found (ignored)", pDe->d_name);
      }
    }
  }
  
  closedir(d);
}
Пример #3
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();
          }
        }
      }
    }
  }
}
Пример #4
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;
}
Пример #5
0
/**
 * Loaded tables are registered for processing events.
 * 
 * \param[in] pEd inotify event dispatcher
 * 
 * \throw InotifyException thrown if base table directory cannot be read
 */
void load_tables(EventDispatcher* pEd) throw (InotifyException)
{
  // WARNING - this function has not been optimized!!!
  
  std::string s;
  if (!IncronCfg::GetValue("system_table_dir", s))
    throw InotifyException("configuration system is corrupted", EINVAL);
  
  DIR* d = opendir(s.c_str());
  if (d != NULL) {
    syslog(LOG_NOTICE, "loading system tables");
      
    struct dirent* pDe = NULL;
    while ((pDe = readdir(d)) != NULL) {
      std::string un(pDe->d_name);
      std::string path(IncronCfg::BuildPath(s, pDe->d_name)); 
      
      bool ok = pDe->d_type == DT_REG;
      if (pDe->d_type == DT_UNKNOWN) {
        struct stat st;
        if (stat(path.c_str(), &st) == 0)
          ok = S_ISREG(st.st_mode);
      }
      
      if (ok) {
        syslog(LOG_INFO, "loading table %s", pDe->d_name);
        UserTable* pUt = new UserTable(pEd, un, true);
        g_ut.insert(SUT_MAP::value_type(path, pUt));
        pUt->Load();
      }
    }
    
    closedir(d);
  }
  else {
    syslog(LOG_WARNING, "cannot open system table directory (ignoring)");
  }
  
  if (!IncronCfg::GetValue("user_table_dir", s))
    throw InotifyException("configuration system is corrupted", EINVAL);
    
  d = opendir(s.c_str());
  if (d == NULL)
    throw InotifyException("cannot open user table directory", errno);
  
  syslog(LOG_NOTICE, "loading user tables");
    
  struct dirent* pDe = NULL;
  while ((pDe = readdir(d)) != NULL) {
    std::string un(pDe->d_name);
    std::string path(IncronCfg::BuildPath(s, pDe->d_name));
    
    bool ok = pDe->d_type == DT_REG;
    if (pDe->d_type == DT_UNKNOWN) {
      struct stat st;
      if (stat(path.c_str(), &st) == 0)
        ok = S_ISREG(st.st_mode);
    }
    
    if (ok) {
      if (UserTable::CheckUser(pDe->d_name)) {
        syslog(LOG_INFO, "loading table for user %s", pDe->d_name);
        UserTable* pUt = new UserTable(pEd, un, false);
        g_ut.insert(SUT_MAP::value_type(path, pUt));
        pUt->Load();
      }
      else {
        syslog(LOG_WARNING, "table for invalid user %s found (ignored)", pDe->d_name);
      }
    }
  }
  
  closedir(d);
}