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] -----