From acdb41fa04d40571ee4d84e2607515643d410671 Mon Sep 17 00:00:00 2001 From: Thomas Osterried Date: Sun, 10 Dec 2006 19:12:59 +0000 Subject: axgetput (bget, bput, ..) for 8bit clean up/download from an axspawn(8) login session. Initial checkin. Import from http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ --- ax25/axgetput/Makefile.am | 22 ++ ax25/axgetput/Makefile.in | 508 ++++++++++++++++++++++++++++++++++++++++++++++ ax25/axgetput/README | 11 + ax25/axgetput/TIPS.txt | 3 + ax25/axgetput/TODO | 3 + ax25/axgetput/axgetput.c | 415 +++++++++++++++++++++++++++++++++++++ ax25/axgetput/axgetput.h | 47 +++++ ax25/axgetput/includes.h | 26 +++ ax25/axgetput/proto_bin.c | 489 ++++++++++++++++++++++++++++++++++++++++++++ ax25/axgetput/proto_bin.h | 34 ++++ ax25/axgetput/util.c | 208 +++++++++++++++++++ ax25/axgetput/util.h | 20 ++ 12 files changed, 1786 insertions(+) create mode 100644 ax25/axgetput/Makefile.am create mode 100644 ax25/axgetput/Makefile.in create mode 100644 ax25/axgetput/README create mode 100644 ax25/axgetput/TIPS.txt create mode 100644 ax25/axgetput/TODO create mode 100644 ax25/axgetput/axgetput.c create mode 100644 ax25/axgetput/axgetput.h create mode 100644 ax25/axgetput/includes.h create mode 100644 ax25/axgetput/proto_bin.c create mode 100644 ax25/axgetput/proto_bin.h create mode 100644 ax25/axgetput/util.c create mode 100644 ax25/axgetput/util.h (limited to 'ax25') diff --git a/ax25/axgetput/Makefile.am b/ax25/axgetput/Makefile.am new file mode 100644 index 0000000..ed37878 --- /dev/null +++ b/ax25/axgetput/Makefile.am @@ -0,0 +1,22 @@ + +installconf: + +etcfiles = +varfiles = + +sbin_PROGRAMS = + +bin_PROGRAMS = axgetput + +man_MANS = axgetput.1 + +EXTRA_DIST = $(man_MANS) + +axgetput_SOURCES = axgetput.c axgetput.h util.h proto_bin.h util.c proto_bin.c includes.h + +install-exec-local: + (cd $(DESTDIR)$(bindir) && ln -sf axgetput bget && ln -sf axgetput bput) + make install-man-local + +install-man-local: + (cd $(DESTDIR)$(mandir)/man1 && ln -sf axgetput.1 bget.1 && ln -sf axgetput.1 bput.1) diff --git a/ax25/axgetput/Makefile.in b/ax25/axgetput/Makefile.in new file mode 100644 index 0000000..14249cd --- /dev/null +++ b/ax25/axgetput/Makefile.in @@ -0,0 +1,508 @@ +# Makefile.in generated by automake 1.9.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 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. + +@SET_MAKE@ + +SOURCES = $(axgetput_SOURCES) + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +sbin_PROGRAMS = +bin_PROGRAMS = axgetput$(EXEEXT) +subdir = ax25/axgetput +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in TODO +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \ + "$(DESTDIR)$(man1dir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) +am_axgetput_OBJECTS = axgetput.$(OBJEXT) util.$(OBJEXT) \ + proto_bin.$(OBJEXT) +axgetput_OBJECTS = $(am_axgetput_OBJECTS) +axgetput_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(axgetput_SOURCES) +DIST_SOURCES = $(axgetput_SOURCES) +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +AX25IO_LIB = @AX25IO_LIB@ +AX25_LIB = @AX25_LIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FLTK_LIB = @FLTK_LIB@ +HAVE_FLTK_FALSE = @HAVE_FLTK_FALSE@ +HAVE_FLTK_TRUE = @HAVE_FLTK_TRUE@ +HAVE_X_FALSE = @HAVE_X_FALSE@ +HAVE_X_TRUE = @HAVE_X_TRUE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NCURSES_LIB = @NCURSES_LIB@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UTIL_LIB = @UTIL_LIB@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +Z_LIB = @Z_LIB@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +etcfiles = +varfiles = +man_MANS = axgetput.1 +EXTRA_DIST = $(man_MANS) +axgetput_SOURCES = axgetput.c axgetput.h util.h proto_bin.h util.c proto_bin.c includes.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ax25/axgetput/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu ax25/axgetput/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ + rm -f "$(DESTDIR)$(sbindir)/$$f"; \ + done + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) +axgetput$(EXEEXT): $(axgetput_OBJECTS) $(axgetput_DEPENDENCIES) + @rm -f axgetput$(EXEEXT) + $(LINK) $(axgetput_LDFLAGS) $(axgetput_OBJECTS) $(axgetput_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/axgetput.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proto_bin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +uninstall-info-am: +install-man1: $(man1_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)" + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) 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/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ + done +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-man + +install-exec-am: install-binPROGRAMS install-exec-local \ + install-sbinPROGRAMS + +install-info: install-info-am + +install-man: install-man1 + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-man \ + uninstall-sbinPROGRAMS + +uninstall-man: uninstall-man1 + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-sbinPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-exec \ + install-exec-am install-exec-local install-info \ + install-info-am install-man install-man1 install-sbinPROGRAMS \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-info-am uninstall-man uninstall-man1 \ + uninstall-sbinPROGRAMS + + +installconf: + +install-exec-local: + (cd $(DESTDIR)$(bindir) && ln -sf axgetput bget && ln -sf axgetput bput) + make install-man-local + +install-man-local: + (cd $(DESTDIR)$(mandir)/man1 && ln -sf axgetput.1 bget.1 && ln -sf axgetput.1 bput.1) +# 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/ax25/axgetput/README b/ax25/axgetput/README new file mode 100644 index 0000000..87d8c01 --- /dev/null +++ b/ax25/axgetput/README @@ -0,0 +1,11 @@ +This shell utility is for up/downloading files via your ax25 unix login +session which is managed by axspawn. +you need a //BIN compatible axspawn, which has the functionality of making +the stream 8bit compatible (normally the EOL-conversion <-> +prevents this). see: + http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/patches/linux-ax25/ + +The location of these sources is + http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + +Since 2006-12-10, axgetput is part of the ax25-tools (s. linux-ax25.org). diff --git a/ax25/axgetput/TIPS.txt b/ax25/axgetput/TIPS.txt new file mode 100644 index 0000000..29d56e8 --- /dev/null +++ b/ax25/axgetput/TIPS.txt @@ -0,0 +1,3 @@ +- compressed download: + gzip -c foo.txt | bget foo.txt.gz + tar cjf - ~/foo ~/bar/ | bget my_data.tar.bz2 diff --git a/ax25/axgetput/TODO b/ax25/axgetput/TODO new file mode 100644 index 0000000..88881c6 --- /dev/null +++ b/ax25/axgetput/TODO @@ -0,0 +1,3 @@ + +- yapp support +- didadit support diff --git a/ax25/axgetput/axgetput.c b/ax25/axgetput/axgetput.c new file mode 100644 index 0000000..1e0a908 --- /dev/null +++ b/ax25/axgetput/axgetput.c @@ -0,0 +1,415 @@ +static const char rcsid[] = "@(#) $Id: axgetput.c,v 1.1 2006/12/10 19:12:59 dl9sau Exp $"; + +/* + * This is axgetput + * + * This shell utility is for up/downloading files via your ax25 unix login + * session which is managed by axspawn. + * you need a //BIN compatible axspawn, which has the functionality of making + * the stream 8bit compatible (normally the EOL-conversion <-> + * prevents this). see: + * http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/patches/linux-ax25/ + * + * (c) 2002 Thomas Osterried DL9SAU + * License: GPL. See http://www.fsf.org/ + * Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + * + */ + + +#include "includes.h" + +#include "axgetput.h" +#include "util.h" +#include "proto_bin.h" + +extern char *optarg; +extern int optind; +extern int errno; + +int fdin = 0; +int fdout = 1; +int fderr = 2; +int fdout_is_pipe = 0; +int fdin_is_pipe = 0; + +int is_stream = 0; +int mode = 0; +int do_crc_only = 0; + +char c_eol = '\n'; + +unsigned int BLOCKSIZ = BLOCKSIZ_DEFAULT; + +char *send_on_signal = 0; + +static struct termios prev_termios; +static int prev_termios_stored = 0; +static mode_t mode_tty = 0; + +#ifndef MYNAME +#define MYNAME "axgetput" +#endif + +struct revision { + char number[16]; + char date[16]; + char time[16]; + char author[16]; + char state[16]; +}; + +static struct revision revision; + +/*---------------------------------------------------------------------------*/ + +static void set_tty_flags() +{ + struct termios termios; + struct stat statbuf; + + if (fdin_is_pipe) + return; + // mesg no + if (!fstat(fdin, &statbuf)) { + // save old mode + mode_tty = statbuf.st_mode; + fchmod(fdin, 0600); + } + // make tty 8bit clean + if (tcgetattr(fdin, &prev_termios) != -1) + prev_termios_stored = 1; + memset((char *) &termios, 0, sizeof(termios)); + termios.c_iflag = IGNBRK | IGNPAR; + termios.c_oflag = 0; + termios.c_cflag = CBAUD | CS8 | CREAD | CLOCAL; + termios.c_cflag = ~(CSTOPB|PARENB|PARODD|HUPCL); + termios.c_lflag = 0; + termios.c_cc[VMIN] = 1; + termios.c_cc[VTIME] = 0; + termios.c_cc[VSTART] = -1; + termios.c_cc[VSTOP] = -1; + tcsetattr(fdin, TCSANOW, &termios); +} + +/*---------------------------------------------------------------------------*/ + +static void restore_tty_flags() +{ + if (fdin_is_pipe) + return; + if (prev_termios_stored) + tcsetattr(fdin, TCSANOW, &prev_termios); + if (mode_tty) + fchmod(fdin, mode_tty); +} + +/*---------------------------------------------------------------------------*/ + +static void eol_convention(int state_should) +{ + // need patched axspawn +#define BIN_ON "//BIN ON\r" +#define BIN_OFF "//BIN OFF\r" + static int state_is = 0; + + // already in correct state? + if ((state_is && state_should) || (!state_is && !state_should)) + return; + + sleep(1); + + if (state_should) { + write(fderr, BIN_ON, strlen(BIN_ON)); + c_eol = '\r'; + } else { + write(fderr, BIN_OFF, strlen(BIN_OFF)); + c_eol = '\n'; + } + state_is = state_should; + + sleep(1); +} + +/*---------------------------------------------------------------------------*/ + +static void restore_defaults() +{ + eol_convention(0); + restore_tty_flags(); +} + +/*---------------------------------------------------------------------------*/ + +static void signal_handler(int sig) +{ + if (send_on_signal) + secure_write(fdout, send_on_signal, strlen(send_on_signal)); + restore_defaults(); + if (*err_msg) { + fputs(err_msg, stderr); + } + fprintf(stderr, "Died by signal %d.\n", sig); + exit(sig); +} + +/*---------------------------------------------------------------------------*/ + +void do_version(void) +{ + fprintf(stderr, MYNAME " %s %s\n", revision.number, revision.date); + fprintf(stderr, " (c) 2002 Thomas Osterried \n"); + fprintf(stderr, " License: GPL. See http://www.fsf.org/\n"); + fprintf(stderr, " Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/\n"); +} + +/*---------------------------------------------------------------------------*/ + +static void usage(int all) { + fprintf(stderr, "usage: %s ", myname); + if (mode % 2) { + fprintf(stderr, "[-ivh] [filename]\n"); + } else { + fprintf(stderr, "[-isvh] [-b ] [filename]\n"); + } + fprintf(stderr, " -h prints detailed help\n"); + fprintf(stderr, " -i computes checksum only\n"); + fprintf(stderr, " -v prints version and exits\n"); + if (!all) + return; + if (mode % 2) { + fprintf(stderr, " filename is usually got from the remote side by the protocol\n"); + fprintf(stderr, " but can be forced if you like to ignore this.\n"); + fprintf(stderr, " filename should be ommitted if output is sent to a pipe\n."); + } else { + fprintf(stderr, " -b value is the blocksize (framelen) of the transmitted data\n"); + fprintf(stderr, " default %d, which is a useful choice for ampr ax25.\n", BLOCKSIZ_DEFAULT); + fprintf(stderr, " -s indicates a stream with unknown size.\n"); + fprintf(stderr, " otherwise, the data will be read to memory until EOF.\n"); + fprintf(stderr, " -s is only available if stdin is a pipe\n"); + fprintf(stderr, " if filename specified in filter, the given name will be suggested instead.\n"); + fprintf(stderr, " filename may be ommited if used as filter.\n"); + } + fputc('\n', stderr); + fprintf(stderr, "Tips: - compressed download:\n"); + fprintf(stderr, " gzip -c foo.txt | bget foo.txt.gz\n"); + fprintf(stderr, " tar cjf - ~/foo ~/bar/ | bget my_data.tar.bz2\n"); + fputc('\n', stderr); + fprintf(stderr, "Other protocols:\n"); + fprintf(stderr, " bget / bput: receive / send with #BIN# protocol\n"); + fprintf(stderr, " yget / yput: receive / send with yapp\n"); + fprintf(stderr, " rget / rput: receive / send with didadit\n"); + fprintf(stderr, "These are (sym)links to one program: " MYNAME "\n"); +} + + +/*---------------------------------------------------------------------------*/ + +// not implemented +static int yput(void) { strcpy(err_msg, "yapp: not implementet yet\n"); return 1; } +static int yget(void) { strcpy(err_msg, "yapp: not implementet yet\n"); return 1; } +static int rget(void) { strcpy(err_msg, "yapp: not implementet yet\n"); return 1; } +static int rput(void) { strcpy(err_msg, "yapp: not implementet yet\n"); return 1; } + +/*---------------------------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + + int len; + int ret = 0; + int c; + char *p; + char buf[1024]; + + strcpy(buf, rcsid); + sscanf(buf, "%*s %*s %*s %s %s %s %s %s", + revision.number, + revision.date, + revision.time, + revision.author, + revision.state); + + // determine what to so in the way how we are called + if ((p = strrchr(argv[0], '/'))) + p++; // skip '/' + else + p = argv[0]; + len = strlen(p); + if (len < 0 || len > sizeof(myname)-1) + len = sizeof(myname)-1; + strncpy(myname, p, len); + myname[len] = 0; + strlwc(myname); + + fdin_is_pipe = (isatty(fdin) ? 0 : 1); + fdout_is_pipe = (isatty(fdout) ? 0 : 1); + + if (fdin_is_pipe && fdout_is_pipe) { + fprintf(stderr, "error: cannot work in between two pipes\n"); + exit(1); + } + + *filename = 0; + *err_msg = 0; + + if (!strcmp(myname, "bput")) + mode = RECV_BIN; + else if (!strcmp(myname, "bget")) + mode = SEND_BIN; + else if (!strcmp(myname, "yput")) + mode = RECV_YAPP; + else if (!strcmp(myname, "yget")) + mode = SEND_YAPP; + else if (!strcmp(myname, "rput")) + mode = RECV_DIDADIT; + else if (!strcmp(myname, "rget")) + mode = SEND_DIDADIT; + + if (mode % 2) { + if (fdin_is_pipe) { + fprintf(stderr, "error: error: stdin must be a tty\n"); + exit(1); + } + } else { + if (fdout_is_pipe) { + fprintf(stderr, "error: stdout must be a tty\n"); + exit(1); + } + } + + signal(SIGHUP, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGINT, signal_handler); + +// for difference betreen "bput -f file" and "bget file" +#define get_filename(f) { \ + if (!strcmp(f, "-")) { \ + if (mode % 2) \ + fdin_is_pipe = 1; \ + else \ + fdout_is_pipe = 1; \ + } else { \ + strncpy(filename, f, sizeof(filename)-1); \ + filename[sizeof(filename)-1] = 0; \ + if (mode % 2) { \ + if (fdin_is_pipe) \ + fdin_is_pipe = 0; \ + } else { \ + if (fdout_is_pipe) \ + fdout_is_pipe = 0; \ + } \ + } \ +} + + while ((c = getopt(argc, argv, (mode % 2) ? "ivh?" : "b:isvh?")) != EOF) { + switch(c) { + case 'b': + if (((BLOCKSIZ = (unsigned ) atoi(optarg)) < BLOCKSIZ_MIN) || BLOCKSIZ > BLOCKSIZ_MAX) { + fprintf(stderr, "error: invalid blocksize: %d\n", BLOCKSIZ); + fprintf(stderr, " blocksize must be in the range %d <= x <= %d. a value\n", BLOCKSIZ_MIN, BLOCKSIZ_MAX); + fprintf(stderr, " of %d (default) is suggested, because it fits in an ax25 frame.\n", BLOCKSIZ_DEFAULT); + exit(1); + } + break; + case 'i': + do_crc_only = 1; + break; + case 's': + is_stream = 1; + break; + case 'v': + do_version(); + exit(0); + break; + case 'h': + case '?': + usage((c == 'h')); + exit(0); + break; + } + } + + if (mode == 0) { + usage(1); + exit(0); + } + + if (optind < argc) { + get_filename(argv[optind]); + optind++; + } + if (optind < argc) { + usage(0); + exit(1); + } + + if (is_stream && !fdin_is_pipe) { + fprintf(stderr, "error: -s is only available in a pipe\n"); + exit(1); + } + + if (do_crc_only) + goto skiped_crc_only_tag_1; + + if (mode % 2) { + if (fdin_is_pipe) { + fprintf(stderr, "error: error: stdin must be a tty.\n"); + exit(1); + } + if (fdout_is_pipe && *filename) { + fprintf(stderr, "error: filename in a pipe does not make sense.\n"); + exit(1); + } + } else { + if (fdout_is_pipe) { + fprintf(stderr, "error: stdout must be a tty.\n"); + exit(1); + } + if (!fdin_is_pipe && !*filename) { + fprintf(stderr, "error: no file to send.\n"); + exit(1); + } + } + + signal(SIGQUIT, signal_handler); + + set_tty_flags(); + eol_convention(1); + +skiped_crc_only_tag_1: + + switch (mode) { + case RECV_BIN: + if (do_crc_only) + ret = bget(); + else + ret = bput(); + break; + case SEND_BIN: + ret = bget(); + break; + case RECV_YAPP: + ret = yput(); + break; + case SEND_YAPP: + ret = yget(); + break; + case RECV_DIDADIT: + ret = rput(); + break; + case SEND_DIDADIT: + ret = rget(); + break; + } + + restore_defaults(); + if (*err_msg) { + fputs(err_msg, stderr); + } + exit(ret); + + return 0; + +} + diff --git a/ax25/axgetput/axgetput.h b/ax25/axgetput/axgetput.h new file mode 100644 index 0000000..410c77d --- /dev/null +++ b/ax25/axgetput/axgetput.h @@ -0,0 +1,47 @@ +/* @(#) $Id: axgetput.h,v 1.1 2006/12/10 19:12:59 dl9sau Exp $ */ + +/* + * (c) 2002 Thomas Osterried DL9SAU + * License: GPL. See http://www.fsf.org/ + * Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + */ + +#ifndef AXGETPUT_H +#define AXGETPUT_H + +extern int fdin; +extern int fdout; +extern int fderr; + +extern int fdin_is_pipe; +extern int fdout_is_pipe; + +char myname[PATH_MAX+1]; +char filename[PATH_MAX+1]; +char err_msg[2048]; + +extern int is_stream; +extern int mode; +extern int do_crc_only; + +extern char c_eol; +extern char *send_on_signal; + +// modes +#define RECV_BIN 1 /* #BIN# protocol: receive */ +#define SEND_BIN 2 /* #BIN# protocol: send */ +#define RECV_YAPP 3 /* yapp protocol: receive */ +#define SEND_YAPP 4 /* yapp protocol: send */ +#define RECV_DIDADIT 5 /* didadit protocol: receive */ +#define SEND_DIDADIT 6 /* didadit protocol: send */ + + +// block sizes + +extern unsigned int BLOCKSIZ; + +#define BLOCKSIZ_MIN 1 /* not suggested */ +#define BLOCKSIZ_DEFAULT 256 /* useful, because it fits in an ax25 frame */ +#define BLOCKSIZ_MAX 1024 /* max. our buffer relies on it */ + +#endif /* AXGETPUT_H */ diff --git a/ax25/axgetput/includes.h b/ax25/axgetput/includes.h new file mode 100644 index 0000000..3c6549d --- /dev/null +++ b/ax25/axgetput/includes.h @@ -0,0 +1,26 @@ +#ifndef INCLUDES_H +#define INCLUDES_H + +/* + * (c) 2002 Thomas Osterried DL9SAU + * License: GPL. See http://www.fsf.org/ + * Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* INCLUDES_H */ diff --git a/ax25/axgetput/proto_bin.c b/ax25/axgetput/proto_bin.c new file mode 100644 index 0000000..c826ec3 --- /dev/null +++ b/ax25/axgetput/proto_bin.c @@ -0,0 +1,489 @@ +/* @(#) $Id: proto_bin.c,v 1.1 2006/12/10 19:12:59 dl9sau Exp $ */ + +/* + * (c) 2002 Thomas Osterried DL9SAU + * License: GPL. See http://www.fsf.org/ + * Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + */ + +#include "includes.h" + +#include "proto_bin.h" +#include "axgetput.h" +#include "util.h" + +static int crctab[256]; +static int bittab[8] = { 128,64,32,16,8,4,2,1 }; +static int crcbit[8] = { + 0x9188,0x48c4,0x2462,0x1231,0x8108,0x4084,0x2042,0x1021 +}; + +/*---------------------------------------------------------------------------*/ + +static int init_crc(void) +{ + int i,j; + + for (i = 0; i < 256; i++) { + crctab[i] = 0; + for (j = 0; j < 8; j++) { + if ((bittab[j] & i) != 0) { + crctab[i] = crctab[i] ^ crcbit[j]; + } + } + } + return 0; +} + +/*---------------------------------------------------------------------------*/ + +static int do_crc(char b, int n, unsigned int crc) +{ + crc = (crctab[(crc >> 8)] ^ ((crc << 8) | (b & 0xff))) & 0xffff; + return (crc); +} + +/*---------------------------------------------------------------------------*/ + +static long parse_sfbin_date_to_unix(const char *s) +{ + + unsigned long x; + + sscanf(s, "%lX", &x); + + return date_dos2unix(((x << 16) >> 16), (x >> 16)); +} + +/*---------------------------------------------------------------------------*/ + +static char * unix_to_sfbin_date_string(long gmt) +{ + + static char buf[9]; + unsigned short s_time, s_date; + + date_unix2dos(((gmt == -1) ? time(0) : gmt), &s_time, &s_date); + sprintf(buf, "%X", ((s_date << 16) + s_time)); + return buf; +} + +/*---------------------------------------------------------------------------*/ + +int bput(void) +{ + struct stat statbuf; + char buf[1024]; /* < signed int */ + char tmpbuf[1024]; + char filename_given[PATH_MAX]; + unsigned long len_read_expected = 0; + unsigned long len_read_left; + time_t file_time = 0L; + unsigned int msg_crc = 0; + unsigned int crc = 0; + char *term_line = 0; + int last_line_had_CR = 0; + int len_termline = 0; + int len = 0; + int fddata = fdout; + int is_eof; + char *p, *q; + +#define save_close(x) { \ + if (!fdout_is_pipe) \ + close(x); \ +} + + + for (;;) { + len = my_read(fdin, buf, sizeof(buf), &is_eof, "\r\n"); + if (is_eof || len < 1) { + sprintf(err_msg, "error: read failed (%s)\n", strerror(errno)); + return 1; + } + if (buf[len-1] == '\n') { + //p = "warning: received. not 8bit clean?\r"; + //secure_write(fdout, p, strlen(p)); + sprintf(err_msg, "bad EOL: \n"); + return 1; + } + if (IS_BIN_ABORT(buf, len)) { + sprintf(err_msg, "Aborted by user request\n"); + return 1; + } + if (buf[len-1] == '\r' && len > 5 && !memcmp(buf, "#BIN#", 5)) { + break; + } + if (len == sizeof(buf)) { + sprintf(err_msg, "line to long\n"); + return 1; + } + } + buf[len-1] = 0; // without trailing \r. and: string termination + + send_on_signal = bin_send_no_on_sig; + + /* parse #BIN arguments */ + *filename_given = 0; + *tmpbuf = 0; + sscanf(buf, "#BIN#%ld#|%d#%s", &len_read_expected, &msg_crc, tmpbuf); + p = tmpbuf; + if (*tmpbuf == '$') { + p++; + if ((q = strchr(tmpbuf, '#'))) { + *q++ = 0; + p = q; + } + file_time = parse_sfbin_date_to_unix(tmpbuf+1); + } + strncpy(filename_given, p, sizeof(filename_given)-1); + filename_given[sizeof(filename_given)-1] = 0; + + if (!fdout_is_pipe) { + // normal mode: store in given filename + if (!*filename) { + p = get_fixed_filename(filename_given, len_read_expected, msg_crc, 1); + strncpy(filename, p, sizeof(filename)-1); + filename[sizeof(filename)-1] = 0; + } + if (!stat(filename, &statbuf)) { + // file exist + if (unlink(filename)) { + sprintf(err_msg, "error: cannot unlink %s (%s)\n", filename, strerror(errno)); + goto abort; + } + } + if ((fddata = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0640)) < 0) { + sprintf(err_msg, "error: cannot open %s (%s)\n", filename, strerror(errno)); + write(fderr, "\r#NO#\r", 6); + return 1; + } + } + + if (!len_read_expected) { + term_line = "***END\r"; + len_termline = strlen(term_line); + } + + // say helo + send_on_signal = bin_send_abort_on_sig; + write(fderr, "\r#OK#\r", 6); + + len_read_left = len_read_expected; + + // #bin# chechsum initialization + init_crc(); + + for (;;) { + + if ((len = my_read(fdin, buf, ((term_line || len_read_left > sizeof(buf)) ? sizeof(buf) : len_read_left), &is_eof, "\r")) < 1) { + save_close(fddata); + sprintf(err_msg, "error: read failed (%s)\n", strerror(errno)); + goto abort; + } + if (!len) { + save_close(fddata); + if (!term_line) { + sprintf(err_msg, "error: unexpected end of file during read: %s\n", strerror(errno)); + return 1; + } + return 0; + } + + if (msg_crc) { + int i; + for (i = 0; i < len; i++) + crc = do_crc((int ) buf[i], 1, crc); + } + + if (buf[len-1] == '\r') { + if (last_line_had_CR) { + if (IS_BIN_ABORT(buf, len)) { + // "\r#ABORT#\r" was sent + if (!fdout_is_pipe) { + close(fddata); + // clean up + unlink(filename); + } + return 1; + } + if (term_line && len == len_termline && !memcmp(buf, term_line, len_termline)) { + // sucessfully read until termination string + break; + } + } + last_line_had_CR = 1; + } else { + last_line_had_CR = 0; + } + if (!term_line) + len_read_left -= len; + + if (secure_write(fddata, buf, len) == -1) { + save_close(fddata); + sprintf(err_msg, "error: write failed (%s)\n", strerror(errno)); + goto abort; + } + + // nothing left? + if (!term_line && len_read_left == 0L) + break; + if (is_eof) { + if (!term_line && len_read_left) { + save_close(fddata); + goto abort; + } + break; + } + } + if (crc != msg_crc) { + sprintf(err_msg, "Invalid crc: computed %d, expected %d.\n", crc, msg_crc); + // don't unlink + save_close(fddata); + return 1; + } + if (!fdout_is_pipe) { + close(fddata); + if (file_time != 0L) { + struct utimbuf utb; + utb.modtime = file_time; + utb.actime = time(0); + utime(filename, &utb); + } + } + + send_on_signal = 0; + return 0; + +abort: + sleep(1); + write(fderr, "\r#ABORT#\r", 9); + return 1; +#undef save_close +} + +/*---------------------------------------------------------------------------*/ + +int bget(void) { + struct strlist { + struct strlist *next; + size_t len; + char data[1]; /* actually a the address of char * pointer */ + }; + + struct strlist *stored_file = 0; + struct strlist *sl_tail = 0; + struct strlist *sl; + struct timeval timeout; + struct stat statbuf; + + unsigned int crc = 0; + + char buf[1024]; + fd_set readfds; + int fddata = fdin; + int len; + unsigned long file_size = 0; + unsigned long len_remains; + int is_eof; + int file_time = 0L; + +#define save_close(x) { \ + if (!fdin_is_pipe) \ + close(x); \ +} + +#define store_line(s, len) { \ + if (!(sl = (struct strlist *) malloc(sizeof(struct strlist *) + sizeof(size_t) + len))) \ + return 1; \ + sl->next = 0; \ + sl->len = len; \ + memcpy(sl->data, s, len); \ + if (!stored_file) { \ + stored_file = sl; \ + } else { \ + sl_tail->next = sl; \ + } \ + sl_tail = sl; \ +} + + if (BLOCKSIZ < 1 || BLOCKSIZ > sizeof(buf)) + BLOCKSIZ = BLOCKSIZ_DEFAULT; + + init_crc(); + + if (!fdin_is_pipe && *filename) { + if ((fddata = open(filename, O_RDONLY)) == -1) { + sprintf(err_msg, "error: cannot open %s (%s)\n", filename, strerror(errno)); + return 1; + } + if (!fstat(fddata, &statbuf)) + file_time = statbuf.st_mtime; + else + file_time = time(0); + + // compute crc + while ((len = read(fddata, buf, BLOCKSIZ)) > 0) { + int i; + for (i = 0; i < len; i++) + crc = do_crc((int ) buf[i], 1, crc); + file_size += len; + } + if (len < 0) { + sprintf(err_msg, "error: read failed (%s)\n", strerror(errno)); + close(fddata); + return 1; + } + // rewind + if (lseek(fddata, 0L, SEEK_SET) != 0L) { + sprintf(err_msg, "error: file io failed on lseek() (%s)\n", strerror(errno)); + close(fddata); + return 1; + } + sprintf(buf, "\r#BIN#%ld#|%d#$%s#%s\r", file_size, crc, unix_to_sfbin_date_string(file_time), get_fixed_filename(filename, file_size, crc, 1)); + } else { + file_time = time(0); + if (!is_stream || do_crc_only) { + sprintf(err_msg, "error: not enough memory\n"); + while ((len = read(fddata, buf, sizeof(buf))) > 0) { + int i; + for (i = 0; i < len; i++) + crc = do_crc((int ) buf[i], 1, crc); + file_size += len; + if (!do_crc_only) + store_line(buf, len); + } + if (len < 0) { + sprintf(err_msg, "error: read failed (%s)\n", strerror(errno)); + close(fddata); + return 1; + } + *err_msg = 0; + sprintf(buf, "\r#BIN#%ld#|%d#$%s#%s\r", file_size, crc, unix_to_sfbin_date_string(file_time), get_fixed_filename(filename, file_size, crc, 1)); + } else { + sprintf(buf, "\r#BIN###$%s#%s\r", unix_to_sfbin_date_string(file_time), get_fixed_filename(filename, 0, 0, 1)); + } + // hack: check for #ABORT# from fdout (fd 1), because fddata (fd 0) is + // our pipe we read the data from, which we actually tx. + // believe me, it does work. + fdin = fdout; + } + + if (do_crc_only) { + printf("File information for %s:\n", get_fixed_filename(filename, file_size, crc, 1)); + printf(" size %ld bytes, crc %d, date %s (%d)\n", file_size, crc, unix_to_sfbin_date_string(file_time), file_time); + return 0; + } + + send_on_signal = bin_send_abort_on_sig; + if (secure_write(fdout, buf, strlen(buf)) == -1) { + sprintf(err_msg, "error: write failed (%s)\n", strerror(errno)); + save_close(fddata); + return 1; + } + + // wait for answer + for (;;) { + // . make sure we do not read from a pipe. fdout is also + // | assigned to the tty + len = my_read(fdout, buf, sizeof(buf), &is_eof, "\r\n"); + if (is_eof || len < 1) { + sprintf(err_msg, "error: read failed (%s)\n", strerror(errno)); + save_close(fddata); + return 1; + } + if (buf[len-1] == '\n') { + //char *p = "warning: received. not 8bit clean?\r"; + //secure_write(fdout, p, strlen(p)); + sprintf(err_msg, "bad EOL: \n"); + goto abort; + } else if (buf[len-1] != '\r') { + sprintf(err_msg, "line to long\n"); + continue; + } + if (IS_BIN_OK(buf, len)) + break; + if (IS_BIN_NO(buf, len)) { + save_close(fddata); + return 0; + } + if (IS_BIN_ABORT(buf, len)) { + sprintf(err_msg, "Aborted by user request\n"); + save_close(fddata); + return 1; + } + } + + len_remains = file_size; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + for (;;) { + char *p_buf; + + // check for user \r#ABORT#\r on tty stream + FD_ZERO(&readfds); + FD_SET(fdin, &readfds); + if (select(fdin+1, &readfds, 0, 0, &timeout) && FD_ISSET(fdin, &readfds)) { + if ((len = read(fdin, buf, sizeof(buf))) < 0) { + sprintf(err_msg, "read from tty failed (%s)\n", strerror(errno)); + save_close(fddata); + goto abort; + } + if (IS_BIN_ABORT(buf, len)) { + sprintf(err_msg, "Aborted by user request\n"); + save_close(fddata); + return 1; + } + } + // read data + if (!fdin_is_pipe || is_stream) { + p_buf = buf; + if ((len = my_read(fddata, buf, ((len_remains > BLOCKSIZ || is_stream) ? BLOCKSIZ : len_remains), &is_eof, 0)) < 1) { + save_close(fddata); + if (len < 0) { + sprintf(err_msg, "error: read failed (%s)\n", strerror(errno)); + goto abort; + } + break; + } + len_remains -= len; + } else { + p_buf = stored_file->data; + len = stored_file->len; + } + // write to client + if (secure_write(fdout, p_buf, len) == -1) { + sprintf(err_msg, "error: write failed (%s)\n", strerror(errno)); + save_close(fddata); + goto abort; + } + if (fdin_is_pipe && !is_stream) { + sl = stored_file; + if (!(stored_file = stored_file->next)) + is_eof = 1; + free(sl); + } + if (!fdin_is_pipe && !len_remains) { + if (read(fddata, buf, 1) == 1) { + sprintf(err_msg, "Warning: file has grown in the meantime\n"); + } + is_eof = 1; + break; + } + // need this because my_read may returned lenth != 0 (data to be written) + // but also has detected EOF. + if (is_eof) + break; + } + + sleep(10); + + return 0; + +abort: + sleep(1); + write(fderr, "\r#ABORT#\r", 9); + return 1; +#undef save_close +} diff --git a/ax25/axgetput/proto_bin.h b/ax25/axgetput/proto_bin.h new file mode 100644 index 0000000..41c43e0 --- /dev/null +++ b/ax25/axgetput/proto_bin.h @@ -0,0 +1,34 @@ +/* @(#) $Id: proto_bin.h,v 1.1 2006/12/10 19:12:59 dl9sau Exp $ */ + +/* + * (c) 2002 Thomas Osterried DL9SAU + * License: GPL. See http://www.fsf.org/ + * Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + */ + +#ifndef PROTO_BIN_H +#define PROTO_BIN_H + +extern int bget(void); +extern int bput(void); + +static const char bin_s_on_ok[] = "#OK#\r"; +static const int bin_len_ok = sizeof(bin_s_on_ok)-1; +static const char bin_s_on_no[] = "#NO#\r"; +static const int bin_len_no = sizeof(bin_s_on_no)-1; +static const char bin_s_on_abort[] = "#ABORT#\r"; +static const int bin_len_abort = sizeof(bin_s_on_abort)-1; + +#define bin_send_no_on_sig "\r#NO#\r" +#define bin_send_abort_on_sig "\r#ABORT#\r" + +#define IS_BIN_NO(s, len) \ + len == bin_len_no && !memcmp(s, bin_s_on_no, bin_len_no) + +#define IS_BIN_OK(s, len) \ + len == bin_len_ok && !memcmp(s, bin_s_on_ok, bin_len_ok) + +#define IS_BIN_ABORT(s, len) \ + len == bin_len_abort && !memcmp(s, bin_s_on_abort, bin_len_abort) + +#endif /* PROTO_BIN_H */ diff --git a/ax25/axgetput/util.c b/ax25/axgetput/util.c new file mode 100644 index 0000000..160647f --- /dev/null +++ b/ax25/axgetput/util.c @@ -0,0 +1,208 @@ +/* @(#) $Id: util.c,v 1.1 2006/12/10 19:12:59 dl9sau Exp $ */ + +/* + * (c) 2002 Thomas Osterried DL9SAU + * License: GPL. See http://www.fsf.org/ + * Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + */ + +#include "includes.h" + +#include "axgetput.h" + +/* Use private function because some platforms are broken, eg 386BSD */ + +static int Xtolower(int c) +{ + return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; +} + +/*---------------------------------------------------------------------------*/ + +char *strlwc(char *s) +{ + char *p; + + for (p = s; (*p = Xtolower(*p)); p++) ; + return s; +} + +/*---------------------------------------------------------------------------*/ + +char *strtrim(char *s) +{ + char *p; + + for (p = s; *p; p++) ; + while (--p >= s && isspace(*p & 0xff)) ; + p[1] = 0; + return s; +} + +/*---------------------------------------------------------------------------*/ + +int my_read(int fd, char *s, int len_max, int *eof, char *p_break) +{ + + struct timeval timeout; + fd_set errfds; + int len_got; + + *eof = 0; + + for (len_got = 0; len_got < len_max; ) { + int len; + char *s_curr = s + len_got; + + if ((len = read(fd, s_curr, (p_break ? 1 : len_max))) < 1) { + if (len == -1 && errno == EAGAIN) { + sleep(10); + continue; + } + *eof = 1; + // len = 0: normal eof. if we're looking for a string, return -1 since + // we have'nt found + return (len == 0 && p_break ? -1 : (len_got ? len_got : len)); + } + len_got += len; + + // read once? or char in p_break found? + if (!p_break || strchr(p_break, *s_curr)) + break; + } + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&errfds); + FD_SET(fdout, &errfds); + if (select(fd+1, 0, 0, &errfds, &timeout) && FD_ISSET(fd, &errfds)) + *eof = 1; + + return len_got; +} + +/*---------------------------------------------------------------------------*/ + +int secure_write(int fd, char *s, int len_write) { + int len_write_left_curr = len_write; + + while (len_write_left_curr) { + int len; + if ((len = write(fd, s, len_write_left_curr)) < 0) { + if (len == -1 && errno == EAGAIN) { + sleep(10); + continue; + } + return -1; + } + if (len != len_write_left_curr) { + // queue busy.. + sleep(10); + } + s += len; + len_write_left_curr -= len; + } + return len_write; +} + +/*---------------------------------------------------------------------------*/ + +char *get_fixed_filename(char *line, long size, unsigned int msg_crc, int generate_filename) { + + static char filename[1024]; + char *p, *q, *r; + + *filename = 0; + + if ((p = strchr(line, '\"'))) { + p++; + } + + /* security.. */ + + if ((q = strrchr((p ? p : line), '/'))) { + p = ++q; + } + if ((q = strrchr((p ? p : line), '\\'))) { + p = ++q; + } + if ((q = strrchr((p ? p : line), ':'))) { + p = ++q; + } + if (!p) { + p = line; + } + while (*p && isspace(*p & 0xff)) + p++; + for (r = filename, q = p; *q; q++) { + if (*q == '"' || *q == ';') { + break; + } + *r++ = *q; + } + *r = 0; + strtrim(filename); + if ((q = strrchr(filename, '.'))) { + if (!*(q+1)) { + /* remove trailing dots */ + *q = 0; + } else { + /* make suffix lowercase */ + strlwc(q); + } + } + if (!*filename && generate_filename) { + sprintf(filename, "unknown-%ld%d%ld.bin", size, msg_crc, time(0)); + } + return filename; +} + +/*---------------------------------------------------------------------------*/ + +/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ + +/* Linear day numbers of the respective 1sts in non-leap years. */ +static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; + /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ + +/*---------------------------------------------------------------------------*/ + +long date_dos2unix(unsigned short time,unsigned short date) +{ + int month,year; + long secs; + + month = ((date >> 5) & 15)-1; + year = date >> 9; + secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* + ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && + month < 2 ? 1 : 0)+3653); + /* days since 1.1.70 plus 80's leap day */ + return secs; +} + +/*---------------------------------------------------------------------------*/ + +/* Convert linear UNIX date to a MS-DOS time/date pair. */ + +void date_unix2dos(int unix_date,unsigned short *time, unsigned short *date) +{ + int day,year,nl_day,month; + + *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+ + (((unix_date/3600) % 24) << 11); + day = unix_date/86400-3652; + year = day/365; + if ((year+3)/4+365*year > day) year--; + day -= (year+3)/4+365*year; + if (day == 59 && !(year & 3)) { + nl_day = day; + month = 2; + } + else { + nl_day = (year & 3) || day <= 59 ? day : day-1; + for (month = 0; month < 12; month++) + if (day_n[month] > nl_day) break; + } + *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9); +} + diff --git a/ax25/axgetput/util.h b/ax25/axgetput/util.h new file mode 100644 index 0000000..f6d115d --- /dev/null +++ b/ax25/axgetput/util.h @@ -0,0 +1,20 @@ +/* @(#) $Id: util.h,v 1.1 2006/12/10 19:12:59 dl9sau Exp $ */ + +/* + * (c) 2002 Thomas Osterried DL9SAU + * License: GPL. See http://www.fsf.org/ + * Sources: http://x-berg.in-berlin.de/cgi-bin/viewcvs.cgi/ampr/axgetput/ + */ + +#ifndef UTIL_H +#define UTIL_H + +extern char *strlwc(char *s); +extern char *strtrim(char *s); +extern int my_read(int fd, char *s, int len_max, int *eof, char *p_break); +extern int secure_write(int fd, char *s, int len_write_left); +extern char *get_fixed_filename(char *line, long size, unsigned int msg_crc, int generate_filename); +extern long date_dos2unix(unsigned short time,unsigned short date); +extern void date_unix2dos(int unix_date,unsigned short *time, unsigned short *date); + +#endif /* UTIL_H */ -- cgit v1.2.3