summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorHanhui <sylixos@gmail.com>2016-08-12 04:37:23 (GMT)
committer Hanhui <sylixos@gmail.com>2016-08-12 04:37:23 (GMT)
commite88de31a4741090b7fab9843dabe3d8be0d2a927 (patch)
tree98cdc5a4f5819688c6e939fd15faf7dffd85f184
downloadlibzmodem-e88de31a4741090b7fab9843dabe3d8be0d2a927.zip
libzmodem-e88de31a4741090b7fab9843dabe3d8be0d2a927.tar.gz
libzmodem-e88de31a4741090b7fab9843dabe3d8be0d2a927.tar.bz2
libzmodem first push.
-rw-r--r--.cproject61
-rw-r--r--.project32
-rw-r--r--.rcsetting31
-rw-r--r--.template/Makefile.arch4
-rw-r--r--.template/config.mk41
-rw-r--r--Makefile4
-rw-r--r--Makefile.arm240
-rw-r--r--Makefile.mips240
-rw-r--r--Makefile.ppc240
-rw-r--r--Makefile.x860
-rw-r--r--config.mk41
-rw-r--r--zmodem/crc.c179
-rw-r--r--zmodem/crctab.c140
-rw-r--r--zmodem/minirb.c85
-rw-r--r--zmodem/rbsb.c549
-rw-r--r--zmodem/rz.c1367
-rw-r--r--zmodem/sz.c1705
-rw-r--r--zmodem/undos.c320
-rw-r--r--zmodem/zm.c878
-rw-r--r--zmodem/zmodem.h142
-rw-r--r--zmodem/zmr.c188
21 files changed, 6487 insertions, 0 deletions
diff --git a/.cproject b/.cproject
new file mode 100644
index 0000000..dfeb849
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+ <storageModule moduleId="org.eclipse.cdt.core.settings">
+ <cconfiguration id="com.sylixos.realevo.toolChain.armsylixeabi.983217589">
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.sylixos.realevo.toolChain.armsylixeabi.983217589" moduleId="org.eclipse.cdt.core.settings" name="Default">
+ <macros>
+ <stringMacro name="SYLIXOS_TOOLCHAIN_PATH" type="VALUE_PATH_DIR" value="F:\ACOINFO\arm-sylixos-toolchain"/>
+ <stringMacro name="SYLIXOS_TEMPLATE_ARCH" type="VALUE_TEXT"/>
+ <stringMacro name="SYLIXOS_TOOLCHAIN_VER" type="VALUE_TEXT" value="4.9.3"/>
+ <stringMacro name="SYLIXOS_TOOLCHAIN_PREFIX" type="VALUE_TEXT" value="arm-sylixos-eabi"/>
+ <stringMacro name="SYLIXOS_BASE_PATH" type="VALUE_PATH_DIR" value=".."/>
+ <stringMacro name="SYLIXOS_TEMPLATE_NAME" type="VALUE_TEXT"/>
+ </macros>
+ <externalSettings/>
+ <extensions>
+ <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ </extensions>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <configuration artifactName="${ProjName}" buildProperties="" description="" id="com.sylixos.realevo.toolChain.armsylixeabi.983217589" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+ <folderInfo id="com.sylixos.realevo.toolChain.armsylixeabi.983217589.899279545" name="/" resourcePath="">
+ <toolChain id="com.sylixos.realevo.toolChain.armsylixeabi.84584337" name="SylixOS Toolchain" superClass="com.sylixos.realevo.toolChain.armsylixeabi">
+ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="com.sylixos.realevo.targetPlatform.armsylixoseabi.1995062193" isAbstract="false" name="SylixOS TagetPlagform" osList="all" superClass="com.sylixos.realevo.targetPlatform.armsylixoseabi"/>
+ <builder id="com.sylixos.realevo.builder.armsylixeabi.1279403652" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="SylixOS Builder" superClass="com.sylixos.realevo.builder.armsylixeabi"/>
+ <tool id="com.sylixos.realevo.tool.armsylixeabi.2031220439" name="arm-sylixos-eabi-gcc" superClass="com.sylixos.realevo.tool.armsylixeabi">
+ <option id="com.sylixos.realevo.option.armsylixoseabi.include.163300813" superClass="com.sylixos.realevo.option.armsylixoseabi.include" valueType="includePath">
+ <listOptionValue builtIn="false" value="&quot;${SYLIXOS_BASE_PATH}/libsylixos/SylixOS&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${SYLIXOS_BASE_PATH}/libsylixos/SylixOS/include&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${SYLIXOS_BASE_PATH}/libsylixos/SylixOS/include/inet&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${SYLIXOS_TOOLCHAIN_PATH}/${SYLIXOS_TOOLCHAIN_PREFIX}/include&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${SYLIXOS_TOOLCHAIN_PATH}/lib/gcc/${SYLIXOS_TOOLCHAIN_PREFIX}/${SYLIXOS_TOOLCHAIN_VER}/include&quot;"/>
+ </option>
+ <option id="com.sylixos.realevo.option.armsylixoseabi.DefinedSymbols.686716040" superClass="com.sylixos.realevo.option.armsylixoseabi.DefinedSymbols" valueType="definedSymbols">
+ <listOptionValue builtIn="false" value="__GNUC__=4"/>
+ <listOptionValue builtIn="false" value="SYLIXOS"/>
+ </option>
+ <inputType id="com.sylixos.realevo.inputType.armnsylixeabic.1885382236" name="SylixOS Input C" superClass="com.sylixos.realevo.inputType.armnsylixeabic"/>
+ <inputType id="com.sylixos.realevo.inputType.armnsylixeabicpp.1210667503" name="SylixOS Input CPP" superClass="com.sylixos.realevo.inputType.armnsylixeabicpp"/>
+ </tool>
+ </toolChain>
+ </folderInfo>
+ </configuration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ </cconfiguration>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <project id="libzmodem.null.1019176072" name="libzmodem"/>
+ </storageModule>
+ <storageModule moduleId="scannerConfiguration">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+</cproject>
diff --git a/.project b/.project
new file mode 100644
index 0000000..d5488be
--- /dev/null
+++ b/.project
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>libzmodem</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.sylixos.realevo.SylixOSBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ <nature>com.sylixos.realevo.SylixOSProject</nature>
+ </natures>
+</projectDescription>
diff --git a/.rcsetting b/.rcsetting
new file mode 100644
index 0000000..0fe93af
--- /dev/null
+++ b/.rcsetting
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="GB2312" standalone="no"?>
+<SylixOSSetting>
+<UploadSetting HostName="" Password="root" UserName="root"/>
+<BaseSetting ProjectType="StaticLibProject"/>
+<BuildConfigration>
+<BuildCfgPair Macro="SylixOS_Debug_Level" Value="debug"/>
+<BuildCfgPair Macro="SylixOS_Create_Date" Value="2016-05-27"/>
+<BuildCfgPair Macro="SylixOS_Base_Path" Value="E:/SylixOS/gcc/v2.1/cortex-a9"/>
+<BuildCfgPair Macro="SylixOS_Fpu_Type" Value=""/>
+<BuildCfgPair Macro="SylixOS_Toolchain_Ver" Value="4.9.3"/>
+<BuildCfgPair Macro="SylixOS_Toolchain" Value="arm-sylixos-eabi"/>
+<BuildCfgPair Macro="projectType" Value="org.eclipse.cdt.build.makefile.projectType.SylixOS"/>
+<BuildCfgPair Macro="SylixOS_Target_Name" Value="libzmodem"/>
+<BuildCfgPair Macro="SylixOS_Arch" Value="arm"/>
+<BuildCfgPair Macro="SylixOS_Src_Path" Value="F:/ACOINFO/RealEvo-IDE/SylixOS"/>
+<BuildCfgPair Macro="SylixOS_Toolchain_Path" Value="F:\ACOINFO\arm-sylixos-toolchain"/>
+<BuildCfgPair Macro="baseNameLower" Value="libzmodem"/>
+<BuildCfgPair Macro="SylixOS_Cpu_Type" Value="-mcpu=arm920t"/>
+<BuildCfgPair Macro="location" Value="E:\SylixOS\gcc\v2.1"/>
+<BuildCfgPair Macro="SylixOS_Create_User" Value="Administrator"/>
+<BuildCfgPair Macro="baseNameUpper" Value="LIBZMODEM"/>
+<BuildCfgPair Macro="projectName" Value="libzmodem"/>
+<BuildCfgPair Macro="baseName" Value="libzmodem"/>
+<BuildCfgPair Macro="Create_Date" Value="2016 年05 月27 日"/>
+</BuildConfigration>
+<OutputSetting>
+<OutputPath Name="Output" Path="Release:Debug" TreeNode="Output"/>
+<OutputPath Name="Debug" Path="Debug" TreeNode="Debug"/>
+<OutputPath Name="Release" Path="Release" TreeNode="Release"/>
+</OutputSetting>
+</SylixOSSetting>
diff --git a/.template/Makefile.arch b/.template/Makefile.arch
new file mode 100644
index 0000000..3e593bd
--- /dev/null
+++ b/.template/Makefile.arch
@@ -0,0 +1,4 @@
+#*********************************************************************************************************
+# include architecture related Makefile
+#*********************************************************************************************************
+include Makefile.$(SylixOS_Arch)
diff --git a/.template/config.mk b/.template/config.mk
new file mode 100644
index 0000000..ebc46ca
--- /dev/null
+++ b/.template/config.mk
@@ -0,0 +1,41 @@
+#*********************************************************************************************************
+#
+# 中国软件开源组织
+#
+# 嵌入式实时操作系统
+#
+# SylixOS(TM) LW : long wing
+#
+# Copyright All Rights Reserved
+#
+#--------------文件信息--------------------------------------------------------------------------------
+#
+# 文 件 名: config.mk
+#
+# 创 建 人: RealEvo-IDE
+#
+# 文件创建日期: $(Create_Date)
+#
+# 描 述: 本文件由 RealEvo-IDE 生成,用于配置 Makefile 功能,请勿手动修改
+#*********************************************************************************************************
+#*********************************************************************************************************
+# SylixOS Base Project path
+#*********************************************************************************************************
+SYLIXOS_BASE_PATH = $(SylixOS_Base_Path)
+
+#*********************************************************************************************************
+# Toolchain prefix
+#*********************************************************************************************************
+TOOLCHAIN_PREFIX = $(SylixOS_Toolchain)-
+
+#*********************************************************************************************************
+# Debug options (debug or release)
+#*********************************************************************************************************
+DEBUG_LEVEL = $(SylixOS_Debug_Level)
+
+#*********************************************************************************************************
+# NOTICE: libsylixos, BSP and other kernel modules projects CAN NOT use vfp!
+#*********************************************************************************************************
+FPUFLAGS = $(SylixOS_Fpu_Type)
+CPUFLAGS = $(SylixOS_Cpu_Type) $(FPUFLAGS)
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4fdfaf0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,4 @@
+#*********************************************************************************************************
+# include architecture related Makefile
+#*********************************************************************************************************
+include Makefile.arm
diff --git a/Makefile.arm b/Makefile.arm
new file mode 100644
index 0000000..79aa09f
--- /dev/null
+++ b/Makefile.arm
@@ -0,0 +1,240 @@
+#*********************************************************************************************************
+# libzmodem Makefile
+# target -> rz sz
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# include config.mk
+#*********************************************************************************************************
+CONFIG_MK_EXIST = $(shell if [ -f ../config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include ../config.mk
+else
+CONFIG_MK_EXIST = $(shell if [ -f config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include config.mk
+else
+CONFIG_MK_EXIST =
+endif
+endif
+
+#*********************************************************************************************************
+# check configure
+#*********************************************************************************************************
+check_defined = \
+ $(foreach 1,$1,$(__check_defined))
+__check_defined = \
+ $(if $(value $1),, \
+ $(error Undefined $1$(if $(value 2), ($(strip $2)))))
+
+$(call check_defined, CONFIG_MK_EXIST, Please configure this project in RealEvo-IDE or \
+create a config.mk file!)
+$(call check_defined, SYLIXOS_BASE_PATH, SylixOS base project path)
+$(call check_defined, TOOLCHAIN_PREFIX, the prefix name of toolchain)
+$(call check_defined, DEBUG_LEVEL, debug level(debug or release))
+
+#*********************************************************************************************************
+# toolchain select
+#*********************************************************************************************************
+CC = $(TOOLCHAIN_PREFIX)gcc
+CXX = $(TOOLCHAIN_PREFIX)g++
+AS = $(TOOLCHAIN_PREFIX)gcc
+AR = $(TOOLCHAIN_PREFIX)ar
+LD = $(TOOLCHAIN_PREFIX)g++
+STRIP = $(TOOLCHAIN_PREFIX)strip
+
+#*********************************************************************************************************
+# do not change the following code
+# buildin internal application source
+#*********************************************************************************************************
+#*********************************************************************************************************
+# src(s) file
+#*********************************************************************************************************
+RZ_SRCS = \
+zmodem/rz.c
+
+SZ_SRCS = \
+zmodem/sz.c
+
+#*********************************************************************************************************
+# build path
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OUTDIR = Debug
+else
+OUTDIR = Release
+endif
+
+OUTPATH = ./$(OUTDIR)
+OBJPATH = $(OUTPATH)/obj
+DEPPATH = $(OUTPATH)/dep
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+RZ = $(OUTPATH)/rz
+STRIP_RZ = $(OUTPATH)/strip/rz
+SZ = $(OUTPATH)/sz
+STRIP_SZ = $(OUTPATH)/strip/sz
+
+#*********************************************************************************************************
+# objects
+#*********************************************************************************************************
+RZ_OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(RZ_SRCS))))
+RZ_DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(RZ_SRCS))))
+
+SZ_OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(SZ_SRCS))))
+SZ_DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(SZ_SRCS))))
+
+#*********************************************************************************************************
+# include path
+#*********************************************************************************************************
+INCDIR = -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include/inet"
+
+#*********************************************************************************************************
+# compiler preprocess
+#*********************************************************************************************************
+DSYMBOL = -DSYLIXOS
+DSYMBOL += -DSYLIXOS_LIB
+DSYMBOL += -DPOSIX
+DSYMBOL += -DREGISTERED
+
+#*********************************************************************************************************
+# compiler optimize
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OPTIMIZE = -O0 -g3 -gdwarf-2
+else
+OPTIMIZE = -O2 -g1 -gdwarf-2 # Do NOT use -O3 and -Os
+endif # -Os is not align for function
+ # loop and jump.
+#*********************************************************************************************************
+# depends and compiler parameter (cplusplus in kernel MUST NOT use exceptions and rtti)
+#*********************************************************************************************************
+DEPENDFLAG = -MM
+CXX_EXCEPT = -fno-exceptions -fno-rtti
+COMMONFLAGS = $(CPUFLAGS) $(OPTIMIZE) -Wall -fmessage-length=0 -fsigned-char -fno-short-enums -mno-unaligned-access
+ASFLAGS = -x assembler-with-cpp $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -c
+CFLAGS = $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -fPIC -c
+CXXFLAGS = $(DSYMBOL) $(INCDIR) $(CXX_EXCEPT) $(COMMONFLAGS) -fPIC -c
+ARFLAGS = -r
+
+#*********************************************************************************************************
+# define some useful variable
+#*********************************************************************************************************
+DEPEND = $(CC) $(DEPENDFLAG) $(CFLAGS)
+DEPEND.d = $(subst -g ,,$(DEPEND))
+COMPILE.S = $(AS) $(ASFLAGS)
+COMPILE_VFP.S = $(AS) $(ASFLAGS)
+COMPILE.c = $(CC) $(CFLAGS)
+COMPILE.cxx = $(CXX) $(CXXFLAGS)
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+all: $(RZ) $(STRIP_RZ) $(SZ) $(STRIP_SZ)
+ @echo create "$(RZ) $(SZ)" success.
+
+#*********************************************************************************************************
+# include depends
+#*********************************************************************************************************
+ifneq ($(MAKECMDGOALS), clean)
+ifneq ($(MAKECMDGOALS), clean_project)
+sinclude $(RZ_DEPS) $(SZ_DEPS)
+endif
+endif
+
+#*********************************************************************************************************
+# create depends files
+#*********************************************************************************************************
+$(DEPPATH)/%.d: %.c
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+$(DEPPATH)/%.d: %.cpp
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+#*********************************************************************************************************
+# compile source files
+#*********************************************************************************************************
+$(OBJPATH)/%.o: %.S
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.S) $< -o $@
+
+$(OBJPATH)/%.o: %.c
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.c) $< -o $@
+
+$(OBJPATH)/%.o: %.cpp
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.cxx) $< -o $@
+
+#*********************************************************************************************************
+# link rz object files
+#*********************************************************************************************************
+$(RZ): $(RZ_OBJS)
+ $(LD) $(CPUFLAGS) -nostdlib -fPIC -shared -o $(RZ) $(RZ_OBJS) \
+ -L"./Debug" -L"./Release" -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)" $(DEPEND_DLL_PATH) $(DEPEND_DLL) \
+ -lvpmpdm -lm -lgcc
+
+#*********************************************************************************************************
+# strip rz
+#*********************************************************************************************************
+$(STRIP_RZ): $(RZ)
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@
+ $(STRIP) $(RZ) -o $(STRIP_RZ)
+
+#*********************************************************************************************************
+# link sz object files
+#*********************************************************************************************************
+$(SZ): $(SZ_OBJS)
+ $(LD) $(CPUFLAGS) -nostdlib -fPIC -shared -o $(SZ) $(SZ_OBJS) \
+ -L"./Debug" -L"./Release" -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)" $(DEPEND_DLL_PATH) $(DEPEND_DLL) \
+ -lvpmpdm -lm -lgcc
+
+#*********************************************************************************************************
+# strip sz
+#*********************************************************************************************************
+$(STRIP_SZ): $(SZ)
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@
+ $(STRIP) $(SZ) -o $(STRIP_SZ)
+
+#*********************************************************************************************************
+# clean
+#*********************************************************************************************************
+.PHONY: clean
+.PHONY: clean_project
+
+#*********************************************************************************************************
+# clean objects
+#*********************************************************************************************************
+clean:
+ -rm -rf $(RZ)
+ -rm -rf $(STRIP_RZ)
+ -rm -rf $(SZ)
+ -rm -rf $(STRIP_SZ)
+ -rm -rf $(RZ_OBJS)
+ -rm -rf $(SZ_OBJS)
+ -rm -rf $(OBJPATH)
+ -rm -rf $(DEPPATH)
+
+#*********************************************************************************************************
+# clean project
+#*********************************************************************************************************
+clean_project:
+ -rm -rf $(OUTPATH)
+
+#*********************************************************************************************************
+# END
+#*********************************************************************************************************
diff --git a/Makefile.mips b/Makefile.mips
new file mode 100644
index 0000000..67c1cfc
--- /dev/null
+++ b/Makefile.mips
@@ -0,0 +1,240 @@
+#*********************************************************************************************************
+# libzmodem Makefile
+# target -> rz sz
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# include config.mk
+#*********************************************************************************************************
+CONFIG_MK_EXIST = $(shell if [ -f ../config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include ../config.mk
+else
+CONFIG_MK_EXIST = $(shell if [ -f config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include config.mk
+else
+CONFIG_MK_EXIST =
+endif
+endif
+
+#*********************************************************************************************************
+# check configure
+#*********************************************************************************************************
+check_defined = \
+ $(foreach 1,$1,$(__check_defined))
+__check_defined = \
+ $(if $(value $1),, \
+ $(error Undefined $1$(if $(value 2), ($(strip $2)))))
+
+$(call check_defined, CONFIG_MK_EXIST, Please configure this project in RealEvo-IDE or \
+create a config.mk file!)
+$(call check_defined, SYLIXOS_BASE_PATH, SylixOS base project path)
+$(call check_defined, TOOLCHAIN_PREFIX, the prefix name of toolchain)
+$(call check_defined, DEBUG_LEVEL, debug level(debug or release))
+
+#*********************************************************************************************************
+# toolchain select
+#*********************************************************************************************************
+CC = $(TOOLCHAIN_PREFIX)gcc
+CXX = $(TOOLCHAIN_PREFIX)g++
+AS = $(TOOLCHAIN_PREFIX)gcc
+AR = $(TOOLCHAIN_PREFIX)ar
+LD = $(TOOLCHAIN_PREFIX)g++
+STRIP = $(TOOLCHAIN_PREFIX)strip
+
+#*********************************************************************************************************
+# do not change the following code
+# buildin internal application source
+#*********************************************************************************************************
+#*********************************************************************************************************
+# src(s) file
+#*********************************************************************************************************
+RZ_SRCS = \
+zmodem/rz.c
+
+SZ_SRCS = \
+zmodem/sz.c
+
+#*********************************************************************************************************
+# build path
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OUTDIR = Debug
+else
+OUTDIR = Release
+endif
+
+OUTPATH = ./$(OUTDIR)
+OBJPATH = $(OUTPATH)/obj
+DEPPATH = $(OUTPATH)/dep
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+RZ = $(OUTPATH)/rz
+STRIP_RZ = $(OUTPATH)/strip/rz
+SZ = $(OUTPATH)/sz
+STRIP_SZ = $(OUTPATH)/strip/sz
+
+#*********************************************************************************************************
+# objects
+#*********************************************************************************************************
+RZ_OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(RZ_SRCS))))
+RZ_DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(RZ_SRCS))))
+
+SZ_OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(SZ_SRCS))))
+SZ_DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(SZ_SRCS))))
+
+#*********************************************************************************************************
+# include path
+#*********************************************************************************************************
+INCDIR = -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include/inet"
+
+#*********************************************************************************************************
+# compiler preprocess
+#*********************************************************************************************************
+DSYMBOL = -DSYLIXOS
+DSYMBOL += -DSYLIXOS_LIB
+DSYMBOL += -DPOSIX
+DSYMBOL += -DREGISTERED
+
+#*********************************************************************************************************
+# compiler optimize
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OPTIMIZE = -O0 -g3 -gdwarf-2
+else
+OPTIMIZE = -O2 -g1 -gdwarf-2 # Do NOT use -O3 and -Os
+endif # -Os is not align for function
+ # loop and jump.
+#*********************************************************************************************************
+# depends and compiler parameter (cplusplus in kernel MUST NOT use exceptions and rtti)
+#*********************************************************************************************************
+DEPENDFLAG = -MM
+CXX_EXCEPT = -fno-exceptions -fno-rtti
+COMMONFLAGS = $(CPUFLAGS) $(OPTIMIZE) -Wall -fmessage-length=0 -fsigned-char -fno-short-enums
+ASFLAGS = -x assembler-with-cpp $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -mabicalls -c
+CFLAGS = $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -fPIC -mabicalls -c
+CXXFLAGS = $(DSYMBOL) $(INCDIR) $(CXX_EXCEPT) $(COMMONFLAGS) -fPIC -mabicalls -c
+ARFLAGS = -r
+
+#*********************************************************************************************************
+# define some useful variable
+#*********************************************************************************************************
+DEPEND = $(CC) $(DEPENDFLAG) $(CFLAGS)
+DEPEND.d = $(subst -g ,,$(DEPEND))
+COMPILE.S = $(AS) $(ASFLAGS)
+COMPILE_VFP.S = $(AS) $(ASFLAGS) -mhard-float
+COMPILE.c = $(CC) $(CFLAGS)
+COMPILE.cxx = $(CXX) $(CXXFLAGS)
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+all: $(RZ) $(STRIP_RZ) $(SZ) $(STRIP_SZ)
+ @echo create "$(RZ) $(SZ)" success.
+
+#*********************************************************************************************************
+# include depends
+#*********************************************************************************************************
+ifneq ($(MAKECMDGOALS), clean)
+ifneq ($(MAKECMDGOALS), clean_project)
+sinclude $(RZ_DEPS) $(SZ_DEPS)
+endif
+endif
+
+#*********************************************************************************************************
+# create depends files
+#*********************************************************************************************************
+$(DEPPATH)/%.d: %.c
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+$(DEPPATH)/%.d: %.cpp
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+#*********************************************************************************************************
+# compile source files
+#*********************************************************************************************************
+$(OBJPATH)/%.o: %.S
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.S) $< -o $@
+
+$(OBJPATH)/%.o: %.c
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.c) $< -o $@
+
+$(OBJPATH)/%.o: %.cpp
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.cxx) $< -o $@
+
+#*********************************************************************************************************
+# link rz object files
+#*********************************************************************************************************
+$(RZ): $(RZ_OBJS)
+ $(LD) $(CPUFLAGS) -fPIC -mabicalls -shared -o $(RZ) $(RZ_OBJS) \
+ -L"./Debug" -L"./Release" -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)" $(DEPEND_DLL_PATH) $(DEPEND_DLL) \
+ -lvpmpdm -lm -lgcc
+
+#*********************************************************************************************************
+# strip rz
+#*********************************************************************************************************
+$(STRIP_RZ): $(RZ)
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@
+ $(STRIP) $(RZ) -o $(STRIP_RZ)
+
+#*********************************************************************************************************
+# link sz object files
+#*********************************************************************************************************
+$(SZ): $(SZ_OBJS)
+ $(LD) $(CPUFLAGS) -fPIC -mabicalls -shared -o $(SZ) $(SZ_OBJS) \
+ -L"./Debug" -L"./Release" -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)" $(DEPEND_DLL_PATH) $(DEPEND_DLL) \
+ -lvpmpdm -lm -lgcc
+
+#*********************************************************************************************************
+# strip sz
+#*********************************************************************************************************
+$(STRIP_SZ): $(SZ)
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@
+ $(STRIP) $(SZ) -o $(STRIP_SZ)
+
+#*********************************************************************************************************
+# clean
+#*********************************************************************************************************
+.PHONY: clean
+.PHONY: clean_project
+
+#*********************************************************************************************************
+# clean objects
+#*********************************************************************************************************
+clean:
+ -rm -rf $(RZ)
+ -rm -rf $(STRIP_RZ)
+ -rm -rf $(SZ)
+ -rm -rf $(STRIP_SZ)
+ -rm -rf $(RZ_OBJS)
+ -rm -rf $(SZ_OBJS)
+ -rm -rf $(OBJPATH)
+ -rm -rf $(DEPPATH)
+
+#*********************************************************************************************************
+# clean project
+#*********************************************************************************************************
+clean_project:
+ -rm -rf $(OUTPATH)
+
+#*********************************************************************************************************
+# END
+#*********************************************************************************************************
diff --git a/Makefile.ppc b/Makefile.ppc
new file mode 100644
index 0000000..b1e22cf
--- /dev/null
+++ b/Makefile.ppc
@@ -0,0 +1,240 @@
+#*********************************************************************************************************
+# libzmodem Makefile
+# target -> rz sz
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# include config.mk
+#*********************************************************************************************************
+CONFIG_MK_EXIST = $(shell if [ -f ../config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include ../config.mk
+else
+CONFIG_MK_EXIST = $(shell if [ -f config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include config.mk
+else
+CONFIG_MK_EXIST =
+endif
+endif
+
+#*********************************************************************************************************
+# check configure
+#*********************************************************************************************************
+check_defined = \
+ $(foreach 1,$1,$(__check_defined))
+__check_defined = \
+ $(if $(value $1),, \
+ $(error Undefined $1$(if $(value 2), ($(strip $2)))))
+
+$(call check_defined, CONFIG_MK_EXIST, Please configure this project in RealEvo-IDE or \
+create a config.mk file!)
+$(call check_defined, SYLIXOS_BASE_PATH, SylixOS base project path)
+$(call check_defined, TOOLCHAIN_PREFIX, the prefix name of toolchain)
+$(call check_defined, DEBUG_LEVEL, debug level(debug or release))
+
+#*********************************************************************************************************
+# toolchain select
+#*********************************************************************************************************
+CC = $(TOOLCHAIN_PREFIX)gcc
+CXX = $(TOOLCHAIN_PREFIX)g++
+AS = $(TOOLCHAIN_PREFIX)gcc
+AR = $(TOOLCHAIN_PREFIX)ar
+LD = $(TOOLCHAIN_PREFIX)g++
+STRIP = $(TOOLCHAIN_PREFIX)strip
+
+#*********************************************************************************************************
+# do not change the following code
+# buildin internal application source
+#*********************************************************************************************************
+#*********************************************************************************************************
+# src(s) file
+#*********************************************************************************************************
+RZ_SRCS = \
+zmodem/rz.c
+
+SZ_SRCS = \
+zmodem/sz.c
+
+#*********************************************************************************************************
+# build path
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OUTDIR = Debug
+else
+OUTDIR = Release
+endif
+
+OUTPATH = ./$(OUTDIR)
+OBJPATH = $(OUTPATH)/obj
+DEPPATH = $(OUTPATH)/dep
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+RZ = $(OUTPATH)/rz
+STRIP_RZ = $(OUTPATH)/strip/rz
+SZ = $(OUTPATH)/sz
+STRIP_SZ = $(OUTPATH)/strip/sz
+
+#*********************************************************************************************************
+# objects
+#*********************************************************************************************************
+RZ_OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(RZ_SRCS))))
+RZ_DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(RZ_SRCS))))
+
+SZ_OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(SZ_SRCS))))
+SZ_DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(SZ_SRCS))))
+
+#*********************************************************************************************************
+# include path
+#*********************************************************************************************************
+INCDIR = -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include/inet"
+
+#*********************************************************************************************************
+# compiler preprocess
+#*********************************************************************************************************
+DSYMBOL = -DSYLIXOS
+DSYMBOL += -DSYLIXOS_LIB
+DSYMBOL += -DPOSIX
+DSYMBOL += -DREGISTERED
+
+#*********************************************************************************************************
+# compiler optimize
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OPTIMIZE = -O0 -g3 -gdwarf-2
+else
+OPTIMIZE = -O2 -g1 -gdwarf-2 # Do NOT use -O3 and -Os
+endif # -Os is not align for function
+ # loop and jump.
+#*********************************************************************************************************
+# depends and compiler parameter (cplusplus in kernel MUST NOT use exceptions and rtti)
+#*********************************************************************************************************
+DEPENDFLAG = -MM
+CXX_EXCEPT = -fno-exceptions -fno-rtti
+COMMONFLAGS = $(CPUFLAGS) $(OPTIMIZE) -Wall -fmessage-length=0 -fsigned-char -fno-short-enums
+ASFLAGS = -x assembler-with-cpp $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -c
+CFLAGS = $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -fPIC -c
+CXXFLAGS = $(DSYMBOL) $(INCDIR) $(CXX_EXCEPT) $(COMMONFLAGS) -fPIC -c
+ARFLAGS = -r
+
+#*********************************************************************************************************
+# define some useful variable
+#*********************************************************************************************************
+DEPEND = $(CC) $(DEPENDFLAG) $(CFLAGS)
+DEPEND.d = $(subst -g ,,$(DEPEND))
+COMPILE.S = $(AS) $(ASFLAGS)
+COMPILE_VFP.S = $(AS) $(ASFLAGS)
+COMPILE.c = $(CC) $(CFLAGS)
+COMPILE.cxx = $(CXX) $(CXXFLAGS)
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+all: $(RZ) $(STRIP_RZ) $(SZ) $(STRIP_SZ)
+ @echo create "$(RZ) $(SZ)" success.
+
+#*********************************************************************************************************
+# include depends
+#*********************************************************************************************************
+ifneq ($(MAKECMDGOALS), clean)
+ifneq ($(MAKECMDGOALS), clean_project)
+sinclude $(RZ_DEPS) $(SZ_DEPS)
+endif
+endif
+
+#*********************************************************************************************************
+# create depends files
+#*********************************************************************************************************
+$(DEPPATH)/%.d: %.c
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+$(DEPPATH)/%.d: %.cpp
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+#*********************************************************************************************************
+# compile source files
+#*********************************************************************************************************
+$(OBJPATH)/%.o: %.S
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.S) $< -o $@
+
+$(OBJPATH)/%.o: %.c
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.c) $< -o $@
+
+$(OBJPATH)/%.o: %.cpp
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.cxx) $< -o $@
+
+#*********************************************************************************************************
+# link rz object files
+#*********************************************************************************************************
+$(RZ): $(RZ_OBJS)
+ $(LD) $(CPUFLAGS) -fPIC -shared -o $(RZ) $(RZ_OBJS) \
+ -L"./Debug" -L"./Release" -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)" $(DEPEND_DLL_PATH) $(DEPEND_DLL) \
+ -lvpmpdm -lm -lgcc
+
+#*********************************************************************************************************
+# strip rz
+#*********************************************************************************************************
+$(STRIP_RZ): $(RZ)
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@
+ $(STRIP) $(RZ) -o $(STRIP_RZ)
+
+#*********************************************************************************************************
+# link sz object files
+#*********************************************************************************************************
+$(SZ): $(SZ_OBJS)
+ $(LD) $(CPUFLAGS) -fPIC -shared -o $(SZ) $(SZ_OBJS) \
+ -L"./Debug" -L"./Release" -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)" $(DEPEND_DLL_PATH) $(DEPEND_DLL) \
+ -lvpmpdm -lm -lgcc
+
+#*********************************************************************************************************
+# strip sz
+#*********************************************************************************************************
+$(STRIP_SZ): $(SZ)
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@
+ $(STRIP) $(SZ) -o $(STRIP_SZ)
+
+#*********************************************************************************************************
+# clean
+#*********************************************************************************************************
+.PHONY: clean
+.PHONY: clean_project
+
+#*********************************************************************************************************
+# clean objects
+#*********************************************************************************************************
+clean:
+ -rm -rf $(RZ)
+ -rm -rf $(STRIP_RZ)
+ -rm -rf $(SZ)
+ -rm -rf $(STRIP_SZ)
+ -rm -rf $(RZ_OBJS)
+ -rm -rf $(SZ_OBJS)
+ -rm -rf $(OBJPATH)
+ -rm -rf $(DEPPATH)
+
+#*********************************************************************************************************
+# clean project
+#*********************************************************************************************************
+clean_project:
+ -rm -rf $(OUTPATH)
+
+#*********************************************************************************************************
+# END
+#*********************************************************************************************************
diff --git a/Makefile.x86 b/Makefile.x86
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Makefile.x86
diff --git a/config.mk b/config.mk
new file mode 100644
index 0000000..92e63c0
--- /dev/null
+++ b/config.mk
@@ -0,0 +1,41 @@
+#*********************************************************************************************************
+#
+# 中国软件开源组织
+#
+# 嵌入式实时操作系统
+#
+# SylixOS(TM) LW : long wing
+#
+# Copyright All Rights Reserved
+#
+#--------------文件信息--------------------------------------------------------------------------------
+#
+# 文 件 名: config.mk
+#
+# 创 建 人: RealEvo-IDE
+#
+# 文件创建日期: 2016 年05 月27 日
+#
+# 描 述: 本文件由 RealEvo-IDE 生成,用于配置 Makefile 功能,请勿手动修改
+#*********************************************************************************************************
+#*********************************************************************************************************
+# SylixOS Base Project path
+#*********************************************************************************************************
+SYLIXOS_BASE_PATH = ..
+
+#*********************************************************************************************************
+# Toolchain prefix
+#*********************************************************************************************************
+TOOLCHAIN_PREFIX = arm-sylixos-eabi-
+
+#*********************************************************************************************************
+# Debug options (debug or release)
+#*********************************************************************************************************
+DEBUG_LEVEL = debug
+
+#*********************************************************************************************************
+# NOTICE: libsylixos, BSP and other kernel modules projects CAN NOT use vfp!
+#*********************************************************************************************************
+FPUFLAGS =
+CPUFLAGS = -mcpu=arm920t $(FPUFLAGS)
+
diff --git a/zmodem/crc.c b/zmodem/crc.c
new file mode 100644
index 0000000..f5ce8c8
--- /dev/null
+++ b/zmodem/crc.c
@@ -0,0 +1,179 @@
+/*% cc -O -K -dos % -o crc.exe
+*/
+
+/*
+ * Crc - 32 BIT ANSI X3.66 CRC checksum files
+ */
+#include <stdio.h>
+#define OK 0
+#define ERROR (-1)
+#define LINT_ARGS
+
+/**********************************************************************\
+|* *|
+|* Demonstration program to compute the 32-bit CRC used as the frame *|
+|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
+|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
+|* protocol). The 32-bit FCS was added via the Federal Register, *|
+|* 1 June 1982, p.23798. I presume but don't know for certain that *|
+|* this polynomial is or will be included in CCITT V.41, which *|
+|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
+|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
+|* errors by a factor of 10^-5 over 16-bit FCS. *|
+|* *|
+\**********************************************************************/
+
+/* Need an unsigned type capable of holding 32 bits; */
+typedef unsigned long int UNS_32_BITS;
+
+/*
+ * Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+/* First, the polynomial itself and its table of feedback terms. The */
+/* polynomial is */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in */
+/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+/* the MSB being 1. */
+
+/* Note that the usual hardware shift register implementation, which */
+/* is what we're using (we're merely optimizing it by doing eight-bit */
+/* chunks at a time) shifts bits into the lowest-order term. In our */
+/* implementation, that means shifting towards the right. Why do we */
+/* do it this way? Because the calculated CRC must be transmitted in */
+/* order from highest-order term to lowest-order term. UARTs transmit */
+/* characters in order from LSB to MSB. By storing the CRC this way, */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part. Reception works similarly. */
+
+/* The feedback terms table consists of 256, 32-bit entries. Notes: */
+/* */
+/* 1. The table can be generated at runtime if desired; code to do so */
+/* is shown later. It might not be obvious, but the feedback */
+/* terms simply represent the results of eight shift/xor opera- */
+/* tions for all combinations of data and CRC register values. */
+/* */
+/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
+/* be they sixteen or thirty-two bits wide. You simply choose the */
+/* appropriate table. Alternatively, because the table can be */
+/* generated at runtime, you can start by generating the table for */
+/* the polynomial in question and use exactly the same "updcrc", */
+/* if your application needn't simultaneously handle two CRC */
+/* polynomials. (Note, however, that XMODEM is strange.) */
+/* */
+/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
+/* of course, 32-bit entries work OK if the high 16 bits are zero. */
+/* */
+/* 4. The values must be right-shifted by eight bits by the "updcrc" */
+/* logic; the shift must be unsigned (bring in zeroes). On some */
+/* hardware you could probably optimize the shift in assembler by */
+/* using byte-swap instructions. */
+
+static UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
+0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
+
+int Block = 0; /* Pad file with 032's to multiple of Block */
+
+main(argc, argv)
+char **argv;
+{
+ register errors = 0;
+
+ if (! strcmp(argv[1], "-x")) {
+ Block = 128; --argc; ++argv;
+ }
+ if (! strcmp(argv[1], "-k")) {
+ Block = 1024; --argc; ++argv;
+ }
+ while( --argc > 0)
+ errors |= crc32file( *++argv);
+ exit(errors != 0);
+}
+
+crc32file(name)
+char *name;
+{
+ register FILE *fin;
+ register unsigned long oldcrc32;
+ register unsigned long crc32;
+ register unsigned long oldcrc;
+ register c;
+ register long charcnt;
+ register long l;
+
+ oldcrc32 = 0xFFFFFFFF; charcnt = 0;
+#ifdef M_I86SM
+ if ((fin=fopen(name, "rb"))==NULL)
+#else
+ if ((fin=fopen(name, "r"))==NULL)
+#endif
+ {
+ perror(name);
+ return ERROR;
+ }
+ while ((c=getc(fin))!=EOF) {
+ ++charcnt;
+ oldcrc32 = UPDC32(c, oldcrc32);
+ }
+
+ if (ferror(fin)) {
+ perror(name);
+ fclose(fin); return ERROR;
+ }
+ else {
+ if (Block) {
+ for (l = charcnt; l % Block; ++l)
+ oldcrc32 = UPDC32(032, oldcrc32);
+ }
+ crc32 = oldcrc32; oldcrc = oldcrc32 = ~oldcrc32;
+
+ printf("%08lX %7ld ", oldcrc, charcnt);
+ if (Block == 128)
+ printf("%5ld+%3ld ", charcnt/Block, charcnt%Block);
+ if (Block == 1024)
+ printf("%5ld+%4ld ", charcnt/Block, charcnt%Block);
+ printf(" %s\n", name);
+ }
+
+ fclose(fin); return OK;
+}
+
+/* End of crc.c */
diff --git a/zmodem/crctab.c b/zmodem/crctab.c
new file mode 100644
index 0000000..9f690be
--- /dev/null
+++ b/zmodem/crctab.c
@@ -0,0 +1,140 @@
+/*
+ * Crc calculation stuff
+ */
+
+/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
+static unsigned short crctab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+/*
+ * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
+ * NOTE: First srgument must be in range 0 to 255.
+ * Second argument is referenced twice.
+ *
+ * Programmers may incorporate any or all code into their programs,
+ * giving proper credit within the source. Publication of the
+ * source routines is permitted so long as proper credit is given
+ * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
+ * Omen Technology.
+ */
+
+#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
+
+/*
+ * Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+
+/* First, the polynomial itself and its table of feedback terms. The */
+/* polynomial is */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in */
+/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+/* the MSB being 1. */
+
+/* Note that the usual hardware shift register implementation, which */
+/* is what we're using (we're merely optimizing it by doing eight-bit */
+/* chunks at a time) shifts bits into the lowest-order term. In our */
+/* implementation, that means shifting towards the right. Why do we */
+/* do it this way? Because the calculated CRC must be transmitted in */
+/* order from highest-order term to lowest-order term. UARTs transmit */
+/* characters in order from LSB to MSB. By storing the CRC this way, */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part. Reception works similarly. */
+
+/* The feedback terms table consists of 256, 32-bit entries. Notes: */
+/* */
+/* The table can be generated at runtime if desired; code to do so */
+/* is shown later. It might not be obvious, but the feedback */
+/* terms simply represent the results of eight shift/xor opera- */
+/* tions for all combinations of data and CRC register values. */
+/* */
+/* The values must be right-shifted by eight bits by the "updcrc" */
+/* logic; the shift must be unsigned (bring in zeroes). On some */
+/* hardware you could probably optimize the shift in assembler by */
+/* using byte-swap instructions. */
+
+static unsigned long cr3tab[] = { /* CRC polynomial 0xedb88320 */
+0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+#ifdef NFGM
+unsigned long
+UPDC32(b, c)
+unsigned long c;
+{
+ return (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF));
+}
+
+#else
+
+#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
+#endif
+
+/* End of crctab.c */
diff --git a/zmodem/minirb.c b/zmodem/minirb.c
new file mode 100644
index 0000000..c955dc6
--- /dev/null
+++ b/zmodem/minirb.c
@@ -0,0 +1,85 @@
+char* Version= "minirb 3.02 12-21-94 Copyright 1994 Omen Technology INC";
+#include <stdio.h>
+#include <signal.h>
+#include <setjmp.h>
+
+FILE *fout; long Bytesleft; int Blklen; char secbuf[1024]; char linbuf[1024];
+int Lleft=0; jmp_buf tohere;
+
+void mode(n) { if (n) system("stty raw -echo"); else system("stty echo -raw"); }
+
+void alrm(c) { longjmp(tohere, -1); }
+
+void bibi(n) {
+ mode(0); fprintf(stderr, "minirb: signal %d; exiting", n); exit(128+n); }
+
+main() {
+ mode(1); if (signal(SIGINT, bibi) == SIG_IGN) {
+ signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN); } else {
+ signal(SIGINT, bibi); signal(SIGKILL, bibi); }
+ printf("%s\r\n\n\n", Version);
+ printf("Send your files with a YAM/ZCOMM \042sb file ...\042 command\r\n");
+ wcreceive(); mode(0); exit(0); }
+
+wcreceive() {
+ for (;;) {
+ if (wcrxpn(secbuf) == -1) break;
+ if (secbuf[0]==0) return;
+ if (procheader(secbuf)== -1 || wcrx()== -1) break; } }
+
+wcrxpn(rpn) char *rpn; { register c;
+et_tu:
+ sendline(025); Lleft=0; while ((c = wcgetsec(rpn)) != 0) {
+ if (c == -10) { sendline(6); Lleft=0; rdln(2); goto et_tu; } return -1; }
+ sendline(6); return 0; }
+
+wcrx() { register int sectnum, sectcurr, sendchar, cblklen;
+ sectnum=0; sendchar=025;
+for (;;) {
+ sendline(sendchar); Lleft=0; sectcurr=wcgetsec(secbuf);
+ if (sectcurr==(sectnum+1 & 0377)) {
+ sectnum++; cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
+ fwrite(secbuf, cblklen, 1, fout);
+ if ((Bytesleft-=cblklen) < 0) Bytesleft = 0;
+ sendchar=6; }
+ else if (sectcurr==(sectnum&0377)) sendchar=6;
+ else if (sectcurr== -10) { fclose(fout); sendline(6); Lleft=0; return 0; }
+ else return -1; } }
+
+wcgetsec(rxbuf) char *rxbuf; {
+ register checksum, wcj, firstch; register char *p; int sectcurr, errors;
+ for (errors=0; errors<15; errors++) {
+ if ((firstch=rdln(5))==2) { Blklen=1024; goto get2; }
+ if (firstch==1) { Blklen=128;
+get2:
+ sectcurr=rdln(2); checksum=0;
+ if ((sectcurr+(rdln(2)))==0377) {
+ for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
+ if ((firstch=rdln(2)) < 0) goto bilge;
+ checksum += (*p++ = firstch); }
+ if ((firstch=rdln(2)) < 0) goto bilge;
+ if (((checksum-firstch)&0377)==0) return sectcurr;
+ } }
+ else if (firstch==4) return -10;
+ else if (firstch==24) return -1;
+bilge: while(rdln(2)!= -2) ;
+ sendline(025); Lleft=0; }
+ return -1; }
+
+rdln(timeout) int timeout; { static char *cdq;
+ if (--Lleft >= 0) return (*cdq++ & 0377);
+ if (setjmp(tohere)) { Lleft = 0; return -2; }
+ signal(SIGALRM, alrm); alarm(timeout);
+ Lleft=read(0, cdq=linbuf, 1024); alarm(0);
+ if (Lleft < 1) return -2;
+ --Lleft; return (*cdq++ & 0377); }
+
+procheader(name) char *name; { register char *p;
+ Bytesleft = 2000000000L; p = name + 1 + strlen(name);
+ if (*p) sscanf(p, "%ld", &Bytesleft);
+ if ((fout=fopen(name, "w")) == NULL) return -1;
+ return 0; }
+
+sendline(c) { char d; d = c; write(1, &d, 1); }
+
+/* End of minirb.c */
diff --git a/zmodem/rbsb.c b/zmodem/rbsb.c
new file mode 100644
index 0000000..bdccb39
--- /dev/null
+++ b/zmodem/rbsb.c
@@ -0,0 +1,549 @@
+/*
+ * V7/BSD HACKERS: SEE NOTES UNDER mode(2) !!!
+ *
+ * This file is #included so the main file can set parameters such as HOWMANY.
+ * See the main files (rz.c/sz.c) for compile instructions.
+ */
+
+char *Copyr = "Copyright 1994 Omen Technology Inc All Rights Reserved";
+
+#ifdef V7
+#include <sys/types.h>
+#include <sys/stat.h>
+#define STAT
+#include <sgtty.h>
+#define OS "V7/BSD"
+char *getenv(), *ttyname();
+#ifdef LLITOUT
+long Locmode; /* Saved "local mode" for 4.x BSD "new driver" */
+long Locbit = LLITOUT; /* Bit SUPPOSED to disable output translations */
+#include <strings.h>
+#endif
+#endif
+
+#ifdef USG
+#include <sys/types.h>
+#include <sys/stat.h>
+#define STAT
+#include <termio.h>
+#define OS "SYS III/V"
+#define MODE2OK
+#include <string.h>
+#ifndef OLD
+#include <stdlib.h>
+#endif
+#include <unistd.h>
+#endif
+
+#ifdef POSIX
+#define USG
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#define STAT
+#include <termios.h>
+#define OS "POSIX"
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifndef READCHECK
+#ifndef FIONREAD
+#define SV
+#endif
+#endif
+#endif
+
+#ifdef OLD
+char *ttyname();
+char *getenv();
+#define time_t long
+#endif
+
+
+#ifdef T6K
+#include <sys/ioctl.h> /* JPRadley: for the Tandy 6000 */
+#endif
+
+#include <setjmp.h>
+
+#if HOWMANY > 255
+Howmany must be 255 or less
+#endif
+
+ /*
+ * Some systems (Venix, Coherent, Regulus) may not support tty raw mode
+ * read(2) the same way as Unix. ONEREAD must be defined to force one
+ * character reads for these systems. Added 7-01-84 CAF
+ */
+
+#define sendline(c) putc(c & 0377, Ttystream)
+#define xsendline(c) putc(c, Ttystream)
+
+char *Nametty;
+FILE *Ttystream;
+int Tty;
+char linbuf[HOWMANY];
+char xXbuf[BUFSIZ];
+int Lleft=0; /* number of characters in linbuf */
+jmp_buf tohere; /* For the interrupt on RX timeout */
+#ifdef ONEREAD
+/* Sorry, Regulus and some others don't work right in raw mode! */
+int Readnum = 1; /* Number of bytes to ask for in read() from modem */
+#else
+int Readnum = HOWMANY; /* Number of bytes to ask for in read() from modem */
+#endif
+int Verbose=0;
+
+
+/*
+ * The following uses an external rdchk() routine if available,
+ * otherwise defines the function for BSD or fakes it for SYSV.
+ */
+
+#ifndef READCHECK
+#ifdef FIONREAD
+#define READCHECK
+/*
+ * Return non 0 iff something to read from io descriptor f
+ */
+rdchk(f)
+{
+ static long lf;
+
+ ioctl(f, FIONREAD, &lf);
+ return ((int) lf);
+}
+
+#else /* FIONREAD */
+
+#ifdef SV
+#define READCHECK
+#include <fcntl.h>
+
+int checked = 0;
+/*
+ * Nonblocking I/O is a bit different in System V, Release 2
+ * Note: this rdchk vsn throws away a byte, OK for ZMODEM
+ * sender because protocol design anticipates this problem.
+ */
+#define EATSIT
+rdchk(f)
+{
+ int lf, savestat;
+ static char bchecked;
+
+ savestat = fcntl(f, F_GETFL) ;
+#ifdef O_NDELAY
+ fcntl(f, F_SETFL, savestat | O_NDELAY) ;
+#else
+ fcntl(f, F_SETFL, savestat | O_NONBLOCK) ;
+#endif
+ lf = read(f, &bchecked, 1) ;
+ fcntl(f, F_SETFL, savestat) ;
+ checked = bchecked & 0377; /* force unsigned byte */
+ return(lf) ;
+}
+#endif
+#endif
+#endif
+
+
+struct {
+ unsigned baudr;
+ int speedcode;
+} speeds[] = {
+ 110, B110,
+#ifdef B150
+ 150, B150,
+#endif
+ 300, B300,
+ 600, B600,
+ 1200, B1200,
+ 2400, B2400,
+ 4800, B4800,
+ 9600, B9600,
+#ifdef B19200
+ 19200, B19200,
+#endif
+#ifdef EXTA
+ 19200, EXTA,
+#endif
+#ifdef B38400
+ 38400, B38400,
+#endif
+#ifdef EXTB
+ 38400, EXTB,
+#endif
+ 0, 0
+};
+static unsigned
+getspeed(code)
+{
+ register n;
+
+ for (n=0; speeds[n].baudr; ++n)
+ if (speeds[n].speedcode == code)
+ return speeds[n].baudr;
+ if (code > 49)
+ return ((unsigned)code);
+ return 1; /* Assume fifo if ioctl failed */
+}
+
+
+#ifdef ICANON
+#ifdef POSIX
+struct termios oldtty, tty;
+#else
+struct termio oldtty, tty;
+#endif
+#else
+struct sgttyb oldtty, tty;
+struct tchars oldtch, tch;
+#endif
+
+/*
+ * mode(n)
+ * 3: save old tty stat, set raw mode with flow control
+ * 2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
+ * 1: save old tty stat, set raw mode
+ * 0: restore original tty mode
+ */
+mode(n)
+{
+ static did0 = FALSE;
+
+ vfile("mode:%d", n);
+ switch(n) {
+#ifdef USG
+ case 2: /* Un-raw mode used by sz, sb when -g detected */
+#ifdef POSIX
+ if(!did0)
+ (void) tcgetattr(Tty, &oldtty);
+#else
+ if(!did0)
+ (void) ioctl(Tty, TCGETA, &oldtty);
+#endif
+ tty = oldtty;
+
+ tty.c_iflag = BRKINT|IXON;
+
+ tty.c_oflag = 0; /* Transparent output */
+
+ tty.c_cflag &= ~(PARENB|CSIZE); /* Disable parity */
+ tty.c_cflag |= (CREAD|CS8); /* Set character size = 8 */
+
+
+#ifdef READCHECK
+ tty.c_lflag = Zmodem ? 0 : ISIG;
+ tty.c_cc[VINTR] = Zmodem ? -1:030; /* Interrupt char */
+#else
+ tty.c_lflag = ISIG;
+ tty.c_cc[VINTR] = Zmodem ? 03:030; /* Interrupt char */
+#endif
+ tty.c_cc[VQUIT] = -1; /* Quit char */
+#ifdef NFGVMIN
+ tty.c_cc[VMIN] = 1;
+#else
+ tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */
+#endif
+ tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
+
+#ifdef POSIX
+ (void) tcsetattr(Tty, TCSADRAIN, &tty);
+#else
+ (void) ioctl(Tty, TCSETAW, &tty);
+#endif
+ did0 = TRUE;
+ return OK;
+ case 1:
+ case 3:
+#ifdef POSIX
+ if(!did0)
+ (void) tcgetattr(Tty, &oldtty);
+#else
+ if(!did0)
+ (void) ioctl(Tty, TCGETA, &oldtty);
+#endif
+ tty = oldtty;
+
+ tty.c_iflag = n==3 ? (IXON|IXOFF) : IXOFF;
+
+ tty.c_lflag = 0;
+
+ tty.c_oflag = 0;
+
+ tty.c_cflag &= ~(CSIZE|PARENB); /* disable parity */
+ tty.c_cflag |= CS8; /* Set character size = 8 */
+#ifdef NFGVMIN
+ tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
+#else
+ tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
+#endif
+ tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
+#ifdef POSIX
+ (void) tcsetattr(Tty, TCSADRAIN, &tty);
+#else
+ (void) ioctl(Tty, TCSETAW, &tty);
+#endif
+ did0 = TRUE;
+#ifdef POSIX
+ Baudrate = getspeed(cfgetospeed(&tty));
+#else
+ Baudrate = getspeed(tty.c_cflag & CBAUD);
+#endif
+ vfile("Baudrate = %u\n", Baudrate);
+ return OK;
+#endif
+#ifdef V7
+ /*
+ * NOTE: this should transmit all 8 bits and at the same time
+ * respond to XOFF/XON flow control. If no FIONREAD or other
+ * rdchk() alternative, also must respond to INTRRUPT char
+ * This doesn't work with V7. It should work with LLITOUT,
+ * but LLITOUT was broken on the machine I tried it on.
+ */
+ case 2: /* Un-raw mode used by sz, sb when -g detected */
+ if(!did0) {
+ ioctl(Tty, TIOCEXCL, 0);
+ ioctl(Tty, TIOCGETP, &oldtty);
+ ioctl(Tty, TIOCGETC, &oldtch);
+#ifdef LLITOUT
+ ioctl(Tty, TIOCLGET, &Locmode);
+#endif
+ }
+ tty = oldtty;
+ tch = oldtch;
+#ifdef READCHECK
+ tch.t_intrc = Zmodem ? -1:030; /* Interrupt char */
+#else
+ tch.t_intrc = Zmodem ? 03:030; /* Interrupt char */
+#endif
+ tty.sg_flags |= (ODDP|EVENP|CBREAK);
+ tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
+ ioctl(Tty, TIOCSETP, &tty);
+ ioctl(Tty, TIOCSETC, &tch);
+#ifdef LLITOUT
+ ioctl(Tty, TIOCLBIS, &Locbit);
+#else
+ bibi(99); /* un-raw doesn't work w/o lit out */
+#endif
+ did0 = TRUE;
+ return OK;
+ case 1:
+ case 3:
+ if(!did0) {
+ ioctl(Tty, TIOCEXCL, 0);
+ ioctl(Tty, TIOCGETP, &oldtty);
+ ioctl(Tty, TIOCGETC, &oldtch);
+#ifdef LLITOUT
+ ioctl(Tty, TIOCLGET, &Locmode);
+#endif
+ }
+ tty = oldtty;
+ tty.sg_flags |= (RAW|TANDEM);
+ tty.sg_flags &= ~ECHO;
+ ioctl(Tty, TIOCSETP, &tty);
+ did0 = TRUE;
+ Baudrate = getspeed(tty.sg_ospeed);
+ return OK;
+#endif
+ case 0:
+ if(!did0)
+ return ERROR;
+#ifdef USG
+#ifdef POSIX
+ (void) tcdrain(Tty); /* Wait for output to drain */
+ (void) tcflush(Tty, TCIFLUSH); /* Flush input queue */
+ (void) tcsetattr(Tty, TCSADRAIN, &oldtty); /* Restore */
+ (void) tcflow(Tty, TCOON); /* Restart output */
+#else
+ (void) ioctl(Tty, TCSBRK, 1); /* Wait for output to drain */
+ (void) ioctl(Tty, TCFLSH, 1); /* Flush input queue */
+ (void) ioctl(Tty, TCSETAW, &oldtty); /* Restore modes */
+ (void) ioctl(Tty, TCXONC,1); /* Restart output */
+#endif
+#endif
+#ifdef V7
+ ioctl(Tty, TIOCSETP, &oldtty);
+ ioctl(Tty, TIOCSETC, &oldtch);
+ ioctl(Tty, TIOCNXCL, 0);
+#ifdef LLITOUT
+ ioctl(Tty, TIOCLSET, &Locmode);
+#endif
+#endif
+
+ return OK;
+ default:
+ return ERROR;
+ }
+}
+
+sendbrk()
+{
+#ifdef V7
+#ifdef TIOCSBRK
+#define CANBREAK
+ sleep(1);
+ ioctl(Tty, TIOCSBRK, 0);
+ sleep(1);
+ ioctl(Tty, TIOCCBRK, 0);
+#endif
+#endif
+#ifdef USG
+#define CANBREAK
+#ifdef POSIX
+ tcsendbreak(Tty, 200);
+#else
+ ioctl(Tty, TCSBRK, 0);
+#endif
+#endif
+}
+
+/* Initialize tty device for serial file xfer */
+inittty()
+{
+ if ((Nametty = ttyname(2)) && *Nametty) {
+ Tty = open(Nametty, 2);
+ } else {
+ Tty = open(Nametty = "/dev/tty", 2);
+ }
+
+ if (Tty <= 0) {
+ perror(Nametty); exit(2);
+ }
+ Ttystream = fdopen(Tty, "w");
+}
+
+flushmoc()
+{
+ fflush(Ttystream);
+}
+flushmo()
+{
+ fflush(Ttystream);
+}
+
+/*
+ * This version of readline is reasoably well suited for
+ * reading many characters.
+ *
+ * timeout is in tenths of seconds
+ */
+void
+alrm(c)
+{
+ longjmp(tohere, -1);
+}
+readline(timeout)
+int timeout;
+{
+ register n;
+ static char *cdq; /* pointer for removing chars from linbuf */
+
+ if (--Lleft >= 0) {
+ if (Verbose > 8) {
+ fprintf(stderr, "%02x ", *cdq&0377);
+ }
+ return (*cdq++ & 0377);
+ }
+ n = timeout/10;
+ if (n < 2)
+ n = 2;
+ if (Verbose > 5)
+ fprintf(stderr, "Calling read: alarm=%d Readnum=%d ",
+ n, Readnum);
+ if (setjmp(tohere)) {
+#ifdef TIOCFLUSH
+/* ioctl(Tty, TIOCFLUSH, 0); */
+#endif
+ Lleft = 0;
+ if (Verbose>1)
+ fprintf(stderr, "Readline:TIMEOUT\n");
+ return TIMEOUT;
+ }
+ signal(SIGALRM, alrm); alarm(n);
+ errno = 0;
+ Lleft=read(Tty, cdq=linbuf, Readnum);
+ alarm(0);
+ if (Verbose > 5) {
+ fprintf(stderr, "Read returned %d bytes errno=%d\n",
+ Lleft, errno);
+ }
+ if (Lleft < 1)
+ return TIMEOUT;
+ if (Verbose > 8) {
+ for (n = Lleft; --n >= 0; ) {
+ fprintf(stderr, "%02x ", *cdq&0377);
+ }
+ fprintf(stderr, "\n");
+ }
+ --Lleft;
+ return (*cdq++ & 0377);
+}
+
+
+
+/*
+ * Purge the modem input queue of all characters
+ */
+purgeline()
+{
+ Lleft = 0;
+#ifdef USG
+#ifdef POSIX
+ tcflush(Tty, 0);
+#else
+ ioctl(Tty, TCFLSH, 0);
+#endif
+#else
+ lseek(Tty, 0L, 2);
+#endif
+}
+
+
+/* send cancel string to get the other end to shut up */
+canit()
+{
+ static char canistr[] = {
+ 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
+ };
+
+ zmputs(canistr);
+ Lleft=0; /* Do read next time ... */
+}
+
+/*
+ * Send a string to the modem, processing for \336 (sleep 1 sec)
+ * and \335 (break signal)
+ */
+zmputs(s)
+char *s;
+{
+ register c;
+
+ while (*s) {
+ switch (c = *s++) {
+ case '\336':
+ sleep(1); continue;
+ case '\335':
+ sendbrk(); continue;
+ default:
+ sendline(c);
+ }
+ }
+ flushmo();
+}
+
+
+/* VARARGS1 */
+vfile(f, a, b, c, d)
+char *f;
+long a, b, c, d;
+{
+ if (Verbose > 2) {
+ fprintf(stderr, f, a, b, c, d);
+ fprintf(stderr, "\n");
+ }
+}
+
+/* End of rbsb.c */
diff --git a/zmodem/rz.c b/zmodem/rz.c
new file mode 100644
index 0000000..537d5d6
--- /dev/null
+++ b/zmodem/rz.c
@@ -0,0 +1,1367 @@
+#define VERSION "3.48 01-27-98"
+#define PUBDIR "/usr/spool/uucppublic"
+
+/*
+ *
+ * rz.c By Chuck Forsberg
+ * Copyright 1997 Omen Technology Inc All Rights Reserved
+ *
+ * A program for Unix to receive files and commands from computers running
+ * Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM.
+ * rz uses Unix buffered input to reduce wasted CPU time.
+ *
+ *
+ *********************************************************************
+ *********************************************************************
+ *
+ *
+ * This version implements numerous enhancements including ZMODEM
+ * Run Length Encoding and variable length headers. These
+ * features were not funded by the original Telenet development
+ * contract.
+ *
+ *
+ * This software may be freely used for educational (didactic
+ * only) purposes. "Didactic" means it is used as a study item
+ * in a course teaching the workings of computer protocols.
+ *
+ * This software may also be freely used to support file transfer
+ * operations to or from duly licensed Omen Technology products.
+ * This includes DSZ, GSZ, ZCOMM, Professional-YAM and PowerCom.
+ * Institutions desiring to use rz/sz this way should add the
+ * following to the sz compile line: -DCOMPL
+ * Programs based on stolen or public domain ZMODEM materials are
+ * not included. Use with other commercial or shareware programs
+ * (Crosstalk, Procomm, etc.) REQUIRES REGISTRATION.
+ *
+ *
+ * Any programs which incorporate part or all of this code must be
+ * provided in source form with this notice intact except by
+ * prior written permission from Omen Technology Incorporated.
+ * This includes compiled executables of this program.
+ *
+ * The .doc files and the file "mailer.rz" must also be included.
+ *
+ * Use of this software for commercial or administrative purposes
+ * except when exclusively limited to interfacing Omen Technology
+ * products requires license payment of $20.00 US per user
+ * (less in quantity, see mailer.rz). Use of this code by
+ * inclusion, decompilation, reverse engineering or any other means
+ * constitutes agreement to these conditions and acceptance of
+ * liability to license the materials and payment of reasonable
+ * legal costs necessary to enforce this license agreement.
+ *
+ *
+ * Omen Technology Inc
+ * Post Office Box 4681
+ * Portland OR 97208
+ *
+ * This code is made available in the hope it will be useful,
+ * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
+ * DAMAGES OF ANY KIND.
+ *
+ *
+ * -DMD may be added to compiler command line to compile in
+ * Directory-creating routines from Public Domain TAR by John Gilmore
+ *
+ * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin
+ */
+
+char *Copyrrz = "Copyright 1997 Omen Technology Inc All Rights Reserved";
+
+
+#define LOGFILE "/tmp/rzlog"
+#define LOGFILE2 "rzlog"
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <errno.h>
+extern int errno;
+
+#define OK 0
+#define FALSE 0
+#define TRUE 1
+#define ERROR (-1)
+
+/*
+ * Max value for HOWMANY is 255.
+ * A larger value reduces system overhead but may evoke kernel bugs.
+ */
+#ifndef HOWMANY
+#define HOWMANY 96
+#endif
+
+/* Ward Christensen / CP/M parameters - Don't change these! */
+#define ENQ 005
+#define CAN ('X'&037)
+#define XOFF ('s'&037)
+#define XON ('q'&037)
+#define SOH 1
+#define STX 2
+#define EOT 4
+#define ACK 6
+#define NAK 025
+#define CPMEOF 032
+#define WANTCRC 0103 /* send C not NAK to get crc not checksum */
+#define TIMEOUT (-2)
+#define RCDO (-3)
+#define GCOUNT (-4)
+#define ERRORMAX 5
+#define RETRYMAX 5
+#define WCEOT (-10)
+#define PATHLEN 257 /* ready for 4.2 bsd ? */
+#define UNIXFILE 0xF000 /* The S_IFMT file mask bit for stat */
+
+int Zmodem=0; /* ZMODEM protocol requested */
+int Nozmodem = 0; /* If invoked as "rb" */
+unsigned Baudrate = 9600;
+
+
+#include "rbsb.c" /* most of the system dependent stuff here */
+#include "crctab.c"
+char endmsg[90] = {0}; /* Possible message to display on exit */
+char Zsendmask[33]; /* Additional control chars to mask */
+
+char *substr();
+FILE *fout;
+
+/*
+ * Routine to calculate the free bytes on the current file system
+ * ~0 means many free bytes (unknown)
+ */
+long getfree()
+{
+ return(2147483647); /* many free bytes ... */
+}
+
+int Lastrx;
+long rxbytes;
+int Crcflg;
+int Firstsec;
+int Eofseen; /* indicates cpm eof (^Z) has been received */
+int errors;
+int Restricted=0; /* restricted; no /.. or ../ in filenames */
+
+#define DEFBYTL 2000000000L /* default rx file size */
+long Bytesleft; /* number of bytes of incoming file left */
+long Modtime; /* Unix style mod time for incoming file */
+int Filemode; /* Unix style mode for incoming file */
+long Totalleft;
+long Filesleft;
+char Pathname[PATHLEN];
+char *Progname; /* the name by which we were called */
+
+int Batch=0;
+int Thisbinary; /* current file is to be received in bin mode */
+int Rxbinary=FALSE; /* receive all files in bin mode */
+int Rxascii=FALSE; /* receive files in ascii (translate) mode */
+int Blklen; /* record length of received packets */
+
+#ifdef SEGMENTS
+int chinseg = 0; /* Number of characters received in this data seg */
+char secbuf[1+(SEGMENTS+1)*1024];
+#else
+char secbuf[1025];
+#endif
+
+
+time_t timep[2];
+char Lzmanag; /* Local file management request */
+char Lzconv; /* Local ZMODEM file conversion request */
+char zconv; /* ZMODEM file conversion request */
+char zmanag; /* ZMODEM file management request */
+char ztrans; /* ZMODEM file transport request */
+int Zctlesc; /* Encode control characters */
+int Zrwindow = 1400; /* RX window size (controls garbage count) */
+
+/*
+ * Log an error
+ */
+void
+zperr1(s,p,u)
+char *s, *p, *u;
+{
+ if (Verbose <= 0)
+ return;
+ fprintf(stderr, "Retry %d: ", errors);
+ fprintf(stderr, s);
+ fprintf(stderr, "\n");
+}
+
+void
+zperr2(s,p,u)
+char *s, *p, *u;
+{
+ if (Verbose <= 0)
+ return;
+ fprintf(stderr, "Retry %d: ", errors);
+ fprintf(stderr, s, p);
+ fprintf(stderr, "\n");
+}
+
+void
+zperr3(s,p,u)
+char *s, *p, *u;
+{
+ if (Verbose <= 0)
+ return;
+ fprintf(stderr, "Retry %d: ", errors);
+ fprintf(stderr, s, p, u);
+ fprintf(stderr, "\n");
+}
+
+#include "zm.c"
+#include "zmr.c"
+
+int tryzhdrtype=ZRINIT; /* Header type to send corresponding to Last rx close */
+
+/* called by signal interrupt or terminate to clean things up */
+void
+bibi(n)
+{
+ if (Zmodem)
+ zmputs(Attn);
+ canit(); mode(0);
+ fprintf(stderr, "rz: caught signal %d; exiting", n);
+ exit(3);
+}
+
+main(argc, argv)
+char *argv[];
+{
+ register char *cp;
+ register npats;
+ char *virgin, **patts;
+ int exitcode = 0;
+
+ Rxtimeout = 100;
+ setbuf(stderr, NULL);
+ if (((cp = getenv("RESTRICTED")) != 0) && *cp == '1')
+ Restricted=TRUE;
+ if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
+ Restricted=TRUE;
+
+ chkinvok(virgin=argv[0]);
+ inittty();
+ npats = 0;
+ while (--argc) {
+ cp = *++argv;
+ if (*cp == '-') {
+ ++cp;
+ while( *cp) {
+ if (isdigit(*cp)) {
+ ++cp; continue;
+ }
+ switch(*cp++) {
+ case '\\':
+ *cp = toupper(*cp); continue;
+ case 'a':
+ if (!Batch || Nozmodem)
+ Rxascii=TRUE;
+ else
+ usage();
+ break;
+ case 't':
+ if (isdigit(*cp))
+ Rxtimeout = atoi(cp);
+ else {
+ if (--argc < 1)
+ usage();
+ Rxtimeout = atoi(*++argv);
+ }
+ if (Rxtimeout<1 || Rxtimeout>1000)
+ usage();
+ break;
+ case 'w':
+ if (isdigit(*cp))
+ Zrwindow = atoi(cp);
+ else {
+ if (--argc < 1)
+ usage();
+ Zrwindow = atoi(*++argv);
+ }
+ break;
+ case 'v':
+ ++Verbose; break;
+ case 'y':
+ Lzmanag = ZMCLOB;
+ break;
+ default:
+ usage();
+ }
+ }
+ }
+ else if ( !npats && argc>0) {
+ if (argv[0][0]) {
+ npats=argc;
+ patts=argv;
+ }
+ }
+ }
+ if (npats > 1)
+ usage();
+ if (Batch && npats)
+ usage();
+ if (Verbose) {
+ if (freopen(LOGFILE, "a", stderr)==NULL)
+ if (freopen(LOGFILE2, "a", stderr)==NULL) {
+ fprintf(stderr, "Can't open log file!\n");
+ exit(2);
+ }
+ setbuf(stderr, NULL);
+ fprintf(stderr, "argv[0]=%s Progname=%s\n", virgin, Progname);
+ }
+ vfile("%s %s for %s tty=%s\n", Progname, VERSION, OS, Nametty);
+ mode(1);
+ if (signal(SIGINT, bibi) == SIG_IGN) {
+ signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
+ }
+ else {
+ signal(SIGINT, bibi); signal(SIGKILL, bibi);
+ }
+ signal(SIGTERM, bibi);
+ if (wcreceive(npats, patts)==ERROR) {
+ exitcode=1;
+ canit();
+ }
+ if (exitcode && !Zmodem) /* bellow again with all thy might. */
+ canit();
+ if (endmsg[0])
+ fprintf(stderr, " %s: %s\r\n", Progname, endmsg);
+ fprintf(stderr, "%s %s finished.\r\n", Progname, VERSION);
+ fflush(stderr);
+#ifndef REGISTERED
+ /* Removing or disabling this code without registering is theft */
+ if (!Usevhdrs) {
+ fprintf(stderr, "\n\n\n**** UNREGISTERED COPY *****\r\n");
+ fprintf(stderr, "Please read the License Agreement in rz.doc\r\n");
+ fflush(stderr);
+ sleep(10);
+ }
+#endif
+#ifdef SYLIXOS
+ sleep(2);
+#endif
+ mode(0);
+ if(exitcode)
+ exit(1);
+ exit(0);
+ /* NOTREACHED */
+}
+
+
+usage()
+{
+ fprintf(stderr,
+ "Receive Files and Commands with ZMODEM/YMODEM/XMODEM Protocol\n\n");
+ fprintf(stderr,"Usage: rz [-v] [-wN] [-tT] (ZMODEM)\n");
+ fprintf(stderr,"or rb [-avy] [-tT] (YMODEM)\n");
+ fprintf(stderr,"or rc [-avy] [-tT] file (XMODEM-CRC)\n");
+ fprintf(stderr,"or rx [-avy] [-tT] file (XMODEM)\n\n");
+ fprintf(stderr,
+"Supports the following incoming ZMODEM options given to the sending program:\n\
+ compression (-Z), binary (-b), ASCII CR/LF>NL (-a), newer(-n),\n\
+ newer+longer(-N), protect (-p), Crash Recovery (-r),\n\
+ clobber (-y), match+clobber (-Y), and append (-+).\n\n");
+ fprintf(stderr,"%s %s for %s by Chuck Forsberg, Omen Technology INC\n",
+ Progname, VERSION, OS);
+ fprintf(stderr, "\t\t\042The High Reliability Software\042\n\n");
+ fprintf(stderr,"Copyright (c) 1997 Omen Technology INC All Rights Reserved\n");
+ fprintf(stderr,
+ "See rz.doc and README for option descriptions and licensing information.\n\n");
+ fprintf(stderr,
+ "This program is designed to talk to terminal programs,\nnot to be called by one.\n");
+#ifndef REGISTERED
+ fprintf(stderr, "\n\n\n **** UNREGISTERED COPY *****\r\n");
+ fprintf(stderr, "Please read the License Agreement in rz.doc\r\n");
+#endif
+ exit(2);
+}
+
+/*
+ * Let's receive something already.
+ */
+
+char *rbmsg = "%s ready. Type \"%s file ...\" to your modem program\n\r";
+
+wcreceive(argc, argp)
+char **argp;
+{
+ register c;
+
+ if (Batch || argc==0) {
+ Crcflg=1;
+ fprintf(stderr, rbmsg, Progname, Nozmodem?"sb":"sz");
+ if (c=tryz()) {
+ if (c == ZCOMPL)
+ return OK;
+ if (c == ERROR)
+ goto fubar;
+ c = rzfiles();
+ if (c)
+ goto fubar;
+ } else {
+ for (;;) {
+ if (wcrxpn(secbuf)== ERROR)
+ goto fubar;
+ if (secbuf[0]==0)
+ return OK;
+ if (procheader(secbuf))
+ goto fubar;
+ if (wcrx()==ERROR)
+ goto fubar;
+ }
+ }
+ } else {
+ Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
+
+ procheader(""); strcpy(Pathname, *argp); checkpath(Pathname);
+ fprintf(stderr, "\nrz: ready to receive %s\r\n", Pathname);
+ if ((fout=fopen(Pathname, "w")) == NULL)
+ return ERROR;
+ if (wcrx()==ERROR)
+ goto fubar;
+ }
+ return OK;
+fubar:
+ canit();
+ Modtime = 1;
+ if (fout)
+ fclose(fout);
+ if (Restricted) {
+ unlink(Pathname);
+ fprintf(stderr, "\r\nrz: %s removed.\r\n", Pathname);
+ }
+ return ERROR;
+}
+
+
+/*
+ * Fetch a pathname from the other end as a C ctyle ASCIZ string.
+ * Length is indeterminate as long as less than Blklen
+ * A null string represents no more files (YMODEM)
+ */
+wcrxpn(rpn)
+char *rpn; /* receive a pathname */
+{
+ register c;
+
+ purgeline();
+
+et_tu:
+ Firstsec=TRUE; Eofseen=FALSE;
+ sendline(Crcflg?WANTCRC:NAK); flushmo();
+ Lleft=0; /* Do read next time ... */
+ switch (c = wcgetsec(rpn, 100)) {
+ case WCEOT:
+ zperr2( "Pathname fetch returned %d", c);
+ sendline(ACK); flushmo();
+ Lleft=0; /* Do read next time ... */
+ readline(1);
+ goto et_tu;
+ case 0:
+ sendline(ACK); flushmo(); return OK;
+ default:
+ return ERROR;
+ }
+}
+
+/*
+ * Adapted from CMODEM13.C, written by
+ * Jack M. Wierda and Roderick W. Hart
+ */
+
+wcrx()
+{
+ register int sectnum, sectcurr;
+ register char sendchar;
+ int cblklen; /* bytes to dump this block */
+
+ Firstsec=TRUE;sectnum=0; Eofseen=FALSE;
+ sendchar=Crcflg?WANTCRC:NAK;
+
+ for (;;) {
+ sendline(sendchar); /* send it now, we're ready! */
+ flushmo();
+ Lleft=0; /* Do read next time ... */
+ sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130);
+ if (sectcurr==(sectnum+1 &0377)) {
+ sectnum++;
+ cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
+ if (putsec(secbuf, cblklen)==ERROR)
+ return ERROR;
+ if ((Bytesleft-=cblklen) < 0)
+ Bytesleft = 0;
+ sendchar=ACK;
+ }
+ else if (sectcurr==(sectnum&0377)) {
+ zperr1( "Received dup Sector");
+ sendchar=ACK;
+ }
+ else if (sectcurr==WCEOT) {
+ if (closeit())
+ return ERROR;
+ sendline(ACK); flushmo();
+ Lleft=0; /* Do read next time ... */
+ return OK;
+ }
+ else if (sectcurr==ERROR)
+ return ERROR;
+ else {
+ zperr1( "Sync Error");
+ return ERROR;
+ }
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Wcgetsec fetches a Ward Christensen type sector.
+ * Returns sector number encountered or ERROR if valid sector not received,
+ * or CAN CAN received
+ * or WCEOT if eot sector
+ * time is timeout for first char, set to 4 seconds thereafter
+ ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
+ * (Caller must do that when he is good and ready to get next sector)
+ */
+
+wcgetsec(rxbuf, maxtime)
+char *rxbuf;
+int maxtime;
+{
+ register checksum, wcj, firstch;
+ register unsigned short oldcrc;
+ register char *p;
+ int sectcurr;
+
+ for (Lastrx=errors=0; errors<RETRYMAX; errors++) {
+
+ if ((firstch=readline(maxtime))==STX) {
+ Blklen=1024; goto get2;
+ }
+ if (firstch==SOH) {
+ Blklen=128;
+get2:
+ sectcurr=readline(1);
+ if ((sectcurr+(oldcrc=readline(1)))==0377) {
+ oldcrc=checksum=0;
+ for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
+ if ((firstch=readline(1)) < 0)
+ goto bilge;
+ oldcrc=updcrc(firstch, oldcrc);
+ checksum += (*p++ = firstch);
+ }
+ if ((firstch=readline(1)) < 0)
+ goto bilge;
+ if (Crcflg) {
+ oldcrc=updcrc(firstch, oldcrc);
+ if ((firstch=readline(1)) < 0)
+ goto bilge;
+ oldcrc=updcrc(firstch, oldcrc);
+ if (oldcrc & 0xFFFF)
+ zperr1( "CRC");
+ else {
+ Firstsec=FALSE;
+ return sectcurr;
+ }
+ }
+ else if (((checksum-firstch)&0377)==0) {
+ Firstsec=FALSE;
+ return sectcurr;
+ }
+ else
+ zperr1( "Checksum");
+ }
+ else
+ zperr1("Sector number garbled");
+ }
+ /* make sure eot really is eot and not just mixmash */
+ else if (firstch==EOT && Lleft==0)
+ return WCEOT;
+ else if (firstch==CAN) {
+ if (Lastrx==CAN) {
+ zperr1( "Sender CANcelled");
+ return ERROR;
+ } else {
+ Lastrx=CAN;
+ continue;
+ }
+ }
+ else if (firstch==TIMEOUT) {
+ if (Firstsec)
+ goto humbug;
+bilge:
+ zperr1( "TIMEOUT");
+ }
+ else
+ zperr1( "Got 0%o sector header", firstch);
+
+humbug:
+ Lastrx=0;
+ while(readline(1)!=TIMEOUT)
+ ;
+ if (Firstsec) {
+ sendline(Crcflg?WANTCRC:NAK); flushmo();
+ Lleft=0; /* Do read next time ... */
+ } else {
+ maxtime=40; sendline(NAK); flushmo();
+ Lleft=0; /* Do read next time ... */
+ }
+ }
+ /* try to stop the bubble machine. */
+ canit();
+ return ERROR;
+}
+
+
+/*
+ * Process incoming file information header
+ * Returns 0 for success, other codes for errors
+ * or skip conditions.
+ */
+procheader(name)
+char *name;
+{
+ register char *openmode, *p;
+ static dummy;
+ struct stat f;
+
+ /* set default parameters and overrides */
+ openmode = "w";
+ Thisbinary = (!Rxascii) || Rxbinary;
+ if (zconv == ZCBIN && Lzconv != ZCRESUM)
+ Lzconv = zconv; /* Remote Binary override */
+ if (Lzconv)
+ zconv = Lzconv;
+ if (Lzmanag)
+ zmanag = Lzmanag;
+
+ /*
+ * Process ZMODEM remote file management requests
+ */
+ if (!Rxbinary && zconv == ZCNL) /* Remote ASCII override */
+ Thisbinary = 0;
+ if (zconv == ZCBIN) /* Remote Binary override */
+ Thisbinary = TRUE;
+ else if (zmanag == ZMAPND)
+ openmode = "a";
+
+ Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
+
+ if (!name || !*name)
+ return 0;
+
+ p = name + 1 + strlen(name);
+ if (*p) { /* file coming from Unix or DOS system */
+ sscanf(p, "%ld%lo%o%lo%d%ld%d%d",
+ &Bytesleft, &Modtime, &Filemode,
+ &dummy, &Filesleft, &Totalleft, &dummy, &dummy);
+ if (Filemode & UNIXFILE)
+ ++Thisbinary;
+ if (Verbose) {
+ fprintf(stderr, "Incoming: %s %ld %lo %o\n",
+ name, Bytesleft, Modtime, Filemode);
+ fprintf(stderr, "YMODEM header: %s\n", p);
+ }
+ }
+
+
+ else { /* File coming from CP/M system */
+ for (p=name; *p; ++p) /* change / to _ */
+ if ( *p == '/')
+ *p = '_';
+
+ if ( *--p == '.') /* zap trailing period */
+ *p = 0;
+ }
+
+ strcpy(Pathname, name);
+ checkpath(name);
+
+ if (*name && stat(name, &f)!= -1) {
+ zmanag &= ZMMASK;
+ if (zmanag==ZMPROT)
+ goto skipfile;
+ vfile("Current %s is %ld %lo", name, f.st_size, f.st_mtime);
+ if (Thisbinary && zconv==ZCRESUM) {
+ rxbytes = f.st_size & ~511;
+ if (Bytesleft < rxbytes) {
+ rxbytes = 0; goto doopen;
+ } else
+ openit(name, "r+");
+ if ( !fout)
+ return ZFERR;
+ if (fseek(fout, rxbytes, 0)) {
+ closeit();
+ return ZFERR;
+ }
+ vfile("Crash recovery at %ld", rxbytes);
+ return 0;
+ }
+ switch (zmanag & ZMMASK) {
+ case ZMNEWL:
+ if (Bytesleft > f.st_size)
+ goto doopen;
+ case ZMNEW:
+ if ((f.st_mtime+1) >= Modtime)
+ goto skipfile;
+ goto doopen;
+ case ZMCLOB:
+ case ZMAPND:
+ goto doopen;
+ default:
+ goto skipfile;
+ }
+ } else if (zmanag & ZMSKNOLOC) {
+skipfile:
+ vfile("Skipping %s", name);
+ return ZSKIP;
+ }
+doopen:
+ openit(name, openmode);
+#ifdef MD
+ if ( !fout)
+ if (make_dirs(name))
+ openit(name, openmode);
+#endif
+ if ( !fout)
+ return ZFERR;
+ return 0;
+}
+
+openit(name, openmode)
+char *name, *openmode;
+{
+ if (strcmp(name, "-"))
+ fout = fopen(name, openmode);
+ else if (isatty(1))
+ fout = fopen("stdout", "a");
+ else
+ fout = stdout;
+}
+
+#ifdef MD
+/*
+ * Directory-creating routines from Public Domain TAR by John Gilmore
+ */
+
+/*
+ * After a file/link/symlink/dir creation has failed, see if
+ * it's because some required directory was not present, and if
+ * so, create all required dirs.
+ */
+make_dirs(pathname)
+register char *pathname;
+{
+ register char *p; /* Points into path */
+ int madeone = 0; /* Did we do anything yet? */
+ int save_errno = errno; /* Remember caller's errno */
+
+ if (errno != ENOENT)
+ return 0; /* Not our problem */
+
+ for (p = strchr(pathname, '/'); p != NULL; p = strchr(p+1, '/')) {
+ /* Avoid mkdir of empty string, if leading or double '/' */
+ if (p == pathname || p[-1] == '/')
+ continue;
+ /* Avoid mkdir where last part of path is '.' */
+ if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
+ continue;
+ *p = 0; /* Truncate the path there */
+ if ( !mkdir(pathname, 0777)) { /* Try to create it as a dir */
+ vfile("Made directory %s\n", pathname);
+ madeone++; /* Remember if we made one */
+ *p = '/';
+ continue;
+ }
+ *p = '/';
+ if (errno == EEXIST) /* Directory already exists */
+ continue;
+ /*
+ * Some other error in the mkdir. We return to the caller.
+ */
+ break;
+ }
+ errno = save_errno; /* Restore caller's errno */
+ return madeone; /* Tell them to retry if we made one */
+}
+
+#if (MD != 2)
+#define TERM_SIGNAL(status) ((status) & 0x7F)
+#define TERM_COREDUMP(status) (((status) & 0x80) != 0)
+#define TERM_VALUE(status) ((status) >> 8)
+/*
+ * Make a directory. Compatible with the mkdir() system call on 4.2BSD.
+ */
+mkdir(dpath, dmode)
+char *dpath;
+int dmode;
+{
+ int cpid, status;
+ struct stat statbuf;
+
+ if (stat(dpath,&statbuf) == 0) {
+ errno = EEXIST; /* Stat worked, so it already exists */
+ return -1;
+ }
+
+ /* If stat fails for a reason other than non-existence, return error */
+ if (errno != ENOENT) return -1;
+
+ switch (cpid = fork()) {
+
+ case -1: /* Error in fork() */
+ return(-1); /* Errno is set already */
+
+ case 0: /* Child process */
+ /*
+ * Cheap hack to set mode of new directory. Since this
+ * child process is going away anyway, we zap its umask.
+ * FIXME, this won't suffice to set SUID, SGID, etc. on this
+ * directory. Does anybody care?
+ */
+ status = umask(0); /* Get current umask */
+ status = umask(status | (0777 & ~dmode)); /* Set for mkdir */
+ execl("/bin/mkdir", "mkdir", dpath, (char *)0);
+ _exit(2); /* Can't exec /bin/mkdir */
+
+ default: /* Parent process */
+ while (cpid != wait(&status)) ; /* Wait for kid to finish */
+ }
+
+ if (TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0) {
+ errno = EIO; /* We don't know why, but */
+ return -1; /* /bin/mkdir failed */
+ }
+
+ return 0;
+}
+#endif /* MD != 2 */
+#endif /* MD */
+
+/*
+ * Putsec writes the n characters of buf to receive file fout.
+ * If not in binary mode, carriage returns, and all characters
+ * starting with CPMEOF are discarded.
+ */
+putsec(buf, n)
+char *buf;
+register n;
+{
+ register char *p;
+
+ if (n == 0)
+ return OK;
+ if (Thisbinary) {
+ for (p=buf; --n>=0; )
+ putc( *p++, fout);
+ }
+ else {
+ if (Eofseen)
+ return OK;
+ for (p=buf; --n>=0; ++p ) {
+ if ( *p == '\r')
+ continue;
+ if (*p == CPMEOF) {
+ Eofseen=TRUE; return OK;
+ }
+ putc(*p ,fout);
+ }
+ }
+ return OK;
+}
+
+/*
+ * substr(string, token) searches for token in string s
+ * returns pointer to token within string if found, NULL otherwise
+ */
+char *
+substr(s, t)
+register char *s,*t;
+{
+ register char *ss,*tt;
+ /* search for first char of token */
+ for (ss=s; *s; s++)
+ if (*s == *t)
+ /* compare token with substring */
+ for (ss=s,tt=t; ;) {
+ if (*tt == 0)
+ return s;
+ if (*ss++ != *tt++)
+ break;
+ }
+ return NULL;
+}
+
+
+/*
+ * If called as rb use YMODEM protocol, etc.
+ */
+chkinvok(s)
+char *s;
+{
+ register char *p;
+
+ p = s;
+ while (*p == '-')
+ s = ++p;
+ while (*p)
+ if (*p++ == '/')
+ s = p;
+ if (*s == 'v') {
+ Verbose=1; ++s;
+ }
+ Progname = s;
+ if (s[0]=='r' && s[1]=='z')
+ Batch = TRUE;
+ if (s[0]=='r' && s[1]=='c')
+ Crcflg = TRUE;
+ if (s[0]=='r' && s[1]=='b')
+ Batch = Nozmodem = TRUE;
+}
+
+/*
+ * Totalitarian Communist pathname processing
+ */
+checkpath(name)
+char *name;
+{
+ if (Restricted) {
+ if (fopen(name, "r") != NULL) {
+ canit();
+ fprintf(stderr, "\r\nrz: %s exists\n", name);
+ bibi(-1);
+ }
+ /* restrict pathnames to current tree or uucppublic */
+ if ( substr(name, "../")
+ || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
+ canit();
+ fprintf(stderr,"\r\nrz:\tSecurity Violation\r\n");
+ bibi(-1);
+ }
+ }
+}
+/*
+ * Ack a ZFIN packet, let byegones be byegones
+ */
+void
+ackbibi()
+{
+ register n;
+
+ vfile("ackbibi:");
+ Readnum = 1;
+ stohdr(0L);
+ for (n=3; --n>=0; ) {
+ purgeline();
+ zshhdr(4,ZFIN, Txhdr);
+ switch (readline(100)) {
+ case 'O':
+ readline(1); /* Discard 2nd 'O' */
+ vfile("ackbibi complete");
+ return;
+ case RCDO:
+ return;
+ case TIMEOUT:
+ default:
+ break;
+ }
+ }
+}
+
+
+/*
+ * Initialize for Zmodem receive attempt, try to activate Zmodem sender
+ * Handles ZSINIT frame
+ * Return ZFILE if Zmodem filename received, -1 on error,
+ * ZCOMPL if transaction finished, else 0
+ */
+tryz()
+{
+ register c, n;
+ register cmdzack1flg;
+
+ if (Nozmodem) /* Check for "rb" program name */
+ return 0;
+
+
+ for (n=15; --n>=0; ) {
+ /* Set buffer length (0) and capability flags */
+#ifdef SEGMENTS
+ stohdr(SEGMENTS*1024L);
+#else
+ stohdr(0L);
+#endif
+#ifdef CANBREAK
+ Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
+#else
+ Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
+#endif
+ if (Zctlesc)
+ Txhdr[ZF0] |= TESCCTL;
+ Txhdr[ZF0] |= CANRLE;
+ Txhdr[ZF1] = CANVHDR;
+ /* tryzhdrtype may == ZRINIT */
+ zshhdr(4,tryzhdrtype, Txhdr);
+ if (tryzhdrtype == ZSKIP) /* Don't skip too far */
+ tryzhdrtype = ZRINIT; /* CAF 8-21-87 */
+again:
+ switch (zgethdr(Rxhdr)) {
+ case ZRQINIT:
+ if (Rxhdr[ZF3] & 0x80)
+ Usevhdrs = 1; /* we can var header */
+ continue;
+ case ZEOF:
+ continue;
+ case TIMEOUT:
+ continue;
+ case ZFILE:
+ zconv = Rxhdr[ZF0];
+ zmanag = Rxhdr[ZF1];
+ ztrans = Rxhdr[ZF2];
+ if (Rxhdr[ZF3] & ZCANVHDR)
+ Usevhdrs = TRUE;
+ tryzhdrtype = ZRINIT;
+ c = zrdata(secbuf, 1024);
+ if (c == GOTCRCW)
+ return ZFILE;
+ zshhdr(4,ZNAK, Txhdr);
+ goto again;
+ case ZSINIT:
+ Zctlesc = TESCCTL & Rxhdr[ZF0];
+ if (zrdata(Attn, ZATTNLEN) == GOTCRCW) {
+ stohdr(1L);
+ zshhdr(4,ZACK, Txhdr);
+ goto again;
+ }
+ zshhdr(4,ZNAK, Txhdr);
+ goto again;
+ case ZFREECNT:
+ stohdr(getfree());
+ zshhdr(4,ZACK, Txhdr);
+ goto again;
+ case ZCOMMAND:
+#ifdef REGISTERED
+ /* Enabling this code without registering is theft */
+ if (Restricted) {
+ sprintf(endmsg, "ZCOMMAND Restricted.");
+ return ERROR;
+ }
+#endif
+ cmdzack1flg = Rxhdr[ZF0];
+ if (zrdata(secbuf, 1024) == GOTCRCW) {
+ void exec2();
+
+ if (cmdzack1flg & ZCACK1)
+ stohdr(0L);
+ else
+ stohdr((long)sys2(secbuf));
+ purgeline(); /* dump impatient questions */
+ do {
+ zshhdr(4,ZCOMPL, Txhdr);
+ }
+ while (++errors<20 && zgethdr(Rxhdr) != ZFIN);
+ ackbibi();
+ if (cmdzack1flg & ZCACK1)
+ exec2(secbuf);
+ return ZCOMPL;
+ }
+ zshhdr(4,ZNAK, Txhdr); goto again;
+ case ZCOMPL:
+ goto again;
+ default:
+ continue;
+ case ZFIN:
+ ackbibi(); return ZCOMPL;
+ case ZCAN:
+ return ERROR;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Receive 1 or more files with ZMODEM protocol
+ */
+rzfiles()
+{
+ register c;
+
+ for (;;) {
+ switch (c = rzfile()) {
+ case ZEOF:
+ case ZSKIP:
+ case ZFERR:
+ switch (tryz()) {
+ case ZCOMPL:
+ return OK;
+ default:
+ return ERROR;
+ case ZFILE:
+ break;
+ }
+ continue;
+ default:
+ return c;
+ case ERROR:
+ return ERROR;
+ }
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Receive a file with ZMODEM protocol
+ * Assumes file name frame is in secbuf
+ */
+rzfile()
+{
+ register c, n;
+
+ Eofseen=FALSE;
+ n = 20; rxbytes = 0l;
+
+ if (c = procheader(secbuf)) {
+ return (tryzhdrtype = c);
+ }
+
+ for (;;) {
+#ifdef SEGMENTS
+ chinseg = 0;
+#endif
+ stohdr(rxbytes);
+ zshhdr(4,ZRPOS, Txhdr);
+nxthdr:
+ switch (c = zgethdr(Rxhdr)) {
+ default:
+ vfile("rzfile: Wrong header %d", c);
+ if ( --n < 0) {
+ sprintf(endmsg, "rzfile: Wrong header %d", c);
+ return ERROR;
+ }
+ continue;
+ case ZCAN:
+ sprintf(endmsg, "Sender CANcelled");
+ return ERROR;
+ case ZNAK:
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ if ( --n < 0) {
+ sprintf(endmsg, "rzfile: got ZNAK", c);
+ return ERROR;
+ }
+ continue;
+ case TIMEOUT:
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ if ( --n < 0) {
+ sprintf(endmsg, "rzfile: TIMEOUT", c);
+ return ERROR;
+ }
+ continue;
+ case ZFILE:
+ zrdata(secbuf, 1024);
+ continue;
+ case ZEOF:
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ if (rclhdr(Rxhdr) != rxbytes) {
+ /*
+ * Ignore eof if it's at wrong place - force
+ * a timeout because the eof might have gone
+ * out before we sent our zrpos.
+ */
+ errors = 0; goto nxthdr;
+ }
+ if (closeit()) {
+ tryzhdrtype = ZFERR;
+ vfile("rzfile: closeit returned <> 0");
+ sprintf(endmsg,"Error closing file");
+ return ERROR;
+ }
+ vfile("rzfile: normal EOF");
+ return c;
+ case ERROR: /* Too much garbage in header search error */
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ if ( --n < 0) {
+ sprintf(endmsg, "Persistent CRC or other ERROR");
+ return ERROR;
+ }
+ zmputs(Attn);
+ continue;
+ case ZSKIP:
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ Modtime = 1;
+ closeit();
+ sprintf(endmsg, "Sender SKIPPED file");
+ return c;
+ case ZDATA:
+ if (rclhdr(Rxhdr) != rxbytes) {
+ if ( --n < 0) {
+ sprintf(endmsg,"Data has bad addr");
+ return ERROR;
+ }
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ zmputs(Attn); continue;
+ }
+moredata:
+ if (Verbose>1)
+ fprintf(stderr, "%7ld ZMODEM%s\n",
+ rxbytes, Crc32r?" CRC-32":"");
+#ifdef SEGMENTS
+ if (chinseg >= (1024 * SEGMENTS)) {
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+ }
+ switch (c = zrdata(secbuf+chinseg, 1024))
+#else
+ switch (c = zrdata(secbuf, 1024))
+#endif
+ {
+ case ZCAN:
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ sprintf(endmsg, "Sender CANcelled");
+ return ERROR;
+ case ERROR: /* CRC error */
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ if ( --n < 0) {
+ sprintf(endmsg, "Persistent CRC or other ERROR");
+ return ERROR;
+ }
+ zmputs(Attn);
+ continue;
+ case TIMEOUT:
+#ifdef SEGMENTS
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#endif
+ if ( --n < 0) {
+ sprintf(endmsg, "TIMEOUT");
+ return ERROR;
+ }
+ continue;
+ case GOTCRCW:
+ n = 20;
+#ifdef SEGMENTS
+ chinseg += Rxcount;
+ putsec(secbuf, chinseg);
+ chinseg = 0;
+#else
+ putsec(secbuf, Rxcount);
+#endif
+ rxbytes += Rxcount;
+ stohdr(rxbytes);
+ sendline(XON);
+ zshhdr(4,ZACK, Txhdr);
+ goto nxthdr;
+ case GOTCRCQ:
+ n = 20;
+#ifdef SEGMENTS
+ chinseg += Rxcount;
+#else
+ putsec(secbuf, Rxcount);
+#endif
+ rxbytes += Rxcount;
+ stohdr(rxbytes);
+ zshhdr(4,ZACK, Txhdr);
+ goto moredata;
+ case GOTCRCG:
+ n = 20;
+#ifdef SEGMENTS
+ chinseg += Rxcount;
+#else
+ putsec(secbuf, Rxcount);
+#endif
+ rxbytes += Rxcount;
+ goto moredata;
+ case GOTCRCE:
+ n = 20;
+#ifdef SEGMENTS
+ chinseg += Rxcount;
+#else
+ putsec(secbuf, Rxcount);
+#endif
+ rxbytes += Rxcount;
+ goto nxthdr;
+ }
+ }
+ }
+}
+
+
+/*
+ * Close the receive dataset, return OK or ERROR
+ */
+closeit()
+{
+ time_t time();
+
+ if (fout == stdout) {
+ fflush(stdout); fout = 0; return OK;
+ }
+ if (fclose(fout)==ERROR) {
+ fprintf(stderr, "File close ERROR\n");
+ return ERROR;
+ }
+ if (Modtime) {
+ timep[0] = time(NULL);
+ timep[1] = Modtime;
+ utime(Pathname, timep);
+ }
+ if (
+#ifdef POSIX
+ S_ISREG(Filemode)
+#else
+ (Filemode&S_IFMT) == S_IFREG
+#endif
+ )
+ chmod(Pathname, (unsigned short)(07777 & Filemode));
+ return OK;
+}
+
+
+/*
+ * Strip leading ! if present, do shell escape.
+ */
+sys2(s)
+register char *s;
+{
+ if (*s == '!')
+ ++s;
+ return system(s);
+}
+/*
+ * Strip leading ! if present, do exec.
+ */
+void
+exec2(s)
+register char *s;
+{
+ if (*s == '!')
+ ++s;
+ mode(0);
+ execl("/bin/sh", "sh", "-c", s);
+}
+
+/* End of rz.c */
diff --git a/zmodem/sz.c b/zmodem/sz.c
new file mode 100644
index 0000000..18b0cf1
--- /dev/null
+++ b/zmodem/sz.c
@@ -0,0 +1,1705 @@
+#define VERSION "3.48 01-27-98"
+#define PUBDIR "/usr/spool/uucppublic"
+
+/*
+ **************************************************************************
+ *
+ * sz.c By Chuck Forsberg, Omen Technology INC
+ * Copyright 1997 Omen Technology Inc All Rights Reserved
+ *
+ *********************************************************************
+ *********************************************************************
+ *
+ *
+ * This version implements numerous enhancements including ZMODEM
+ * Run Length Encoding and variable length headers. These
+ * features were not funded by the original Telenet development
+ * contract.
+ *
+ *
+ * This software may be freely used for educational (didactic
+ * only) purposes. "Didactic" means it is used as a study item
+ * in a course teaching the workings of computer protocols.
+ *
+ * This software may also be freely used to support file transfer
+ * operations to or from duly licensed Omen Technology products.
+ * This includes DSZ, GSZ, ZCOMM, Professional-YAM and PowerCom.
+ * Institutions desiring to use rz/sz this way should add the
+ * following to the sz compile line: -DCOMPL
+ * Programs based on stolen or public domain ZMODEM materials are
+ * not included. Use with other commercial or shareware programs
+ * (Crosstalk, Procomm, etc.) REQUIRES REGISTRATION.
+ *
+ *
+ * Any programs which incorporate part or all of this code must be
+ * provided in source form with this notice intact except by
+ * prior written permission from Omen Technology Incorporated.
+ * This includes compiled executables of this program.
+ *
+ * The .doc files and the file "mailer.rz" must also be included.
+ *
+ * Use of this software for commercial or administrative purposes
+ * except when exclusively limited to interfacing Omen Technology
+ * products requires license payment of $20.00 US per user
+ * (less in quantity, see mailer.rz). Use of this code by
+ * inclusion, decompilation, reverse engineering or any other means
+ * constitutes agreement to these conditions and acceptance of
+ * liability to license the materials and payment of reasonable
+ * legal costs necessary to enforce this license agreement.
+ *
+ *
+ * Omen Technology Inc
+ * Post Office Box 4681
+ * Portland OR 97208
+ *
+ * This code is made available in the hope it will be useful,
+ * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
+ * DAMAGES OF ANY KIND.
+ *
+ * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin
+ */
+
+char *Copyrsz = "Copyright 1997 Omen Technology Inc All Rights Reserved";
+
+char *substr();
+
+#define LOGFILE "/tmp/szlog"
+#define LOGFILE2 "szlog"
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <errno.h>
+extern int errno;
+#define STATIC
+
+#define PATHLEN 1000
+#define OK 0
+#define FALSE 0
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE 1
+#define ERROR (-1)
+/* Ward Christensen / CP/M parameters - Don't change these! */
+#define ENQ 005
+#define CAN ('X'&037)
+#define XOFF ('s'&037)
+#define XON ('q'&037)
+#define SOH 1
+#define STX 2
+#define EOT 4
+#define ACK 6
+#define NAK 025
+#define SYN 026
+#define CPMEOF 032
+#define WANTCRC 0103 /* send C not NAK to get crc not checksum */
+#define WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */
+#define TIMEOUT (-2)
+#define RCDO (-3)
+#define GCOUNT (-4)
+#define RETRYMAX 10
+
+
+#define HOWMANY 2
+STATIC int Zmodem=0; /* ZMODEM protocol requested by receiver */
+unsigned Baudrate = 9600; /* Default, set by first mode() call */
+STATIC unsigned Txwindow; /* Control the size of the transmitted window */
+STATIC unsigned Txwspac; /* Spacing between zcrcq requests */
+STATIC unsigned Txwcnt; /* Counter used to space ack requests */
+STATIC long Lrxpos; /* Receiver's last reported offset */
+STATIC int errors;
+char endmsg[80] = {0}; /* Possible message to display on exit */
+char Zsendmask[33]; /* Additional control chars to mask */
+
+#include "rbsb.c" /* most of the system dependent stuff here */
+
+#include "crctab.c"
+
+STATIC int Filesleft;
+STATIC long Totalleft;
+
+/*
+ * Attention string to be executed by receiver to interrupt streaming data
+ * when an error is detected. A pause (0336) may be needed before the
+ * ^C (03) or after it.
+ */
+#ifdef READCHECK
+STATIC char Myattn[] = { 0 };
+#else
+#ifdef USG
+STATIC char Myattn[] = { 03, 0336, 0 };
+#endif
+#endif
+
+FILE *in;
+
+STATIC int Canseek = 1; /* 1: Can seek 0: only rewind -1: neither (pipe) */
+
+#ifndef SMALL
+#ifndef TXBSIZE
+#define TXBSIZE 32768
+#endif
+
+#define TXBMASK (TXBSIZE-1)
+STATIC char Txb[TXBSIZE + 1024]; /* Circular buffer for file reads */
+STATIC char *txbuf = Txb; /* Pointer to current file segment */
+#else
+char txbuf[1024];
+#endif
+
+
+STATIC long vpos = 0; /* Number of bytes read from file */
+
+STATIC char Lastrx;
+STATIC char Crcflg;
+STATIC int Modem2=0; /* XMODEM Protocol - don't send pathnames */
+STATIC int Restricted=0; /* restricted; no /.. or ../ in filenames */
+STATIC int Fullname=0; /* transmit full pathname */
+STATIC int Unlinkafter=0; /* Unlink file after it is sent */
+STATIC int Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */
+STATIC int firstsec;
+STATIC int errcnt=0; /* number of files unreadable */
+STATIC int Skipbitch=0;
+STATIC int Skipcount=0; /* Count of skipped files */
+STATIC int blklen=128; /* length of transmitted records */
+STATIC int Optiong; /* Let it rip no wait for sector ACK's */
+STATIC int Eofseen; /* EOF seen on input set by zfilbuf */
+STATIC int BEofseen; /* EOF seen on input set by fooseek */
+STATIC int Totsecs; /* total number of sectors this file */
+STATIC int Filcnt=0; /* count of number of files opened */
+STATIC unsigned Rxbuflen=16384; /* Receiver's max buffer length */
+STATIC long Tframlen = 0; /* Override for tx frame length */
+STATIC int blkopt=0; /* Override value for zmodem blklen */
+STATIC int Rxflags = 0;
+STATIC long bytcnt, maxbytcnt;
+STATIC int Wantfcs32 = TRUE; /* want to send 32 bit FCS */
+STATIC char Lzconv; /* Local ZMODEM file conversion request */
+STATIC char Lzmanag; /* Local ZMODEM file management request */
+STATIC int Lskipnocor;
+STATIC char Lztrans;
+STATIC int Command; /* Send a command, then exit. */
+STATIC char *Cmdstr; /* Pointer to the command string */
+STATIC int Cmdack1; /* Rx ACKs command, then do it */
+STATIC int Exitcode;
+STATIC int Test; /* 1= Force receiver to send Attn, etc with qbf. */
+ /* 2= Character transparency test */
+STATIC char *qbf=
+ "The quick brown fox jumped over the lazy dog's back 1234567890\r\n";
+STATIC long Lastsync; /* Last offset to which we got a ZRPOS */
+STATIC int Beenhereb4; /* How many times we've been ZRPOS'd here */
+STATIC int Ksendstr; /* 1= Send esc-?-3-4-l to remote kermit */
+STATIC char *ksendbuf = "\033[?34l";
+
+STATIC jmp_buf intrjmp; /* For the interrupt on RX CAN */
+
+
+/* called by signal interrupt or terminate to clean things up */
+void
+bibi(n)
+{
+ canit(); fflush(stdout); mode(0);
+ fprintf(stderr, "sz: caught signal %d; exiting\n", n);
+ if (n == SIGQUIT)
+ abort();
+ if (n == 99)
+ fprintf(stderr, "mode(2) in rbsb.c not implemented!!\n");
+ exit(3);
+}
+
+/* Called when ZMODEM gets an interrupt (^X) */
+void
+onintr(c)
+{
+ signal(SIGINT, SIG_IGN);
+ longjmp(intrjmp, -1);
+}
+
+STATIC int Zctlesc; /* Encode control characters */
+STATIC int Nozmodem = 0; /* If invoked as "sb" */
+STATIC char *Progname = "sz";
+STATIC int Zrwindow = 1400; /* RX window size (controls garbage count) */
+
+
+/*
+ * Log an error
+ */
+void
+zperr1(s,p,u)
+char *s, *p, *u;
+{
+ if (Verbose <= 0)
+ return;
+ fprintf(stderr, "Retry %d: ", errors);
+ fprintf(stderr, s);
+ fprintf(stderr, "\n");
+}
+
+void
+zperr2(s,p,u)
+char *s, *p, *u;
+{
+ if (Verbose <= 0)
+ return;
+ fprintf(stderr, "Retry %d: ", errors);
+ fprintf(stderr, s, p);
+ fprintf(stderr, "\n");
+}
+
+void
+zperr3(s,p,u)
+char *s, *p, *u;
+{
+ if (Verbose <= 0)
+ return;
+ fprintf(stderr, "Retry %d: ", errors);
+ fprintf(stderr, s, p, u);
+ fprintf(stderr, "\n");
+}
+
+
+#include "zm.c"
+#include "zmr.c"
+
+main(argc, argv)
+char *argv[];
+{
+ register char *cp;
+ register npats;
+ char **patts;
+
+ if ((cp = getenv("ZNULLS")) && *cp)
+ Znulls = atoi(cp);
+ if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
+ Restricted=TRUE;
+ inittty();
+ chkinvok(argv[0]);
+
+ Rxtimeout = 600;
+ npats=0;
+ if (argc<2)
+ usage();
+ while (--argc) {
+ cp = *++argv;
+ if (*cp++ == '-' && *cp) {
+ while ( *cp) {
+ if (isdigit(*cp)) {
+ ++cp; continue;
+ }
+ switch(*cp++) {
+ case '\\':
+ *cp = toupper(*cp); continue;
+ case '+':
+ Lzmanag = ZMAPND; break;
+ case 'a':
+ if (Nozmodem || Modem2)
+ usage();
+ Lzconv = ZCNL; break;
+ case 'b':
+ Lzconv = ZCBIN; break;
+ case 'c':
+ Lzmanag = ZMCHNG; break;
+ case 'd':
+ ++Dottoslash;
+ /* **** FALL THROUGH TO **** */
+ case 'f':
+ Fullname=TRUE; break;
+ case 'g' :
+ Ksendstr = TRUE; break;
+ case 'e':
+ Zctlesc = 1; break;
+ case 'k':
+ blklen=1024; break;
+ case 'L':
+ if (isdigit(*cp))
+ blkopt = atoi(cp);
+ else {
+ if (--argc < 1)
+ usage();
+ blkopt = atoi(*++argv);
+ }
+ if (blkopt<24 || blkopt>1024)
+ usage();
+ break;
+ case 'l':
+ if (isdigit(*cp))
+ Tframlen = atol(cp);
+ else {
+ if (--argc < 1)
+ usage();
+ Tframlen = atol(*++argv);
+ }
+ if (Tframlen<32 || Tframlen>65535L)
+ usage();
+ break;
+ case 'N':
+ Lzmanag = ZMNEWL; break;
+ case 'n':
+ Lzmanag = ZMNEW; break;
+ case 'o':
+ Wantfcs32 = FALSE; break;
+ case 'p':
+ Lzmanag = ZMPROT; break;
+ case 'r':
+ if (Lzconv == ZCRESUM)
+ Lzmanag = (Lzmanag & ZMMASK) | ZMCRC;
+ Lzconv = ZCRESUM; break;
+ case 'T':
+ chartest(1); chartest(2);
+ mode(0); exit(0);
+ case 'u':
+ ++Unlinkafter; break;
+ case 'v':
+ ++Verbose; break;
+ case 'w':
+ if (isdigit(*cp))
+ Txwindow = atoi(cp);
+ else {
+ if (--argc < 1)
+ usage();
+ Txwindow = atoi(*++argv);
+ }
+ if (Txwindow < 256)
+ Txwindow = 256;
+ Txwindow = (Txwindow/64) * 64;
+ Txwspac = Txwindow/4;
+ if (blkopt > Txwspac
+ || (!blkopt && Txwspac < 1024))
+ blkopt = Txwspac;
+ break;
+ case 'x':
+ Skipbitch = 1; break;
+ case 'Y':
+ Lskipnocor = TRUE;
+ /* **** FALLL THROUGH TO **** */
+ case 'y':
+ Lzmanag = ZMCLOB; break;
+ case 'Z':
+ case 'z':
+ Lztrans = ZTRLE; break;
+ default:
+ usage();
+ }
+ }
+ }
+ else if (Command) {
+ if (argc != 1) {
+ usage();
+ }
+ Cmdstr = *argv;
+ }
+ else if ( !npats && argc>0) {
+ if (argv[0][0]) {
+ npats=argc;
+ patts=argv;
+ }
+ }
+ }
+ if (npats < 1 && !Command && !Test)
+ usage();
+ if (Verbose) {
+ if (freopen(LOGFILE, "a", stderr)==NULL)
+ if (freopen(LOGFILE2, "a", stderr)==NULL) {
+ printf("Can't open log file!");
+ exit(2);
+ }
+ setbuf(stderr, NULL);
+ }
+ vfile("%s %s for %s tty=%s\n", Progname, VERSION, OS, Nametty);
+
+ mode(3);
+
+ if (signal(SIGINT, bibi) == SIG_IGN) {
+ signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
+ } else {
+ signal(SIGINT, bibi); signal(SIGKILL, bibi);
+ }
+#ifdef SIGQUIT
+ signal(SIGQUIT, SIG_IGN);
+#endif
+#ifdef SIGTERM
+ signal(SIGTERM, bibi);
+#endif
+
+ countem(npats, patts);
+
+ if (!Modem2 && !Nozmodem) {
+ if (Ksendstr)
+ printf(ksendbuf);
+ printf("rz\r"); fflush(stdout);
+ stohdr(0x80L); /* Show we can var header */
+ if (Command)
+ Txhdr[ZF0] = ZCOMMAND;
+ zshhdr(4, ZRQINIT, Txhdr);
+ }
+ fflush(stdout);
+
+
+ if (Command) {
+ if (getzrxinit()) {
+ Exitcode=1; canit();
+ }
+ else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
+ Exitcode=1; canit();
+ }
+ } else if (wcsend(npats, patts)==ERROR) {
+ Exitcode=1;
+ canit();
+ sleep(20);
+ }
+ if (Skipcount) {
+ printf("%d file(s) skipped by receiver request\r\n", Skipcount);
+ if (Verbose) fprintf(stderr,
+ "%d file(s) skipped by receiver request\r\n", Skipcount);
+ }
+ if (endmsg[0]) {
+ printf("\r\n%s: %s\r\n", Progname, endmsg);
+ if (Verbose)
+ fprintf(stderr, "%s\r\n", endmsg);
+ }
+ printf("%s %s finished.\r\n", Progname, VERSION);
+ fflush(stdout);
+ mode(0);
+ if(errcnt || Exitcode)
+ exit(1);
+
+#ifndef REGISTERED
+ /* Removing or disabling this code without registering is theft */
+ if (!Usevhdrs) {
+ printf("\n\n\n**** UNREGISTERED COPY *****\r\n");
+ printf("\n\n\nPlease read the License Agreement in sz.doc\n");
+ fflush(stdout);
+ sleep(10);
+ }
+#endif
+#ifdef SYLIXOS
+ sleep(2);
+#endif
+ exit(0);
+ /*NOTREACHED*/
+}
+
+/* Say "bibi" to the receiver, try to do it cleanly */
+void
+saybibi()
+{
+ for (;;) {
+ stohdr(0L); /* CAF Was zsbhdr - minor change */
+ zshhdr(4, ZFIN, Txhdr); /* to make debugging easier */
+ switch (zgethdr(Rxhdr)) {
+ case ZFIN:
+ sendline('O'); sendline('O'); flushmo();
+ case ZCAN:
+ case TIMEOUT:
+ return;
+ }
+ }
+}
+
+wcsend(argc, argp)
+char *argp[];
+{
+ register n;
+
+ Crcflg=FALSE;
+ firstsec=TRUE;
+ bytcnt = maxbytcnt = -1;
+ vfile("wcsend: argc=%d", argc);
+ if (Nozmodem) {
+ printf("Start your local YMODEM receive. ");
+ fflush(stdout);
+ }
+ for (n=0; n<argc; ++n) {
+ Totsecs = 0;
+ if (wcs(argp[n])==ERROR)
+ return ERROR;
+ }
+ Totsecs = 0;
+ if (Filcnt==0) { /* bitch if we couldn't open ANY files */
+ if (!Nozmodem && !Modem2) {
+ Command = TRUE;
+ Cmdstr = "echo \"sz: Can't open any requested files\"";
+ if (getnak()) {
+ Exitcode=1; canit();
+ }
+ if (!Zmodem)
+ canit();
+ else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
+ Exitcode=1; canit();
+ }
+ Exitcode = 1; return OK;
+ }
+ canit();
+ sprintf(endmsg, "Can't open any requested files");
+ return ERROR;
+ }
+ if (Zmodem)
+ saybibi();
+ else if ( !Modem2)
+ wctxpn("");
+ return OK;
+}
+
+wcs(oname)
+char *oname;
+{
+ register c;
+ register char *p;
+ struct stat f;
+ char name[PATHLEN];
+
+ strcpy(name, oname);
+ vfile("wcs: name=%s", name);
+
+ if (Restricted) {
+ /* restrict pathnames to current tree or uucppublic */
+ if ( substr(name, "../")
+ || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
+ canit(); sprintf(endmsg,"Security Violation");
+ return ERROR;
+ }
+ }
+
+#ifdef TXBSIZE
+ if ( !strcmp(name, "-")) {
+ if ((p = getenv("ONAME")) && *p)
+ strcpy(name, p);
+ else
+ sprintf(name, "s%d.sz", getpid());
+ in = stdin;
+ }
+ else
+#endif
+ in=fopen(name, "r");
+
+ if (in==NULL) {
+ ++errcnt;
+ return OK; /* pass over it, there may be others */
+ }
+ BEofseen = Eofseen = 0; vpos = 0;
+
+ /* Check for directory */
+ fstat(fileno(in), &f);
+#ifdef POSIX
+ if (S_ISDIR(f.st_mode))
+#else
+ c = f.st_mode & S_IFMT;
+ if (c == S_IFDIR || c == S_IFBLK)
+#endif
+ {
+ fclose(in);
+ return OK;
+ }
+
+ ++Filcnt;
+ switch (wctxpn(name)) {
+ case ZSKIP:
+ case ZFERR:
+ return OK;
+ case OK:
+ break;
+ default:
+ return ERROR;
+ }
+ if (!Zmodem && wctx(f.st_size))
+ return ERROR;
+
+ if (Unlinkafter)
+ unlink(oname);
+
+ return 0;
+}
+
+/*
+ * generate and transmit pathname block consisting of
+ * pathname (null terminated),
+ * file length, mode time and file mode in octal
+ * as provided by the Unix fstat call.
+ * N.B.: modifies the passed name, may extend it!
+ */
+wctxpn(name)
+char *name;
+{
+ register char *p, *q;
+ char name2[PATHLEN];
+ struct stat f;
+
+ vfile("wctxpn: %s", name);
+ if (Modem2) {
+ if (*name && fstat(fileno(in), &f)!= -1) {
+ fprintf(stderr, "Sending %s, %ld XMODEM blocks. ",
+ name, (127+f.st_size)>>7);
+ }
+ printf("Start your local XMODEM receive. ");
+ fflush(stdout);
+ return OK;
+ }
+ zperr2("Awaiting pathname nak for %s", *name?name:"<END>");
+ if ( !Zmodem)
+ if (getnak())
+ return ERROR;
+
+ q = (char *) 0;
+ if (Dottoslash) { /* change . to . */
+ for (p=name; *p; ++p) {
+ if (*p == '/')
+ q = p;
+ else if (*p == '.')
+ *(q=p) = '/';
+ }
+ if (q && strlen(++q) > 8) { /* If name>8 chars */
+ q += 8; /* make it .ext */
+ strcpy(name2, q); /* save excess of name */
+ *q = '.';
+ strcpy(++q, name2); /* add it back */
+ }
+ }
+
+ for (p=name, q=txbuf ; *p; )
+ if ((*q++ = *p++) == '/' && !Fullname)
+ q = txbuf;
+ *q++ = 0;
+ p=q;
+ while (q < (txbuf + 1024))
+ *q++ = 0;
+ if (*name) {
+ if (fstat(fileno(in), &f)!= -1)
+ sprintf(p, "%lu %lo %o 3 %d %ld", f.st_size, f.st_mtime,
+ f.st_mode, Filesleft, Totalleft);
+ Totalleft -= f.st_size;
+ }
+ if (--Filesleft <= 0)
+ Filesleft = Totalleft = 0;
+ if (Totalleft < 0)
+ Totalleft = 0;
+
+ /* force 1k blocks if name won't fit in 128 byte block */
+ if (txbuf[125])
+ blklen=1024;
+ else { /* A little goodie for IMP/KMD */
+ txbuf[127] = (f.st_size + 127) >>7;
+ txbuf[126] = (f.st_size + 127) >>15;
+ }
+ vfile("wctxpn: %s", p);
+ if (Zmodem)
+ return zsendfile(txbuf, 1+strlen(p)+(p-txbuf));
+ if (wcputsec(txbuf, 0, 128)==ERROR)
+ return ERROR;
+ return OK;
+}
+
+getnak()
+{
+ register firstch;
+
+ Lastrx = 0;
+ for (;;) {
+ switch (firstch = readline(800)) {
+ case ZPAD:
+ if (getzrxinit())
+ return ERROR;
+ return FALSE;
+ case TIMEOUT:
+ sprintf(endmsg, "Timeout waiting for ZRINIT");
+ return TRUE;
+ case WANTG:
+#ifdef MODE2OK
+ mode(2); /* Set cbreak, XON/XOFF, etc. */
+#endif
+ Optiong = TRUE;
+ blklen=1024;
+ case WANTCRC:
+ Crcflg = TRUE;
+ case NAK:
+ return FALSE;
+ case CAN:
+ if ((firstch = readline(20)) == CAN && Lastrx == CAN) {
+ sprintf(endmsg, "Got CAN waiting to send file");
+ return TRUE;
+ }
+ default:
+ break;
+ }
+ Lastrx = firstch;
+ }
+}
+
+
+wctx(flen)
+long flen;
+{
+ register int thisblklen;
+ register int sectnum, attempts, firstch;
+ long charssent;
+
+ charssent = 0; firstsec=TRUE; thisblklen = blklen;
+ vfile("wctx:file length=%ld", flen);
+
+ while ((firstch=readline(Rxtimeout))!=NAK && firstch != WANTCRC
+ && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN)
+ ;
+ if (firstch==CAN) {
+ zperr1("Receiver CANcelled");
+ return ERROR;
+ }
+ if (firstch==WANTCRC)
+ Crcflg=TRUE;
+ if (firstch==WANTG)
+ Crcflg=TRUE;
+ sectnum=0;
+ for (;;) {
+ if (flen <= (charssent + 896L))
+ thisblklen = 128;
+ if ( !filbuf(txbuf, thisblklen))
+ break;
+ if (wcputsec(txbuf, ++sectnum, thisblklen)==ERROR)
+ return ERROR;
+ charssent += thisblklen;
+ }
+ fclose(in);
+ attempts=0;
+ do {
+ purgeline();
+ sendline(EOT);
+ flushmo();
+ ++attempts;
+ }
+ while ((firstch=(readline(Rxtimeout)) != ACK) && attempts < RETRYMAX);
+ if (attempts == RETRYMAX) {
+ zperr1("No ACK on EOT");
+ return ERROR;
+ }
+ else
+ return OK;
+}
+
+wcputsec(buf, sectnum, cseclen)
+char *buf;
+int sectnum;
+int cseclen; /* data length of this sector to send */
+{
+ register checksum, wcj;
+ register char *cp;
+ unsigned oldcrc;
+ int firstch;
+ int attempts;
+
+ firstch=0; /* part of logic to detect CAN CAN */
+
+ if (Verbose>1)
+ fprintf(stderr, "Sector %3d %2dk\n", Totsecs, Totsecs/8 );
+ for (attempts=0; attempts <= RETRYMAX; attempts++) {
+ Lastrx= firstch;
+ sendline(cseclen==1024?STX:SOH);
+ sendline(sectnum);
+ sendline(-sectnum -1);
+ oldcrc=checksum=0;
+ for (wcj=cseclen,cp=buf; --wcj>=0; ) {
+ sendline(*cp);
+ oldcrc=updcrc((0377& *cp), oldcrc);
+ checksum += *cp++;
+ }
+ if (Crcflg) {
+ oldcrc=updcrc(0,updcrc(0,oldcrc));
+ sendline((int)oldcrc>>8);
+ sendline((int)oldcrc);
+ }
+ else
+ sendline(checksum);
+ flushmo();
+
+ if (Optiong) {
+ firstsec = FALSE; return OK;
+ }
+ firstch = readline(Rxtimeout);
+gotnak:
+ switch (firstch) {
+ case CAN:
+ if(Lastrx == CAN) {
+cancan:
+ zperr1("Cancelled"); return ERROR;
+ }
+ break;
+ case TIMEOUT:
+ zperr1("Timeout on sector ACK"); continue;
+ case WANTCRC:
+ if (firstsec)
+ Crcflg = TRUE;
+ case NAK:
+ zperr1("NAK on sector"); continue;
+ case ACK:
+ firstsec=FALSE;
+ Totsecs += (cseclen>>7);
+ return OK;
+ case ERROR:
+ zperr1("Got burst for sector ACK"); break;
+ default:
+ zperr2("Got %02x for sector ACK", firstch); break;
+ }
+ for (;;) {
+ Lastrx = firstch;
+ if ((firstch = readline(Rxtimeout)) == TIMEOUT)
+ break;
+ if (firstch == NAK || firstch == WANTCRC)
+ goto gotnak;
+ if (firstch == CAN && Lastrx == CAN)
+ goto cancan;
+ }
+ }
+ zperr1("Retry Count Exceeded");
+ return ERROR;
+}
+
+/* fill buf with count chars padding with ^Z for CPM */
+filbuf(buf, count)
+register char *buf;
+{
+ register m;
+
+ m = read(fileno(in), buf, count);
+ if (m <= 0)
+ return 0;
+ while (m < count)
+ buf[m++] = 032;
+ return count;
+}
+
+/* Fill buffer with blklen chars */
+zfilbuf()
+{
+ int n;
+
+#ifdef TXBSIZE
+ vfile("zfilbuf: bytcnt =%lu vpos=%lu blklen=%d", bytcnt, vpos, blklen);
+ /* We assume request is within buffer, or just beyond */
+ txbuf = Txb + (bytcnt & TXBMASK);
+ if (vpos <= bytcnt) {
+ n = fread(txbuf, 1, blklen, in);
+
+ vpos += n;
+ if (n < blklen)
+ Eofseen = 1;
+ vfile("zfilbuf: n=%d vpos=%lu Eofseen=%d", n, vpos, Eofseen);
+ return n;
+ }
+ if (vpos >= (bytcnt+blklen))
+ return blklen;
+ /* May be a short block if crash recovery etc. */
+ Eofseen = BEofseen;
+ return (vpos - bytcnt);
+#else
+ n = fread(txbuf, 1, blklen, in);
+ if (n < blklen) {
+ Eofseen = 1;
+ vfile("zfilbuf: n=%d vpos=%lu Eofseen=%d", n, vpos, Eofseen);
+ }
+ return n;
+#endif
+}
+
+#ifdef TXBSIZE
+/* Replacement for brain damaged fseek function. Returns 0==success */
+fooseek(fptr, pos, whence)
+FILE *fptr;
+long pos;
+{
+ long m, n;
+
+ vfile("fooseek: pos =%lu vpos=%lu Canseek=%d", pos, vpos, Canseek);
+ /* Seek offset < current buffer */
+ if (pos < (vpos -TXBSIZE +1024)) {
+ BEofseen = 0;
+ if (Canseek > 0) {
+ vpos = pos & ~TXBMASK;
+ if (vpos > pos)
+ vpos -= TXBSIZE;
+ vfile("seek to vpos=%ld", vpos);
+ if (fseek(fptr, vpos, 0))
+ return 1;
+ }
+ else if (Canseek == 0) {
+ vfile("seek to 00000");
+ if (fseek(fptr, vpos = 0L, 0))
+ return 1;
+ } else
+ return 1;
+ while (vpos < pos) {
+ n = fread(Txb, (size_t)1, (size_t)TXBSIZE, fptr);
+ vpos += n;
+ vfile("n=%d vpos=%ld", n, vpos);
+ if (n < TXBSIZE) {
+ BEofseen = 1;
+ break;
+ }
+ }
+ vfile("vpos=%ld", vpos);
+ return 0;
+ }
+ /* Seek offset > current buffer (Crash Recovery, etc.) */
+ if (pos > vpos) {
+ if (Canseek)
+ if (fseek(fptr, vpos = (pos & ~TXBMASK), 0))
+ return 1;
+ while (vpos <= pos) {
+ txbuf = Txb + (vpos & TXBMASK);
+ m = TXBSIZE - (vpos & TXBMASK);
+ vfile("m=%ld vpos=%ld", m,vpos);
+ n = fread(txbuf, (size_t)1, (size_t)m, fptr);
+ vfile("n=%ld vpos=%ld", n,vpos);
+ vpos += n;
+ vfile("bo=%d m=%ld vpos=%ld", txbuf-Txb,m,vpos);
+ if (n < m) {
+ BEofseen = 1;
+ break;
+ }
+ }
+ return 0;
+ }
+ /* Seek offset is within current buffer */
+ vfile("within buffer: vpos=%ld", vpos);
+ return 0;
+}
+#define fseek fooseek
+#endif
+
+
+/*
+ * substr(string, token) searches for token in string s
+ * returns pointer to token within string if found, NULL otherwise
+ */
+char *
+substr(s, t)
+register char *s,*t;
+{
+ register char *ss,*tt;
+ /* search for first char of token */
+ for (ss=s; *s; s++)
+ if (*s == *t)
+ /* compare token with substring */
+ for (ss=s,tt=t; ;) {
+ if (*tt == 0)
+ return s;
+ if (*ss++ != *tt++)
+ break;
+ }
+ return NULL;
+}
+
+char *usinfo[] = {
+ "Send Files and Commands with ZMODEM/YMODEM/XMODEM Protocol\n",
+ "Usage: sz [-+abcdefgklLnNuvwxyYZ] [-] file ...",
+ "\t zcommand [-egv] COMMAND",
+ "\t zcommandi [-egv] COMMAND",
+ "\t sb [-adfkuv] [-] file ...",
+ "\t sx [-akuv] [-] file",
+ ""
+};
+
+usage()
+{
+ char **pp;
+
+ fprintf(stderr, "\n%s %s for %s by Chuck Forsberg, Omen Technology INC\n",
+ Progname, VERSION, OS);
+ fprintf(stderr, "\t\t\042The High Reliability Software\042\n");
+ for (pp=usinfo; **pp; ++pp)
+ fprintf(stderr, "%s\n", *pp);
+ fprintf(stderr,"\nCopyright (c) 1997 Omen Technology INC All Rights Reserved\n");
+ fprintf(stderr,
+ "See sz.doc and README for option descriptions and licensing information.\n\n");
+ fprintf(stderr,
+ "This program is designed to talk to terminal programs,\nnot to be called by one.\n");
+ exit(3);
+}
+
+/*
+ * Get the receiver's init parameters
+ */
+getzrxinit()
+{
+ register n;
+ struct stat f;
+
+ for (n=10; --n>=0; ) {
+
+ switch (zgethdr(Rxhdr)) {
+ case ZCHALLENGE: /* Echo receiver's challenge numbr */
+ stohdr(Rxpos);
+ zshhdr(4, ZACK, Txhdr);
+ continue;
+ case ZCOMMAND: /* They didn't see out ZRQINIT */
+ stohdr(0L);
+ zshhdr(4, ZRQINIT, Txhdr);
+ continue;
+ case ZRINIT:
+ if (Rxhlen==4 && (Rxhdr[ZF1] & ZRQNVH)) {
+ stohdr(0x80L); /* Show we can var header */
+ zshhdr(4, ZRQINIT, Txhdr);
+ continue;
+ }
+ Rxflags = 0377 & Rxhdr[ZF0];
+#if COMPL
+ Usevhdrs = 1;
+#else
+ Usevhdrs = Rxhdr[ZF1] & CANVHDR;
+#endif
+ Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
+ Zctlesc |= Rxflags & TESCCTL;
+ if (Rxhdr[ZF1] & ZRRQQQ) /* Escape ctrls */
+ initzsendmsk(Rxhdr+ZRPXQQ);
+ Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
+ if ( !(Rxflags & CANFDX))
+ Txwindow = 0;
+ vfile("Rxbuflen=%d Tframlen=%ld", Rxbuflen, Tframlen);
+ signal(SIGINT, SIG_IGN);
+#ifdef MODE2OK
+ mode(2); /* Set cbreak, XON/XOFF, etc. */
+#endif
+
+#ifndef READCHECK
+#ifndef USG
+ /* Use 1024 byte frames if no sample/interrupt */
+ if (Rxbuflen < 32 || Rxbuflen > 1024) {
+ Rxbuflen = 1024;
+ vfile("Rxbuflen=%d", Rxbuflen);
+ }
+#endif
+#endif
+
+ /* Override to force shorter frame length */
+ if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
+ Rxbuflen = Tframlen;
+ if ( !Rxbuflen && (Tframlen>=32))
+ Rxbuflen = Tframlen;
+ vfile("Rxbuflen=%d", Rxbuflen);
+
+
+ /*
+ * If input is not a regular file, force ACK's to
+ * prevent running beyond the buffer limits
+ */
+ if ( !Command) {
+ fstat(fileno(in), &f);
+ if (
+#ifdef POSIX
+ !S_ISREG(f.st_mode)
+#else
+ (f.st_mode & S_IFMT) != S_IFREG
+#endif
+ ) {
+ Canseek = -1;
+ f.st_size = 0;
+ f.st_mtime = 0;
+#ifdef TXBSIZE
+ Txwindow = TXBSIZE - 1024;
+ Txwspac = TXBSIZE/4;
+#else
+ sprintf(endmsg, "Can't seek on input");
+ return ERROR;
+#endif
+ }
+ }
+
+ /* Set initial subpacket length */
+ if (blklen < 1024) { /* Command line override? */
+ if (Baudrate > 300)
+ blklen = 256;
+ if (Baudrate > 1200)
+ blklen = 512;
+ if (Baudrate > 2400)
+ blklen = 1024;
+ if (Baudrate < 300)
+ blklen = 1024;
+ }
+ if (Rxbuflen && blklen>Rxbuflen)
+ blklen = Rxbuflen;
+ if (blkopt && blklen > blkopt)
+ blklen = blkopt;
+ vfile("Rxbuflen=%d blklen=%d", Rxbuflen, blklen);
+ vfile("Txwindow = %u Txwspac = %d", Txwindow, Txwspac);
+
+
+ if (Lztrans == ZTRLE && (Rxflags & CANRLE))
+ Txfcs32 = 2;
+ else
+ Lztrans = 0;
+
+ return (sendzsinit());
+ case ZCAN:
+ case TIMEOUT:
+ return ERROR;
+ case ZRQINIT:
+ if (Rxhdr[ZF0] == ZCOMMAND)
+ continue;
+ default:
+ zshhdr(4, ZNAK, Txhdr);
+ continue;
+ }
+ }
+ return ERROR;
+}
+
+/* Send send-init information */
+sendzsinit()
+{
+ register c;
+
+ if (Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
+ return OK;
+ errors = 0;
+ for (;;) {
+ stohdr(0L);
+#ifdef ALTCANOFF
+ Txhdr[ALTCOFF] = ALTCANOFF;
+#endif
+ if (Zctlesc) {
+ Txhdr[ZF0] |= TESCCTL; zshhdr(4, ZSINIT, Txhdr);
+ }
+ else
+ zsbhdr(4, ZSINIT, Txhdr);
+ zsdata(Myattn, ZATTNLEN, ZCRCW);
+ c = zgethdr(Rxhdr);
+ switch (c) {
+ case ZCAN:
+ return ERROR;
+ case ZACK:
+ return OK;
+ default:
+ if (++errors > 19)
+ return ERROR;
+ continue;
+ }
+ }
+}
+
+/* Send file name and related info */
+zsendfile(buf, blen)
+char *buf;
+{
+ register c;
+ register unsigned long crc;
+ int m, n, i;
+ char *p;
+ long lastcrcrq = -1;
+ long lastcrcof = -1;
+ long l;
+
+ for (errors=0; ++errors<11;) {
+ Txhdr[ZF0] = Lzconv; /* file conversion request */
+ Txhdr[ZF1] = Lzmanag; /* file management request */
+ if (Lskipnocor)
+ Txhdr[ZF1] |= ZMSKNOLOC;
+ Txhdr[ZF2] = Lztrans; /* file transport request */
+ Txhdr[ZF3] = 0;
+ zsbhdr(4, ZFILE, Txhdr);
+ zsdata(buf, blen, ZCRCW);
+again:
+ c = zgethdr(Rxhdr);
+ switch (c) {
+ case ZRINIT:
+ while ((c = readline(50)) > 0)
+ if (c == ZPAD) {
+ goto again;
+ }
+ continue;
+ case ZCAN:
+ case TIMEOUT:
+ case ZABORT:
+ case ZFIN:
+ sprintf(endmsg, "Got %s on pathname", frametypes[c+FTOFFSET]);
+ return ERROR;
+ default:
+ sprintf(endmsg, "Got %d frame type on pathname", c);
+ continue;
+ case ERROR:
+ case ZNAK:
+ continue;
+ case ZCRC:
+ l = Rxhdr[9] & 0377;
+ l = (l<<8) + (Rxhdr[8] & 0377);
+ l = (l<<8) + (Rxhdr[7] & 0377);
+ l = (l<<8) + (Rxhdr[6] & 0377);
+ if (Rxpos != lastcrcrq || l != lastcrcof) {
+ lastcrcrq = Rxpos;
+ crc = 0xFFFFFFFFL;
+ if (Canseek >= 0) {
+ fseek(in, bytcnt = l, 0); i = 0;
+ vfile("CRC32 on %ld bytes", Rxpos);
+ do {
+ /* No rx timeouts! */
+ if (--i < 0) {
+ i = 32768L/blklen;
+ sendline(SYN);
+ flushmoc();
+ }
+ bytcnt += m = n = zfilbuf();
+ if (bytcnt > maxbytcnt)
+ maxbytcnt = bytcnt;
+ for (p = txbuf; --m >= 0; ++p) {
+ c = *p & 0377;
+ crc = UPDC32(c, crc);
+ }
+#ifdef DEBUG
+ vfile("bytcnt=%ld crc=%08lX",
+ bytcnt, crc);
+#endif
+ } while (n && bytcnt < lastcrcrq);
+ crc = ~crc;
+#ifndef MMIO
+ clearerr(in); /* Clear possible EOF */
+#endif
+ }
+ }
+ stohdr(crc);
+ zsbhdr(4, ZCRC, Txhdr);
+ goto again;
+ case ZFERR:
+ case ZSKIP:
+ ++Skipcount;
+ if (Skipbitch)
+ ++errcnt;
+ fclose(in); return c;
+ case ZRPOS:
+ /*
+ * Suppress zcrcw request otherwise triggered by
+ * lastyunc==bytcnt
+ */
+ if (fseek(in, Rxpos, 0))
+ return ERROR;
+ Lastsync = (maxbytcnt = bytcnt = Txpos = Lrxpos = Rxpos) -1;
+ return zsendfdata();
+ }
+ }
+ fclose(in); return ERROR;
+}
+
+/* Send the data in the file */
+zsendfdata()
+{
+ register c, e, n;
+ register newcnt;
+ register long tcount = 0;
+ int junkcount; /* Counts garbage chars received by TX */
+ static int tleft = 6; /* Counter for test mode */
+
+ junkcount = 0;
+ Beenhereb4 = 0;
+somemore:
+ if (setjmp(intrjmp)) {
+waitack:
+ junkcount = 0;
+ c = getinsync(0);
+gotack:
+ switch (c) {
+ default:
+ case ZCAN:
+ fclose(in);
+ return ERROR;
+ case ZRINIT:
+ fclose(in);
+ return ZSKIP;
+ case ZSKIP:
+ ++Skipcount;
+ if (Skipbitch)
+ ++errcnt;
+ fclose(in);
+ return c;
+ case ZACK:
+ case ZRPOS:
+ break;
+ }
+#ifdef READCHECK
+ /*
+ * If the reverse channel can be tested for data,
+ * this logic may be used to detect error packets
+ * sent by the receiver, in place of setjmp/longjmp
+ * rdchk(Tty) returns non 0 if a character is available
+ */
+ while (rdchk(Tty)) {
+#ifdef EATSIT
+ switch (checked)
+#else
+ switch (readline(1))
+#endif
+ {
+ case CAN:
+ case ZPAD:
+ c = getinsync(1);
+ goto gotack;
+ case XOFF: /* Wait a while for an XON */
+ readline(100);
+ }
+ }
+#endif
+ }
+
+ signal(SIGINT, onintr);
+ newcnt = Rxbuflen;
+ Txwcnt = 0;
+ stohdr(Txpos);
+ zsbhdr(4, ZDATA, Txhdr);
+
+ /*
+ * Special testing mode. This should force receiver to Attn,ZRPOS
+ * many times. Each time the signal should be caught, causing the
+ * file to be started over from the beginning.
+ */
+ if (Test) {
+ if ( --tleft)
+ while (tcount < 20000) {
+ printf(qbf); fflush(stdout);
+ tcount += strlen(qbf);
+#ifdef READCHECK
+ while (rdchk(Tty)) {
+#ifdef EATSIT
+ switch (checked)
+#else
+ switch (readline(1))
+#endif
+ {
+ case CAN:
+ case ZPAD:
+ goto waitack;
+ case XOFF: /* Wait for XON */
+ readline(100);
+ }
+ }
+#endif
+ }
+ signal(SIGINT, SIG_IGN); canit();
+ sleep(20); purgeline(); mode(0);
+ printf("\nsz: Tcount = %ld\n", tcount);
+ if (tleft) {
+ printf("ERROR: Interrupts Not Caught\n");
+ exit(1);
+ }
+ exit(0);
+ }
+
+ do {
+ n = zfilbuf();
+ if (Eofseen)
+ e = ZCRCE;
+ else if (junkcount > 3)
+ e = ZCRCW;
+ else if (bytcnt == Lastsync)
+ e = ZCRCW;
+ else if (Rxbuflen && (newcnt -= n) <= 0)
+ e = ZCRCW;
+ else if (Txwindow && (Txwcnt += n) >= Txwspac) {
+ Txwcnt = 0; e = ZCRCQ;
+ } else
+ e = ZCRCG;
+ if (Verbose>1)
+ fprintf(stderr, "%7ld ZMODEM%s\n",
+ Txpos, Crc32t?" CRC-32":"");
+ zsdata(txbuf, n, e);
+ bytcnt = Txpos += n;
+ if (bytcnt > maxbytcnt)
+ maxbytcnt = bytcnt;
+ if (e == ZCRCW)
+ goto waitack;
+#ifdef READCHECK
+ /*
+ * If the reverse channel can be tested for data,
+ * this logic may be used to detect error packets
+ * sent by the receiver, in place of setjmp/longjmp
+ * rdchk(Tty) returns non 0 if a character is available
+ */
+ fflush(stdout);
+ while (rdchk(Tty)) {
+#ifdef EATSIT
+ switch (checked)
+#else
+ switch (readline(1))
+#endif
+ {
+ case CAN:
+ case ZPAD:
+ c = getinsync(1);
+ if (c == ZACK)
+ break;
+ /* zcrce - dinna wanna starta ping-pong game */
+ zsdata(txbuf, 0, ZCRCE);
+ goto gotack;
+ case XOFF: /* Wait a while for an XON */
+ readline(100);
+ default:
+ ++junkcount;
+ }
+ }
+#endif /* READCHECK */
+ if (Txwindow) {
+ while ((tcount = (Txpos - Lrxpos)) >= Txwindow) {
+ vfile("%ld window >= %u", tcount, Txwindow);
+ if (e != ZCRCQ)
+ zsdata(txbuf, 0, e = ZCRCQ);
+ c = getinsync(1);
+ if (c != ZACK) {
+ zsdata(txbuf, 0, ZCRCE);
+ goto gotack;
+ }
+ }
+ vfile("window = %ld", tcount);
+ }
+ } while (!Eofseen);
+ signal(SIGINT, SIG_IGN);
+
+ for (;;) {
+ stohdr(Txpos);
+ zsbhdr(4, ZEOF, Txhdr);
+egotack:
+ switch (getinsync(0)) {
+ case ZACK:
+ goto egotack;
+ case ZNAK:
+ continue;
+ case ZRPOS:
+ goto somemore;
+ case ZRINIT:
+ fclose(in);
+ return OK;
+ case ZSKIP:
+ ++Skipcount;
+ if (Skipbitch)
+ ++errcnt;
+ fclose(in);
+ return c;
+ default:
+ sprintf(endmsg, "Got %d trying to send end of file", c);
+ case ERROR:
+ fclose(in);
+ return ERROR;
+ }
+ }
+}
+
+/*
+ * Respond to receiver's complaint, get back in sync with receiver
+ */
+getinsync(flag)
+{
+ register c;
+
+ for (;;) {
+ if (Test) {
+ printf("\r\n\n\n***** Signal Caught *****\r\n");
+ Rxpos = 0; c = ZRPOS;
+ } else
+ c = zgethdr(Rxhdr);
+ switch (c) {
+ case ZCAN:
+ case ZABORT:
+ case ZFIN:
+ case TIMEOUT:
+ sprintf(endmsg, "Got %s sending data", frametypes[c+FTOFFSET]);
+ return ERROR;
+ case ZRPOS:
+ if (Rxpos > bytcnt) {
+ vfile("getinsync: Rxpos=%lx bytcnt=%lx Maxbytcnt=%lx",
+ Rxpos, bytcnt, maxbytcnt);
+ if (Rxpos > maxbytcnt)
+ sprintf(endmsg,
+ "Nonstandard Protocol at %lX", Rxpos);
+ return ZRPOS;
+ }
+ /* ************************************* */
+ /* If sending to a buffered modem, you */
+ /* might send a break at this point to */
+ /* dump the modem's buffer. */
+ clearerr(in); /* In case file EOF seen */
+ if (fseek(in, Rxpos, 0)) {
+ sprintf(endmsg, "Bad Seek to %ld", Rxpos);
+ return ERROR;
+ }
+ Eofseen = 0;
+ bytcnt = Lrxpos = Txpos = Rxpos;
+ if (Lastsync == Rxpos) {
+ if (++Beenhereb4 > 12) {
+ sprintf(endmsg, "Can't send block");
+ return ERROR;
+ }
+ if (Beenhereb4 > 4)
+ if (blklen > 32)
+ blklen /= 2;
+ } else
+ Beenhereb4 = 0;
+ Lastsync = Rxpos;
+ return c;
+ case ZACK:
+ Lrxpos = Rxpos;
+ if (flag || Txpos == Rxpos)
+ return ZACK;
+ continue;
+ case ZRINIT:
+ return c;
+ case ZSKIP:
+ ++Skipcount;
+ if (Skipbitch)
+ ++errcnt;
+ return c;
+ case ERROR:
+ default:
+ zsbhdr(4, ZNAK, Txhdr);
+ continue;
+ }
+ }
+}
+
+
+/* Send command and related info */
+zsendcmd(buf, blen)
+char *buf;
+{
+ register c;
+ long cmdnum;
+
+ cmdnum = getpid();
+ errors = 0;
+ for (;;) {
+ stohdr(cmdnum);
+ Txhdr[ZF0] = Cmdack1;
+ zsbhdr(4, ZCOMMAND, Txhdr);
+ zsdata(buf, blen, ZCRCW);
+listen:
+ Rxtimeout = 100; /* Ten second wait for resp. */
+ Usevhdrs = 0; /* Allow rx to send fixed len headers */
+ c = zgethdr(Rxhdr);
+
+ switch (c) {
+ case ZRINIT:
+ goto listen; /* CAF 8-21-87 */
+ case ERROR:
+ case GCOUNT:
+ case TIMEOUT:
+ if (++errors > 11)
+ return ERROR;
+ continue;
+ case ZCAN:
+ case ZABORT:
+ case ZFIN:
+ case ZSKIP:
+ case ZRPOS:
+ return ERROR;
+ default:
+ if (++errors > 20)
+ return ERROR;
+ continue;
+ case ZCOMPL:
+ Exitcode = Rxpos;
+ saybibi();
+ return OK;
+ case ZRQINIT:
+ vfile("******** RZ *******");
+ system("rz");
+ vfile("******** SZ *******");
+ goto listen;
+ }
+ }
+}
+
+/*
+ * If called as sb use YMODEM protocol
+ */
+chkinvok(s)
+char *s;
+{
+ register char *p;
+
+ p = s;
+ while (*p == '-')
+ s = ++p;
+ while (*p)
+ if (*p++ == '/')
+ s = p;
+ if (*s == 'v') {
+ Verbose=1; ++s;
+ }
+ Progname = s;
+ if (s[0]=='z' && s[1] == 'c') {
+ Command = TRUE;
+ if (s[8] == 'i')
+ Cmdack1 = ZCACK1;
+ }
+ if (s[0]=='s' && s[1]=='b') {
+ Nozmodem = TRUE; blklen=1024;
+ }
+ if (s[0]=='s' && s[1]=='x') {
+ Modem2 = TRUE;
+ }
+}
+
+countem(argc, argv)
+register char **argv;
+{
+ struct stat f;
+
+ for (Totalleft = 0, Filesleft = 0; --argc >=0; ++argv) {
+ f.st_size = -1;
+ if (Verbose>2) {
+ fprintf(stderr, "\nCountem: %03d %s ", argc, *argv);
+ fflush(stderr);
+ }
+ if (access(*argv, 04) >= 0 && stat(*argv, &f) >= 0) {
+ ++Filesleft; Totalleft += f.st_size;
+ }
+ if (Verbose>2)
+ fprintf(stderr, " %ld", f.st_size);
+ }
+ if (Verbose>2)
+ fprintf(stderr, "\ncountem: Total %d %ld\n",
+ Filesleft, Totalleft);
+}
+
+chartest(m)
+{
+ register n;
+
+ mode(m);
+ printf("\r\n\nCharacter Transparency Test Mode %d\r\n", m);
+ printf("If Pro-YAM/ZCOMM is not displaying ^M hit ALT-V NOW.\r\n");
+ printf("Hit Enter.\021"); fflush(stdout);
+ readline(500);
+
+ for (n = 0; n < 256; ++n) {
+ if (!(n%8))
+ printf("\r\n");
+ printf("%02x ", n); fflush(stdout);
+ sendline(n); flushmo();
+ printf(" "); fflush(stdout);
+ if (n == 127) {
+ printf("Hit Enter.\021"); fflush(stdout);
+ readline(500);
+ printf("\r\n"); fflush(stdout);
+ }
+ }
+ printf("\021\r\nEnter Characters, echo is in hex.\r\n");
+ printf("Hit SPACE or pause 40 seconds for exit.\r\n");
+
+ while (n != TIMEOUT && n != ' ') {
+ n = readline(400);
+ printf("%02x\r\n", n);
+ fflush(stdout);
+ }
+ printf("\r\nMode %d character transparency test ends.\r\n", m);
+ fflush(stdout);
+}
+
+/*
+ * Set additional control chars to mask in Zsendmask
+ * according to bit array stored in char array at p
+ */
+initzsendmsk(p)
+register char *p;
+{
+ register c;
+
+ for (c = 0; c < 33; ++c) {
+ if (p[c>>3] & (1 << (c & 7))) {
+ Zsendmask[c] = 1;
+ vfile("Escaping %02o", c);
+ }
+ }
+}
+
+
+/* End of sz.c */
diff --git a/zmodem/undos.c b/zmodem/undos.c
new file mode 100644
index 0000000..f5d10ea
--- /dev/null
+++ b/zmodem/undos.c
@@ -0,0 +1,320 @@
+/*% cc -xenix -M0 -compat -Osa -K -i % -o undos
+ *
+ * Undos - change DOS format files to Unix, etc.
+ */
+char ID[] =
+ "Undos Rev 03-06-94 Copyright Omen Technology Inc All Rights Reserved\n";
+
+/*
+ **************************************************************************
+ *
+ * undos.c By Chuck Forsberg, Omen Technology INC
+ * Copyright 1997 Omen Technology Inc All Rights Reserved
+ *
+ *********************************************************************
+ *********************************************************************
+ *
+ *
+ * This software may be freely used for educational (didactic
+ * only) purposes. "Didactic" means it is used as a study item
+ * in a course teaching the workings of computer protocols.
+ *
+ * This software may also be freely used to support file transfer
+ * operations to or from duly licensed Omen Technology products.
+ * This includes DSZ, GSZ, ZCOMM, Professional-YAM and PowerCom.
+ * Use with other commercial or shareware programs
+ * (Crosstalk, Procomm, etc.) REQUIRES REGISTRATION.
+ *
+ *
+ * Any programs which incorporate part or all of this code must be
+ * provided in source form with this notice intact except by
+ * prior written permission from Omen Technology Incorporated.
+ * This includes compiled executables of this program.
+ *
+ * The .doc files and the file "mailer.rz" must also be included.
+ *
+ * Use of this software for commercial or administrative purposes
+ * except when exclusively limited to interfacing Omen Technology
+ * products requires license payment of $20.00 US per user
+ * (less in quantity, see mailer.rz). Use of this code by
+ * inclusion, decompilation, reverse engineering or any other means
+ * constitutes agreement to these conditions and acceptance of
+ * liability to license the materials and payment of reasonable
+ * legal costs necessary to enforce this license agreement.
+ *
+ *
+ * Omen Technology Inc
+ * Post Office Box 4681
+ * Portland OR 97208
+ *
+ * This code is made available in the hope it will be useful,
+ * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
+ * DAMAGES OF ANY KIND.
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <utime.h>
+
+#define LL 10240
+#define SUB 032
+
+
+#if 0
+struct utimbuf {
+ time_t actime; /* access time */
+ time_t modtime; /* modification time */
+};
+#endif
+
+void usage(), xperror(), chngfmt();
+
+char Lbuf[LL+2];
+char *Progname;
+int Todos = 0;
+int Tocpm = 0;
+int Tomac = 0;
+int Unmac = 0;
+int Strip = 0;
+int Stripsp = 0;
+int Graphics = 0;
+int Unparity = 0;
+int Munged = 0;
+int Lineflush = 0; /* Flush output at end of each line */
+
+main(argc, argv)
+char **argv;
+{
+ Progname = *argv;
+ if (! strcmp(Progname, "tocpm"))
+ Todos = Tocpm = 1;
+ if (! strcmp(Progname, "todos"))
+ Todos = 1;
+ if (! strcmp(Progname, "unmac"))
+ Unmac = 1;
+ if (! strcmp(Progname, "tomac"))
+ Tomac = 1;
+ if (! strcmp(Progname, "unparity"))
+ Unparity = 1;
+
+ if (! strcmp(argv[1], "-p")) {
+ ++Strip; ++Stripsp; --argc; ++argv;
+ }
+ if (! strcmp(argv[1], "-s")) {
+ ++Strip; --argc; ++argv;
+ }
+ if (! strcmp(argv[1], "-g")) {
+ Strip = 0; ++Graphics; --argc; ++argv;
+ }
+
+
+ if (argc == 1) {
+ chngfmt(NULL); exit(0);
+ }
+
+ if (argc<2 || *argv[1]== '-')
+ usage();
+ while (--argc >= 1)
+ chngfmt(*++argv);
+ exit(Munged);
+}
+
+void
+usage()
+{
+ fprintf(stderr, ID);
+ fprintf(stderr, "\nUsage: {undos|tounix|todos|tocpm|unmac|tomac} [-p] [-s] [file ...]\n");
+ fprintf(stderr, " -p Strip trailing spaces, parity bit, ignore bytes < 007\n");
+ fprintf(stderr, " -s Strip parity bit, ignore bytes < 007\n");
+ fprintf(stderr, " -g Allow Graphics (line drawing) characters\n");
+ fprintf(stderr, "-or- unparity [file ...]\n");
+ exit(1);
+}
+
+void
+chngfmt(name)
+char *name;
+{
+ register c;
+ register char *p;
+ register n;
+ register FILE *fin;
+ FILE *fout;
+ int linno = 0;
+ long fpos;
+ struct stat st, ost;
+ struct utimbuf times;
+ char outnam[64];
+ int nlong = LL;
+
+ if (name) {
+ if (stat(name, &st)) {
+ xperror(name); return;
+ }
+ if ((st.st_mode & S_IFMT) != S_IFREG) {
+ fprintf(stderr, "%s: %s is not a regular file\n", Progname, name);
+ return;
+ }
+ if ((fin = fopen(name, "r")) == NULL) {
+ xperror(name); return;
+ }
+ strcpy(outnam, "undosXXXXXX");
+ mktemp(outnam);
+ if ((fout = fopen(outnam, "w")) == NULL) {
+ xperror(outnam); exit(2);
+ }
+ } else {
+ fin = stdin; fout = stdout;
+ }
+ if (fstat(fileno(fout), &ost)) {
+ xperror("Can't fstat output!"); return;
+ }
+ if ((ost.st_mode & S_IFMT) != S_IFREG) {
+ Lineflush = 1;
+ }
+
+ if (Unparity) {
+ while ((c = getc(fin)) != EOF)
+ if (putc((c & 0177), fout) == EOF) {
+ xperror(outnam); exit(2);
+ }
+ goto closeit;
+ }
+ for (;;) {
+ ++linno;
+ Lbuf[0] = 0;
+ for (p=Lbuf+1, n=LL; --n>0; ) {
+ignore:
+ if ((c = getc(fin)) == EOF)
+ break;
+ if ( !c)
+ goto ignore;
+ if (c & 0200 && !Graphics) {
+ if (Strip) {
+ if ((c &= 0177) < 7)
+ goto ignore;
+ } else if (name)
+ goto thisbin;
+ }
+ if (c < '\7') {
+ if (Strip) {
+ if ((c &= 0177) < 7)
+ goto ignore;
+ } else if (name)
+ goto thisbin;
+ }
+ if (c == SUB) {
+ if (linno == 1 && name) /* ARC or ZOO file */
+ goto thisbin;
+ break;
+ }
+ if (c == '\r' && Unmac)
+ c = '\n';
+ *p++ = c;
+ if (c == '\n')
+ break;
+ }
+ *p = '\0';
+ if (n < nlong)
+ nlong = n;
+
+ if (n == 0 && name) {
+thisbin:
+ if (n) {
+ fprintf(stderr, "%s: %s is a binary file", Progname, name);
+ fprintf(stderr, " line=%d char =%2X\n", linno, c);
+ } else {
+ fprintf(stderr, "line=%d char =%2X\n", linno, c);
+ fprintf(stderr, "%s: %s has long line!\n", Progname, name);
+ if (!Unmac)
+ fprintf(stderr, "Try unmac?\n");
+ }
+ Munged = 1; fclose(fin); fclose(fout);
+ unlink(outnam); return;
+ }
+
+ if (Todos) {
+ if (*--p == '\n' && p[-1] != '\r') {
+ *p++ = '\r'; *p++ = '\n'; *p = 0;
+ }
+ } else if (Tomac) {
+ if (*--p == '\n') {
+ if (p[-1] == '\r')
+ --p;
+ *p++ = '\r'; *p = 0;
+ }
+ } else {
+ if (*--p == '\n' && *--p == '\r') {
+ while (p>(Lbuf+1) && p[-1] == '\r')
+ --p;
+ if (Stripsp)
+ while (p>(Lbuf+1) && p[-1] == ' ')
+ --p;
+ *p++ = '\n'; *p = 0;
+ }
+ }
+ if (Lbuf[1] && fputs(Lbuf+1, fout) == EOF) {
+ xperror(outnam); exit(2);
+ }
+ switch (c) {
+ case EOF:
+ if (ferror(fin)) {
+ xperror(name); exit(3);
+ }
+ case SUB:
+ if (Tocpm) {
+ fpos = ftell(fout);
+ do {
+ putc(SUB, fout);
+ } while (++fpos & 127);
+ }
+closeit:
+ if ( !name)
+ return;
+ fclose(fout); fclose(fin);
+ if (st.st_nlink > 1)
+ sprintf(Lbuf, "trap '' 1 2 3 15; cp %s %s", outnam, name);
+ else
+ sprintf(Lbuf, "mv %s %s", outnam, name);
+ system(Lbuf);
+ times.actime = st.st_atime;
+ times.modtime = st.st_mtime;
+ if (utime(name, &times)) {
+ xperror("Can't set file date");
+ }
+ if (st.st_nlink > 1)
+ unlink(outnam);
+ nlong = LL - nlong;
+ if (nlong > 132)
+ fprintf(stderr, "Longest line in %s has %d bytes.\n",
+ name ? name:"stdin", nlong);
+ return;
+ }
+ if (Lineflush)
+ fflush(fout);
+ }
+}
+
+void
+xperror(s)
+char *s;
+{
+ register char *p;
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+ extern errno;
+
+ if (errno >= sys_nerr)
+ p = "Gloryovsky: a New Error!";
+ else
+ p = sys_errlist[errno];
+ fprintf(stderr, "%s: %s: %s\n", Progname, s, p);
+}
+
diff --git a/zmodem/zm.c b/zmodem/zm.c
new file mode 100644
index 0000000..c09ea47
--- /dev/null
+++ b/zmodem/zm.c
@@ -0,0 +1,878 @@
+/*
+ * Z M . C
+ * Copyright 1994 Omen Technology Inc All Rights Reserved
+ * ZMODEM protocol primitives
+ *
+ * Entry point Functions:
+ * zsbhdr(type, hdr) send binary header
+ * zshhdr(type, hdr) send hex header
+ * zgethdr(hdr) receive header - binary or hex
+ * zsdata(buf, len, frameend) send data
+ * zrdata(buf, len) receive data
+ * stohdr(pos) store position data in Txhdr
+ * long rclhdr(hdr) recover position offset from header
+ *
+ *
+ * This version implements numerous enhancements including ZMODEM
+ * Run Length Encoding and variable length headers. These
+ * features were not funded by the original Telenet development
+ * contract.
+ *
+ * This software may be freely used for educational (didactic
+ * only) purposes. This software may also be freely used to
+ * support file transfer operations to or from licensed Omen
+ * Technology products. Use with other commercial or shareware
+ * programs (Crosstalk, Procomm, etc.) REQUIRES REGISTRATION.
+ *
+ * Any programs which use part or all of this software must be
+ * provided in source form with this notice intact except by
+ * written permission from Omen Technology Incorporated.
+ *
+ * Use of this software for commercial or administrative purposes
+ * except when exclusively limited to interfacing Omen Technology
+ * products requires a per port license payment of $20.00 US per
+ * port (less in quantity). Use of this code by inclusion,
+ * decompilation, reverse engineering or any other means
+ * constitutes agreement to these conditions and acceptance of
+ * liability to license the materials and payment of reasonable
+ * legal costs necessary to enforce this license agreement.
+ *
+ *
+ * Omen Technology Inc
+ * Post Office Box 4681
+ * Portland OR 97208
+ *
+ * This code is made available in the hope it will be useful,
+ * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
+ * DAMAGES OF ANY KIND.
+ *
+ */
+
+#ifndef CANFDX
+#include "zmodem.h"
+int Rxtimeout = 100; /* Tenths of seconds to wait for something */
+#endif
+
+/* Globals used by ZMODEM functions */
+int Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */
+int Rxtype; /* Type of header received */
+int Rxhlen; /* Length of header received */
+int Rxcount; /* Count of data bytes received */
+char Rxhdr[ZMAXHLEN]; /* Received header */
+char Txhdr[ZMAXHLEN]; /* Transmitted header */
+long Rxpos; /* Received file position */
+long Txpos; /* Transmitted file position */
+int Txfcs32; /* TURE means send binary frames with 32 bit FCS */
+int Crc32t; /* Controls 32 bit CRC being sent */
+ /* 1 == CRC32, 2 == CRC32 + RLE */
+int Crc32r; /* Indicates/controls 32 bit CRC being received */
+ /* 0 == CRC16, 1 == CRC32, 2 == CRC32 + RLE */
+int Usevhdrs; /* Use variable length headers */
+int Znulls; /* Number of nulls to send at beginning of ZDATA hdr */
+char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
+char *Altcan; /* Alternate canit string */
+
+static lastsent; /* Last char we sent */
+
+static char *frametypes[] = {
+ "No Response to Error Correction Request", /* -4 */
+ "No Carrier Detect", /* -3 */
+ "TIMEOUT", /* -2 */
+ "ERROR", /* -1 */
+#define FTOFFSET 4
+ "ZRQINIT",
+ "ZRINIT",
+ "ZSINIT",
+ "ZACK",
+ "ZFILE",
+ "ZSKIP",
+ "ZNAK",
+ "ZABORT",
+ "ZFIN",
+ "ZRPOS",
+ "ZDATA",
+ "ZEOF",
+ "ZFERR",
+ "ZCRC",
+ "ZCHALLENGE",
+ "ZCOMPL",
+ "ZCAN",
+ "ZFREECNT",
+ "ZCOMMAND",
+ "ZSTDERR",
+ "xxxxx"
+#define FRTYPES 22 /* Total number of frame types in this array */
+ /* not including psuedo negative entries */
+};
+
+static char badcrc[] = "Bad CRC";
+
+/* Send ZMODEM binary header hdr of type type */
+zsbhdr(len, type, hdr)
+register char *hdr;
+{
+ register int n;
+ register unsigned short crc;
+
+#ifndef DSZ
+ vfile("zsbhdr: %c %d %s %lx", Usevhdrs?'v':'f', len,
+ frametypes[type+FTOFFSET], rclhdr(hdr));
+#endif
+ if (type == ZDATA)
+ for (n = Znulls; --n >=0; )
+ xsendline(0);
+
+ xsendline(ZPAD); xsendline(ZDLE);
+
+ switch (Crc32t=Txfcs32) {
+ case 2:
+ zsbh32(len, hdr, type, Usevhdrs?ZVBINR32:ZBINR32);
+ flushmo(); break;
+ case 1:
+ zsbh32(len, hdr, type, Usevhdrs?ZVBIN32:ZBIN32); break;
+ default:
+ if (Usevhdrs) {
+ xsendline(ZVBIN);
+ zsendline(len);
+ }
+ else
+ xsendline(ZBIN);
+ zsendline(type);
+ crc = updcrc(type, 0);
+
+ for (n=len; --n >= 0; ++hdr) {
+ zsendline(*hdr);
+ crc = updcrc((0377& *hdr), crc);
+ }
+ crc = updcrc(0,updcrc(0,crc));
+ zsendline(((int)(crc>>8)));
+ zsendline(crc);
+ }
+ if (type != ZDATA)
+ flushmo();
+}
+
+
+/* Send ZMODEM binary header hdr of type type */
+zsbh32(len, hdr, type, flavour)
+register char *hdr;
+{
+ register int n;
+ register unsigned long crc;
+
+ xsendline(flavour);
+ if (Usevhdrs)
+ zsendline(len);
+ zsendline(type);
+ crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
+
+ for (n=len; --n >= 0; ++hdr) {
+ crc = UPDC32((0377 & *hdr), crc);
+ zsendline(*hdr);
+ }
+ crc = ~crc;
+ for (n=4; --n >= 0;) {
+ zsendline((int)crc);
+ crc >>= 8;
+ }
+}
+
+/* Send ZMODEM HEX header hdr of type type */
+zshhdr(len, type, hdr)
+register char *hdr;
+{
+ register int n;
+ register unsigned short crc;
+
+#ifndef DSZ
+ vfile("zshhdr: %c %d %s %lx", Usevhdrs?'v':'f', len,
+ frametypes[type+FTOFFSET], rclhdr(hdr));
+#endif
+ sendline(ZPAD); sendline(ZPAD); sendline(ZDLE);
+ if (Usevhdrs) {
+ sendline(ZVHEX);
+ zputhex(len);
+ }
+ else
+ sendline(ZHEX);
+ zputhex(type);
+ Crc32t = 0;
+
+ crc = updcrc(type, 0);
+ for (n=len; --n >= 0; ++hdr) {
+ zputhex(*hdr); crc = updcrc((0377 & *hdr), crc);
+ }
+ crc = updcrc(0,updcrc(0,crc));
+ zputhex(((int)(crc>>8))); zputhex(crc);
+
+ /* Make it printable on remote machine */
+ sendline(015); sendline(0212);
+ /*
+ * Uncork the remote in case a fake XOFF has stopped data flow
+ */
+ if (type != ZFIN && type != ZACK)
+ sendline(021);
+ flushmo();
+}
+
+/*
+ * Send binary array buf of length length, with ending ZDLE sequence frameend
+ */
+static char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};
+zsdata(buf, length, frameend)
+register char *buf;
+{
+ register unsigned short crc;
+
+#ifndef DSZ
+ vfile("zsdata: %d %s", length, Zendnames[frameend-ZCRCE&3]);
+#endif
+ switch (Crc32t) {
+ case 1:
+ zsda32(buf, length, frameend); break;
+ case 2:
+ zsdar32(buf, length, frameend); break;
+ default:
+ crc = 0;
+ for (;--length >= 0; ++buf) {
+ zsendline(*buf); crc = updcrc((0377 & *buf), crc);
+ }
+ xsendline(ZDLE); xsendline(frameend);
+ crc = updcrc(frameend, crc);
+
+ crc = updcrc(0,updcrc(0,crc));
+ zsendline(((int)(crc>>8))); zsendline(crc);
+ }
+ if (frameend == ZCRCW)
+ xsendline(XON);
+ if (frameend != ZCRCG)
+ flushmo();
+}
+
+zsda32(buf, length, frameend)
+register char *buf;
+{
+ register int c;
+ register unsigned long crc;
+
+ crc = 0xFFFFFFFFL;
+ for (;--length >= 0; ++buf) {
+ c = *buf & 0377;
+ zsendline(c);
+ crc = UPDC32(c, crc);
+ }
+ xsendline(ZDLE); xsendline(frameend);
+ crc = UPDC32(frameend, crc);
+
+ crc = ~crc;
+ for (c=4; --c >= 0;) {
+ zsendline((int)crc); crc >>= 8;
+ }
+}
+
+/*
+ * Receive array buf of max length with ending ZDLE sequence
+ * and CRC. Returns the ending character or error code.
+ * NB: On errors may store length+1 bytes!
+ */
+zrdata(buf, length)
+register char *buf;
+{
+ register int c;
+ register unsigned short crc;
+ register char *end;
+ register int d;
+
+ switch (Crc32r) {
+ case 1:
+ return zrdat32(buf, length);
+ case 2:
+ return zrdatr32(buf, length);
+ }
+
+ crc = Rxcount = 0; end = buf + length;
+ while (buf <= end) {
+ if ((c = zdlread()) & ~0377) {
+crcfoo:
+ switch (c) {
+ case GOTCRCE:
+ case GOTCRCG:
+ case GOTCRCQ:
+ case GOTCRCW:
+ crc = updcrc((d=c)&0377, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = updcrc(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = updcrc(c, crc);
+ if (crc & 0xFFFF) {
+ zperr1(badcrc);
+ return ERROR;
+ }
+ Rxcount = length - (end - buf);
+#ifndef DSZ
+ vfile("zrdata: %d %s", Rxcount,
+ Zendnames[d-GOTCRCE&3]);
+#endif
+ return d;
+ case GOTCAN:
+ zperr1("Sender Canceled");
+ return ZCAN;
+ case TIMEOUT:
+ zperr1("TIMEOUT");
+ return c;
+ default:
+ garbitch(); return c;
+ }
+ }
+ *buf++ = c;
+ crc = updcrc(c, crc);
+ }
+#ifdef DSZ
+ garbitch();
+#else
+ zperr1("Data subpacket too long");
+#endif
+ return ERROR;
+}
+
+zrdat32(buf, length)
+register char *buf;
+{
+ register int c;
+ register unsigned long crc;
+ register char *end;
+ register int d;
+
+ crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
+ while (buf <= end) {
+ if ((c = zdlread()) & ~0377) {
+crcfoo:
+ switch (c) {
+ case GOTCRCE:
+ case GOTCRCG:
+ case GOTCRCQ:
+ case GOTCRCW:
+ d = c; c &= 0377;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if (crc != 0xDEBB20E3) {
+ zperr1(badcrc);
+ return ERROR;
+ }
+ Rxcount = length - (end - buf);
+#ifndef DSZ
+ vfile("zrdat32: %d %s", Rxcount,
+ Zendnames[d-GOTCRCE&3]);
+#endif
+ return d;
+ case GOTCAN:
+ zperr1("Sender Canceled");
+ return ZCAN;
+ case TIMEOUT:
+ zperr1("TIMEOUT");
+ return c;
+ default:
+ garbitch(); return c;
+ }
+ }
+ *buf++ = c;
+ crc = UPDC32(c, crc);
+ }
+ zperr1("Data subpacket too long");
+ return ERROR;
+}
+
+garbitch()
+{
+ zperr1("Garbled data subpacket");
+}
+
+/*
+ * Read a ZMODEM header to hdr, either binary or hex.
+ *
+ * Set Rxhlen to size of header (default 4) (valid iff good hdr)
+ * On success, set Zmodem to 1, set Rxpos and return type of header.
+ * Otherwise return negative on error.
+ * Return ERROR instantly if ZCRCW sequence, for fast error recovery.
+ */
+zgethdr(hdr)
+char *hdr;
+{
+ register int c, n, cancount;
+
+ n = Zrwindow + Baudrate;
+ Rxframeind = Rxtype = 0;
+
+startover:
+ cancount = 5;
+again:
+ switch (c = readline(Rxtimeout)) {
+ case 021: case 0221:
+ goto again;
+ case RCDO:
+ case TIMEOUT:
+ goto fifi;
+ case CAN:
+gotcan:
+ if (--cancount <= 0) {
+ c = ZCAN; goto fifi;
+ }
+ switch (c = readline(Rxtimeout)) {
+ case TIMEOUT:
+ goto again;
+ case ZCRCW:
+ switch (readline(Rxtimeout)) {
+ case TIMEOUT:
+ c = ERROR; goto fifi;
+ case RCDO:
+ goto fifi;
+ default:
+ goto agn2;
+ }
+ case RCDO:
+ goto fifi;
+ default:
+ break;
+ case CAN:
+ if (--cancount <= 0) {
+ c = ZCAN; goto fifi;
+ }
+ goto again;
+ }
+ /* **** FALL THRU TO **** */
+ default:
+agn2:
+ if ( --n == 0) {
+ c = GCOUNT; goto fifi;
+ }
+ goto startover;
+ case ZPAD: /* This is what we want. */
+ break;
+ }
+ cancount = 5;
+splat:
+ switch (c = noxrd7()) {
+ case ZPAD:
+ goto splat;
+ case RCDO:
+ case TIMEOUT:
+ goto fifi;
+ default:
+ goto agn2;
+ case ZDLE: /* This is what we want. */
+ break;
+ }
+
+
+ Rxhlen = 4; /* Set default length */
+ Rxframeind = c = noxrd7();
+ switch (c) {
+ case ZVBIN32:
+ if ((Rxhlen = c = zdlread()) < 0)
+ goto fifi;
+ if (c > ZMAXHLEN)
+ goto agn2;
+ Crc32r = 1; c = zrbhd32(hdr); break;
+ case ZBIN32:
+ if (Usevhdrs)
+ goto agn2;
+ Crc32r = 1; c = zrbhd32(hdr); break;
+ case ZVBINR32:
+ if ((Rxhlen = c = zdlread()) < 0)
+ goto fifi;
+ if (c > ZMAXHLEN)
+ goto agn2;
+ Crc32r = 2; c = zrbhd32(hdr); break;
+ case ZBINR32:
+ if (Usevhdrs)
+ goto agn2;
+ Crc32r = 2; c = zrbhd32(hdr); break;
+ case RCDO:
+ case TIMEOUT:
+ goto fifi;
+ case ZVBIN:
+ if ((Rxhlen = c = zdlread()) < 0)
+ goto fifi;
+ if (c > ZMAXHLEN)
+ goto agn2;
+ Crc32r = 0; c = zrbhdr(hdr); break;
+ case ZBIN:
+ if (Usevhdrs)
+ goto agn2;
+ Crc32r = 0; c = zrbhdr(hdr); break;
+ case ZVHEX:
+ if ((Rxhlen = c = zgethex()) < 0)
+ goto fifi;
+ if (c > ZMAXHLEN)
+ goto agn2;
+ Crc32r = 0; c = zrhhdr(hdr); break;
+ case ZHEX:
+ if (Usevhdrs)
+ goto agn2;
+ Crc32r = 0; c = zrhhdr(hdr); break;
+ case CAN:
+ goto gotcan;
+ default:
+ goto agn2;
+ }
+ for (n = Rxhlen; ++n < ZMAXHLEN; ) /* Clear unused hdr bytes */
+ hdr[n] = 0;
+ Rxpos = hdr[ZP3] & 0377;
+ Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377);
+ Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377);
+ Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);
+fifi:
+ switch (c) {
+ case GOTCAN:
+ c = ZCAN;
+ /* **** FALL THRU TO **** */
+ case ZNAK:
+ case ZCAN:
+ case ERROR:
+ case TIMEOUT:
+ case RCDO:
+ case GCOUNT:
+ zperr2("Got %s", frametypes[c+FTOFFSET]);
+ /* **** FALL THRU TO **** */
+#ifndef DSZ
+ default:
+ if (c >= -4 && c <= FRTYPES)
+ vfile("zgethdr: %c %d %s %lx", Rxframeind, Rxhlen,
+ frametypes[c+FTOFFSET], Rxpos);
+ else
+ vfile("zgethdr: %c %d %lx", Rxframeind, c, Rxpos);
+#endif
+ }
+ /* Use variable length headers if we got one */
+ if (c >= 0 && c <= FRTYPES && Rxframeind & 040)
+ Usevhdrs = 1;
+ return c;
+}
+
+/* Receive a binary style header (type and position) */
+zrbhdr(hdr)
+register char *hdr;
+{
+ register int c, n;
+ register unsigned short crc;
+
+ if ((c = zdlread()) & ~0377)
+ return c;
+ Rxtype = c;
+ crc = updcrc(c, 0);
+
+ for (n=Rxhlen; --n >= 0; ++hdr) {
+ if ((c = zdlread()) & ~0377)
+ return c;
+ crc = updcrc(c, crc);
+ *hdr = c;
+ }
+ if ((c = zdlread()) & ~0377)
+ return c;
+ crc = updcrc(c, crc);
+ if ((c = zdlread()) & ~0377)
+ return c;
+ crc = updcrc(c, crc);
+ if (crc & 0xFFFF) {
+ zperr1(badcrc);
+ return ERROR;
+ }
+#ifdef ZMODEM
+ Protocol = ZMODEM;
+#endif
+ Zmodem = 1;
+ return Rxtype;
+}
+
+/* Receive a binary style header (type and position) with 32 bit FCS */
+zrbhd32(hdr)
+register char *hdr;
+{
+ register int c, n;
+ register unsigned long crc;
+
+ if ((c = zdlread()) & ~0377)
+ return c;
+ Rxtype = c;
+ crc = 0xFFFFFFFFL; crc = UPDC32(c, crc);
+#ifdef DEBUGZ
+ vfile("zrbhd32 c=%X crc=%lX", c, crc);
+#endif
+
+ for (n=Rxhlen; --n >= 0; ++hdr) {
+ if ((c = zdlread()) & ~0377)
+ return c;
+ crc = UPDC32(c, crc);
+ *hdr = c;
+#ifdef DEBUGZ
+ vfile("zrbhd32 c=%X crc=%lX", c, crc);
+#endif
+ }
+ for (n=4; --n >= 0;) {
+ if ((c = zdlread()) & ~0377)
+ return c;
+ crc = UPDC32(c, crc);
+#ifdef DEBUGZ
+ vfile("zrbhd32 c=%X crc=%lX", c, crc);
+#endif
+ }
+ if (crc != 0xDEBB20E3) {
+ zperr1(badcrc);
+ return ERROR;
+ }
+#ifdef ZMODEM
+ Protocol = ZMODEM;
+#endif
+ Zmodem = 1;
+ return Rxtype;
+}
+
+
+/* Receive a hex style header (type and position) */
+zrhhdr(hdr)
+char *hdr;
+{
+ register int c;
+ register unsigned short crc;
+ register int n;
+
+ if ((c = zgethex()) < 0)
+ return c;
+ Rxtype = c;
+ crc = updcrc(c, 0);
+
+ for (n=Rxhlen; --n >= 0; ++hdr) {
+ if ((c = zgethex()) < 0)
+ return c;
+ crc = updcrc(c, crc);
+ *hdr = c;
+ }
+ if ((c = zgethex()) < 0)
+ return c;
+ crc = updcrc(c, crc);
+ if ((c = zgethex()) < 0)
+ return c;
+ crc = updcrc(c, crc);
+ if (crc & 0xFFFF) {
+ zperr1(badcrc); return ERROR;
+ }
+ c = readline(Rxtimeout);
+ if (c < 0)
+ return c;
+ c = readline(Rxtimeout);
+#ifdef ZMODEM
+ Protocol = ZMODEM;
+#endif
+ Zmodem = 1;
+ if (c < 0)
+ return c;
+ return Rxtype;
+}
+
+/* Send a byte as two hex digits */
+zputhex(c)
+register int c;
+{
+ static char digits[] = "0123456789abcdef";
+
+#ifdef DEBUGZ
+ if (Verbose>8)
+ vfile("zputhex: %02X", c);
+#endif
+ sendline(digits[(c&0xF0)>>4]);
+ sendline(digits[(c)&0xF]);
+}
+
+/*
+ * Send character c with ZMODEM escape sequence encoding.
+ */
+zsendline(c)
+register c;
+{
+ switch (c &= 0377) {
+ case 0377:
+ lastsent = c;
+ if (Zctlesc || Zsendmask[32]) {
+ xsendline(ZDLE); c = ZRUB1;
+ }
+ xsendline(c);
+ break;
+ case ZDLE:
+ xsendline(ZDLE); xsendline (lastsent = (c ^= 0100));
+ break;
+ case 021: case 023:
+ case 0221: case 0223:
+ xsendline(ZDLE); c ^= 0100; xsendline(lastsent = c);
+ break;
+ default:
+ if (((c & 0140) == 0) && (Zctlesc || Zsendmask[c & 037])) {
+ xsendline(ZDLE); c ^= 0100;
+ }
+ xsendline(lastsent = c);
+ }
+}
+
+/* Decode two lower case hex digits into an 8 bit byte value */
+zgethex()
+{
+ register int c;
+
+ c = zgeth1();
+#ifdef DEBUGZ
+ if (Verbose>8)
+ vfile("zgethex: %02X", c);
+#endif
+ return c;
+}
+zgeth1()
+{
+ register int c, n;
+
+ if ((c = noxrd7()) < 0)
+ return c;
+ n = c - '0';
+ if (n > 9)
+ n -= ('a' - ':');
+ if (n & ~0xF)
+ return ERROR;
+ if ((c = noxrd7()) < 0)
+ return c;
+ c -= '0';
+ if (c > 9)
+ c -= ('a' - ':');
+ if (c & ~0xF)
+ return ERROR;
+ c += (n<<4);
+ return c;
+}
+
+/*
+ * Read a byte, checking for ZMODEM escape encoding
+ * including CAN*5 which represents a quick abort
+ */
+zdlread()
+{
+ register int c;
+
+again:
+ /* Quick check for non control characters */
+ if ((c = readline(Rxtimeout)) & 0140)
+ return c;
+ switch (c) {
+ case ZDLE:
+ break;
+ case 023:
+ case 0223:
+ case 021:
+ case 0221:
+ goto again;
+ default:
+ if (Zctlesc && !(c & 0140)) {
+ goto again;
+ }
+ return c;
+ }
+again2:
+ if ((c = readline(Rxtimeout)) < 0)
+ return c;
+ if (c == CAN && (c = readline(Rxtimeout)) < 0)
+ return c;
+ if (c == CAN && (c = readline(Rxtimeout)) < 0)
+ return c;
+ if (c == CAN && (c = readline(Rxtimeout)) < 0)
+ return c;
+ switch (c) {
+ case CAN:
+ return GOTCAN;
+ case ZCRCE:
+ case ZCRCG:
+ case ZCRCQ:
+ case ZCRCW:
+ return (c | GOTOR);
+ case ZRUB0:
+ return 0177;
+ case ZRUB1:
+ return 0377;
+ case 023:
+ case 0223:
+ case 021:
+ case 0221:
+ goto again2;
+ default:
+ if (Zctlesc && ! (c & 0140)) {
+ goto again2;
+ }
+ if ((c & 0140) == 0100)
+ return (c ^ 0100);
+ break;
+ }
+ if (Verbose>1)
+ zperr2("Bad escape sequence %x", c);
+ return ERROR;
+}
+
+/*
+ * Read a character from the modem line with timeout.
+ * Eat parity, XON and XOFF characters.
+ */
+noxrd7()
+{
+ register int c;
+
+ for (;;) {
+ if ((c = readline(Rxtimeout)) < 0)
+ return c;
+ switch (c &= 0177) {
+ case XON:
+ case XOFF:
+ continue;
+ default:
+ if (Zctlesc && !(c & 0140))
+ continue;
+ case '\r':
+ case '\n':
+ case ZDLE:
+ return c;
+ }
+ }
+ /* NOTREACHED */
+}
+
+/* Store long integer pos in Txhdr */
+stohdr(pos)
+long pos;
+{
+ Txhdr[ZP0] = pos;
+ Txhdr[ZP1] = pos>>8;
+ Txhdr[ZP2] = pos>>16;
+ Txhdr[ZP3] = pos>>24;
+}
+
+/* Recover a long integer from a header */
+long
+rclhdr(hdr)
+register char *hdr;
+{
+ register long l;
+
+ l = (hdr[ZP3] & 0377);
+ l = (l << 8) | (hdr[ZP2] & 0377);
+ l = (l << 8) | (hdr[ZP1] & 0377);
+ l = (l << 8) | (hdr[ZP0] & 0377);
+ return l;
+}
+
+/* End of zm.c */
diff --git a/zmodem/zmodem.h b/zmodem/zmodem.h
new file mode 100644
index 0000000..10ce4fa
--- /dev/null
+++ b/zmodem/zmodem.h
@@ -0,0 +1,142 @@
+/*
+ * Z M O D E M . H Manifest constants for ZMODEM
+ * application to application file transfer protocol
+ * Copyright 1993 Omen Technology Inc All Rights Reserved
+ */
+#define ZPAD '*' /* 052 Padding character begins frames */
+#define ZDLE 030 /* Ctrl-X Zmodem escape - `ala BISYNC DLE */
+#define ZDLEE (ZDLE^0100) /* Escaped ZDLE as transmitted */
+#define ZBIN 'A' /* Binary frame indicator (CRC-16) */
+#define ZHEX 'B' /* HEX frame indicator */
+#define ZBIN32 'C' /* Binary frame with 32 bit FCS */
+#define ZBINR32 'D' /* RLE packed Binary frame with 32 bit FCS */
+#define ZVBIN 'a' /* Binary frame indicator (CRC-16) */
+#define ZVHEX 'b' /* HEX frame indicator */
+#define ZVBIN32 'c' /* Binary frame with 32 bit FCS */
+#define ZVBINR32 'd' /* RLE packed Binary frame with 32 bit FCS */
+#define ZRESC 0176 /* RLE flag/escape character */
+#define ZMAXHLEN 16 /* Max header information length NEVER CHANGE */
+#define ZMAXSPLEN 1024 /* Max subpacket length NEVER CHANGE */
+
+/* Frame types (see array "frametypes" in zm.c) */
+#define ZRQINIT 0 /* Request receive init */
+#define ZRINIT 1 /* Receive init */
+#define ZSINIT 2 /* Send init sequence (optional) */
+#define ZACK 3 /* ACK to above */
+#define ZFILE 4 /* File name from sender */
+#define ZSKIP 5 /* To sender: skip this file */
+#define ZNAK 6 /* Last packet was garbled */
+#define ZABORT 7 /* Abort batch transfers */
+#define ZFIN 8 /* Finish session */
+#define ZRPOS 9 /* Resume data trans at this position */
+#define ZDATA 10 /* Data packet(s) follow */
+#define ZEOF 11 /* End of file */
+#define ZFERR 12 /* Fatal Read or Write error Detected */
+#define ZCRC 13 /* Request for file CRC and response */
+#define ZCHALLENGE 14 /* Receiver's Challenge */
+#define ZCOMPL 15 /* Request is complete */
+#define ZCAN 16 /* Other end canned session with CAN*5 */
+#define ZFREECNT 17 /* Request for free bytes on filesystem */
+#define ZCOMMAND 18 /* Command from sending program */
+#define ZSTDERR 19 /* Output to standard error, data follows */
+
+/* ZDLE sequences */
+#define ZCRCE 'h' /* CRC next, frame ends, header packet follows */
+#define ZCRCG 'i' /* CRC next, frame continues nonstop */
+#define ZCRCQ 'j' /* CRC next, frame continues, ZACK expected */
+#define ZCRCW 'k' /* CRC next, ZACK expected, end of frame */
+#define ZRUB0 'l' /* Translate to rubout 0177 */
+#define ZRUB1 'm' /* Translate to rubout 0377 */
+
+/* zdlread return values (internal) */
+/* -1 is general error, -2 is timeout */
+#define GOTOR 0400
+#define GOTCRCE (ZCRCE|GOTOR) /* ZDLE-ZCRCE received */
+#define GOTCRCG (ZCRCG|GOTOR) /* ZDLE-ZCRCG received */
+#define GOTCRCQ (ZCRCQ|GOTOR) /* ZDLE-ZCRCQ received */
+#define GOTCRCW (ZCRCW|GOTOR) /* ZDLE-ZCRCW received */
+#define GOTCAN (GOTOR|030) /* CAN*5 seen */
+
+/* Byte positions within header array */
+#define ZF0 3 /* First flags byte */
+#define ZF1 2
+#define ZF2 1
+#define ZF3 0
+#define ZP0 0 /* Low order 8 bits of position */
+#define ZP1 1
+#define ZP2 2
+#define ZP3 3 /* High order 8 bits of file position */
+
+/* Parameters for ZRINIT header */
+#define ZRPXWN 8 /* 9th byte in header contains window size/256 */
+#define ZRPXQQ 9 /* 10th to 14th bytes contain quote mask */
+/* Bit Masks for ZRINIT flags byte ZF0 */
+#define CANFDX 01 /* Rx can send and receive true FDX */
+#define CANOVIO 02 /* Rx can receive data during disk I/O */
+#define CANBRK 04 /* Rx can send a break signal */
+#define CANRLE 010 /* Receiver can decode RLE */
+#define CANLZW 020 /* Receiver can uncompress */
+#define CANFC32 040 /* Receiver can use 32 bit Frame Check */
+#define ESCCTL 0100 /* Receiver expects ctl chars to be escaped */
+#define ESC8 0200 /* Receiver expects 8th bit to be escaped */
+
+/* Bit Masks for ZRINIT flags byte ZF1 */
+#define CANVHDR 01 /* Variable headers OK */
+#define ZRRQWN 8 /* Receiver specified window size in ZRPXWN */
+#define ZRRQQQ 16 /* Additional control chars to quote in ZRPXQQ */
+#define ZRQNVH (ZRRQWN|ZRRQQQ) /* Variable len hdr reqd to access info */
+
+/* Parameters for ZSINIT frame */
+#define ZATTNLEN 32 /* Max length of attention string */
+#define ALTCOFF ZF1 /* Offset to alternate canit string, 0 if not used */
+/* Bit Masks for ZSINIT flags byte ZF0 */
+#define TESCCTL 0100 /* Transmitter expects ctl chars to be escaped */
+#define TESC8 0200 /* Transmitter expects 8th bit to be escaped */
+
+/* Parameters for ZFILE frame */
+/* Conversion options one of these in ZF0 */
+#define ZCBIN 1 /* Binary transfer - inhibit conversion */
+#define ZCNL 2 /* Convert NL to local end of line convention */
+#define ZCRESUM 3 /* Resume interrupted file transfer */
+/* Management include options, one of these ored in ZF1 */
+#define ZMSKNOLOC 0200 /* Skip file if not present at rx */
+/* Management options, one of these ored in ZF1 */
+#define ZMMASK 037 /* Mask for the choices below */
+#define ZMNEWL 1 /* Transfer if source newer or longer */
+#define ZMCRC 2 /* Transfer if different file CRC or length */
+#define ZMAPND 3 /* Append contents to existing file (if any) */
+#define ZMCLOB 4 /* Replace existing file */
+#define ZMNEW 5 /* Transfer if source newer */
+ /* Number 5 is alive ... */
+#define ZMDIFF 6 /* Transfer if dates or lengths different */
+#define ZMPROT 7 /* Protect destination file */
+#define ZMCHNG 8 /* Change filename if destination exists */
+/* Transport options, one of these in ZF2 */
+#define ZTLZW 1 /* Lempel-Ziv compression */
+#define ZTRLE 3 /* Run Length encoding */
+/* Extended options for ZF3, bit encoded */
+#define ZXSPARS 64 /* Encoding for sparse file operations */
+#define ZCANVHDR 01 /* Variable headers OK */
+/* Receiver window size override */
+#define ZRWOVR 4 /* byte position for receive window override/256 */
+
+/* Parameters for ZCOMMAND frame ZF0 (otherwise 0) */
+#define ZCACK1 1 /* Acknowledge, then do command */
+
+long rclhdr();
+
+/* Globals used by ZMODEM functions */
+extern Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */
+extern Rxtype; /* Type of header received */
+extern Rxcount; /* Count of data bytes received */
+extern Rxtimeout; /* Tenths of seconds to wait for something */
+extern long Rxpos; /* Received file position */
+extern long Txpos; /* Transmitted file position */
+extern Txfcs32; /* TURE means send binary frames with 32 bit FCS */
+extern Crc32t; /* Display flag indicating 32 bit CRC being sent */
+extern Crc32; /* Display flag indicating 32 bit CRC being received */
+extern Znulls; /* Number of nulls to send at beginning of ZDATA hdr */
+extern char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
+extern char *Altcan; /* Alternate canit string */
+
+/* End of zmodem.h */
diff --git a/zmodem/zmr.c b/zmodem/zmr.c
new file mode 100644
index 0000000..72446c8
--- /dev/null
+++ b/zmodem/zmr.c
@@ -0,0 +1,188 @@
+/*
+ * File: zmr.c
+ * Copyright 1988, 1994 Omen Technology Inc All Rights Reserved
+ *
+ *
+ *
+ * This module implements ZMODEM Run Length Encoding, an
+ * extension that was not funded by the original Telenet
+ * development contract.
+ *
+ * This software may be freely used for educational (didactic
+ * only) purposes. This software may also be freely used to
+ * support file transfer operations to or from licensed Omen
+ * Technology products. Use with other commercial or shareware
+ * programs (Crosstalk, Procomm, etc.) REQUIRES REGISTRATION.
+ *
+ * Any programs which use part or all of this software must be
+ * provided in source form with this notice intact except by
+ * written permission from Omen Technology Incorporated.
+ *
+ * Use of this software for commercial or administrative purposes
+ * except when exclusively limited to interfacing Omen Technology
+ * products requires a per port license payment of $20.00 US per
+ * port (less in quantity). Use of this code by inclusion,
+ * decompilation, reverse engineering or any other means
+ * constitutes agreement to these conditions and acceptance of
+ * liability to license the materials and payment of reasonable
+ * legal costs necessary to enforce this license agreement.
+ *
+ *
+ * Omen Technology Inc
+ * Post Office Box 4681
+ * Portland OR 97208
+ *
+ * This code is made available in the hope it will be useful,
+ * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
+ * DAMAGES OF ANY KIND.
+ *
+ * ZMODEM RLE compression and decompression functions
+ */
+
+/* Send data subpacket RLE encoded with 32 bit FCS */
+zsdar32(buf, length, frameend)
+char *buf;
+{
+ register int c, l, n;
+ register unsigned long crc;
+
+ crc = 0xFFFFFFFFL; l = *buf++ & 0377;
+ if (length == 1) {
+ zsendline(l); crc = UPDC32(l, crc);
+ if (l == ZRESC) {
+ zsendline(1); crc = UPDC32(1, crc);
+ }
+ } else {
+ for (n = 0; --length >= 0; ++buf) {
+ if ((c = *buf & 0377) == l && n < 126 && length>0) {
+ ++n; continue;
+ }
+ switch (n) {
+ case 0:
+ zsendline(l);
+ crc = UPDC32(l, crc);
+ if (l == ZRESC) {
+ zsendline(0100); crc = UPDC32(0100, crc);
+ }
+ l = c; break;
+ case 1:
+ if (l != ZRESC) {
+ zsendline(l); zsendline(l);
+ crc = UPDC32(l, crc);
+ crc = UPDC32(l, crc);
+ n = 0; l = c; break;
+ }
+ /* **** FALL THRU TO **** */
+ default:
+ zsendline(ZRESC); crc = UPDC32(ZRESC, crc);
+ if (l == 040 && n < 34) {
+ n += 036;
+ zsendline(n); crc = UPDC32(n, crc);
+ }
+ else {
+ n += 0101;
+ zsendline(n); crc = UPDC32(n, crc);
+ zsendline(l); crc = UPDC32(l, crc);
+ }
+ n = 0; l = c; break;
+ }
+ }
+ }
+ xsendline(ZDLE); xsendline(frameend);
+ crc = UPDC32(frameend, crc);
+
+ crc = ~crc;
+ for (length=4; --length >= 0;) {
+ zsendline((int)crc); crc >>= 8;
+ }
+}
+
+
+/* Receive data subpacket RLE encoded with 32 bit FCS */
+zrdatr32(buf, length)
+register char *buf;
+{
+ register int c;
+ register unsigned long crc;
+ register char *end;
+ register int d;
+
+ crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
+ d = 0; /* Use for RLE decoder state */
+ while (buf <= end) {
+ if ((c = zdlread()) & ~0377) {
+crcfoo:
+ switch (c) {
+ case GOTCRCE:
+ case GOTCRCG:
+ case GOTCRCQ:
+ case GOTCRCW:
+ d = c; c &= 0377;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if ((c = zdlread()) & ~0377)
+ goto crcfoo;
+ crc = UPDC32(c, crc);
+ if (crc != 0xDEBB20E3) {
+ zperr1(badcrc);
+ return ERROR;
+ }
+ Rxcount = length - (end - buf);
+#ifndef DSZ
+ vfile("zrdatr32: %d %s", Rxcount,
+ Zendnames[d-GOTCRCE&3]);
+#endif
+ return d;
+ case GOTCAN:
+ zperr1("Sender Canceled");
+ return ZCAN;
+ case TIMEOUT:
+ zperr1("TIMEOUT");
+ return c;
+ default:
+ zperr1("Bad data subpacket");
+ return c;
+ }
+ }
+ crc = UPDC32(c, crc);
+ switch (d) {
+ case 0:
+ if (c == ZRESC) {
+ d = -1; continue;
+ }
+ *buf++ = c; continue;
+ case -1:
+ if (c >= 040 && c < 0100) {
+ d = c - 035; c = 040; goto spaces;
+ }
+ if (c == 0100) {
+ d = 0;
+ *buf++ = ZRESC; continue;
+ }
+ d = c; continue;
+ default:
+ d -= 0100;
+ if (d < 1)
+ goto badpkt;
+spaces:
+ if ((buf + d) > end)
+ goto badpkt;
+ while ( --d >= 0)
+ *buf++ = c;
+ d = 0; continue;
+ }
+ }
+badpkt:
+ zperr1("Data subpacket too long");
+ return ERROR;
+}
+
+/* End of zmr.c */