|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 3284 (0xcd4) Types: TextFile Notes: UNIX file Names: »cuxcvr.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/cu/cuxcvr.c«
/* * The transceiver code that is used by CU * on the remote system to send/receive files. */ #include <stdio.h> #include "cu.h" #include <sgtty.h> static struct sgttyb new, old; char *receive(); char *send(); main(argc, argv) int argc; char *argv[]; { register int i, estat; register char *s; register char * (*func)(); if (argc < 3) usage(); switch (*argv[1]) { case 'r': func = receive; break; case 's': func = send; break; default: usage(); } init(); estat = 0; for (i = 2; i < argc; i++) if ((s = (*func)(argv[i])) != NULL) { estat++; break; } endpkt(s==NULL ? "END" : s, 1); gexit(estat); } /* * This code sits on the remote system * and acts as a transmitter. It allows * CU to receive a file on its local system. */ char * receive(ifile) char *ifile; { register int n; register unsigned seqno; register char *ofile; register FILE *fp; ofile = basename(ifile); if ((n = strlen(ofile)) > NPKT) return ("file name too long"); if ((fp = fopen(ifile, "r")) == NULL) return ("cannot open file"); xpkt.p_type = 'F'; xpkt.p_len = n + 1 + 3; xpkt.p_seq[0] = xpkt.p_seq[1] = 0; strncpy(&xpkt.p_data[0], ofile, NPKT); sendpkt(&xpkt); for (seqno = 0; ; seqno++) { xpkt.p_type = 'I'; xpkt.p_seq[0] = seqno&0xFF; xpkt.p_seq[1] = seqno>>8; if ((n = fread(xpkt.p_data, 1, NPKT, fp)) <= 0) break; xpkt.p_len = n + 3; sendpkt(&xpkt); } fclose(fp); return (NULL); } /* * This code sits on the remote system and * is the receiver. It enables CU to send * a file to this remote system from its * local system. */ char * send(ifile) char *ifile; { register char *ofile; register PKT *rpp; register unsigned seqno; register int n; FILE *fp; ofile = basename(ifile); if ((n = strlen(ifile)) > NPKT) return ("file name too long"); if ((fp = fopen(ofile, "w")) == NULL) return ("cannot create file", 1); xpkt.p_type = 'F'; xpkt.p_len = n + 1 + 3; xpkt.p_seq[0] = xpkt.p_seq[1] = 0; strncpy(&xpkt.p_data[0], ifile, NPKT); putpkt(&xpkt); seqno = 0; for (;;) { rpp = rcvpkt(seqno); switch (rpp->p_type) { case 'F': ackpkt(); fclose(fp); return (NULL); case 'I': seqno++; fwrite(rpp->p_data, 1, rpp->p_len-3, fp); break; case 'A': break; default: nakpkt(); continue; } ackpkt(); } /* NOTREACHED */ } /* * Extract base name from a file. */ basename(s) register char *s; { register char *cp; for (cp=s; *cp!='\0'; cp++) ; while (cp>s && *--cp!='/') ; if (*cp == '/') cp++; return (cp); } /* * Initialise the serial port (standard output) * for sending/receiving of data. */ init() { pktinit(); ioctl(1, TIOCGETP, &old); new = old; new.sg_flags |= RAW; new.sg_flags &= ~(ECHO|CRMOD); ioctl(1, TIOCSETN, &new); } /* * When an end packet is received, come * here for common cleanup. */ doend(pp) register PKT *pp; { if (pp != NULL) endpkt(pp->p_data, 0); gexit(0); } /* * Exit with status but after * resetting the serial port to * a known state. */ gexit(s) int s; { ioctl(1, TIOCSETN, &old); exit(s); } /* * Serial put command. */ sput(c) { putchar(c); } /* * Serial get a character. */ sget() { return (getchar()); } usage() { fprintf(stderr, "Usage: /etc/cuxcvr [rs] file ...\n"); exit(1); }