summaryrefslogtreecommitdiffstats
path: root/user_call
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-04-21 09:51:03 +0200
committerRalf Baechle <ralf@linux-mips.org>1999-04-21 09:51:03 +0200
commit17287576555a5c46fa23549e2e5f073660dccb70 (patch)
tree08be5f5005dad609a2803758b8b825170f6701cb /user_call
Import ax25-tools 0.0.1 from tarballax25-tools-0.0.1
Diffstat (limited to 'user_call')
-rw-r--r--user_call/Makefile.am10
-rw-r--r--user_call/Makefile.in349
-rw-r--r--user_call/README59
-rw-r--r--user_call/ax25_call.c156
-rw-r--r--user_call/netrom_call.c165
-rw-r--r--user_call/rose_call.c162
6 files changed, 901 insertions, 0 deletions
diff --git a/user_call/Makefile.am b/user_call/Makefile.am
new file mode 100644
index 0000000..5aedbd3
--- /dev/null
+++ b/user_call/Makefile.am
@@ -0,0 +1,10 @@
+
+installconf:
+
+
+sbin_PROGRAMS = ax25_call netrom_call rose_call
+
+man_MANS = ax25_call.8 netrom_call.8 rose_call.8
+
+DATA_EXTRA = $(man_MANS)
+
diff --git a/user_call/Makefile.in b/user_call/Makefile.in
new file mode 100644
index 0000000..232f104
--- /dev/null
+++ b/user_call/Makefile.in
@@ -0,0 +1,349 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+AWK = @AWK@
+CC = @CC@
+MAKEINFO = @MAKEINFO@
+NCURSES_LIB = @NCURSES_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+sbin_PROGRAMS = ax25_call netrom_call rose_call
+
+man_MANS = ax25_call.8 netrom_call.8 rose_call.8
+
+DATA_EXTRA = $(man_MANS)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(sbin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+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_LDADD = $(LDADD)
+ax25_call_DEPENDENCIES =
+ax25_call_LDFLAGS =
+netrom_call_SOURCES = netrom_call.c
+netrom_call_OBJECTS = netrom_call.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_LDADD = $(LDADD)
+rose_call_DEPENDENCIES =
+rose_call_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+
+NROFF = nroff
+DIST_COMMON = README 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
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps user_call/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-sbinPROGRAMS:
+
+clean-sbinPROGRAMS:
+ -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+
+distclean-sbinPROGRAMS:
+
+maintainer-clean-sbinPROGRAMS:
+
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sbindir)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+ax25_call: $(ax25_call_OBJECTS) $(ax25_call_DEPENDENCIES)
+ @rm -f ax25_call
+ $(LINK) $(ax25_call_LDFLAGS) $(ax25_call_OBJECTS) $(ax25_call_LDADD) $(LIBS)
+
+netrom_call: $(netrom_call_OBJECTS) $(netrom_call_DEPENDENCIES)
+ @rm -f netrom_call
+ $(LINK) $(netrom_call_LDFLAGS) $(netrom_call_OBJECTS) $(netrom_call_LDADD) $(LIBS)
+
+rose_call: $(rose_call_OBJECTS) $(rose_call_DEPENDENCIES)
+ @rm -f rose_call
+ $(LINK) $(rose_call_LDFLAGS) $(rose_call_OBJECTS) $(rose_call_LDADD) $(LIBS)
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man8
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man8
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = user_call
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ax25_call.o: ax25_call.c
+netrom_call.o: netrom_call.c
+rose_call.o: rose_call.c
+
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-sbinPROGRAMS
+install-exec: install-exec-am
+
+install-data-am: install-man
+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: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-sbinPROGRAMS clean-compile clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-sbinPROGRAMS distclean-compile distclean-tags \
+ distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-sbinPROGRAMS \
+ maintainer-clean-compile maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \
+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
+
+
+installconf:
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/user_call/README b/user_call/README
new file mode 100644
index 0000000..beee347
--- /dev/null
+++ b/user_call/README
@@ -0,0 +1,59 @@
+This is the first version of the user_call utilities. They are little
+program,s to allow users of ax25d and the node to initiate outgoing AX.25,
+NET/ROM and Rose connections. They are very powerful program because it can
+pretend to be someone else, so be careful !
+
+My testing has been within the confined of the node, but the comments here
+apply equally well to use via ax25d.
+
+Ax25_call takes at least three parameters:
+
+ax25_call <port> <my callsign> <remote callsign> [<digipeaters> ...]
+
+Netrom_call takes three parameters:
+
+netrom_call <port> <my callsign> <remote address>
+
+Rose_call takes four parameters:
+
+rose_call <port> <my callsign> <remote callsign> <remote Rose address>
+
+The <port> is the name of a local AX.25, NET/ROM or Rose port as defined in
+the axports, nrports or rsports files respectively. <my callsign> is the
+callsign that this connection appears to have come from, ie the local
+*user*. It has nothing to do with your AX.25 port callsign.
+
+Ax25_call must have at least the callsign of the remote user and a set of
+optional digipeaters.
+
+The <remote address> for netrom_call may be of two forms, either the remote
+node callsign, or a combination of the remote node alias and remote node
+callsign seperated by a ':'. Netrom_call only connects to the remote
+callisgn, the full address is sent to the local user for information.
+
+The <remote callsign> for rose_call is the "service" at the remote Rose
+node, ie USERS or any other valid AX.25 callsign, <remote Rose address> is
+the ten-digit Rose address of the remote node.
+
+To start any of these from within the node, you will need to add a line like
+the following to the /etc/ax25/node.conf file, this example uses rose_call:
+
+ExtCmd BBS 0 root /usr/sbin/rose_call rose_call rose %S k4dpz 3100352392
+
+This assumes that rose_call is installed in /usr/sbin which is the default.
+This will create a new command "BBS" for the node, which when typed will
+connect the user to the callsign K4DPZ at remote Rose node 3100352392. The
+callsign of the local user is where the %S appears in the line, it is
+substituted by node for the users callsign. See node.conf(5) for more
+details of the syntax.
+
+Setting up these programs via ax25d is also quite simple and is similar
+conceptually to the example above.
+
+All of these programs generates errors that are received by the local user,
+so if there are any problems then the local user will be able to quote the
+message to you.
+
+Give them a whirl and let me know how you go.
+
+Jonathan
diff --git a/user_call/ax25_call.c b/user_call/ax25_call.c
new file mode 100644
index 0000000..aaa47ce
--- /dev/null
+++ b/user_call/ax25_call.c
@@ -0,0 +1,156 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <sys/socket.h>
+#include <netax25/ax25.h>
+#include <netrose/rose.h>
+#include <netax25/axlib.h>
+#include <netax25/axconfig.h>
+
+void alarm_handler(int sig)
+{
+}
+
+void err(char *message)
+{
+ 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);
+ struct full_sockaddr_ax25 axbind, axconnect;
+
+ /*
+ * Arguments should be "ax25_call port mycall remcall [digis ...]"
+ */
+ if (argc < 4) {
+ strcpy(buffer, "ERROR: invalid number of parameters\r");
+ err(buffer);
+ }
+
+ if (ax25_config_load_ports() == 0) {
+ strcpy(buffer, "ERROR: problem with axports file\r");
+ err(buffer);
+ }
+
+ /*
+ * Parse the passed values for correctness.
+ */
+ 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]);
+ 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]);
+ 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]);
+ err(buffer);
+ }
+
+ if (ax25_aton_arglist(argv + 3, &axconnect) == -1) {
+ sprintf(buffer, "ERROR: invalid destination callsign or digipeater\r");
+ err(buffer);
+ }
+
+ /*
+ * Open the socket into the kernel.
+ */
+ if ((s = socket(AF_AX25, SOCK_SEQPACKET, 0)) < 0) {
+ sprintf(buffer, "ERROR: cannot open AX.25 socket, %s\r", strerror(errno));
+ err(buffer);
+ }
+
+ /*
+ * Set our AX.25 callsign and AX.25 port callsign accordingly.
+ */
+ if (bind(s, (struct sockaddr *)&axbind, addrlen) != 0) {
+ sprintf(buffer, "ERROR: cannot bind AX.25 socket, %s\r", strerror(errno));
+ err(buffer);
+ }
+
+ sprintf(buffer, "Connecting to %s ...\r", argv[3]);
+ 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 *)&axconnect, addrlen) != 0) {
+ switch (errno) {
+ case ECONNREFUSED:
+ strcpy(buffer, "*** Connection refused - aborting\r");
+ break;
+ case ENETUNREACH:
+ strcpy(buffer, "*** No known route - aborting\r");
+ break;
+ case EINTR:
+ strcpy(buffer, "*** Connection timed out - aborting\r");
+ break;
+ default:
+ sprintf(buffer, "ERROR: cannot connect to AX.25 callsign, %s\r", strerror(errno));
+ break;
+ }
+
+ err(buffer);
+ }
+
+ /*
+ * We got there.
+ */
+ alarm(0);
+
+ strcpy(buffer, "*** Connected\r");
+ 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);
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &read_fd)) {
+ if ((n = read(STDIN_FILENO, buffer, 512)) == -1) {
+ close(s);
+ break;
+ }
+ write(s, buffer, n);
+ }
+ }
+
+ return 0;
+}
diff --git a/user_call/netrom_call.c b/user_call/netrom_call.c
new file mode 100644
index 0000000..004b109
--- /dev/null
+++ b/user_call/netrom_call.c
@@ -0,0 +1,165 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <sys/socket.h>
+#include <netax25/ax25.h>
+#include <netrom/netrom.h>
+#include <netrose/rose.h>
+
+#include <netax25/axlib.h>
+#include <netax25/axconfig.h>
+#include <netax25/nrconfig.h>
+
+void alarm_handler(int sig)
+{
+}
+
+void err(char *message)
+{
+ 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);
+ struct full_sockaddr_ax25 nrbind, nrconnect;
+
+ /*
+ * Arguments should be "netrom_call port mycall remaddr"
+ */
+ if (argc != 4) {
+ strcpy(buffer, "ERROR: invalid number of parameters\r");
+ err(buffer);
+ }
+
+ if (nr_config_load_ports() == 0) {
+ strcpy(buffer, "ERROR: problem with nrports file\r");
+ err(buffer);
+ }
+
+ /*
+ * Parse the passed values for correctness.
+ */
+ nrconnect.fsa_ax25.sax25_family = nrbind.fsa_ax25.sax25_family = AF_NETROM;
+ 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]);
+ 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]);
+ err(buffer);
+ }
+
+ if (ax25_aton_entry(argv[2], nrbind.fsa_digipeater[0].ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[2]);
+ err(buffer);
+ }
+
+ if ((addr = strchr(argv[3], ':')) == NULL)
+ addr = argv[3];
+ else
+ addr++;
+
+ if (ax25_aton_entry(addr, nrconnect.fsa_ax25.sax25_call.ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[3]);
+ err(buffer);
+ }
+
+ /*
+ * Open the socket into the kernel.
+ */
+ if ((s = socket(AF_NETROM, SOCK_SEQPACKET, 0)) < 0) {
+ sprintf(buffer, "ERROR: cannot open NET/ROM socket, %s\r", strerror(errno));
+ err(buffer);
+ }
+
+ /*
+ * Set our AX.25 callsign and NET/ROM callsign accordingly.
+ */
+ if (bind(s, (struct sockaddr *)&nrbind, addrlen) != 0) {
+ sprintf(buffer, "ERROR: cannot bind NET/ROM socket, %s\r", strerror(errno));
+ err(buffer);
+ }
+
+ sprintf(buffer, "Connecting to %s ...\r", argv[3]);
+ 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 *)&nrconnect, addrlen) != 0) {
+ switch (errno) {
+ case ECONNREFUSED:
+ strcpy(buffer, "*** Connection refused - aborting\r");
+ break;
+ case ENETUNREACH:
+ strcpy(buffer, "*** No known route - aborting\r");
+ break;
+ case EINTR:
+ strcpy(buffer, "*** Connection timed out - aborting\r");
+ break;
+ default:
+ sprintf(buffer, "ERROR: cannot connect to NET/ROM node, %s\r", strerror(errno));
+ break;
+ }
+
+ err(buffer);
+ }
+
+ /*
+ * We got there.
+ */
+ alarm(0);
+
+ strcpy(buffer, "*** Connected\r");
+ 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);
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &read_fd)) {
+ if ((n = read(STDIN_FILENO, buffer, 512)) == -1) {
+ close(s);
+ break;
+ }
+ write(s, buffer, n);
+ }
+ }
+
+ return 0;
+}
diff --git a/user_call/rose_call.c b/user_call/rose_call.c
new file mode 100644
index 0000000..606284d
--- /dev/null
+++ b/user_call/rose_call.c
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <sys/socket.h>
+#include <netax25/ax25.h>
+#include <netrose/rose.h>
+#include <netax25/axlib.h>
+#include <netax25/axconfig.h>
+#include <netax25/rsconfig.h>
+
+void alarm_handler(int sig)
+{
+}
+
+void err(char *message)
+{
+ 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);
+ struct sockaddr_rose rosebind, roseconnect;
+
+ /*
+ * Arguments should be "rose_call port mycall remcall remaddr"
+ */
+ if (argc != 5) {
+ strcpy(buffer, "ERROR: invalid number of parameters\r");
+ err(buffer);
+ }
+
+ if (rs_config_load_ports() == 0) {
+ strcpy(buffer, "ERROR: problem with rsports file\r");
+ err(buffer);
+ }
+
+ /*
+ * Parse the passed values for correctness.
+ */
+ 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]);
+ err(buffer);
+ }
+
+ if (rose_aton(addr, rosebind.srose_addr.rose_addr) == -1) {
+ sprintf(buffer, "ERROR: invalid Rose port address - %s\r", argv[1]);
+ err(buffer);
+ }
+
+ if (ax25_aton_entry(argv[2], rosebind.srose_call.ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[2]);
+ err(buffer);
+ }
+
+ if (ax25_aton_entry(argv[3], roseconnect.srose_call.ax25_call) == -1) {
+ sprintf(buffer, "ERROR: invalid callsign - %s\r", argv[3]);
+ err(buffer);
+ }
+
+ if (rose_aton(argv[4], roseconnect.srose_addr.rose_addr) == -1) {
+ sprintf(buffer, "ERROR: invalid Rose address - %s\r", argv[4]);
+ err(buffer);
+ }
+
+ /*
+ * Open the socket into the kernel.
+ */
+ if ((s = socket(AF_ROSE, SOCK_SEQPACKET, 0)) < 0) {
+ sprintf(buffer, "ERROR: cannot open Rose socket, %s\r", strerror(errno));
+ err(buffer);
+ }
+
+ /*
+ * Set our AX.25 callsign and Rose address accordingly.
+ */
+ if (bind(s, (struct sockaddr *)&rosebind, addrlen) != 0) {
+ sprintf(buffer, "ERROR: cannot bind Rose socket, %s\r", strerror(errno));
+ err(buffer);
+ }
+
+ sprintf(buffer, "Connecting to %s @ %s ...\r", argv[3], argv[4]);
+ 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 *)&roseconnect, addrlen) != 0) {
+ switch (errno) {
+ case ECONNREFUSED:
+ strcpy(buffer, "*** Connection refused - aborting\r");
+ break;
+ case ENETUNREACH:
+ strcpy(buffer, "*** No known route - aborting\r");
+ break;
+ case EINTR:
+ strcpy(buffer, "*** Connection timed out - aborting\r");
+ break;
+ default:
+ sprintf(buffer, "ERROR: cannot connect to Rose address, %s\r", strerror(errno));
+ break;
+ }
+
+ err(buffer);
+ }
+
+ /*
+ * We got there.
+ */
+ alarm(0);
+
+ strcpy(buffer, "*** Connected\r");
+ 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);
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &read_fd)) {
+ if ((n = read(STDIN_FILENO, buffer, 512)) == -1) {
+ close(s);
+ break;
+ }
+ write(s, buffer, n);
+ }
+ }
+
+ return 0;
+}