diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2015-05-25 20:57:47 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-05-25 21:02:13 +0200 |
commit | 6911c1b1acd455e514de2fc88b3eaf0a23cabdd6 (patch) | |
tree | 4bcb25b6fd2e2374f66b5000b5ff12b6f7240ddf | |
parent | 4984e59635ed76196dc5f9a18ae8118be4853758 (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-- | AUTHORS | 1 | ||||
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | ax25-tools.spec.in | 2 | ||||
-rw-r--r-- | ax25/.gitignore | 1 | ||||
-rw-r--r-- | ax25/Makefile.am | 4 | ||||
-rw-r--r-- | ax25/ax25d.8 | 1 | ||||
-rw-r--r-- | ax25/ax25d.conf.5 | 1 | ||||
-rw-r--r-- | ax25/axwrapper.8 | 25 | ||||
-rw-r--r-- | ax25/axwrapper.c | 225 |
9 files changed, 260 insertions, 1 deletions
@@ -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> @@ -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; +} |