Beispiel #1
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());
    }
}
Beispiel #2
0
// Set some watchers so we can monitorize dirs, files etc.
void On::setWatchers() {

    // Set JSON watcher
    Inotify notify;
    InotifyWatch watch("/var/local/asturix/launcherjsonview.json", IN_CLOSE_WRITE);
    notify.Add(watch);
    for (;;) {
        notify.WaitForEvents();
        size_t count = notify.GetEventCount();
        while (count > 0) {
            InotifyEvent event;
            bool got_event = notify.GetEvent(&event);
            if (got_event) {
                QMetaObject::invokeMethod(this,"appsChanged",Qt::QueuedConnection);
            }
            count--;
        }
    }

    DConfClient *dConfWallpaper = dconf_client_new(NULL, iconThemeChanged, NULL, NULL);
    dconf_client_watch(dConfWallpaper, "/org/gnome/desktop/interface/icon-theme", NULL, NULL);
}
Beispiel #3
0
bool EventDispatcher::ProcessEvents()
{
  // consume pipe events if any (and report back)
  bool pipe = (m_pPoll[0].revents & POLLIN);
  if (pipe) {
    char c;
    while (read(m_pPoll[0].fd, &c, 1) > 0) {}
    m_pPoll[0].revents = 0;
  }

  // process table management events if any
  if (m_pPoll[1].revents & POLLIN) {
    ProcessMgmtEvents();
    m_pPoll[1].revents = 0;
  }

  InotifyEvent evt;

  for (size_t i=2; i<m_size; i++) {

    // process events if occurred
    if (m_pPoll[i].revents & POLLIN) {
      FDUT_MAP::iterator it = m_maps.find(m_pPoll[i].fd);
      if (it != m_maps.end()) {
        Inotify* pIn = ((*it).second)->GetInotify();
        pIn->WaitForEvents(true);

        // process events for this object
        while (pIn->GetEvent(evt)) {
          ((*it).second)->OnEvent(evt);
        }
      }
      m_pPoll[i].revents = 0;
    }
  }

  return pipe;
}
Beispiel #4
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 #5
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 #6
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)
{
  AppArgs::Init();

  if (!(  AppArgs::AddOption("about",       '?', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("help",        'h', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("foreground",  'n', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("kill",        'k', AAT_NO_VALUE, false)
      &&  AppArgs::AddOption("config",      'f', AAT_MANDATORY_VALUE, false)
      &&  AppArgs::AddOption("version",     'V', AAT_NO_VALUE, false)))
  {
    fprintf(stderr, "error while initializing application");
    return 1;
  }
  
  AppArgs::Parse(argc, argv);
  
  if (AppArgs::ExistsOption("help")) {
    fprintf(stderr, "%s\n", INCROND_HELP);
    return 0;
  }
  
  if (AppArgs::ExistsOption("about")) {
    fprintf(stderr, "%s\n", INCROND_DESCRIPTION);
    return 0;
  }
  
  if (AppArgs::ExistsOption("version")) {
    fprintf(stderr, "%s\n", INCROND_VERSION);
    return 0;
  }
  
  IncronCfg::Init();
  
  std::string cfg;
  if (!AppArgs::GetOption("config", cfg))
    cfg = INCRON_CONFIG;
  IncronCfg::Load(cfg);
  
  std::string lckdir;
  IncronCfg::GetValue("lockfile_dir", lckdir);
  std::string lckfile;
  IncronCfg::GetValue("lockfile_name", lckfile);
  AppInstance app(lckfile, lckdir);
  
  if (AppArgs::ExistsOption("kill")) {
    fprintf(stderr, "attempting to terminate a running instance of incrond...\n");
    if (app.Terminate()) {
      fprintf(stderr, "the instance notified, going down\n");
      return 0;
    }
    else { 
      fprintf(stderr, "error - incrond probably not running\n");
      return 1;
    }
  }
  
  if (AppArgs::ExistsOption("foreground"))
    g_daemon = false;
  
  
  openlog(INCROND_NAME, INCRON_LOG_OPTS, INCRON_LOG_FACIL);
  
  syslog(LOG_NOTICE, "starting service (version %s, built on %s %s)", INCRON_VERSION, __DATE__, __TIME__);
  
  AppArgs::Destroy();
  
  int ret = 0;
  
  std::string sysBase;
  std::string userBase;
  
  if (!IncronCfg::GetValue("system_table_dir", sysBase))
    throw InotifyException("configuration is corrupted", EINVAL);
  
  if (access(sysBase.c_str(), R_OK) != 0) {
    syslog(LOG_CRIT, "cannot read directory for system tables (%s): (%i) %s", sysBase.c_str(), errno, strerror(errno));
    if (!g_daemon)
        fprintf(stderr, "cannot read directory for system tables (%s): (%i) %s", sysBase.c_str(), errno, strerror(errno));
    ret = 1;
    goto error;
  }
  
  if (!IncronCfg::GetValue("user_table_dir", userBase))
    throw InotifyException("configuration is corrupted", EINVAL);
  
  if (access(userBase.c_str(), R_OK) != 0) {
    syslog(LOG_CRIT, "cannot read directory for user tables (%s): (%i) %s", userBase.c_str(), errno, strerror(errno));
    if (!g_daemon)
        fprintf(stderr, "cannot read directory for user tables (%s): (%i) %s", userBase.c_str(), errno, strerror(errno));
    ret = 1;
    goto error;
  }
  
  try {
    if (g_daemon)
      if (daemon(0, 0) == -1) {
        syslog(LOG_CRIT, "daemonizing failed: (%i) %s", errno, strerror(errno));
        fprintf(stderr, "daemonizing failed: (%i) %s\n", errno, strerror(errno));
        ret = 1;
        goto error;
      }
  
    try {
    if (!app.Lock()) {
      syslog(LOG_CRIT, "another instance of incrond already running");
      if (!g_daemon)
        fprintf(stderr, "another instance of incrond already running\n");
      ret = 1;
      goto error;
      }
    } catch (AppInstException e) {
      syslog(LOG_CRIT, "instance lookup failed: (%i) %s", e.GetErrorNumber(), strerror(e.GetErrorNumber()));
      if (!g_daemon)
        fprintf(stderr, "instance lookup failed: (%i) %s\n", e.GetErrorNumber(), strerror(e.GetErrorNumber()));
      ret = 1;
      goto error;
    }
    
    prepare_pipe();
    
    Inotify in;
    in.SetNonBlock(true);
    in.SetCloseOnExec(true);
    
    uint32_t wm = IN_CREATE | IN_CLOSE_WRITE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_UNMOUNT;
    InotifyWatch stw(sysBase, wm);
    in.Add(stw);
    InotifyWatch utw(userBase, wm);
    in.Add(utw);
    
    EventDispatcher ed(g_cldPipe[0], &in, &stw, &utw);
    
    try {
      load_tables(&ed);
    } catch (InotifyException e) {
      int err = e.GetErrorNumber();
      syslog(LOG_CRIT, "%s: (%i) %s", e.GetMessage().c_str(), err, strerror(err));
      ret = 1;
      goto error;
    }
    
    ed.Rebuild(); // not too efficient, but simple 
    
    signal(SIGTERM, on_signal);
    signal(SIGINT, on_signal);
    signal(SIGCHLD, on_signal);
    
    syslog(LOG_NOTICE, "ready to process filesystem events");
    
    while (!g_fFinish) {
      
      int res = poll(ed.GetPollData(), ed.GetSize(), -1);
      
      if (res > 0) {
        if (ed.ProcessEvents())
          UserTable::FinishDone();
      }
      else if (res < 0) {
        switch (errno) {
          case EINTR:   // syscall interrupted - continue polling
            break;
          case EAGAIN:  // not enough resources - wait a moment and try again
            syslog(LOG_WARNING, "polling failed due to resource shortage, retrying later...");
            sleep(POLL_EAGAIN_WAIT);
            break;
          default:
            throw InotifyException("polling failed", errno, NULL);
        } 
      }
      
    }
    
    free_tables(&ed);
    
    if (g_cldPipe[0] != -1)
      close(g_cldPipe[0]);
    if (g_cldPipe[1] != -1)
      close(g_cldPipe[1]);
  } 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));
    ret = 1;
  }

error:

  syslog(LOG_NOTICE, "stopping service");
  
  closelog();
  
  return ret;
}
Beispiel #7
-1
void EventDispatcher::Register(UserTable* pTab)
{
  if (pTab != NULL) {
    Inotify* pIn = pTab->GetInotify();
    if (pIn != NULL) {
      int fd = pIn->GetDescriptor();
      if (fd != -1) {
        m_maps.insert(FDUT_MAP::value_type(fd, pTab));
        Rebuild();
      }
    }
  }
}