Subversion Repositories public

Rev

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

Rev 67 Rev 69
Line 23... Line 23...
23
#include <errno.h>
23
#include <errno.h>
24
#include <sys/poll.h>
24
#include <sys/poll.h>
25
#include <sys/stat.h>
25
#include <sys/stat.h>
26
26
27
#include "inotify-cxx.h"
27
#include "inotify-cxx.h"
-
 
28
#include "appinst.h"
-
 
29
#include "appargs.h"
28
30
29
#include "incron.h"
31
#include "incron.h"
30
#include "incrontab.h"
32
#include "incrontab.h"
31
#include "usertable.h"
33
#include "usertable.h"
-
 
34
#include "incroncfg.h"
32
35
33
36
34
/// Logging options (console as fallback, log PID)
37
/// Logging options (console as fallback, log PID)
35
#define INCRON_LOG_OPTS (LOG_CONS | LOG_PID)
38
#define INCRON_LOG_OPTS (LOG_CONS | LOG_PID)
36
39
37
/// Logging facility (use CRON)
40
/// Logging facility (use CRON)
38
#define INCRON_LOG_FACIL LOG_CRON
41
#define INCRON_LOG_FACIL LOG_CRON
39
42
40
/// Help text
43
/// incrond version string
41
#define INCROND_HELP_TEXT "Usage: incrond [option]\n" \
44
#define INCROND_VERSION INCROND_NAME " " INCRON_VERSION
-
 
45
-
 
46
/// incrontab description string
42
                          "incrond - inotify cron daemon\n" \
47
#define INCROND_DESCRIPTION "incrond - inotify cron daemon\n" \
43
                          "(c) Lukas Jelinek, 2006, 2007\n\n" \
48
                            "(c) Lukas Jelinek, 2006, 2007"
-
 
49
-
 
50
/// incrontab help string
-
 
51
#define INCROND_HELP INCROND_DESCRIPTION "\n\n" \
-
 
52
          "usage: incrond [<options>]\n\n" \
-
 
53
          "<operation> may be one of the following:\n" \
-
 
54
          "These options may be used:\n" \
-
 
55
          "  -?, --about                  gives short information about program\n" \
44
                          "-h, --help             Give this help list\n" \
56
          "  -h, --help                   prints this help text\n" \
45
                          "-n, --foreground       Run on foreground (don't daemonize)\n" \
57
          "  -n, --foreground             runs on foreground (no daemonizing)\n" \
46
                          "-k, --kill             Terminate running instance of incrond\n" \
58
          "  -k, --kill                   terminates running instance of incrond\n" \
-
 
59
          "  -f <FILE>, --config=<FILE>   overrides default configuration file  (requires root privileges)\n" \
47
                          "-V, --version          Print program version\n\n" \
60
          "  -V, --version                prints program version\n\n" \
48
                          "Report bugs to <bugs@aiken.cz>"
61
          "For reporting bugs please use http:://bts.aiken.cz\n"
49
62
50
#define INCROND_VERSION_TEXT INCRON_DAEMON_NAME " " INCRON_VERSION
-
 
51
63
52
64
53
/// User name to user table mapping table
65
/// User name to user table mapping table
54
SUT_MAP g_ut;
66
SUT_MAP g_ut;
55
67
Line 92... Line 104...
92
    default:;
104
    default:;
93
  }
105
  }
94
}
106
}
95
107
96
108
-
 
109
-
 
110
97
/// Attempts to load all user incron tables.
111
/// Attempts to load all user incron tables.
98
/**
112
/**
99
 * Loaded tables are registered for processing events.
113
 * Loaded tables are registered for processing events.
100
 *
114
 *
101
 * \param[in] pEd inotify event dispatcher
115
 * \param[in] pEd inotify event dispatcher
Line 104... Line 118...
104
 */
118
 */
