summaryrefslogtreecommitdiffstats
path: root/user_call
diff options
context:
space:
mode:
Diffstat (limited to 'user_call')
-rw-r--r--user_call/Makefile.am27
-rw-r--r--user_call/Makefile.in93
-rw-r--r--user_call/README.user_call (renamed from user_call/README)0
-rw-r--r--user_call/ax25_call.859
-rw-r--r--user_call/ax25_call.c90
-rw-r--r--user_call/netrom_call.829
-rw-r--r--user_call/netrom_call.c97
-rw-r--r--user_call/rose_call.827
-rw-r--r--user_call/rose_call.c96
-rw-r--r--user_call/tcp_call.81
-rw-r--r--user_call/tcp_call.c139
-rw-r--r--user_call/user_io.c215
-rw-r--r--user_call/user_io.h12
13 files changed, 653 insertions, 232 deletions
diff --git a/user_call/Makefile.am b/user_call/Makefile.am
index 0a176b9..24cf7d7 100644
--- a/user_call/Makefile.am
+++ b/user_call/Makefile.am
@@ -2,11 +2,30 @@
installconf:
-sbin_PROGRAMS = ax25_call netrom_call rose_call
+sbin_PROGRAMS = ax25_call netrom_call rose_call tcp_call
-man_MANS = ax25_call.8 netrom_call.8 rose_call.8
+man_MANS = ax25_call.8 netrom_call.8 rose_call.8 tcp_call.8
-EXTRA_DIST = $(man_MANS)
+docdir=${prefix}/doc/ax25-tools
+doc_DATA= README.user_call
-LDADD = $(AX25_LIB)
+EXTRA_DIST = $(man_MANS) $(doc_DATA)
+
+LDADD = $(AX25_LIB) $(Z_LIB)
+
+ax25_call_SOURCES = ax25_call.c \
+ user_io.c \
+ user_io.h
+
+netrom_call_SOURCES = netrom_call.c \
+ user_io.c \
+ user_io.h
+
+rose_call_SOURCES = rose_call.c \
+ user_io.c \
+ user_io.h
+
+tcp_call_SOURCES = tcp_call.c \
+ user_io.c \
+ user_io.h
diff --git a/user_call/Makefile.in b/user_call/Makefile.in
index cf78c65..8935ee8 100644
--- a/user_call/Makefile.in
+++ b/user_call/Makefile.in
@@ -68,13 +68,28 @@ UTIL_LIB = @UTIL_LIB@
VERSION = @VERSION@
Z_LIB = @Z_LIB@
-sbin_PROGRAMS = ax25_call netrom_call rose_call
+sbin_PROGRAMS = ax25_call netrom_call rose_call tcp_call
-man_MANS = ax25_call.8 netrom_call.8 rose_call.8
+man_MANS = ax25_call.8 netrom_call.8 rose_call.8 tcp_call.8
-EXTRA_DIST = $(man_MANS)
+docdir = ${prefix}/doc/ax25-tools
+doc_DATA = README.user_call
+
+EXTRA_DIST = $(man_MANS) $(doc_DATA)
+
+LDADD = $(AX25_LIB) $(Z_LIB)
+
+ax25_call_SOURCES = ax25_call.c user_io.c user_io.h
+
+
+netrom_call_SOURCES = netrom_call.c user_io.c user_io.h
+
+
+rose_call_SOURCES = rose_call.c user_io.c user_io.h
+
+
+tcp_call_SOURCES = tcp_call.c user_io.c user_io.h
-LDADD = $(AX25_LIB)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
@@ -89,21 +104,22 @@ X_CFLAGS = @X_CFLAGS@
X_LIBS = @X_LIBS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
-ax25_call_SOURCES = ax25_call.c
-ax25_call_OBJECTS = ax25_call.o
+ax25_call_OBJECTS = ax25_call.o user_io.o
ax25_call_LDADD = $(LDADD)
ax25_call_DEPENDENCIES =
ax25_call_LDFLAGS =
-netrom_call_SOURCES = netrom_call.c
-netrom_call_OBJECTS = netrom_call.o
+netrom_call_OBJECTS = netrom_call.o user_io.o
netrom_call_LDADD = $(LDADD)
netrom_call_DEPENDENCIES =
netrom_call_LDFLAGS =
-rose_call_SOURCES = rose_call.c
-rose_call_OBJECTS = rose_call.o
+rose_call_OBJECTS = rose_call.o user_io.o
rose_call_LDADD = $(LDADD)
rose_call_DEPENDENCIES =
rose_call_LDFLAGS =
+tcp_call_OBJECTS = tcp_call.o user_io.o
+tcp_call_LDADD = $(LDADD)
+tcp_call_DEPENDENCIES =
+tcp_call_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
@@ -112,15 +128,17 @@ man8dir = $(mandir)/man8
MANS = $(man_MANS)
NROFF = nroff
-DIST_COMMON = README Makefile.am Makefile.in
+DATA = $(doc_DATA)
+
+DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
-SOURCES = ax25_call.c netrom_call.c rose_call.c
-OBJECTS = ax25_call.o netrom_call.o rose_call.o
+SOURCES = $(ax25_call_SOURCES) $(netrom_call_SOURCES) $(rose_call_SOURCES) $(tcp_call_SOURCES)
+OBJECTS = $(ax25_call_OBJECTS) $(netrom_call_OBJECTS) $(rose_call_OBJECTS) $(tcp_call_OBJECTS)
all: all-redirect
.SUFFIXES:
@@ -189,6 +207,10 @@ rose_call: $(rose_call_OBJECTS) $(rose_call_DEPENDENCIES)
@rm -f rose_call
$(LINK) $(rose_call_LDFLAGS) $(rose_call_OBJECTS) $(rose_call_LDADD) $(LIBS)
+tcp_call: $(tcp_call_OBJECTS) $(tcp_call_DEPENDENCIES)
+ @rm -f tcp_call
+ $(LINK) $(tcp_call_LDFLAGS) $(tcp_call_OBJECTS) $(tcp_call_LDADD) $(LIBS)
+
install-man8:
$(mkinstalldirs) $(DESTDIR)$(man8dir)
@list='$(man8_MANS)'; \
@@ -228,6 +250,25 @@ uninstall-man:
@$(NORMAL_UNINSTALL)
$(MAKE) $(AM_MAKEFLAGS) uninstall-man8
+install-docDATA: $(doc_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(docdir)
+ @list='$(doc_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-docDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(doc_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(docdir)/$$p; \
+ done
+
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
@@ -272,9 +313,6 @@ distdir: $(DISTFILES)
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
-ax25_call.o: ax25_call.c ../config.h
-netrom_call.o: netrom_call.c ../config.h
-rose_call.o: rose_call.c ../config.h
info-am:
info: info-am
@@ -287,20 +325,21 @@ installcheck: installcheck-am
install-exec-am: install-sbinPROGRAMS
install-exec: install-exec-am
-install-data-am: install-man
+install-data-am: install-man install-docDATA
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
-uninstall-am: uninstall-sbinPROGRAMS uninstall-man
+uninstall-am: uninstall-sbinPROGRAMS uninstall-man uninstall-docDATA
uninstall: uninstall-am
-all-am: Makefile $(PROGRAMS) $(MANS)
+all-am: Makefile $(PROGRAMS) $(MANS) $(DATA)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
- $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
+ $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 \
+ $(DESTDIR)$(docdir)
mostlyclean-generic:
@@ -339,13 +378,13 @@ maintainer-clean: maintainer-clean-am
clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
install-sbinPROGRAMS mostlyclean-compile distclean-compile \
clean-compile maintainer-clean-compile install-man8 uninstall-man8 \
-install-man uninstall-man tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+install-man uninstall-man uninstall-docDATA install-docDATA tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir info-am info dvi-am dvi check check-am installcheck-am \
+installcheck install-exec-am install-exec install-data-am install-data \
+install-am install uninstall-am uninstall all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
installconf:
diff --git a/user_call/README b/user_call/README.user_call
index beee347..beee347 100644
--- a/user_call/README
+++ b/user_call/README.user_call
diff --git a/user_call/ax25_call.8 b/user_call/ax25_call.8
index ab93de0..e7542e4 100644
--- a/user_call/ax25_call.8
+++ b/user_call/ax25_call.8
@@ -1,13 +1,20 @@
-.TH AX25_CALL 8 "11 December 1996" Linux "Linux Programmer's Manual"
+.TH AX25_CALL 8 "4 July 1999" Linux "Linux Programmer's Manual"
.SH NAME
-ax25_call \- make an AX.25 connection
+ax25_call, netrom_call, rose_call, tcp_call \- make an AX.25, NET/ROM,
+ROSE or TCP connection
.SH SYNOPSIS
-.B ax25_call port local_call remote_call [digipeaters ...]
+.B ax25_call [-c] [-i paclen] [-o paclen] port local_call remote_call [digipeaters ...]
+.sp
+.B netrom_call [-c] [-i paclen] [-o paclen] port local_call remote_netrom_addr
+.sp
+.B rose_call [-c] [-i paclen] [-o paclen] port local_call remote_call remote_rose_addr
+.sp
+.B tcp_call [-c] [-i paclen] [-o paclen] remote_addr remote_port
.SH DESCRIPTION
.LP
-.B ax25_call
-establishes an AX.25 connection in a manner suitable for calling from either
-the
+.B ax25_call, netrom_call, rose_call and tcp_call
+establish an AX.25, NET/ROM, ROSE or a TCP connection in a manner
+suitable for calling from either the
.B ax25d
program directly, or from the
.B node
@@ -15,10 +22,48 @@ program as an external command. By setting the command line arguments
appropriately it is possible to set the local callsign from which the call
will be made. No translation of the end of lines is performed by this
program.
+.sp
+For
+.B netrom_call
+the remote_netrom_addr parameter may either be in the form of a single
+callsign or as a NET/ROM alias and callsign pair separated by
+colon. For example NMCLUS:GB7BPQ.
+.sp
+For
+.B rose_call
+the remote_rose_addr parameter must be in the form of a ten digit
+ROSE address.
+.sp
+For
+.B tcp_call
+the remote_addr parameter must be a dotted-quad IP address or a
+hostname and the remote_port must be a service name (see services(5))
+or a port number.
+.SH OPTIONS
+.TP 12
+.BI \-c
+Enables zlib based compression on the incoming connection. Compression
+algorithm is the same as in LinuxNode (see node(8)).
+.TP 12
+.BI "\-i paclen"
+The maximum frame length to be used on the incoming connection. The
+default is 256 for ax25_call and rose_call, 236 for netrom_call and
+1024 for tcp_call.
+.TP 12
+.BI "\-o paclen"
+The maximum frame length to be used on the outgoing connection. The
+default is 256 for ax25_call and rose_call, 236 for netrom_call and
+1024 for tcp_call.
.SH FILES
.br
/etc/ax25/axports
+.br
+/etc/ax25/nrports
+.br
+/etc/ax25/rsports
.SH "SEE ALSO"
-.BR ax25 (4).
+.BR ax25(4), netrom(4), rose(4), tcp(4).
.SH AUTHOR
Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>
+.br
+Tomi Manninen OH2BNS <tomi.manninen@hut.fi>
diff --git a/user_call/ax25_call.c b/user_call/ax25_call.c
index 235feb9..cbedf63 100644
--- a/user_call/ax25_call.c
+++ b/user_call/ax25_call.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -8,8 +9,8 @@
#include <sys/time.h>
#include <sys/types.h>
-
#include <sys/socket.h>
+
#ifdef HAVE_NETAX25_AX25_H
#include <netax25/ax25.h>
#else
@@ -24,27 +25,46 @@
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
-void alarm_handler(int sig)
-{
-}
+#include "user_io.h"
-void err(char *message)
+void alarm_handler(int sig)
{
- write(STDOUT_FILENO, message, strlen(message));
- exit(1);
}
int main(int argc, char **argv)
{
- char buffer[512], *addr;
- fd_set read_fd;
- int n, s, addrlen = sizeof(struct full_sockaddr_ax25);
+ char buffer[256], *addr;
+ int s, addrlen = sizeof(struct full_sockaddr_ax25);
struct full_sockaddr_ax25 axbind, axconnect;
+ while ((s = getopt(argc, argv, "ci:o:")) != -1) {
+ switch (s) {
+ case 'c':
+ init_compress();
+ compression = 1;
+ break;
+ case 'i':
+ paclen_in = atoi(optarg);
+ break;
+ case 'o':
+ paclen_out = atoi(optarg);
+ break;
+ case ':':
+ case '?':
+ err("ERROR: invalid option usage\r");
+ return 1;
+ }
+ }
+
+ if (paclen_in < 1 || paclen_out < 1) {
+ err("ERROR: invalid paclen\r");
+ return 1;
+ }
+
/*
* Arguments should be "ax25_call port mycall remcall [digis ...]"
*/
- if (argc < 4) {
+ if ((argc - optind) < 3) {
strcpy(buffer, "ERROR: invalid number of parameters\r");
err(buffer);
}
@@ -60,22 +80,22 @@ int main(int argc, char **argv)
axconnect.fsa_ax25.sax25_family = axbind.fsa_ax25.sax25_family = AF_AX25;
axbind.fsa_ax25.sax25_ndigis = 1;
- if ((addr = ax25_config_get_addr(argv[1])) == NULL) {
- sprintf(buffer, "ERROR: invalid AX.25 port name - %s\r", argv[1]);
+ if ((addr = ax25_config_get_addr(argv[optind])) == NULL) {
+ sprintf(buffer, "ERROR: invalid AX.25 port name - %s\r", argv[optind]);
err(buffer);
}
if (ax25_aton_entry(addr, axbind.fsa_digipeater[0].ax25_call) == -1) {
- sprintf(buffer, "ERROR: invalid AX.25 port callsign - %s\r", argv[1]);
+ sprintf(buffer, "ERROR: invalid AX.25 port callsign - %s\r", argv[optind]);
err(buffer);
}
- if (ax25_aton_entry(argv[2], axbind.fsa_ax25.sax25_call.ax25_call) == -1) {
- sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[2]);
+ if (ax25_aton_entry(argv[optind + 1], axbind.fsa_ax25.sax25_call.ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[optind + 1]);
err(buffer);
}
- if (ax25_aton_arglist(argv + 3, &axconnect) == -1) {
+ if (ax25_aton_arglist(argv + optind + 2, &axconnect) == -1) {
sprintf(buffer, "ERROR: invalid destination callsign or digipeater\r");
err(buffer);
}
@@ -96,8 +116,8 @@ int main(int argc, char **argv)
err(buffer);
}
- sprintf(buffer, "Connecting to %s ...\r", argv[3]);
- write(STDOUT_FILENO, buffer, strlen(buffer));
+ sprintf(buffer, "Connecting to %s ...\r", argv[optind + 2]);
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
/*
* If no response in 30 seconds, go away.
@@ -134,34 +154,14 @@ int main(int argc, char **argv)
alarm(0);
strcpy(buffer, "*** Connected\r");
- write(STDOUT_FILENO, buffer, strlen(buffer));
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
- /*
- * Loop until one end of the connection goes away.
- */
- for (;;) {
- FD_ZERO(&read_fd);
- FD_SET(STDIN_FILENO, &read_fd);
- FD_SET(s, &read_fd);
-
- select(s + 1, &read_fd, NULL, NULL, NULL);
-
- if (FD_ISSET(s, &read_fd)) {
- if ((n = read(s, buffer, 512)) == -1) {
- strcpy(buffer, "\r*** Disconnected\r");
- err(buffer);
- }
- write(STDOUT_FILENO, buffer, n);
- }
+ select_loop(s);
- if (FD_ISSET(STDIN_FILENO, &read_fd)) {
- if ((n = read(STDIN_FILENO, buffer, 512)) == -1) {
- close(s);
- break;
- }
- write(s, buffer, n);
- }
- }
+ strcpy(buffer, "\r*** Disconnected\r");
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
+
+ end_compress();
return 0;
}
diff --git a/user_call/netrom_call.8 b/user_call/netrom_call.8
index 1a11989..41ea354 100644
--- a/user_call/netrom_call.8
+++ b/user_call/netrom_call.8
@@ -1,28 +1 @@
-.TH NETROM_CALL 8 "11 December 1996" Linux "Linux Programmer's Manual"
-.SH NAME
-netrom_call \- make a NET/ROM connection
-.SH SYNOPSIS
-.B netrom_call port local_call remote_addr
-.SH DESCRIPTION
-.LP
-.B netrom_call
-establishes a NET/ROM connection in a manner suitable for calling from either
-the
-.B ax25d
-program directly, or from the
-.B node
-program as an external command. By setting the command line arguments
-appropriately it is possible to set the local callsign from which the call
-will be made. No translation of the end of line conventions is performed by
-this program.
-.sp 1
-The remote_addr parameter may either be in the form of a single callsign or
-as a NET/ROM alias and callsign pair seperated by colon. For example
-NMCLUS:GB7BPQ.
-.SH FILES
-.br
-/etc/ax25/nrports
-.SH "SEE ALSO"
-.BR netrom (4).
-.SH AUTHOR
-Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>
+.so man8/ax25_call.8
diff --git a/user_call/netrom_call.c b/user_call/netrom_call.c
index deb877e..ca4c1c9 100644
--- a/user_call/netrom_call.c
+++ b/user_call/netrom_call.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -8,8 +9,8 @@
#include <sys/time.h>
#include <sys/types.h>
-
#include <sys/socket.h>
+
#ifdef HAVE_NETAX25_AX25_H
#include <netax25/ax25.h>
#else
@@ -30,27 +31,49 @@
#include <netax25/axconfig.h>
#include <netax25/nrconfig.h>
-void alarm_handler(int sig)
-{
-}
+#include "user_io.h"
-void err(char *message)
+void alarm_handler(int sig)
{
- write(STDOUT_FILENO, message, strlen(message));
- exit(1);
}
int main(int argc, char **argv)
{
- char buffer[512], *addr;
- fd_set read_fd;
- int n, s, addrlen = sizeof(struct full_sockaddr_ax25);
+ char buffer[256], *addr;
+ int s, addrlen = sizeof(struct full_sockaddr_ax25);
struct full_sockaddr_ax25 nrbind, nrconnect;
+ paclen_in = 236;
+ paclen_out = 236;
+
+ while ((s = getopt(argc, argv, "ci:o:")) != -1) {
+ switch (s) {
+ case 'c':
+ init_compress();
+ compression = 1;
+ break;
+ case 'i':
+ paclen_in = atoi(optarg);
+ break;
+ case 'o':
+ paclen_out = atoi(optarg);
+ break;
+ case ':':
+ case '?':
+ err("ERROR: invalid option usage\r");
+ return 1;
+ }
+ }
+
+ if (paclen_in < 1 || paclen_out < 1) {
+ err("ERROR: invalid paclen\r");
+ return 1;
+ }
+
/*
* Arguments should be "netrom_call port mycall remaddr"
*/
- if (argc != 4) {
+ if ((argc - optind) != 3) {
strcpy(buffer, "ERROR: invalid number of parameters\r");
err(buffer);
}
@@ -67,28 +90,28 @@ int main(int argc, char **argv)
nrbind.fsa_ax25.sax25_ndigis = 1;
nrconnect.fsa_ax25.sax25_ndigis = 0;
- if ((addr = nr_config_get_addr(argv[1])) == NULL) {
- sprintf(buffer, "ERROR: invalid NET/ROM port name - %s\r", argv[1]);
+ if ((addr = nr_config_get_addr(argv[optind])) == NULL) {
+ sprintf(buffer, "ERROR: invalid NET/ROM port name - %s\r", argv[optind]);
err(buffer);
}
if (ax25_aton_entry(addr, nrbind.fsa_ax25.sax25_call.ax25_call) == -1) {
- sprintf(buffer, "ERROR: invalid NET/ROM port callsign - %s\r", argv[1]);
+ sprintf(buffer, "ERROR: invalid NET/ROM port callsign - %s\r", argv[optind]);
err(buffer);
}
- if (ax25_aton_entry(argv[2], nrbind.fsa_digipeater[0].ax25_call) == -1) {
- sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[2]);
+ if (ax25_aton_entry(argv[optind + 1], nrbind.fsa_digipeater[0].ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[optind + 1]);
err(buffer);
}
- if ((addr = strchr(argv[3], ':')) == NULL)
- addr = argv[3];
+ if ((addr = strchr(argv[optind + 2], ':')) == NULL)
+ addr = argv[optind + 2];
else
addr++;
if (ax25_aton_entry(addr, nrconnect.fsa_ax25.sax25_call.ax25_call) == -1) {
- sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[3]);
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[optind + 2]);
err(buffer);
}
@@ -108,8 +131,8 @@ int main(int argc, char **argv)
err(buffer);
}
- sprintf(buffer, "Connecting to %s ...\r", argv[3]);
- write(STDOUT_FILENO, buffer, strlen(buffer));
+ sprintf(buffer, "Connecting to %s ...\r", argv[optind + 2]);
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
/*
* If no response in 30 seconds, go away.
@@ -146,34 +169,14 @@ int main(int argc, char **argv)
alarm(0);
strcpy(buffer, "*** Connected\r");
- write(STDOUT_FILENO, buffer, strlen(buffer));
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
- /*
- * Loop until one end of the connection goes away.
- */
- for (;;) {
- FD_ZERO(&read_fd);
- FD_SET(STDIN_FILENO, &read_fd);
- FD_SET(s, &read_fd);
-
- select(s + 1, &read_fd, NULL, NULL, NULL);
-
- if (FD_ISSET(s, &read_fd)) {
- if ((n = read(s, buffer, 512)) == -1) {
- strcpy(buffer, "\r*** Disconnected\r");
- err(buffer);
- }
- write(STDOUT_FILENO, buffer, n);
- }
+ select_loop(s);
- if (FD_ISSET(STDIN_FILENO, &read_fd)) {
- if ((n = read(STDIN_FILENO, buffer, 512)) == -1) {
- close(s);
- break;
- }
- write(s, buffer, n);
- }
- }
+ strcpy(buffer, "\r*** Disconnected\r");
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
+
+ end_compress();
return 0;
}
diff --git a/user_call/rose_call.8 b/user_call/rose_call.8
index 9eb888e..41ea354 100644
--- a/user_call/rose_call.8
+++ b/user_call/rose_call.8
@@ -1,26 +1 @@
-.TH ROSE_CALL 8 "11 December 1996" Linux "Linux Programmer's Manual"
-.SH NAME
-rose_call \- make a ROSE connection
-.SH SYNOPSIS
-.B rose_call port local_call remote_call remote_rose_addr
-.SH DESCRIPTION
-.LP
-.B rose_call
-establishes a ROSE connection in a manner suitable for calling from either
-the
-.B ax25d
-program directly, or from the
-.B node
-program as an external command. By setting the command line arguments
-appropriately it is possible to set the local callsign from which the call
-will be made. No translation of the end of line conventions is performed by
-this program.
-.sp 1
-The remote_rose_addr parameter must be in the form of a ten digit ROSE address.
-.SH FILES
-.br
-/etc/ax25/rsports
-.SH "SEE ALSO"
-.BR rose (4).
-.SH AUTHOR
-Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>
+.so man8/ax25_call.8
diff --git a/user_call/rose_call.c b/user_call/rose_call.c
index 10e235b..51308a2 100644
--- a/user_call/rose_call.c
+++ b/user_call/rose_call.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -8,8 +9,8 @@
#include <sys/time.h>
#include <sys/types.h>
-
#include <sys/socket.h>
+
#ifdef HAVE_NETAX25_AX25_H
#include <netax25/ax25.h>
#else
@@ -25,27 +26,46 @@
#include <netax25/axconfig.h>
#include <netax25/rsconfig.h>
-void alarm_handler(int sig)
-{
-}
+#include "user_io.h"
-void err(char *message)
+void alarm_handler(int sig)
{
- write(STDOUT_FILENO, message, strlen(message));
- exit(1);
}
int main(int argc, char **argv)
{
- char buffer[512], *addr;
- fd_set read_fd;
- int n, s, addrlen = sizeof(struct sockaddr_rose);
+ char buffer[256], *addr;
+ int s, addrlen = sizeof(struct sockaddr_rose);
struct sockaddr_rose rosebind, roseconnect;
+ while ((s = getopt(argc, argv, "ci:o:")) != -1) {
+ switch (s) {
+ case 'c':
+ init_compress();
+ compression = 1;
+ break;
+ case 'i':
+ paclen_in = atoi(optarg);
+ break;
+ case 'o':
+ paclen_out = atoi(optarg);
+ break;
+ case ':':
+ case '?':
+ err("ERROR: invalid option usage\r");
+ return 1;
+ }
+ }
+
+ if (paclen_in < 1 || paclen_out < 1) {
+ err("ERROR: invalid paclen\r");
+ return 1;
+ }
+
/*
* Arguments should be "rose_call port mycall remcall remaddr"
*/
- if (argc != 5) {
+ if ((argc - optind) != 4) {
strcpy(buffer, "ERROR: invalid number of parameters\r");
err(buffer);
}
@@ -61,28 +81,28 @@ int main(int argc, char **argv)
roseconnect.srose_family = rosebind.srose_family = AF_ROSE;
roseconnect.srose_ndigis = rosebind.srose_ndigis = 0;
- if ((addr = rs_config_get_addr(argv[1])) == NULL) {
- sprintf(buffer, "ERROR: invalid Rose port name - %s\r", argv[1]);
+ if ((addr = rs_config_get_addr(argv[optind])) == NULL) {
+ sprintf(buffer, "ERROR: invalid Rose port name - %s\r", argv[optind]);
err(buffer);
}
if (rose_aton(addr, rosebind.srose_addr.rose_addr) == -1) {
- sprintf(buffer, "ERROR: invalid Rose port address - %s\r", argv[1]);
+ sprintf(buffer, "ERROR: invalid Rose port address - %s\r", argv[optind]);
err(buffer);
}
- if (ax25_aton_entry(argv[2], rosebind.srose_call.ax25_call) == -1) {
- sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[2]);
+ if (ax25_aton_entry(argv[optind + 1], rosebind.srose_call.ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[optind + 1]);
err(buffer);
}
- if (ax25_aton_entry(argv[3], roseconnect.srose_call.ax25_call) == -1) {
- sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[3]);
+ if (ax25_aton_entry(argv[optind + 2], roseconnect.srose_call.ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[optind + 2]);
err(buffer);
}
- if (rose_aton(argv[4], roseconnect.srose_addr.rose_addr) == -1) {
- sprintf(buffer, "ERROR: invalid Rose address - %s\r", argv[4]);
+ if (rose_aton(argv[optind + 3], roseconnect.srose_addr.rose_addr) == -1) {
+ sprintf(buffer, "ERROR: invalid Rose address - %s\r", argv[optind + 3]);
err(buffer);
}
@@ -102,8 +122,8 @@ int main(int argc, char **argv)
err(buffer);
}
- sprintf(buffer, "Connecting to %s @ %s ...\r", argv[3], argv[4]);
- write(STDOUT_FILENO, buffer, strlen(buffer));
+ sprintf(buffer, "Connecting to %s @ %s ...\r", argv[optind + 2], argv[optind + 3]);
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
/*
* If no response in 30 seconds, go away.
@@ -140,34 +160,14 @@ int main(int argc, char **argv)
alarm(0);
strcpy(buffer, "*** Connected\r");
- write(STDOUT_FILENO, buffer, strlen(buffer));
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
- /*
- * Loop until one end of the connection goes away.
- */
- for (;;) {
- FD_ZERO(&read_fd);
- FD_SET(STDIN_FILENO, &read_fd);
- FD_SET(s, &read_fd);
-
- select(s + 1, &read_fd, NULL, NULL, NULL);
-
- if (FD_ISSET(s, &read_fd)) {
- if ((n = read(s, buffer, 512)) == -1) {
- strcpy(buffer, "\r*** Disconnected\r");
- err(buffer);
- }
- write(STDOUT_FILENO, buffer, n);
- }
+ select_loop(s);
- if (FD_ISSET(STDIN_FILENO, &read_fd)) {
- if ((n = read(STDIN_FILENO, buffer, 512)) == -1) {
- close(s);
- break;
- }
- write(s, buffer, n);
- }
- }
+ strcpy(buffer, "\r*** Disconnected\r");
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
+
+ end_compress();
return 0;
}
diff --git a/user_call/tcp_call.8 b/user_call/tcp_call.8
new file mode 100644
index 0000000..41ea354
--- /dev/null
+++ b/user_call/tcp_call.8
@@ -0,0 +1 @@
+.so man8/ax25_call.8
diff --git a/user_call/tcp_call.c b/user_call/tcp_call.c
new file mode 100644
index 0000000..c3b5e3c
--- /dev/null
+++ b/user_call/tcp_call.c
@@ -0,0 +1,139 @@
+#include <stdlib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <netdb.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include "user_io.h"
+
+void alarm_handler(int sig)
+{
+}
+
+int main(int argc, char **argv)
+{
+ char buffer[256];
+ int s, addrlen = sizeof(struct sockaddr_in);
+ struct sockaddr_in addr;
+ struct hostent *hp;
+ struct servent *sp;
+ int verbose = 1;
+
+ paclen_in = 1024;
+ paclen_out = 1024;
+
+ while ((s = getopt(argc, argv, "ci:o:q")) != -1) {
+ switch (s) {
+ case 'c':
+ init_compress();
+ compression = 1;
+ break;
+ case 'i':
+ paclen_in = atoi(optarg);
+ break;
+ case 'o':
+ paclen_out = atoi(optarg);
+ break;
+ case 'q':
+ verbose = 0;
+ break;
+ case ':':
+ case '?':
+ err("ERROR: invalid option usage\n");
+ return 1;
+ }
+ }
+
+ if (paclen_in < 1 || paclen_out < 1) {
+ err("ERROR: invalid paclen\n");
+ return 1;
+ }
+
+ /*
+ * Arguments should be "tcp_call remaddr remport"
+ */
+ if ((argc - optind) != 2) {
+ strcpy(buffer, "ERROR: invalid number of parameters\n");
+ err(buffer);
+ }
+
+ /*
+ * Open the socket into the kernel.
+ */
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ sprintf(buffer, "ERROR: can't open socket: %s\n", strerror(errno));
+ err(buffer);
+ }
+
+ /*
+ * Resolve the hostname.
+ */
+ hp = gethostbyname(argv[optind]);
+ if (hp == NULL) {
+ err("ERROR: Unknown host\n");
+ }
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
+
+ /*
+ * And the service name.
+ */
+ if ((sp = getservbyname(argv[optind+1], "tcp")) != NULL)
+ addr.sin_port = sp->s_port;
+ else
+ addr.sin_port = htons(atoi(argv[optind+1]));
+
+ if (addr.sin_port == 0) {
+ err("ERROR: Unknown service\n");
+ }
+
+ if (verbose) {
+ sprintf(buffer, "*** Connecting to %s ...\n", hp->h_name);
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
+ }
+
+ /*
+ * If no response in 30 seconds, go away.
+ */
+ alarm(30);
+
+ signal(SIGALRM, alarm_handler);
+
+ /*
+ * Lets try and connect to the far end.
+ */
+ if (connect(s, (struct sockaddr *)&addr, addrlen) != 0) {
+ sprintf(buffer, "ERROR: can't connect: %s\n", strerror(errno));
+ err(buffer);
+ }
+
+ /*
+ * We got there.
+ */
+ alarm(0);
+
+ if (verbose) {
+ strcpy(buffer, "*** Connected\n");
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
+ }
+
+ select_loop(s);
+
+ if (verbose) {
+ strcpy(buffer, "\n*** Disconnected\n");
+ user_write(STDOUT_FILENO, buffer, strlen(buffer));
+ }
+
+ end_compress();
+
+ return 0;
+}
diff --git a/user_call/user_io.c b/user_call/user_io.c
new file mode 100644
index 0000000..2e594f6
--- /dev/null
+++ b/user_call/user_io.c
@@ -0,0 +1,215 @@
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "config.h"
+#include "user_io.h"
+
+int compression = 0;
+int paclen_in = 256;
+int paclen_out = 256;
+
+/* This is for select_loop() */
+static unsigned char buf[8192];
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+
+/* Error in (de)compression happened? */
+static int compression_error = 0;
+
+/* These are for the (de)compressor */
+static unsigned char input_buffer[8192];
+static unsigned char output_buffer[8192];
+
+static z_stream incoming_stream;
+static z_stream outgoing_stream;
+#endif
+
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+void err(char *message)
+{
+ user_write(STDOUT_FILENO, message, strlen(message));
+ exit(1);
+}
+
+void init_compress(void)
+{
+#ifdef HAVE_ZLIB_H
+ inflateInit(&incoming_stream);
+ deflateInit(&outgoing_stream, 9);
+
+ incoming_stream.next_in = input_buffer;
+#else
+ err("*** Compression support not available!!!\r\n");
+#endif
+}
+
+void end_compress(void)
+{
+#ifdef HAVE_ZLIB_H
+ inflateEnd(&incoming_stream);
+ deflateEnd(&outgoing_stream);
+#endif
+}
+
+static int flush_output(int fd, const void *buf, size_t count)
+{
+ int cnt = count;
+
+ while (cnt > 0) {
+ write(fd, buf, min(paclen_out, cnt));
+ buf += paclen_out;
+ cnt -= paclen_out;
+ }
+
+ return count;
+}
+
+int user_write(int fd, const void *buf, size_t count)
+{
+#ifdef HAVE_ZLIB_H
+ int status;
+#endif
+
+ if (count == 0)
+ return 0;
+
+#ifndef HAVE_ZLIB_H
+ return flush_output(fd, buf, count);
+#else
+ /* Only output to stdout can be compressed */
+ if (fd != STDOUT_FILENO || !compression)
+ return flush_output(fd, buf, count);
+
+ if (compression_error) {
+ errno = 0;
+ return -1;
+ }
+
+ /* Input is the contents of the input buffer. */
+ outgoing_stream.next_in = (unsigned char *)buf;
+ outgoing_stream.avail_in = count;
+
+ /* Loop compressing until deflate() returns with avail_out != 0. */
+ do {
+ /* Set up fixed-size output buffer. */
+ outgoing_stream.next_out = output_buffer;
+ outgoing_stream.avail_out = sizeof(output_buffer);
+
+ /* Compress as much data into the buffer as possible. */
+ status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH);
+
+ if (status != Z_OK) {
+ compression_error = status;
+ errno = 0;
+ return -1;
+ }
+
+ /* Now send the compressed data */
+ flush_output(fd, output_buffer, sizeof(output_buffer) - outgoing_stream.avail_out);
+
+ } while (outgoing_stream.avail_out == 0);
+
+ return count;
+#endif
+}
+
+int user_read(int fd, void *buf, size_t count)
+{
+#ifdef HAVE_ZLIB_H
+ int status, len;
+#endif
+
+ if (count == 0)
+ return 0;
+
+#ifndef HAVE_ZLIB_H
+ return read(fd, buf, count);
+#else
+ /* Only input from stdin can be compressed */
+ if (fd != STDIN_FILENO || !compression)
+ return read(fd, buf, count);
+
+ if (compression_error) {
+ errno = 0;
+ return -1;
+ }
+
+ incoming_stream.next_out = buf;
+ incoming_stream.avail_out = count;
+
+ for (;;) {
+ status = inflate(&incoming_stream, Z_SYNC_FLUSH);
+
+ if (count - incoming_stream.avail_out > 0)
+ return count - incoming_stream.avail_out;
+
+ if (status != Z_OK && status != Z_BUF_ERROR) {
+ compression_error = status;
+ errno = 0;
+ return -1;
+ }
+
+ incoming_stream.next_in = input_buffer;
+ incoming_stream.avail_in = 0;
+
+ if ((len = read(fd, input_buffer, sizeof(input_buffer))) < 0)
+ return -1;
+
+ incoming_stream.avail_in = len;
+ }
+
+ return 0;
+#endif
+}
+
+int select_loop(int s)
+{
+ fd_set read_fd;
+ int n;
+
+ if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
+ close(s);
+ return -1;
+ }
+ if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) {
+ close(s);
+ return -1;
+ }
+
+ /*
+ * Loop until one end of the connection goes away.
+ */
+ for (;;) {
+ FD_ZERO(&read_fd);
+ FD_SET(STDIN_FILENO, &read_fd);
+ FD_SET(s, &read_fd);
+
+ select(s + 1, &read_fd, NULL, NULL, NULL);
+
+ if (FD_ISSET(s, &read_fd)) {
+ while ((n = user_read(s, buf, 8192)) > 0)
+ user_write(STDOUT_FILENO, buf, n);
+ if (n == 0 || errno != EAGAIN) {
+ close(s);
+ break;
+ }
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &read_fd)) {
+ while ((n = user_read(STDIN_FILENO, buf, 8192)) > 0)
+ user_write(s, buf, n);
+ if (n == 0 || errno != EAGAIN) {
+ close(s);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/user_call/user_io.h b/user_call/user_io.h
new file mode 100644
index 0000000..98099a5
--- /dev/null
+++ b/user_call/user_io.h
@@ -0,0 +1,12 @@
+extern void err(char *message);
+
+extern int user_write(int fd, const void *buf, size_t count);
+extern int user_read(int fd, void *buf, size_t count);
+extern int select_loop(int s);
+
+extern void init_compress(void);
+extern void end_compress(void);
+
+extern int compression;
+extern int paclen_in;
+extern int paclen_out;