From 17287576555a5c46fa23549e2e5f073660dccb70 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 21 Apr 1999 09:51:03 +0200 Subject: Import ax25-tools 0.0.1 from tarball --- user_call/Makefile.am | 10 ++ user_call/Makefile.in | 349 ++++++++++++++++++++++++++++++++++++++++++++++++ user_call/README | 59 ++++++++ user_call/ax25_call.c | 156 ++++++++++++++++++++++ user_call/netrom_call.c | 165 +++++++++++++++++++++++ user_call/rose_call.c | 162 ++++++++++++++++++++++ 6 files changed, 901 insertions(+) create mode 100644 user_call/Makefile.am create mode 100644 user_call/Makefile.in create mode 100644 user_call/README create mode 100644 user_call/ax25_call.c create mode 100644 user_call/netrom_call.c create mode 100644 user_call/rose_call.c (limited to 'user_call') 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 [ ...] + +Netrom_call takes three parameters: + +netrom_call + +Rose_call takes four parameters: + +rose_call + +The is the name of a local AX.25, NET/ROM or Rose port as defined in +the axports, nrports or rsports files respectively. 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 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 for rose_call is the "service" at the remote Rose +node, ie USERS or any other valid AX.25 callsign, 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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +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 +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +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; +} -- cgit v1.2.3