Subversion Repositories public

Rev

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

Rev 67 Rev 69
Line 20... Line 20...
20
#include <stdio.h>
20
#include <stdio.h>
21
#include <unistd.h>
21
#include <unistd.h>
22
#include <sys/stat.h>
22
#include <sys/stat.h>
23
#include <sys/wait.h>
23
#include <sys/wait.h>
24
#include <sys/inotify.h>
24
#include <sys/inotify.h>
-
 
25
#include <fcntl.h>
-
 
26
-
 
27
#include "inotify-cxx.h"
-
 
28
#include "appargs.h"
25
29
26
#include "incron.h"
30
#include "incron.h"
27
#include "incrontab.h"
31
#include "incrontab.h"
-
 
32
#include "incroncfg.h"
-
 
33
28
34
29
// Alternative editor
35
/// Alternative editor
30
#define INCRON_ALT_EDITOR "/etc/alternatives/editor"
36
#define INCRON_ALT_EDITOR "/etc/alternatives/editor"
31
37
32
// #define INCRON_DEFAULT_EDITOR "nano" // for vim haters like me ;-)
38
/// Default (hard-wired) editor
33
#define INCRON_DEFAULT_EDITOR "vim"
39
#define INCRON_DEFAULT_EDITOR "vim"
34
40
-
 
41
/// incrontab version string
-
 
42
#define INCRONTAB_VERSION INCRONTAB_NAME " " INCRON_VERSION
35
43
36
const char* argp_program_version = INCRON_TAB_NAME " " INCRON_VERSION;
44
/// incrontab description string
37
const char* argp_program_bug_address = INCRON_BUG_ADDRESS;
45
#define INCRONTAB_DESCRIPTION "incrontab - inotify cron table manipulator\n" \
38
-
 
39
static char doc[] = "incrontab - incron table manipulator\n(c) Lukas Jelinek, 2006, 2007";
46
                              "(c) Lukas Jelinek, 2006, 2007"
40
47
41
static char args_doc[] = "FILE";
48
/// incrontab help string
42
-
 
43
static struct argp_option options[] = {
49
#define INCRONTAB_HELP INCRONTAB_DESCRIPTION "\n\n" \
44
  {"list",    'l', 0,      0,  "List the current table" },
50
          "usage: incrontab [<options>] <operation>\n" \
45
  {"remove",  'r', 0,      0,  "Remove the table completely" },
51
          "       incrontab [<options>] <FILE-TO-IMPORT>\n\n" \
46
  {"edit",    'e', 0,      0,  "Edit the table" },
52
          "<operation> may be one of the following:\n" \
47
  {"types",   't', 0,      0,  "List all supported event types" },
53
          "  -?, --about                  gives short information about program\n" \
48
  {"user",    'u', "USER", 0,  "Override the current user" },
54
          "  -h, --help                   prints this help text\n" \
49
  { 0 }
-
 
50
};
-
 
51
-
 
52
/// incrontab operations
-
 
53
typedef enum
-
 
54
{
-
 
55
  OPER_NONE,    /// nothing
-
 
56
  OPER_LIST,    /// list table
55
          "  -l, --list                   lists user table\n" \
57
  OPER_REMOVE,  /// remove table
-
 
58
  OPER_EDIT,    /// edit table
-
 
59
  OPER_TYPES    /// list event types
-
 
60
} InCronTab_Operation_t;
-
 
61
-
 
62
/// incrontab arguments
-
 
63
struct arguments
-
 
64
{
-
 
65
  char *user;     /// user name
-
 
66
  int oper;       /// operation code
56
          "  -r, --remove                 removes user table\n" \
67
  char *file;     /// file to import
-
 
68
};
-
 
69
-
 
70
/// Parses the program options (arguments).
57
          "  -e, --edit                   provides editting user table\n" \
71
/**
-
 
72
 * \param[in] key argument key (name)
-
 
73
 * \param[in] arg argument value
-
 
74
 * \param[out] state options setting
-
 
75
 * \return 0 on success, ARGP_ERR_UNKNOWN on unknown argument(s)
58
          "  -t, --types                  list supported event types\n" \
76
 */
-
 
