Subversion Repositories public

Rev

Rev 67 | Rev 77 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 67 Rev 69
Line 21... Line 21...
21
#include <unistd.h>
21
#include <unistd.h>
22
#include <grp.h>
22
#include <grp.h>
23
#include <sys/stat.h>
23
#include <sys/stat.h>
24
24
25
#include "usertable.h"
25
#include "usertable.h"
-
 
26
#include "incroncfg.h"
26
27
27
#ifdef IN_DONT_FOLLOW
28
#ifdef IN_DONT_FOLLOW
28
#define DONT_FOLLOW(mask) InotifyEvent::IsType(mask, IN_DONT_FOLLOW)
29
#define DONT_FOLLOW(mask) InotifyEvent::IsType(mask, IN_DONT_FOLLOW)
29
#else // IN_DONT_FOLLOW
30
#else // IN_DONT_FOLLOW
30
#define DONT_FOLLOW(mask) (false)
31
#define DONT_FOLLOW(mask) (false)
31
#endif // IN_DONT_FOLLOW
32
#endif // IN_DONT_FOLLOW
32
33
33
34
34
PROC_LIST UserTable::s_procList;
35
PROC_MAP UserTable::s_procMap;
35
36
36
extern volatile bool g_fFinish;
37
extern volatile bool g_fFinish;
37
extern SUT_MAP g_ut;
38
extern SUT_MAP g_ut;
38
39
39
40
Line 162... Line 163...
162
      if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) {
163
      if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) {
163
        syslog(LOG_CRIT, "base directory destroyed, exitting");
164
        syslog(LOG_CRIT, "base directory destroyed, exitting");
164
        g_fFinish = true;
165
        g_fFinish = true;
165
      }
166
      }
166
      else if (!e.GetName().empty()) {
167
      else if (!e.GetName().empty()) {
167
        SUT_MAP::iterator it = g_ut.find(m_pSys->GetPath() + e.GetName());
168
        SUT_MAP::iterator it = g_ut.find(IncronCfg::BuildPath(m_pSys->GetPath(), e.GetName()));
168
        if (it != g_ut.end()) {
169
        if (it != g_ut.end()) {
169
          UserTable* pUt = (*it).second;
170
          UserTable* pUt = (*it).second;
170
          if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
171
          if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
171
            syslog(LOG_INFO, "system table %s changed, reloading", e.GetName().c_str());
172
            syslog(LOG_INFO, "system table %s changed, reloading", e.GetName().c_str());
172
            pUt->Dispose();
173
            pUt->Dispose();
Line 179... Line 180...
179
          }
180
          }
180
        }
181
        }
181
        else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
182
        else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
182
          syslog(LOG_INFO, "system table %s created, loading", e.GetName().c_str());
183
          syslog(LOG_INFO, "system table %s created, loading", e.GetName().c_str());
183
          UserTable* pUt = new UserTable(this, e.GetName(), true);
184
          UserTable* pUt = new UserTable(this, e.GetName(), true);
184
          g_ut.insert(SUT_MAP::value_type(std::string(INCRON_SYS_TABLE_BASE) + e.GetName(), pUt));
185
          g_ut.insert(SUT_MAP::value_type(IncronTab::GetSystemTablePath(e.GetName()), pUt));
185
          pUt->Load();
186
          pUt->Load();
186
        }
187
        }
187
      }
188
      }
188
    }
189
    }
189
    else if (e.GetWatch() == m_pUser) {
190
    else if (e.GetWatch() == m_pUser) {
190
      if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) {
191
      if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) {
191
        syslog(LOG_CRIT, "base directory destroyed, exitting");
192
        syslog(LOG_CRIT, "base directory destroyed, exitting");
192
        g_fFinish = true;
193
        g_fFinish = true;
193
      }
194
      }
