summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2015-05-25 20:57:47 +0200
committerRalf Baechle <ralf@linux-mips.org>2015-05-25 21:02:13 +0200
commit6911c1b1acd455e514de2fc88b3eaf0a23cabdd6 (patch)
tree4bcb25b6fd2e2374f66b5000b5ff12b6f7240ddf
parent4984e59635ed76196dc5f9a18ae8118be4853758 (diff)
Add Tomi Manninen OH2BNS's axwrapper program.
Axwrapper first creates a pipe and then forks and execs the program <server-program> with arguments given at the axwrapper command line. The argv[0] argument is mandatory; further arguments are optional. The parent process then sits and waits for any I/O to and from the user and converts any carriage return characters from the user to line feeds and any line feeds from the program to carriage returns. This is useful when starting non-AX.25-aware programs from ax25d. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--AUTHORS1
-rw-r--r--ChangeLog1
-rw-r--r--ax25-tools.spec.in2
-rw-r--r--ax25/.gitignore1
-rw-r--r--ax25/Makefile.am4
-rw-r--r--ax25/ax25d.81
-rw-r--r--ax25/ax25d.conf.51
-rw-r--r--ax25/axwrapper.825
-rw-r--r--ax25/axwrapper.c225
9 files changed, 260 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index 15d81ee..ca85b04 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,4 +1,5 @@
axspawn Joerg Reuter DL1BKE <jreuter@poboxes.com>
+axwrapper Tomi Manninen OH2BNS <oh2bns@sral.fi>
ax25ipd Rob Mayfield VK5XXX <mayfieldrob@mail.dec.com>
ax25rtd Klaus Kudielka <oe1kib@oe1xtu.ampr.org>
bpqparms Joerg Reuter DL1BKE <jreuter@poboxes.com>
diff --git a/ChangeLog b/ChangeLog
index 228416c..66435ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,7 @@ ax25-tools (0.0.10)
2.2.1. In the unexpected case somebody should still need them the
patches can be found in older releases and the source archive.
* Add support for building rpm packages.
+ * Add Tomi Manninen OH2BNS's axwrapper program.
-- Ralf Baechle DL5RB <ralf@linux-mips.org> Sat, 6 Jun 2009 17:36:01 +0100
diff --git a/ax25-tools.spec.in b/ax25-tools.spec.in
index f49fe28..6931272 100644
--- a/ax25-tools.spec.in
+++ b/ax25-tools.spec.in
@@ -23,6 +23,7 @@ line programs; the GUI programs are contained in ax25-tools-x package.
* axctl - configure/Kill running AX.25 connections
* axparms - configure AX.25 interfaces
* axspawn - allow automatic login to a Linux system
+ * axwrapper - run non-ax.25-aware programs from ax25d
* beacon - transmit periodic messages on an AX.25 port
* bpqparms - configure BPQ ethernet devices
* mheardd - display AX.25 calls recently heard
@@ -108,6 +109,7 @@ rm -rf $RPM_BUILD_ROOT
%{_sbindir}/axctl
%{_sbindir}/axparms
%{_sbindir}/axspawn
+%{_sbindir}/axwrapper
%{_sbindir}/beacon
%{_sbindir}/bpqparms
%{_sbindir}/dmascc_cfg
diff --git a/ax25/.gitignore b/ax25/.gitignore
index 00323ec..a925695 100644
--- a/ax25/.gitignore
+++ b/ax25/.gitignore
@@ -6,6 +6,7 @@ ax25d
axctl
axparms
axspawn
+axwrapper
beacon
bpqparms
mheard
diff --git a/ax25/Makefile.am b/ax25/Makefile.am
index 029217c..40eac38 100644
--- a/ax25/Makefile.am
+++ b/ax25/Makefile.am
@@ -16,7 +16,8 @@ installconf:
done
-sbin_PROGRAMS = ax25d axctl axparms axspawn beacon bpqparms mheardd rxecho
+sbin_PROGRAMS = ax25d axctl axparms axspawn axwrapper beacon bpqparms mheardd \
+ rxecho
bin_PROGRAMS = mheard
@@ -41,6 +42,7 @@ ax25d_SOURCES = ax25d.c
axctl_SOURCES = axctl.c
axparms_SOURCES = axparms.c
axspawn_SOURCES = axspawn.c axspawn.h access.c access.h md5.c md5.h
+axwrapper_SOURCES = axwrapper.c
beacon_SOURCES = beacon.c
bpqparms_SOURCES = bpqparms.c
mheard_SOURCES = mheard.c
diff --git a/ax25/ax25d.8 b/ax25/ax25d.8
index 96ceec4..8155c3c 100644
--- a/ax25/ax25d.8
+++ b/ax25/ax25d.8
@@ -37,6 +37,7 @@ Display the version.
.SH "SEE ALSO"
.BR kill (1),
.BR ax25 (4),
+.BR ax25wrapper (8),
.BR netrom (4),
.BR rose (4),
.BR ax25d.conf (5).
diff --git a/ax25/ax25d.conf.5 b/ax25/ax25d.conf.5
index 0fd80db..eeb26c2 100644
--- a/ax25/ax25d.conf.5
+++ b/ax25/ax25d.conf.5
@@ -282,6 +282,7 @@ or
/etc/ax25/ax25d.conf
.SH "SEE ALSO"
.BR ax25 (4),
+.BR ax25wrapper (8),
.BR netrom (4),
.BR rose (4),
.BR axports (5),
diff --git a/ax25/axwrapper.8 b/ax25/axwrapper.8
new file mode 100644
index 0000000..5372dd8
--- /dev/null
+++ b/ax25/axwrapper.8
@@ -0,0 +1,25 @@
+.TH AXWRAPPER 8 "25 May 2015" Linux "Linux System Managers Manual"
+.SH NAME
+axwrapper \- Run non-ax.25-aware programs from ax25d
+.SH SYNOPSIS
+.B axwrapper [ -p paclen ] server-program argv[0] ...
+.SH DESCRIPTION
+.LP
+.B Axwrapper
+first creates a pipe and then forks and execs the program <server-program> with
+arguments given at the axwrapper command line. The argv[0] argument is
+mandatory; further arguments are optional. The parent process then sits
+and waits for any I/O to and from the user and converts any carriage return
+characters from the user to line feeds and any line feeds from the program to
+carriage returns. This is useful when starting non-AX.25-aware programs from
+ax25d.
+.SH OPTIONS
+.BI "\-c paclen"
+.IP
+Specify a the size of the output buffer. The default length is 256 bytes.
+.SH FILES
+.SH "SEE ALSO"
+.BR ax25 (8)
+.BR ax25.conf (5)
+.SH AUTHOR
+Tomi Manninen OH2BNS <oh2bns@sral.fi>
diff --git a/ax25/axwrapper.c b/ax25/axwrapper.c
new file mode 100644
index 0000000..872932a
--- /dev/null
+++ b/ax25/axwrapper.c
@@ -0,0 +1,225 @@
+/*
+ * axwrapper.c - Convert end-of-line sequences for non-AX.25 aware programs -
+ * version 1.1
+ *
+ * Copyright (C) 1996-2001 Tomi Manninen, OH2BNS, <tomi.manninen@hut.fi>.
+ *
+ * Compile with: gcc -Wall -O6 -o axwrapper axwrapper.c
+ *
+ * Usage: axwrapper [-p <paclen>] <filename> <argv[0]> ...
+ *
+ * Axwrapper first creates a pipe and then forks and execs the program
+ * <filename> with arguments given at the axwrapper command line.
+ * The parent process then sits and waits for any I/O to and from the
+ * user and converts any <CR>'s from user to <NL>'s and any <NL>'s from
+ * the program to <CR>'s. This is useful when starting non-AX.25 aware
+ * programs from ax25d.
+ *
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <string.h>
+#include <errno.h>
+
+#define FLUSHTIMEOUT 500000 /* 0.5 sec */
+
+#define PERROR(s) fprintf(stderr, "*** %s: %s\r", (s), strerror(errno))
+#define USAGE() fputs("Usage: axwrapper [-p <paclen>] <filename> <argv[0]> ...\r", stderr)
+
+void sigchld_handler(int sig)
+{
+ /* fprintf(stderr, "Caught SIGCHLD, exiting...\r"); */
+ exit(0);
+}
+
+void convert_cr_lf(unsigned char *buf, int len)
+{
+ while (len-- > 0) {
+ if (*buf == '\r') *buf = '\n';
+ buf++;
+ }
+}
+
+void convert_lf_cr(unsigned char *buf, int len)
+{
+ while (len-- > 0) {
+ if (*buf == '\n') *buf = '\r';
+ buf++;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ unsigned char buf[4096], *stdoutbuf;
+ int pipe_in[2];
+ int pipe_out[2];
+ int pipe_err[2];
+ int len;
+ int pid;
+ int paclen = 256;
+ fd_set fdset;
+ struct timeval tv;
+
+ while ((len = getopt(argc, argv, "p:")) != -1) {
+ switch (len) {
+ case 'p':
+ paclen = atoi(optarg);
+ break;
+ case ':':
+ case '?':
+ USAGE();
+ exit(1);
+ }
+ }
+
+ if (argc - optind < 2) {
+ USAGE();
+ exit(1);
+ }
+
+ if ((stdoutbuf = malloc(paclen)) == NULL) {
+ PERROR("axwrapper: malloc");
+ exit(1);
+ }
+
+ setvbuf(stdout, stdoutbuf, _IOFBF, paclen);
+
+ if (pipe(pipe_in) == -1) {
+ PERROR("axwrapper: pipe");
+ exit(1);
+ }
+ if (pipe(pipe_out) == -1) {
+ PERROR("axwrapper: pipe");
+ exit(1);
+ }
+ if (pipe(pipe_err) == -1) {
+ PERROR("axwrapper: pipe");
+ exit(1);
+ }
+
+ /* signal(SIGCHLD, sigchld_handler); */
+ signal(SIGCHLD, SIG_IGN);
+
+ pid = fork();
+
+ if (pid == -1) {
+ /* fork error */
+ PERROR("axwrapper: fork");
+ exit(1);
+ }
+
+ if (pid == 0) {
+ /* child */
+ dup2(pipe_in[0], STDIN_FILENO);
+ close(pipe_in[1]);
+
+ dup2(pipe_out[1], STDOUT_FILENO);
+ close(pipe_out[0]);
+
+ dup2(pipe_err[1], STDERR_FILENO);
+ close(pipe_err[0]);
+
+ execve(argv[optind], argv + optind + 1, NULL);
+
+ /* execve() should not return */
+ perror("axwrapper: execve");
+ exit(1);
+ }
+
+ /* parent */
+
+ close(pipe_in[0]);
+ close(pipe_out[1]);
+ close(pipe_err[1]);
+
+ if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) {
+ perror("axwrapper: fcntl");
+ exit(1);
+ }
+ if (fcntl(pipe_out[0], F_SETFL, O_NONBLOCK) == -1) {
+ perror("axwrapper: fcntl");
+ exit(1);
+ }
+ if (fcntl(pipe_err[0], F_SETFL, O_NONBLOCK) == -1) {
+ perror("axwrapper: fcntl");
+ exit(1);
+ }
+
+ while (1) {
+ FD_ZERO(&fdset);
+ FD_SET(STDIN_FILENO, &fdset);
+ FD_SET(pipe_out[0], &fdset);
+ FD_SET(pipe_err[0], &fdset);
+ tv.tv_sec = 0;
+ tv.tv_usec = FLUSHTIMEOUT;
+
+ len = select(256, &fdset, 0, 0, &tv);
+ if (len == -1) {
+ perror("axwrapper: select");
+ exit(1);
+ }
+ if (len == 0) {
+ fflush(stdout);
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &fdset)) {
+ len = read(STDIN_FILENO, buf, sizeof(buf));
+ if (len < 0 && errno != EAGAIN) {
+ perror("axwrapper: read");
+ break;
+ }
+ if (len == 0)
+ break;
+ convert_cr_lf(buf, len);
+ write(pipe_in[1], buf, len);
+ }
+ if (FD_ISSET(pipe_out[0], &fdset)) {
+ len = read(pipe_out[0], buf, sizeof(buf));
+ if (len < 0 && errno != EAGAIN) {
+ perror("axwrapper: read");
+ break;
+ }
+ if (len == 0)
+ break;
+ convert_lf_cr(buf, len);
+ fwrite(buf, 1, len, stdout);
+ }
+ if (FD_ISSET(pipe_err[0], &fdset)) {
+ len = read(pipe_err[0], buf, sizeof(buf));
+ if (len < 0 && errno != EAGAIN) {
+ perror("axwrapper: read");
+ break;
+ }
+ if (len == 0)
+ break;
+ convert_lf_cr(buf, len);
+ fwrite(buf, 1, len, stderr);
+ }
+ }
+
+ kill(pid, SIGTERM);
+ close(pipe_in[1]);
+ close(pipe_out[0]);
+ close(pipe_err[0]);
+ return 0;
+}