Subversion Repositories public

Rev

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

Rev 65 Rev 67
Line 19... Line 19...
19
#include <string>
19
#include <string>
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
25
25
#include "incron.h"
26
#include "incron.h"
26
#include "incrontab.h"
27
#include "incrontab.h"
27
28
-
 
29
// Alternative editor
-
 
30
#define INCRON_ALT_EDITOR "/etc/alternatives/editor"
28
31
29
// #define INCRON_DEFAULT_EDITOR "nano" // for vim haters like me ;-)
32
// #define INCRON_DEFAULT_EDITOR "nano" // for vim haters like me ;-)
30
#define INCRON_DEFAULT_EDITOR "vim"
33
#define INCRON_DEFAULT_EDITOR "vim"
31
34
32
35
Line 39... Line 42...
39
42
40
static struct argp_option options[] = {
43
static struct argp_option options[] = {
41
  {"list",    'l', 0,      0,  "List the current table" },
44
  {"list",    'l', 0,      0,  "List the current table" },
42
  {"remove",  'r', 0,      0,  "Remove the table completely" },
45
  {"remove",  'r', 0,      0,  "Remove the table completely" },
43
  {"edit",    'e', 0,      0,  "Edit the table" },
46
  {"edit",    'e', 0,      0,  "Edit the table" },
-
 
47
  {"types",   't', 0,      0,  "List all supported event types" },
44
  {"user",    'u', "USER", 0,  "Override the current user" },
48
  {"user",    'u', "USER", 0,  "Override the current user" },
45
  { 0 }
49
  { 0 }
46
};
50
};
47
51
48
/// incrontab operations
52
/// incrontab operations
49
typedef enum
53
typedef enum
50
{
54
{
51
  OPER_NONE,    /// nothing
55
  OPER_NONE,    /// nothing
52
  OPER_LIST,    /// list table
56
  OPER_LIST,    /// list table
53
  OPER_REMOVE,  /// remove table
57
  OPER_REMOVE,  /// remove table
54
  OPER_EDIT     /// edit table
58
  OPER_EDIT,    /// edit table
-
 
59
  OPER_TYPES    /// list event types
55
} InCronTab_Operation_t;
60
} InCronTab_Operation_t;
56
61
57
/// incrontab arguments
62
/// incrontab arguments
58
struct arguments
63
struct arguments
59
{
64
{
Line 81... Line 86...
81
      arguments->oper = OPER_REMOVE;
86
      arguments->oper = OPER_REMOVE;
82
      break;
87
      break;
83
    case 'e':
88
    case 'e':
84
      arguments->oper = OPER_EDIT;
89
      arguments->oper = OPER_EDIT;
85
      break;
90
      break;
-
 
91
    case 't':
-
 
92
      arguments->oper = OPER_TYPES;
-
 
93
      break;
86
    case 'u':
94
    case 'u':
87
      arguments->user = arg;
95
      arguments->user = arg;
88
      break;
96
      break;
89
    case ARGP_KEY_ARG:
97
    case ARGP_KEY_ARG:
90
      if (state->arg_num >= 1)
98
      if (state->arg_num >= 1)
Line 155... Line 163...
155
 */
163
 */
156
bool list_table(const char* user)
164
bool list_table(const char* user)
157
{
165
{
158
  std::string tp(InCronTab::GetUserTablePath(user));
166
  std::string tp(InCronTab::GetUserTablePath(user));
159
 
167
 
160
  if (eaccess(tp.c_str(), R_OK) != 0) {
168
  if (euidaccess(tp.c_str(), R_OK) != 0) {
161
    if (errno == ENOENT) {
169
    if (errno == ENOENT) {
162
      fprintf(stderr, "no table for %s\n", user);
170
      fprintf(stderr, "no table for %s\n", user);
163
      return true;
171
      return true;
164
    }
172
    }
165
    else {
173
    else {
Line 268... Line 276...
268
  if (stat(s, &st) != 0) {
276
  if (stat(s, &st) != 0) {
269
    fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno));
277
    fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno));
270
    goto end;
278
    goto end;
271
  }
279
  }
272
 
280
 
273
  mt = st.st_mtime;
281
  mt = st.st_mtime; // save modification time for detecting its change
274
 
282
 
-
 
283
  // Editor selecting algorithm:
-
 
284
  // 1. Check EDITOR environment variable
-
 
285
  // 2. Check VISUAL environment variable
-
 
286
  // 3. Check presence of /etc/alternatives/editor
-
 
287
  // 4. Use hard-wired editor
275
  e = getenv("EDITOR");
288
  e = getenv("EDITOR");
276
  if (e == NULL)
289
  if (e == NULL) {
-
 
290
    e = getenv("VISUAL");
-
 
291
    if (e == NULL) {
-
 
292
      if (access(INCRON_ALT_EDITOR, X_OK) == 0)
-
 
293
        e = INCRON_ALT_EDITOR;
-
 
294
      else
277
    e = INCRON_DEFAULT_EDITOR;
295
        e = INCRON_DEFAULT_EDITOR;
-
 
296
    }
-
 
297
  }
278
 
298
 
-
 
299
  // this block is explicite due to gotos' usage simplification
279
  {
300
  {
280
    pid_t pid = fork();
301
    pid_t pid = fork();
281
    if (pid == 0) {
302
    if (pid == 0) {
282
      if (setgid(gid) != 0 || setuid(uid) != 0) {
303
      if (setgid(gid) != 0 || setuid(uid) != 0) {
283
        fprintf(stderr, "cannot set user %s: %s\n", user, strerror(errno));
304
        fprintf(stderr, "cannot set user %s: %s\n", user, strerror(errno));
Line 337... Line 358...
337
  unlink(s);
358
  unlink(s);
338
  return ok;
359
  return ok;
339
}
360
}
340
361
341
362
-
 
363
/// Prints the list of all available inotify event types.
-
 
364
void list_types()
-
 
365
{
-
 
366
  printf( "IN_ACCESS,IN_MODIFY,IN_ATTRIB,IN_CLOSE_WRITE,"\
-
 
367
          "IN_CLOSE_NOWRITE,IN_OPEN,IN_MOVED_FROM,IN_MOVED_TO,"\
-
 
368
          "IN_CREATE,IN_DELETE,IN_DELETE_SELF,IN_CLOSE,IN_MOVE,"\
-
 
369
          "IN_ONESHOT,IN_ALL_EVENTS");
-
 
370
   
-
 
371
#ifdef IN_DONT_FOLLOW
-
 
372
  printf(",IN_DONT_FOLLOW");
-
 
373
#endif // IN_DONT_FOLLOW
-
 
374
-
 
375
#ifdef IN_ONLYDIR
-
 
376
  printf(",IN_ONLYDIR");
-
 
377
#endif // IN_ONLYDIR
-
 
378
-
 
379
#ifdef IN_MOVE_SELF
-
 
380
  printf(",IN_MOVE_SELF");
-
 
381
#endif // IN_MOVE_SELF
-
 
382
 
-
 
383
  printf("\n");
-
 
384
}
-
 
385
-
 
386
342
int main(int argc, char** argv)
387
int main(int argc, char** argv)
343
{
388
{
344
  struct arguments arguments;
389
  struct arguments arguments;
345
 
390
 
346
  arguments.user = NULL;
391
  arguments.user = NULL;
Line 403... Line 448...
403
      break;
448
      break;
404
    case OPER_EDIT:
449
    case OPER_EDIT:
405
      if (!edit_table(arguments.user))
450
      if (!edit_table(arguments.user))
406
        return 1;
451
        return 1;
407
      break;
452
      break;
-
 
453
    case OPER_TYPES:
-
 
454
      list_types();
-
 
455
      break;
408
    default:
456
    default:
409
      fprintf(stderr, "invalid usage\n");
457
      fprintf(stderr, "invalid usage\n");
410
      return 1;
458
      return 1;
411
  }
459
  }
412
 
460