1433d6423SLionel Sambuc #define VERSION "sz 2.12 05-29-88"
2433d6423SLionel Sambuc #define PUBDIR "/usr/spool/uucppublic"
3433d6423SLionel Sambuc
4433d6423SLionel Sambuc /*% cc -compat -M2 -Ox -K -i -DTXBSIZE=16384 -DNFGVMIN -DREADCHECK sz.c -lx -o sz; size sz
5433d6423SLionel Sambuc
6433d6423SLionel Sambuc Following is used for testing, might not be reasonable for production
7433d6423SLionel Sambuc <-xtx-*> cc -Osal -DTXBSIZE=32768 -DSV sz.c -lx -o $B/sz; size $B/sz
8433d6423SLionel Sambuc
9433d6423SLionel Sambuc ****************************************************************************
10433d6423SLionel Sambuc *
11433d6423SLionel Sambuc * sz.c By Chuck Forsberg, Omen Technology INC
12433d6423SLionel Sambuc *
13433d6423SLionel Sambuc ****************************************************************************
14433d6423SLionel Sambuc *
15433d6423SLionel Sambuc * Typical Unix/Xenix/Clone compiles:
16433d6423SLionel Sambuc *
17433d6423SLionel Sambuc * cc -O sz.c -o sz USG (SYS III/V) Unix
18433d6423SLionel Sambuc * cc -O -DSV sz.c -o sz Sys V Release 2 with non-blocking input
19433d6423SLionel Sambuc * Define to allow reverse channel checking
20433d6423SLionel Sambuc * cc -O -DV7 sz.c -o sz Unix Version 7, 2.8 - 4.3 BSD
21433d6423SLionel Sambuc *
22433d6423SLionel Sambuc * cc -O -K -i -DNFGVMIN -DREADCHECK sz.c -lx -o sz Classic Xenix
23433d6423SLionel Sambuc *
24433d6423SLionel Sambuc * ln sz sb **** All versions ****
25433d6423SLionel Sambuc * ln sz sx **** All versions ****
26433d6423SLionel Sambuc *
27433d6423SLionel Sambuc ****************************************************************************
28433d6423SLionel Sambuc *
29433d6423SLionel Sambuc * Typical VMS compile and install sequence:
30433d6423SLionel Sambuc *
31433d6423SLionel Sambuc * define LNK$LIBRARY SYS$LIBRARY:VAXCRTL.OLB
32433d6423SLionel Sambuc * cc sz.c
33433d6423SLionel Sambuc * cc vvmodem.c
34433d6423SLionel Sambuc * link sz,vvmodem
35433d6423SLionel Sambuc * sz :== $disk$user2:[username.subdir]sz.exe
36433d6423SLionel Sambuc *
37433d6423SLionel Sambuc * If you feel adventureous, remove the #define BADSYNC line
38433d6423SLionel Sambuc * immediately following the #ifdef vax11c line! Some VMS
39433d6423SLionel Sambuc * systems know how to fseek, some don't.
40433d6423SLionel Sambuc *
41433d6423SLionel Sambuc ****************************************************************************
42433d6423SLionel Sambuc *
43433d6423SLionel Sambuc *
44433d6423SLionel Sambuc * A program for Unix to send files and commands to computers running
45433d6423SLionel Sambuc * Professional-YAM, PowerCom, YAM, IMP, or programs supporting Y/XMODEM.
46433d6423SLionel Sambuc *
47433d6423SLionel Sambuc * Sz uses buffered I/O to greatly reduce CPU time compared to UMODEM.
48433d6423SLionel Sambuc *
49433d6423SLionel Sambuc * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin
50433d6423SLionel Sambuc *
51433d6423SLionel Sambuc * 2.1x hacks to avoid VMS fseek() bogosity, allow input from pipe
52433d6423SLionel Sambuc * -DBADSEEK -DTXBSIZE=32768
53433d6423SLionel Sambuc * 2.x has mods for VMS flavor
54433d6423SLionel Sambuc *
55433d6423SLionel Sambuc * 1.34 implements tx backchannel garbage count and ZCRCW after ZRPOS
56433d6423SLionel Sambuc * in accordance with the 7-31-87 ZMODEM Protocol Description
57433d6423SLionel Sambuc */
58433d6423SLionel Sambuc
59433d6423SLionel Sambuc
60433d6423SLionel Sambuc #include <sys/types.h>
61433d6423SLionel Sambuc
62433d6423SLionel Sambuc #ifdef vax11c
63433d6423SLionel Sambuc #define BADSEEK
64433d6423SLionel Sambuc #define TXBSIZE 32768 /* Must be power of two, < MAXINT */
65433d6423SLionel Sambuc #include <types.h>
66433d6423SLionel Sambuc #include <stat.h>
67433d6423SLionel Sambuc #define LOGFILE "szlog.tmp"
68433d6423SLionel Sambuc #define OS "VMS"
69433d6423SLionel Sambuc #define READCHECK
70433d6423SLionel Sambuc #define BUFWRITE
71433d6423SLionel Sambuc #define iofd
72433d6423SLionel Sambuc extern int errno;
73433d6423SLionel Sambuc #define SS_NORMAL SS$_NORMAL
74433d6423SLionel Sambuc #define xsendline(c) sendline(c)
75433d6423SLionel Sambuc
76433d6423SLionel Sambuc
77433d6423SLionel Sambuc #else /* vax11c */
78433d6423SLionel Sambuc
79433d6423SLionel Sambuc
80433d6423SLionel Sambuc #define SS_NORMAL 0
81433d6423SLionel Sambuc #define LOGFILE "/tmp/szlog"
82433d6423SLionel Sambuc
83433d6423SLionel Sambuc #define sendline(c) putchar((c) & 0377)
84433d6423SLionel Sambuc #define xsendline(c) putchar(c)
85433d6423SLionel Sambuc
86433d6423SLionel Sambuc #endif
87433d6423SLionel Sambuc
88433d6423SLionel Sambuc #include <signal.h>
89433d6423SLionel Sambuc #include <setjmp.h>
90433d6423SLionel Sambuc #include <ctype.h>
91433d6423SLionel Sambuc #include <errno.h>
92433d6423SLionel Sambuc #include <stdlib.h>
93433d6423SLionel Sambuc #include <string.h>
94433d6423SLionel Sambuc #include <stdlib.h>
95433d6423SLionel Sambuc #include <unistd.h>
96433d6423SLionel Sambuc #include <utime.h>
97433d6423SLionel Sambuc #include <stdio.h>
98433d6423SLionel Sambuc #include <stdarg.h>
99433d6423SLionel Sambuc
100433d6423SLionel Sambuc #define PATHLEN 256
101433d6423SLionel Sambuc #define OK 0
102433d6423SLionel Sambuc #define FALSE 0
103433d6423SLionel Sambuc #define TRUE 1
104433d6423SLionel Sambuc #undef ERROR
105433d6423SLionel Sambuc #define ERROR (-1)
106433d6423SLionel Sambuc /* Ward Christensen / CP/M parameters - Don't change these! */
107433d6423SLionel Sambuc #define ENQ 005
108433d6423SLionel Sambuc #define CAN ('X'&037)
109433d6423SLionel Sambuc #define XOFF ('s'&037)
110433d6423SLionel Sambuc #define XON ('q'&037)
111433d6423SLionel Sambuc #define SOH 1
112433d6423SLionel Sambuc #define STX 2
113433d6423SLionel Sambuc #define EOT 4
114433d6423SLionel Sambuc #define ACK 6
115433d6423SLionel Sambuc #define NAK 025
116433d6423SLionel Sambuc #define CPMEOF 032
117433d6423SLionel Sambuc #define WANTCRC 0103 /* send C not NAK to get crc not checksum */
118433d6423SLionel Sambuc #define WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */
119433d6423SLionel Sambuc #define TIMEOUT (-2)
120433d6423SLionel Sambuc #define RCDO (-3)
121433d6423SLionel Sambuc #define RETRYMAX 10
122433d6423SLionel Sambuc
123433d6423SLionel Sambuc
124433d6423SLionel Sambuc #define HOWMANY 2
125433d6423SLionel Sambuc int Zmodem=0; /* ZMODEM protocol requested by receiver */
126433d6423SLionel Sambuc unsigned Baudrate=2400; /* Default, should be set by first mode() call */
127433d6423SLionel Sambuc unsigned Txwindow; /* Control the size of the transmitted window */
128433d6423SLionel Sambuc unsigned Txwspac; /* Spacing between zcrcq requests */
129433d6423SLionel Sambuc unsigned Txwcnt; /* Counter used to space ack requests */
130433d6423SLionel Sambuc long Lrxpos; /* Receiver's last reported offset */
131433d6423SLionel Sambuc int errors;
132433d6423SLionel Sambuc
133433d6423SLionel Sambuc #ifdef vax11c
134433d6423SLionel Sambuc #include "vrzsz.c" /* most of the system dependent stuff here */
135433d6423SLionel Sambuc #else
136433d6423SLionel Sambuc #include "rbsb.c" /* most of the system dependent stuff here */
137433d6423SLionel Sambuc #endif
138433d6423SLionel Sambuc #include "crctab.c"
139433d6423SLionel Sambuc
140433d6423SLionel Sambuc int Filesleft;
141433d6423SLionel Sambuc long Totalleft;
142433d6423SLionel Sambuc
143433d6423SLionel Sambuc /*
144433d6423SLionel Sambuc * Attention string to be executed by receiver to interrupt streaming data
145433d6423SLionel Sambuc * when an error is detected. A pause (0336) may be needed before the
146433d6423SLionel Sambuc * ^C (03) or after it.
147433d6423SLionel Sambuc */
148433d6423SLionel Sambuc #ifdef READCHECK
149433d6423SLionel Sambuc char Myattn[] = { 0 };
150433d6423SLionel Sambuc #else
151433d6423SLionel Sambuc #ifdef USG
152433d6423SLionel Sambuc char Myattn[] = { 03, 0336, 0 };
153433d6423SLionel Sambuc #else
154433d6423SLionel Sambuc char Myattn[] = { 0 };
155433d6423SLionel Sambuc #endif
156433d6423SLionel Sambuc #endif
157433d6423SLionel Sambuc
158433d6423SLionel Sambuc FILE *in;
159433d6423SLionel Sambuc
160433d6423SLionel Sambuc #ifdef BADSEEK
161433d6423SLionel Sambuc int Canseek = 0; /* 1: Can seek 0: only rewind -1: neither (pipe) */
162433d6423SLionel Sambuc #ifndef TXBSIZE
163433d6423SLionel Sambuc #define TXBSIZE 16384 /* Must be power of two, < MAXINT */
164433d6423SLionel Sambuc #endif
165433d6423SLionel Sambuc #else
166433d6423SLionel Sambuc int Canseek = 1; /* 1: Can seek 0: only rewind -1: neither (pipe) */
167433d6423SLionel Sambuc #endif
168433d6423SLionel Sambuc
169433d6423SLionel Sambuc #ifdef TXBSIZE
170433d6423SLionel Sambuc #define TXBMASK (TXBSIZE-1)
171433d6423SLionel Sambuc char Txb[TXBSIZE]; /* Circular buffer for file reads */
172433d6423SLionel Sambuc char *txbuf = Txb; /* Pointer to current file segment */
173433d6423SLionel Sambuc #else
174433d6423SLionel Sambuc char txbuf[1024];
175433d6423SLionel Sambuc #endif
176433d6423SLionel Sambuc long vpos = 0; /* Number of bytes read from file */
177433d6423SLionel Sambuc
178433d6423SLionel Sambuc char Lastrx;
179433d6423SLionel Sambuc char Crcflg;
180433d6423SLionel Sambuc int Verbose=0;
181433d6423SLionel Sambuc int Modem2=0; /* XMODEM Protocol - don't send pathnames */
182433d6423SLionel Sambuc int Restricted=0; /* restricted; no /.. or ../ in filenames */
183433d6423SLionel Sambuc int Quiet=0; /* overrides logic that would otherwise set verbose */
184433d6423SLionel Sambuc int Ascii=0; /* Add CR's for brain damaged programs */
185433d6423SLionel Sambuc int Fullname=0; /* transmit full pathname */
186433d6423SLionel Sambuc int Unlinkafter=0; /* Unlink file after it is sent */
187433d6423SLionel Sambuc int Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */
188433d6423SLionel Sambuc int firstsec;
189433d6423SLionel Sambuc int errcnt=0; /* number of files unreadable */
190433d6423SLionel Sambuc int blklen=128; /* length of transmitted records */
191433d6423SLionel Sambuc int Optiong; /* Let it rip no wait for sector ACK's */
192433d6423SLionel Sambuc int Eofseen; /* EOF seen on input set by zfilbuf */
193433d6423SLionel Sambuc int BEofseen; /* EOF seen on input set by fooseek */
194433d6423SLionel Sambuc int Totsecs; /* total number of sectors this file */
195433d6423SLionel Sambuc int Filcnt=0; /* count of number of files opened */
196433d6423SLionel Sambuc int Lfseen=0;
197433d6423SLionel Sambuc unsigned Rxbuflen = 16384; /* Receiver's max buffer length */
198433d6423SLionel Sambuc int Tframlen = 0; /* Override for tx frame length */
199433d6423SLionel Sambuc int blkopt=0; /* Override value for zmodem blklen */
200433d6423SLionel Sambuc int Rxflags = 0;
201433d6423SLionel Sambuc long bytcnt;
202433d6423SLionel Sambuc int Wantfcs32 = TRUE; /* want to send 32 bit FCS */
203433d6423SLionel Sambuc char Lzconv; /* Local ZMODEM file conversion request */
204433d6423SLionel Sambuc char Lzmanag; /* Local ZMODEM file management request */
205433d6423SLionel Sambuc int Lskipnocor;
206433d6423SLionel Sambuc char Lztrans;
207433d6423SLionel Sambuc char zconv; /* ZMODEM file conversion request */
208433d6423SLionel Sambuc char zmanag; /* ZMODEM file management request */
209433d6423SLionel Sambuc char ztrans; /* ZMODEM file transport request */
210433d6423SLionel Sambuc int Command; /* Send a command, then exit. */
211433d6423SLionel Sambuc char *Cmdstr; /* Pointer to the command string */
212433d6423SLionel Sambuc int Cmdtries = 11;
213433d6423SLionel Sambuc int Cmdack1; /* Rx ACKs command, then do it */
214433d6423SLionel Sambuc int Exitcode = 0;
215433d6423SLionel Sambuc int Test; /* 1= Force receiver to send Attn, etc with qbf. */
216433d6423SLionel Sambuc /* 2= Character transparency test */
217433d6423SLionel Sambuc char *qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n";
218433d6423SLionel Sambuc long Lastsync; /* Last offset to which we got a ZRPOS */
219433d6423SLionel Sambuc int Beenhereb4; /* How many times we've been ZRPOS'd same place */
220433d6423SLionel Sambuc
221433d6423SLionel Sambuc jmp_buf tohere; /* For the interrupt on RX timeout */
222433d6423SLionel Sambuc jmp_buf intrjmp; /* For the interrupt on RX CAN */
223433d6423SLionel Sambuc
224433d6423SLionel Sambuc void onintr(int sig );
225433d6423SLionel Sambuc int main(int argc , char *argv []);
226433d6423SLionel Sambuc int wcsend(int argc , char *argp []);
227433d6423SLionel Sambuc int wcs(char *oname );
228433d6423SLionel Sambuc int wctxpn(char *name );
229433d6423SLionel Sambuc int getnak(void);
230433d6423SLionel Sambuc int wctx(long flen );
231433d6423SLionel Sambuc int wcputsec(char *buf , int sectnum , int cseclen );
232433d6423SLionel Sambuc int filbuf(char *buf , int count );
233433d6423SLionel Sambuc int zfilbuf(void);
234433d6423SLionel Sambuc int fooseek(FILE *fptr , long pos , int whence );
235433d6423SLionel Sambuc void alrm(int sig );
236433d6423SLionel Sambuc int readline(int timeout );
237433d6423SLionel Sambuc void flushmo(void);
238433d6423SLionel Sambuc void purgeline(void);
239433d6423SLionel Sambuc void canit(void);
240433d6423SLionel Sambuc void zperr();
241433d6423SLionel Sambuc char *substr(char *s , char *t );
242433d6423SLionel Sambuc int usage(void);
243433d6423SLionel Sambuc int getzrxinit(void);
244433d6423SLionel Sambuc int sendzsinit(void);
245433d6423SLionel Sambuc int zsendfile(char *buf , int blen );
246433d6423SLionel Sambuc int zsendfdata(void);
247433d6423SLionel Sambuc int getinsync(int flag );
248433d6423SLionel Sambuc void saybibi(void);
249433d6423SLionel Sambuc void bttyout(int c );
250433d6423SLionel Sambuc int zsendcmd(char *buf , int blen );
251433d6423SLionel Sambuc void chkinvok(char *s );
252433d6423SLionel Sambuc void countem(int argc , char **argv );
253433d6423SLionel Sambuc void chartest(int m );
254433d6423SLionel Sambuc
255433d6423SLionel Sambuc /* called by signal interrupt or terminate to clean things up */
bibi(int n)256433d6423SLionel Sambuc void bibi(int n)
257433d6423SLionel Sambuc {
258433d6423SLionel Sambuc canit(); fflush(stdout); mode(0);
259433d6423SLionel Sambuc fprintf(stderr, "sz: caught signal %d; exiting\n", n);
260433d6423SLionel Sambuc if (n == SIGQUIT)
261433d6423SLionel Sambuc abort();
262433d6423SLionel Sambuc if (n == 99)
263433d6423SLionel Sambuc fprintf(stderr, "mode(2) in rbsb.c not implemented!!\n");
264433d6423SLionel Sambuc cucheck();
265433d6423SLionel Sambuc exit(128+n);
266433d6423SLionel Sambuc }
267433d6423SLionel Sambuc /* Called when ZMODEM gets an interrupt (^X) */
onintr(int sig)268433d6423SLionel Sambuc void onintr(int sig)
269433d6423SLionel Sambuc {
270433d6423SLionel Sambuc signal(SIGINT, SIG_IGN);
271433d6423SLionel Sambuc longjmp(intrjmp, -1);
272433d6423SLionel Sambuc }
273433d6423SLionel Sambuc
274433d6423SLionel Sambuc int Zctlesc; /* Encode control characters */
275433d6423SLionel Sambuc int Nozmodem = 0; /* If invoked as "sb" */
276433d6423SLionel Sambuc char *Progname = "sz";
277433d6423SLionel Sambuc int Zrwindow = 1400; /* RX window size (controls garbage count) */
278433d6423SLionel Sambuc #include "zm.c"
279433d6423SLionel Sambuc
280433d6423SLionel Sambuc
main(int argc,char * argv[])281433d6423SLionel Sambuc int main(int argc, char *argv[])
282433d6423SLionel Sambuc {
283433d6423SLionel Sambuc register char *cp;
284433d6423SLionel Sambuc register int npats;
285433d6423SLionel Sambuc int dm;
286433d6423SLionel Sambuc char **patts;
287433d6423SLionel Sambuc static char xXbuf[BUFSIZ];
288433d6423SLionel Sambuc
289433d6423SLionel Sambuc if ((cp = getenv("ZNULLS")) && *cp)
290433d6423SLionel Sambuc Znulls = atoi(cp);
291433d6423SLionel Sambuc if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
292433d6423SLionel Sambuc Restricted=TRUE;
293433d6423SLionel Sambuc from_cu();
294433d6423SLionel Sambuc chkinvok(argv[0]);
295433d6423SLionel Sambuc
296433d6423SLionel Sambuc Rxtimeout = 600;
297433d6423SLionel Sambuc npats=0;
298433d6423SLionel Sambuc if (argc<2)
299433d6423SLionel Sambuc usage();
300433d6423SLionel Sambuc setbuf(stdout, xXbuf);
301433d6423SLionel Sambuc while (--argc) {
302433d6423SLionel Sambuc cp = *++argv;
303433d6423SLionel Sambuc if (*cp++ == '-' && *cp) {
304433d6423SLionel Sambuc while ( *cp) {
305433d6423SLionel Sambuc switch(*cp++) {
306433d6423SLionel Sambuc case '\\':
307433d6423SLionel Sambuc *cp = toupper(*cp); continue;
308433d6423SLionel Sambuc case '+':
309433d6423SLionel Sambuc Lzmanag = ZMAPND; break;
310433d6423SLionel Sambuc #ifdef CSTOPB
311433d6423SLionel Sambuc case '2':
312433d6423SLionel Sambuc Twostop = TRUE; break;
313433d6423SLionel Sambuc #endif
314433d6423SLionel Sambuc case 'a':
315433d6423SLionel Sambuc Lzconv = ZCNL;
316433d6423SLionel Sambuc Ascii = TRUE; break;
317433d6423SLionel Sambuc case 'b':
318433d6423SLionel Sambuc Lzconv = ZCBIN; break;
319433d6423SLionel Sambuc case 'C':
320433d6423SLionel Sambuc if (--argc < 1) {
321433d6423SLionel Sambuc usage();
322433d6423SLionel Sambuc }
323433d6423SLionel Sambuc Cmdtries = atoi(*++argv);
324433d6423SLionel Sambuc break;
325433d6423SLionel Sambuc case 'i':
326433d6423SLionel Sambuc Cmdack1 = ZCACK1;
327433d6423SLionel Sambuc /* **** FALL THROUGH TO **** */
328433d6423SLionel Sambuc case 'c':
329433d6423SLionel Sambuc if (--argc != 1) {
330433d6423SLionel Sambuc usage();
331433d6423SLionel Sambuc }
332433d6423SLionel Sambuc Command = TRUE;
333433d6423SLionel Sambuc Cmdstr = *++argv;
334433d6423SLionel Sambuc break;
335433d6423SLionel Sambuc case 'd':
336433d6423SLionel Sambuc ++Dottoslash;
337433d6423SLionel Sambuc /* **** FALL THROUGH TO **** */
338433d6423SLionel Sambuc case 'f':
339433d6423SLionel Sambuc Fullname=TRUE; break;
340433d6423SLionel Sambuc case 'e':
341433d6423SLionel Sambuc Zctlesc = 1; break;
342433d6423SLionel Sambuc case 'k':
343433d6423SLionel Sambuc blklen=1024; break;
344433d6423SLionel Sambuc case 'L':
345433d6423SLionel Sambuc if (--argc < 1) {
346433d6423SLionel Sambuc usage();
347433d6423SLionel Sambuc }
348433d6423SLionel Sambuc blkopt = atoi(*++argv);
349433d6423SLionel Sambuc if (blkopt<24 || blkopt>1024)
350433d6423SLionel Sambuc usage();
351433d6423SLionel Sambuc break;
352433d6423SLionel Sambuc case 'l':
353433d6423SLionel Sambuc if (--argc < 1) {
354433d6423SLionel Sambuc usage();
355433d6423SLionel Sambuc }
356433d6423SLionel Sambuc Tframlen = atoi(*++argv);
357433d6423SLionel Sambuc if (Tframlen<32 || Tframlen>1024)
358433d6423SLionel Sambuc usage();
359433d6423SLionel Sambuc break;
360433d6423SLionel Sambuc case 'N':
361433d6423SLionel Sambuc Lzmanag = ZMNEWL; break;
362433d6423SLionel Sambuc case 'n':
363433d6423SLionel Sambuc Lzmanag = ZMNEW; break;
364433d6423SLionel Sambuc case 'o':
365433d6423SLionel Sambuc Wantfcs32 = FALSE; break;
366433d6423SLionel Sambuc case 'p':
367433d6423SLionel Sambuc Lzmanag = ZMPROT; break;
368433d6423SLionel Sambuc case 'r':
369433d6423SLionel Sambuc Lzconv = ZCRESUM;
370433d6423SLionel Sambuc case 'q':
371433d6423SLionel Sambuc Quiet=TRUE; Verbose=0; break;
372433d6423SLionel Sambuc case 't':
373433d6423SLionel Sambuc if (--argc < 1) {
374433d6423SLionel Sambuc usage();
375433d6423SLionel Sambuc }
376433d6423SLionel Sambuc Rxtimeout = atoi(*++argv);
377433d6423SLionel Sambuc if (Rxtimeout<10 || Rxtimeout>1000)
378433d6423SLionel Sambuc usage();
379433d6423SLionel Sambuc break;
380433d6423SLionel Sambuc case 'T':
381433d6423SLionel Sambuc if (++Test > 1) {
382433d6423SLionel Sambuc chartest(1); chartest(2);
383433d6423SLionel Sambuc mode(0); exit(0);
384433d6423SLionel Sambuc }
385433d6423SLionel Sambuc break;
386433d6423SLionel Sambuc #ifndef vax11c
387433d6423SLionel Sambuc case 'u':
388433d6423SLionel Sambuc ++Unlinkafter; break;
389433d6423SLionel Sambuc #endif
390433d6423SLionel Sambuc case 'v':
391433d6423SLionel Sambuc ++Verbose; break;
392433d6423SLionel Sambuc case 'w':
393433d6423SLionel Sambuc if (--argc < 1) {
394433d6423SLionel Sambuc usage();
395433d6423SLionel Sambuc }
396433d6423SLionel Sambuc Txwindow = atoi(*++argv);
397433d6423SLionel Sambuc if (Txwindow < 256)
398433d6423SLionel Sambuc Txwindow = 256;
399433d6423SLionel Sambuc Txwindow = (Txwindow/64) * 64;
400433d6423SLionel Sambuc Txwspac = Txwindow/4;
401433d6423SLionel Sambuc if (blkopt > Txwspac
402433d6423SLionel Sambuc || (!blkopt && Txwspac < 1024))
403433d6423SLionel Sambuc blkopt = Txwspac;
404433d6423SLionel Sambuc break;
405433d6423SLionel Sambuc case 'X':
406433d6423SLionel Sambuc ++Modem2; break;
407433d6423SLionel Sambuc case 'Y':
408433d6423SLionel Sambuc Lskipnocor = TRUE;
409433d6423SLionel Sambuc /* **** FALLL THROUGH TO **** */
410433d6423SLionel Sambuc case 'y':
411433d6423SLionel Sambuc Lzmanag = ZMCLOB; break;
412433d6423SLionel Sambuc default:
413433d6423SLionel Sambuc usage();
414433d6423SLionel Sambuc }
415433d6423SLionel Sambuc }
416433d6423SLionel Sambuc }
417433d6423SLionel Sambuc else if ( !npats && argc>0) {
418433d6423SLionel Sambuc if (argv[0][0]) {
419433d6423SLionel Sambuc npats=argc;
420433d6423SLionel Sambuc patts=argv;
421433d6423SLionel Sambuc #ifndef vax11c
422433d6423SLionel Sambuc if ( !strcmp(*patts, "-"))
423433d6423SLionel Sambuc iofd = 1;
424433d6423SLionel Sambuc #endif
425433d6423SLionel Sambuc }
426433d6423SLionel Sambuc }
427433d6423SLionel Sambuc }
428433d6423SLionel Sambuc if (npats < 1 && !Command && !Test)
429433d6423SLionel Sambuc usage();
430433d6423SLionel Sambuc if (Verbose) {
431433d6423SLionel Sambuc if (freopen(LOGFILE, "a", stderr)==NULL) {
432433d6423SLionel Sambuc printf("Can't open log file %s\n",LOGFILE);
433433d6423SLionel Sambuc exit(0200);
434433d6423SLionel Sambuc }
435433d6423SLionel Sambuc setbuf(stderr, (char *)NULL);
436433d6423SLionel Sambuc }
437433d6423SLionel Sambuc if (Fromcu && !Quiet) {
438433d6423SLionel Sambuc if (Verbose == 0)
439433d6423SLionel Sambuc Verbose = 2;
440433d6423SLionel Sambuc }
441433d6423SLionel Sambuc vfile("%s %s for %s\n", Progname, VERSION, OS);
442433d6423SLionel Sambuc
443433d6423SLionel Sambuc mode(1);
444433d6423SLionel Sambuc
445433d6423SLionel Sambuc if (signal(SIGINT, bibi) == SIG_IGN) {
446433d6423SLionel Sambuc signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
447433d6423SLionel Sambuc } else {
448433d6423SLionel Sambuc signal(SIGINT, bibi); signal(SIGKILL, bibi);
449433d6423SLionel Sambuc }
450433d6423SLionel Sambuc if ( !Fromcu)
451433d6423SLionel Sambuc signal(SIGQUIT, SIG_IGN);
452433d6423SLionel Sambuc signal(SIGTERM, bibi);
453433d6423SLionel Sambuc
454433d6423SLionel Sambuc if ( !Modem2) {
455433d6423SLionel Sambuc if (!Nozmodem) {
456433d6423SLionel Sambuc printf("rz\r"); fflush(stdout);
457433d6423SLionel Sambuc }
458433d6423SLionel Sambuc countem(npats, patts);
459433d6423SLionel Sambuc if (!Nozmodem) {
460433d6423SLionel Sambuc stohdr(0L);
461433d6423SLionel Sambuc if (Command)
462433d6423SLionel Sambuc Txhdr[ZF0] = ZCOMMAND;
463433d6423SLionel Sambuc zshhdr(ZRQINIT, Txhdr);
464433d6423SLionel Sambuc }
465433d6423SLionel Sambuc }
466433d6423SLionel Sambuc fflush(stdout);
467433d6423SLionel Sambuc
468433d6423SLionel Sambuc if (Command) {
469433d6423SLionel Sambuc if (getzrxinit()) {
470433d6423SLionel Sambuc Exitcode=0200; canit();
471433d6423SLionel Sambuc }
472433d6423SLionel Sambuc else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
473433d6423SLionel Sambuc Exitcode=0200; canit();
474433d6423SLionel Sambuc }
475433d6423SLionel Sambuc } else if (wcsend(npats, patts)==ERROR) {
476433d6423SLionel Sambuc Exitcode=0200;
477433d6423SLionel Sambuc canit();
478433d6423SLionel Sambuc }
479433d6423SLionel Sambuc fflush(stdout);
480433d6423SLionel Sambuc mode(0);
481433d6423SLionel Sambuc dm = ((errcnt != 0) | Exitcode);
482433d6423SLionel Sambuc if (dm) {
483433d6423SLionel Sambuc cucheck(); exit(dm);
484433d6423SLionel Sambuc }
485433d6423SLionel Sambuc putc('\n',stderr);
486433d6423SLionel Sambuc exit(SS_NORMAL);
487433d6423SLionel Sambuc /*NOTREACHED*/
488433d6423SLionel Sambuc }
489433d6423SLionel Sambuc
wcsend(int argc,char * argp[])490433d6423SLionel Sambuc int wcsend(int argc, char *argp[])
491433d6423SLionel Sambuc {
492433d6423SLionel Sambuc register int n;
493433d6423SLionel Sambuc
494433d6423SLionel Sambuc Crcflg=FALSE;
495433d6423SLionel Sambuc firstsec=TRUE;
496433d6423SLionel Sambuc bytcnt = -1;
497433d6423SLionel Sambuc for (n=0; n<argc; ++n) {
498433d6423SLionel Sambuc Totsecs = 0;
499433d6423SLionel Sambuc if (wcs(argp[n])==ERROR)
500433d6423SLionel Sambuc return ERROR;
501433d6423SLionel Sambuc }
502433d6423SLionel Sambuc Totsecs = 0;
503433d6423SLionel Sambuc if (Filcnt==0) { /* bitch if we couldn't open ANY files */
504433d6423SLionel Sambuc if ( !Modem2) {
505433d6423SLionel Sambuc Command = TRUE;
506433d6423SLionel Sambuc Cmdstr = "echo \"sz: Can't open any requested files\"";
507433d6423SLionel Sambuc if (getnak()) {
508433d6423SLionel Sambuc Exitcode=0200; canit();
509433d6423SLionel Sambuc }
510433d6423SLionel Sambuc if (!Zmodem)
511433d6423SLionel Sambuc canit();
512433d6423SLionel Sambuc else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
513433d6423SLionel Sambuc Exitcode=0200; canit();
514433d6423SLionel Sambuc }
515433d6423SLionel Sambuc Exitcode = 1; return OK;
516433d6423SLionel Sambuc }
517433d6423SLionel Sambuc canit();
518433d6423SLionel Sambuc fprintf(stderr,"\r\nCan't open any requested files.\r\n");
519433d6423SLionel Sambuc return ERROR;
520433d6423SLionel Sambuc }
521433d6423SLionel Sambuc if (Zmodem)
522433d6423SLionel Sambuc saybibi();
523433d6423SLionel Sambuc else if ( !Modem2)
524433d6423SLionel Sambuc wctxpn("");
525433d6423SLionel Sambuc return OK;
526433d6423SLionel Sambuc }
527433d6423SLionel Sambuc
wcs(char * oname)528433d6423SLionel Sambuc int wcs(char *oname)
529433d6423SLionel Sambuc {
530433d6423SLionel Sambuc register int c;
531433d6423SLionel Sambuc register char *p;
532433d6423SLionel Sambuc struct stat f;
533433d6423SLionel Sambuc char name[PATHLEN];
534433d6423SLionel Sambuc
535433d6423SLionel Sambuc strcpy(name, oname);
536433d6423SLionel Sambuc
537433d6423SLionel Sambuc if (Restricted) {
538433d6423SLionel Sambuc /* restrict pathnames to current tree or uucppublic */
539433d6423SLionel Sambuc if ( substr(name, "../")
540433d6423SLionel Sambuc || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
541433d6423SLionel Sambuc canit();
542433d6423SLionel Sambuc fprintf(stderr,"\r\nsz:\tSecurity Violation\r\n");
543433d6423SLionel Sambuc return ERROR;
544433d6423SLionel Sambuc }
545433d6423SLionel Sambuc }
546433d6423SLionel Sambuc
547433d6423SLionel Sambuc if ( !strcmp(oname, "-")) {
548433d6423SLionel Sambuc if ((p = getenv("ONAME")) && *p)
549433d6423SLionel Sambuc strcpy(name, p);
550433d6423SLionel Sambuc else
551433d6423SLionel Sambuc sprintf(name, "s%d.sz", getpid());
552433d6423SLionel Sambuc in = stdin;
553433d6423SLionel Sambuc }
554433d6423SLionel Sambuc else if ((in=fopen(oname, "r"))==NULL) {
555433d6423SLionel Sambuc ++errcnt;
556433d6423SLionel Sambuc return OK; /* pass over it, there may be others */
557433d6423SLionel Sambuc }
558433d6423SLionel Sambuc BEofseen = Eofseen = 0; vpos = 0;
559433d6423SLionel Sambuc /* Check for directory or block special files */
560433d6423SLionel Sambuc fstat(fileno(in), &f);
561433d6423SLionel Sambuc c = f.st_mode & S_IFMT;
562433d6423SLionel Sambuc if (c == S_IFDIR || c == S_IFBLK) {
563433d6423SLionel Sambuc fclose(in);
564433d6423SLionel Sambuc return OK;
565433d6423SLionel Sambuc }
566433d6423SLionel Sambuc
567433d6423SLionel Sambuc ++Filcnt;
568433d6423SLionel Sambuc switch (wctxpn(name)) {
569433d6423SLionel Sambuc case ERROR:
570433d6423SLionel Sambuc return ERROR;
571433d6423SLionel Sambuc case ZSKIP:
572433d6423SLionel Sambuc return OK;
573433d6423SLionel Sambuc }
574433d6423SLionel Sambuc if (!Zmodem && wctx(f.st_size)==ERROR)
575433d6423SLionel Sambuc return ERROR;
576433d6423SLionel Sambuc #ifndef vax11c
577433d6423SLionel Sambuc if (Unlinkafter)
578433d6423SLionel Sambuc unlink(oname);
579433d6423SLionel Sambuc #endif
580433d6423SLionel Sambuc return 0;
581433d6423SLionel Sambuc }
582433d6423SLionel Sambuc
583433d6423SLionel Sambuc /*
584433d6423SLionel Sambuc * generate and transmit pathname block consisting of
585433d6423SLionel Sambuc * pathname (null terminated),
586433d6423SLionel Sambuc * file length, mode time and file mode in octal
587433d6423SLionel Sambuc * as provided by the Unix fstat call.
588433d6423SLionel Sambuc * N.B.: modifies the passed name, may extend it!
589433d6423SLionel Sambuc */
wctxpn(char * name)590433d6423SLionel Sambuc int wctxpn(char *name)
591433d6423SLionel Sambuc {
592433d6423SLionel Sambuc register char *p, *q;
593433d6423SLionel Sambuc char name2[PATHLEN];
594433d6423SLionel Sambuc struct stat f;
595433d6423SLionel Sambuc
596433d6423SLionel Sambuc if (Modem2) {
597433d6423SLionel Sambuc if ((in!=stdin) && *name && fstat(fileno(in), &f)!= -1) {
598433d6423SLionel Sambuc fprintf(stderr, "Sending %s, %lld blocks: ",
599433d6423SLionel Sambuc name, f.st_size>>7);
600433d6423SLionel Sambuc }
601433d6423SLionel Sambuc fprintf(stderr, "Give your local XMODEM receive command now.\r\n");
602433d6423SLionel Sambuc return OK;
603433d6423SLionel Sambuc }
604433d6423SLionel Sambuc zperr("Awaiting pathname nak for %s", *name?name:"<END>");
605433d6423SLionel Sambuc if ( !Zmodem)
606433d6423SLionel Sambuc if (getnak())
607433d6423SLionel Sambuc return ERROR;
608433d6423SLionel Sambuc
609433d6423SLionel Sambuc q = (char *) 0;
610433d6423SLionel Sambuc if (Dottoslash) { /* change . to . */
611433d6423SLionel Sambuc for (p=name; *p; ++p) {
612433d6423SLionel Sambuc if (*p == '/')
613433d6423SLionel Sambuc q = p;
614433d6423SLionel Sambuc else if (*p == '.')
615433d6423SLionel Sambuc *(q=p) = '/';
616433d6423SLionel Sambuc }
617433d6423SLionel Sambuc if (q && strlen(++q) > 8) { /* If name>8 chars */
618433d6423SLionel Sambuc q += 8; /* make it .ext */
619433d6423SLionel Sambuc strcpy(name2, q); /* save excess of name */
620433d6423SLionel Sambuc *q = '.';
621433d6423SLionel Sambuc strcpy(++q, name2); /* add it back */
622433d6423SLionel Sambuc }
623433d6423SLionel Sambuc }
624433d6423SLionel Sambuc
625433d6423SLionel Sambuc for (p=name, q=txbuf ; *p; )
626433d6423SLionel Sambuc if ((*q++ = *p++) == '/' && !Fullname)
627433d6423SLionel Sambuc q = txbuf;
628433d6423SLionel Sambuc *q++ = 0;
629433d6423SLionel Sambuc p=q;
630433d6423SLionel Sambuc while (q < (txbuf + 1024))
631433d6423SLionel Sambuc *q++ = 0;
632433d6423SLionel Sambuc if (!Ascii && (in!=stdin) && *name && fstat(fileno(in), &f)!= -1)
633d0055759SDavid van Moolenbroek sprintf(p, "%llu %llo %o 0 %d %ld", f.st_size, f.st_mtime,
634433d6423SLionel Sambuc f.st_mode, Filesleft, Totalleft);
635433d6423SLionel Sambuc Totalleft -= f.st_size;
636433d6423SLionel Sambuc if (--Filesleft <= 0)
637433d6423SLionel Sambuc Totalleft = 0;
638433d6423SLionel Sambuc if (Totalleft < 0)
639433d6423SLionel Sambuc Totalleft = 0;
640433d6423SLionel Sambuc
641433d6423SLionel Sambuc /* force 1k blocks if name won't fit in 128 byte block */
642433d6423SLionel Sambuc if (txbuf[125])
643433d6423SLionel Sambuc blklen=1024;
644433d6423SLionel Sambuc else { /* A little goodie for IMP/KMD */
645433d6423SLionel Sambuc txbuf[127] = (f.st_size + 127) >>7;
646433d6423SLionel Sambuc txbuf[126] = (f.st_size + 127) >>15;
647433d6423SLionel Sambuc }
648433d6423SLionel Sambuc if (Zmodem)
649433d6423SLionel Sambuc return zsendfile(txbuf, 1+strlen(p)+(p-txbuf));
650433d6423SLionel Sambuc if (wcputsec(txbuf, 0, 128)==ERROR)
651433d6423SLionel Sambuc return ERROR;
652433d6423SLionel Sambuc return OK;
653433d6423SLionel Sambuc }
654433d6423SLionel Sambuc
getnak()655433d6423SLionel Sambuc int getnak()
656433d6423SLionel Sambuc {
657433d6423SLionel Sambuc register int firstch;
658433d6423SLionel Sambuc
659433d6423SLionel Sambuc Lastrx = 0;
660433d6423SLionel Sambuc for (;;) {
661433d6423SLionel Sambuc switch (firstch = readline(800)) {
662433d6423SLionel Sambuc case ZPAD:
663433d6423SLionel Sambuc if (getzrxinit())
664433d6423SLionel Sambuc return ERROR;
665433d6423SLionel Sambuc Ascii = 0; /* Receiver does the conversion */
666433d6423SLionel Sambuc return FALSE;
667433d6423SLionel Sambuc case TIMEOUT:
668433d6423SLionel Sambuc zperr("Timeout on pathname");
669433d6423SLionel Sambuc return TRUE;
670433d6423SLionel Sambuc case WANTG:
671433d6423SLionel Sambuc #ifdef MODE2OK
672433d6423SLionel Sambuc mode(2); /* Set cbreak, XON/XOFF, etc. */
673433d6423SLionel Sambuc #endif
674433d6423SLionel Sambuc Optiong = TRUE;
675433d6423SLionel Sambuc blklen=1024;
676433d6423SLionel Sambuc case WANTCRC:
677433d6423SLionel Sambuc Crcflg = TRUE;
678433d6423SLionel Sambuc case NAK:
679433d6423SLionel Sambuc return FALSE;
680433d6423SLionel Sambuc case CAN:
681433d6423SLionel Sambuc if ((firstch = readline(20)) == CAN && Lastrx == CAN)
682433d6423SLionel Sambuc return TRUE;
683433d6423SLionel Sambuc default:
684433d6423SLionel Sambuc break;
685433d6423SLionel Sambuc }
686433d6423SLionel Sambuc Lastrx = firstch;
687433d6423SLionel Sambuc }
688433d6423SLionel Sambuc }
689433d6423SLionel Sambuc
690433d6423SLionel Sambuc
wctx(long flen)691433d6423SLionel Sambuc int wctx(long flen)
692433d6423SLionel Sambuc {
693433d6423SLionel Sambuc register int thisblklen;
694433d6423SLionel Sambuc register int sectnum, attempts, firstch;
695433d6423SLionel Sambuc long charssent;
696433d6423SLionel Sambuc
697433d6423SLionel Sambuc charssent = 0; firstsec=TRUE; thisblklen = blklen;
698433d6423SLionel Sambuc vfile("wctx:file length=%ld", flen);
699433d6423SLionel Sambuc
700433d6423SLionel Sambuc while ((firstch=readline(Rxtimeout))!=NAK && firstch != WANTCRC
701433d6423SLionel Sambuc && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN)
702433d6423SLionel Sambuc ;
703433d6423SLionel Sambuc if (firstch==CAN) {
704433d6423SLionel Sambuc zperr("Receiver CANcelled");
705433d6423SLionel Sambuc return ERROR;
706433d6423SLionel Sambuc }
707433d6423SLionel Sambuc if (firstch==WANTCRC)
708433d6423SLionel Sambuc Crcflg=TRUE;
709433d6423SLionel Sambuc if (firstch==WANTG)
710433d6423SLionel Sambuc Crcflg=TRUE;
711433d6423SLionel Sambuc sectnum=0;
712433d6423SLionel Sambuc for (;;) {
713433d6423SLionel Sambuc if (flen <= (charssent + 896L))
714433d6423SLionel Sambuc thisblklen = 128;
715433d6423SLionel Sambuc if ( !filbuf(txbuf, thisblklen))
716433d6423SLionel Sambuc break;
717433d6423SLionel Sambuc if (wcputsec(txbuf, ++sectnum, thisblklen)==ERROR)
718433d6423SLionel Sambuc return ERROR;
719433d6423SLionel Sambuc charssent += thisblklen;
720433d6423SLionel Sambuc }
721433d6423SLionel Sambuc fclose(in);
722433d6423SLionel Sambuc attempts=0;
723433d6423SLionel Sambuc do {
724433d6423SLionel Sambuc purgeline();
725433d6423SLionel Sambuc sendline(EOT);
726433d6423SLionel Sambuc fflush(stdout);
727433d6423SLionel Sambuc ++attempts;
728433d6423SLionel Sambuc }
729*ab712d19SDavid van Moolenbroek while ((firstch = readline(Rxtimeout)) != ACK &&
730*ab712d19SDavid van Moolenbroek attempts < RETRYMAX);
731433d6423SLionel Sambuc if (attempts == RETRYMAX) {
732433d6423SLionel Sambuc zperr("No ACK on EOT");
733433d6423SLionel Sambuc return ERROR;
734433d6423SLionel Sambuc }
735433d6423SLionel Sambuc else
736433d6423SLionel Sambuc return OK;
737433d6423SLionel Sambuc }
738433d6423SLionel Sambuc /**
739433d6423SLionel Sambuc * @param cseclen :data length of this sector to send
740433d6423SLionel Sambuc */
wcputsec(char * buf,int sectnum,int cseclen)741433d6423SLionel Sambuc int wcputsec(char *buf, int sectnum, int cseclen)
742433d6423SLionel Sambuc {
743433d6423SLionel Sambuc register int checksum, wcj;
744433d6423SLionel Sambuc register char *cp;
745433d6423SLionel Sambuc unsigned oldcrc;
746433d6423SLionel Sambuc int firstch;
747433d6423SLionel Sambuc int attempts;
748433d6423SLionel Sambuc
749433d6423SLionel Sambuc firstch=0; /* part of logic to detect CAN CAN */
750433d6423SLionel Sambuc
751433d6423SLionel Sambuc if (Verbose>2)
752433d6423SLionel Sambuc fprintf(stderr, "Sector %3d %2dk\n", Totsecs, Totsecs/8 );
753433d6423SLionel Sambuc else if (Verbose>1)
754433d6423SLionel Sambuc fprintf(stderr, "\rSector %3d %2dk ", Totsecs, Totsecs/8 );
755433d6423SLionel Sambuc for (attempts=0; attempts <= RETRYMAX; attempts++) {
756433d6423SLionel Sambuc Lastrx= firstch;
757433d6423SLionel Sambuc sendline(cseclen==1024?STX:SOH);
758433d6423SLionel Sambuc sendline(sectnum);
759433d6423SLionel Sambuc sendline(-sectnum -1);
760433d6423SLionel Sambuc oldcrc=checksum=0;
761433d6423SLionel Sambuc for (wcj=cseclen,cp=buf; --wcj>=0; ) {
762433d6423SLionel Sambuc sendline(*cp);
763433d6423SLionel Sambuc oldcrc=updcrc((0377& *cp), oldcrc);
764433d6423SLionel Sambuc checksum += *cp++;
765433d6423SLionel Sambuc }
766433d6423SLionel Sambuc if (Crcflg) {
767433d6423SLionel Sambuc oldcrc=updcrc(0,updcrc(0,oldcrc));
768433d6423SLionel Sambuc sendline((int)oldcrc>>8);
769433d6423SLionel Sambuc sendline((int)oldcrc);
770433d6423SLionel Sambuc }
771433d6423SLionel Sambuc else
772433d6423SLionel Sambuc sendline(checksum);
773433d6423SLionel Sambuc
774433d6423SLionel Sambuc if (Optiong) {
775433d6423SLionel Sambuc firstsec = FALSE; return OK;
776433d6423SLionel Sambuc }
777433d6423SLionel Sambuc firstch = readline(Rxtimeout);
778433d6423SLionel Sambuc gotnak:
779433d6423SLionel Sambuc switch (firstch) {
780433d6423SLionel Sambuc case CAN:
781433d6423SLionel Sambuc if(Lastrx == CAN) {
782433d6423SLionel Sambuc cancan:
783433d6423SLionel Sambuc zperr("Cancelled"); return ERROR;
784433d6423SLionel Sambuc }
785433d6423SLionel Sambuc break;
786433d6423SLionel Sambuc case TIMEOUT:
787433d6423SLionel Sambuc zperr("Timeout on sector ACK"); continue;
788433d6423SLionel Sambuc case WANTCRC:
789433d6423SLionel Sambuc if (firstsec)
790433d6423SLionel Sambuc Crcflg = TRUE;
791433d6423SLionel Sambuc case NAK:
792433d6423SLionel Sambuc zperr("NAK on sector"); continue;
793433d6423SLionel Sambuc case ACK:
794433d6423SLionel Sambuc firstsec=FALSE;
795433d6423SLionel Sambuc Totsecs += (cseclen>>7);
796433d6423SLionel Sambuc return OK;
797433d6423SLionel Sambuc case ERROR:
798433d6423SLionel Sambuc zperr("Got burst for sector ACK"); break;
799433d6423SLionel Sambuc default:
800433d6423SLionel Sambuc zperr("Got %02x for sector ACK", firstch); break;
801433d6423SLionel Sambuc }
802433d6423SLionel Sambuc for (;;) {
803433d6423SLionel Sambuc Lastrx = firstch;
804433d6423SLionel Sambuc if ((firstch = readline(Rxtimeout)) == TIMEOUT)
805433d6423SLionel Sambuc break;
806433d6423SLionel Sambuc if (firstch == NAK || firstch == WANTCRC)
807433d6423SLionel Sambuc goto gotnak;
808433d6423SLionel Sambuc if (firstch == CAN && Lastrx == CAN)
809433d6423SLionel Sambuc goto cancan;
810433d6423SLionel Sambuc }
811433d6423SLionel Sambuc }
812433d6423SLionel Sambuc zperr("Retry Count Exceeded");
813433d6423SLionel Sambuc return ERROR;
814433d6423SLionel Sambuc }
815433d6423SLionel Sambuc
816433d6423SLionel Sambuc /* fill buf with count chars padding with ^Z for CPM */
filbuf(char * buf,int count)817433d6423SLionel Sambuc int filbuf(char *buf, int count)
818433d6423SLionel Sambuc {
819433d6423SLionel Sambuc register int c, m;
820433d6423SLionel Sambuc
821433d6423SLionel Sambuc if ( !Ascii) {
822433d6423SLionel Sambuc m = read(fileno(in), buf, count);
823433d6423SLionel Sambuc if (m <= 0)
824433d6423SLionel Sambuc return 0;
825433d6423SLionel Sambuc while (m < count)
826433d6423SLionel Sambuc buf[m++] = 032;
827433d6423SLionel Sambuc return count;
828433d6423SLionel Sambuc }
829433d6423SLionel Sambuc m=count;
830433d6423SLionel Sambuc if (Lfseen) {
831433d6423SLionel Sambuc *buf++ = 012; --m; Lfseen = 0;
832433d6423SLionel Sambuc }
833433d6423SLionel Sambuc while ((c=getc(in))!=EOF) {
834433d6423SLionel Sambuc if (c == 012) {
835433d6423SLionel Sambuc *buf++ = 015;
836433d6423SLionel Sambuc if (--m == 0) {
837433d6423SLionel Sambuc Lfseen = TRUE; break;
838433d6423SLionel Sambuc }
839433d6423SLionel Sambuc }
840433d6423SLionel Sambuc *buf++ =c;
841433d6423SLionel Sambuc if (--m == 0)
842433d6423SLionel Sambuc break;
843433d6423SLionel Sambuc }
844433d6423SLionel Sambuc if (m==count)
845433d6423SLionel Sambuc return 0;
846433d6423SLionel Sambuc else
847433d6423SLionel Sambuc while (--m>=0)
848433d6423SLionel Sambuc *buf++ = CPMEOF;
849433d6423SLionel Sambuc return count;
850433d6423SLionel Sambuc }
851433d6423SLionel Sambuc
852433d6423SLionel Sambuc /* Fill buffer with blklen chars */
zfilbuf()853433d6423SLionel Sambuc int zfilbuf()
854433d6423SLionel Sambuc {
855433d6423SLionel Sambuc int n;
856433d6423SLionel Sambuc
857433d6423SLionel Sambuc #ifdef TXBSIZE
858433d6423SLionel Sambuc /* We assume request is within buffer, or just beyond */
859433d6423SLionel Sambuc txbuf = Txb + (bytcnt & TXBMASK);
860433d6423SLionel Sambuc if (vpos <= bytcnt) {
861433d6423SLionel Sambuc n = fread(txbuf, 1, blklen, in);
862433d6423SLionel Sambuc vpos += n;
863433d6423SLionel Sambuc if (n < blklen)
864433d6423SLionel Sambuc Eofseen = 1;
865433d6423SLionel Sambuc return n;
866433d6423SLionel Sambuc }
867433d6423SLionel Sambuc if (vpos >= (bytcnt+blklen))
868433d6423SLionel Sambuc return blklen;
869433d6423SLionel Sambuc /* May be a short block if crash recovery etc. */
870433d6423SLionel Sambuc Eofseen = BEofseen;
871433d6423SLionel Sambuc return (vpos - bytcnt);
872433d6423SLionel Sambuc #else
873433d6423SLionel Sambuc n = fread(txbuf, 1, blklen, in);
874433d6423SLionel Sambuc if (n < blklen)
875433d6423SLionel Sambuc Eofseen = 1;
876433d6423SLionel Sambuc return n;
877433d6423SLionel Sambuc #endif
878433d6423SLionel Sambuc }
879433d6423SLionel Sambuc
880433d6423SLionel Sambuc #ifdef TXBSIZE
fooseek(FILE * fptr,long pos,int whence)881433d6423SLionel Sambuc int fooseek(FILE *fptr, long pos, int whence)
882433d6423SLionel Sambuc {
883433d6423SLionel Sambuc int m, n;
884433d6423SLionel Sambuc
885433d6423SLionel Sambuc vfile("fooseek: pos =%lu vpos=%lu Canseek=%d", pos, vpos, Canseek);
886433d6423SLionel Sambuc /* Seek offset < current buffer */
887433d6423SLionel Sambuc if (pos < (vpos -TXBSIZE +1024)) {
888433d6423SLionel Sambuc BEofseen = 0;
889433d6423SLionel Sambuc if (Canseek > 0) {
890433d6423SLionel Sambuc vpos = pos & ~TXBMASK;
891433d6423SLionel Sambuc if (vpos >= pos)
892433d6423SLionel Sambuc vpos -= TXBSIZE;
893433d6423SLionel Sambuc if (fseek(fptr, vpos, 0))
894433d6423SLionel Sambuc return 1;
895433d6423SLionel Sambuc }
896433d6423SLionel Sambuc else if (Canseek == 0)
897433d6423SLionel Sambuc if (fseek(fptr, vpos = 0L, 0))
898433d6423SLionel Sambuc return 1;
899433d6423SLionel Sambuc else
900433d6423SLionel Sambuc return 1;
901433d6423SLionel Sambuc while (vpos <= pos) {
902433d6423SLionel Sambuc n = fread(Txb, 1, TXBSIZE, fptr);
903433d6423SLionel Sambuc vpos += n;
904433d6423SLionel Sambuc vfile("n=%d vpos=%ld", n, vpos);
905433d6423SLionel Sambuc if (n < TXBSIZE) {
906433d6423SLionel Sambuc BEofseen = 1;
907433d6423SLionel Sambuc break;
908433d6423SLionel Sambuc }
909433d6423SLionel Sambuc }
910433d6423SLionel Sambuc vfile("vpos=%ld", vpos);
911433d6423SLionel Sambuc return 0;
912433d6423SLionel Sambuc }
913433d6423SLionel Sambuc /* Seek offset > current buffer (crash recovery, etc.) */
914433d6423SLionel Sambuc if (pos > vpos) {
915433d6423SLionel Sambuc if (Canseek)
916433d6423SLionel Sambuc if (fseek(fptr, vpos = (pos & ~TXBMASK), 0))
917433d6423SLionel Sambuc return 1;
918433d6423SLionel Sambuc while (vpos <= pos) {
919433d6423SLionel Sambuc txbuf = Txb + (vpos & TXBMASK);
920433d6423SLionel Sambuc m = TXBSIZE - (vpos & TXBMASK);
921433d6423SLionel Sambuc n = fread(txbuf, 1, m, fptr);
922433d6423SLionel Sambuc vpos += n;
923433d6423SLionel Sambuc vfile("bo=%d n=%d vpos=%ld", txbuf-Txb, n, vpos);
924433d6423SLionel Sambuc if (m < n) {
925433d6423SLionel Sambuc BEofseen = 1;
926433d6423SLionel Sambuc break;
927433d6423SLionel Sambuc }
928433d6423SLionel Sambuc }
929433d6423SLionel Sambuc return 0;
930433d6423SLionel Sambuc }
931433d6423SLionel Sambuc /* Seek offset is within current buffer */
932433d6423SLionel Sambuc vfile("vpos=%ld", vpos);
933433d6423SLionel Sambuc return 0;
934433d6423SLionel Sambuc }
935433d6423SLionel Sambuc #define fseek fooseek
936433d6423SLionel Sambuc #endif
937433d6423SLionel Sambuc
vfile(const char * string,...)938433d6423SLionel Sambuc void vfile(const char *string, ...)
939433d6423SLionel Sambuc {
940433d6423SLionel Sambuc if (Verbose > 2) {
941433d6423SLionel Sambuc va_list args;
942433d6423SLionel Sambuc va_start(args, string);
943433d6423SLionel Sambuc vfprintf(stderr, string, args);
944433d6423SLionel Sambuc va_end(args);
945433d6423SLionel Sambuc fprintf(stderr, "\n");
946433d6423SLionel Sambuc }
947433d6423SLionel Sambuc }
948433d6423SLionel Sambuc
949433d6423SLionel Sambuc
alrm(int sig)950433d6423SLionel Sambuc void alrm(int sig)
951433d6423SLionel Sambuc {
952433d6423SLionel Sambuc longjmp(tohere, -1);
953433d6423SLionel Sambuc }
954433d6423SLionel Sambuc
955433d6423SLionel Sambuc
956433d6423SLionel Sambuc #ifndef vax11c
957433d6423SLionel Sambuc /*
958433d6423SLionel Sambuc * readline(timeout) reads character(s) from file descriptor 0
959433d6423SLionel Sambuc * timeout is in tenths of seconds
960433d6423SLionel Sambuc */
readline(int timeout)961433d6423SLionel Sambuc int readline(int timeout)
962433d6423SLionel Sambuc {
963433d6423SLionel Sambuc register int c;
964433d6423SLionel Sambuc static char byt[1];
965433d6423SLionel Sambuc
966433d6423SLionel Sambuc fflush(stdout);
967433d6423SLionel Sambuc if (setjmp(tohere)) {
968433d6423SLionel Sambuc zperr("TIMEOUT");
969433d6423SLionel Sambuc return TIMEOUT;
970433d6423SLionel Sambuc }
971433d6423SLionel Sambuc c = timeout/10;
972433d6423SLionel Sambuc if (c<2)
973433d6423SLionel Sambuc c=2;
974433d6423SLionel Sambuc if (Verbose>5) {
975433d6423SLionel Sambuc fprintf(stderr, "Timeout=%d Calling alarm(%d) ", timeout, c);
976433d6423SLionel Sambuc }
977433d6423SLionel Sambuc signal(SIGALRM, alrm); alarm(c);
978433d6423SLionel Sambuc c=read(iofd, byt, 1);
979433d6423SLionel Sambuc alarm(0);
980433d6423SLionel Sambuc if (Verbose>5)
981433d6423SLionel Sambuc fprintf(stderr, "ret %x\n", byt[0]);
982433d6423SLionel Sambuc if (c<1)
983433d6423SLionel Sambuc return TIMEOUT;
984433d6423SLionel Sambuc return (byt[0]&0377);
985433d6423SLionel Sambuc }
986433d6423SLionel Sambuc
flushmo()987433d6423SLionel Sambuc void flushmo()
988433d6423SLionel Sambuc {
989433d6423SLionel Sambuc fflush(stdout);
990433d6423SLionel Sambuc }
991433d6423SLionel Sambuc
992433d6423SLionel Sambuc
purgeline()993433d6423SLionel Sambuc void purgeline()
994433d6423SLionel Sambuc {
995433d6423SLionel Sambuc #ifdef USG
996433d6423SLionel Sambuc ioctl(iofd, TCFLSH, 0);
997433d6423SLionel Sambuc #else
998433d6423SLionel Sambuc lseek(iofd, 0L, 2);
999433d6423SLionel Sambuc #endif
1000433d6423SLionel Sambuc }
1001433d6423SLionel Sambuc #endif
1002433d6423SLionel Sambuc
1003433d6423SLionel Sambuc /* send cancel string to get the other end to shut up */
canit()1004433d6423SLionel Sambuc void canit()
1005433d6423SLionel Sambuc {
1006433d6423SLionel Sambuc static char canistr[] = {
1007433d6423SLionel Sambuc 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
1008433d6423SLionel Sambuc };
1009433d6423SLionel Sambuc
1010433d6423SLionel Sambuc #ifdef vax11c
1011433d6423SLionel Sambuc raw_wbuf(strlen(canistr), canistr);
1012433d6423SLionel Sambuc purgeline();
1013433d6423SLionel Sambuc #else
1014d0055759SDavid van Moolenbroek printf("%s", canistr);
1015433d6423SLionel Sambuc fflush(stdout);
1016433d6423SLionel Sambuc #endif
1017433d6423SLionel Sambuc }
1018433d6423SLionel Sambuc
1019433d6423SLionel Sambuc
1020433d6423SLionel Sambuc /*
1021433d6423SLionel Sambuc * Log an error
1022433d6423SLionel Sambuc */
1023433d6423SLionel Sambuc /*VARARGS1*/
zperr(char * s,char * p,char * u)1024433d6423SLionel Sambuc void zperr(char *s, char *p, char *u)
1025433d6423SLionel Sambuc {
1026433d6423SLionel Sambuc if (Verbose <= 0)
1027433d6423SLionel Sambuc return;
1028433d6423SLionel Sambuc fprintf(stderr, "\nRetry %d: ", errors);
1029433d6423SLionel Sambuc fprintf(stderr, s, p, u);
1030433d6423SLionel Sambuc fprintf(stderr, "\n");
1031433d6423SLionel Sambuc }
1032433d6423SLionel Sambuc
1033433d6423SLionel Sambuc /*
1034433d6423SLionel Sambuc * substr(string, token) searches for token in string s
1035433d6423SLionel Sambuc * returns pointer to token within string if found, NULL otherwise
1036433d6423SLionel Sambuc */
1037433d6423SLionel Sambuc char *
substr(char * s,char * t)1038433d6423SLionel Sambuc substr(char *s, char *t)
1039433d6423SLionel Sambuc {
1040433d6423SLionel Sambuc register char *ss,*tt;
1041433d6423SLionel Sambuc /* search for first char of token */
1042433d6423SLionel Sambuc for (ss=s; *s; s++)
1043433d6423SLionel Sambuc if (*s == *t)
1044433d6423SLionel Sambuc /* compare token with substring */
1045433d6423SLionel Sambuc for (ss=s,tt=t; ;) {
1046433d6423SLionel Sambuc if (*tt == 0)
1047433d6423SLionel Sambuc return s;
1048433d6423SLionel Sambuc if (*ss++ != *tt++)
1049433d6423SLionel Sambuc break;
1050433d6423SLionel Sambuc }
1051433d6423SLionel Sambuc return (char *)NULL;
1052433d6423SLionel Sambuc }
1053433d6423SLionel Sambuc
1054433d6423SLionel Sambuc char *babble[] = {
1055433d6423SLionel Sambuc #ifdef vax11c
1056433d6423SLionel Sambuc " Send file(s) with ZMODEM Protocol",
1057433d6423SLionel Sambuc "Usage: sz [-2+abdefkLlNnquvwYy] [-] file ...",
1058433d6423SLionel Sambuc " sz [-2Ceqv] -c COMMAND",
1059433d6423SLionel Sambuc " \\ Force next option letter to upper case",
1060433d6423SLionel Sambuc #else
1061433d6423SLionel Sambuc "Send file(s) with ZMODEM/YMODEM/XMODEM Protocol",
1062433d6423SLionel Sambuc " (Y) = Option applies to YMODEM only",
1063433d6423SLionel Sambuc " (Z) = Option applies to ZMODEM only",
1064433d6423SLionel Sambuc "Usage: sz [-2+abdefkLlNnquvwYy] [-] file ...",
1065433d6423SLionel Sambuc " sz [-2Ceqv] -c COMMAND",
1066433d6423SLionel Sambuc " sb [-2adfkquv] [-] file ...",
1067433d6423SLionel Sambuc " sx [-2akquv] [-] file",
1068433d6423SLionel Sambuc #endif
1069433d6423SLionel Sambuc #ifdef CSTOPB
1070433d6423SLionel Sambuc " 2 Use 2 stop bits",
1071433d6423SLionel Sambuc #endif
1072433d6423SLionel Sambuc " + Append to existing destination file (Z)",
1073433d6423SLionel Sambuc " a (ASCII) change NL to CR/LF",
1074433d6423SLionel Sambuc " b Binary file transfer override",
1075433d6423SLionel Sambuc " c send COMMAND (Z)",
1076433d6423SLionel Sambuc #ifndef vax11c
1077433d6423SLionel Sambuc " d Change '.' to '/' in pathnames (Y/Z)",
1078433d6423SLionel Sambuc #endif
1079433d6423SLionel Sambuc " e Escape all control characters (Z)",
1080433d6423SLionel Sambuc " f send Full pathname (Y/Z)",
1081433d6423SLionel Sambuc " i send COMMAND, ack Immediately (Z)",
1082433d6423SLionel Sambuc " k Send 1024 byte packets (Y)",
1083433d6423SLionel Sambuc " L N Limit subpacket length to N bytes (Z)",
1084433d6423SLionel Sambuc " l N Limit frame length to N bytes (l>=L) (Z)",
1085433d6423SLionel Sambuc " n send file if source newer (Z)",
1086433d6423SLionel Sambuc " N send file if source newer or longer (Z)",
1087433d6423SLionel Sambuc " o Use 16 bit CRC instead of 32 bit CRC (Z)",
1088433d6423SLionel Sambuc " p Protect existing destination file (Z)",
1089433d6423SLionel Sambuc " r Resume/Recover interrupted file transfer (Z)",
1090433d6423SLionel Sambuc " q Quiet (no progress reports)",
1091433d6423SLionel Sambuc #ifndef vax11c
1092433d6423SLionel Sambuc " u Unlink file after transmission",
1093433d6423SLionel Sambuc #endif
1094433d6423SLionel Sambuc " v Verbose - provide debugging information",
1095433d6423SLionel Sambuc " w N Window is N bytes (Z)",
1096433d6423SLionel Sambuc " Y Yes, overwrite existing file, skip if not present at rx (Z)",
1097433d6423SLionel Sambuc " y Yes, overwrite existing file (Z)",
1098433d6423SLionel Sambuc "- as pathname sends standard input as sPID.sz or environment ONAME",
1099433d6423SLionel Sambuc ""
1100433d6423SLionel Sambuc };
1101433d6423SLionel Sambuc
usage()1102433d6423SLionel Sambuc int usage()
1103433d6423SLionel Sambuc {
1104433d6423SLionel Sambuc char **pp;
1105433d6423SLionel Sambuc
1106433d6423SLionel Sambuc for (pp=babble; **pp; ++pp)
1107433d6423SLionel Sambuc fprintf(stderr, "%s\n", *pp);
1108433d6423SLionel Sambuc fprintf(stderr, "%s for %s by Chuck Forsberg, Omen Technology INC\n",
1109433d6423SLionel Sambuc VERSION, OS);
1110433d6423SLionel Sambuc fprintf(stderr, "\t\t\042The High Reliability Software\042\n");
1111433d6423SLionel Sambuc cucheck();
1112433d6423SLionel Sambuc exit(SS_NORMAL);
1113433d6423SLionel Sambuc }
1114433d6423SLionel Sambuc
1115433d6423SLionel Sambuc /*
1116433d6423SLionel Sambuc * Get the receiver's init parameters
1117433d6423SLionel Sambuc */
getzrxinit()1118433d6423SLionel Sambuc int getzrxinit()
1119433d6423SLionel Sambuc {
1120433d6423SLionel Sambuc register int n;
1121433d6423SLionel Sambuc struct stat f;
1122433d6423SLionel Sambuc
1123433d6423SLionel Sambuc for (n=10; --n>=0; ) {
1124433d6423SLionel Sambuc
1125433d6423SLionel Sambuc switch (zgethdr(Rxhdr, 1)) {
1126433d6423SLionel Sambuc case ZCHALLENGE: /* Echo receiver's challenge numbr */
1127433d6423SLionel Sambuc stohdr(Rxpos);
1128433d6423SLionel Sambuc zshhdr(ZACK, Txhdr);
1129433d6423SLionel Sambuc continue;
1130433d6423SLionel Sambuc case ZCOMMAND: /* They didn't see out ZRQINIT */
1131433d6423SLionel Sambuc stohdr(0L);
1132433d6423SLionel Sambuc zshhdr(ZRQINIT, Txhdr);
1133433d6423SLionel Sambuc continue;
1134433d6423SLionel Sambuc case ZRINIT:
1135433d6423SLionel Sambuc Rxflags = 0377 & Rxhdr[ZF0];
1136433d6423SLionel Sambuc Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
1137433d6423SLionel Sambuc Zctlesc |= Rxflags & TESCCTL;
1138433d6423SLionel Sambuc Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
1139433d6423SLionel Sambuc if ( !(Rxflags & CANFDX))
1140433d6423SLionel Sambuc Txwindow = 0;
1141433d6423SLionel Sambuc vfile("Rxbuflen=%d Tframlen=%d", Rxbuflen, Tframlen);
1142433d6423SLionel Sambuc if ( !Fromcu)
1143433d6423SLionel Sambuc signal(SIGINT, SIG_IGN);
1144433d6423SLionel Sambuc #ifdef MODE2OK
1145433d6423SLionel Sambuc mode(2); /* Set cbreak, XON/XOFF, etc. */
1146433d6423SLionel Sambuc #endif
1147433d6423SLionel Sambuc #ifndef READCHECK
1148433d6423SLionel Sambuc #ifndef USG
1149433d6423SLionel Sambuc /* Use 1024 byte frames if no sample/interrupt */
1150433d6423SLionel Sambuc if (Rxbuflen < 32 || Rxbuflen > 1024) {
1151433d6423SLionel Sambuc Rxbuflen = 1024;
1152433d6423SLionel Sambuc vfile("Rxbuflen=%d", Rxbuflen);
1153433d6423SLionel Sambuc }
1154433d6423SLionel Sambuc #endif
1155433d6423SLionel Sambuc #endif
1156433d6423SLionel Sambuc /* Override to force shorter frame length */
1157433d6423SLionel Sambuc if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
1158433d6423SLionel Sambuc Rxbuflen = Tframlen;
1159433d6423SLionel Sambuc if ( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))
1160433d6423SLionel Sambuc Rxbuflen = Tframlen;
1161433d6423SLionel Sambuc vfile("Rxbuflen=%d", Rxbuflen);
1162433d6423SLionel Sambuc
1163433d6423SLionel Sambuc #ifndef vax11c
1164433d6423SLionel Sambuc /* If using a pipe for testing set lower buf len */
1165433d6423SLionel Sambuc fstat(iofd, &f);
1166433d6423SLionel Sambuc if ((f.st_mode & S_IFMT) != S_IFCHR) {
1167433d6423SLionel Sambuc Rxbuflen = 1024;
1168433d6423SLionel Sambuc }
1169433d6423SLionel Sambuc #endif
1170433d6423SLionel Sambuc #ifdef BADSEEK
1171433d6423SLionel Sambuc Canseek = 0;
1172433d6423SLionel Sambuc Txwindow = TXBSIZE - 1024;
1173433d6423SLionel Sambuc Txwspac = TXBSIZE/4;
1174433d6423SLionel Sambuc #endif
1175433d6423SLionel Sambuc /*
1176433d6423SLionel Sambuc * If input is not a regular file, force ACK's to
1177433d6423SLionel Sambuc * prevent running beyond the buffer limits
1178433d6423SLionel Sambuc */
1179433d6423SLionel Sambuc if ( !Command) {
1180433d6423SLionel Sambuc fstat(fileno(in), &f);
1181433d6423SLionel Sambuc if ((f.st_mode & S_IFMT) != S_IFREG) {
1182433d6423SLionel Sambuc Canseek = -1;
1183433d6423SLionel Sambuc #ifdef TXBSIZE
1184433d6423SLionel Sambuc Txwindow = TXBSIZE - 1024;
1185433d6423SLionel Sambuc Txwspac = TXBSIZE/4;
1186433d6423SLionel Sambuc #else
1187433d6423SLionel Sambuc return ERROR;
1188433d6423SLionel Sambuc #endif
1189433d6423SLionel Sambuc }
1190433d6423SLionel Sambuc }
1191433d6423SLionel Sambuc /* Set initial subpacket length */
1192433d6423SLionel Sambuc if (blklen < 1024) { /* Command line override? */
1193433d6423SLionel Sambuc if (Baudrate > 300)
1194433d6423SLionel Sambuc blklen = 256;
1195433d6423SLionel Sambuc if (Baudrate > 1200)
1196433d6423SLionel Sambuc blklen = 512;
1197433d6423SLionel Sambuc if (Baudrate > 2400)
1198433d6423SLionel Sambuc blklen = 1024;
1199433d6423SLionel Sambuc }
1200433d6423SLionel Sambuc if (Rxbuflen && blklen>Rxbuflen)
1201433d6423SLionel Sambuc blklen = Rxbuflen;
1202433d6423SLionel Sambuc if (blkopt && blklen > blkopt)
1203433d6423SLionel Sambuc blklen = blkopt;
1204433d6423SLionel Sambuc vfile("Rxbuflen=%d blklen=%d", Rxbuflen, blklen);
1205433d6423SLionel Sambuc vfile("Txwindow = %u Txwspac = %d", Txwindow, Txwspac);
1206433d6423SLionel Sambuc
1207433d6423SLionel Sambuc return (sendzsinit());
1208433d6423SLionel Sambuc case ZCAN:
1209433d6423SLionel Sambuc case TIMEOUT:
1210433d6423SLionel Sambuc return ERROR;
1211433d6423SLionel Sambuc case ZRQINIT:
1212433d6423SLionel Sambuc if (Rxhdr[ZF0] == ZCOMMAND)
1213433d6423SLionel Sambuc continue;
1214433d6423SLionel Sambuc default:
1215433d6423SLionel Sambuc zshhdr(ZNAK, Txhdr);
1216433d6423SLionel Sambuc continue;
1217433d6423SLionel Sambuc }
1218433d6423SLionel Sambuc }
1219433d6423SLionel Sambuc return ERROR;
1220433d6423SLionel Sambuc }
1221433d6423SLionel Sambuc
1222433d6423SLionel Sambuc /* Send send-init information */
sendzsinit()1223433d6423SLionel Sambuc int sendzsinit()
1224433d6423SLionel Sambuc {
1225433d6423SLionel Sambuc register int c;
1226433d6423SLionel Sambuc
1227433d6423SLionel Sambuc if (Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
1228433d6423SLionel Sambuc return OK;
1229433d6423SLionel Sambuc errors = 0;
1230433d6423SLionel Sambuc for (;;) {
1231433d6423SLionel Sambuc stohdr(0L);
1232433d6423SLionel Sambuc if (Zctlesc) {
1233433d6423SLionel Sambuc Txhdr[ZF0] |= TESCCTL; zshhdr(ZSINIT, Txhdr);
1234433d6423SLionel Sambuc }
1235433d6423SLionel Sambuc else
1236433d6423SLionel Sambuc zsbhdr(ZSINIT, Txhdr);
1237433d6423SLionel Sambuc zsdata(Myattn, 1+strlen(Myattn), ZCRCW);
1238433d6423SLionel Sambuc c = zgethdr(Rxhdr, 1);
1239433d6423SLionel Sambuc switch (c) {
1240433d6423SLionel Sambuc case ZCAN:
1241433d6423SLionel Sambuc return ERROR;
1242433d6423SLionel Sambuc case ZACK:
1243433d6423SLionel Sambuc return OK;
1244433d6423SLionel Sambuc default:
1245433d6423SLionel Sambuc if (++errors > 19)
1246433d6423SLionel Sambuc return ERROR;
1247433d6423SLionel Sambuc continue;
1248433d6423SLionel Sambuc }
1249433d6423SLionel Sambuc }
1250433d6423SLionel Sambuc }
1251433d6423SLionel Sambuc
1252433d6423SLionel Sambuc /* Send file name and related info */
zsendfile(char * buf,int blen)1253433d6423SLionel Sambuc int zsendfile(char *buf, int blen)
1254433d6423SLionel Sambuc {
1255433d6423SLionel Sambuc register int c;
1256433d6423SLionel Sambuc register UNSL long crc;
1257433d6423SLionel Sambuc
1258433d6423SLionel Sambuc for (;;) {
1259433d6423SLionel Sambuc Txhdr[ZF0] = Lzconv; /* file conversion request */
1260433d6423SLionel Sambuc Txhdr[ZF1] = Lzmanag; /* file management request */
1261433d6423SLionel Sambuc if (Lskipnocor)
1262433d6423SLionel Sambuc Txhdr[ZF1] |= ZMSKNOLOC;
1263433d6423SLionel Sambuc Txhdr[ZF2] = Lztrans; /* file transport request */
1264433d6423SLionel Sambuc Txhdr[ZF3] = 0;
1265433d6423SLionel Sambuc zsbhdr(ZFILE, Txhdr);
1266433d6423SLionel Sambuc zsdata(buf, blen, ZCRCW);
1267433d6423SLionel Sambuc again:
1268433d6423SLionel Sambuc c = zgethdr(Rxhdr, 1);
1269433d6423SLionel Sambuc switch (c) {
1270433d6423SLionel Sambuc case ZRINIT:
1271433d6423SLionel Sambuc while ((c = readline(50)) > 0)
1272433d6423SLionel Sambuc if (c == ZPAD) {
1273433d6423SLionel Sambuc goto again;
1274433d6423SLionel Sambuc }
1275433d6423SLionel Sambuc /* **** FALL THRU TO **** */
1276433d6423SLionel Sambuc default:
1277433d6423SLionel Sambuc continue;
1278433d6423SLionel Sambuc case ZCAN:
1279433d6423SLionel Sambuc case TIMEOUT:
1280433d6423SLionel Sambuc case ZABORT:
1281433d6423SLionel Sambuc case ZFIN:
1282433d6423SLionel Sambuc return ERROR;
1283433d6423SLionel Sambuc case ZCRC:
1284433d6423SLionel Sambuc crc = 0xFFFFFFFFL;
1285433d6423SLionel Sambuc if (Canseek >= 0) {
1286433d6423SLionel Sambuc while (((c = getc(in)) != EOF) && --Rxpos)
1287433d6423SLionel Sambuc crc = UPDC32(c, crc);
1288433d6423SLionel Sambuc crc = ~crc;
1289433d6423SLionel Sambuc clearerr(in); /* Clear EOF */
1290433d6423SLionel Sambuc fseek(in, 0L, 0);
1291433d6423SLionel Sambuc }
1292433d6423SLionel Sambuc stohdr(crc);
1293433d6423SLionel Sambuc zsbhdr(ZCRC, Txhdr);
1294433d6423SLionel Sambuc goto again;
1295433d6423SLionel Sambuc case ZSKIP:
1296433d6423SLionel Sambuc fclose(in); return c;
1297433d6423SLionel Sambuc case ZRPOS:
1298433d6423SLionel Sambuc /*
1299433d6423SLionel Sambuc * Suppress zcrcw request otherwise triggered by
1300433d6423SLionel Sambuc * lastyunc==bytcnt
1301433d6423SLionel Sambuc */
1302433d6423SLionel Sambuc if (Rxpos && fseek(in, Rxpos, 0))
1303433d6423SLionel Sambuc return ERROR;
1304433d6423SLionel Sambuc Lastsync = (bytcnt = Txpos = Rxpos) -1;
1305433d6423SLionel Sambuc return zsendfdata();
1306433d6423SLionel Sambuc }
1307433d6423SLionel Sambuc }
1308433d6423SLionel Sambuc }
1309433d6423SLionel Sambuc
1310433d6423SLionel Sambuc /* Send the data in the file */
zsendfdata()1311433d6423SLionel Sambuc int zsendfdata()
1312433d6423SLionel Sambuc {
1313433d6423SLionel Sambuc register int c, e, n;
1314433d6423SLionel Sambuc register int newcnt;
1315433d6423SLionel Sambuc register long tcount = 0;
1316433d6423SLionel Sambuc int junkcount; /* Counts garbage chars received by TX */
1317433d6423SLionel Sambuc static int tleft = 6; /* Counter for test mode */
1318433d6423SLionel Sambuc
1319433d6423SLionel Sambuc Lrxpos = 0;
1320433d6423SLionel Sambuc junkcount = 0;
1321433d6423SLionel Sambuc Beenhereb4 = FALSE;
1322433d6423SLionel Sambuc somemore:
1323433d6423SLionel Sambuc if (setjmp(intrjmp)) {
1324433d6423SLionel Sambuc waitack:
1325433d6423SLionel Sambuc junkcount = 0;
1326433d6423SLionel Sambuc c = getinsync(0);
1327433d6423SLionel Sambuc gotack:
1328433d6423SLionel Sambuc switch (c) {
1329433d6423SLionel Sambuc default:
1330433d6423SLionel Sambuc case ZCAN:
1331433d6423SLionel Sambuc fclose(in);
1332433d6423SLionel Sambuc return ERROR;
1333433d6423SLionel Sambuc case ZSKIP:
1334433d6423SLionel Sambuc fclose(in);
1335433d6423SLionel Sambuc return c;
1336433d6423SLionel Sambuc case ZACK:
1337433d6423SLionel Sambuc case ZRPOS:
1338433d6423SLionel Sambuc break;
1339433d6423SLionel Sambuc case ZRINIT:
1340433d6423SLionel Sambuc return OK;
1341433d6423SLionel Sambuc }
1342433d6423SLionel Sambuc #ifdef READCHECK
1343433d6423SLionel Sambuc /*
1344433d6423SLionel Sambuc * If the reverse channel can be tested for data,
1345433d6423SLionel Sambuc * this logic may be used to detect error packets
1346433d6423SLionel Sambuc * sent by the receiver, in place of setjmp/longjmp
1347433d6423SLionel Sambuc * rdchk(fdes) returns non 0 if a character is available
1348433d6423SLionel Sambuc */
1349433d6423SLionel Sambuc while (rdchk(iofd)) {
1350433d6423SLionel Sambuc #ifdef SV
1351433d6423SLionel Sambuc switch (checked)
1352433d6423SLionel Sambuc #else
1353433d6423SLionel Sambuc switch (readline(1))
1354433d6423SLionel Sambuc #endif
1355433d6423SLionel Sambuc {
1356433d6423SLionel Sambuc case CAN:
1357433d6423SLionel Sambuc case ZPAD:
1358433d6423SLionel Sambuc c = getinsync(1);
1359433d6423SLionel Sambuc goto gotack;
1360433d6423SLionel Sambuc case XOFF: /* Wait a while for an XON */
1361433d6423SLionel Sambuc case XOFF|0200:
1362433d6423SLionel Sambuc readline(100);
1363433d6423SLionel Sambuc }
1364433d6423SLionel Sambuc }
1365433d6423SLionel Sambuc #endif
1366433d6423SLionel Sambuc }
1367433d6423SLionel Sambuc
1368433d6423SLionel Sambuc if ( !Fromcu)
1369433d6423SLionel Sambuc signal(SIGINT, onintr);
1370433d6423SLionel Sambuc newcnt = Rxbuflen;
1371433d6423SLionel Sambuc Txwcnt = 0;
1372433d6423SLionel Sambuc stohdr(Txpos);
1373433d6423SLionel Sambuc zsbhdr(ZDATA, Txhdr);
1374433d6423SLionel Sambuc
1375433d6423SLionel Sambuc /*
1376433d6423SLionel Sambuc * Special testing mode. This should force receiver to Attn,ZRPOS
1377433d6423SLionel Sambuc * many times. Each time the signal should be caught, causing the
1378433d6423SLionel Sambuc * file to be started over from the beginning.
1379433d6423SLionel Sambuc */
1380433d6423SLionel Sambuc if (Test) {
1381433d6423SLionel Sambuc if ( --tleft)
1382433d6423SLionel Sambuc while (tcount < 20000) {
1383d0055759SDavid van Moolenbroek printf("%s", qbf); fflush(stdout);
1384433d6423SLionel Sambuc tcount += strlen(qbf);
1385433d6423SLionel Sambuc #ifdef READCHECK
1386433d6423SLionel Sambuc while (rdchk(iofd)) {
1387433d6423SLionel Sambuc #ifdef SV
1388433d6423SLionel Sambuc switch (checked)
1389433d6423SLionel Sambuc #else
1390433d6423SLionel Sambuc switch (readline(1))
1391433d6423SLionel Sambuc #endif
1392433d6423SLionel Sambuc {
1393433d6423SLionel Sambuc case CAN:
1394433d6423SLionel Sambuc case ZPAD:
1395433d6423SLionel Sambuc #ifdef TCFLSH
1396433d6423SLionel Sambuc ioctl(iofd, TCFLSH, 1);
1397433d6423SLionel Sambuc #endif
1398433d6423SLionel Sambuc goto waitack;
1399433d6423SLionel Sambuc case XOFF: /* Wait for XON */
1400433d6423SLionel Sambuc case XOFF|0200:
1401433d6423SLionel Sambuc readline(100);
1402433d6423SLionel Sambuc }
1403433d6423SLionel Sambuc }
1404433d6423SLionel Sambuc #endif
1405433d6423SLionel Sambuc }
1406433d6423SLionel Sambuc signal(SIGINT, SIG_IGN); canit();
1407433d6423SLionel Sambuc sleep(3); purgeline(); mode(0);
1408433d6423SLionel Sambuc printf("\nsz: Tcount = %ld\n", tcount);
1409433d6423SLionel Sambuc if (tleft) {
1410433d6423SLionel Sambuc printf("ERROR: Interrupts Not Caught\n");
1411433d6423SLionel Sambuc exit(1);
1412433d6423SLionel Sambuc }
1413433d6423SLionel Sambuc exit(SS_NORMAL);
1414433d6423SLionel Sambuc }
1415433d6423SLionel Sambuc
1416433d6423SLionel Sambuc do {
1417433d6423SLionel Sambuc n = zfilbuf();
1418433d6423SLionel Sambuc if (Eofseen)
1419433d6423SLionel Sambuc e = ZCRCE;
1420433d6423SLionel Sambuc else if (junkcount > 3)
1421433d6423SLionel Sambuc e = ZCRCW;
1422433d6423SLionel Sambuc else if (bytcnt == Lastsync)
1423433d6423SLionel Sambuc e = ZCRCW;
1424433d6423SLionel Sambuc else if (Rxbuflen && (newcnt -= n) <= 0)
1425433d6423SLionel Sambuc e = ZCRCW;
1426433d6423SLionel Sambuc else if (Txwindow && (Txwcnt += n) >= Txwspac) {
1427433d6423SLionel Sambuc Txwcnt = 0; e = ZCRCQ;
1428433d6423SLionel Sambuc }
1429433d6423SLionel Sambuc else
1430433d6423SLionel Sambuc e = ZCRCG;
1431433d6423SLionel Sambuc if (Verbose>1)
1432433d6423SLionel Sambuc fprintf(stderr, "\r%7ld ZMODEM%s ",
1433433d6423SLionel Sambuc Txpos, Crc32t?" CRC-32":"");
1434433d6423SLionel Sambuc zsdata(txbuf, n, e);
1435433d6423SLionel Sambuc bytcnt = Txpos += n;
1436433d6423SLionel Sambuc if (e == ZCRCW)
1437433d6423SLionel Sambuc goto waitack;
1438433d6423SLionel Sambuc #ifdef READCHECK
1439433d6423SLionel Sambuc /*
1440433d6423SLionel Sambuc * If the reverse channel can be tested for data,
1441433d6423SLionel Sambuc * this logic may be used to detect error packets
1442433d6423SLionel Sambuc * sent by the receiver, in place of setjmp/longjmp
1443433d6423SLionel Sambuc * rdchk(fdes) returns non 0 if a character is available
1444433d6423SLionel Sambuc */
1445433d6423SLionel Sambuc fflush(stdout);
1446433d6423SLionel Sambuc while (rdchk(iofd)) {
1447433d6423SLionel Sambuc #ifdef SV
1448433d6423SLionel Sambuc switch (checked)
1449433d6423SLionel Sambuc #else
1450433d6423SLionel Sambuc switch (readline(1))
1451433d6423SLionel Sambuc #endif
1452433d6423SLionel Sambuc {
1453433d6423SLionel Sambuc case CAN:
1454433d6423SLionel Sambuc case ZPAD:
1455433d6423SLionel Sambuc c = getinsync(1);
1456433d6423SLionel Sambuc if (c == ZACK)
1457433d6423SLionel Sambuc break;
1458433d6423SLionel Sambuc #ifdef TCFLSH
1459433d6423SLionel Sambuc ioctl(iofd, TCFLSH, 1);
1460433d6423SLionel Sambuc #endif
1461433d6423SLionel Sambuc /* zcrce - dinna wanna starta ping-pong game */
1462433d6423SLionel Sambuc zsdata(txbuf, 0, ZCRCE);
1463433d6423SLionel Sambuc goto gotack;
1464433d6423SLionel Sambuc case XOFF: /* Wait a while for an XON */
1465433d6423SLionel Sambuc case XOFF|0200:
1466433d6423SLionel Sambuc readline(100);
1467433d6423SLionel Sambuc default:
1468433d6423SLionel Sambuc ++junkcount;
1469433d6423SLionel Sambuc }
1470433d6423SLionel Sambuc }
1471433d6423SLionel Sambuc #endif /* READCHECK */
1472433d6423SLionel Sambuc if (Txwindow) {
1473433d6423SLionel Sambuc while ((tcount = Txpos - Lrxpos) >= Txwindow) {
1474433d6423SLionel Sambuc vfile("%ld window >= %u", tcount, Txwindow);
1475433d6423SLionel Sambuc if (e != ZCRCQ)
1476433d6423SLionel Sambuc zsdata(txbuf, 0, e = ZCRCQ);
1477433d6423SLionel Sambuc c = getinsync(1);
1478433d6423SLionel Sambuc if (c != ZACK) {
1479433d6423SLionel Sambuc #ifdef TCFLSH
1480433d6423SLionel Sambuc ioctl(iofd, TCFLSH, 1);
1481433d6423SLionel Sambuc #endif
1482433d6423SLionel Sambuc zsdata(txbuf, 0, ZCRCE);
1483433d6423SLionel Sambuc goto gotack;
1484433d6423SLionel Sambuc }
1485433d6423SLionel Sambuc }
1486433d6423SLionel Sambuc vfile("window = %ld", tcount);
1487433d6423SLionel Sambuc }
1488433d6423SLionel Sambuc } while (!Eofseen);
1489433d6423SLionel Sambuc if ( !Fromcu)
1490433d6423SLionel Sambuc signal(SIGINT, SIG_IGN);
1491433d6423SLionel Sambuc
1492433d6423SLionel Sambuc for (;;) {
1493433d6423SLionel Sambuc stohdr(Txpos);
1494433d6423SLionel Sambuc zsbhdr(ZEOF, Txhdr);
1495433d6423SLionel Sambuc switch (getinsync(0)) {
1496433d6423SLionel Sambuc case ZACK:
1497433d6423SLionel Sambuc continue;
1498433d6423SLionel Sambuc case ZRPOS:
1499433d6423SLionel Sambuc goto somemore;
1500433d6423SLionel Sambuc case ZRINIT:
1501433d6423SLionel Sambuc return OK;
1502433d6423SLionel Sambuc case ZSKIP:
1503433d6423SLionel Sambuc fclose(in);
1504433d6423SLionel Sambuc return c;
1505433d6423SLionel Sambuc default:
1506433d6423SLionel Sambuc fclose(in);
1507433d6423SLionel Sambuc return ERROR;
1508433d6423SLionel Sambuc }
1509433d6423SLionel Sambuc }
1510433d6423SLionel Sambuc }
1511433d6423SLionel Sambuc
1512433d6423SLionel Sambuc /*
1513433d6423SLionel Sambuc * Respond to receiver's complaint, get back in sync with receiver
1514433d6423SLionel Sambuc */
getinsync(int flag)1515433d6423SLionel Sambuc int getinsync(int flag)
1516433d6423SLionel Sambuc {
1517433d6423SLionel Sambuc register int c;
1518433d6423SLionel Sambuc
1519433d6423SLionel Sambuc for (;;) {
1520433d6423SLionel Sambuc if (Test) {
1521433d6423SLionel Sambuc printf("\r\n\n\n***** Signal Caught *****\r\n");
1522433d6423SLionel Sambuc Rxpos = 0; c = ZRPOS;
1523433d6423SLionel Sambuc } else
1524433d6423SLionel Sambuc c = zgethdr(Rxhdr, 0);
1525433d6423SLionel Sambuc switch (c) {
1526433d6423SLionel Sambuc case ZCAN:
1527433d6423SLionel Sambuc case ZABORT:
1528433d6423SLionel Sambuc case ZFIN:
1529433d6423SLionel Sambuc case TIMEOUT:
1530433d6423SLionel Sambuc return ERROR;
1531433d6423SLionel Sambuc case ZRPOS:
1532433d6423SLionel Sambuc /* ************************************* */
1533433d6423SLionel Sambuc /* If sending to a buffered modem, you */
1534433d6423SLionel Sambuc /* might send a break at this point to */
1535433d6423SLionel Sambuc /* dump the modem's buffer. */
1536433d6423SLionel Sambuc clearerr(in); /* In case file EOF seen */
1537433d6423SLionel Sambuc if (fseek(in, Rxpos, 0))
1538433d6423SLionel Sambuc return ERROR;
1539433d6423SLionel Sambuc Eofseen = 0;
1540433d6423SLionel Sambuc bytcnt = Lrxpos = Txpos = Rxpos;
1541433d6423SLionel Sambuc if (Lastsync == Rxpos) {
1542433d6423SLionel Sambuc if (++Beenhereb4 > 4)
1543433d6423SLionel Sambuc if (blklen > 32)
1544433d6423SLionel Sambuc blklen /= 2;
1545433d6423SLionel Sambuc }
1546433d6423SLionel Sambuc Lastsync = Rxpos;
1547433d6423SLionel Sambuc return c;
1548433d6423SLionel Sambuc case ZACK:
1549433d6423SLionel Sambuc Lrxpos = Rxpos;
1550433d6423SLionel Sambuc if (flag || Txpos == Rxpos)
1551433d6423SLionel Sambuc return ZACK;
1552433d6423SLionel Sambuc continue;
1553433d6423SLionel Sambuc case ZRINIT:
1554433d6423SLionel Sambuc case ZSKIP:
1555433d6423SLionel Sambuc fclose(in);
1556433d6423SLionel Sambuc return c;
1557433d6423SLionel Sambuc case ERROR:
1558433d6423SLionel Sambuc default:
1559433d6423SLionel Sambuc zsbhdr(ZNAK, Txhdr);
1560433d6423SLionel Sambuc continue;
1561433d6423SLionel Sambuc }
1562433d6423SLionel Sambuc }
1563433d6423SLionel Sambuc }
1564433d6423SLionel Sambuc
1565433d6423SLionel Sambuc
1566433d6423SLionel Sambuc /* Say "bibi" to the receiver, try to do it cleanly */
saybibi()1567433d6423SLionel Sambuc void saybibi()
1568433d6423SLionel Sambuc {
1569433d6423SLionel Sambuc for (;;) {
1570433d6423SLionel Sambuc stohdr(0L); /* CAF Was zsbhdr - minor change */
1571433d6423SLionel Sambuc zshhdr(ZFIN, Txhdr); /* to make debugging easier */
1572433d6423SLionel Sambuc switch (zgethdr(Rxhdr, 0)) {
1573433d6423SLionel Sambuc case ZFIN:
1574433d6423SLionel Sambuc sendline('O'); sendline('O'); flushmo();
1575433d6423SLionel Sambuc case ZCAN:
1576433d6423SLionel Sambuc case TIMEOUT:
1577433d6423SLionel Sambuc return;
1578433d6423SLionel Sambuc }
1579433d6423SLionel Sambuc }
1580433d6423SLionel Sambuc }
1581433d6423SLionel Sambuc
1582433d6423SLionel Sambuc /* Local screen character display function */
bttyout(int c)1583433d6423SLionel Sambuc void bttyout(int c)
1584433d6423SLionel Sambuc {
1585433d6423SLionel Sambuc if (Verbose)
1586433d6423SLionel Sambuc putc(c, stderr);
1587433d6423SLionel Sambuc }
1588433d6423SLionel Sambuc
1589433d6423SLionel Sambuc /* Send command and related info */
zsendcmd(char * buf,int blen)1590433d6423SLionel Sambuc int zsendcmd(char *buf, int blen)
1591433d6423SLionel Sambuc {
1592433d6423SLionel Sambuc register int c;
1593433d6423SLionel Sambuc long cmdnum;
1594433d6423SLionel Sambuc
1595433d6423SLionel Sambuc cmdnum = getpid();
1596433d6423SLionel Sambuc errors = 0;
1597433d6423SLionel Sambuc for (;;) {
1598433d6423SLionel Sambuc stohdr(cmdnum);
1599433d6423SLionel Sambuc Txhdr[ZF0] = Cmdack1;
1600433d6423SLionel Sambuc zsbhdr(ZCOMMAND, Txhdr);
1601433d6423SLionel Sambuc zsdata(buf, blen, ZCRCW);
1602433d6423SLionel Sambuc listen:
1603433d6423SLionel Sambuc Rxtimeout = 100; /* Ten second wait for resp. */
1604433d6423SLionel Sambuc c = zgethdr(Rxhdr, 1);
1605433d6423SLionel Sambuc
1606433d6423SLionel Sambuc switch (c) {
1607433d6423SLionel Sambuc case ZRINIT:
1608433d6423SLionel Sambuc goto listen; /* CAF 8-21-87 */
1609433d6423SLionel Sambuc case ERROR:
1610433d6423SLionel Sambuc case TIMEOUT:
1611433d6423SLionel Sambuc if (++errors > Cmdtries)
1612433d6423SLionel Sambuc return ERROR;
1613433d6423SLionel Sambuc continue;
1614433d6423SLionel Sambuc case ZCAN:
1615433d6423SLionel Sambuc case ZABORT:
1616433d6423SLionel Sambuc case ZFIN:
1617433d6423SLionel Sambuc case ZSKIP:
1618433d6423SLionel Sambuc case ZRPOS:
1619433d6423SLionel Sambuc return ERROR;
1620433d6423SLionel Sambuc default:
1621433d6423SLionel Sambuc if (++errors > 20)
1622433d6423SLionel Sambuc return ERROR;
1623433d6423SLionel Sambuc continue;
1624433d6423SLionel Sambuc case ZCOMPL:
1625433d6423SLionel Sambuc Exitcode = Rxpos;
1626433d6423SLionel Sambuc saybibi();
1627433d6423SLionel Sambuc return OK;
1628433d6423SLionel Sambuc case ZRQINIT:
1629433d6423SLionel Sambuc #ifdef vax11c /* YAMP :== Yet Another Missing Primitive */
1630433d6423SLionel Sambuc return ERROR;
1631433d6423SLionel Sambuc #else
1632433d6423SLionel Sambuc vfile("******** RZ *******");
1633433d6423SLionel Sambuc system("rz");
1634433d6423SLionel Sambuc vfile("******** SZ *******");
1635433d6423SLionel Sambuc goto listen;
1636433d6423SLionel Sambuc #endif
1637433d6423SLionel Sambuc }
1638433d6423SLionel Sambuc }
1639433d6423SLionel Sambuc }
1640433d6423SLionel Sambuc
1641433d6423SLionel Sambuc /*
1642433d6423SLionel Sambuc * If called as sb use YMODEM protocol
1643433d6423SLionel Sambuc */
chkinvok(char * s)1644433d6423SLionel Sambuc void chkinvok(char *s)
1645433d6423SLionel Sambuc {
1646433d6423SLionel Sambuc #ifdef vax11c
1647433d6423SLionel Sambuc Progname = "sz";
1648433d6423SLionel Sambuc #else
1649433d6423SLionel Sambuc register char *p;
1650433d6423SLionel Sambuc
1651433d6423SLionel Sambuc p = s;
1652433d6423SLionel Sambuc while (*p == '-')
1653433d6423SLionel Sambuc s = ++p;
1654433d6423SLionel Sambuc while (*p)
1655433d6423SLionel Sambuc if (*p++ == '/')
1656433d6423SLionel Sambuc s = p;
1657433d6423SLionel Sambuc if (*s == 'v') {
1658433d6423SLionel Sambuc Verbose=1; ++s;
1659433d6423SLionel Sambuc }
1660433d6423SLionel Sambuc Progname = s;
1661433d6423SLionel Sambuc if (s[0]=='s' && s[1]=='b') {
1662433d6423SLionel Sambuc Nozmodem = TRUE; blklen=1024;
1663433d6423SLionel Sambuc }
1664433d6423SLionel Sambuc if (s[0]=='s' && s[1]=='x') {
1665433d6423SLionel Sambuc Modem2 = TRUE;
1666433d6423SLionel Sambuc }
1667433d6423SLionel Sambuc #endif
1668433d6423SLionel Sambuc }
1669433d6423SLionel Sambuc
countem(int argc,char ** argv)1670433d6423SLionel Sambuc void countem(int argc, char **argv)
1671433d6423SLionel Sambuc {
1672433d6423SLionel Sambuc register int c;
1673433d6423SLionel Sambuc struct stat f;
1674433d6423SLionel Sambuc
1675433d6423SLionel Sambuc for (Totalleft = 0, Filesleft = 0; --argc >=0; ++argv) {
1676433d6423SLionel Sambuc f.st_size = -1;
1677433d6423SLionel Sambuc if (Verbose>2) {
1678433d6423SLionel Sambuc fprintf(stderr, "\nCountem: %03d %s ", argc, *argv);
1679433d6423SLionel Sambuc fflush(stderr);
1680433d6423SLionel Sambuc }
1681433d6423SLionel Sambuc if (access(*argv, 04) >= 0 && stat(*argv, &f) >= 0) {
1682433d6423SLionel Sambuc c = f.st_mode & S_IFMT;
1683433d6423SLionel Sambuc if (c != S_IFDIR && c != S_IFBLK) {
1684433d6423SLionel Sambuc ++Filesleft; Totalleft += f.st_size;
1685433d6423SLionel Sambuc }
1686433d6423SLionel Sambuc }
1687433d6423SLionel Sambuc if (Verbose>2)
1688433d6423SLionel Sambuc fprintf(stderr, " %lld", f.st_size);
1689433d6423SLionel Sambuc }
1690433d6423SLionel Sambuc if (Verbose>2)
1691433d6423SLionel Sambuc fprintf(stderr, "\ncountem: Total %d %ld\n",
1692433d6423SLionel Sambuc Filesleft, Totalleft);
1693433d6423SLionel Sambuc }
1694433d6423SLionel Sambuc
chartest(int m)1695433d6423SLionel Sambuc void chartest(int m)
1696433d6423SLionel Sambuc {
1697433d6423SLionel Sambuc register int n;
1698433d6423SLionel Sambuc
1699433d6423SLionel Sambuc mode(m);
1700433d6423SLionel Sambuc printf("\r\n\nCharacter Transparency Test Mode %d\r\n", m);
1701433d6423SLionel Sambuc printf("If Pro-YAM/ZCOMM is not displaying ^M hit ALT-V NOW.\r\n");
1702433d6423SLionel Sambuc printf("Hit Enter.\021"); fflush(stdout);
1703433d6423SLionel Sambuc readline(500);
1704433d6423SLionel Sambuc
1705433d6423SLionel Sambuc for (n = 0; n < 256; ++n) {
1706433d6423SLionel Sambuc if (!(n%8))
1707433d6423SLionel Sambuc printf("\r\n");
1708433d6423SLionel Sambuc printf("%02x ", n); fflush(stdout);
1709433d6423SLionel Sambuc sendline(n); flushmo();
1710433d6423SLionel Sambuc printf(" "); fflush(stdout);
1711433d6423SLionel Sambuc if (n == 127) {
1712433d6423SLionel Sambuc printf("Hit Enter.\021"); fflush(stdout);
1713433d6423SLionel Sambuc readline(500);
1714433d6423SLionel Sambuc printf("\r\n"); fflush(stdout);
1715433d6423SLionel Sambuc }
1716433d6423SLionel Sambuc }
1717433d6423SLionel Sambuc printf("\021\r\nEnter Characters, echo is in hex.\r\n");
1718433d6423SLionel Sambuc printf("Hit SPACE or pause 40 seconds for exit.\r\n");
1719433d6423SLionel Sambuc
1720433d6423SLionel Sambuc while (n != TIMEOUT && n != ' ') {
1721433d6423SLionel Sambuc n = readline(400);
1722433d6423SLionel Sambuc printf("%02x\r\n", n);
1723433d6423SLionel Sambuc fflush(stdout);
1724433d6423SLionel Sambuc }
1725433d6423SLionel Sambuc printf("\r\nMode %d character transparency test ends.\r\n", m);
1726433d6423SLionel Sambuc fflush(stdout);
1727433d6423SLionel Sambuc }
1728433d6423SLionel Sambuc
1729433d6423SLionel Sambuc /* End of sz.c */
1730