1: /*
2: * minirb.c By Chuck Forsberg Omen Technology INC
3: * "The High Reliability Communications Software"
4: *
5: * A bootstrap program for Unix to receive files from computers running
6: * YMODEM Batch (Professional-YAM, PowerCom, ZCOMM, etc.).
7: *
8: * Minirb uses system(3) to call stty, avoiding system dependent code.
9: * program strips CR and CPMEOF (^Z) characters (see putsec()).
10: * Please refer to rz.c for comments, etc.
11: */
12: char * Version = "minirb 2.00 05-25-87";
13:
14: #include <stdio.h>
15: #include <signal.h>
16: #include <setjmp.h>
17:
18: #define OK 0
19: #define FALSE 0
20: #define TRUE 1
21: #define ERROR (-1)
22: #define CAN ('X'&037)
23: #define SOH 1
24: #define STX 2
25: #define EOT 4
26: #define ACK 6
27: #define NAK 025
28: #define TIMEOUT (-2)
29: #define RETRYMAX 9
30: #define WCEOT (-10)
31:
32: FILE *fout;
33: long Bytesleft;
34: int Blklen;
35: char secbuf[1024];
36: char linbuf[1024];
37: int Lleft=0;
38: jmp_buf tohere;
39:
40: alrm() { longjmp(tohere, -1); }
41:
42: bibi(n) {
43: canit(); mode(0);
44: fprintf(stderr, "minirb: caught signal %d; exiting", n);
45: exit(128+n);
46: }
47:
48: mode(n) {
49: if (n) system("stty raw -echo");
50: else system("stty echo -raw");
51: }
52:
53: main() {
54: mode(1);
55: if (signal(SIGINT, bibi) == SIG_IGN) {
56: signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
57: } else {
58: signal(SIGINT, bibi); signal(SIGKILL, bibi);
59: }
60: printf("minirb: Now send file(s) with \042sb file ...\042 command\r\n");
61:
62: if (wcreceive()==ERROR)
63: canit();
64: mode(0); exit(0);
65: }
66:
67: wcreceive() {
68: for (;;) {
69: if (wcrxpn(secbuf) == ERROR) break;
70: if (secbuf[0]==0) return OK;
71: if (procheader(secbuf)==ERROR || wcrx()==ERROR) break;
72: }
73: canit(); return ERROR;
74: }
75:
76:
77: wcrxpn(rpn) char *rpn; {
78: register c;
79:
80: purgeline();
81: et_tu:
82: sendline(NAK); Lleft=0;
83: while ((c = wcgetsec(rpn, 100)) != 0) {
84: if (c == WCEOT) { sendline(ACK); Lleft=0; readline(1); goto et_tu; }
85: return ERROR;
86: }
87: sendline(ACK); return OK;
88: }
89:
90: wcrx() {
91: register int sectnum, sectcurr, sendchar, cblklen;
92:
93: sectnum=0; sendchar=NAK;
94: for (;;) {
95: sendline(sendchar); Lleft=0;
96: sectcurr=wcgetsec(secbuf, 50);
97: if (sectcurr==(sectnum+1 & 0377)) {
98: sectnum++; cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
99: putsec(secbuf, cblklen);
100: if ((Bytesleft-=cblklen) < 0) Bytesleft = 0;
101: sendchar=ACK;
102: }
103: else if (sectcurr==(sectnum&0377)) sendchar=ACK;
104: else if (sectcurr==WCEOT) {
105: if (fclose(fout)==ERROR) return ERROR;
106: sendline(ACK); Lleft=0; return OK;
107: }
108: else if (sectcurr==ERROR) return ERROR;
109: else return ERROR;
110: }
111: }
112:
113: wcgetsec(rxbuf, maxtime) char *rxbuf; int maxtime; {
114: register checksum, wcj, firstch; register char *p; int sectcurr, errors;
115: for (errors=0; errors<RETRYMAX; errors++) {
116: if ((firstch=readline(maxtime))==STX) { Blklen=1024; goto get2; }
117: if (firstch==SOH) {
118: Blklen=128;
119: get2:
120: sectcurr=readline(1); checksum=0;
121: if ((sectcurr+(readline(1)))==0377) {
122: for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
123: if ((firstch=readline(1)) < 0) goto bilge;
124: checksum += (*p++ = firstch);
125: }
126: if ((firstch=readline(1)) < 0) goto bilge;
127: if (((checksum-firstch)&0377)==0) return sectcurr;
128: }
129: }
130: else if (firstch==EOT) return WCEOT;
131: else if (firstch==CAN) return ERROR;
132: bilge:
133: while(readline(1)!=TIMEOUT)
134: ;
135: maxtime=40; sendline(NAK); Lleft=0;
136: }
137: canit(); return ERROR;
138: }
139:
140: readline(timeout) int timeout; {
141: register n; static char *cdq;
142:
143: if (--Lleft >= 0) return (*cdq++ & 0377);
144: n = timeout/10;
145: if (n < 2) n = 3;
146: if (setjmp(tohere)) { Lleft = 0; return TIMEOUT; }
147: signal(SIGALRM, alrm); alarm(n);
148: Lleft=read(0, cdq=linbuf, 1024); alarm(0);
149: if (Lleft < 1) return TIMEOUT;
150: --Lleft; return (*cdq++ & 0377);
151: }
152:
153: purgeline() { Lleft = 0; lseek(0, 0L, 2); }
154:
155:
156: (name) char *name; {
157: register char *p;
158:
159: Bytesleft = 2000000000L; p = name + 1 + strlen(name);
160: if (*p) sscanf(p, "%ld", &Bytesleft);
161: if ((fout=fopen(name, "w")) == NULL) return ERROR;
162: return OK;
163: }
164:
165: putsec(p, n) char *p; int n;
166: { for (; --n>=0; ++p) if (*p != 015 && *p != 032) putc(*p, fout); }
167:
168: sendline(c) { char d; d = c; write(1, &d, 1); }
169:
170: char canistr[] = { 24,24,24,24,24,24,24,24,0 };
171:
172: canit() { printf(canistr); Lleft=0; }
173:
174: /* END of minirb.c */
Defined functions
alrm
defined in line
40; used 1 times
bibi
defined in line
42; used 3 times
main
defined in line
53;
never used
mode
defined in line
48; used 3 times
defined in line
156; used 1 times
wcrx
defined in line
90; used 1 times
Defined variables
Lleft
defined in line
37; used 12 times
Defined macros
ACK
defined in line
26; used 5 times
CAN
defined in line
22; used 1 times
EOT
defined in line
25; used 1 times
ERROR
defined in line
21; used 14 times
FALSE
defined in line
19;
never used
NAK
defined in line
27; used 3 times
OK
defined in line
18; used 4 times
SOH
defined in line
23; used 1 times
STX
defined in line
24; used 1 times
TRUE
defined in line
20;
never used
WCEOT
defined in line
30; used 3 times