194
      else if (!e.GetName().empty()) {
195
      else if (!e.GetName().empty()) {
195
        SUT_MAP::iterator it = g_ut.find(m_pUser->GetPath() + e.GetName());
196
        SUT_MAP::iterator it = g_ut.find(IncronCfg::BuildPath(m_pUser->GetPath(), e.GetName()));
196
        if (it != g_ut.end()) {
197
        if (it != g_ut.end()) {
197
          UserTable* pUt = (*it).second;
198
          UserTable* pUt = (*it).second;
198
          if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
199
          if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
199
            syslog(LOG_INFO, "table for user %s changed, reloading", e.GetName().c_str());
200
            syslog(LOG_INFO, "table for user %s changed, reloading", e.GetName().c_str());
200
            pUt->Dispose();
201
            pUt->Dispose();
Line 208... Line 209...
208
        }
209
        }
209
        else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
210
        else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
210
          if (UserTable::CheckUser(e.GetName().c_str())) {
211
          if (UserTable::CheckUser(e.GetName().c_str())) {
211
            syslog(LOG_INFO, "table for user %s created, loading", e.GetName().c_str());
212
            syslog(LOG_INFO, "table for user %s created, loading", e.GetName().c_str());
212
            UserTable* pUt = new UserTable(this, e.GetName(), false);
213
            UserTable* pUt = new UserTable(this, e.GetName(), false);
213
            g_ut.insert(SUT_MAP::value_type(std::string(INCRON_USER_TABLE_BASE) + e.GetName(), pUt));
214
            g_ut.insert(SUT_MAP::value_type(IncronTab::GetUserTablePath(e.GetName()), pUt));
214
            pUt->Load();
215
            pUt->Load();
215
          }
216
          }
216
        }
217
        }
217
      }
218
      }
218
    }
219
    }
Line 238... Line 239...
238
}
239
}
239
 
240
 
