#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

#include "babysit.h"

#define CONTROL_BUFFER_LENGTH 32

void usage_error(const char progname[]) {
    fprintf(stderr, "Usage: %s [OPTIONS] service_dir\n"
                    "    -u: up\n"
                    "    -d: down\n"
                    "    -o: once (don't restart if service stops)\n"
                    "    -p: pause (SIGSTOP)\n"
                    "    -c: continue (SIGCONT)\n"
                    "    -h: hangup (SIGHUP)\n"
                    "    -a: alarm (SIGALRM)\n"
                    "    -i: interrupt (SIGINT)\n"
                    "    -t: terminate (SIGTERM)\n"
                    "    -k: kill (SIGKILL)\n"
                    "    -x: exit\n", progname);
    exit(1);
}

int main(int argc, char * const argv[]) {
    const char *service_dir;
    char control_buffer[CONTROL_BUFFER_LENGTH];
    int control_count = 0;
    int control_fd;
    int option;

    while ((option = getopt(argc, argv, "udopchaitkx")) != -1) {
        if (option == '?'){
            usage_error(argv[0]);
        }

        control_buffer[control_count++] = option;

        if (control_count >= CONTROL_BUFFER_LENGTH) {
            fprintf(stderr, "Only %d options allowed.\n", CONTROL_BUFFER_LENGTH);
            exit(1);
        }
    }

    service_dir = argv[optind];
    if (service_dir == NULL) {
        usage_error(argv[0]);
    }

    if (chdir(service_dir) != 0) {
        perror("chdir service_dir");
        exit(1);
    }

    if ((control_fd = open(CONTROL_FIFO, O_WRONLY|O_NONBLOCK)) == -1) {
        /* According to Single Unix and fifo(4) on Linux, opening a fifo
         * with O_WRONLY|O_NONBLOCK fails with ENXIO if no one is
         * reading from the other end. So iff this open succeeds,
         * babysit is running. If it fails with something other than
         * ENXIO, there is something else hosed anyway, so assume it's
         * not running "properly" */
        if (errno == ENXIO || errno == ENOENT) {
            fprintf(stderr, "babysit not running in %s\n", service_dir);
        }
        else {
            perror("open control_fifo");
        }
        exit(1);
    }

    /* Single Unix says write will always completely write on FIFOs, but just
     * in case, check for != control_count, not == -1 */
    if (write(control_fd, control_buffer, control_count) != control_count) {
        perror("control fifo write error");
        exit(1);
    }
    exit(0);
}


syntax highlighted by Code2HTML, v. 0.9.1