diff options
author | Asbjørn Sloth Tønnesen <asbjorn@asbjorn.biz> | 2012-08-07 18:26:52 +0000 |
---|---|---|
committer | Asbjørn Sloth Tønnesen <asbjorn@asbjorn.biz> | 2012-08-07 18:26:52 +0000 |
commit | dd038e573b01235290f0bd790bd2c51638a1e767 (patch) | |
tree | fa818e223f59b50b61efaab5d1d59ebdc938072d /freebsd | |
parent | 3c009483447338700b67a15eeed09b7f5e9e7046 (diff) | |
download | labitrack-dd038e573b01235290f0bd790bd2c51638a1e767.tar.gz labitrack-dd038e573b01235290f0bd790bd2c51638a1e767.tar.xz labitrack-dd038e573b01235290f0bd790bd2c51638a1e767.zip |
add various support files
Signed-off-by: Asbjørn Sloth Tønnesen <asbjorn@asbjorn.biz>
Diffstat (limited to 'freebsd')
-rw-r--r-- | freebsd/kqueue.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/freebsd/kqueue.c b/freebsd/kqueue.c new file mode 100644 index 0000000..e8825db --- /dev/null +++ b/freebsd/kqueue.c @@ -0,0 +1,142 @@ +#include <sys/types.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/event.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +int printer_ready; +char * printer; +char * queue_dir; +char * trigger; +#define BUFLEN 50 +char queue_dir_new[BUFLEN]; +char trigger_cmd[BUFLEN]; + +int open_and_subscribe(struct kevent * change, const char * path) +{ + int f; + f = open(path, O_RDONLY); + if (f == -1) { + perror("open"); + return -1; + } + + EV_SET(change, f, EVFILT_VNODE, + EV_ADD | EV_ENABLE | EV_ONESHOT, + NOTE_DELETE | NOTE_EXTEND | + NOTE_WRITE | NOTE_ATTRIB, + 0, 0); +} + +int check_printer_status(){ + struct stat buf; + //printf("%s\n", printer); + int r = stat(printer, &buf); + if (r<0) { + if (printer_ready != 0) { + printf("Printer offline\n"); + } + printer_ready = 0; + if (errno == ENOENT) { + printf("Printer not detected\n"); + } else { + perror("stat"); + return -1; + } + } else { + if (printer_ready != 1) { + printf("Printer online\n"); + print_loop(printer, queue_dir); + } + printer_ready = 1; + } + return 0; +} + +int print_loop() +{ + FILE * p; + int status; + char buf[BUFLEN]; + printf("Print loop\n"); + p = popen(trigger_cmd, "r"); + if (p == NULL) + perror("popen"); + while (fgets(buf, BUFLEN, p) != NULL) + printf("%s", buf); + status = pclose(p); + if (status != 0) { + printf("Trigger exited with status %d\n", status); + } + return status; +} + +int main(int argc, const char * argv[]) +{ + int fd, fq, kq, nev; + struct kevent change; + struct kevent event; + + int len; + + if (argc != 4) { + fprintf(stderr, "usage: %s printer queue_dir trigger\n", argv[0]); + return -1; + } + printer = strdup(argv[1]); + queue_dir = strdup(argv[2]); + trigger = strdup(argv[3]); + + len = snprintf(trigger_cmd, BUFLEN, "%s %s %s", trigger, printer, queue_dir); + if (len >= BUFLEN - 1) { + printf("Buffer too small\n"); + return -1; + } + + len = snprintf(queue_dir_new, BUFLEN, "%s/new", queue_dir); + if (len >= BUFLEN - 1) { + printf("Buffer too small\n"); + return -1; + } + + printer_ready = 0; + + kq = kqueue(); + if (kq == -1) + perror("kqueue"); + + fq = open_and_subscribe(&change, queue_dir_new); + + struct timespec timeout; + timeout.tv_sec = 5; + timeout.tv_nsec = 0; + + check_printer_status(); + for (;;) { + nev = kevent(kq, &change, 1, &event, 1, &timeout); + if (nev == -1) + perror("kevent"); + if (nev == 0) { // timeout + check_printer_status(); + } else if (nev > 0) { + if (event.fflags & NOTE_DELETE) { + continue; + } + printf("Got event for %d\n", event.ident); + if (printer_ready) { + print_loop(printer, queue_dir, trigger); + } + } + } + + close(kq); + close(fq); + close(fd); + return EXIT_SUCCESS; +} |