77
static error_t parse_opt(int key, char *arg, struct argp_state *state)
59
          "  -d, --reload                 request incrond to reload user table\n" \
78
{
-
 
79
  struct arguments* arguments = (struct arguments*) state->input;
60
          "  -V, --version                prints program version\n\n" \
80
     
-
 
81
  switch (key) {
-
 
82
    case 'l':
-
 
83
      arguments->oper = OPER_LIST;
-
 
84
      break;
61
          "\n" \
85
    case 'r':
-
 
86
      arguments->oper = OPER_REMOVE;
62
          "These options may be used:\n" \
87
      break;
-
 
88
    case 'e':
-
 
89
      arguments->oper = OPER_EDIT;
-
 
90
      break;
-
 
91
    case 't':
-
 
92
      arguments->oper = OPER_TYPES;
63
          "  -u <USER>, --user=<USER>     overrides current user (requires root privileges)\n" \
93
      break;
-
 
94
    case 'u':
-
 
95
      arguments->user = arg;
-
 
96
      break;
-
 
97
    case ARGP_KEY_ARG:
-
 
98
      if (state->arg_num >= 1)
64
          "  -f <FILE>, --config=<FILE>   overrides default configuration file  (requires root privileges)\n\n" \
99
        argp_usage(state);
65
          "For reporting bugs please use http:://bts.aiken.cz\n"
100
      arguments->file = arg;
-
 
101
      break;
-
 
102
    case ARGP_KEY_END:
-
 
103
      break;
-
 
104
    default:
-
 
105
      return ARGP_ERR_UNKNOWN;
-
 
106
  }
-
 
107
 
-
 
108
  return 0;
-
 
109
}
-
 
110
66
               
111
/// Program arguments
-
 
112
static struct argp argp = { options, parse_opt, args_doc, doc };
-
 
113
67
114
68
115
69
116
/// Copies a file to an user table.
70
/// Copies a file to an user table.
117
/**
71
/**
118
 * \param[in] path path to file
72
 * \param[in] rPath path to file
119
 * \param[in] user user name
73
 * \param[in] rUser user name
120
 * \return true = success, false = failure
74
 * \return true = success, false = failure
121
 */
75
 */
122
bool copy_from_file(const char* path, const char* user)
76
bool copy_from_file(const std::string& rPath, const std::string& rUser)
123
{
77
{
-
 
78
  fprintf(stderr, "copying table from file '%s'\n", rPath.c_str());
-
 
79
 
124
  InCronTab tab;
80
  IncronTab tab;
125
  std::string s(path);
81
  std::string s(rPath);
126
  if (s == "-")
82
  if (s == "-")
127
    s = "/dev/stdin";
83
    s = "/dev/stdin";
128
  if (!tab.Load(s)) {
84
  if (!tab.Load(s)) {
129
    fprintf(stderr, "cannot load table from file: %s\n", path);
85
    fprintf(stderr, "cannot load table from file '%s'\n", rPath.c_str());
130
    return false;
86
    return false;
131
  }
87
  }
132
 
88
 
133
  std::string out(InCronTab::GetUserTablePath(user));
89
  std::string out(IncronTab::GetUserTablePath(rUser));
134
  if (!tab.Save(out)) {
90
  if (!tab.Save(out)) {
135
    fprintf(stderr, "cannot create table for user: %s\n", user);
91
    fprintf(stderr, "cannot create table for user '%s'\n", rUser.c_str());
136
    return false;
92
    return false;
137
  }
93
  }
138
 
94
 
139
  return true;
95
  return true;
140
}
96
}
141
97
142
/// Removes an user table.
98
/// Removes an user table.
143
/**
99
/**
144
 * \param[in] user user name
100
 * \param[in] rUser user name
145
 * \return true = success, false = failure
101
 * \return true = success, false = failure
146
 */
102
 */
