diff options
Diffstat (limited to 'ax25rtd/ax25rtctl.c')
-rw-r--r-- | ax25rtd/ax25rtctl.c | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/ax25rtd/ax25rtctl.c b/ax25rtd/ax25rtctl.c new file mode 100644 index 0000000..6f40423 --- /dev/null +++ b/ax25rtd/ax25rtctl.c @@ -0,0 +1,437 @@ +/* $Id: ax25rtctl.c,v 1.7 1997/06/05 18:52:55 oe1kib Exp oe1kib $ + * + * Copyright (c) 1996 Jörg Reuter (jreuter@poboxes.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <getopt.h> +#include <time.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/un.h> + +#include <config.h> +#include "../pathnames.h" + +static const struct option lopts[] = { + {"add", 1, 0, 'a'}, + {"del", 1, 0, 'd'}, + {"list", 1, 0, 'l'}, + {"expire", 1, 0, 'e'}, + {"save", 0, 0, 's'}, + {"reload", 0, 0, 'r'}, + {"shutdown", 0, 0, 'q'}, + {"Version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {"debug", 0, 0, 'x'}, + {"version", 0, 0, 'v'}, + {NULL, 0, 0, 0 } +}; + +static const char *sopts = "a:d:l:e:srqvVh"; + +static void usage(void) +{ + fprintf(stderr,"usage:\n"); + fprintf(stderr,"ax25rtctl -a|--add ax25 <callsign> <dev> <time> [digipeater]\n"); + fprintf(stderr," -a|--add ip <ip> <dev> <time> <call> <ipmode>\n"); + fprintf(stderr," -d|--del ax25 <callsign> <dev>\n"); + fprintf(stderr," -d|--del ip <ip>\n"); + fprintf(stderr," -l|--list ax25|ip\n"); + fprintf(stderr," -e|--expire <minutes>\n"); + fprintf(stderr," -s|--save\n"); + fprintf(stderr," -r|--reload\n"); + fprintf(stderr," -q|--shutdown\n"); + fprintf(stderr," -V|--Version\n"); + fprintf(stderr," -h|--help\n"); + fprintf(stderr," -v|--version\n"); + exit(1); +} + +static int open_socket(void) +{ + int sock, addrlen; + struct sockaddr_un addr; + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + { + perror("ax25rtctl socket"); + exit(1); + } + + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, DATA_AX25ROUTED_CTL_SOCK); + addrlen = strlen(DATA_AX25ROUTED_CTL_SOCK) + sizeof(addr.sun_family); + + if (connect(sock, (struct sockaddr *) &addr, addrlen) < 0) + { + perror("ax25rtctl connect"); + exit(1); + } + + return sock; +} + +static int wsock(int sock, char *s) +{ + return write(sock, s, strlen(s)); +} + +static char *get_next_arg(char **p) +{ + char *p2; + + if (p == NULL || *p == NULL) + return NULL; + + p2 = *p; + for (; *p2 && *p2 == ' '; p2++) ; + if (!*p2) + return NULL; + + *p = strchr(p2, ' '); + if (*p != NULL) + { + **p = '\0'; + (*p)++; + } + + return p2; +} + +static void list_ax25(void) +{ + int sock, len, offs; + char buf[512], *b, *s, *digi, *call, *dev, *ct; + time_t t; + + sock = open_socket(); + + wsock(sock, "list ax25\n"); + + offs = 0; + + printf("Callsign Port Last update Path\n"); + +/* + DB0PRA-15 scc3 Tue Aug 6 16:35:38 1996 +*/ + + while(1) + { + len = read(sock, buf+offs, sizeof(buf)-offs-1); + if (len <= 0) + { + close(sock); + return; + } + + buf[len+offs] = '\0'; + s = buf; + for (s = buf; (b = strchr(s, '\n')) != NULL; s = b+1) + { + *b = '\0'; + + if (s[0] == '.') + { + close(sock); + return; + } + + call = get_next_arg(&s); + dev = get_next_arg(&s); + t = strtol(get_next_arg(&s), NULL, 16); + + if (t == 0) + { + ct = "(permanent)"; + ct = strdup(ct); + } else { + ct = strdup(ctime(&t)); + ct[strlen(ct)-6] = '\0'; + } + + printf("%-9s %-6s %s", call, dev, ct); + + free(ct); + + while ( (digi = get_next_arg(&s)) != NULL) + printf(" %s", digi); + + printf("\n"); + } + + if (b == NULL && s != NULL) + { + offs = strlen(s); + if (offs) + memcpy(buf, s, offs); + } + } + + close(sock); +} + +static void list_ip(void) +{ + int sock, len, offs; + char buf[512], *b, *s, *ip, *call, *dev, *ct, *mode; + time_t t; + + sock = open_socket(); + + wsock(sock, "list ip\n"); + + offs = 0; + printf("IP Address Port Callsign Mode Last update\n"); + +/* + 255.255.255.255 scc3 DB0PRA-15 v Thu Jan 7 06:54:19 1971 + */ + while(1) + { + len = read(sock, buf+offs, sizeof(buf)-offs-1); + if (len <= 0) + { + close(sock); + return; + } + + buf[len+offs] = '\0'; + s = buf; + for (s = buf; (b = strchr(s, '\n')) != NULL; s = b+1) + { + *b = '\0'; + + if (s[0] == '.') + { + close(sock); + return; + } + + ip = get_next_arg(&s); + dev = get_next_arg(&s); + t = strtol(get_next_arg(&s), NULL, 16); + call = get_next_arg(&s); + mode = get_next_arg(&s); + + if (t == 0) + { + ct = "(permanent)"; + } else { + ct = ctime(&t); + ct[strlen(ct)-6] = '\0'; + } + + printf("%-15s %-6s %-9s %-4s %s\n", ip, dev, call, mode, ct); + } + + if (b == NULL && s != NULL) + { + offs = strlen(s); + if (offs) + memcpy(buf, s, offs); + } + } + + close(sock); +} + +static void Version(void) +{ + int sock; + char buf[256]; + + printf("ax25rtctl $Revision: 1.7 $\n"); + sock = open_socket(); + wsock(sock, "version\n"); + read(sock, buf, sizeof(buf)); + printf("%s", buf); + close(sock); +} + +static void debug(void) +{ + int sock, n, k; + unsigned char buf[256]; + fd_set fd_set, fd_set2; + struct timeval tv; + + + sock = open_socket(); + + while (1) + { + FD_ZERO(&fd_set); + FD_SET(0, &fd_set); + FD_SET(sock, &fd_set); + + FD_ZERO(&fd_set2); + FD_SET(sock, &fd_set2); + + tv.tv_sec = 0; + tv.tv_usec = 0; + if (select(sock+1, &fd_set, NULL, &fd_set2, &tv) < 0) + { + perror("socket gone"); + exit(1); + } + + if (FD_ISSET(sock, &fd_set2)) + exit(0); + + if (FD_ISSET(0, &fd_set)) + { + n = read(0, buf, sizeof(buf)); + if (n) + { + k = write(sock, buf, n); + if (k <= 0) + exit(0); + } + } + + if (FD_ISSET(sock, &fd_set)) + { + n = read(sock, buf, sizeof(buf)); + if (n) + write(0, buf, n); + } + } +} + +int main(int argc, char **argv) +{ + int sock, cmd, k, len; + unsigned char buf[256]; + int opt_ind = 0; + long when; + + cmd = getopt_long(argc, argv, sopts, lopts, &opt_ind); + switch (cmd) + { + case 'a': + if (!strcmp(optarg, "ax25")) + { + if (argc < optind+3) + usage(); + + len = sprintf(buf, "add ax25"); + for (k = optind; k < argc; k++) + len += sprintf(buf+len, " %s", argv[k]); + sprintf(buf+len, "\n"); + + sock = open_socket(); + wsock(sock, buf); + close(sock); + } else + if (!strcmp(optarg, "ip")) + { + if (argc < optind+5) + usage(); + + len = sprintf(buf, "add ip"); + for (k = optind; k < argc; k++) + len += sprintf(buf+len, " %s", argv[k]); + sprintf(buf+len, "\n"); + + sock = open_socket(); + wsock(sock, buf); + close(sock); + } else + usage(); + return 0; + case 'd': + if (!strcmp(optarg, "ax25")) + { + if (argc < optind+2) + usage(); + + sprintf(buf, "del ax25 %s %s\n", argv[optind], argv[optind+1]); + + sock = open_socket(); + wsock(sock, buf); + close(sock); + } else + if (!strcmp(optarg, "ip")) + { + if (argc < optind+1) + usage(); + + sprintf(buf, "del ip %s\n", argv[optind]); + + sock = open_socket(); + wsock(sock, buf); + close(sock); + } else + usage(); + return 0; + case 'l': + if (!strcmp(optarg, "ax25")) + list_ax25(); + else if (!strcmp(optarg, "ip")) + list_ip(); + else + usage(); + return 0; + case 'e': + when = atoi(optarg); + if (when <= 0) + usage(); + sock = open_socket(); + sprintf(buf, "expire %ld\n", when); + wsock(sock, buf); + close(sock); + return 0; + case 's': + sock = open_socket(); + wsock(sock, "save\n"); + close(sock); + return 0; + case 'r': + sock = open_socket(); + wsock(sock, "reload\n"); + close(sock); + return 0; + case 'q': + sock = open_socket(); + wsock(sock, "shutdown\n"); + close(sock); + return 0; + case 'V': + Version(); + return 0; + case 'v': + printf("ax25rtctl: %s\n", VERSION); + return 0; + case 'x': + debug(); + case ':': + case 'h': + case '?': + default: + usage(); + } + usage(); + return 1; +} |