diff options
author | Erwan Velu <erwanaliasr1@gmail.com> | 2011-03-15 21:51:46 +0100 |
---|---|---|
committer | Erwan Velu <erwanaliasr1@gmail.com> | 2011-03-15 21:58:47 +0100 |
commit | 997985d79e5813e8a33e82fb0cc0c0f08cf2c55d (patch) | |
tree | 075ba6a5c1abceb938626430743e6de6e2cbc4fe /com32/sysdump | |
parent | 3905382158cc8c5c40f71e1b33f1802341838bca (diff) | |
download | syslinux-997985d79e5813e8a33e82fb0cc0c0f08cf2c55d.tar.gz syslinux-997985d79e5813e8a33e82fb0cc0c0f08cf2c55d.tar.xz syslinux-997985d79e5813e8a33e82fb0cc0c0f08cf2c55d.zip |
libupload: New library to manage uploads
This commit creates a library to upload content via 3 backends
(srec/ymodem/tftp).
Code came from sysdump and got librarized for being used more easily
by more other com32 modules.
Diffstat (limited to 'com32/sysdump')
-rw-r--r-- | com32/sysdump/Makefile | 2 | ||||
-rw-r--r-- | com32/sysdump/acpi.c | 10 | ||||
-rw-r--r-- | com32/sysdump/backend.h | 55 | ||||
-rw-r--r-- | com32/sysdump/be_srec.c | 85 | ||||
-rw-r--r-- | com32/sysdump/be_tftp.c | 178 | ||||
-rw-r--r-- | com32/sysdump/be_ymodem.c | 175 | ||||
-rw-r--r-- | com32/sysdump/cpio.c | 75 | ||||
-rw-r--r-- | com32/sysdump/cpuid.c | 4 | ||||
-rw-r--r-- | com32/sysdump/ctime.c | 77 | ||||
-rw-r--r-- | com32/sysdump/ctime.h | 8 | ||||
-rw-r--r-- | com32/sysdump/dmi.c | 8 | ||||
-rw-r--r-- | com32/sysdump/main.c | 20 | ||||
-rw-r--r-- | com32/sysdump/memmap.c | 6 | ||||
-rw-r--r-- | com32/sysdump/memory.c | 6 | ||||
-rw-r--r-- | com32/sysdump/pci.c | 6 | ||||
-rw-r--r-- | com32/sysdump/serial.c | 169 | ||||
-rw-r--r-- | com32/sysdump/serial.h | 19 | ||||
-rw-r--r-- | com32/sysdump/srecsend.h | 9 | ||||
-rw-r--r-- | com32/sysdump/sysdump.h | 16 | ||||
-rw-r--r-- | com32/sysdump/vesa.c | 4 | ||||
-rw-r--r-- | com32/sysdump/ymodem.txt | 2108 | ||||
-rw-r--r-- | com32/sysdump/zout.c | 99 |
22 files changed, 41 insertions, 3098 deletions
diff --git a/com32/sysdump/Makefile b/com32/sysdump/Makefile index bffee3a2..b2093de0 100644 --- a/com32/sysdump/Makefile +++ b/com32/sysdump/Makefile @@ -19,7 +19,7 @@ topdir = ../.. include ../MCONFIG -include $(topdir)/version.mk -LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC) +LIBS = ../libutil/libutil_com.a ../lib/libcom32.a ../libupload/libcom32upload.a $(LIBGCC) LNXLIBS = ../libutil/libutil_lnx.a MODULES = sysdump.c32 diff --git a/com32/sysdump/acpi.c b/com32/sysdump/acpi.c index 8671fc8a..f2be4f45 100644 --- a/com32/sysdump/acpi.c +++ b/com32/sysdump/acpi.c @@ -18,7 +18,7 @@ #include <string.h> #include <stdlib.h> #include "sysdump.h" -#include "backend.h" +#include "../libupload/upload_backend.h" #include "rbtree.h" struct acpi_rsdp { @@ -151,7 +151,7 @@ static const struct acpi_rsdp *find_rsdp(void) return scan_for_rsdp(0xe0000, 0x100000); } -static void dump_table(struct backend *be, +static void dump_table(struct upload_backend *be, const char name[], const void *ptr, uint32_t len) { char namebuf[64]; @@ -171,7 +171,7 @@ static void dump_table(struct backend *be, write_data(be, ptr, len); } -static void dump_rsdt(struct backend *be, const struct acpi_rsdp *rsdp) +static void dump_rsdt(struct upload_backend *be, const struct acpi_rsdp *rsdp) { const struct acpi_rsdt *rsdt; uint32_t i, n; @@ -196,7 +196,7 @@ static void dump_rsdt(struct backend *be, const struct acpi_rsdp *rsdp) } } -static void dump_xsdt(struct backend *be, const struct acpi_rsdp *rsdp) +static void dump_xsdt(struct upload_backend *be, const struct acpi_rsdp *rsdp) { const struct acpi_xsdt *xsdt; uint32_t rsdp_len = rsdp->rev > 0 ? rsdp->len : 20; @@ -231,7 +231,7 @@ static void dump_xsdt(struct backend *be, const struct acpi_rsdp *rsdp) } } -void dump_acpi(struct backend *be) +void dump_acpi(struct upload_backend *be) { const struct acpi_rsdp *rsdp; uint32_t rsdp_len; diff --git a/com32/sysdump/backend.h b/com32/sysdump/backend.h deleted file mode 100644 index f2b3bc25..00000000 --- a/com32/sysdump/backend.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef BACKEND_H -#define BACKEND_H - -#include <stddef.h> -#include <inttypes.h> -#include <stdbool.h> -#include <zlib.h> -#include "serial.h" - -/* Backend flags */ -#define BE_NEEDLEN 0x01 - -struct backend { - const char *name; - const char *helpmsg; - int minargs; - - size_t dbytes; - size_t zbytes; - const char **argv; - - uint32_t now; - - int (*write)(struct backend *); - - z_stream zstream; - char *outbuf; - size_t alloc; -}; - -/* zout.c */ -int init_data(struct backend *be, const char *argv[]); -int write_data(struct backend *be, const void *buf, size_t len); -int flush_data(struct backend *be); - -/* cpio.c */ -#define cpio_init init_data -int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen, - const char *filename); -int cpio_mkdir(struct backend *be, const char *filename); -int cpio_writefile(struct backend *be, const char *filename, - const void *data, size_t len); -int cpio_close(struct backend *be); -#define MODE_FILE 0100644 -#define MODE_DIR 0040755 - -/* backends.c */ -struct backend *get_backend(const char *name); - -/* backends */ -extern struct backend be_tftp; -extern struct backend be_ymodem; -extern struct backend be_srec; - -#endif /* BACKEND_H */ diff --git a/com32/sysdump/be_srec.c b/com32/sysdump/be_srec.c deleted file mode 100644 index fc69c886..00000000 --- a/com32/sysdump/be_srec.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * S-records dump routine -- dumps S-records on the console - */ - -#include <string.h> -#include <stdio.h> -#include <inttypes.h> -#include <minmax.h> -#include "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 be_srec_write(struct 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 backend be_srec = { - .name = "srec", - .helpmsg = "[filename]", - .minargs = 0, - .write = be_srec_write, -}; diff --git a/com32/sysdump/be_tftp.c b/com32/sysdump/be_tftp.c deleted file mode 100644 index 36a91eb8..00000000 --- a/com32/sysdump/be_tftp.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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 "backend.h" - -enum tftp_opcode { - TFTP_RRQ = 1, - TFTP_WRQ = 2, - TFTP_DATA = 3, - TFTP_ACK = 4, - TFTP_ERROR = 5, -}; - -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; -}; - -#define RCV_BUF 2048 - -static int send_ack_packet(struct tftp_state *tftp, - const void *pkt, size_t len) -{ - com32sys_t ireg, oreg; - 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); - - memset(&ireg, 0, sizeof ireg); - ireg.eax.w[0] = 0x0009; - - 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); - - ireg.ebx.w[0] = PXENV_UDP_WRITE; - ireg.es = SEG(uw); - ireg.edi.w[0] = OFFS(uw); - - __intcall(0x22, &ireg, &oreg); - - 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); - - ireg.ebx.w[0] = PXENV_UDP_READ; - ireg.es = SEG(ur); - ireg.edi.w[0] = OFFS(ur); - __intcall(0x22, &ireg, &oreg); - - if (!(oreg.eflags.l & EFLAGS_CF) && - 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 = 0; /* All good! */ - goto done; - } else if (ntohs(xb[1]) == TFTP_ERROR) { - goto done; - } - } - } while ((clock_t)(times(NULL) - start) < *timeout); - } - -done: - lfree(ur); - lfree(uw); - - return err; -} - -static int be_tftp_write(struct backend *be) -{ - static uint16_t local_port = 0x4000; - struct tftp_state tftp; - char buffer[512+4+6]; - int nlen; - 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 -1; - } - } else { - tftp.srv_ip = sdi->pxe.ipinfo->serverip; - if (!tftp.srv_ip) { - printf("\nNo server IP address\n"); - return -1; - } - } - - 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 (send_ack_packet(&tftp, buffer, 2+nlen+1+6)) - return -1; - - 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 (send_ack_packet(&tftp, buffer, chunk+4)) - return -1; - } while (chunk == 512); - - return 0; -} - -struct backend be_tftp = { - .name = "tftp", - .helpmsg = "filename [tftp_server]", - .minargs = 1, - .write = be_tftp_write, -}; diff --git a/com32/sysdump/be_ymodem.c b/com32/sysdump/be_ymodem.c deleted file mode 100644 index 316b3d4e..00000000 --- a/com32/sysdump/be_ymodem.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Ymodem send routine. Only supports 1K blocks and CRC mode. - */ - -#include <string.h> -#include <stdio.h> -#include <inttypes.h> -#include "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 be_ymodem_write(struct 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 backend be_ymodem = { - .name = "ymodem", - .helpmsg = "filename [port [speed]]", - .minargs = 1, - .write = be_ymodem_write, -}; diff --git a/com32/sysdump/cpio.c b/com32/sysdump/cpio.c deleted file mode 100644 index 81d0d4be..00000000 --- a/com32/sysdump/cpio.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * cpio.c - * - * Write a compressed CPIO file - */ - -#include <stdio.h> -#include <string.h> -#include <inttypes.h> -#include <stdbool.h> -#include <zlib.h> -#include "backend.h" -#include "ctime.h" - -int cpio_pad(struct 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 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%08x%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 backend *be, const char *filename) -{ - return cpio_hdr(be, MODE_DIR, 0, filename); -} - -int cpio_writefile(struct 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 backend *be) -{ - return cpio_hdr(be, 0, 0, "TRAILER!!!"); -} diff --git a/com32/sysdump/cpuid.c b/com32/sysdump/cpuid.c index 372a70db..53c54f2f 100644 --- a/com32/sysdump/cpuid.c +++ b/com32/sysdump/cpuid.c @@ -8,7 +8,7 @@ #include <com32.h> #include <sys/cpu.h> #include "sysdump.h" -#include "backend.h" +#include "../libupload/upload_backend.h" struct cpuid_data { uint32_t eax, ebx, ecx, edx; @@ -29,7 +29,7 @@ static void get_cpuid(uint32_t eax, uint32_t ecx, struct cpuid_data *data) #define CPUID_CHUNK 128 -void dump_cpuid(struct backend *be) +void dump_cpuid(struct upload_backend *be) { struct cpuid_info *buf = NULL; int nentry, nalloc; diff --git a/com32/sysdump/ctime.c b/com32/sysdump/ctime.c deleted file mode 100644 index 56c8efb6..00000000 --- a/com32/sysdump/ctime.c +++ /dev/null @@ -1,77 +0,0 @@ -#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); - - ir.eax.b[1] = 0x02; - __intcall(0x1A, &ir, &t0); - - 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; -} diff --git a/com32/sysdump/ctime.h b/com32/sysdump/ctime.h deleted file mode 100644 index e6461253..00000000 --- a/com32/sysdump/ctime.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef CTIME_H -#define CTIME_H - -#include <inttypes.h> - -uint32_t posix_time(void); - -#endif /* CTIME_H */ diff --git a/com32/sysdump/dmi.c b/com32/sysdump/dmi.c index be4cce46..64fcffb7 100644 --- a/com32/sysdump/dmi.c +++ b/com32/sysdump/dmi.c @@ -6,7 +6,7 @@ #include <string.h> #include <stdlib.h> #include "sysdump.h" -#include "backend.h" +#include "../libupload/upload_backend.h" struct dmi_header { char signature[5]; @@ -60,7 +60,7 @@ static bool is_smbios(size_t dptr) is_old_dmi(dptr+16); } -static void dump_smbios(struct backend *be, size_t dptr) +static void dump_smbios(struct upload_backend *be, size_t dptr) { const struct smbios_header *smb = (void *)dptr; struct smbios_header smx = *smb; @@ -82,7 +82,7 @@ static void dump_smbios(struct backend *be, size_t dptr) write_data(be, (const void *)smb->dmi.tbladdr, smb->dmi.tbllen); } -static void dump_old_dmi(struct backend *be, size_t dptr) +static void dump_old_dmi(struct upload_backend *be, size_t dptr) { const struct dmi_header *dmi = (void *)dptr; struct fake { @@ -108,7 +108,7 @@ static void dump_old_dmi(struct backend *be, size_t dptr) write_data(be, (const void *)dmi->tbladdr, dmi->tbllen); } -void dump_dmi(struct backend *be) +void dump_dmi(struct upload_backend *be) { size_t dptr; diff --git a/com32/sysdump/main.c b/com32/sysdump/main.c index d0d40a7b..4931024a 100644 --- a/com32/sysdump/main.c +++ b/com32/sysdump/main.c @@ -20,7 +20,7 @@ #include <console.h> #include <sys/cpu.h> #include "../../version.h" -#include "backend.h" +#include "../libupload/upload_backend.h" #include "sysdump.h" const char program[] = "sysdump"; @@ -32,7 +32,7 @@ __noreturn die(const char *msg) exit(1); } -static void dump_all(struct backend *be, const char *argv[]) +static void dump_all(struct upload_backend *be, const char *argv[]) { cpio_init(be, argv); @@ -50,20 +50,20 @@ static void dump_all(struct backend *be, const char *argv[]) flush_data(be); } -static struct backend *backends[] = +static struct upload_backend *upload_backends[] = { - &be_tftp, - &be_ymodem, - &be_srec, + &upload_tftp, + &upload_ymodem, + &upload_srec, NULL }; __noreturn usage(void) { - struct backend **bep, *be; + struct upload_backend **bep, *be; printf("Usage:\n"); - for (bep = backends ; (be = *bep) ; bep++) + for (bep = upload_backends ; (be = *bep) ; bep++) printf(" %s %s %s\n", program, be->name, be->helpmsg); exit(1); @@ -71,7 +71,7 @@ __noreturn usage(void) int main(int argc, char *argv[]) { - struct backend **bep, *be; + struct upload_backend **bep, *be; openconsole(&dev_null_r, &dev_stdcon_w); fputs(version, stdout); @@ -79,7 +79,7 @@ int main(int argc, char *argv[]) if (argc < 2) usage(); - for (bep = backends ; (be = *bep) ; bep++) { + for (bep = upload_backends ; (be = *bep) ; bep++) { if (!strcmp(be->name, argv[1])) break; } diff --git a/com32/sysdump/memmap.c b/com32/sysdump/memmap.c index 251107d5..7a21a312 100644 --- a/com32/sysdump/memmap.c +++ b/com32/sysdump/memmap.c @@ -7,7 +7,7 @@ #include <stdlib.h> #include <com32.h> #include "sysdump.h" -#include "backend.h" +#include "../libupload/upload_backend.h" #define E820_CHUNK 128 struct e820_info { @@ -16,7 +16,7 @@ struct e820_info { uint8_t data[24]; }; -static void dump_e820(struct backend *be) +static void dump_e820(struct upload_backend *be) { com32sys_t ireg, oreg; struct e820_info *curr; @@ -63,7 +63,7 @@ static void dump_e820(struct backend *be) lfree(curr); } -void dump_memory_map(struct backend *be) +void dump_memory_map(struct upload_backend *be) { com32sys_t ireg, oreg; diff --git a/com32/sysdump/memory.c b/com32/sysdump/memory.c index 6552e7f3..20b20c63 100644 --- a/com32/sysdump/memory.c +++ b/com32/sysdump/memory.c @@ -7,7 +7,7 @@ #include <stdlib.h> #include <sys/cpu.h> #include "sysdump.h" -#include "backend.h" +#include "../libupload/upload_backend.h" static char *lowmem; static size_t lowmem_len; @@ -29,7 +29,7 @@ void snapshot_lowmem(void) } } -static void dump_memory_range(struct backend *be, const void *where, +static void dump_memory_range(struct upload_backend *be, const void *where, const void *addr, size_t len) { char filename[32]; @@ -38,7 +38,7 @@ static void dump_memory_range(struct backend *be, const void *where, cpio_writefile(be, filename, where, len); } -void dump_memory(struct backend *be) +void dump_memory(struct upload_backend *be) { printf("Dumping memory... "); diff --git a/com32/sysdump/pci.c b/com32/sysdump/pci.c index 1d687279..7646a75d 100644 --- a/com32/sysdump/pci.c +++ b/com32/sysdump/pci.c @@ -7,9 +7,9 @@ #include <stdlib.h> #include <sys/pci.h> #include "sysdump.h" -#include "backend.h" +#include "../libupload/upload_backend.h" -static void dump_pci_device(struct backend *be, pciaddr_t a, uint8_t hdrtype) +static void dump_pci_device(struct upload_backend *be, pciaddr_t a, uint8_t hdrtype) { unsigned int bus = pci_bus(a); unsigned int dev = pci_dev(a); @@ -31,7 +31,7 @@ static void dump_pci_device(struct backend *be, pciaddr_t a, uint8_t hdrtype) cpio_writefile(be, filename, data, sizeof data); } -void dump_pci(struct backend *be) +void dump_pci(struct upload_backend *be) { int cfgtype; unsigned int nbus, ndev, nfunc, maxfunc; diff --git a/com32/sysdump/serial.c b/com32/sysdump/serial.c deleted file mode 100644 index a3987531..00000000 --- a/com32/sysdump/serial.c +++ /dev/null @@ -1,169 +0,0 @@ -#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); -} diff --git a/com32/sysdump/serial.h b/com32/sysdump/serial.h deleted file mode 100644 index 356f2cef..00000000 --- a/com32/sysdump/serial.h +++ /dev/null @@ -1,19 +0,0 @@ -#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 */ diff --git a/com32/sysdump/srecsend.h b/com32/sysdump/srecsend.h deleted file mode 100644 index 667be20d..00000000 --- a/com32/sysdump/srecsend.h +++ /dev/null @@ -1,9 +0,0 @@ -#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 */ diff --git a/com32/sysdump/sysdump.h b/com32/sysdump/sysdump.h index a5b963f8..15bb899d 100644 --- a/com32/sysdump/sysdump.h +++ b/com32/sysdump/sysdump.h @@ -1,15 +1,15 @@ #ifndef SYSDUMP_H #define SYSDUMP_H -struct backend; +struct upload_backend; -void dump_memory_map(struct backend *); +void dump_memory_map(struct upload_backend *); void snapshot_lowmem(void); -void dump_memory(struct backend *); -void dump_dmi(struct backend *); -void dump_acpi(struct backend *); -void dump_cpuid(struct backend *); -void dump_pci(struct backend *); -void dump_vesa_tables(struct backend *); +void dump_memory(struct upload_backend *); +void dump_dmi(struct upload_backend *); +void dump_acpi(struct upload_backend *); +void dump_cpuid(struct upload_backend *); +void dump_pci(struct upload_backend *); +void dump_vesa_tables(struct upload_backend *); #endif /* SYSDUMP_H */ diff --git a/com32/sysdump/vesa.c b/com32/sysdump/vesa.c index 017f9e4f..aebed182 100644 --- a/com32/sysdump/vesa.c +++ b/com32/sysdump/vesa.c @@ -1,10 +1,10 @@ #include <string.h> #include <stdio.h> #include "../lib/sys/vesa/vesa.h" -#include "backend.h" +#include "../libupload/upload_backend.h" #include "sysdump.h" -void dump_vesa_tables(struct backend *be) +void dump_vesa_tables(struct upload_backend *be) { com32sys_t rm; struct vesa_info *vip; diff --git a/com32/sysdump/ymodem.txt b/com32/sysdump/ymodem.txt deleted file mode 100644 index 2264ff78..00000000 --- a/com32/sysdump/ymodem.txt +++ /dev/null @@ -1,2108 +0,0 @@ - - - - - 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 - diff --git a/com32/sysdump/zout.c b/com32/sysdump/zout.c deleted file mode 100644 index ece934cc..00000000 --- a/com32/sysdump/zout.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 "backend.h" -#include "ctime.h" - -#define ALLOC_CHUNK 65536 - -int init_data(struct 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 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 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 backend *be) -{ - int rv = Z_OK; - - while (rv != Z_STREAM_END) { - rv = do_deflate(be, Z_FINISH); - if (rv < 0) - return -1; - } - - printf("Uploading data, %u bytes... ", be->zbytes); - - if (be->write(be)) - return -1; - - free(be->outbuf); - be->outbuf = NULL; - be->dbytes = be->zbytes = be->alloc = 0; - - printf("done.\n"); - return 0; -} |