
/*
 * SLIPCTL.C - send command to RUNSLIP slip manager
 *
 * (c)Copyright 1994, Matthew Dillon, All rights reserved.  This code may
 *    be used in any project, commercial or otherwise, as long as I am given
 *    appropriate credit and as long as this copyright remains intact in all
 *    source and document files.
 */

#include "defs.h"

int command(int fd, const char *cmd, char **av);

int
main(int ac, char **av)
{
    int fd;
    int r = 1;
    struct stat st;

    if (ac == 1) {
        puts("slipctl command slipid");
        puts("slipon slipid [device]");
        puts("slipoff slipid");
        puts("slipreset slipid [device]");
        exit(0);
    }

    /*
     * Get a handle on the command file, exclusive-lock it, and check
     * for the only timing window (against runslip locking and deleting
     * it just after we open the file).
     */

    while ((fd = open(RUNSLIP_CMD, O_CREAT|O_APPEND|O_WRONLY, 0660)) >= 0) {
        flock(fd, LOCK_EX);
        fstat(fd, &st);
        if (st.st_nlink != 0) {
            if (strstr(av[0], "off")) {
                r = command(fd, "disable", &av[1]);
            } else if (strstr(av[0], "on")) {
                r = command(fd, "enable", &av[1]);
            } else if (strstr(av[0], "reset")) {
                r = command(fd, "reset", &av[1]);
            } else {
                r = command(fd, av[1], &av[2]);
            }
            break;
        }
        flock(fd, LOCK_UN);
        close(fd);
        /* loop try again */
    }
    if (fd < 0) {
        printf("unable to append to %s\n", RUNSLIP_CMD);
    } else {
        flock(fd, LOCK_UN);
        close(fd);
    }
    return(r);
}

int
command(int fd, const char *cmd, char **av)
{
    int r = 0;
    char buf[256];

    buf[0] = 0;

    if (strlen(cmd) > 64) {
        printf("argument error\n");
        r = 1;
    } else {
	int i;
	int l;

        strcpy(buf, cmd);

        for (i = 0; av[i]; ++i) {
            if (strlen(buf) + strlen(av[i]) + 3 > sizeof(buf)) {
                printf("argument error\n");
                r = 1;
                break;
            }
            strcat(buf, " ");
            strcat(buf, av[i]);
	}
    }
    if (r == 0) {
    	strcat(buf, "\n");
    	write(fd, buf, strlen(buf));
    }
    return(r);
}

