tformatting: 4 spaces -> 8 tabs - wendy - watch files/directories and run commands on any event
 (HTM) git clone git://z3bra.org/wendy
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 9fd06b0d1bdbc8cac24a9dd9a0bce8fe570a512f
 (DIR) parent 496ea93e3942b856d01b7a955c6e069b3828644b
 (HTM) Author: z3bra <willy@mailoo.org>
       Date:   Mon, 30 Mar 2015 20:43:57 +0200
       
       formatting: 4 spaces -> 8 tabs
       
       Diffstat:
         M wendy.c                             |     382 +++++++++++++++----------------
       
       1 file changed, 188 insertions(+), 194 deletions(-)
       ---
 (DIR) diff --git a/wendy.c b/wendy.c
       t@@ -27,13 +27,12 @@
        /* maximum number of event * queuing at the same time */
        #define BUF_LEN         (512 * (EVENT_SIZE+16))
        
       -#define DEFAULT_FILE    "." /* defaults to current directory */
        #define DEFAULT_CHECK   1   /* defaults to 1 second */
        
        struct node_t {
       -    int wd;
       -    char path[PATH_MAX];
       -    struct node_t *next;
       +        int wd;
       +        char path[PATH_MAX];
       +        struct node_t *next;
        };
        
        extern char **environ;
       t@@ -41,233 +40,228 @@ extern char **environ;
        int verbose = 0, nb = 0;
        struct node_t *head = NULL;
        
       -    void
       +        void
        usage()
        {
       -    fputs("usage: wendy [-C] [-D] [-M] [-m mask] [-l] [-f file] [-t timeout] [-q] "
       -            "[-e command [args] ..]\n"
       -            "\t-C           : raise creation events (default)\n"
       -            "\t-D           : raise deletion events\n"
       -            "\t-M           : raise modification events\n"
       -            "\t-m mask      : set mask manually (see -l))\n"
       -            "\t-l           : list events mask values\n"
       -            "\t-f file      : file to watch (everything is a file)\n"
       -            "\t-t timeout   : time between event check (in seconds)\n"
       -            "\t-v           : talk to me, program\n"
       -            "\t-e command   : command to launch (must be the last argument!)\n",
       -            stdout);
       -    exit(1);
       +        fputs("usage: wendy [-m mask] [-l] [-f file] [-t timeout] [-q] "
       +                        "[-e command [args] ..]\n"
       +                        "\t-m mask      : set mask manually (see -l))\n"
       +                        "\t-l           : list events mask values\n"
       +                        "\t-f file      : file to watch (everything is a file)\n"
       +                        "\t-t timeout   : time between event check (in seconds)\n"
       +                        "\t-v           : talk to me, program\n"
       +                        "\t-e command   : command to launch (must be the last arg!)\n",
       +                        stdout);
       +        exit(1);
        }
        
       -    void
       +        void
        list_events()
        {
       -    fprintf(stdout,
       -            "IN_ACCESS ........ %u\n"
       -            "IN_MODIFY ........ %u\n"
       -            "IN_ATTRIB ........ %u\n"
       -            "IN_CLOSE_WRITE ... %u\n"
       -            "IN_CLOSE_NOWRITE . %u\n"
       -            "IN_OPEN .......... %u\n"
       -            "IN_MOVED_FROM .... %u\n"
       -            "IN_MOVED_TO ...... %u\n"
       -            "IN_CREATE ........ %u\n"
       -            "IN_DELETE ........ %u\n"
       -            "IN_DELETE_SELF ... %u\n"
       -            "IN_MOVE_SELF ..... %u\n"
       -            "IN_ALL_EVENTS .... %u\n"
       -            "IN_UNMOUNT ....... %u\n",
       -            IN_ACCESS,
       -            IN_MODIFY,
       -            IN_ATTRIB,
       -            IN_CLOSE_WRITE,
       -            IN_CLOSE_NOWRITE,
       -            IN_OPEN,
       -            IN_MOVED_FROM,
       -            IN_MOVED_TO,
       -            IN_CREATE,
       -            IN_DELETE,
       -            IN_DELETE_SELF,
       -            IN_MOVE_SELF,
       -            IN_ALL_EVENTS,
       -            IN_UNMOUNT
       -                );
       -    exit(0);
       +        fprintf(stdout,
       +                        "IN_ACCESS ........ %u\n"
       +                        "IN_MODIFY ........ %u\n"
       +                        "IN_ATTRIB ........ %u\n"
       +                        "IN_CLOSE_WRITE ... %u\n"
       +                        "IN_CLOSE_NOWRITE . %u\n"
       +                        "IN_OPEN .......... %u\n"
       +                        "IN_MOVED_FROM .... %u\n"
       +                        "IN_MOVED_TO ...... %u\n"
       +                        "IN_CREATE ........ %u\n"
       +                        "IN_DELETE ........ %u\n"
       +                        "IN_DELETE_SELF ... %u\n"
       +                        "IN_MOVE_SELF ..... %u\n"
       +                        "IN_ALL_EVENTS .... %u\n"
       +                        "IN_UNMOUNT ....... %u\n",
       +                        IN_ACCESS,
       +                        IN_MODIFY,
       +                        IN_ATTRIB,
       +                        IN_CLOSE_WRITE,
       +                        IN_CLOSE_NOWRITE,
       +                        IN_OPEN,
       +                        IN_MOVED_FROM,
       +                        IN_MOVED_TO,
       +                        IN_CREATE,
       +                        IN_DELETE,
       +                        IN_DELETE_SELF,
       +                        IN_MOVE_SELF,
       +                        IN_ALL_EVENTS,
       +                        IN_UNMOUNT
       +                                );
       +        exit(0);
        }
        
       -    char *
       +        char *
        read_filename(int fd)
        {
       -    int i;
       -    char *fn = NULL, ch;
       -
       -    fn = malloc(PATH_MAX);
       -    if (!fn)
       -        return NULL;
       -
       -    for (i=0; read(fd, &ch, 1) > 0 && i < PATH_MAX; i++) {
       -        if (ch == 0 || ch == '\n') {
       -            *(fn + i + 1) = 0;
       -            return fn;
       -        } else {
       -            *(fn+i) = ch;
       -        }
       -    }
       -
       -    return NULL;
       +        int i;
       +        char *fn = NULL, ch;
       +
       +        fn = malloc(PATH_MAX);
       +        if (!fn)
       +                return NULL;
       +
       +        for (i=0; read(fd, &ch, 1) > 0 && i < PATH_MAX; i++) {
       +                if (ch == 0 || ch == '\n') {
       +                        *(fn + i + 1) = 0;
       +                        return fn;
       +                } else {
       +                        *(fn+i) = ch;
       +                }
       +        }
       +
       +        return NULL;
        }
        
       -    int
       +        int
        execvpe(const char *program, char **argv, char **envp)
        {
       -    char **saved = environ;
       -    int rc;
       -    environ = envp;
       -    rc = execvp(program, argv);
       -    environ = saved;
       -    return rc;
       +        char **saved = environ;
       +        int rc;
       +        environ = envp;
       +        rc = execvp(program, argv);
       +        environ = saved;
       +        return rc;
        }
        
       -    struct node_t *
       +        struct node_t *
        add_node(int wd, const char *path)
        {
       -    struct node_t *n = NULL;
       +        struct node_t *n = NULL;
        
       -    n = malloc(sizeof(struct node_t));
       +        n = malloc(sizeof(struct node_t));
       +        if (!n)
       +                return NULL;
        
       -    if (!n)
       -        return NULL;
       +        n->wd = wd;
       +        strncpy(n->path, path, PATH_MAX);
       +        n->next = head ? head : NULL;
       +        head = n;
        
       -    n->wd = wd;
       -    strncpy(n->path, path, PATH_MAX);
       -
       -    n->next = head ? head : NULL;
       -    head = n;
       -
       -    return n;
       +        return n;
        }
        
       -    const char *
       +        const char *
        wd_name(int wd)
        {
       -    struct node_t *n = head;
       +        struct node_t *n = head;
        
       -    while (n && n->wd != wd)
       -        n = n->next;
       +        while (n && n->wd != wd)
       +                n = n->next;
        
       -    return n ? n->path : "unknown";
       +        return n ? n->path : "unknown";
        }
        
       -    int
       +        int
        watch_node(int fd, const char *path, uint32_t mask)
        {
       -    int wd = -1;
       +        int wd = -1;
        
       -    if (!path)
       -        return -1;
       +        if (!path)
       +                return -1;
        
       -    /* add a watcher on the file */
       -    wd  = inotify_add_watch(fd, path, mask);
       -    if (wd < 0) {
       -        perror("inotify_add_watch");
       -        exit(1);
       -    }
       +        /* add a watcher on the file */
       +        wd  = inotify_add_watch(fd, path, mask);
       +        if (wd < 0) {
       +                perror("inotify_add_watch");
       +                exit(1);
       +        }
        
       -    add_node(wd, path);
       -    nb++;
       +        add_node(wd, path);
       +        nb++;
        
       -    return wd;
       +        return wd;
        }
        
       -    int
       +        int
        main (int argc, char **argv)
        {
       -    int  fd, len, i = 0, timeout = 0, ignore = 0;
       -    uint32_t mask = 0;
       -    char buf[BUF_LEN];
       -    char *fn = NULL;
       -    char **cmd = NULL;
       -    struct inotify_event *ev;
       -
       -    if ((argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage();
       -
       -    /* get file descriptor */
       -    fd = inotify_init();
       -    if (fd < 0)
       -        perror("inotify_init");
       -
       -
       -    /* parse option given. see usage() above */
       -    for(i = 1; (i < argc) && (argv[i][0] == '-') && !ignore; i++) {
       -        switch (argv[i][1]) {
       -            case 'C': mask |= IN_CREATE; break;
       -            case 'D': mask |= IN_DELETE; break;
       -            case 'M': mask |= IN_MODIFY; break;
       -            case 'm': mask = atoi(argv[++i]); break;
       -            case 'l': list_events(); break;
       -            case 'v': verbose += 1; break;
       -            case 'f': watch_node(fd, argv[++i], mask); break;
       -            case 't': timeout = atoi(argv[++i]); break;
       -            case 'e': cmd = &argv[++i]; ignore=1; break;
       -            default: usage();
       -        }
       -    }
       -
       -    /* test given arguments */
       -    if (!timeout)   { timeout = DEFAULT_CHECK; }
       -
       -    if (!nb) {
       -        while ((fn = read_filename(0)) != NULL)
       -            watch_node(fd, fn, mask);
       -
       -        free(fn);
       -    }
       -
       -    /* start looping */
       -    while (nb>0) {
       -        /* get every event raised, and queue them */
       -        len = read(fd, buf, BUF_LEN);
       -        if (!len || len < 0) {
       -            perror("read");
       -        }
       -
       -        i = 0;
       -
       -        /* treat all events queued */
       -        while (i < len) {
       -
       -            /* get events one by one */
       -            ev = (struct inotify_event *) &buf[i];
       -
       -            if (verbose) {
       -                if (ev->mask & IN_IGNORED) {
       -                    printf("!\t%s\n", ev->len? ev->name: wd_name(ev->wd));
       -                    nb--;
       -                }
       -
       -                printf("%-3u\t%s\n", ev->mask, ev->len? ev->name: wd_name(ev->wd));
       -            }
       -
       -            /*
       -             * Do not do anything if no command given.
       -             * Also only execute the command if the file concerned by the event
       -             * is the one we're watching, or if we're not looking for a specific
       -             * file.
       -             *
       -             * If you don't undersand this sentence, don't worry. Me neither.
       -             * Just trust the if().
       -             */
       -            if (cmd) {
       -                /* OMG a new event ! Quick, raise an alert ! */
       -                if (!fork()) { execvpe(cmd[0], cmd, environ); }
       -            }
       -
       -            /* jump to the next one */
       -            i += EVENT_SIZE + ev->len;
       -        }
       -        /* wait before queuing events */
       -        sleep(timeout);
       -    }
       -
       -    return EXIT_SUCCESS;
       +        int  fd, len, i = 0, timeout = 0, ignore = 0;
       +        uint32_t mask = 0;
       +        char buf[BUF_LEN];
       +        char *fn = NULL;
       +        char **cmd = NULL;
       +        struct inotify_event *ev;
       +
       +        if ((argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage();
       +
       +        /* get file descriptor */
       +        fd = inotify_init();
       +        if (fd < 0)
       +                perror("inotify_init");
       +
       +
       +        /* parse option given. see usage() above */
       +        for(i = 1; (i < argc) && (argv[i][0] == '-') && !ignore; i++) {
       +                switch (argv[i][1]) {
       +                        case 'm': mask = atoi(argv[++i]); break;
       +                        case 'l': list_events(); break;
       +                        case 'v': verbose += 1; break;
       +                        case 'f': watch_node(fd, argv[++i], mask); break;
       +                        case 't': timeout = atoi(argv[++i]); break;
       +                        case 'e': cmd = &argv[++i]; ignore=1; break;
       +                        default: usage();
       +                }
       +        }
       +
       +        /* test given arguments */
       +        if (!timeout)   { timeout = DEFAULT_CHECK; }
       +
       +        if (!nb) {
       +                while ((fn = read_filename(0)) != NULL)
       +                        watch_node(fd, fn, mask);
       +
       +                free(fn);
       +        }
       +
       +        /* start looping */
       +        while (nb>0) {
       +                /* get every event raised, and queue them */
       +                len = read(fd, buf, BUF_LEN);
       +                if (!len || len < 0) {
       +                        perror("read");
       +                }
       +
       +                i = 0;
       +
       +                /* treat all events queued */
       +                while (i < len) {
       +
       +                        /* get events one by one */
       +                        ev = (struct inotify_event *) &buf[i];
       +
       +                        if (verbose) {
       +                                if (ev->mask & IN_IGNORED) {
       +                                        printf("!\t%s\n", ev->len? ev->name:
       +                                                        wd_name(ev->wd));
       +                                        nb--;
       +                                }
       +
       +                                printf("%u\t%s\n", ev->mask, ev->len?
       +                                                ev->name: wd_name(ev->wd));
       +                                fflush(stdout);
       +                        }
       +
       +                        /*
       +                         * Do not do anything if no command given.  Also only
       +                         * execute the command if the file concerned by the
       +                         * event is the one we're watching, or if we're not
       +                         * looking for a specific file.
       +                         *
       +                         * If you don't undersand this sentence, don't worry.
       +                         * Me neither.  Just trust the if().
       +                         */
       +                        if (cmd) {
       +                                /* OMG a new event ! Quick, raise an alert ! */
       +                                if (!fork()) { execvpe(cmd[0], cmd, environ); }
       +                        }
       +
       +                        /* jump to the next one */
       +                        i += EVENT_SIZE + ev->len;
       +                }
       +                /* wait before queuing events */
       +                sleep(timeout);
       +        }
       +
       +        return EXIT_SUCCESS;
        }