240
void UserTable::Load()
241
void UserTable::Load()
241
{
242
{
242
  m_tab.Load(m_fSysTable
243
  m_tab.Load(m_fSysTable
243
      ? InCronTab::GetSystemTablePath(m_user)
244
      ? IncronTab::GetSystemTablePath(m_user)
244
      : InCronTab::GetUserTablePath(m_user));
245
      : IncronTab::GetUserTablePath(m_user));
245
 
246
 
246
  int cnt = m_tab.GetCount();
247
  int cnt = m_tab.GetCount();
247
  for (int i=0; i<cnt; i++) {
248
  for (int i=0; i<cnt; i++) {
248
    InCronTabEntry& rE = m_tab.GetEntry(i);
249
    IncronTabEntry& rE = m_tab.GetEntry(i);
249
    InotifyWatch* pW = new InotifyWatch(rE.GetPath(), rE.GetMask());
250
    InotifyWatch* pW = new InotifyWatch(rE.GetPath(), rE.GetMask());
250
   
251
   
251
    // warning only - permissions may change later
252
    // warning only - permissions may change later
252
    if (!(m_fSysTable || MayAccess(rE.GetPath(), DONT_FOLLOW(rE.GetMask()))))
253
    if (!(m_fSysTable || MayAccess(rE.GetPath(), DONT_FOLLOW(rE.GetMask()))))
253
      syslog(LOG_WARNING, "access denied on %s - events will be discarded silently", rE.GetPath().c_str());
254
      syslog(LOG_WARNING, "access denied on %s - events will be discarded silently", rE.GetPath().c_str());
Line 273... Line 274...
273
 
274
 
274
  IWCE_MAP::iterator it = m_map.begin();
275
  IWCE_MAP::iterator it = m_map.begin();
275
  while (it != m_map.end()) {
276
  while (it != m_map.end()) {
276
    InotifyWatch* pW = (*it).first;
277
    InotifyWatch* pW = (*it).first;
277
    m_in.Remove(pW);
278
    m_in.Remove(pW);
-
 
279
   
-
 
280
    PROC_MAP::iterator it2 = s_procMap.begin();
-
 
281
    while (it2 != s_procMap.end()) {
-
 
282
      if ((*it2).second.pWatch == pW) {
-
 
283
        PROC_MAP::iterator it3 = it2;
-
 
284
        it2++;
-
 
285
        s_procMap.erase(it3);
-
 
286
      }
-
 
287
      else {
-
 
288
        it2++;
-
 
289
      }
-
 
290
    }
-
 
291
   
278
    delete pW;
292
    delete pW;
279
    it++;
293
    it++;
280
  }
294
  }
281
 
295
 
282
  m_map.clear();
296
  m_map.clear();
283
}
297
}
284
 
298
 
285
void UserTable::OnEvent(InotifyEvent& rEvt)
299
void UserTable::OnEvent(InotifyEvent& rEvt)
286
{
300
{
287
  InotifyWatch* pW = rEvt.GetWatch();
301
  InotifyWatch* pW = rEvt.GetWatch();
288
  InCronTabEntry* pE = FindEntry(pW);
302
  IncronTabEntry* pE = FindEntry(pW);
289
 
303
 
290
  // no entry found - this shouldn't occur
304
  // no entry found - this shouldn't occur
291
  if (pE == NULL)
305
  if (pE == NULL)
292
    return;
306
    return;
293
 
307
 
Line 355... Line 369...
355
    syslog(LOG_INFO, "(%s) CMD (%s)", m_user.c_str(), cmd.c_str());
369
    syslog(LOG_INFO, "(%s) CMD (%s)", m_user.c_str(), cmd.c_str());
356
 
370
 
357
  if (pE->IsNoLoop())
371
  if (pE->IsNoLoop())
358
    pW->SetEnabled(false);
372
    pW->SetEnabled(false);
359
 
373
 
360
  ProcData_t pd;
-
 
361
  pd.pid = fork();
374
  pid_t pid = fork();
362
  if (pd.pid == 0) {
375
  if (pid == 0) {
363
   
376
   
364
    // for system table
377
    // for system table
365
    if (m_fSysTable) {
378
    if (m_fSysTable) {
366
      if (execvp(argv[0], argv) != 0) // exec failed
379
      if (execvp(argv[0], argv) != 0) // exec failed
367
      {
380
      {
Line 380... Line 393...
380
        syslog(LOG_ERR, "cannot exec process: %s", strerror(errno));
393
        syslog(LOG_ERR, "cannot exec process: %s", strerror(errno));
381
        _exit(1);
394
        _exit(1);
382
      }
395
      }
383
    }
396
    }
384
  }
397
  }
385
  else if (pd.pid > 0) {
398
  else if (pid > 0) {
-
 
399
    ProcData_t pd;
386
    if (pE->IsNoLoop()) {
400
    if (pE->IsNoLoop()) {
387
      pd.onDone = on_proc_done;
401
      pd.onDone = on_proc_done;
388
      pd.pWatch = pW;
402
      pd.pWatch = pW;
389
    }
403
    }
390
    else {
404
    else {
391
      pd.onDone = NULL;
405
      pd.onDone = NULL;
392
      pd.pWatch = NULL;
406
      pd.pWatch = NULL;
393
    }
407
    }
394
   
408
   
395
    s_procList.push_back(pd);
409
    s_procMap.insert(PROC_MAP::value_type(pid, pd));
396
  }
410
  }
397
  else {
411
  else {
398
    if (pE->IsNoLoop())
412
    if (pE->IsNoLoop())
399
      pW->SetEnabled(true);
413
      pW->SetEnabled(true);
400
     
414
     
Line 402... Line 416...
402
  }
416
  }
403
 
417
 
404
  CleanupArgs(argc, argv);
418
  CleanupArgs(argc, argv);
405
}
419
}
406
420
407
InCronTabEntry* UserTable::FindEntry(InotifyWatch* pWatch)
421
IncronTabEntry* UserTable::FindEntry(InotifyWatch* pWatch)
408
{
422
{
409
  IWCE_MAP::iterator it = m_map.find(pWatch);
423
  IWCE_MAP::iterator it = m_map.find(pWatch);
410
  if (it == m_map.end())
424
  if (it == m_map.end())
411
    return NULL;
425
    return NULL;
412
   
426
   
Line 450... Line 464...
450
  delete[] argv;
464
  delete[] argv;
451
}
465
}
452
466
453
void UserTable::FinishDone()
467
void UserTable::FinishDone()
454
{
468
{
455
  PROC_LIST::iterator it = s_procList.begin();
-
 
456
  while (it != s_procList.end()) {
-
 
457
    ProcData_t& pd = *it;
469
  pid_t res = 0;
458
    int status = 0;
470
  int status = 0;
459
    int res = waitpid(pd.pid, &status, WNOHANG);
471
  while ((res = waitpid(-1, &status, WNOHANG)) > 0) {
-
 
472
    PROC_MAP::iterator it = s_procMap.find(res);
460
    if (res == pd.pid && (WIFEXITED(status) || WIFSIGNALED(status))) {
473
    if (it != s_procMap.end()) {
-
 
474
      ProcData_t pd = (*it).second;
461
      if (pd.onDone != NULL)
475
      if (pd.onDone != NULL)
462
        (*pd.onDone)(pd.pWatch);
476
        (*pd.onDone)(pd.pWatch);
463
      it = s_procList.erase(it);
477
      s_procMap.erase(it);
464
    }
-
 
465
    else {
-
 
466
      it++;
-
 
467
    }
478
    }
468
  }  
479
  }  
469
}
480
}
470
481
471
bool UserTable::MayAccess(const std::string& rPath, bool fNoFollow) const
482
bool UserTable::MayAccess(const std::string& rPath, bool fNoFollow) const