Index: bootcd/isolinux/syslinux-6.03/com32/libupload/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,37 @@
+# Include configuration rules
+VPATH = $(SRC)
+include $(MAKEDIR)/com32.mk
+
+REQFLAGS += -I$(SRC)
+
+LIBOBJS := $(notdir $(patsubst %.c,%.o,$(wildcard $(SRC)/*.c)))
+
+BINDIR   = /usr/bin
+LIBDIR   = /usr/lib
+DATADIR  = /usr/share
+AUXDIR   = $(DATADIR)/syslinux
+INCDIR   = /usr/include
+COM32DIR = $(AUXDIR)/com32
+
+all: libcom32upload.a
+
+libcom32upload.a : $(LIBOBJS)
+	rm -f $@
+	$(AR) cq $@ $^
+	$(RANLIB) $@
+
+tidy dist clean:
+	find . \( -name \*.o -o -name \*.a -o -name .\*.d -o -name \*.tmp \) -print0 | \
+		xargs -0r rm -f
+
+spotless: clean
+	rm -f *.a
+	rm -f *~ \#* */*~ */\#*
+
+install: all
+	mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
+	install -m 644 libcom32upload.a $(INSTALLROOT)$(COM32DIR)
+	mkdir -p $(INSTALLROOT)$(COM32DIR)/include/
+	cp -r $(SRC)/*.h $(INSTALLROOT)$(COM32DIR)/include/
+
+-include .*.d */.*.d */*/.*.d
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/cpio.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/cpio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/cpio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,75 @@
+/*
+ * cpio.c
+ *
+ * Write a compressed CPIO file
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "upload_backend.h"
+#include "ctime.h"
+
+int cpio_pad(struct upload_backend *be)
+{
+    static char pad[4];		/* Up to 4 zero bytes */
+    if (be->dbytes & 3)
+	return write_data(be, pad, -be->dbytes & 3);
+    else
+	return 0;
+}
+
+int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen,
+	     const char *filename)
+{
+    static uint32_t inode = 2;
+    char hdr[6+13*8+1];
+    int nlen = strlen(filename)+1;
+    int rv = 0;
+
+    cpio_pad(be);
+
+    sprintf(hdr, "%06o%08x%08x%08x%08x%08x%08x%08zx%08x%08x%08x%08x%08x%08x",
+	    070701,		/* c_magic */
+	    inode++,		/* c_ino */
+	    mode,		/* c_mode */
+	    0,			/* c_uid */
+	    0,			/* c_gid */
+	    1,			/* c_nlink */
+	    be->now,		/* c_mtime */
+	    datalen,		/* c_filesize */
+	    0,			/* c_maj */
+	    0,			/* c_min */
+	    0,			/* c_rmaj */
+	    0,			/* c_rmin */
+	    nlen,		/* c_namesize */
+	    0);			/* c_chksum */
+    rv |= write_data(be, hdr, 6+13*8);
+    rv |= write_data(be, filename, nlen);
+    rv |= cpio_pad(be);
+    return rv;
+}
+
+int cpio_mkdir(struct upload_backend *be, const char *filename)
+{
+    return cpio_hdr(be, MODE_DIR, 0, filename);
+}
+
+int cpio_writefile(struct upload_backend *be, const char *filename,
+		   const void *data, size_t len)
+{
+    int rv;
+
+    rv = cpio_hdr(be, MODE_FILE, len, filename);
+    rv |= write_data(be, data, len);
+    rv |= cpio_pad(be);
+
+    return rv;
+}
+
+int cpio_close(struct upload_backend *be)
+{
+    return cpio_hdr(be, 0, 0, "TRAILER!!!");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,79 @@
+#include <com32.h>
+#include <string.h>
+#include "ctime.h"
+
+static uint8_t frombcd(uint8_t v)
+{
+    uint8_t a = v & 0x0f;
+    uint8_t b = v >> 4;
+
+    return a + b*10;
+}
+
+uint32_t posix_time(void)
+{
+    /* Days from March 1 for a specific month, starting in March */
+    static const unsigned int yday[12] =
+	{ 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 };
+    com32sys_t ir, d0, d1, t0;
+    unsigned int c, y, mo, d, h, m, s;
+    uint32_t t;
+
+    memset(&ir, 0, sizeof ir);
+
+    ir.eax.b[1] = 0x04;
+    __intcall(0x1A, &ir, &d0);
+
+    memset(&ir, 0, sizeof ir);
+    ir.eax.b[1] = 0x02;
+    __intcall(0x1A, &ir, &t0);
+
+    memset(&ir, 0, sizeof ir);
+    ir.eax.b[1] = 0x04;
+    __intcall(0x1A, &ir, &d1);
+
+    if (t0.ecx.b[1] < 0x12)
+	d0 = d1;
+
+    c  = frombcd(d0.ecx.b[1]);
+    y  = frombcd(d0.ecx.b[0]);
+    mo = frombcd(d0.edx.b[1]);
+    d  = frombcd(d0.edx.b[0]);
+
+    h  = frombcd(t0.ecx.b[1]);
+    m  = frombcd(t0.ecx.b[0]);
+    s  = frombcd(t0.edx.b[1]);
+
+    /* We of course have no idea about the timezone, so ignore it */
+
+    /*
+     * Look for impossible dates... this code was written in 2010, so
+     * assume any century less than 20 is just broken.
+     */
+    if (c < 20)
+	c = 20;
+    y += c*100;
+
+    /* Consider Jan and Feb as the last months of the previous year */
+    if (mo < 3) {
+	y--;
+	mo += 12;
+    }
+
+    /*
+     * Just in case: if the month is nonsense, don't read off the end
+     * of the table...
+     */
+    if (mo-3 > 11)
+	return 0;
+
+    t = y*365 + y/4 - y/100 + y/400 + yday[mo-3] + d - 719469;
+    t *= 24;
+    t += h;
+    t *= 60;
+    t += m;
+    t *= 60;
+    t += s;
+
+    return t;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,8 @@
+#ifndef CTIME_H
+#define CTIME_H
+
+#include <inttypes.h>
+
+uint32_t posix_time(void);
+
+#endif /* CTIME_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/serial.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,169 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+#include <syslinux/config.h>
+
+#include "serial.h"
+
+enum {
+    THR = 0,
+    RBR = 0,
+    DLL = 0,
+    DLM = 1,
+    IER = 1,
+    IIR = 2,
+    FCR = 2,
+    LCR = 3,
+    MCR = 4,
+    LSR = 5,
+    MSR = 6,
+    SCR = 7,
+};
+
+
+int serial_init(struct serial_if *sif, const char *argv[])
+{
+    const struct syslinux_serial_console_info *sci
+	= syslinux_serial_console_info();
+    uint16_t port;
+    unsigned int divisor;
+    uint8_t dll, dlm, lcr;
+
+    if (!argv[0]) {
+	if (sci->iobase) {
+	    port = sci->iobase;
+	} else {
+	    printf("No port number specified and not using serial console!\n");
+	    return -1;
+	}
+    } else {
+	port = strtoul(argv[0], NULL, 0);
+	if (port <= 3) {
+	    uint16_t addr = ((uint16_t *)0x400)[port];
+	    if (!addr) {
+		printf("No serial port address found!\n");
+	    return -1;
+	    }
+	    printf("Serial port %u is at 0x%04x\n", port, addr);
+	    port = addr;
+	}
+    }
+
+    sif->port = port;
+    sif->console = false;
+
+    divisor = 1;		/* Default speed = 115200 bps */
+
+    /* Check to see if this is the same as the serial console */
+    if (port == sci->iobase) {
+	/* Overlaying the console... */
+	sif->console = true;
+
+	/* Default to already configured speed */
+	divisor = sci->divisor;
+
+	/* Shut down I/O to the console for the time being */
+	openconsole(&dev_null_r, &dev_null_w);
+    }
+
+    if (argv[0] && argv[1])
+	divisor = 115200/strtoul(argv[1], NULL, 0);
+
+    cli();			/* Just in case... */
+
+    /* Save old register settings */
+    sif->old.lcr = inb(port + LCR);
+    sif->old.mcr = inb(port + MCR);
+    sif->old.iir = inb(port + IIR);
+
+    /* Set speed */
+    outb(0x83, port + LCR);	/* Enable divisor access */
+    sif->old.dll = inb(port + DLL);
+    sif->old.dlm = inb(port + DLM);
+    outb(divisor, port + DLL);
+    outb(divisor >> 8, port + DLM);
+    (void)inb(port + IER);	/* Synchronize */
+
+    dll = inb(port + DLL);
+    dlm = inb(port + DLM);
+    lcr = inb(port + LCR);
+    outb(0x03, port + LCR);	/* Enable data access, n81 */
+    (void)inb(port + IER);	/* Synchronize */
+    sif->old.ier = inb(port + IER);
+
+    /* Disable interrupts */
+    outb(0, port + IER);
+
+    sti();
+
+    if (dll != (uint8_t)divisor ||
+	dlm != (uint8_t)(divisor >> 8) ||
+	lcr != 0x83) {
+	serial_cleanup(sif);
+	printf("No serial port detected!\n");
+	return -1;		/* This doesn't look like a serial port */
+    }
+
+    /* Enable 16550A FIFOs if available */
+    outb(0x01, port + FCR);	/* Enable FIFO */
+    (void)inb(port + IER);	/* Synchronize */
+    if (inb(port + IIR) < 0xc0)
+	outb(0x00, port + FCR);	/* Disable FIFOs if non-functional */
+    (void)inb(port + IER);	/* Synchronize */
+
+    return 0;
+}
+
+void serial_write(struct serial_if *sif, const void *data, size_t n)
+{
+    uint16_t port = sif->port;
+    const char *p = data;
+    uint8_t lsr;
+
+    while (n--) {
+	do {
+	    lsr = inb(port + LSR);
+	} while (!(lsr & 0x20));
+
+	outb(*p++, port + THR);
+    }
+}
+
+void serial_read(struct serial_if *sif, void *data, size_t n)
+{
+    uint16_t port = sif->port;
+    char *p = data;
+    uint8_t lsr;
+
+    while (n--) {
+	do {
+	    lsr = inb(port + LSR);
+	} while (!(lsr & 0x01));
+
+	*p++ = inb(port + RBR);
+    }
+}
+
+void serial_cleanup(struct serial_if *sif)
+{
+    uint16_t port = sif->port;
+
+    outb(0x83, port + LCR);
+    (void)inb(port + IER);
+    outb(sif->old.dll, port + DLL);
+    outb(sif->old.dlm, port + DLM);
+    (void)inb(port + IER);
+    outb(sif->old.lcr & 0x7f, port + LCR);
+    (void)inb(port + IER);
+    outb(sif->old.mcr, port + MCR);
+    outb(sif->old.ier, port + IER);
+    if (sif->old.iir < 0xc0)
+	outb(0x00, port + FCR);	/* Disable FIFOs */
+
+    /* Re-enable console messages, if we shut them down */
+    if (sif->console)
+	openconsole(&dev_null_r, &dev_stdcon_w);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/serial.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/serial.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/serial.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+#ifndef SERIAL_H
+#define SERIAL_H
+
+#include <stddef.h>
+
+struct serial_if {
+    uint16_t port;
+    bool console;
+    struct {
+	uint8_t dll, dlm, ier, iir, lcr, mcr;
+    } old;
+};
+
+int serial_init(struct serial_if *sif, const char *argv[]);
+void serial_read(struct serial_if *sif, void *data, size_t n);
+void serial_write(struct serial_if *sif, const void *data, size_t n);
+void serial_cleanup(struct serial_if *sif);
+
+#endif /* SERIAL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/srecsend.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/srecsend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/srecsend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,9 @@
+#ifndef SRECSEND_H
+#define SRECSEND_H
+
+#include "file.h"
+
+void send_srec(struct serial_if *, struct file_info *,
+		 void (*)(void *, size_t, struct file_info *, size_t));
+
+#endif /* SRECSEND_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/tftp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/tftp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/tftp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,22 @@
+#include <stdint.h>
+
+#ifndef UPLOAD_TFTP
+#define UPLOAD_TFTP
+/* TFTP Error codes */
+enum tftp_error_codes {
+TFTP_ERR_UNKNOWN_ERROR = 0, // We have to use the message from the server
+TFTP_ERR_FILE_NOT_FOUND	= 1, /**< File not found */
+TFTP_ERR_ACCESS_DENIED = 2, /**< Access violation */
+TFTP_ERR_DISK_FULL = 3, /**< Disk full or allocation exceeded */
+TFTP_ERR_ILLEGAL_OP = 4, /**< Illegal TFTP operation */
+TFTP_ERR_UNKNOWN_TID = 5, /**< Unknown transfer ID */
+TFTP_ERR_FILE_EXISTS = 6, /**< File already exists */
+TFTP_ERR_UNKNOWN_USER = 7, /**< No such user */
+TFTP_ERR_BAD_OPTS = 8, /**< Option negotiation failed */
+TFTP_ERR_UNABLE_TO_RESOLVE = 9, // Not in RFC, internal usage 
+TFTP_ERR_UNABLE_TO_CONNECT = 10, // Not in RFC, internal usage
+TFTP_OK	= 11, /* Not in RFC */
+};
+
+extern const char *tftp_string_error_message[];
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_backend.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_backend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_backend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,56 @@
+#ifndef BACKEND_H
+#define BACKEND_H
+
+#include <stddef.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "serial.h"
+#include "tftp.h"
+
+/* Backend flags */
+#define BE_NEEDLEN	0x01
+
+struct upload_backend {
+    const char *name;
+    const char *helpmsg;
+    int minargs;
+
+    size_t dbytes;
+    size_t zbytes;
+    const char **argv;
+
+    uint32_t now;
+
+    int (*write)(struct upload_backend *);
+
+    z_stream zstream;
+    char *outbuf;
+    size_t alloc;
+};
+
+/* zout.c */
+int init_data(struct upload_backend *be, const char *argv[]);
+int write_data(struct upload_backend *be, const void *buf, size_t len);
+int flush_data(struct upload_backend *be);
+
+/* cpio.c */
+#define cpio_init init_data
+int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen,
+	     const char *filename);
+int cpio_mkdir(struct upload_backend *be, const char *filename);
+int cpio_writefile(struct upload_backend *be, const char *filename,
+		   const void *data, size_t len);
+int cpio_close(struct upload_backend *be);
+#define MODE_FILE	0100644
+#define MODE_DIR	0040755
+
+/* backends.c */
+struct upload_backend *get_upload_backend(const char *name);
+
+/* backends */
+extern struct upload_backend upload_tftp;
+extern struct upload_backend upload_ymodem;
+extern struct upload_backend upload_srec;
+
+#endif /* BACKEND_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_srec.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_srec.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_srec.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,85 @@
+/*
+ * S-records dump routine -- dumps S-records on the console
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <minmax.h>
+#include "upload_backend.h"
+
+/* Write a single S-record */
+static int write_srecord(unsigned int len,  unsigned int alen,
+                         uint32_t addr, uint8_t type, const void *data)
+{
+    char buf[2+2+8+255*2+2+2];
+    char *p = buf;
+    uint8_t csum;
+    const uint8_t *dptr = data;
+    unsigned int i;
+
+    switch (alen) {
+    case 2:
+        addr &= 0xffff;
+        break;
+    case 3:
+        addr &= 0xffffff;
+        break;
+    case 4:
+        break;
+    }
+
+    csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
+    for (i = 0; i < len; i++)
+        csum += dptr[i];
+    csum = 0xff-csum;
+
+    p += sprintf(p, "S%c%02X%0*X", type, len+alen+1, alen*2, addr);
+    for (i = 0; i < len; i++)
+        p += sprintf(p, "%02X", dptr[i]);
+    p += sprintf(p, "%02X\n", csum);
+
+    fputs(buf, stdout);
+    return 0;
+}
+
+static int upload_srec_write(struct upload_backend *be)
+{
+    char name[33];
+    const char *buf;
+    size_t len, chunk, offset, hdrlen;
+
+    buf = be->outbuf;
+    len = be->zbytes;
+
+    putchar('\n');
+
+    hdrlen = snprintf(name, sizeof name, "%.32s",
+		      be->argv[0] ? be->argv[0] : "");
+
+    /* Write head record */
+    write_srecord(hdrlen, 2, 0, '0', name);
+
+    /* Write data records */
+    offset = 0;
+    while (len) {
+	chunk = min(len, (size_t)32);
+
+	write_srecord(chunk, 4, offset, '3', buf);
+	buf += chunk;
+	len -= chunk;
+	offset += chunk;
+    }
+
+    /* Write termination record */
+    write_srecord(0, 4, 0, '7', NULL);
+
+    return 0;
+}
+
+struct upload_backend upload_srec = {
+    .name       = "srec",
+    .helpmsg    = "[filename]",
+    .minargs    = 0,
+    .write      = upload_srec_write,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_tftp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_tftp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_tftp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,192 @@
+/*
+ * TFTP data output backend
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+#include <netinet/in.h>
+#include <sys/times.h>
+#include "upload_backend.h"
+
+enum tftp_opcode {
+    TFTP_RRQ	= 1,
+    TFTP_WRQ	= 2,
+    TFTP_DATA	= 3,
+    TFTP_ACK	= 4,
+    TFTP_ERROR	= 5,
+};
+
+struct tftp_error {
+	uint16_t opcode;
+	uint16_t errcode;
+	char errmsg[0];
+} __attribute__ (( packed ));
+
+struct tftp_state {
+    uint32_t my_ip;
+    uint32_t srv_ip;
+    uint32_t srv_gw;
+    uint16_t my_port;
+    uint16_t srv_port;
+    uint16_t seq;
+};
+
+const char *tftp_string_error_message[]={
+"",
+"File not found",
+"Access Denied",
+"Disk Full",
+"Illegal Operation",
+"Unknown Transfert ID",
+"File already exists",
+"Unknown User",
+"Negociation failed",
+"Unable to resolve hostname", // not in RFC
+"Unable to connect", // not in RFC
+"No Error",
+};
+
+#define RCV_BUF	2048
+
+static int send_ack_packet(struct tftp_state *tftp,
+			   const void *pkt, size_t len)
+{
+    t_PXENV_UDP_WRITE *uw;
+    t_PXENV_UDP_READ  *ur;
+    clock_t start;
+    static const clock_t timeouts[] = {
+	2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 15, 18, 21, 26, 31,
+	37, 44, 53, 64, 77, 92, 110, 132, 159, 191, 229, 0
+    };
+    const clock_t *timeout;
+    int err = -1;
+
+    uw = lmalloc(sizeof *uw + len);
+    ur = lmalloc(sizeof *ur + RCV_BUF);
+
+    for (timeout = timeouts ; *timeout ; timeout++) {
+	memset(uw, 0, sizeof *uw);
+	memcpy(uw+1, pkt, len);
+	uw->ip = tftp->srv_ip;
+	uw->gw = tftp->srv_gw;
+	uw->src_port = tftp->my_port;
+	uw->dst_port = tftp->srv_port ? tftp->srv_port : htons(69);
+	uw->buffer_size = len;
+	uw->buffer = FAR_PTR(uw+1);
+
+	pxe_call(PXENV_UDP_WRITE, uw);
+
+	start = times(NULL);
+
+	do {
+	    memset(ur, 0, sizeof *ur);
+	    ur->src_ip = tftp->srv_ip;
+	    ur->dest_ip = tftp->my_ip;
+	    ur->s_port = tftp->srv_port;
+	    ur->d_port = tftp->my_port;
+	    ur->buffer_size = RCV_BUF;
+	    ur->buffer = FAR_PTR(ur+1);
+
+	    err = pxe_call(PXENV_UDP_READ, ur);
+
+	    if (!err &&	ur->status == PXENV_STATUS_SUCCESS &&
+		tftp->srv_ip == ur->src_ip &&
+		(tftp->srv_port == 0 ||
+		 tftp->srv_port == ur->s_port)) {
+		uint16_t *xb = (uint16_t *)(ur+1);
+		if (ntohs(xb[0]) == TFTP_ACK &&
+		    ntohs(xb[1]) == tftp->seq) {
+		    tftp->srv_port = ur->s_port;
+		    err = TFTP_OK;		/* All good! */
+		    goto done;
+		} else if (ntohs(xb[0]) == TFTP_ERROR) {
+		    struct tftp_error *te = (struct tftp_error *)(ur+1);
+		    if (te->errcode == TFTP_ERR_UNKNOWN_ERROR) {
+		    	tftp_string_error_message[TFTP_ERR_UNKNOWN_ERROR]=strdup(te->errmsg);
+		    }
+ 		    err=-ntohs(te->errcode); // Return the associated error code
+		    goto done;
+		}
+	    }
+	} while ((clock_t)(times(NULL) - start) < *timeout);
+    }
+
+done:
+    lfree(ur);
+    lfree(uw);
+
+    return err;
+}
+
+static int upload_tftp_write(struct upload_backend *be)
+{
+    static uint16_t local_port = 0x4000;
+    struct tftp_state tftp;
+    char buffer[512+4+6];
+    int nlen;
+    int err=TFTP_OK;
+    const union syslinux_derivative_info *sdi =
+	syslinux_derivative_info();
+    const char *data = be->outbuf;
+    size_t len = be->zbytes;
+    size_t chunk;
+
+    tftp.my_ip    = sdi->pxe.myip;
+    tftp.my_port  = htons(local_port++);
+    tftp.srv_gw   = ((tftp.srv_ip ^ tftp.my_ip) & sdi->pxe.ipinfo->netmask)
+	? sdi->pxe.ipinfo->gateway : 0;
+    tftp.srv_port = 0;
+    tftp.seq      = 0;
+
+    if (be->argv[1]) {
+	tftp.srv_ip   = pxe_dns(be->argv[1]);
+	if (!tftp.srv_ip) {
+//	    printf("\nUnable to resolve hostname: %s\n", be->argv[1]);
+	    return -TFTP_ERR_UNABLE_TO_RESOLVE;
+	}
+    } else {
+	tftp.srv_ip   = sdi->pxe.ipinfo->serverip;
+	if (!tftp.srv_ip) {
+//	    printf("\nNo server IP address\n");
+	    return -TFTP_ERR_UNABLE_TO_CONNECT;
+	}
+    }
+
+/*    printf("server %u.%u.%u.%u... ",
+	   ((uint8_t *)&tftp.srv_ip)[0],
+	   ((uint8_t *)&tftp.srv_ip)[1],
+	   ((uint8_t *)&tftp.srv_ip)[2],
+	   ((uint8_t *)&tftp.srv_ip)[3]);*/
+
+    buffer[0] = 0;
+    buffer[1] = TFTP_WRQ;
+    nlen = strlcpy(buffer+2, be->argv[0], 512);
+    memcpy(buffer+3+nlen, "octet", 6);
+
+    if ((err=send_ack_packet(&tftp, buffer, 2+nlen+1+6))!=TFTP_OK)
+	return err;
+
+    do {
+	chunk = len >= 512 ? 512 : len;
+
+	buffer[1] = TFTP_DATA;
+	*((uint16_t *)(buffer+2)) = htons(++tftp.seq);
+	memcpy(buffer+4, data, chunk);
+	data += chunk;
+	len -= chunk;
+
+	if ((err=send_ack_packet(&tftp, buffer, chunk+4))!=TFTP_OK)
+	    return err;
+    } while (chunk == 512);
+
+    return TFTP_OK;
+}
+
+struct upload_backend upload_tftp = {
+    .name       = "tftp",
+    .helpmsg    = "filename [tftp_server]",
+    .minargs    = 1,
+    .write      = upload_tftp_write,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_ymodem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_ymodem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_ymodem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,175 @@
+/*
+ * Ymodem send routine.  Only supports 1K blocks and CRC mode.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include "upload_backend.h"
+#include "serial.h"
+
+enum {
+    SOH = 0x01,
+    STX = 0x02,
+    EOT = 0x04,
+    ACK = 0x06,
+    NAK = 0x15,
+    CAN = 0x18,
+};
+
+struct ymodem_state {
+    struct serial_if serial;
+    unsigned int seq, blocks;
+};
+
+/*
+ * Append a CRC16 to a block
+ */
+static void add_crc16(uint8_t * blk, int len)
+{
+    static const uint16_t 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
+    };
+    uint16_t crc = 0;
+
+    while (len--)
+	crc = crctab[(crc >> 8) ^ *blk++] ^ crc << 8;
+
+    *blk++ = crc >> 8;
+    *blk = crc;
+}
+
+static void send_ack(struct ymodem_state *ym, const uint8_t *blk,
+		     size_t bytes);
+
+static void send_ack_blk(struct ymodem_state *ym, uint8_t *blk)
+{
+    printf("Sending block %u/%u...\r", ym->seq, ym->blocks);
+
+    blk[0] = STX;
+    blk[1] = ym->seq++;
+    blk[2] = ~blk[1];
+    add_crc16(blk+3, 1024);
+
+    send_ack(ym, blk, 1024+5);
+}
+
+static void send_ack(struct ymodem_state *ym, const uint8_t *blk, size_t bytes)
+{
+    uint8_t ack_buf;
+
+    do {
+	serial_write(&ym->serial, blk, bytes);
+
+	do {
+	    serial_read(&ym->serial, &ack_buf, 1);
+	} while (ack_buf != ACK && ack_buf != NAK);
+    } while (ack_buf == NAK);
+}
+
+static int upload_ymodem_write(struct upload_backend *be)
+{
+    static const uint8_t eot_buf = EOT;
+    uint8_t ack_buf;
+    uint8_t blk_buf[1024 + 5];
+    struct ymodem_state ym;
+    const char *buf;
+    size_t len, chunk;
+    const char ymodem_banner[] = "Now begin Ymodem download...\r\n";
+
+    buf = be->outbuf;
+    len = be->zbytes;
+
+    putchar('\n');
+
+    ym.seq = 0;
+    ym.blocks = (len+1023)/1024;
+
+    /* Initialize serial port */
+    if (serial_init(&ym.serial, &be->argv[1]))
+	return -1;
+
+    /* Write banner */
+    printf("Writing banner...\n");
+    serial_write(&ym.serial, ymodem_banner, sizeof ymodem_banner-1);
+
+    /* Wait for initial handshake */
+    printf("Waiting for handshake...\n");
+    do {
+	serial_read(&ym.serial, &ack_buf, 1);
+    } while (ack_buf != 'C');
+
+    /* Send filename block */
+    memset(blk_buf, 0, sizeof blk_buf);
+    snprintf((char *)blk_buf+3, 1024, "%s%c%zu 0%o 0644",
+	     be->argv[0], 0, be->zbytes, be->now);
+    send_ack_blk(&ym, blk_buf);
+
+    while (len) {
+	chunk = len < 1024 ? len : 1024;
+
+	memcpy(blk_buf+3, buf, chunk);
+	if (chunk < 1024)
+	    memset(blk_buf+3+chunk, 0x1a, 1024-chunk);
+
+	send_ack_blk(&ym, blk_buf);
+	buf += chunk;
+	len -= chunk;
+    }
+
+    printf("\nSending EOT...\n");
+    send_ack(&ym, &eot_buf, 1);
+
+    printf("Waiting for handshake...\n");
+    do {
+	serial_read(&ym.serial, &ack_buf, 1);
+    } while (ack_buf != 'C');
+    ym.seq = 0;
+
+    printf("Sending batch termination block...\n");
+    memset(blk_buf+3, 0, 1024);
+    send_ack_blk(&ym, blk_buf);
+
+    printf("Cleaning up...             \n");
+    serial_cleanup(&ym.serial);
+
+    return 0;
+}
+
+struct upload_backend upload_ymodem = {
+    .name       = "ymodem",
+    .helpmsg    = "filename [port [speed]]",
+    .minargs    = 1,
+    .write      = upload_ymodem_write,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/ymodem.txt
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/ymodem.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/ymodem.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2108 @@
+
+
+
+                                      - 1 -
+
+
+
+                         XMODEM/YMODEM PROTOCOL REFERENCE
+                     A compendium of documents describing the
+
+                                XMODEM and YMODEM
+
+                             File Transfer Protocols
+
+
+
+
+                      This document was formatted 10-14-88.
+
+
+
+
+
+
+
+                             Edited by Chuck Forsberg
+
+
+
+
+
+
+
+
+
+                This file may be redistributed without restriction
+                        provided the text is not altered.
+
+                     Please distribute as widely as possible.
+
+                           Questions to Chuck Forsberg
+
+
+
+
+
+                               Omen Technology Inc
+                          The High Reliability Software
+                            17505-V Sauvie Island Road
+                              Portland Oregon 97231
+                            VOICE: 503-621-3406 :VOICE
+      TeleGodzilla BBS: 503-621-3746 Speed 19200(Telebit PEP),2400,1200,300
+                              CompuServe: 70007,2304
+                                    GEnie: CAF
+                        UUCP: ...!tektronix!reed!omen!caf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                      - 2 -
+
+
+
+    1.  TOWER OF BABEL
+
+    A "YMODEM Tower of Babel" has descended on the microcomputing community
+    bringing with it confusion, frustration, bloated phone bills, and wasted
+    man hours.  Sadly, I (Chuck Forsberg) am partly to blame for this mess.
+
+    As author of the early 1980s batch and 1k XMODEM extensions, I assumed
+    readers of earlier versions of this document would implement as much of
+    the YMODEM protocol as their programming skills and computing environments
+    would permit.  This proved a rather naive assumption as programmers
+    motivated by competitive pressure implemented as little of YMODEM as
+    possible.  Some have taken whatever parts of YMODEM that appealed to them,
+    applied them to MODEM7 Batch, Telink, XMODEM or whatever, and called the
+    result YMODEM.
+
+    Jeff Garbers (Crosstalk package development director) said it all: "With
+    protocols in the public domain, anyone who wants to dink around with them
+    can go ahead." [1]
+
+    Documents containing altered examples derived from YMODEM.DOC have added
+    to the confusion.  In one instance, some self styled rewriter of history
+    altered the heading in YMODEM.DOC's Figure 1 from "1024 byte Packets" to
+    "YMODEM/CRC File Transfer Protocol".  None of the XMODEM and YMODEM
+    examples shown in that document were correct.
+
+    To put an end to this confusion, we must make "perfectly clear" what
+    YMODEM stands for, as Ward Christensen defined it in his 1985 coining of
+    the term.
+
+    To the majority of you who read, understood, and respected Ward's
+    definition of YMODEM, I apologize for the inconvenience.
+
+    1.1  Definitions
+
+    ARC     ARC is a program that compresses one or more files into an archive
+            and extracts files from such archives.
+
+    XMODEM  refers to the file transfer etiquette introduced by Ward
+            Christensen's 1977 MODEM.ASM program.  The name XMODEM comes from
+            Keith Petersen's XMODEM.ASM program, an adaptation of MODEM.ASM
+            for Remote CP/M (RCPM) systems.  It's also called the MODEM or
+            MODEM2 protocol.  Some who are unaware of MODEM7's unusual batch
+            file mode call it MODEM7.  Other aliases include "CP/M Users'
+            Group" and "TERM II FTP 3".  The name XMODEM caught on partly
+            because it is distinctive and partly because of media interest in
+
+
+    __________
+
+     1. Page C/12, PC-WEEK July 12, 1987
+
+
+
+
+    Chapter 1
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              3
+
+
+
+            bulletin board and RCPM systems where it was accessed with an
+            "XMODEM" command.  This protocol is supported by every serious
+            communications program because of its universality, simplicity,
+            and reasonable performance.
+
+    XMODEM/CRC replaces XMODEM's 1 byte checksum with a two byte Cyclical
+            Redundancy Check (CRC-16), giving modern error detection
+            protection.
+
+    XMODEM-1k Refers to the XMODEM/CRC protocol with 1024 byte data blocks.
+
+    YMODEM  Refers to the XMODEM/CRC (optional 1k blocks) protocol with batch
+            transmission as described below.  In a nutshell, YMODEM means
+            BATCH.
+
+    YMODEM-g Refers to the streaming YMODEM variation described below.
+
+    True YMODEM(TM) In an attempt to sort out the YMODEM Tower of Babel, Omen
+            Technology has trademarked the term True YMODEM(TM) to represent
+            the complete YMODEM protocol described in this document, including
+            pathname, length, and modification date transmitted in block 0.
+            Please contact Omen Technology about certifying programs for True
+            YMODEM(TM) compliance.
+
+    ZMODEM  uses familiar XMODEM/CRC and YMODEM technology in a new protocol
+            that provides reliability, throughput, file management, and user
+            amenities appropriate to contemporary data communications.
+
+    ZOO     Like ARC, ZOO is a program that compresses one or more files into
+            a "zoo archive".  ZOO supports many different operating systems
+            including Unix and VMS.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 1
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              4
+
+
+
+    2.  YMODEM MINIMUM REQUIREMENTS
+
+    All programs claiming to support YMODEM must meet the following minimum
+    requirements:
+
+       + The sending program shall send the pathname (file name) in block 0.
+
+       + The pathname shall be a null terminated ASCII string as described
+         below.
+
+         For those who are too lazy to read the entire document:
+
+            + Unless specifically requested, only the file name portion is
+              sent.
+
+            + No drive letter is sent.
+
+            + Systems that do not distinguish between upper and lower case
+              letters in filenames shall send the pathname in lower case only.
+
+
+       + The receiving program shall use this pathname for the received file
+         name, unless explicitly overridden.
+
+       + When the receiving program receives this block and successfully
+         opened the output file, it shall acknowledge this block with an ACK
+         character and then proceed with a normal XMODEM file transfer
+         beginning with a "C" or NAK tranmsitted by the receiver.
+
+       + The sending program shall use CRC-16 in response to a "C" pathname
+         nak, otherwise use 8 bit checksum.
+
+       + The receiving program must accept any mixture of 128 and 1024 byte
+         blocks within each file it receives.  Sending programs may
+         arbitrarily switch between 1024 and 128 byte blocks.
+
+       + The sending program must not change the length of an unacknowledged
+         block.
+
+       + At the end of each file, the sending program shall send EOT up to ten
+         times until it receives an ACK character.  (This is part of the
+         XMODEM spec.)
+
+       + The end of a transfer session shall be signified by a null (empty)
+         pathname, this pathname block shall be acknowledged the same as other
+         pathname blocks.
+
+    Programs not meeting all of these requirements are not YMODEM compatible,
+    and shall not be described as supporting YMODEM.
+
+    Meeting these MINIMUM requirements does not guarantee reliable file
+
+
+
+    Chapter 2
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              5
+
+
+
+    transfers under stress.  Particular attention is called to XMODEM's single
+    character supervisory messages that are easily corrupted by transmission
+    errors.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 2
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              6
+
+
+
+    3.  WHY YMODEM?
+
+    Since its development half a decade ago, the Ward Christensen modem
+    protocol has enabled a wide variety of computer systems to interchange
+    data.  There is hardly a communications program that doesn't at least
+    claim to support this protocol.
+
+    Advances in computing, modems and networking have revealed a number of
+    weaknesses in the original protocol:
+
+       + The short block length caused throughput to suffer when used with
+         timesharing systems, packet switched networks, satellite circuits,
+         and buffered (error correcting) modems.
+
+       + The 8 bit arithmetic checksum and other aspects allowed line
+         impairments to interfere with dependable, accurate transfers.
+
+       + Only one file could be sent per command.  The file name had to be
+         given twice, first to the sending program and then again to the
+         receiving program.
+
+       + The transmitted file could accumulate as many as 127 extraneous
+         bytes.
+
+       + The modification date of the file was lost.
+
+    A number of other protocols have been developed over the years, but none
+    have displaced XMODEM to date:
+
+       + Lack of public domain documentation and example programs have kept
+         proprietary protocols such as Blast, Relay, and others tightly bound
+         to the fortunes of their suppliers.
+
+       + Complexity discourages the widespread application of BISYNC, SDLC,
+         HDLC, X.25, and X.PC protocols.
+
+       + Performance compromises and complexity have limited the popularity of
+         the Kermit protocol, which was developed to allow file transfers in
+         environments hostile to XMODEM.
+
+    The XMODEM protocol extensions and YMODEM Batch address some of these
+    weaknesses while maintaining most of XMODEM's simplicity.
+
+    YMODEM is supported by the public domain programs YAM (CP/M),
+    YAM(CP/M-86), YAM(CCPM-86), IMP (CP/M), KMD (CP/M), rz/sz (Unix, Xenix,
+    VMS, Berkeley Unix, Venix, Xenix, Coherent, IDRIS, Regulus).  Commercial
+    implementations include MIRROR, and Professional-YAM.[1] Communications
+
+
+
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              7
+
+
+
+    programs supporting these extensions have been in use since 1981.
+
+    The 1k block length (XMODEM-1k) described below may be used in conjunction
+    with YMODEM Batch Protocol, or with single file transfers identical to the
+    XMODEM/CRC protocol except for minimal changes to support 1k blocks.
+
+    Another extension is the YMODEM-g protocol.  YMODEM-g provides batch
+    transfers with maximum throughput when used with end to end error
+    correcting media, such as X.PC and error correcting modems, including 9600
+    bps units by TeleBit, U.S.Robotics, Hayes, Electronic Vaults, Data Race,
+    and others.
+
+    To complete this tome, edited versions of Ward Christensen's original
+    protocol document and John Byrns's CRC-16 document are included for
+    reference.
+
+    References to the MODEM or MODEM7 protocol have been changed to XMODEM to
+    accommodate the vernacular.  In Australia, it is properly called the
+    Christensen Protocol.
+
+
+    3.1  Some Messages from the Pioneer
+
+    #: 130940 S0/Communications 25-Apr-85  18:38:47
+    Sb: my protocol
+    Fm: Ward Christensen 76703,302 [2]
+    To: all
+
+    Be aware the article[3] DID quote me correctly in terms of the phrases
+    like "not robust", etc.
+
+    It was a quick hack I threw together, very unplanned (like everything I
+    do), to satisfy a personal need to communicate with "some other" people.
+
+    ONLY the fact that it was done in 8/77, and that I put it in the public
+    domain immediately, made it become the standard that it is.
+
+
+
+
+
+
+
+    __________________________________________________________________________
+
+     1. Available for IBM PC,XT,AT, Unix and Xenix
+
+     2. Edited for typesetting appearance
+
+     3. Infoworld April 29 p. 16
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              8
+
+
+
+    I think its time for me to
+
+    (1) document it; (people call me and say "my product is going to include
+    it - what can I 'reference'", or "I'm writing a paper on it, what do I put
+    in the bibliography") and
+
+    (2) propose an "incremental extension" to it, which might take "exactly"
+    the form of Chuck Forsberg's YAM protocol.  He wrote YAM in C for CP/M and
+    put it in the public domain, and wrote a batch protocol for Unix[4] called
+    rb and sb (receive batch, send batch), which was basically XMODEM with
+       (a) a record 0 containing filename date time and size
+       (b) a 1K block size option
+       (c) CRC-16.
+
+    He did some clever programming to detect false ACK or EOT, but basically
+    left them the same.
+
+    People who suggest I make SIGNIFICANT changes to the protocol, such as
+    "full duplex", "multiple outstanding blocks", "multiple destinations", etc
+    etc don't understand that the incredible simplicity of the protocol is one
+    of the reasons it survived to this day in as many machines and programs as
+    it may be found in!
+
+    Consider the PC-NET group back in '77 or so - documenting to beat the band
+    - THEY had a protocol, but it was "extremely complex", because it tried to
+    be "all things to all people" - i.e. send binary files on a 7-bit system,
+    etc.  I was not that "benevolent". I (emphasize > I < ) had an 8-bit UART,
+    so "my protocol was an 8-bit protocol", and I would just say "sorry" to
+    people who were held back by 7-bit limitations.  ...
+
+    Block size: Chuck Forsberg created an extension of my protocol, called
+    YAM, which is also supported via his public domain programs for UNIX
+    called rb and sb - receive batch and send batch.  They cleverly send a
+    "block 0" which contains the filename, date, time, and size.
+    Unfortunately, its UNIX style, and is a bit weird[5] - octal numbers, etc.
+    BUT, it is a nice way to overcome the kludgy "echo the chars of the name"
+    introduced with MODEM7.  Further, chuck uses CRC-16 and optional 1K
+    blocks.  Thus the record 0, 1K, and CRC, make it a "pretty slick new
+    protocol" which is not significantly different from my own.
+
+    Also, there is a catchy name - YMODEM.  That means to some that it is the
+    "next thing after XMODEM", and to others that it is the Y(am)MODEM
+
+
+    __________
+
+     4. VAX/VMS versions of these programs are also available.
+
+     5. The file length, time, and file mode are optional.  The pathname and
+        file length may be sent alone if desired.
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              9
+
+
+
+    protocol.  I don't want to emphasize that too much - out of fear that
+    other mfgrs might think it is a "competitive" protocol, rather than an
+    "unaffiliated" protocol.  Chuck is currently selling a much-enhanced
+    version of his CP/M-80 C program YAM, calling it Professional Yam, and its
+    for the PC - I'm using it right now.  VERY slick!  32K capture buffer,
+    script, scrolling, previously captured text search, plus built-in commands
+    for just about everything - directory (sorted every which way), XMODEM,
+    YMODEM, KERMIT, and ASCII file upload/download, etc.  You can program it
+    to "behave" with most any system - for example when trying a number for
+    CIS it detects the "busy" string back from the modem and substitutes a
+    diff phone # into the dialing string and branches back to try it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             10
+
+
+
+    4.  XMODEM PROTOCOL ENHANCEMENTS
+
+    This chapter discusses the protocol extensions to Ward Christensen's 1982
+    XMODEM protocol description document.
+
+    The original document recommends the user be asked whether to continue
+    trying or abort after 10 retries.  Most programs no longer ask the
+    operator whether he wishes to keep retrying.  Virtually all correctable
+    errors are corrected within the first few retransmissions.  If the line is
+    so bad that ten attempts are insufficient, there is a significant danger
+    of undetected errors.  If the connection is that bad, it's better to
+    redial for a better connection, or mail a floppy disk.
+
+
+    4.1  Graceful Abort
+
+    The YAM and Professional-YAM X/YMODEM routines recognize a sequence of two
+    consecutive CAN (Hex 18) characters without modem errors (overrun,
+    framing, etc.) as a transfer abort command.  This sequence is recognized
+    when is waiting for the beginning of a block or for an acknowledgement to
+    a block that has been sent.  The check for two consecutive CAN characters
+    reduces the number of transfers aborted by line hits.  YAM sends eight CAN
+    characters when it aborts an XMODEM, YMODEM, or ZMODEM protocol file
+    transfer.  Pro-YAM then sends eight backspaces to delete the CAN
+    characters from the remote's keyboard input buffer, in case the remote had
+    already aborted the transfer and was awaiting a keyboarded command.
+
+
+    4.2  CRC-16 Option
+
+    The XMODEM protocol uses an optional two character CRC-16 instead of the
+    one character arithmetic checksum used by the original protocol and by
+    most commercial implementations.  CRC-16 guarantees detection of all
+    single and double bit errors,  all errors with an odd number of error
+    bits, all burst errors of length 16 or less, 99.9969% of all 17-bit error
+    bursts, and 99.9984 per cent of all possible longer error bursts.  By
+    contrast, a double bit error, or a burst error of 9 bits or more can sneak
+    past the XMODEM protocol arithmetic checksum.
+
+    The XMODEM/CRC protocol is similar to the XMODEM protocol, except that the
+    receiver specifies CRC-16 by sending C (Hex 43) instead of NAK when
+    requesting the FIRST block.  A two byte CRC is sent in place of the one
+    byte arithmetic checksum.
+
+    YAM's c option to the r command enables CRC-16 in single file reception,
+    corresponding to the original implementation in the MODEM7 series
+    programs.  This remains the default because many commercial communications
+    programs and bulletin board systems still do not support CRC-16,
+    especially those written in Basic or Pascal.
+
+    XMODEM protocol with CRC is accurate provided both sender and receiver
+
+
+
+    Chapter 4                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             11
+
+
+
+    both report a successful transmission.  The protocol is robust in the
+    presence of characters lost by buffer overloading on timesharing systems.
+
+    The single character ACK/NAK responses generated by the receiving program
+    adapt well to split speed modems, where the reverse channel is limited to
+    ten per cent or less of the main channel's speed.
+
+    XMODEM and YMODEM are half duplex protocols which do not attempt to
+    transmit information and control signals in both directions at the same
+    time.  This avoids buffer overrun problems that have been reported by
+    users attempting to exploit full duplex asynchronous file transfer
+    protocols such as Blast.
+
+    Professional-YAM adds several proprietary logic enhancements to XMODEM's
+    error detection and recovery.  These compatible enhancements eliminate
+    most of the bad file transfers other programs make when using the XMODEM
+    protocol under less than ideal conditions.
+
+
+    4.3  XMODEM-1k 1024 Byte Block
+
+    Disappointing throughput downloading from Unix with YMODEM[1] lead to the
+    development of 1024 byte blocks in 1982.  1024 byte blocks reduce the
+    effect of delays from timesharing systems, modems, and packet switched
+    networks on throughput by 87.5 per cent in addition to decreasing XMODEM's
+    3 per cent overhead (block number, CRC, etc.).
+
+    Some environments cannot accept 1024 byte bursts, including some networks
+    and minicomputer ports.  The longer block length should be an option.
+
+    The choice to use 1024 byte blocks is expressed to the sending program on
+    its command line or selection menu.[2] 1024 byte blocks improve throughput
+    in many applications.
+
+    An STX (02) replaces the SOH (01) at the beginning of the transmitted
+    block to notify the receiver of the longer block length.  The transmitted
+    block contains 1024 bytes of data.  The receiver should be able to accept
+    any mixture of 128 and 1024 byte blocks.  The block number (in the second
+    and third bytes of the block) is incremented by one for each block
+    regardless of the block length.
+
+    The sender must not change between 128 and 1024 byte block lengths if it
+    has not received a valid ACK for the current block.  Failure to observe
+
+
+    __________
+
+     1. The name hadn't been coined yet, but the protocol was the same.
+
+     2. See "KMD/IMP Exceptions to YMODEM" below.
+
+
+
+
+    Chapter 4                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             12
+
+
+
+    this restriction allows transmission errors to pass undetected.
+
+    If 1024 byte blocks are being used, it is possible for a file to "grow" up
+    to the next multiple of 1024 bytes.  This does not waste disk space if the
+    allocation granularity is 1k or greater.  With YMODEM batch transmission,
+    the optional file length transmitted in the file name block allows the
+    receiver to discard the padding, preserving the exact file length and
+    contents.
+
+    1024 byte blocks may be used with batch file transmission or with single
+    file transmission.  CRC-16 should be used with the k option to preserve
+    data integrity over phone lines.  If a program wishes to enforce this
+    recommendation, it should cancel the transfer, then issue an informative
+    diagnostic message if the receiver requests checksum instead of CRC-16.
+
+    Under no circumstances may a sending program use CRC-16 unless the
+    receiver commands CRC-16.
+
+             Figure 1.  XMODEM-1k Blocks
+
+             SENDER                                  RECEIVER
+                                                     "sx -k foo.bar"
+             "foo.bar open x.x minutes"
+                                                     C
+             STX 01 FE Data[1024] CRC CRC
+                                                     ACK
+             STX 02 FD Data[1024] CRC CRC
+                                                     ACK
+             STX 03 FC Data[1000] CPMEOF[24] CRC CRC
+                                                     ACK
+             EOT
+                                                     ACK
+
+             Figure 2.  Mixed 1024 and 128 byte Blocks
+
+             SENDER                                  RECEIVER
+                                                     "sx -k foo.bar"
+             "foo.bar open x.x minutes"
+                                                     C
+             STX 01 FE Data[1024] CRC CRC
+                                                     ACK
+             STX 02 FD Data[1024] CRC CRC
+                                                     ACK
+             SOH 03 FC Data[128] CRC CRC
+                                                     ACK
+             SOH 04 FB Data[100] CPMEOF[28] CRC CRC
+                                                     ACK
+             EOT
+                                                     ACK
+
+
+
+
+
+    Chapter 4                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             13
+
+
+
+    5.  YMODEM Batch File Transmission
+
+    The YMODEM Batch protocol is an extension to the XMODEM/CRC protocol that
+    allows 0 or more files to be transmitted with a single command.  (Zero
+    files may be sent if none of the requested files is accessible.) The
+    design approach of the YMODEM Batch protocol is to use the normal routines
+    for sending and receiving XMODEM blocks in a layered fashion similar to
+    packet switching methods.
+
+    Why was it necessary to design a new batch protocol when one already
+    existed in MODEM7?[1] The batch file mode used by MODEM7 is unsuitable
+    because it does not permit full pathnames, file length, file date, or
+    other attribute information to be transmitted.  Such a restrictive design,
+    hastily implemented with only CP/M in mind, would not have permitted
+    extensions to current areas of personal computing such as Unix, DOS, and
+    object oriented systems.  In addition, the MODEM7 batch file mode is
+    somewhat susceptible to transmission impairments.
+
+    As in the case of single a file transfer, the receiver initiates batch
+    file transmission by sending a "C" character (for CRC-16).
+
+    The sender opens the first file and sends block number 0 with the
+    following information.[2]
+
+    Only the pathname (file name) part is required for batch transfers.
+
+    To maintain upwards compatibility, all unused bytes in block 0 must be set
+    to null.
+
+    Pathname The pathname (conventionally, the file name) is sent as a null
+         terminated ASCII string.  This is the filename format used by the
+         handle oriented MSDOS(TM) functions and C library fopen functions.
+         An assembly language example follows:
+                                  DB      'foo.bar',0
+         No spaces are included in the pathname.  Normally only the file name
+         stem (no directory prefix) is transmitted unless the sender has
+         selected YAM's f option to send the full pathname.  The source drive
+         (A:, B:, etc.) is not sent.
+
+         Filename Considerations:
+
+
+
+    __________
+
+     1. The MODEM7 batch protocol transmitted CP/M FCB bytes f1...f8 and
+        t1...t3 one character at a time.  The receiver echoed these bytes as
+        received, one at a time.
+
+     2. Only the data part of the block is described here.
+
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             14
+
+
+
+            + File names are forced to lower case unless the sending system
+              supports upper/lower case file names.  This is a convenience for
+              users of systems (such as Unix) which store filenames in upper
+              and lower case.
+
+            + The receiver should accommodate file names in lower and upper
+              case.
+
+            + When transmitting files between different operating systems,
+              file names must be acceptable to both the sender and receiving
+              operating systems.
+
+         If directories are included, they are delimited by /; i.e.,
+         "subdir/foo" is acceptable, "subdir\foo" is not.
+
+    Length The file length and each of the succeeding fields are optional.[3]
+         The length field is stored in the block as a decimal string counting
+         the number of data bytes in the file.  The file length does not
+         include any CPMEOF (^Z) or other garbage characters used to pad the
+         last block.
+
+         If the file being transmitted is growing during transmission, the
+         length field should be set to at least the final expected file
+         length, or not sent.
+
+         The receiver stores the specified number of characters, discarding
+         any padding added by the sender to fill up the last block.
+
+    Modification Date The mod date is optional, and the filename and length
+         may be sent without requiring the mod date to be sent.
+
+         Iff the modification date is sent, a single space separates the
+         modification date from the file length.
+
+         The mod date is sent as an octal number giving the time the contents
+         of the file were last changed, measured in seconds from Jan 1 1970
+         Universal Coordinated Time (GMT).  A date of 0 implies the
+         modification date is unknown and should be left as the date the file
+         is received.
+
+         This standard format was chosen to eliminate ambiguities arising from
+         transfers between different time zones.
+
+
+
+
+
+    __________
+
+     3. Fields may not be skipped.
+
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             15
+
+
+
+    Mode Iff the file mode is sent, a single space separates the file mode
+         from the modification date.  The file mode is stored as an octal
+         string.  Unless the file originated from a Unix system, the file mode
+         is set to 0.  rb(1) checks the file mode for the 0x8000 bit which
+         indicates a Unix type regular file.  Files with the 0x8000 bit set
+         are assumed to have been sent from another Unix (or similar) system
+         which uses the same file conventions.  Such files are not translated
+         in any way.
+
+
+    Serial Number Iff the serial number is sent, a single space separates the
+         serial number from the file mode.  The serial number of the
+         transmitting program is stored as an octal string.  Programs which do
+         not have a serial number should omit this field, or set it to 0.  The
+         receiver's use of this field is optional.
+
+
+    Other Fields YMODEM was designed to allow additional header fields to be
+         added as above without creating compatibility problems with older
+         YMODEM programs.  Please contact Omen Technology if other fields are
+         needed for special application requirements.
+
+    The rest of the block is set to nulls.  This is essential to preserve
+    upward compatibility.[4]
+
+    If the filename block is received with a CRC or other error, a
+    retransmission is requested.  After the filename block has been received,
+    it is ACK'ed if the write open is successful.  If the file cannot be
+    opened for writing, the receiver cancels the transfer with CAN characters
+    as described above.
+
+    The receiver then initiates transfer of the file contents with a "C"
+    character, according to the standard XMODEM/CRC protocol.
+
+    After the file contents and XMODEM EOT have been transmitted and
+    acknowledged, the receiver again asks for the next pathname.
+
+    Transmission of a null pathname terminates batch file transmission.
+
+    Note that transmission of no files is not necessarily an error.  This is
+    possible if none of the files requested of the sender could be opened for
+    reading.
+
+
+
+    __________
+
+     4. If, perchance, this information extends beyond 128 bytes (possible
+        with Unix 4.2 BSD extended file names), the block should be sent as a
+        1k block as described above.
+
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             16
+
+
+
+    Most YMODEM receivers request CRC-16 by default.
+
+    The Unix programs sz(1) and rz(1) included in the source code file
+    RZSZ.ZOO should answer other questions about YMODEM batch protocol.
+
+              Figure 3.  YMODEM Batch Transmission Session (1 file)
+
+              SENDER                                  RECEIVER
+                                                      "sb foo.*<CR>"
+              "sending in batch mode etc."
+                                                      C (command:rb)
+              SOH 00 FF foo.c NUL[123] CRC CRC
+                                                      ACK
+                                                      C
+              SOH 01 FE Data[128] CRC CRC
+                                                      ACK
+              SOH 02 FC Data[128] CRC CRC
+                                                      ACK
+              SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+                                                      ACK
+              EOT
+                                                      NAK
+              EOT
+                                                      ACK
+                                                      C
+              SOH 00 FF NUL[128] CRC CRC
+                                                      ACK
+
+                Figure 7.  YMODEM Header Information and Features
+
+    _____________________________________________________________
+    | Program   | Length | Date | Mode | S/N | 1k-Blk | YMODEM-g |
+    |___________|________|______|______|_____|________|__________|
+    |Unix rz/sz | yes    | yes  | yes  | no  | yes    | sb only  |
+    |___________|________|______|______|_____|________|__________|
+    |VMS rb/sb  | yes    | no   | no   | no  | yes    | no       |
+    |___________|________|______|______|_____|________|__________|
+    |Pro-YAM    | yes    | yes  | no   | yes | yes    | yes      |
+    |___________|________|______|______|_____|________|__________|
+    |CP/M YAM   | no     | no   | no   | no  | yes    | no       |
+    |___________|________|______|______|_____|________|__________|
+    |KMD/IMP    | ?      | no   | no   | no  | yes    | no       |
+    |___________|________|______|______|_____|________|__________|
+
+    5.1  KMD/IMP Exceptions to YMODEM
+
+    KMD and IMP use a "CK" character sequence emitted by the receiver to
+    trigger the use of 1024 byte blocks as an alternative to specifying this
+    option to the sending program.  This two character sequence generally
+    works well on single process micros in direct communication, provided the
+    programs rigorously adhere to all the XMODEM recommendations included
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             17
+
+
+
+           Figure 4.  YMODEM Batch Transmission Session (2 files)
+
+           SENDER                                  RECEIVER
+                                                   "sb foo.c baz.c<CR>"
+           "sending in batch mode etc."
+                                                   C (command:rb)
+           SOH 00 FF foo.c NUL[123] CRC CRC
+                                                   ACK
+                                                   C
+           SOH 01 FE Data[128] CRC CRC
+                                                   ACK
+           SOH 02 FC Data[128] CRC CRC
+                                                   ACK
+           SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+                                                   ACK
+           EOT
+                                                   NAK
+           EOT
+                                                   ACK
+                                                   C
+           SOH 00 FF baz.c NUL[123] CRC CRC
+                                                   ACK
+                                                   C
+           SOH 01 FB Data[100] CPMEOF[28] CRC CRC
+                                                   ACK
+           EOT
+                                                   NAK
+           EOT
+                                                   ACK
+                                                   C
+           SOH 00 FF NUL[128] CRC CRC
+                                                   ACK
+
+            Figure 5.  YMODEM Batch Transmission Session-1k Blocks
+
+            SENDER                                  RECEIVER
+                                                    "sb -k foo.*<CR>"
+            "sending in batch mode etc."
+                                                    C (command:rb)
+            SOH 00 FF foo.c NUL[123] CRC CRC
+                                                    ACK
+                                                    C
+            STX 01 FD Data[1024] CRC CRC
+                                                    ACK
+            SOH 02 FC Data[128] CRC CRC
+                                                    ACK
+            SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+                                                    ACK
+            EOT
+                                                    NAK
+            EOT
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             18
+
+
+
+                                                    ACK
+                                                    C
+            SOH 00 FF NUL[128] CRC CRC
+                                                    ACK
+
+           Figure 6.  YMODEM Filename block transmitted by sz
+
+           -rw-r--r--  6347 Jun 17 1984 20:34 bbcsched.txt
+
+           00 0100FF62 62637363 6865642E 74787400   |...bbcsched.txt.|
+           10 36333437 20333331 34373432 35313320   |6347 3314742513 |
+           20 31303036 34340000 00000000 00000000   |100644..........|
+           30 00000000 00000000 00000000 00000000
+           40 00000000 00000000 00000000 00000000
+           50 00000000 00000000 00000000 00000000
+           60 00000000 00000000 00000000 00000000
+           70 00000000 00000000 00000000 00000000
+           80 000000CA 56
+
+    herein.  Programs with marginal XMODEM implementations do not fare so
+    well.  Timesharing systems and packet switched networks can separate the
+    successive characters, rendering this method unreliable.
+
+    Sending programs may detect the CK sequence if the operating enviornment
+    does not preclude reliable implementation.
+
+    Instead of the standard YMODEM file length in decimal, KMD and IMP
+    transmit the CP/M record count in the last two bytes of the header block.
+
+
+    6.  YMODEM-g File Transmission
+
+    Developing technology is providing phone line data transmission at ever
+    higher speeds using very specialized techniques.  These high speed modems,
+    as well as session protocols such as X.PC, provide high speed, nearly
+    error free communications at the expense of considerably increased delay
+    time.
+
+    This delay time is moderate compared to human interactions, but it
+    cripples the throughput of most error correcting protocols.
+
+    The g option to YMODEM has proven effective under these circumstances.
+    The g option is driven by the receiver, which initiates the batch transfer
+    by transmitting a G instead of C.  When the sender recognizes the G, it
+    bypasses the usual wait for an ACK to each transmitted block, sending
+    succeeding blocks at full speed, subject to XOFF/XON or other flow control
+    exerted by the medium.
+
+    The sender expects an inital G to initiate the transmission of a
+    particular file, and also expects an ACK on the EOT sent at the end of
+    each file.  This synchronization allows the receiver time to open and
+
+
+
+    Chapter 6                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             19
+
+
+
+    close files as necessary.
+
+    If an error is detected in a YMODEM-g transfer, the receiver aborts the
+    transfer with the multiple CAN abort sequence.  The ZMODEM protocol should
+    be used in applications that require both streaming throughput and error
+    recovery.
+
+            Figure 8.  YMODEM-g Transmission Session
+
+            SENDER                                  RECEIVER
+                                                    "sb foo.*<CR>"
+            "sending in batch mode etc..."
+                                                    G (command:rb -g)
+            SOH 00 FF foo.c NUL[123] CRC CRC
+                                                    G
+            SOH 01 FE Data[128] CRC CRC
+            STX 02 FD Data[1024] CRC CRC
+            SOH 03 FC Data[128] CRC CRC
+            SOH 04 FB Data[100] CPMEOF[28] CRC CRC
+            EOT
+                                                    ACK
+                                                    G
+            SOH 00 FF NUL[128] CRC CRC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 6                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             20
+
+
+
+    7.  XMODEM PROTOCOL OVERVIEW
+
+    8/9/82 by Ward Christensen.
+
+    I will maintain a master copy of this.  Please pass on changes or
+    suggestions via CBBS/Chicago at (312) 545-8086, CBBS/CPMUG (312) 849-1132
+    or by voice at (312) 849-6279.
+
+    7.1  Definitions
+
+      <soh> 01H
+      <eot> 04H
+      <ack> 06H
+      <nak> 15H
+      <can> 18H
+      <C>   43H
+
+
+    7.2  Transmission Medium Level Protocol
+
+    Asynchronous, 8 data bits, no parity, one stop bit.
+
+    The protocol imposes no restrictions on the contents of the data being
+    transmitted.  No control characters are looked for in the 128-byte data
+    messages.  Absolutely any kind of data may be sent - binary, ASCII, etc.
+    The protocol has not formally been adopted to a 7-bit environment for the
+    transmission of ASCII-only (or unpacked-hex) data , although it could be
+    simply by having both ends agree to AND the protocol-dependent data with
+    7F hex before validating it.  I specifically am referring to the checksum,
+    and the block numbers and their ones- complement.
+
+    Those wishing to maintain compatibility of the CP/M file structure, i.e.
+    to allow modemming ASCII files to or from CP/M systems should follow this
+    data format:
+
+       + ASCII tabs used (09H); tabs set every 8.
+
+       + Lines terminated by CR/LF (0DH 0AH)
+
+       + End-of-file indicated by ^Z, 1AH.  (one or more)
+
+       + Data is variable length, i.e. should be considered a continuous
+         stream of data bytes, broken into 128-byte chunks purely for the
+         purpose of transmission.
+
+       + A CP/M "peculiarity": If the data ends exactly on a 128-byte
+         boundary, i.e. CR in 127, and LF in 128, a subsequent sector
+         containing the ^Z EOF character(s) is optional, but is preferred.
+         Some utilities or user programs still do not handle EOF without ^Zs.
+
+
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             21
+
+
+
+       + The last block sent is no different from others, i.e.  there is no
+         "short block".
+                  Figure 9.  XMODEM Message Block Level Protocol
+
+    Each block of the transfer looks like:
+          <SOH><blk #><255-blk #><--128 data bytes--><cksum>
+    in which:
+    <SOH>         = 01 hex
+    <blk #>       = binary number, starts at 01 increments by 1, and
+                    wraps 0FFH to 00H (not to 01)
+    <255-blk #>   = blk # after going thru 8080 "CMA" instr, i.e.
+                    each bit complemented in the 8-bit block number.
+                    Formally, this is the "ones complement".
+    <cksum>       = the sum of the data bytes only.  Toss any carry.
+
+    7.3  File Level Protocol
+
+    7.3.1  Common_to_Both_Sender_and_Receiver
+    All errors are retried 10 times.  For versions running with an operator
+    (i.e. NOT with XMODEM), a message is typed after 10 errors asking the
+    operator whether to "retry or quit".
+
+    Some versions of the protocol use <can>, ASCII ^X, to cancel transmission.
+    This was never adopted as a standard, as having a single "abort" character
+    makes the transmission susceptible to false termination due to an <ack>
+    <nak> or <soh> being corrupted into a <can> and aborting transmission.
+
+    The protocol may be considered "receiver driven", that is, the sender need
+    not automatically re-transmit, although it does in the current
+    implementations.
+
+
+    7.3.2  Receive_Program_Considerations
+    The receiver has a 10-second timeout.  It sends a <nak> every time it
+    times out.  The receiver's first timeout, which sends a <nak>, signals the
+    transmitter to start.  Optionally, the receiver could send a <nak>
+    immediately, in case the sender was ready.  This would save the initial 10
+    second timeout.  However, the receiver MUST continue to timeout every 10
+    seconds in case the sender wasn't ready.
+
+    Once into a receiving a block, the receiver goes into a one-second timeout
+    for each character and the checksum.  If the receiver wishes to <nak> a
+    block for any reason (invalid header, timeout receiving data), it must
+    wait for the line to clear.  See "programming tips" for ideas
+
+    Synchronizing:  If a valid block number is received, it will be: 1) the
+    expected one, in which case everything is fine; or 2) a repeat of the
+    previously received block.  This should be considered OK, and only
+    indicates that the receivers <ack> got glitched, and the sender re-
+    transmitted; 3) any other block number indicates a fatal loss of
+    synchronization, such as the rare case of the sender getting a line-glitch
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             22
+
+
+
+    that looked like an <ack>.  Abort the transmission, sending a <can>
+
+
+    7.3.3  Sending_program_considerations
+    While waiting for transmission to begin, the sender has only a single very
+    long timeout, say one minute.  In the current protocol, the sender has a
+    10 second timeout before retrying.  I suggest NOT doing this, and letting
+    the protocol be completely receiver-driven.  This will be compatible with
+    existing programs.
+
+    When the sender has no more data, it sends an <eot>, and awaits an <ack>,
+    resending the <eot> if it doesn't get one.  Again, the protocol could be
+    receiver-driven, with the sender only having the high-level 1-minute
+    timeout to abort.
+
+
+    Here is a sample of the data flow, sending a 3-block message.  It includes
+    the two most common line hits - a garbaged block, and an <ack> reply
+    getting garbaged.  <xx> represents the checksum byte.
+
+                  Figure 10.  Data flow including Error Recovery
+
+    SENDER                                  RECEIVER
+                                  times out after 10 seconds,
+                                  <---              <nak>
+    <soh> 01 FE -data- <xx>       --->
+                                  <---              <ack>
+    <soh> 02 FD -data- xx         --->       (data gets line hit)
+                                  <---              <nak>
+    <soh> 02 FD -data- xx         --->
+                                  <---              <ack>
+    <soh> 03 FC -data- xx         --->
+    (ack gets garbaged)           <---              <ack>
+    <soh> 03 FC -data- xx         --->              <ack>
+    <eot>                         --->
+                                  <---       <anything except ack>
+    <eot>                         --->
+                                  <---              <ack>
+    (finished)
+
+    7.4  Programming Tips
+
+       + The character-receive subroutine should be called with a parameter
+         specifying the number of seconds to wait.  The receiver should first
+         call it with a time of 10, then <nak> and try again, 10 times.
+
+         After receiving the <soh>, the receiver should call the character
+         receive subroutine with a 1-second timeout, for the remainder of the
+         message and the <cksum>.  Since they are sent as a continuous stream,
+         timing out of this implies a serious like glitch that caused, say,
+         127 characters to be seen instead of 128.
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             23
+
+
+
+       + When the receiver wishes to <nak>, it should call a "PURGE"
+         subroutine, to wait for the line to clear.  Recall the sender tosses
+         any characters in its UART buffer immediately upon completing sending
+         a block, to ensure no glitches were mis- interpreted.
+
+         The most common technique is for "PURGE" to call the character
+         receive subroutine, specifying a 1-second timeout,[1] and looping
+         back to PURGE until a timeout occurs.  The <nak> is then sent,
+         ensuring the other end will see it.
+
+       + You may wish to add code recommended by John Mahr to your character
+         receive routine - to set an error flag if the UART shows framing
+         error, or overrun.  This will help catch a few more glitches - the
+         most common of which is a hit in the high bits of the byte in two
+         consecutive bytes.  The <cksum> comes out OK since counting in 1-byte
+         produces the same result of adding 80H + 80H as with adding 00H +
+         00H.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    __________
+
+     1. These times should be adjusted for use with timesharing systems.
+
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             24
+
+
+
+    8.  XMODEM/CRC Overview
+
+    Original 1/13/85 by John Byrns -- CRC option.
+
+    Please pass on any reports of errors in this document or suggestions for
+    improvement to me via Ward's/CBBS at (312) 849-1132, or by voice at (312)
+    885-1105.
+
+    The CRC used in the Modem Protocol is an alternate form of block check
+    which provides more robust error detection than the original checksum.
+    Andrew S. Tanenbaum says in his book, Computer Networks, that the CRC-
+    CCITT used by the Modem Protocol will detect all single and double bit
+    errors, all errors with an odd number of bits, all burst errors of length
+    16 or less, 99.997% of 17-bit error bursts, and 99.998% of 18-bit and
+    longer bursts.[1]
+
+    The changes to the Modem Protocol to replace the checksum with the CRC are
+    straight forward. If that were all that we did we would not be able to
+    communicate between a program using the old checksum protocol and one
+    using the new CRC protocol. An initial handshake was added to solve this
+    problem. The handshake allows a receiving program with CRC capability to
+    determine whether the sending program supports the CRC option, and to
+    switch it to CRC mode if it does. This handshake is designed so that it
+    will work properly with programs which implement only the original
+    protocol. A description of this handshake is presented in section 10.
+
+                Figure 11.  Message Block Level Protocol, CRC mode
+
+    Each block of the transfer in CRC mode looks like:
+         <SOH><blk #><255-blk #><--128 data bytes--><CRC hi><CRC lo>
+    in which:
+    <SOH>        = 01 hex
+    <blk #>      = binary number, starts at 01 increments by 1, and
+                   wraps 0FFH to 00H (not to 01)
+    <255-blk #>  = ones complement of blk #.
+    <CRC hi>     = byte containing the 8 hi order coefficients of the CRC.
+    <CRC lo>     = byte containing the 8 lo order coefficients of the CRC.
+
+    8.1  CRC Calculation
+
+    8.1.1  Formal_Definition
+    To calculate the 16 bit CRC the message bits are considered to be the
+    coefficients of a polynomial. This message polynomial is first multiplied
+    by X^16 and then divided by the generator polynomial (X^16 + X^12 + X^5 +
+
+
+    __________
+
+     1. This reliability figure is misleading because XMODEM's critical
+        supervisory functions are not protected by this CRC.
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             25
+
+
+
+    1) using modulo two arithmetic. The remainder left after the division is
+    the desired CRC. Since a message block in the Modem Protocol is 128 bytes
+    or 1024 bits, the message polynomial will be of order X^1023. The hi order
+    bit of the first byte of the message block is the coefficient of X^1023 in
+    the message polynomial.  The lo order bit of the last byte of the message
+    block is the coefficient of X^0 in the message polynomial.
+
+               Figure 12.  Example of CRC Calculation written in C
+
+    The following XMODEM crc routine is taken from "rbsb.c".  Please refer to
+    the source code for these programs (contained in RZSZ.ZOO) for usage.  A
+    fast table driven version is also included in this file.
+
+    /* update CRC */
+    unsigned short
+    updcrc(c, crc)
+    register c;
+    register unsigned crc;
+    {
+            register count;
+
+            for (count=8; --count>=0;) {
+                    if (crc & 0x8000) {
+                            crc <<= 1;
+                            crc += (((c<<=1) & 0400)  !=  0);
+                            crc ^= 0x1021;
+                    }
+                    else {
+                            crc <<= 1;
+                            crc += (((c<<=1) & 0400)  !=  0);
+                    }
+            }
+            return crc;
+    }
+
+    8.2  CRC File Level Protocol Changes
+
+    8.2.1  Common_to_Both_Sender_and_Receiver
+    The only change to the File Level Protocol for the CRC option is the
+    initial handshake which is used to determine if both the sending and the
+    receiving programs support the CRC mode. All Modem Programs should support
+    the checksum mode for compatibility with older versions.  A receiving
+    program that wishes to receive in CRC mode implements the mode setting
+    handshake by sending a <C> in place of the initial <nak>.  If the sending
+    program supports CRC mode it will recognize the <C> and will set itself
+    into CRC mode, and respond by sending the first block as if a <nak> had
+    been received. If the sending program does not support CRC mode it will
+    not respond to the <C> at all. After the receiver has sent the <C> it will
+    wait up to 3 seconds for the <soh> that starts the first block. If it
+    receives a <soh> within 3 seconds it will assume the sender supports CRC
+    mode and will proceed with the file exchange in CRC mode. If no <soh> is
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             26
+
+
+
+    received within 3 seconds the receiver will switch to checksum mode, send
+    a <nak>, and proceed in checksum mode. If the receiver wishes to use
+    checksum mode it should send an initial <nak> and the sending program
+    should respond to the <nak> as defined in the original Modem Protocol.
+    After the mode has been set by the initial <C> or <nak> the protocol
+    follows the original Modem Protocol and is identical whether the checksum
+    or CRC is being used.
+
+
+    8.2.2  Receive_Program_Considerations
+    There are at least 4 things that can go wrong with the mode setting
+    handshake.
+
+      1.  the initial <C> can be garbled or lost.
+
+      2.  the initial <soh> can be garbled.
+
+      3.  the initial <C> can be changed to a <nak>.
+
+      4.  the initial <nak> from a receiver which wants to receive in checksum
+          can be changed to a <C>.
+
+    The first problem can be solved if the receiver sends a second <C> after
+    it times out the first time. This process can be repeated several times.
+    It must not be repeated too many times before sending a <nak> and
+    switching to checksum mode or a sending program without CRC support may
+    time out and abort. Repeating the <C> will also fix the second problem if
+    the sending program cooperates by responding as if a <nak> were received
+    instead of ignoring the extra <C>.
+
+    It is possible to fix problems 3 and 4 but probably not worth the trouble
+    since they will occur very infrequently. They could be fixed by switching
+    modes in either the sending or the receiving program after a large number
+    of successive <nak>s. This solution would risk other problems however.
+
+
+    8.2.3  Sending_Program_Considerations
+    The sending program should start in the checksum mode. This will insure
+    compatibility with checksum only receiving programs. Anytime a <C> is
+    received before the first <nak> or <ack> the sending program should set
+    itself into CRC mode and respond as if a <nak> were received. The sender
+    should respond to additional <C>s as if they were <nak>s until the first
+    <ack> is received. This will assist the receiving program in determining
+    the correct mode when the <soh> is lost or garbled. After the first <ack>
+    is received the sending program should ignore <C>s.
+
+
+
+
+
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             27
+
+
+
+    8.3  Data Flow Examples with CRC Option
+
+    Here is a data flow example for the case where the receiver requests
+    transmission in the CRC mode but the sender does not support the CRC
+    option. This example also includes various transmission errors.  <xx>
+    represents the checksum byte.
+
+          Figure 13.  Data Flow: Receiver has CRC Option, Sender Doesn't
+
+    SENDER                                        RECEIVER
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <nak>
+    <soh> 01 FE -data- <xx> --->
+                            <---                <ack>
+    <soh> 02 FD -data- <xx> --->        (data gets line hit)
+                            <---                <nak>
+    <soh> 02 FD -data- <xx> --->
+                            <---                <ack>
+    <soh> 03 FC -data- <xx> --->
+       (ack gets garbaged)  <---                <ack>
+                                    times out after 10 seconds,
+                            <---                <nak>
+    <soh> 03 FC -data- <xx> --->
+                            <---                <ack>
+    <eot>                   --->
+                            <---                <ack>
+
+    Here is a data flow example for the case where the receiver requests
+    transmission in the CRC mode and the sender supports the CRC option.  This
+    example also includes various transmission errors.  <xxxx> represents the
+    2 CRC bytes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             28
+
+
+
+               Figure 14.  Receiver and Sender Both have CRC Option
+
+    SENDER                                       RECEIVER
+                              <---                 <C>
+    <soh> 01 FE -data- <xxxx> --->
+                              <---                 <ack>
+    <soh> 02 FD -data- <xxxx> --->         (data gets line hit)
+                              <---                 <nak>
+    <soh> 02 FD -data- <xxxx> --->
+                              <---                 <ack>
+    <soh> 03 FC -data- <xxxx> --->
+    (ack gets garbaged)       <---                 <ack>
+                                         times out after 10 seconds,
+                              <---                 <nak>
+    <soh> 03 FC -data- <xxxx> --->
+                              <---                 <ack>
+    <eot>                     --->
+                              <---                 <ack>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             29
+
+
+
+    9.  MORE INFORMATION
+
+    Please contact Omen Technology for troff source files and typeset copies
+    of this document.
+
+
+    9.1  TeleGodzilla Bulletin Board
+
+    More information may be obtained by calling TeleGodzilla at 503-621-3746.
+    Speed detection is automatic for 1200, 2400 and 19200(Telebit PEP) bps.
+    TrailBlazer modem users may issue the TeleGodzilla trailblazer command to
+    swith to 19200 bps once they have logged in.
+
+    Interesting files include RZSZ.ZOO (C source code), YZMODEM.ZOO (Official
+    XMODEM, YMODEM, and ZMODEM protocol descriptions), ZCOMMEXE.ARC,
+    ZCOMMDOC.ARC, and ZCOMMHLP.ARC (PC-DOS shareware comm program with XMODEM,
+    True YMODEM(TM), ZMODEM, Kermit Sliding Windows, Telink, MODEM7 Batch,
+    script language, etc.).
+
+
+    9.2  Unix UUCP Access
+
+    UUCP sites can obtain the current version of this file with
+                     uucp omen!/u/caf/public/ymodem.doc /tmp
+    A continually updated list of available files is stored in
+    /usr/spool/uucppublic/FILES.  When retrieving these files with uucp,
+    remember that the destination directory on your system must be writeable
+    by anyone, or the UUCP transfer will fail.
+
+    The following L.sys line calls TeleGodzilla (Pro-YAM in host operation).
+    TeleGodzilla determines the incoming speed automatically.
+
+    In response to "Name Please:" uucico gives the Pro-YAM "link" command as a
+    user name.  The password (Giznoid) controls access to the Xenix system
+    connected to the IBM PC's other serial port.  Communications between
+    Pro-YAM and Xenix use 9600 bps; YAM converts this to the caller's speed.
+
+    Finally, the calling uucico logs in as uucp.
+
+    omen Any ACU 2400 1-503-621-3746 se:--se: link ord: Giznoid in:--in: uucp
+
+
+
+    10.  REVISIONS
+
+    6-18-88 Further revised for clarity.  Corrected block numbering in two
+    examples.
+    10-27-87 Optional fields added for number of files remaining to be sent
+    and total number of bytes remaining to be sent.
+    10-18-87 Flow control discussion added to 1024 byte block descritpion,
+    minor revisions for clarity per user comments.
+
+
+
+    Chapter 10                                        Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             30
+
+
+
+    8-03-87 Revised for clarity.
+    5-31-1987 emphasizes minimum requirements for YMODEM, and updates
+    information on accessing files.
+    9-11-1986 clarifies nomenclature and some minor points.
+    The April 15 1986 edition clarifies some points concerning CRC
+    calculations and spaces in the header.
+
+
+    11.  YMODEM Programs
+
+    ZCOMM, A shareware little brother to Professional-YAM, is available as
+    ZCOMMEXE.ARC on TeleGodzilla and other bulletin board systems.  ZCOMM may
+    be used to test YMODEM amd ZMODEM implementations.
+
+    Unix programs supporting YMODEM are available on TeleGodzilla in RZSZ.ZOO.
+    This ZOO archive includes a ZCOMM/Pro-YAM/PowerCom script ZUPL.T to upload
+    a bootstrap program MINIRB.C, compile it, and then upload the rest of the
+    files using the compiled MINIRB.  Most Unix like systems are supported,
+    including V7, Xenix, Sys III, 4.2 BSD, SYS V, Idris, Coherent, and
+    Regulus.
+
+    A version for VAX-VMS is available in VRBSB.SHQ.
+
+    Irv Hoff has added 1k blocks and basic YMODEM batch transfers to the KMD
+    and IMP series programs, which replace the XMODEM and MODEM7/MDM7xx series
+    respectively.  Overlays are available for a wide variety of CP/M systems.
+
+    Questions about Professional-YAM communications software may be directed
+    to:
+         Chuck Forsberg
+         Omen Technology Inc
+         17505-V Sauvie Island Road
+         Portland Oregon 97231
+         VOICE: 503-621-3406 :VOICE
+         Modem: 503-621-3746 Speed: 19200(Telebit PEP),2400,1200,300
+         Usenet: ...!tektronix!reed!omen!caf
+         CompuServe: 70007,2304
+         GEnie: CAF
+
+    Unlike ZMODEM and Kermit, XMODEM and YMODEM place obstacles in the path of
+    a reliable high performance implementation, evidenced by poor reliability
+    under stress of the industry leaders' XMODEM and YMODEM programs.  Omen
+    Technology provides consulting and other services to those wishing to
+    implement XMODEM, YMODEM, and ZMODEM with state of the art features and
+    reliability.
+
+
+
+
+
+
+
+
+
+    Chapter 11                                        Xmodem Protocol Overview
+
+
+
+
+
+
+
+
+
+
+
+                                     CONTENTS
+
+
+     1.  TOWER OF BABEL...................................................   2
+         1.1  Definitions.................................................   2
+
+     2.  YMODEM MINIMUM REQUIREMENTS......................................   4
+
+     3.  WHY YMODEM?......................................................   6
+         3.1  Some Messages from the Pioneer..............................   7
+
+     4.  XMODEM PROTOCOL ENHANCEMENTS.....................................  10
+         4.1  Graceful Abort..............................................  10
+         4.2  CRC-16 Option...............................................  10
+         4.3  XMODEM-1k 1024 Byte Block...................................  11
+
+     5.  YMODEM Batch File Transmission...................................  13
+         5.1  KMD/IMP Exceptions to YMODEM................................  16
+
+     6.  YMODEM-g File Transmission.......................................  18
+
+     7.  XMODEM PROTOCOL OVERVIEW.........................................  20
+         7.1  Definitions.................................................  20
+         7.2  Transmission Medium Level Protocol..........................  20
+         7.3  File Level Protocol.........................................  21
+         7.4  Programming Tips............................................  22
+
+     8.  XMODEM/CRC Overview..............................................  24
+         8.1  CRC Calculation.............................................  24
+         8.2  CRC File Level Protocol Changes.............................  25
+         8.3  Data Flow Examples with CRC Option..........................  27
+
+     9.  MORE INFORMATION.................................................  29
+         9.1  TeleGodzilla Bulletin Board.................................  29
+         9.2  Unix UUCP Access............................................  29
+
+    10.  REVISIONS........................................................  29
+
+    11.  YMODEM Programs..................................................  30
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                      - i -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                 LIST OF FIGURES
+
+
+     Figure 1.  XMODEM-1k Blocks..........................................  12
+
+     Figure 2.  Mixed 1024 and 128 byte Blocks............................  12
+
+     Figure 3.  YMODEM Batch Transmission Session (1 file)................  16
+
+     Figure 4.  YMODEM Batch Transmission Session (2 files)...............  16
+
+     Figure 5.  YMODEM Batch Transmission Session-1k Blocks...............  16
+
+     Figure 6.  YMODEM Filename block transmitted by sz...................  16
+
+     Figure 7.  YMODEM Header Information and Features....................  16
+
+     Figure 8.  YMODEM-g Transmission Session.............................  19
+
+     Figure 9.  XMODEM Message Block Level Protocol.......................  21
+
+    Figure 10.  Data flow including Error Recovery........................  22
+
+    Figure 11.  Message Block Level Protocol, CRC mode....................  24
+
+    Figure 12.  Example of CRC Calculation written in C...................  25
+
+    Figure 13.  Data Flow: Receiver has CRC Option, Sender Doesn't........  27
+
+    Figure 14.  Receiver and Sender Both have CRC Option..................  28
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                      - ii -
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/zout.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/zout.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/zout.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,100 @@
+/*
+ * Compress input and feed it to a block-oriented back end.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "upload_backend.h"
+#include "ctime.h"
+
+#define ALLOC_CHUNK	65536
+
+int init_data(struct upload_backend *be, const char *argv[])
+{
+    be->now = posix_time();
+    be->argv = argv;
+
+    memset(&be->zstream, 0, sizeof be->zstream);
+
+    be->zstream.next_out  = NULL;
+    be->outbuf = NULL;
+    be->zstream.avail_out = be->alloc  = 0;
+    be->dbytes = be->zbytes = 0;
+
+    /* Initialize a gzip data stream */
+    if (deflateInit2(&be->zstream, 9, Z_DEFLATED,
+		     16+15, 9, Z_DEFAULT_STRATEGY) < 0)
+	return -1;
+
+    return 0;
+}
+
+static int do_deflate(struct upload_backend *be, int flush)
+{
+    int rv;
+    char *buf;
+
+    while (1) {
+	rv = deflate(&be->zstream, flush);
+	be->zbytes = be->alloc - be->zstream.avail_out;
+	if (be->zstream.avail_out)
+	    return rv;		   /* Not an issue of output space... */
+
+	buf = realloc(be->outbuf, be->alloc + ALLOC_CHUNK);
+	if (!buf)
+	    return Z_MEM_ERROR;
+	be->outbuf = buf;
+	be->alloc += ALLOC_CHUNK;
+	be->zstream.next_out = (void *)(buf + be->zbytes);
+	be->zstream.avail_out = be->alloc - be->zbytes;
+    }
+}
+
+
+int write_data(struct upload_backend *be, const void *buf, size_t len)
+{
+    int rv = Z_OK;
+
+    be->zstream.next_in = (void *)buf;
+    be->zstream.avail_in = len;
+
+    be->dbytes += len;
+
+    while (be->zstream.avail_in) {
+	rv = do_deflate(be, Z_NO_FLUSH);
+	if (rv < 0) {
+	    printf("do_deflate returned %d\n", rv);
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+/* Output the data and shut down the stream */
+int flush_data(struct upload_backend *be)
+{
+    int rv = Z_OK;
+    int err=-1;
+
+    while (rv != Z_STREAM_END) {
+	rv = do_deflate(be, Z_FINISH);
+	if (rv < 0)
+	    return -1;
+    }
+
+//    printf("Uploading data, %u bytes... ", be->zbytes);
+
+    if ((err=be->write(be)) != 0)
+	return err;
+
+    free(be->outbuf);
+    be->outbuf = NULL;
+    be->dbytes = be->zbytes = be->alloc = 0;
+
+//    printf("done.\n");
+    return 0;
+}
