#include #include #include #include #include #include #include #include #include #include #include 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; }