info-mac@uw-beaver (info-mac) (12/01/84)
From: Ed Pattermann <PATTERMANN@SUMEX-AIM.ARPA>
I had thought someone at Utah was doing a MACPUT/MACGET for Tops20. Is
that true? Wasn't there also someone considering modifying the Tops20
MODEM program (by Bill Westfield) to download resource and data forks?
-- Ed
---------------
Date: Tue 27 Nov 84 19:12:49-EST
From: S.BOY-BOYCE-GEORGE%CRNL20A.BITNET@Berkeley
Subject: macget/put
To: patterman@sumex-aim.ARPA
Has anyone ported macget/put to TOPS-20. I made one attempt (using the Utah C
package) but it didn't seem to fly. Any ideas?
Address: Cornell Computer Services, Cornell University, Ithaca NY, 14851
s.boy@crnl20a.bitnet,george@cornell.arpa,gboydecy@cornella.bitnet
-------
-------info-mac@uw-beaver (info-mac) (12/01/84)
From: Dan Tappan <Tappan@BBNG.ARPA>
I have a hacked up MACGET for TOPS20, compiles with the MIT C compiler.
It is below if anyone can use it. I have not done MACPUT.
-----
#include <stdio.h>
#define RECORDBYTES 132
#define DATABYTES 128
#define NAMEBYTES 63
#define RETRIES 15
#define SOHTIMO 60
#define LINTIMO 60
#define CHRTIMO 10
#define MAXRECNO 0xff
#define BYTEMASK 0xff
#define TMO -1
#define DUP '\000'
#define SOH '\001'
#define EOT '\004'
#define ACK '\006'
#define NAK '\025'
#define CAN '\030'
#define EEF '\032'
#define ESC '\033'
#define H_NLENOFF 1
#define H_NAMEOFF 2
#define H_TYPEOFF 65
#define H_AUTHOFF 69
#define H_DLENOFF 81
#define H_RLENOFF 85
#define TEXT 0
#define DATA 1
#define RSRC 2
#define FULL 3
int mode, txtmode;
struct macheader {
char m_name[NAMEBYTES+1];
char m_type[4];
char m_author[4];
int m_datalen;
int m_rsrclen;
} mh;
struct filenames {
char f_info[256];
char f_data[256];
char f_rsrc[256];
} files;
int lastack;
char buf[DATABYTES];
/*
* macget -- receive file from macintosh using xmodem protocol
*
* (c) 1984 Brown University Computer Science
* may be used but not sold without permission
* written by Dave Johnson 5/22/84
* revised ddj 6/29/84
*
* Converted tops20 (mit c) 7/31/84, took out all timeout
* stuff (signal not supported), only binary mode transfers
* supported.
*/
char usage[] = "usage: \"macget [-rdu] [filename]\"\n";
static recv_file(), recv_hdr();
main(ac, av)
char **av;
{
char *name;
mode = FULL;
name = "";
ac--; av++;
while (ac) {
if (av[0][0] == '-') {
switch (av[0][1]) {
case 'R':
case 'r':
mode = RSRC;
break;
case 'D':
case 'd':
mode = DATA;
break;
case 'U':
case 'u':
mode = TEXT;
break;
default:
fprintf(stderr, usage);
exit(1);
}
}
else {
name = av[0];
}
ac--; av++;
}
setup_tty();
if (send_sync() == ACK) {
txtmode = 0;
recv_hdr(name);
if (mode == TEXT) txtmode++;
recv_file(files.f_data, mh.m_datalen, 1);
txtmode = 0;
recv_file(files.f_rsrc, mh.m_rsrclen, 0);
}
reset_tty();
}
static recv_hdr(name)
char *name;
{
int n;
FILE *fp;
char *tmpnam();
char tmpname[50];
char *np;
tmpnam(tmpname);
recv_file(tmpname, DATABYTES, 1);
fp = fopen(tmpname, "r8b");
if (fp == NULL) {
perror("temp file");
cleanup(-1);
}
fread(buf, 1, DATABYTES, fp);
fclose(fp);
if (name && *name) {
n = strlen(name);
if (n > NAMEBYTES) n = NAMEBYTES;
strncpy(mh.m_name, name, n);
mh.m_name[n] = '\0';
}
else {
n = buf[H_NLENOFF] & BYTEMASK;
if (n > NAMEBYTES) n = NAMEBYTES;
strncpy(mh.m_name, buf + H_NAMEOFF, n);
mh.m_name[n] = '\0';
}
for (np = mh.m_name; *np; np++)
if (*np == ' ') *np = '_';
if (mode == FULL) {
sprintf(files.f_info, "%s.info", mh.m_name);
rename(tmpname, files.f_info);
sprintf(files.f_data, "%s.data", mh.m_name);
sprintf(files.f_rsrc, "%s.rsrc", mh.m_name);
}
else {
unlink(tmpname);
switch (mode) {
case RSRC:
sprintf(files.f_data, "/dev/null");
sprintf(files.f_rsrc, "%s.rsrc", mh.m_name);
break;
case DATA:
sprintf(files.f_data, "%s.data", mh.m_name);
sprintf(files.f_rsrc, "/dev/null");
break;
case TEXT:
sprintf(files.f_data, "%s.text", mh.m_name);
sprintf(files.f_rsrc, "/dev/null");
break;
}
}
strncpy(mh.m_type, buf + H_TYPEOFF, 4);
strncpy(mh.m_author, buf + H_AUTHOFF, 4);
mh.m_datalen = get4(buf + H_DLENOFF);
mh.m_rsrclen = get4(buf + H_RLENOFF);
}
static recv_file(fname, bytes, more)
char *fname;
int bytes, more;
{
register int status, n;
FILE *outf;
int naks = 0;
lastack = 0;
outf = fopen(fname, txtmode ? "w" : "w8b");
if (outf == NULL) {
perror(fname);
cleanup(-1);
}
for (;;) {
status = rec_read(buf, DATABYTES);
switch (status) {
case EOT:
tputc(ACK);
if (more)
tputc(NAK);
fclose(outf);
return;
case ACK:
tputc(ACK);
naks = 0;
n = (bytes > DATABYTES) ? DATABYTES : bytes;
bytes -= n;
fwrite(buf, n, 1, outf);
break;
case DUP:
tputc(ACK);
naks = 0;
break;
case NAK:
if (naks++ < RETRIES) {
tputc(NAK);
break;
}
/* fall through */
case CAN:
tputc(CAN);
fclose(outf);
/* unlink fname? */
cleanup(-1);
/* NOTREACHED */
}
}
}
send_sync()
{
int c;
for (;;) {
c = tgetc(60);
switch (c) {
case ESC:
break;
case CAN:
case EOT:
case TMO:
return c;
default:
continue;
}
c = tgetc(1);
if (c != 'a')
continue;
tputc(ACK);
return ACK;
}
}
rec_read(buf, recsize)
char buf[];
int recsize;
{
int c, rec, rec_bar, cksum;
c = tgetc(SOHTIMO);
switch (c) {
case TMO:
return NAK;
case EOT:
return EOT;
case CAN:
return CAN;
case SOH:
/* read header */
rec = tgetc(CHRTIMO);
if (rec == TMO)
return NAK;
rec_bar = tgetc(CHRTIMO);
if (rec_bar == TMO)
return NAK;
/* check header */
if (rec != MAXRECNO - rec_bar) return NAK;
/* fill buffer */
cksum = tgetrec(buf, recsize, LINTIMO);
if (cksum == TMO)
return NAK;
/* get checksum */
c = tgetc(CHRTIMO);
if (c == TMO)
return NAK;
if (c != (cksum & BYTEMASK))
return NAK;
/* check record number */
if (rec == lastack)
return DUP;
if (rec != ((lastack + 1) & MAXRECNO))
return CAN;
else {
lastack = rec;
return ACK;
}
}
/* NOTREACHED */
}
static int ttyfd;
static FILE *ttyf;
tgetrec(buf, count, timeout)
char *buf;
int count, timeout;
{
char *bp;
int i, cksum;
bp = buf; i = count;
while(i-- > 0) *bp++ = tgetc(100);
cksum = 0;
bp = buf;
for (i = 0; i < count; bp++, i++) {
cksum += *bp;
}
return cksum;
}
tgetc(timeout)
int timeout;
{
int c;
c = _BIN(ttyfd);
if (c == -1) /* probably hung up or logged off */
return EOT;
else
return c & BYTEMASK;
}
tputc(c)
char c;
{
_BOUT(ttyfd, c);
}
static int otty;
/* should turn messages off */
setup_tty()
{
int cleanup();
int timedout();
ttyf = stdin;
ttyfd = fileno(stdin);
otty = _RFMOD(ttyfd);
_SFMOD(ttyfd, otty&0777777773477);
_STPAR(ttyfd, otty%0777777777775);
_STIW(0777773, 0);
}
reset_tty()
{
sleep(2); /* should wait for output to drain */
_SFMOD(ttyfd, otty);
_STPAR(ttyfd, otty);
}
cleanup(sig)
int sig;
{
reset_tty();
exit(sig);
}
get4(bp)
char *bp;
{
register int i;
int value = 0;
for (i = 0; i < 4; i++) {
value <<= 8;
value |= (*bp & BYTEMASK);
bp++;
}
return value;
}
-------info-mac@uw-beaver (info-mac) (12/01/84)
From: Dan Tappan <Tappan@BBNG.ARPA>
I have a hacked up MACGET for TOPS20, compiles with the MIT C compiler.
It is below if anyone can use it. I have not done MACPUT.
[Ed. File is on {SUMEX-AIM}<INFO-MAC>MACGET.T20C]
-----