home *** CD-ROM | disk | FTP | other *** search
- From: Frank D. Cringle <fdc@cliwe.ping.de>
- Date: Tue, 30 Aug 94 09:40:15 +0200
- Message-Id: <9408300740.AA08233@cliwe.ping.de>
- To: jeff@vela.acs.oakland.edu
- Subject: Submission for CP/M archives
-
- Here is a unix equivalent to the epslink.azm program in the epson area of the
- archives. It may be useful for folks who want to transfer files between unix
- machines and epson PX-8's without needing to install xmodem or kermit or
- whatever on their PX-8. Other than that I reverse-engineered it from
- filink.com on my PX-8, its all my own work and I hereby donate it to the
- public domain.
-
- I am submitting this as a shell archive, because it is aimed at unix users.
- Feel free to convert it if you want to conform to some other convention.
-
- Submitted-by: fdc@cliwe.ping.de
- Archive-name: filink-0.01/part01
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is filink-0.01, a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 08/30/1994 07:37 UTC by fdc@cliwe.ping.de
- # Source directory /tmp/filink-0.01
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 1892 -rw-rw-r-- README
- # 112 -rw-rw-r-- Makefile
- # 7054 -rw-rw-r-- filink.c
- #
- # ============= README ==============
- if test -f 'README' -a X"$1" != X"-c"; then
- echo 'x - skipping README (File already exists)'
- else
- echo 'x - extracting README (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'README' &&
- Transfer files between a unix machine and an Epson PX-8 (Geneva)
- ================================================================
- X
- filink.c implements the file transfer protocol which is built into
- the Epson PX-8 (a portable CP/M machine of early '80s vintage).
- X
- It is designed to be called as a file-transfer subprocess by some
- other program that is talking to the PX-8. This might be cu or tip
- or, best of all, pcomm.
- X
- The user interface of filink is, well, spartan. If filink is executed
- without parameters it expects to receive one or more files from the
- PX-8. If you give it some command-line arguments (which may have been
- wildcard-expanded by a shell), it will interpret them as filenames and
- try to send them to the PX-8.
- X
- Using filing from tip:
- ~Cfilink # receive files
- ~Cfilink list of files # send files
- X
- Using filink from cu (only works with gnu (Taylor) cu):
- ~+filink # receive files
- ~+filink list of files # send files
- X
- Using filink from pcomm:
- First install filink as an external protocol -
- type ctrl-A S 6, then enter filink for upload and download as shown:
- X
- X UPLOAD
- X
- X Name Command line Requires file list?
- X 1) zmodem zmtx Y
- X 2) kermit kermit -ivs Y
- X 3) filink filink Y
- X
- X DOWNLOAD
- X
- X Name Command line Requires file list?
- X 4) zmodem zmrx -o N
- X 5) kermit kermit -ivr Y
- X 6) filink filink N
- X
- You can now transfer files by typing ctrl-A <up-arrow> to upload to
- the PX-8 or ctrl-A <down-arrow> to download files to the unix machine.
- X
- X
- Frank Cringle
- fdc@cliwe.ping.de
- SHAR_EOF
- chmod 0664 README ||
- echo 'restore of README failed'
- Wc_c="`wc -c < 'README'`"
- test 1892 -eq "$Wc_c" ||
- echo 'README: original size 1892, current size' "$Wc_c"
- fi
- # ============= Makefile ==============
- if test -f 'Makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping Makefile (File already exists)'
- else
- echo 'x - extracting Makefile (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
- CC = gcc
- CFLAGS = -O2 -g -Wall
- X
- filink: filink.o
- X
- install: filink
- X mv filink /usr/local/bin
- SHAR_EOF
- chmod 0664 Makefile ||
- echo 'restore of Makefile failed'
- Wc_c="`wc -c < 'Makefile'`"
- test 112 -eq "$Wc_c" ||
- echo 'Makefile: original size 112, current size' "$Wc_c"
- fi
- # ============= filink.c ==============
- if test -f 'filink.c' -a X"$1" != X"-c"; then
- echo 'x - skipping filink.c (File already exists)'
- else
- echo 'x - extracting filink.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'filink.c' &&
- /* filink.c - transfer files between unix and an Epson PX-8 */
- X
- /* This program is in the public domain. If it doesn't work or causes */
- /* you grief in any way, blame the public, not me! */
- /* Frank Cringle, August 1994 */
- X
- /* The best way to compile this is with gcc on a sysv-like machine. */
- /* If that is not what you have available, try to get as close as */
- /* possible - use the sys5 universe or /usr/5bin/cc or whatever. */
- X
- /* Version 0.01 */
- X
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <termios.h>
- #include <string.h>
- #include <ctype.h>
- X
- struct termios cookedtio, rawtio;
- X
- #define GOTTIO 1
- #define ISATTY 2
- #define ISRAW 4
- int ttyflags;
- X
- /* put the tty back to normal mode */
- static void
- ttycooked(void)
- {
- X tcflush(0, TCIOFLUSH);
- X if (ttyflags & ISRAW) {
- X tcsetattr(fileno(stdin), TCSAFLUSH, &cookedtio);
- X putc('\n', stdout);
- X ttyflags &= ~ISRAW;
- X }
- }
- X
- /* set up the tty (stdin/stdout) to transfer all 8-bit characters */
- static void
- ttyraw(void)
- {
- X if (!(ttyflags & GOTTIO) && isatty(fileno(stdin))) {
- X ttyflags = ISATTY|GOTTIO;
- X tcflush(0, TCIOFLUSH);
- X if (tcgetattr(fileno(stdin), &cookedtio) != 0) {
- X perror("tcgetattr");
- X exit(1);
- X }
- X rawtio = cookedtio;
- X rawtio.c_iflag = 0;
- X rawtio.c_oflag &= ~(OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
- X rawtio.c_lflag = 0;
- X memset(rawtio.c_cc, 0, NCCS);
- X rawtio.c_cc[VMIN] = 0; /* read returns as soon as data */
- X /* is available */
- X rawtio.c_cc[VTIME] = 1; /* or after 1 tenth of a */
- X /* second at the latest*/
- X }
- X if ((ttyflags & (ISATTY | ISRAW)) == ISATTY) {
- X tcsetattr(fileno(stdin), TCSAFLUSH, &rawtio);
- X ttyflags |= ISRAW;
- X }
- X
- X /* reset to normal before exit. If your C library does not */
- X /* have atexit(), you should install ttycooked as a handler */
- X /* for SIGINT, SIGHUP, etc. */
- X atexit(ttycooked);
- }
- X
- /* print timeout message and quit */
- static void
- noanswer(int state, int who)
- {
- X fprintf(stderr, "%s not responding in state %d\r\n",
- X who == 'R' ? "Receiver" : "Sender", state);
- X exit(1);
- }
- X
- /* send a character with error checking */
- static void
- send(char c)
- {
- X if (write(1, &c, 1) != 1) {
- X perror("stdout");
- X exit(1);
- X }
- }
- X
- /* get a character
- X (give up and return -1 after trys*0.1 secs if trys is positive) */
- static int
- get(int trys)
- {
- X char c;
- X
- X do {
- X if (trys <= 0)
- X trys = -1;
- X switch (read(0, &c, 1)) {
- X case 1: return c & 0xff;
- X case 0: break;
- X default:
- X perror("stdin");
- X exit(1);
- X }
- X } while (--trys);
- X return -1;
- }
- X
- /* send named file */
- static void
- sendfile(char *name)
- {
- X FILE *f;
- X char buf[128];
- X int bufc = 0;
- X char fn[12];
- X char *p = name;
- X int csum = 0, i, state = 1;
- X
- X if ((f = fopen(name, "r")) == NULL) {
- X perror(name);
- X return;
- X }
- X /* strip path */
- X if ((p = strrchr(name, '/')) != NULL)
- X p++;
- X else
- X p = name;
- X /* convert name to upper case (max 8 chars) */
- X for (i = 0; i < 8 && *p && *p != '.'; i++) {
- X fn[i] = toupper(*p);
- X p++;
- X }
- X while (i < 8)
- X fn[i++] = ' ';
- X /* skip to extension (if there is one) */
- X while (*p && *p != '.')
- X p++;
- X if (*p == '.')
- X p++;
- X /* copy and convert extension */
- X for (i = 8; i < 11 && *p; i++) {
- X fn[i] = toupper(*p);
- X p++;
- X }
- X while (i < 11)
- X fn[i++] = ' ';
- X fn[11] = 0;
- X p = fn;
- X
- X while (1)
- X switch (state) {
- X case 1: send('R');
- X switch (get(50)) {
- X case 'S':
- X state = 2;
- X break;
- X case -1:
- X fputs("Receiver not ready\r\n", stderr);
- X }
- X break;
- X case 2: send('G');
- X state = 3;
- X break;
- X case 3: send(4);
- X switch (get(20)) {
- X case 8: state = 4;
- X break;
- X case -1:
- X noanswer(state, 'R');
- X }
- X break;
- X case 4: if (*p == 0)
- X state = 5;
- X else {
- X send(*p);
- X if ((i = get(20)) == *p)
- X p++;
- X else if (i == -1)
- X noanswer(state, 'R');
- X else
- X state = 3;
- X }
- X break;
- X case 5: send(5);
- X switch (get(20)) {
- X case 9: state = 6;
- X break;
- X case -1:
- X noanswer(state, 'R');
- X default:
- X state = 3;
- X }
- X break;
- X case 6: if (bufc == 0 && feof(f)) {
- X send(3);
- X state = 9;
- X }
- X else {
- X send(2);
- X switch (get(20)) {
- X case -1:
- X noanswer(state, 'R');
- X case 'P':
- X state = 7;
- X }
- X }
- X break;
- X case 7: if (bufc == 0) {
- X memset(buf, 0x1a, 128);
- X fread(buf, 128, 1, f);
- X bufc = 128;
- X csum = 0;
- X }
- X csum ^= buf[128 - bufc];
- X send(buf[128 - bufc--]);
- X state = bufc ? 7 : 8;
- X break;
- X case 8: send(csum);
- X switch (get(20)) {
- X case 'B':
- X state = 6;
- X bufc = 128;
- X break;
- X case 'G':
- X state = 6;
- X bufc = 0;
- X break;
- X case -1:
- X noanswer(state, 'R');
- X default:
- X state = 8;
- X break;
- X }
- X break;
- X case 9: send(19);
- X return;
- X }
- }
- X
- /* receive however many files the other guy wants to send */
- static void
- receivefile(void)
- {
- X FILE *f = NULL;
- X char buf[128], name[13], *p = NULL;
- X int bufc = 0;
- X int c, csum = 0, i = 0, state = 1;
- X
- X while (1)
- X switch (state) {
- X case 1: switch (get(50)) {
- X case 'R':
- X send('S');
- X state = 2;
- X break;
- X case -1:
- X fputs("Sender not ready\r\n", stderr);
- X }
- X break;
- X case 2: switch (get(20)) {
- X case 'G':
- X state = 3;
- X break;
- X case -1:
- X noanswer(state, 'S');
- X }
- X break;
- X case 3: switch (get(20)) {
- X case 4: send(8);
- X p = name;
- X i = 0;
- X state = 4;
- X break;
- X case 19:
- X exit(0);
- X case -1:
- X noanswer(state, 'S');
- X default:
- X send('X');
- X }
- X break;
- X case 4: if ((c = get(20)) == -1)
- X noanswer(state, 'S');
- X /* pick up filename and convert it to */
- X /* lower case */
- X if (c < ' ' || i >= 11) {
- X send('X');
- X state = 3;
- X }
- X else {
- X if (++i == 8)
- X *p++ = '.';
- X if (c != ' ')
- X *p++ = tolower(c & 0x7f);
- X send(c);
- X }
- X if (i == 11) {
- X *p = 0;
- X if (p > name && p[-1] == '.')
- X p[-1] = 0;
- X state = 5;
- X }
- X break;
- X case 5: switch (get(20)) {
- X case 5: if ((f = fopen(name, "w")) == NULL) {
- X perror(name);
- X send('X');
- X state = 3;
- X /* protocol weakness: there is */
- X /* no way to say "this ain't */
- X /* never gonna work" */
- X }
- X else {
- X send(9);
- X state = 6;
- X }
- X break;
- X case -1:
- X noanswer(state, 'S');
- X default:
- X send('X');
- X state = 3;
- X }
- X break;
- X case 6: switch (get(20)) {
- X case 2: send('P');
- X p = buf;
- X bufc = 0;
- X csum = 0;
- X state = 7;
- X break;
- X case 3: fclose(f);
- X state = 3;
- X break;
- X case -1:
- X noanswer(state, 'S');
- X default:
- X send('N');
- X }
- X break;
- X case 7: if ((c = get(20)) == -1)
- X noanswer(state, 'S');
- X *p++ = c;
- X csum ^= c;
- X if (++bufc == 128)
- X state = 8;
- X break;
- X case 8: if ((c = get(20)) == -1)
- X noanswer(state, 'S');
- X if (c != csum)
- X send('B');
- X else {
- X if (fwrite(buf, 128, 1, f) == 0) {
- X perror(name);
- X exit(1);
- X }
- X send('G');
- X }
- X state = 6;
- X break;
- X }
- X return;
- }
- X
- int
- main(int argc, char **argv)
- {
- X int i;
- X
- X ttyraw();
- X if (argc == 1)
- X receivefile();
- X else
- X for (i = 1; i < argc; i++)
- X sendfile(argv[i]);
- X ttycooked();
- X exit(0);
- }
- SHAR_EOF
- chmod 0664 filink.c ||
- echo 'restore of filink.c failed'
- Wc_c="`wc -c < 'filink.c'`"
- test 7054 -eq "$Wc_c" ||
- echo 'filink.c: original size 7054, current size' "$Wc_c"
- fi
- exit 0
-
- Frank Cringle | fdc@cliwe.ping.de
- Phone +49 2304 45565 |
-
-