147
bool remove_table(const char* user)
103
bool remove_table(const std::string& rUser)
148
{
104
{
-
 
105
  fprintf(stderr, "removing table for user '%s'\n", rUser.c_str());
-
 
106
 
149
  std::string tp(InCronTab::GetUserTablePath(user));
107
  std::string tp(IncronTab::GetUserTablePath(rUser));
150
 
108
 
151
  if (unlink(tp.c_str()) != 0 && errno != ENOENT) {
109
  if (unlink(tp.c_str()) != 0 && errno != ENOENT) {
152
    fprintf(stderr, "cannot remove table for user: %s\n", user);
110
    fprintf(stderr, "cannot remove table for user '%s': %s\n", rUser.c_str(), strerror(errno));
153
    return false;
111
    return false;
154
  }
112
  }
155
 
113
 
156
  return true;
114
  return true;
157
}
115
}
158
116
159
/// Lists an user table.
117
/// Lists an user table.
160
/**
118
/**
161
 * \param[in] user user name
119
 * \param[in] rUser user name
162
 * \return true = success, false = failure
120
 * \return true = success, false = failure
163
 */
121
 */
164
bool list_table(const char* user)
122
bool list_table(const std::string& rUser)
165
{
123
{
166
  std::string tp(InCronTab::GetUserTablePath(user));
124
  std::string tp(IncronTab::GetUserTablePath(rUser));
167
 
125
 
168
  if (euidaccess(tp.c_str(), R_OK) != 0) {
126
  FILE* f = fopen(tp.c_str(), "r");
-
 
127
  if (f == NULL) {
169
    if (errno == ENOENT) {
128
    if (errno == ENOENT) {
170
      fprintf(stderr, "no table for %s\n", user);
129
      fprintf(stderr, "no table for %s\n", rUser.c_str());
171
      return true;
130
      return true;
172
    }
131
    }
173
    else {
132
    else {
174
      fprintf(stderr, "cannot read table for %s: %s\n", user, strerror(errno));
133
      fprintf(stderr, "cannot read table for '%s': %s\n", rUser.c_str(), strerror(errno));
175
      return false;
134
      return false;
176
    }
135
    }
177
  }
136
  }
178
 
-
 
179
  FILE* f = fopen(tp.c_str(), "r");
-
 
180
  if (f == NULL)
-
 
181
    return false;
-
 
182
   
137
   
183
  char s[1024];
138
  char s[1024];
184
  while (fgets(s, 1024, f) != NULL) {
139
  while (fgets(s, 1024, f) != NULL) {
185
    fputs(s, stdout);
140
    fputs(s, stdout);
186
  }
141
  }
Line 190... Line 145...
190
  return true;
145
  return true;
191
}
146
}
192
147
193
/// Allows to edit an user table.
148
/// Allows to edit an user table.
194
/**
149
/**
195
 * \param[in] user user name
150
 * \param[in] rUser user name
196
 * \return true = success, false = failure
151
 * \return true = success, false = failure
197
 *
152
 *
198
 * \attention This function is very complex and may contain
153
 * \attention This function is very complex and may contain
199
 *            various bugs including security ones. Please keep
154
 *            various bugs including security ones. Please keep
200
 *            it in mind..
155
 *            it in mind..
201
 */
156
 */