105
void load_tables(EventDispatcher* pEd) throw (InotifyException)
119
void load_tables(EventDispatcher* pEd) throw (InotifyException)
106
{
120
{
107
  // WARNING - this function has not been optimized!!!
121
  // WARNING - this function has not been optimized!!!
108
 
122
 
-
 
123
  std::string s;
-
 
124
  if (!IncronCfg::GetValue("system_table_dir", s))
-
 
125
    throw InotifyException("configuration system is corrupted", EINVAL);
-
 
126
 
109
  DIR* d = opendir(INCRON_SYS_TABLE_BASE);
127
  DIR* d = opendir(s.c_str());
110
  if (d != NULL) {
128
  if (d != NULL) {
111
    syslog(LOG_NOTICE, "loading system tables");
129
    syslog(LOG_NOTICE, "loading system tables");
112
     
130
     
113
    struct dirent* pDe = NULL;
131
    struct dirent* pDe = NULL;
114
    while ((pDe = readdir(d)) != NULL) {
132
    while ((pDe = readdir(d)) != NULL) {
115
      std::string un(pDe->d_name);
133
      std::string un(pDe->d_name);
-
 
134
      std::string path(IncronCfg::BuildPath(s, pDe->d_name));
116
     
135
     
117
      bool ok = pDe->d_type == DT_REG;
136
      bool ok = pDe->d_type == DT_REG;
118
      if (pDe->d_type == DT_UNKNOWN) {
137
      if (pDe->d_type == DT_UNKNOWN) {
119
        struct stat st;
138
        struct stat st;
120
        if (stat(pDe->d_name, &st) == 0)
139
        if (stat(path.c_str(), &st) == 0)
121
          ok = S_ISREG(st.st_mode);
140
          ok = S_ISREG(st.st_mode);
122
      }
141
      }
123
     
142
     
124
      if (ok) {
143
      if (ok) {
125
        syslog(LOG_INFO, "loading table %s", pDe->d_name);
144
        syslog(LOG_INFO, "loading table %s", pDe->d_name);
126
        UserTable* pUt = new UserTable(pEd, un, true);
145
        UserTable* pUt = new UserTable(pEd, un, true);
127
        g_ut.insert(SUT_MAP::value_type(std::string(INCRON_SYS_TABLE_BASE) + un, pUt));
146
        g_ut.insert(SUT_MAP::value_type(path, pUt));
128
        pUt->Load();
147
        pUt->Load();
129
      }
148
      }
130
    }
149
    }
131
   
150
   
132
    closedir(d);
151
    closedir(d);
133
  }
152
  }
134
  else {
153
  else {
135
    syslog(LOG_WARNING, "cannot open system table directory (ignoring)");
154
    syslog(LOG_WARNING, "cannot open system table directory (ignoring)");
136
  }
155
  }
137
 
156
 
-
 
157
  if (!IncronCfg::GetValue("user_table_dir", s))
-
 
158
    throw InotifyException("configuration system is corrupted", EINVAL);
138
 
159
   
139
  d = opendir(INCRON_USER_TABLE_BASE);
160
  d = opendir(s.c_str());
140
  if (d == NULL)
161
  if (d == NULL)
141
    throw InotifyException("cannot open user table directory", errno);
162
    throw InotifyException("cannot open user table directory", errno);
142
 
163
 
143
  syslog(LOG_NOTICE, "loading user tables");
164
  syslog(LOG_NOTICE, "loading user tables");
144
   
165
   
145
  struct dirent* pDe = NULL;
166
  struct dirent* pDe = NULL;
146
  while ((pDe = readdir(d)) != NULL) {
167
  while ((pDe = readdir(d)) != NULL) {
147
    std::string un(pDe->d_name);
168
    std::string un(pDe->d_name);
-
 
169
    std::string path(IncronCfg::BuildPath(s, pDe->d_name));
148
   
170
   
149
    bool ok = pDe->d_type == DT_REG;
171
    bool ok = pDe->d_type == DT_REG;
150
    if (pDe->d_type == DT_UNKNOWN) {
172
    if (pDe->d_type == DT_UNKNOWN) {
151
      struct stat st;
173
      struct stat st;
152
      if (stat(pDe->d_name, &st) == 0)
174
      if (stat(path.c_str(), &st) == 0)
153
        ok = S_ISREG(st.st_mode);
175
        ok = S_ISREG(st.st_mode);
154
    }
176
    }
155
   
177
   
156
    if (ok) {
178
    if (ok) {
157
      if (UserTable::CheckUser(pDe->d_name)) {
179
      if (UserTable::CheckUser(pDe->d_name)) {
158
        syslog(LOG_INFO, "loading table for user %s", pDe->d_name);
180
        syslog(LOG_INFO, "loading table for user %s", pDe->d_name);
159
        UserTable* pUt = new UserTable(pEd, un, false);
181
        UserTable* pUt = new UserTable(pEd, un, false);
160
        g_ut.insert(SUT_MAP::value_type(std::string(INCRON_USER_TABLE_BASE) + un, pUt));
182
        g_ut.insert(SUT_MAP::value_type(path, pUt));
161
        pUt->Load();
183
        pUt->Load();
162
      }
184
      }
163
      else {
185
      else {
164
        syslog(LOG_WARNING, "table for invalid user %s found (ignored)", pDe->d_name);
186
        syslog(LOG_WARNING, "table for invalid user %s found (ignored)", pDe->d_name);
165
      }
187
      }
Line 217... Line 239...
217
{
239
{
218
  return strcmp(s, shortCmd)  == 0
240
  return strcmp(s, shortCmd)  == 0
219
      || strcmp(s, longCmd)   == 0;
241
      || strcmp(s, longCmd)   == 0;
220
}
242
}
221
243
222
/// Attempts to kill all running instances of incrond.
-
 
223
/**
-
 
224
 * It kills only instances which use the same executable image
-
 
225
 * as the currently running one.
-
 
226
 *
-
 
227
 * \return true = at least one instance killed, false = otherwise
-
 
228
 * \attention More than one instance may be currently run simultaneously.
-
 
229
 */
-
 
230
bool kill_incrond()
-
 
231
{
-
 
232
  unsigned pid_self = (unsigned) getpid(); // self PID
-
 
233
 
-
 
234
  char s[PATH_MAX];
-
 
235
  snprintf(s, PATH_MAX, "/proc/%u/exe", pid_self);
-
 
236
 
-
 
237
  char path_self[PATH_MAX];
-
 
238
  ssize_t len = readlink(s, path_self, PATH_MAX-1);
-
 
239
  if (len <= 0)
-
 
240
    return false;
-
 
241
  path_self[len] = '\0';
-
 
242
 
-
 
243
  DIR* d = opendir("/proc");
-
 
244
  if (d == NULL)
-
 
245
    return false;
-
 
246
   
-
 
247
  bool ok = false;
-
 
248
   
-
 
249
  char path[PATH_MAX];
-
 
250
  struct dirent* de = NULL;
-
 
251
  while ((de = readdir(d)) != NULL) {
-
 
252
    bool to = false;
-
 
253
    if (de->d_type == DT_DIR)
-
 
254
      to = true;
-
 
255
    else if (de->d_type == DT_UNKNOWN) {
-
 
256
      // fallback way
-
 
257
      snprintf(s, PATH_MAX, "/proc/%s", de->d_name);
-
 
258
      struct stat st;
-
 
259
      if (stat(s, &st) == 0 && S_ISDIR(st.st_mode))
-
 
260
        to = true;
-
 
261
    }
-
 
262
   
-
 
263
    if (to) {
-
 
264
      unsigned pid;
-
 
265
      if (sscanf(de->d_name, "%u", &pid) == 1   // PID successfully retrieved
-
 
266
          && pid != pid_self)                   // don't do suicide!
-
 
267
      {
-
 
268
        snprintf(s, PATH_MAX, "/proc/%u/exe", pid);
-
 
269
        len = readlink(s, path, PATH_MAX-1);
-
 
270
        if (len > 0) {
-
 
271
          path[len] = '\0';
-
 
272
          if (    strcmp(path, path_self) == 0
-
 
273
              &&  kill((pid_t) pid, SIGTERM) == 0)
-
 
274
            ok = true;
-
 
275
        }
-
 
276
      }
-
 
277
    }
-
 
278
  }
-
 
279
 
-
 
280
  closedir(d);
-
 
281
 
-
 
282
  return ok;
-
 
283
}
-
 
284
-
 
285
/// Initializes a poll array.
244
/// Initializes a poll array.
286
/**
245
/**
-
 
246
 * \param[out] pfd poll structure array
287
 * \param[in] pipefd pipe file descriptor
247
 * \param[in] pipefd pipe file descriptor
288
 * \param[in] infd inotify infrastructure file descriptor
248
 * \param[in] infd inotify infrastructure file descriptor
289
 */
249
 */
290
void init_poll_array(struct pollfd pfd[], int pipefd, int infd)
250
void init_poll_array(struct pollfd pfd[], int pipefd, int infd)
291
{
251
{
Line 306... Line 266...
306
 *
266
 *
307
 * \attention In daemon mode, it finishes immediately.
267
 * \attention In daemon mode, it finishes immediately.
308
 */
268
 */
309
int main(int argc, char** argv)
269
int main(int argc, char** argv)
310
{
270
{
311
  if (argc > 2) {
271
  AppArgs::Init();
-
 
272
-
 
273
  if (!(  AppArgs::AddOption("about",       '?', AAT_NO_VALUE, false)
-
 
274
      &&  AppArgs::AddOption("help",        'h', AAT_NO_VALUE, false)
-
 
275
      &&  AppArgs::AddOption("foreground",  'n', AAT_NO_VALUE, false)
-
 
276
      &&  AppArgs::AddOption("kill",        'k', AAT_NO_VALUE, false)
-
 
277
      &&  AppArgs::AddOption("config",      'f', AAT_MANDATORY_VALUE, false))
312
    fprintf(stderr, "error: too many parameters\n");
278
      &&  AppArgs::AddOption("version",     'V', AAT_NO_VALUE, false))
-
 
279
  {
313
    fprintf(stderr, "give --help or -h for more information\n");
280
    fprintf(stderr, "error while initializing application");
314
    return 1;
281
    return 1;
315
  }
282
  }
316
 
283
 
317
  if (argc == 2) {
284
  AppArgs::Parse(argc, argv);
-
 
285
 
318
    if (check_parameter(argv[1], "-h", "--help")) {
286
  if (AppArgs::ExistsOption("help")) {
319
      printf("%s\n", INCROND_HELP_TEXT);
287
    fprintf(stderr, "%s\n", INCROND_HELP);
320
      return 0;
288
    return 0;
321
    }
289
  }
-
 
290
 
322
    else if (check_parameter(argv[1], "-n", "--foreground")) {
291
  if (AppArgs::ExistsOption("about")) {
-
 
292
    fprintf(stderr, "%s\n", INCROND_DESCRIPTION);
323
      g_daemon = false;
293
    return 0;
324
    }
294
  }
325
    else if (check_parameter(argv[1], "-k", "--kill")) {
-
 
326
      fprintf(stderr, "attempting to terminate a running instance of incrond...\n");
-
 
-
 
295
 
327
      if (kill_incrond()) {
296
  if (AppArgs::ExistsOption("version")) {
328
        fprintf(stderr, "instance(s) notified, going down\n");
297
    fprintf(stderr, "%s\n", INCROND_VERSION);
329
        return 0;
298
    return 0;
330
      }
299
  }
331
      else {
300
 
332
        fprintf(stderr, "error - incrond probably not running\n");
301
  AppInstance app("incrond");
-
 
302
 
333
        return 1;
303
  IncronCfg::Init();
334
      }
-
 
335
    }
304
 
336
    else if (check_parameter(argv[1], "-V", "--version")) {
305
  if (AppArgs::ExistsOption("kill")) {
-
 
306
    fprintf(stderr, "attempting to terminate a running instance of incrond...\n");
-
 
307
    if (app.SendSignal(SIGTERM)) {
337
      printf("%s\n", INCROND_VERSION_TEXT);
308
      fprintf(stderr, "instance(s) notified, going down\n");
338
      return 0;
309
      return 0;
339
    }
310
    }
340
    else {
311
    else {
341
      fprintf(stderr, "error - unrecognized parameter: %s\n", argv[1]);
312
      fprintf(stderr, "error - incrond probably not running\n");
342
      return 1;
313
      return 1;
343
    }
314
    }
344
  }
315
  }
345
 
316
 
-
 
317
  if (AppArgs::ExistsOption("foreground"))
-
 
318
    g_daemon = false;
-
 
319
 
-
 
320
 
346
  openlog(INCRON_DAEMON_NAME, INCRON_LOG_OPTS, INCRON_LOG_FACIL);
321
  openlog(INCROND_NAME, INCRON_LOG_OPTS, INCRON_LOG_FACIL);
347
 
322
 
348
  syslog(LOG_NOTICE, "starting service (version %s, built on %s %s)", INCRON_VERSION, __DATE__, __TIME__);
323
  syslog(LOG_NOTICE, "starting service (version %s, built on %s %s)", INCRON_VERSION, __DATE__, __TIME__);
349
 
324
 
-
 
325
  std::string cfg;
-
 
326
  if (!AppArgs::GetOption("config", cfg))
-
 
327
    cfg = INCRON_CONFIG;
-
 
328
  IncronCfg::Load(cfg);
-
 
329
 
-
 
330
  AppArgs::Destroy();
-
 
331
 
-
 
332
  int ret = 0;
-
 
333
 
-
 
334
  std::string sysBase;
-
 
335
  std::string userBase;
-
 
336
 
-
 
337
  if (!IncronCfg::GetValue("system_table_dir", sysBase))
-
 
338
    throw InotifyException("configuration is corrupted", EINVAL);
-
 
339
 
-
 
340
  if (access(sysBase.c_str(), R_OK) != 0) {
-
 
341
    syslog(LOG_CRIT, "cannot read directory for system tables (%s): (%i) %s", sysBase.c_str(), errno, strerror(errno));
-
 
342
    if (!g_daemon)
-
 
343
        fprintf(stderr, "cannot read directory for system tables (%s): (%i) %s", sysBase.c_str(), errno, strerror(errno));
-
 
344
    ret = 1;
-
 
345
    goto error;
-
 
346
  }
-
 
347
 
-
 
348
  if (!IncronCfg::GetValue("user_table_dir", userBase))
-
 
349
    throw InotifyException("configuration is corrupted", EINVAL);
-
 
350
 
-
 
351
  if (access(userBase.c_str(), R_OK) != 0) {
-
 
352
    syslog(LOG_CRIT, "cannot read directory for user tables (%s): (%i) %s", userBase.c_str(), errno, strerror(errno));
-
 
353
    if (!g_daemon)
-
 
354
        fprintf(stderr, "cannot read directory for user tables (%s): (%i) %s", userBase.c_str(), errno, strerror(errno));
-
 
355
    ret = 1;
-
 
356
    goto error;
-
 
357
  }
-
 
358
 
350
  try {
359
  try {
351
    if (g_daemon)
360
    if (g_daemon)
352
      daemon(0, 0);
361
      daemon(0, 0);
-
 
362
 
-
 
363
    try {
-
 
364
    if (!app.Lock()) {
-
 
365
      syslog(LOG_CRIT, "another instance of incrond already running");
-
 
366
      if (!g_daemon)
-
 
367
        fprintf(stderr, "another instance of incrond already running\n");
-
 
368
      ret = 1;
-
 
369
      goto error;
-
 
370
      }
-
 
371
    } catch (AppInstException e) {
-
 
372
      syslog(LOG_CRIT, "instance lookup failed: (%i) %s", e.GetErrorNumber(), strerror(e.GetErrorNumber()));
-
 
373
      if (!g_daemon)
-
 
374
        fprintf(stderr, "instance lookup failed: (%i) %s\n", e.GetErrorNumber(), strerror(e.GetErrorNumber()));
-
 
375
      ret = 1;
-
 
376
      goto error;
-
 
377
    }
353
   
378
   
354
    prepare_pipe();
379
    prepare_pipe();
355
   
380
   
356
    Inotify in;
381
    Inotify in;
357
    in.SetNonBlock(true);
382
    in.SetNonBlock(true);
358
    in.SetCloseOnExec(true);
383
    in.SetCloseOnExec(true);
359
   
384
   
360
    uint32_t wm = IN_CLOSE_WRITE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_UNMOUNT;
385
    uint32_t wm = IN_CLOSE_WRITE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_UNMOUNT;
361
    InotifyWatch stw(INCRON_SYS_TABLE_BASE, wm);
386
    InotifyWatch stw(sysBase, wm);
362
    in.Add(stw);
387
    in.Add(stw);
363
    InotifyWatch utw(INCRON_USER_TABLE_BASE, wm);
388
    InotifyWatch utw(userBase, wm);
364
    in.Add(utw);
389
    in.Add(utw);
365
   
390
   
366
    EventDispatcher ed(g_cldPipe[0], &in, &stw, &utw);
391
    EventDispatcher ed(g_cldPipe[0], &in, &stw, &utw);
367
   
392
   
368
    try {
393
    try {
369
      load_tables(&ed);
394
      load_tables(&ed);
370
    } catch (InotifyException e) {
395
    } catch (InotifyException e) {
371
      int err = e.GetErrorNumber();
396
      int err = e.GetErrorNumber();
372
      syslog(LOG_CRIT, "%s: (%i) %s", e.GetMessage().c_str(), err, strerror(err));
397
      syslog(LOG_CRIT, "%s: (%i) %s", e.GetMessage().c_str(), err, strerror(err));
373
      syslog(LOG_NOTICE, "stopping service");
-
 
374
      closelog();
398
      ret = 1;
375
      return 1;
399
      goto error;
376
    }
400
    }
377
   
401
   
378
    signal(SIGTERM, on_signal);
402
    signal(SIGTERM, on_signal);
379
    signal(SIGINT, on_signal);
403
    signal(SIGINT, on_signal);
380
    signal(SIGCHLD, on_signal);
404
    signal(SIGCHLD, on_signal);
Line 391... Line 415...
391
      }
415
      }
392
      else if (res < 0) {
416
      else if (res < 0) {
393
        if (errno != EINTR)
417
        if (errno != EINTR)
394
          throw InotifyException("polling failed", errno, NULL);
418
          throw InotifyException("polling failed", errno, NULL);
395
      }
419
      }
396
      /*
-
 
397
     
420
     
398
      while (in.GetEvent(e)) {
-
 
399
       
-
 
400
        if (e.GetWatch() == &stw) {
-
 
401
          if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) {
-
 
402
            syslog(LOG_CRIT, "base directory destroyed, exitting");
-
 
403
            g_fFinish = true;
-
 
404
          }
-
 
405
          else if (!e.GetName().empty()) {
-
 
406
            SUT_MAP::iterator it = g_ut.find(stw.GetPath() + e.GetName());
-
 
407
            if (it != g_ut.end()) {
-
 
408
              UserTable* pUt = (*it).second;
-
 
409
              if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
-
 
410
                syslog(LOG_INFO, "system table %s changed, reloading", e.GetName().c_str());
-
 
411
                pUt->Dispose();
-
 
412
                pUt->Load();
-
 
413
              }
-
 
414
              else if (e.IsType(IN_MOVED_FROM) || e.IsType(IN_DELETE)) {
-
 
415
                syslog(LOG_INFO, "system table %s destroyed, removing", e.GetName().c_str());
-
 
416
                delete pUt;
-
 
417
                g_ut.erase(it);
-
 
418
              }
-
 
419
            }
-
 
420
            else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
-
 
421
              syslog(LOG_INFO, "system table %s created, loading", e.GetName().c_str());
-
 
422
              UserTable* pUt = new UserTable(&in, &ed, e.GetName(), true);
-
 
423
              g_ut.insert(SUT_MAP::value_type(std::string(INCRON_SYS_TABLE_BASE) + e.GetName(), pUt));
-
 
424
              pUt->Load();
-
 
425
            }
-
 
426
          }
-
 
427
        }
-
 
428
        else if (e.GetWatch() == &utw) {
-
 
429
          if (e.IsType(IN_DELETE_SELF) || e.IsType(IN_UNMOUNT)) {
-
 
430
            syslog(LOG_CRIT, "base directory destroyed, exitting");
-
 
431
            g_fFinish = true;
-
 
432
          }
-
 
433
          else if (!e.GetName().empty()) {
-
 
434
            SUT_MAP::iterator it = g_ut.find(e.GetWatch()->GetPath() + e.GetName());
-
 
435
            if (it != g_ut.end()) {
-
 
436
              UserTable* pUt = (*it).second;
-
 
437
              if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
-
 
438
                syslog(LOG_INFO, "table for user %s changed, reloading", e.GetName().c_str());
-
 
439
                pUt->Dispose();
-
 
440
                pUt->Load();
-
 
441
              }
-
 
442
              else if (e.IsType(IN_MOVED_FROM) || e.IsType(IN_DELETE)) {
-
 
443
                syslog(LOG_INFO, "table for user %s destroyed, removing",  e.GetName().c_str());
-
 
444
                delete pUt;
-
 
445
                g_ut.erase(it);
-
 
446
              }
-
 
447
            }
-
 
448
            else if (e.IsType(IN_CLOSE_WRITE) || e.IsType(IN_MOVED_TO)) {
-
 
449
              if (check_user(e.GetName().c_str())) {
-
 
450
                syslog(LOG_INFO, "table for user %s created, loading", e.GetName().c_str());
-
 
451
                UserTable* pUt = new UserTable(&in, &ed, e.GetName(), false);
-
 
452
                g_ut.insert(SUT_MAP::value_type(std::string(INCRON_USER_TABLE_BASE) + e.GetName(), pUt));
-
 
453
                pUt->Load();
-
 
454
              }
-
 
455
            }
-
 
456
          }
-
 
457
        }
-
 
458
        else {
-
 
459
          ed.DispatchEvent(e);
-
 
460
        }
-
 
461
       
-
 
462
      }
-
 
463
     
-
 
464
      */
-
 
465
    }
421
    }
466
   
422
   
467
    if (g_cldPipe[0] != -1)
423
    if (g_cldPipe[0] != -1)
468
      close(g_cldPipe[0]);
424
      close(g_cldPipe[0]);
469
    if (g_cldPipe[1] != -1)
425
    if (g_cldPipe[1] != -1)
Line 471... Line 427...
471
  } catch (InotifyException e) {
427
  } catch (InotifyException e) {
472
    int err = e.GetErrorNumber();
428
    int err = e.GetErrorNumber();
473
    syslog(LOG_CRIT, "*** unhandled exception occurred ***");
429
    syslog(LOG_CRIT, "*** unhandled exception occurred ***");
474
    syslog(LOG_CRIT, "  %s", e.GetMessage().c_str());
430
    syslog(LOG_CRIT, "  %s", e.GetMessage().c_str());
475
    syslog(LOG_CRIT, "  error: (%i) %s", err, strerror(err));
431
    syslog(LOG_CRIT, "  error: (%i) %s", err, strerror(err));
-
 
432
    ret = 1;
476
  }
433
  }
477
434
-
 
435
error:
-
 
436
478
  syslog(LOG_NOTICE, "stopping service");
437
  syslog(LOG_NOTICE, "stopping service");
479
 
438
 
480
  closelog();
439
  closelog();
481
 
440
 
482
  return 0;
441
  return ret;
483
}
442
}