1/***********************************************************************
2*
3* cmd-control.c
4*
5* Simple command-line program for sending commands to L2TP daemon
6*
7* Copyright (C) 2002 by Roaring Penguin Software Inc.
8*
9* This software may be distributed under the terms of the GNU General
10* Public License, Version 2, or (at your option) any later version.
11*
12* LIC: GPL
13*
14***********************************************************************/
15
16static char const RCSID[] =
17"$Id: cmd-control.c 3323 2011-09-21 18:45:48Z lly.dev $";
18#include <stdio.h>
19#include <sys/socket.h>
20#include <sys/un.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <stdlib.h>
24#include <syslog.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <errno.h>
28#include <sys/uio.h>
29
30
31/**********************************************************************
32* %FUNCTION: send_cmd
33* %ARGUMENTS:
34*  cmd -- command to send to server
35* %RETURNS:
36*  file descriptor for channel to server
37* %DESCRIPTION:
38*  Sends a command to the server
39***********************************************************************/
40static int
41send_cmd(char const *cmd, char const *sockpath)
42{
43    struct sockaddr_un addr;
44    int fd;
45    struct iovec v[2];
46
47    /* Do not send zero-length command */
48    if (!*cmd) {
49	errno = ESPIPE;
50	return -1;
51    }
52
53    memset(&addr, 0, sizeof(addr));
54    addr.sun_family = AF_LOCAL;
55    strncpy(addr.sun_path, sockpath, sizeof(addr.sun_path) - 1);
56
57    fd = socket(AF_LOCAL, SOCK_STREAM, 0);
58    if (fd < 0) {
59	perror("socket");
60	return -1;
61    }
62    if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
63	perror("connect");
64	close(fd);
65	return -1;
66    }
67    v[0].iov_base = (char *) cmd;
68    v[0].iov_len = strlen(cmd);
69    v[1].iov_base = "\n";
70    v[1].iov_len = 1;
71    writev(fd, v, 2);
72    return fd;
73}
74
75static void
76usage(int argc, char *argv[], int exitcode)
77{
78    fprintf(stderr, "Usage: %s [-s socket] command\n", argv[0]);
79    exit(exitcode);
80}
81
82int
83main(int argc, char *argv[])
84{
85    int fd;
86    int n;
87    int opt;
88    char buf[4096];
89    char *sockpath = "/var/run/l2tpctrl";
90
91    while((opt = getopt(argc, argv, "s:h")) != -1) {
92	switch(opt) {
93	case 's':
94	    sockpath = optarg;
95	    break;
96	default:
97	    usage(argc, argv, (opt == 'h') ? EXIT_SUCCESS : EXIT_FAILURE);
98	}
99    }
100
101    if (optind >= argc) {
102	usage(argc, argv, EXIT_FAILURE);
103    }
104
105    fd = send_cmd(argv[optind], sockpath);
106    if (fd < 0) {
107	return 1;
108    }
109
110    for(;;) {
111	n = read(fd, buf, sizeof(buf));
112	if (n < 0) {
113	    perror("read");
114	    printf("\n");
115	    close(fd);
116	    return 1;
117	}
118	if (n == 0) {
119	    printf("\n");
120	    close(fd);
121	    return 0;
122	}
123	write(1, buf, n);
124    }
125}
126
127