202
bool edit_table(const char* user)
157
bool edit_table(const std::string& rUser)
203
{
158
{
204
  std::string tp(InCronTab::GetUserTablePath(user));
159
  std::string tp(IncronTab::GetUserTablePath(rUser));
205
 
160
 
206
  struct passwd* ppwd = getpwnam(user);
161
  struct passwd* ppwd = getpwnam(rUser.c_str());
207
  if (ppwd == NULL) {
162
  if (ppwd == NULL) {
208
    fprintf(stderr, "cannot find user %s: %s\n", user, strerror(errno));
163
    fprintf(stderr, "cannot find user '%s': %s\n", rUser.c_str(), strerror(errno));
209
    return false;
164
    return false;
210
  }
165
  }
211
 
166
 
212
  uid_t uid = ppwd->pw_uid;
167
  uid_t uid = ppwd->pw_uid;
213
  uid_t gid = ppwd->pw_gid;
168
  uid_t gid = ppwd->pw_gid;
Line 217... Line 172...
217
 
172
 
218
  uid_t iu = geteuid();
173
  uid_t iu = geteuid();
219
  uid_t ig = getegid();
174
  uid_t ig = getegid();
220
175
221
  if (setegid(gid) != 0 || seteuid(uid) != 0) {
176
  if (setegid(gid) != 0 || seteuid(uid) != 0) {
222
    fprintf(stderr, "cannot change effective UID/GID for user %s: %s\n", user, strerror(errno));
177
    fprintf(stderr, "cannot change effective UID/GID for user '%s': %s\n", rUser.c_str(), strerror(errno));
223
    return false;
178
    return false;
224
  }
179
  }
225
 
180
 
226
  int fd = mkstemp(s);
181
  int fd = mkstemp(s);
227
  if (fd == -1) {
182
  if (fd == -1) {
Line 232... Line 187...
232
  bool ok = false;
187
  bool ok = false;
233
  FILE* out = NULL;
188
  FILE* out = NULL;
234
  FILE* in = NULL;
189
  FILE* in = NULL;
235
  time_t mt = (time_t) 0;
190
  time_t mt = (time_t) 0;
236
  const char* e = NULL;
191
  const char* e = NULL;
-
 
192
  std::string ed;
237
 
193
 
238
  if (setegid(ig) != 0 || seteuid(iu) != 0) {
194
  if (setegid(ig) != 0 || seteuid(iu) != 0) {
239
    fprintf(stderr, "cannot change effective UID/GID: %s\n", strerror(errno));
195
    fprintf(stderr, "cannot change effective UID/GID: %s\n", strerror(errno));
240
    close(fd);
196
    close(fd);
241
    goto end;
197
    goto end;
Line 251... Line 207...
251
  in = fopen(tp.c_str(), "r");
207
  in = fopen(tp.c_str(), "r");
252
  if (in == NULL) {
208
  if (in == NULL) {
253
    if (errno == ENOENT) {
209
    if (errno == ENOENT) {
254
      in = fopen("/dev/null", "r");
210
      in = fopen("/dev/null", "r");
255
      if (in == NULL) {
211
      if (in == NULL) {
256
        fprintf(stderr, "cannot get empty table for %s: %s\n", user, strerror(errno));
212
        fprintf(stderr, "cannot get empty table for '%s': %s\n", rUser.c_str(), strerror(errno));
257
        fclose(out);
213
        fclose(out);
258
        goto end;
214
        goto end;
259
      }
215
      }
260
    }
216
    }
261
    else {
217
    else {
262
      fprintf(stderr, "cannot read old table for %s: %s\n", user, strerror(errno));
218
      fprintf(stderr, "cannot read old table for '%s': %s\n", rUser.c_str(), strerror(errno));
263
      fclose(out);
219
      fclose(out);
264
      goto end;
220
      goto end;
265
    }
221
    }
266
  }
222
  }
267
 
223
 
Line 281... Line 237...
281
  mt = st.st_mtime; // save modification time for detecting its change
237
  mt = st.st_mtime; // save modification time for detecting its change
282
 
238
 
283
  // Editor selecting algorithm:
239
  // Editor selecting algorithm:
284
  // 1. Check EDITOR environment variable
240
  // 1. Check EDITOR environment variable
285
  // 2. Check VISUAL environment variable
241
  // 2. Check VISUAL environment variable
-
 
242
  // 3. Try to get from configuration
286
  // 3. Check presence of /etc/alternatives/editor
243
  // 4. Check presence of /etc/alternatives/editor
287
  // 4. Use hard-wired editor
244
  // 5. Use hard-wired editor
-
 
245
 
288
  e = getenv("EDITOR");
246
  e = getenv("EDITOR");
289
  if (e == NULL) {
247
  if (e == NULL) {
290
    e = getenv("VISUAL");
248
    e = getenv("VISUAL");
291
    if (e == NULL) {
249
    if (e == NULL) {
-
 
250
     
-
 
251
      if (!IncronCfg::GetValue("editor", ed))
-
 
252
        throw InotifyException("configuration is corrupted", EINVAL);
-
 
253
     
-
 
254
      if (!ed.empty()) {
-
 
255
        e = ed.c_str();
-
 
256
      }
-
 
257
      else {
292
      if (access(INCRON_ALT_EDITOR, X_OK) == 0)
258
        if (access(INCRON_ALT_EDITOR, X_OK) == 0)
293
        e = INCRON_ALT_EDITOR;
259
          e = INCRON_ALT_EDITOR;
294
      else
260
        else
295
        e = INCRON_DEFAULT_EDITOR;
261
          e = INCRON_DEFAULT_EDITOR;
-
 
262
      }
296
    }
263
    }
297
  }
264
  }
298
 
265
 
299
  // this block is explicite due to gotos' usage simplification
266
  // this block is explicite due to gotos' usage simplification
300
  {
267
  {
301
    pid_t pid = fork();
268
    pid_t pid = fork();
302
    if (pid == 0) {
269
    if (pid == 0) {
303
      if (setgid(gid) != 0 || setuid(uid) != 0) {
270
      if (setgid(gid) != 0 || setuid(uid) != 0) {
304
        fprintf(stderr, "cannot set user %s: %s\n", user, strerror(errno));
271
        fprintf(stderr, "cannot set user '%s': %s\n", rUser.c_str(), strerror(errno));
305
        goto end;
272
        goto end;
306
      }    
273
      }    
307
     
274
     
308
      execlp(e, e, s, NULL);
275
      execlp(e, e, s, NULL);
309
      _exit(1);
276
      _exit(1);
Line 335... Line 302...
335
    ok = true;
302
    ok = true;
336
    goto end;
303
    goto end;
337
  }
304
  }
338
 
305
 
339
  {
306
  {
340
    InCronTab ict;
307
    IncronTab ict;
341
    if (ict.Load(s) && ict.Save(tp)) {
308
    if (ict.Load(s) && ict.Save(tp)) {
342
      if (chmod(tp.c_str(), S_IRUSR | S_IWUSR) != 0) {
309
      if (chmod(tp.c_str(), S_IRUSR | S_IWUSR) != 0) {
343
        fprintf(stderr, "cannot change mode of temporary file: %s\n", strerror(errno));
310
        fprintf(stderr, "cannot change mode of temporary file: %s\n", strerror(errno));
344
      }
311
      }
345
    }
312
    }
Line 381... Line 348...
381
#endif // IN_MOVE_SELF
348
#endif // IN_MOVE_SELF
382
 
349
 
383
  printf("\n");
350
  printf("\n");
384
}
351
}
385
352
-
 
353
/// Reloads an user table.
-
 
354
/**
-
 
355
 * \param[in] rUser user name
-
 
356
 * \return true = success, false = otherwise
-
 
357
 */
-
 
358
bool reload_table(const std::string& rUser)
-
 
359
{
-
 
360
  fprintf(stderr, "requesting table reload for user '%s'...\n", rUser.c_str());
-
 
361
 
-
 
362
  std::string tp(IncronTab::GetUserTablePath(rUser));
-
 
363
 
-
 
364
  int fd = open(tp.c_str(), O_WRONLY | O_APPEND);
-
 
365
  if (fd == -1) {
-
 
366
    if (errno == ENOENT) {
-
 
367
      fprintf(stderr, "no table for '%s'\n", rUser.c_str());
-
 
368
      return true;
-
 
369
    }
-
 
370
    else {
-
 
371
      fprintf(stderr, "cannot access table for '%s': %s\n", rUser.c_str(), strerror(errno));
-
 
372
      return false;
-
 
373
    }
-
 
374
  }
-
 
375
 
-
 
376
  close(fd);
-
 
377
 
-
 
378
  fprintf(stderr, "request done\n");
-
 
379
 
-
 
380
  return true;
-
 
381
}
386
382
387
int main(int argc, char** argv)
383
int main(int argc, char** argv)
388
{
384
{
-
 
385
  AppArgs::Init();
-
 
386
-
 
387
  if (!(  AppArgs::AddOption("about",   '?', AAT_NO_VALUE, false)
-
 
388
      &&  AppArgs::AddOption("help",    'h', AAT_NO_VALUE, false)
-
 
389
      &&  AppArgs::AddOption("list",    'l', AAT_NO_VALUE, false)
-
 
390
      &&  AppArgs::AddOption("remove",  'r', AAT_NO_VALUE, false)
-
 
391
      &&  AppArgs::AddOption("edit",    'e', AAT_NO_VALUE, false)
-
 
392
      &&  AppArgs::AddOption("types",   't', AAT_NO_VALUE, false)
-
 
393
      &&  AppArgs::AddOption("reload",  'd', AAT_NO_VALUE, false)
-
 
394
      &&  AppArgs::AddOption("user",    'u', AAT_MANDATORY_VALUE, false)
-
 
395
      &&  AppArgs::AddOption("config",  'f', AAT_MANDATORY_VALUE, false))
-
 
396
      &&  AppArgs::AddOption("version", 'V', AAT_NO_VALUE, false))
-
 
397
  {
-
 
398
    fprintf(stderr, "error while initializing application");
389
  struct arguments arguments;
399
    return 1;
-
 
400
  }
390
 
401
 
391
  arguments.user = NULL;
-
 
392
  arguments.oper = OPER_NONE;
-
 
393
  arguments.file = NULL;
402
  AppArgs::Parse(argc, argv);
394
 
403
 
-
 
404
  if (AppArgs::ExistsOption("help")) {
-
 
405
    fprintf(stderr, "%s\n", INCRONTAB_HELP);
-
 
406
    return 0;
-
 
407
  }
-
 
408
 
-
 
409
  if (AppArgs::ExistsOption("about")) {
395
  argp_parse (&argp, argc, argv, 0, 0, &arguments);
410
    fprintf(stderr, "%s\n", INCRONTAB_DESCRIPTION);
-
 
411
    return 0;
-
 
412
  }
-
 
413
 
-
 
414
  if (AppArgs::ExistsOption("version")) {
-
 
415
    fprintf(stderr, "%s\n", INCRONTAB_VERSION);
-
 
416
    return 0;
-
 
417
  }
396
 
418
 
-
 
419
  bool oper = AppArgs::ExistsOption("list")
-
 
420
          ||  AppArgs::ExistsOption("remove")
-
 
421
          ||  AppArgs::ExistsOption("edit")
-
 
422
          ||  AppArgs::ExistsOption("types")
-
 
423
          ||  AppArgs::ExistsOption("reload");
-
 
424
397
  if (arguments.file != NULL && arguments.oper != OPER_NONE) {
425
  size_t vals = AppArgs::GetValueCount();          
-
 
426
         
-
 
427
  if (!oper && vals == 0) {
398
    fprintf(stderr, "invalid arguments - specify source file or operation\n");
428
    fprintf(stderr, "invalid arguments - specify operation or source file\n");
399
    return 1;
429
    return 1;
400
  }
430
  }
-
 
431
 
401
  if (arguments.file == NULL && arguments.oper == OPER_NONE) {
432
  if (oper && vals > 0) {
402
    fprintf(stderr, "invalid arguments - specify source file or operation\n");
433
    fprintf(stderr, "invalid arguments - operation and source file cannot be combined\n");
403
    return 1;
434
    return 1;
404
  }
435
  }
405
 
436
 
406
  uid_t uid = getuid();
437
  uid_t uid = getuid();
407
 
438
 
-
 
439
  std::string user;
-
 
440
  bool chuser = AppArgs::GetOption("user", user);
-
 
441
 
408
  if (uid != 0 && arguments.user != NULL) {
442
  if (uid != 0 && chuser) {
409
    fprintf(stderr, "cannot access table for user %s: permission denied\n", arguments.user);
443
    fprintf(stderr, "cannot override user to '%s': insufficient privileges\n", user.c_str());
410
    return 1;
444
    return 1;
411
  }
445
  }
412
 
446
 
413
  struct passwd pwd;
447
  struct passwd pwd;
414
 
448
 
415
  if (arguments.user == NULL) {
449
  if (!chuser) {
416
    struct passwd* ppwd = getpwuid(uid);
450
    struct passwd* ppwd = getpwuid(uid);
417
    if (ppwd == NULL) {
451
    if (ppwd == NULL) {
418
      fprintf(stderr, "cannot determine current user\n");
452
      fprintf(stderr, "cannot determine current user\n");
419
      return 1;
453
      return 1;
420
    }
454
    }
421
    memcpy(&pwd, ppwd, sizeof(pwd));
455
    memcpy(&pwd, ppwd, sizeof(pwd));
422
    arguments.user = pwd.pw_name;
456
    user = pwd.pw_name;
423
  }
457
  }
424
  else if (getpwnam(arguments.user) == NULL) {
458
  else if (getpwnam(user.c_str()) == NULL) {
425
    fprintf(stderr, "user %s not found\n", arguments.user);
459
    fprintf(stderr, "user '%s' not found\n", user.c_str());
426
    return 1;
460
    return 1;
427
  }
461
  }
428
 
462
 
429
  if (!InCronTab::CheckUser(arguments.user)) {
-
 
430
    fprintf(stderr, "user %s is not allowed to use incron\n", arguments.user);
-
 
431
    return 1;
463
  try {
432
  }
-
 
433
 
464
 
434
  switch (arguments.oper) {
465
    IncronCfg::Init();
-
 
466
   
-
 
467
    std::string cfg(INCRON_CONFIG);
-
 
468
    if (AppArgs::GetOption("config", cfg)) {
435
    case OPER_NONE:
469
      if (uid != 0) {
436
      fprintf(stderr, "copying table from file: %s\n", arguments.file);
470
        fprintf(stderr, "insufficient privileges to use custom configuration (will use default)\n");
-
 
471
      }
-
 
472
      else if (euidaccess(cfg.c_str(), R_OK) != 0) {
437
      if (!copy_from_file(arguments.file, arguments.user))
473
        perror("cannot read configuration file (will use default)");
438
        return 1;
474
      }
439
      break;
475
    }
-
 
476
   
440
    case OPER_LIST:
477
    IncronCfg::Load(cfg);
-
 
478
   
441
      if (!list_table(arguments.user))
479
    if (!IncronTab::CheckUser(user)) {
-
 
480
      fprintf(stderr, "user '%s' is not allowed to use incron\n", user.c_str());
442
        return 1;
481
      return 1;
-
 
482
    }
-
 
483
   
443
      break;
484
    if (!oper) {
444
    case OPER_REMOVE:
485
      std::string file;
445
      fprintf(stderr, "removing table for user %s\n", arguments.user);
486
      if (!AppArgs::GetValue(0, file)
446
      if (!remove_table(arguments.user))
487
          || !copy_from_file(file, user))
-
 
488
      {
447
        return 1;
489
        return 1;
448
      break;
490
      }
-
 
491
    }
-
 
492
    else {
-
 
493
      if (AppArgs::ExistsOption("list")) {
-
 
494
        if (!list_table(user))
-
 
495
          return 1;
-
 
496
      }
-
 
497
      else if (AppArgs::ExistsOption("remove")) {
-
 
498
        if (!remove_table(user))
449
    case OPER_EDIT:
499
          return 1;
-
 
500
      }
-
 
501
      else if (AppArgs::ExistsOption("edit")) {
450
      if (!edit_table(arguments.user))
502
        if (!edit_table(user))
-
 
503
          return 1;
-
 
504
      }
-
 
505
      else if (AppArgs::ExistsOption("types")) {
-
 
506
        list_types();
-
 
507
      }
-
 
508
      else if (AppArgs::ExistsOption("reload")) {
-
 
509
        if (!reload_table(user))
-
 
510
          return 1;
-
 
511
      }
-
 
512
      else {
-
 
513
        fprintf(stderr, "invalid usage\n");
451
        return 1;
514
        return 1;
452
      break;
515
      }
453
    case OPER_TYPES:
-
 
454
      list_types();
516
    }
-
 
517
   
455
      break;
518
    return 0;    
-
 
519
   
456
    default:
520
  } catch (InotifyException e) {
-
 
521
    fprintf(stderr, "*** unhandled exception occurred ***\n");
457
      fprintf(stderr, "invalid usage\n");
522
    fprintf(stderr, "%s\n", e.GetMessage().c_str());
-
 
523
    fprintf(stderr, "error: (%i) %s\n", e.GetErrorNumber(), strerror(e.GetErrorNumber()));
-
 
524
   
458
      return 1;
525
    return 1;
459
  }
526
  }
460
 
-
 
461
  return 0;
-
 
462
}
527
}