1 | #define VERSION "sz 2.12 05-29-88"
|
---|
2 | #define PUBDIR "/usr/spool/uucppublic"
|
---|
3 |
|
---|
4 | /*% cc -compat -M2 -Ox -K -i -DTXBSIZE=16384 -DNFGVMIN -DREADCHECK sz.c -lx -o sz; size sz
|
---|
5 |
|
---|
6 | Following is used for testing, might not be reasonable for production
|
---|
7 | <-xtx-*> cc -Osal -DTXBSIZE=32768 -DSV sz.c -lx -o $B/sz; size $B/sz
|
---|
8 |
|
---|
9 | ****************************************************************************
|
---|
10 | *
|
---|
11 | * sz.c By Chuck Forsberg, Omen Technology INC
|
---|
12 | *
|
---|
13 | ****************************************************************************
|
---|
14 | *
|
---|
15 | * Typical Unix/Xenix/Clone compiles:
|
---|
16 | *
|
---|
17 | * cc -O sz.c -o sz USG (SYS III/V) Unix
|
---|
18 | * cc -O -DSV sz.c -o sz Sys V Release 2 with non-blocking input
|
---|
19 | * Define to allow reverse channel checking
|
---|
20 | * cc -O -DV7 sz.c -o sz Unix Version 7, 2.8 - 4.3 BSD
|
---|
21 | *
|
---|
22 | * cc -O -K -i -DNFGVMIN -DREADCHECK sz.c -lx -o sz Classic Xenix
|
---|
23 | *
|
---|
24 | * ln sz sb **** All versions ****
|
---|
25 | * ln sz sx **** All versions ****
|
---|
26 | *
|
---|
27 | ****************************************************************************
|
---|
28 | *
|
---|
29 | * Typical VMS compile and install sequence:
|
---|
30 | *
|
---|
31 | * define LNK$LIBRARY SYS$LIBRARY:VAXCRTL.OLB
|
---|
32 | * cc sz.c
|
---|
33 | * cc vvmodem.c
|
---|
34 | * link sz,vvmodem
|
---|
35 | * sz :== $disk$user2:[username.subdir]sz.exe
|
---|
36 | *
|
---|
37 | * If you feel adventureous, remove the #define BADSYNC line
|
---|
38 | * immediately following the #ifdef vax11c line! Some VMS
|
---|
39 | * systems know how to fseek, some don't.
|
---|
40 | *
|
---|
41 | ****************************************************************************
|
---|
42 | *
|
---|
43 | *
|
---|
44 | * A program for Unix to send files and commands to computers running
|
---|
45 | * Professional-YAM, PowerCom, YAM, IMP, or programs supporting Y/XMODEM.
|
---|
46 | *
|
---|
47 | * Sz uses buffered I/O to greatly reduce CPU time compared to UMODEM.
|
---|
48 | *
|
---|
49 | * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin
|
---|
50 | *
|
---|
51 | * 2.1x hacks to avoid VMS fseek() bogosity, allow input from pipe
|
---|
52 | * -DBADSEEK -DTXBSIZE=32768
|
---|
53 | * 2.x has mods for VMS flavor
|
---|
54 | *
|
---|
55 | * 1.34 implements tx backchannel garbage count and ZCRCW after ZRPOS
|
---|
56 | * in accordance with the 7-31-87 ZMODEM Protocol Description
|
---|
57 | */
|
---|
58 |
|
---|
59 |
|
---|
60 | #include <sys/types.h>
|
---|
61 |
|
---|
62 | #ifdef vax11c
|
---|
63 | #define BADSEEK
|
---|
64 | #define TXBSIZE 32768 /* Must be power of two, < MAXINT */
|
---|
65 | #include <types.h>
|
---|
66 | #include <stat.h>
|
---|
67 | #define LOGFILE "szlog.tmp"
|
---|
68 | #define OS "VMS"
|
---|
69 | #define READCHECK
|
---|
70 | #define BUFWRITE
|
---|
71 | #define iofd
|
---|
72 | extern int errno;
|
---|
73 | #define SS_NORMAL SS$_NORMAL
|
---|
74 | #define xsendline(c) sendline(c)
|
---|
75 |
|
---|
76 |
|
---|
77 | #else /* vax11c */
|
---|
78 |
|
---|
79 |
|
---|
80 | #define SS_NORMAL 0
|
---|
81 | #define LOGFILE "/tmp/szlog"
|
---|
82 |
|
---|
83 | #define sendline(c) putchar((c) & 0377)
|
---|
84 | #define xsendline(c) putchar(c)
|
---|
85 |
|
---|
86 | #endif
|
---|
87 |
|
---|
88 | #include <signal.h>
|
---|
89 | #include <setjmp.h>
|
---|
90 | #include <ctype.h>
|
---|
91 | #include <errno.h>
|
---|
92 | #include <stdlib.h>
|
---|
93 | #include <string.h>
|
---|
94 | #include <stdlib.h>
|
---|
95 | #include <unistd.h>
|
---|
96 | #include <utime.h>
|
---|
97 | #include <stdio.h>
|
---|
98 |
|
---|
99 | #define PATHLEN 256
|
---|
100 | #define OK 0
|
---|
101 | #define FALSE 0
|
---|
102 | #define TRUE 1
|
---|
103 | #undef ERROR
|
---|
104 | #define ERROR (-1)
|
---|
105 | /* Ward Christensen / CP/M parameters - Don't change these! */
|
---|
106 | #define ENQ 005
|
---|
107 | #define CAN ('X'&037)
|
---|
108 | #define XOFF ('s'&037)
|
---|
109 | #define XON ('q'&037)
|
---|
110 | #define SOH 1
|
---|
111 | #define STX 2
|
---|
112 | #define EOT 4
|
---|
113 | #define ACK 6
|
---|
114 | #define NAK 025
|
---|
115 | #define CPMEOF 032
|
---|
116 | #define WANTCRC 0103 /* send C not NAK to get crc not checksum */
|
---|
117 | #define WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */
|
---|
118 | #define TIMEOUT (-2)
|
---|
119 | #define RCDO (-3)
|
---|
120 | #define RETRYMAX 10
|
---|
121 |
|
---|
122 |
|
---|
123 | #define HOWMANY 2
|
---|
124 | int Zmodem=0; /* ZMODEM protocol requested by receiver */
|
---|
125 | unsigned Baudrate=2400; /* Default, should be set by first mode() call */
|
---|
126 | unsigned Txwindow; /* Control the size of the transmitted window */
|
---|
127 | unsigned Txwspac; /* Spacing between zcrcq requests */
|
---|
128 | unsigned Txwcnt; /* Counter used to space ack requests */
|
---|
129 | long Lrxpos; /* Receiver's last reported offset */
|
---|
130 | int errors;
|
---|
131 |
|
---|
132 | #ifdef vax11c
|
---|
133 | #include "vrzsz.c" /* most of the system dependent stuff here */
|
---|
134 | #else
|
---|
135 | #include "rbsb.c" /* most of the system dependent stuff here */
|
---|
136 | #endif
|
---|
137 | #include "crctab.c"
|
---|
138 |
|
---|
139 | int Filesleft;
|
---|
140 | long Totalleft;
|
---|
141 |
|
---|
142 | /*
|
---|
143 | * Attention string to be executed by receiver to interrupt streaming data
|
---|
144 | * when an error is detected. A pause (0336) may be needed before the
|
---|
145 | * ^C (03) or after it.
|
---|
146 | */
|
---|
147 | #ifdef READCHECK
|
---|
148 | char Myattn[] = { 0 };
|
---|
149 | #else
|
---|
150 | #ifdef USG
|
---|
151 | char Myattn[] = { 03, 0336, 0 };
|
---|
152 | #else
|
---|
153 | char Myattn[] = { 0 };
|
---|
154 | #endif
|
---|
155 | #endif
|
---|
156 |
|
---|
157 | FILE *in;
|
---|
158 |
|
---|
159 | #ifdef BADSEEK
|
---|
160 | int Canseek = 0; /* 1: Can seek 0: only rewind -1: neither (pipe) */
|
---|
161 | #ifndef TXBSIZE
|
---|
162 | #define TXBSIZE 16384 /* Must be power of two, < MAXINT */
|
---|
163 | #endif
|
---|
164 | #else
|
---|
165 | int Canseek = 1; /* 1: Can seek 0: only rewind -1: neither (pipe) */
|
---|
166 | #endif
|
---|
167 |
|
---|
168 | #ifdef TXBSIZE
|
---|
169 | #define TXBMASK (TXBSIZE-1)
|
---|
170 | char Txb[TXBSIZE]; /* Circular buffer for file reads */
|
---|
171 | char *txbuf = Txb; /* Pointer to current file segment */
|
---|
172 | #else
|
---|
173 | char txbuf[1024];
|
---|
174 | #endif
|
---|
175 | long vpos = 0; /* Number of bytes read from file */
|
---|
176 |
|
---|
177 | char Lastrx;
|
---|
178 | char Crcflg;
|
---|
179 | int Verbose=0;
|
---|
180 | int Modem2=0; /* XMODEM Protocol - don't send pathnames */
|
---|
181 | int Restricted=0; /* restricted; no /.. or ../ in filenames */
|
---|
182 | int Quiet=0; /* overrides logic that would otherwise set verbose */
|
---|
183 | int Ascii=0; /* Add CR's for brain damaged programs */
|
---|
184 | int Fullname=0; /* transmit full pathname */
|
---|
185 | int Unlinkafter=0; /* Unlink file after it is sent */
|
---|
186 | int Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */
|
---|
187 | int firstsec;
|
---|
188 | int errcnt=0; /* number of files unreadable */
|
---|
189 | int blklen=128; /* length of transmitted records */
|
---|
190 | int Optiong; /* Let it rip no wait for sector ACK's */
|
---|
191 | int Eofseen; /* EOF seen on input set by zfilbuf */
|
---|
192 | int BEofseen; /* EOF seen on input set by fooseek */
|
---|
193 | int Totsecs; /* total number of sectors this file */
|
---|
194 | int Filcnt=0; /* count of number of files opened */
|
---|
195 | int Lfseen=0;
|
---|
196 | unsigned Rxbuflen = 16384; /* Receiver's max buffer length */
|
---|
197 | int Tframlen = 0; /* Override for tx frame length */
|
---|
198 | int blkopt=0; /* Override value for zmodem blklen */
|
---|
199 | int Rxflags = 0;
|
---|
200 | long bytcnt;
|
---|
201 | int Wantfcs32 = TRUE; /* want to send 32 bit FCS */
|
---|
202 | char Lzconv; /* Local ZMODEM file conversion request */
|
---|
203 | char Lzmanag; /* Local ZMODEM file management request */
|
---|
204 | int Lskipnocor;
|
---|
205 | char Lztrans;
|
---|
206 | char zconv; /* ZMODEM file conversion request */
|
---|
207 | char zmanag; /* ZMODEM file management request */
|
---|
208 | char ztrans; /* ZMODEM file transport request */
|
---|
209 | int Command; /* Send a command, then exit. */
|
---|
210 | char *Cmdstr; /* Pointer to the command string */
|
---|
211 | int Cmdtries = 11;
|
---|
212 | int Cmdack1; /* Rx ACKs command, then do it */
|
---|
213 | int Exitcode = 0;
|
---|
214 | int Test; /* 1= Force receiver to send Attn, etc with qbf. */
|
---|
215 | /* 2= Character transparency test */
|
---|
216 | char *qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n";
|
---|
217 | long Lastsync; /* Last offset to which we got a ZRPOS */
|
---|
218 | int Beenhereb4; /* How many times we've been ZRPOS'd same place */
|
---|
219 |
|
---|
220 | jmp_buf tohere; /* For the interrupt on RX timeout */
|
---|
221 | jmp_buf intrjmp; /* For the interrupt on RX CAN */
|
---|
222 |
|
---|
223 | _PROTOTYPE(void onintr , (int sig ));
|
---|
224 | _PROTOTYPE(int main , (int argc , char *argv []));
|
---|
225 | _PROTOTYPE(int wcsend , (int argc , char *argp []));
|
---|
226 | _PROTOTYPE(int wcs , (char *oname ));
|
---|
227 | _PROTOTYPE(int wctxpn , (char *name ));
|
---|
228 | _PROTOTYPE(int getnak , (void));
|
---|
229 | _PROTOTYPE(int wctx , (long flen ));
|
---|
230 | _PROTOTYPE(int wcputsec , (char *buf , int sectnum , int cseclen ));
|
---|
231 | _PROTOTYPE(int filbuf , (char *buf , int count ));
|
---|
232 | _PROTOTYPE(int zfilbuf , (void));
|
---|
233 | _PROTOTYPE(int fooseek , (FILE *fptr , long pos , int whence ));
|
---|
234 | _PROTOTYPE(void alrm , (int sig ));
|
---|
235 | _PROTOTYPE(int readline , (int timeout ));
|
---|
236 | _PROTOTYPE(void flushmo , (void));
|
---|
237 | _PROTOTYPE(void purgeline , (void));
|
---|
238 | _PROTOTYPE(void canit , (void));
|
---|
239 | void zperr();
|
---|
240 | _PROTOTYPE(char *substr , (char *s , char *t ));
|
---|
241 | _PROTOTYPE(int usage , (void));
|
---|
242 | _PROTOTYPE(int getzrxinit , (void));
|
---|
243 | _PROTOTYPE(int sendzsinit , (void));
|
---|
244 | _PROTOTYPE(int zsendfile , (char *buf , int blen ));
|
---|
245 | _PROTOTYPE(int zsendfdata , (void));
|
---|
246 | _PROTOTYPE(int getinsync , (int flag ));
|
---|
247 | _PROTOTYPE(void saybibi , (void));
|
---|
248 | _PROTOTYPE(void bttyout , (int c ));
|
---|
249 | _PROTOTYPE(int zsendcmd , (char *buf , int blen ));
|
---|
250 | _PROTOTYPE(void chkinvok , (char *s ));
|
---|
251 | _PROTOTYPE(void countem , (int argc , char **argv ));
|
---|
252 | _PROTOTYPE(void chartest , (int m ));
|
---|
253 |
|
---|
254 | /* called by signal interrupt or terminate to clean things up */
|
---|
255 | void bibi(n)
|
---|
256 | int n;
|
---|
257 | {
|
---|
258 | canit(); fflush(stdout); mode(0);
|
---|
259 | fprintf(stderr, "sz: caught signal %d; exiting\n", n);
|
---|
260 | if (n == SIGQUIT)
|
---|
261 | abort();
|
---|
262 | if (n == 99)
|
---|
263 | fprintf(stderr, "mode(2) in rbsb.c not implemented!!\n");
|
---|
264 | cucheck();
|
---|
265 | exit(128+n);
|
---|
266 | }
|
---|
267 | /* Called when ZMODEM gets an interrupt (^X) */
|
---|
268 | void onintr(sig)
|
---|
269 | int sig;
|
---|
270 | {
|
---|
271 | signal(SIGINT, SIG_IGN);
|
---|
272 | longjmp(intrjmp, -1);
|
---|
273 | }
|
---|
274 |
|
---|
275 | int Zctlesc; /* Encode control characters */
|
---|
276 | int Nozmodem = 0; /* If invoked as "sb" */
|
---|
277 | char *Progname = "sz";
|
---|
278 | int Zrwindow = 1400; /* RX window size (controls garbage count) */
|
---|
279 | #include "zm.c"
|
---|
280 |
|
---|
281 |
|
---|
282 | int main(argc, argv)
|
---|
283 | int argc;
|
---|
284 | char *argv[];
|
---|
285 | {
|
---|
286 | register char *cp;
|
---|
287 | register npats;
|
---|
288 | int dm;
|
---|
289 | char **patts;
|
---|
290 | static char xXbuf[BUFSIZ];
|
---|
291 |
|
---|
292 | if ((cp = getenv("ZNULLS")) && *cp)
|
---|
293 | Znulls = atoi(cp);
|
---|
294 | if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
|
---|
295 | Restricted=TRUE;
|
---|
296 | from_cu();
|
---|
297 | chkinvok(argv[0]);
|
---|
298 |
|
---|
299 | Rxtimeout = 600;
|
---|
300 | npats=0;
|
---|
301 | if (argc<2)
|
---|
302 | usage();
|
---|
303 | setbuf(stdout, xXbuf);
|
---|
304 | while (--argc) {
|
---|
305 | cp = *++argv;
|
---|
306 | if (*cp++ == '-' && *cp) {
|
---|
307 | while ( *cp) {
|
---|
308 | switch(*cp++) {
|
---|
309 | case '\\':
|
---|
310 | *cp = toupper(*cp); continue;
|
---|
311 | case '+':
|
---|
312 | Lzmanag = ZMAPND; break;
|
---|
313 | #ifdef CSTOPB
|
---|
314 | case '2':
|
---|
315 | Twostop = TRUE; break;
|
---|
316 | #endif
|
---|
317 | case 'a':
|
---|
318 | Lzconv = ZCNL;
|
---|
319 | Ascii = TRUE; break;
|
---|
320 | case 'b':
|
---|
321 | Lzconv = ZCBIN; break;
|
---|
322 | case 'C':
|
---|
323 | if (--argc < 1) {
|
---|
324 | usage();
|
---|
325 | }
|
---|
326 | Cmdtries = atoi(*++argv);
|
---|
327 | break;
|
---|
328 | case 'i':
|
---|
329 | Cmdack1 = ZCACK1;
|
---|
330 | /* **** FALL THROUGH TO **** */
|
---|
331 | case 'c':
|
---|
332 | if (--argc != 1) {
|
---|
333 | usage();
|
---|
334 | }
|
---|
335 | Command = TRUE;
|
---|
336 | Cmdstr = *++argv;
|
---|
337 | break;
|
---|
338 | case 'd':
|
---|
339 | ++Dottoslash;
|
---|
340 | /* **** FALL THROUGH TO **** */
|
---|
341 | case 'f':
|
---|
342 | Fullname=TRUE; break;
|
---|
343 | case 'e':
|
---|
344 | Zctlesc = 1; break;
|
---|
345 | case 'k':
|
---|
346 | blklen=1024; break;
|
---|
347 | case 'L':
|
---|
348 | if (--argc < 1) {
|
---|
349 | usage();
|
---|
350 | }
|
---|
351 | blkopt = atoi(*++argv);
|
---|
352 | if (blkopt<24 || blkopt>1024)
|
---|
353 | usage();
|
---|
354 | break;
|
---|
355 | case 'l':
|
---|
356 | if (--argc < 1) {
|
---|
357 | usage();
|
---|
358 | }
|
---|
359 | Tframlen = atoi(*++argv);
|
---|
360 | if (Tframlen<32 || Tframlen>1024)
|
---|
361 | usage();
|
---|
362 | break;
|
---|
363 | case 'N':
|
---|
364 | Lzmanag = ZMNEWL; break;
|
---|
365 | case 'n':
|
---|
366 | Lzmanag = ZMNEW; break;
|
---|
367 | case 'o':
|
---|
368 | Wantfcs32 = FALSE; break;
|
---|
369 | case 'p':
|
---|
370 | Lzmanag = ZMPROT; break;
|
---|
371 | case 'r':
|
---|
372 | Lzconv = ZCRESUM;
|
---|
373 | case 'q':
|
---|
374 | Quiet=TRUE; Verbose=0; break;
|
---|
375 | case 't':
|
---|
376 | if (--argc < 1) {
|
---|
377 | usage();
|
---|
378 | }
|
---|
379 | Rxtimeout = atoi(*++argv);
|
---|
380 | if (Rxtimeout<10 || Rxtimeout>1000)
|
---|
381 | usage();
|
---|
382 | break;
|
---|
383 | case 'T':
|
---|
384 | if (++Test > 1) {
|
---|
385 | chartest(1); chartest(2);
|
---|
386 | mode(0); exit(0);
|
---|
387 | }
|
---|
388 | break;
|
---|
389 | #ifndef vax11c
|
---|
390 | case 'u':
|
---|
391 | ++Unlinkafter; break;
|
---|
392 | #endif
|
---|
393 | case 'v':
|
---|
394 | ++Verbose; break;
|
---|
395 | case 'w':
|
---|
396 | if (--argc < 1) {
|
---|
397 | usage();
|
---|
398 | }
|
---|
399 | Txwindow = atoi(*++argv);
|
---|
400 | if (Txwindow < 256)
|
---|
401 | Txwindow = 256;
|
---|
402 | Txwindow = (Txwindow/64) * 64;
|
---|
403 | Txwspac = Txwindow/4;
|
---|
404 | if (blkopt > Txwspac
|
---|
405 | || (!blkopt && Txwspac < 1024))
|
---|
406 | blkopt = Txwspac;
|
---|
407 | break;
|
---|
408 | case 'X':
|
---|
409 | ++Modem2; break;
|
---|
410 | case 'Y':
|
---|
411 | Lskipnocor = TRUE;
|
---|
412 | /* **** FALLL THROUGH TO **** */
|
---|
413 | case 'y':
|
---|
414 | Lzmanag = ZMCLOB; break;
|
---|
415 | default:
|
---|
416 | usage();
|
---|
417 | }
|
---|
418 | }
|
---|
419 | }
|
---|
420 | else if ( !npats && argc>0) {
|
---|
421 | if (argv[0][0]) {
|
---|
422 | npats=argc;
|
---|
423 | patts=argv;
|
---|
424 | #ifndef vax11c
|
---|
425 | if ( !strcmp(*patts, "-"))
|
---|
426 | iofd = 1;
|
---|
427 | #endif
|
---|
428 | }
|
---|
429 | }
|
---|
430 | }
|
---|
431 | if (npats < 1 && !Command && !Test)
|
---|
432 | usage();
|
---|
433 | if (Verbose) {
|
---|
434 | if (freopen(LOGFILE, "a", stderr)==NULL) {
|
---|
435 | printf("Can't open log file %s\n",LOGFILE);
|
---|
436 | exit(0200);
|
---|
437 | }
|
---|
438 | setbuf(stderr, (char *)NULL);
|
---|
439 | }
|
---|
440 | if (Fromcu && !Quiet) {
|
---|
441 | if (Verbose == 0)
|
---|
442 | Verbose = 2;
|
---|
443 | }
|
---|
444 | vfile("%s %s for %s\n", Progname, VERSION, OS);
|
---|
445 |
|
---|
446 | mode(1);
|
---|
447 |
|
---|
448 | if (signal(SIGINT, bibi) == SIG_IGN) {
|
---|
449 | signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
|
---|
450 | } else {
|
---|
451 | signal(SIGINT, bibi); signal(SIGKILL, bibi);
|
---|
452 | }
|
---|
453 | if ( !Fromcu)
|
---|
454 | signal(SIGQUIT, SIG_IGN);
|
---|
455 | signal(SIGTERM, bibi);
|
---|
456 |
|
---|
457 | if ( !Modem2) {
|
---|
458 | if (!Nozmodem) {
|
---|
459 | printf("rz\r"); fflush(stdout);
|
---|
460 | }
|
---|
461 | countem(npats, patts);
|
---|
462 | if (!Nozmodem) {
|
---|
463 | stohdr(0L);
|
---|
464 | if (Command)
|
---|
465 | Txhdr[ZF0] = ZCOMMAND;
|
---|
466 | zshhdr(ZRQINIT, Txhdr);
|
---|
467 | }
|
---|
468 | }
|
---|
469 | fflush(stdout);
|
---|
470 |
|
---|
471 | if (Command) {
|
---|
472 | if (getzrxinit()) {
|
---|
473 | Exitcode=0200; canit();
|
---|
474 | }
|
---|
475 | else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
|
---|
476 | Exitcode=0200; canit();
|
---|
477 | }
|
---|
478 | } else if (wcsend(npats, patts)==ERROR) {
|
---|
479 | Exitcode=0200;
|
---|
480 | canit();
|
---|
481 | }
|
---|
482 | fflush(stdout);
|
---|
483 | mode(0);
|
---|
484 | dm = ((errcnt != 0) | Exitcode);
|
---|
485 | if (dm) {
|
---|
486 | cucheck(); exit(dm);
|
---|
487 | }
|
---|
488 | putc('\n',stderr);
|
---|
489 | exit(SS_NORMAL);
|
---|
490 | /*NOTREACHED*/
|
---|
491 | }
|
---|
492 |
|
---|
493 | int wcsend(argc, argp)
|
---|
494 | int argc;
|
---|
495 | char *argp[];
|
---|
496 | {
|
---|
497 | register int n;
|
---|
498 |
|
---|
499 | Crcflg=FALSE;
|
---|
500 | firstsec=TRUE;
|
---|
501 | bytcnt = -1;
|
---|
502 | for (n=0; n<argc; ++n) {
|
---|
503 | Totsecs = 0;
|
---|
504 | if (wcs(argp[n])==ERROR)
|
---|
505 | return ERROR;
|
---|
506 | }
|
---|
507 | Totsecs = 0;
|
---|
508 | if (Filcnt==0) { /* bitch if we couldn't open ANY files */
|
---|
509 | if ( !Modem2) {
|
---|
510 | Command = TRUE;
|
---|
511 | Cmdstr = "echo \"sz: Can't open any requested files\"";
|
---|
512 | if (getnak()) {
|
---|
513 | Exitcode=0200; canit();
|
---|
514 | }
|
---|
515 | if (!Zmodem)
|
---|
516 | canit();
|
---|
517 | else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
|
---|
518 | Exitcode=0200; canit();
|
---|
519 | }
|
---|
520 | Exitcode = 1; return OK;
|
---|
521 | }
|
---|
522 | canit();
|
---|
523 | fprintf(stderr,"\r\nCan't open any requested files.\r\n");
|
---|
524 | return ERROR;
|
---|
525 | }
|
---|
526 | if (Zmodem)
|
---|
527 | saybibi();
|
---|
528 | else if ( !Modem2)
|
---|
529 | wctxpn("");
|
---|
530 | return OK;
|
---|
531 | }
|
---|
532 |
|
---|
533 | int wcs(oname)
|
---|
534 | char *oname;
|
---|
535 | {
|
---|
536 | register c;
|
---|
537 | register char *p;
|
---|
538 | struct stat f;
|
---|
539 | char name[PATHLEN];
|
---|
540 |
|
---|
541 | strcpy(name, oname);
|
---|
542 |
|
---|
543 | if (Restricted) {
|
---|
544 | /* restrict pathnames to current tree or uucppublic */
|
---|
545 | if ( substr(name, "../")
|
---|
546 | || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
|
---|
547 | canit();
|
---|
548 | fprintf(stderr,"\r\nsz:\tSecurity Violation\r\n");
|
---|
549 | return ERROR;
|
---|
550 | }
|
---|
551 | }
|
---|
552 |
|
---|
553 | if ( !strcmp(oname, "-")) {
|
---|
554 | if ((p = getenv("ONAME")) && *p)
|
---|
555 | strcpy(name, p);
|
---|
556 | else
|
---|
557 | sprintf(name, "s%d.sz", getpid());
|
---|
558 | in = stdin;
|
---|
559 | }
|
---|
560 | else if ((in=fopen(oname, "r"))==NULL) {
|
---|
561 | ++errcnt;
|
---|
562 | return OK; /* pass over it, there may be others */
|
---|
563 | }
|
---|
564 | BEofseen = Eofseen = 0; vpos = 0;
|
---|
565 | /* Check for directory or block special files */
|
---|
566 | fstat(fileno(in), &f);
|
---|
567 | c = f.st_mode & S_IFMT;
|
---|
568 | if (c == S_IFDIR || c == S_IFBLK) {
|
---|
569 | fclose(in);
|
---|
570 | return OK;
|
---|
571 | }
|
---|
572 |
|
---|
573 | ++Filcnt;
|
---|
574 | switch (wctxpn(name)) {
|
---|
575 | case ERROR:
|
---|
576 | return ERROR;
|
---|
577 | case ZSKIP:
|
---|
578 | return OK;
|
---|
579 | }
|
---|
580 | if (!Zmodem && wctx(f.st_size)==ERROR)
|
---|
581 | return ERROR;
|
---|
582 | #ifndef vax11c
|
---|
583 | if (Unlinkafter)
|
---|
584 | unlink(oname);
|
---|
585 | #endif
|
---|
586 | return 0;
|
---|
587 | }
|
---|
588 |
|
---|
589 | /*
|
---|
590 | * generate and transmit pathname block consisting of
|
---|
591 | * pathname (null terminated),
|
---|
592 | * file length, mode time and file mode in octal
|
---|
593 | * as provided by the Unix fstat call.
|
---|
594 | * N.B.: modifies the passed name, may extend it!
|
---|
595 | */
|
---|
596 | int wctxpn(name)
|
---|
597 | char *name;
|
---|
598 | {
|
---|
599 | register char *p, *q;
|
---|
600 | char name2[PATHLEN];
|
---|
601 | struct stat f;
|
---|
602 |
|
---|
603 | if (Modem2) {
|
---|
604 | if ((in!=stdin) && *name && fstat(fileno(in), &f)!= -1) {
|
---|
605 | fprintf(stderr, "Sending %s, %ld blocks: ",
|
---|
606 | name, f.st_size>>7);
|
---|
607 | }
|
---|
608 | fprintf(stderr, "Give your local XMODEM receive command now.\r\n");
|
---|
609 | return OK;
|
---|
610 | }
|
---|
611 | zperr("Awaiting pathname nak for %s", *name?name:"<END>");
|
---|
612 | if ( !Zmodem)
|
---|
613 | if (getnak())
|
---|
614 | return ERROR;
|
---|
615 |
|
---|
616 | q = (char *) 0;
|
---|
617 | if (Dottoslash) { /* change . to . */
|
---|
618 | for (p=name; *p; ++p) {
|
---|
619 | if (*p == '/')
|
---|
620 | q = p;
|
---|
621 | else if (*p == '.')
|
---|
622 | *(q=p) = '/';
|
---|
623 | }
|
---|
624 | if (q && strlen(++q) > 8) { /* If name>8 chars */
|
---|
625 | q += 8; /* make it .ext */
|
---|
626 | strcpy(name2, q); /* save excess of name */
|
---|
627 | *q = '.';
|
---|
628 | strcpy(++q, name2); /* add it back */
|
---|
629 | }
|
---|
630 | }
|
---|
631 |
|
---|
632 | for (p=name, q=txbuf ; *p; )
|
---|
633 | if ((*q++ = *p++) == '/' && !Fullname)
|
---|
634 | q = txbuf;
|
---|
635 | *q++ = 0;
|
---|
636 | p=q;
|
---|
637 | while (q < (txbuf + 1024))
|
---|
638 | *q++ = 0;
|
---|
639 | if (!Ascii && (in!=stdin) && *name && fstat(fileno(in), &f)!= -1)
|
---|
640 | sprintf(p, "%lu %lo %o 0 %d %ld", f.st_size, f.st_mtime,
|
---|
641 | f.st_mode, Filesleft, Totalleft);
|
---|
642 | Totalleft -= f.st_size;
|
---|
643 | if (--Filesleft <= 0)
|
---|
644 | Totalleft = 0;
|
---|
645 | if (Totalleft < 0)
|
---|
646 | Totalleft = 0;
|
---|
647 |
|
---|
648 | /* force 1k blocks if name won't fit in 128 byte block */
|
---|
649 | if (txbuf[125])
|
---|
650 | blklen=1024;
|
---|
651 | else { /* A little goodie for IMP/KMD */
|
---|
652 | txbuf[127] = (f.st_size + 127) >>7;
|
---|
653 | txbuf[126] = (f.st_size + 127) >>15;
|
---|
654 | }
|
---|
655 | if (Zmodem)
|
---|
656 | return zsendfile(txbuf, 1+strlen(p)+(p-txbuf));
|
---|
657 | if (wcputsec(txbuf, 0, 128)==ERROR)
|
---|
658 | return ERROR;
|
---|
659 | return OK;
|
---|
660 | }
|
---|
661 |
|
---|
662 | int getnak()
|
---|
663 | {
|
---|
664 | register firstch;
|
---|
665 |
|
---|
666 | Lastrx = 0;
|
---|
667 | for (;;) {
|
---|
668 | switch (firstch = readline(800)) {
|
---|
669 | case ZPAD:
|
---|
670 | if (getzrxinit())
|
---|
671 | return ERROR;
|
---|
672 | Ascii = 0; /* Receiver does the conversion */
|
---|
673 | return FALSE;
|
---|
674 | case TIMEOUT:
|
---|
675 | zperr("Timeout on pathname");
|
---|
676 | return TRUE;
|
---|
677 | case WANTG:
|
---|
678 | #ifdef MODE2OK
|
---|
679 | mode(2); /* Set cbreak, XON/XOFF, etc. */
|
---|
680 | #endif
|
---|
681 | Optiong = TRUE;
|
---|
682 | blklen=1024;
|
---|
683 | case WANTCRC:
|
---|
684 | Crcflg = TRUE;
|
---|
685 | case NAK:
|
---|
686 | return FALSE;
|
---|
687 | case CAN:
|
---|
688 | if ((firstch = readline(20)) == CAN && Lastrx == CAN)
|
---|
689 | return TRUE;
|
---|
690 | default:
|
---|
691 | break;
|
---|
692 | }
|
---|
693 | Lastrx = firstch;
|
---|
694 | }
|
---|
695 | }
|
---|
696 |
|
---|
697 |
|
---|
698 | int wctx(flen)
|
---|
699 | long flen;
|
---|
700 | {
|
---|
701 | register int thisblklen;
|
---|
702 | register int sectnum, attempts, firstch;
|
---|
703 | long charssent;
|
---|
704 |
|
---|
705 | charssent = 0; firstsec=TRUE; thisblklen = blklen;
|
---|
706 | vfile("wctx:file length=%ld", flen);
|
---|
707 |
|
---|
708 | while ((firstch=readline(Rxtimeout))!=NAK && firstch != WANTCRC
|
---|
709 | && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN)
|
---|
710 | ;
|
---|
711 | if (firstch==CAN) {
|
---|
712 | zperr("Receiver CANcelled");
|
---|
713 | return ERROR;
|
---|
714 | }
|
---|
715 | if (firstch==WANTCRC)
|
---|
716 | Crcflg=TRUE;
|
---|
717 | if (firstch==WANTG)
|
---|
718 | Crcflg=TRUE;
|
---|
719 | sectnum=0;
|
---|
720 | for (;;) {
|
---|
721 | if (flen <= (charssent + 896L))
|
---|
722 | thisblklen = 128;
|
---|
723 | if ( !filbuf(txbuf, thisblklen))
|
---|
724 | break;
|
---|
725 | if (wcputsec(txbuf, ++sectnum, thisblklen)==ERROR)
|
---|
726 | return ERROR;
|
---|
727 | charssent += thisblklen;
|
---|
728 | }
|
---|
729 | fclose(in);
|
---|
730 | attempts=0;
|
---|
731 | do {
|
---|
732 | purgeline();
|
---|
733 | sendline(EOT);
|
---|
734 | fflush(stdout);
|
---|
735 | ++attempts;
|
---|
736 | }
|
---|
737 | while ((firstch=(readline(Rxtimeout)) != ACK) && attempts < RETRYMAX);
|
---|
738 | if (attempts == RETRYMAX) {
|
---|
739 | zperr("No ACK on EOT");
|
---|
740 | return ERROR;
|
---|
741 | }
|
---|
742 | else
|
---|
743 | return OK;
|
---|
744 | }
|
---|
745 |
|
---|
746 | int wcputsec(buf, sectnum, cseclen)
|
---|
747 | char *buf;
|
---|
748 | int sectnum;
|
---|
749 | int cseclen; /* data length of this sector to send */
|
---|
750 | {
|
---|
751 | register checksum, wcj;
|
---|
752 | register char *cp;
|
---|
753 | unsigned oldcrc;
|
---|
754 | int firstch;
|
---|
755 | int attempts;
|
---|
756 |
|
---|
757 | firstch=0; /* part of logic to detect CAN CAN */
|
---|
758 |
|
---|
759 | if (Verbose>2)
|
---|
760 | fprintf(stderr, "Sector %3d %2dk\n", Totsecs, Totsecs/8 );
|
---|
761 | else if (Verbose>1)
|
---|
762 | fprintf(stderr, "\rSector %3d %2dk ", Totsecs, Totsecs/8 );
|
---|
763 | for (attempts=0; attempts <= RETRYMAX; attempts++) {
|
---|
764 | Lastrx= firstch;
|
---|
765 | sendline(cseclen==1024?STX:SOH);
|
---|
766 | sendline(sectnum);
|
---|
767 | sendline(-sectnum -1);
|
---|
768 | oldcrc=checksum=0;
|
---|
769 | for (wcj=cseclen,cp=buf; --wcj>=0; ) {
|
---|
770 | sendline(*cp);
|
---|
771 | oldcrc=updcrc((0377& *cp), oldcrc);
|
---|
772 | checksum += *cp++;
|
---|
773 | }
|
---|
774 | if (Crcflg) {
|
---|
775 | oldcrc=updcrc(0,updcrc(0,oldcrc));
|
---|
776 | sendline((int)oldcrc>>8);
|
---|
777 | sendline((int)oldcrc);
|
---|
778 | }
|
---|
779 | else
|
---|
780 | sendline(checksum);
|
---|
781 |
|
---|
782 | if (Optiong) {
|
---|
783 | firstsec = FALSE; return OK;
|
---|
784 | }
|
---|
785 | firstch = readline(Rxtimeout);
|
---|
786 | gotnak:
|
---|
787 | switch (firstch) {
|
---|
788 | case CAN:
|
---|
789 | if(Lastrx == CAN) {
|
---|
790 | cancan:
|
---|
791 | zperr("Cancelled"); return ERROR;
|
---|
792 | }
|
---|
793 | break;
|
---|
794 | case TIMEOUT:
|
---|
795 | zperr("Timeout on sector ACK"); continue;
|
---|
796 | case WANTCRC:
|
---|
797 | if (firstsec)
|
---|
798 | Crcflg = TRUE;
|
---|
799 | case NAK:
|
---|
800 | zperr("NAK on sector"); continue;
|
---|
801 | case ACK:
|
---|
802 | firstsec=FALSE;
|
---|
803 | Totsecs += (cseclen>>7);
|
---|
804 | return OK;
|
---|
805 | case ERROR:
|
---|
806 | zperr("Got burst for sector ACK"); break;
|
---|
807 | default:
|
---|
808 | zperr("Got %02x for sector ACK", firstch); break;
|
---|
809 | }
|
---|
810 | for (;;) {
|
---|
811 | Lastrx = firstch;
|
---|
812 | if ((firstch = readline(Rxtimeout)) == TIMEOUT)
|
---|
813 | break;
|
---|
814 | if (firstch == NAK || firstch == WANTCRC)
|
---|
815 | goto gotnak;
|
---|
816 | if (firstch == CAN && Lastrx == CAN)
|
---|
817 | goto cancan;
|
---|
818 | }
|
---|
819 | }
|
---|
820 | zperr("Retry Count Exceeded");
|
---|
821 | return ERROR;
|
---|
822 | }
|
---|
823 |
|
---|
824 | /* fill buf with count chars padding with ^Z for CPM */
|
---|
825 | int filbuf(buf, count)
|
---|
826 | register char *buf;
|
---|
827 | int count;
|
---|
828 | {
|
---|
829 | register c, m;
|
---|
830 |
|
---|
831 | if ( !Ascii) {
|
---|
832 | m = read(fileno(in), buf, count);
|
---|
833 | if (m <= 0)
|
---|
834 | return 0;
|
---|
835 | while (m < count)
|
---|
836 | buf[m++] = 032;
|
---|
837 | return count;
|
---|
838 | }
|
---|
839 | m=count;
|
---|
840 | if (Lfseen) {
|
---|
841 | *buf++ = 012; --m; Lfseen = 0;
|
---|
842 | }
|
---|
843 | while ((c=getc(in))!=EOF) {
|
---|
844 | if (c == 012) {
|
---|
845 | *buf++ = 015;
|
---|
846 | if (--m == 0) {
|
---|
847 | Lfseen = TRUE; break;
|
---|
848 | }
|
---|
849 | }
|
---|
850 | *buf++ =c;
|
---|
851 | if (--m == 0)
|
---|
852 | break;
|
---|
853 | }
|
---|
854 | if (m==count)
|
---|
855 | return 0;
|
---|
856 | else
|
---|
857 | while (--m>=0)
|
---|
858 | *buf++ = CPMEOF;
|
---|
859 | return count;
|
---|
860 | }
|
---|
861 |
|
---|
862 | /* Fill buffer with blklen chars */
|
---|
863 | int zfilbuf()
|
---|
864 | {
|
---|
865 | int n;
|
---|
866 |
|
---|
867 | #ifdef TXBSIZE
|
---|
868 | /* We assume request is within buffer, or just beyond */
|
---|
869 | txbuf = Txb + (bytcnt & TXBMASK);
|
---|
870 | if (vpos <= bytcnt) {
|
---|
871 | n = fread(txbuf, 1, blklen, in);
|
---|
872 | vpos += n;
|
---|
873 | if (n < blklen)
|
---|
874 | Eofseen = 1;
|
---|
875 | return n;
|
---|
876 | }
|
---|
877 | if (vpos >= (bytcnt+blklen))
|
---|
878 | return blklen;
|
---|
879 | /* May be a short block if crash recovery etc. */
|
---|
880 | Eofseen = BEofseen;
|
---|
881 | return (vpos - bytcnt);
|
---|
882 | #else
|
---|
883 | n = fread(txbuf, 1, blklen, in);
|
---|
884 | if (n < blklen)
|
---|
885 | Eofseen = 1;
|
---|
886 | return n;
|
---|
887 | #endif
|
---|
888 | }
|
---|
889 |
|
---|
890 | #ifdef TXBSIZE
|
---|
891 | int fooseek(fptr, pos, whence)
|
---|
892 | FILE *fptr;
|
---|
893 | long pos;
|
---|
894 | {
|
---|
895 | int m, n;
|
---|
896 |
|
---|
897 | vfile("fooseek: pos =%lu vpos=%lu Canseek=%d", pos, vpos, Canseek);
|
---|
898 | /* Seek offset < current buffer */
|
---|
899 | if (pos < (vpos -TXBSIZE +1024)) {
|
---|
900 | BEofseen = 0;
|
---|
901 | if (Canseek > 0) {
|
---|
902 | vpos = pos & ~TXBMASK;
|
---|
903 | if (vpos >= pos)
|
---|
904 | vpos -= TXBSIZE;
|
---|
905 | if (fseek(fptr, vpos, 0))
|
---|
906 | return 1;
|
---|
907 | }
|
---|
908 | else if (Canseek == 0)
|
---|
909 | if (fseek(fptr, vpos = 0L, 0))
|
---|
910 | return 1;
|
---|
911 | else
|
---|
912 | return 1;
|
---|
913 | while (vpos <= pos) {
|
---|
914 | n = fread(Txb, 1, TXBSIZE, fptr);
|
---|
915 | vpos += n;
|
---|
916 | vfile("n=%d vpos=%ld", n, vpos);
|
---|
917 | if (n < TXBSIZE) {
|
---|
918 | BEofseen = 1;
|
---|
919 | break;
|
---|
920 | }
|
---|
921 | }
|
---|
922 | vfile("vpos=%ld", vpos);
|
---|
923 | return 0;
|
---|
924 | }
|
---|
925 | /* Seek offset > current buffer (crash recovery, etc.) */
|
---|
926 | if (pos > vpos) {
|
---|
927 | if (Canseek)
|
---|
928 | if (fseek(fptr, vpos = (pos & ~TXBMASK), 0))
|
---|
929 | return 1;
|
---|
930 | while (vpos <= pos) {
|
---|
931 | txbuf = Txb + (vpos & TXBMASK);
|
---|
932 | m = TXBSIZE - (vpos & TXBMASK);
|
---|
933 | n = fread(txbuf, 1, m, fptr);
|
---|
934 | vpos += n;
|
---|
935 | vfile("bo=%d n=%d vpos=%ld", txbuf-Txb, n, vpos);
|
---|
936 | if (m < n) {
|
---|
937 | BEofseen = 1;
|
---|
938 | break;
|
---|
939 | }
|
---|
940 | }
|
---|
941 | return 0;
|
---|
942 | }
|
---|
943 | /* Seek offset is within current buffer */
|
---|
944 | vfile("vpos=%ld", vpos);
|
---|
945 | return 0;
|
---|
946 | }
|
---|
947 | #define fseek fooseek
|
---|
948 | #endif
|
---|
949 |
|
---|
950 |
|
---|
951 | /* VARARGS1 */
|
---|
952 | void vfile(f, a, b, c)
|
---|
953 | register char *f,*a,*b,*c;
|
---|
954 | {
|
---|
955 | if (Verbose > 2) {
|
---|
956 | fprintf(stderr, f, a, b, c);
|
---|
957 | fprintf(stderr, "\n");
|
---|
958 | }
|
---|
959 | }
|
---|
960 |
|
---|
961 |
|
---|
962 | void alrm(sig)
|
---|
963 | int sig;
|
---|
964 | {
|
---|
965 | longjmp(tohere, -1);
|
---|
966 | }
|
---|
967 |
|
---|
968 |
|
---|
969 | #ifndef vax11c
|
---|
970 | /*
|
---|
971 | * readline(timeout) reads character(s) from file descriptor 0
|
---|
972 | * timeout is in tenths of seconds
|
---|
973 | */
|
---|
974 | int readline(timeout)
|
---|
975 | int timeout;
|
---|
976 | {
|
---|
977 | register int c;
|
---|
978 | static char byt[1];
|
---|
979 |
|
---|
980 | fflush(stdout);
|
---|
981 | if (setjmp(tohere)) {
|
---|
982 | zperr("TIMEOUT");
|
---|
983 | return TIMEOUT;
|
---|
984 | }
|
---|
985 | c = timeout/10;
|
---|
986 | if (c<2)
|
---|
987 | c=2;
|
---|
988 | if (Verbose>5) {
|
---|
989 | fprintf(stderr, "Timeout=%d Calling alarm(%d) ", timeout, c);
|
---|
990 | }
|
---|
991 | signal(SIGALRM, alrm); alarm(c);
|
---|
992 | c=read(iofd, byt, 1);
|
---|
993 | alarm(0);
|
---|
994 | if (Verbose>5)
|
---|
995 | fprintf(stderr, "ret %x\n", byt[0]);
|
---|
996 | if (c<1)
|
---|
997 | return TIMEOUT;
|
---|
998 | return (byt[0]&0377);
|
---|
999 | }
|
---|
1000 |
|
---|
1001 | void flushmo()
|
---|
1002 | {
|
---|
1003 | fflush(stdout);
|
---|
1004 | }
|
---|
1005 |
|
---|
1006 |
|
---|
1007 | void purgeline()
|
---|
1008 | {
|
---|
1009 | #ifdef USG
|
---|
1010 | ioctl(iofd, TCFLSH, 0);
|
---|
1011 | #else
|
---|
1012 | lseek(iofd, 0L, 2);
|
---|
1013 | #endif
|
---|
1014 | }
|
---|
1015 | #endif
|
---|
1016 |
|
---|
1017 | /* send cancel string to get the other end to shut up */
|
---|
1018 | void canit()
|
---|
1019 | {
|
---|
1020 | static char canistr[] = {
|
---|
1021 | 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
|
---|
1022 | };
|
---|
1023 |
|
---|
1024 | #ifdef vax11c
|
---|
1025 | raw_wbuf(strlen(canistr), canistr);
|
---|
1026 | purgeline();
|
---|
1027 | #else
|
---|
1028 | printf(canistr);
|
---|
1029 | fflush(stdout);
|
---|
1030 | #endif
|
---|
1031 | }
|
---|
1032 |
|
---|
1033 |
|
---|
1034 | /*
|
---|
1035 | * Log an error
|
---|
1036 | */
|
---|
1037 | /*VARARGS1*/
|
---|
1038 | void zperr(s,p,u)
|
---|
1039 | char *s, *p, *u;
|
---|
1040 | {
|
---|
1041 | if (Verbose <= 0)
|
---|
1042 | return;
|
---|
1043 | fprintf(stderr, "\nRetry %d: ", errors);
|
---|
1044 | fprintf(stderr, s, p, u);
|
---|
1045 | fprintf(stderr, "\n");
|
---|
1046 | }
|
---|
1047 |
|
---|
1048 | /*
|
---|
1049 | * substr(string, token) searches for token in string s
|
---|
1050 | * returns pointer to token within string if found, NULL otherwise
|
---|
1051 | */
|
---|
1052 | char *
|
---|
1053 | substr(s, t)
|
---|
1054 | register char *s,*t;
|
---|
1055 | {
|
---|
1056 | register char *ss,*tt;
|
---|
1057 | /* search for first char of token */
|
---|
1058 | for (ss=s; *s; s++)
|
---|
1059 | if (*s == *t)
|
---|
1060 | /* compare token with substring */
|
---|
1061 | for (ss=s,tt=t; ;) {
|
---|
1062 | if (*tt == 0)
|
---|
1063 | return s;
|
---|
1064 | if (*ss++ != *tt++)
|
---|
1065 | break;
|
---|
1066 | }
|
---|
1067 | return (char *)NULL;
|
---|
1068 | }
|
---|
1069 |
|
---|
1070 | char *babble[] = {
|
---|
1071 | #ifdef vax11c
|
---|
1072 | " Send file(s) with ZMODEM Protocol",
|
---|
1073 | "Usage: sz [-2+abdefkLlNnquvwYy] [-] file ...",
|
---|
1074 | " sz [-2Ceqv] -c COMMAND",
|
---|
1075 | " \\ Force next option letter to upper case",
|
---|
1076 | #else
|
---|
1077 | "Send file(s) with ZMODEM/YMODEM/XMODEM Protocol",
|
---|
1078 | " (Y) = Option applies to YMODEM only",
|
---|
1079 | " (Z) = Option applies to ZMODEM only",
|
---|
1080 | "Usage: sz [-2+abdefkLlNnquvwYy] [-] file ...",
|
---|
1081 | " sz [-2Ceqv] -c COMMAND",
|
---|
1082 | " sb [-2adfkquv] [-] file ...",
|
---|
1083 | " sx [-2akquv] [-] file",
|
---|
1084 | #endif
|
---|
1085 | #ifdef CSTOPB
|
---|
1086 | " 2 Use 2 stop bits",
|
---|
1087 | #endif
|
---|
1088 | " + Append to existing destination file (Z)",
|
---|
1089 | " a (ASCII) change NL to CR/LF",
|
---|
1090 | " b Binary file transfer override",
|
---|
1091 | " c send COMMAND (Z)",
|
---|
1092 | #ifndef vax11c
|
---|
1093 | " d Change '.' to '/' in pathnames (Y/Z)",
|
---|
1094 | #endif
|
---|
1095 | " e Escape all control characters (Z)",
|
---|
1096 | " f send Full pathname (Y/Z)",
|
---|
1097 | " i send COMMAND, ack Immediately (Z)",
|
---|
1098 | " k Send 1024 byte packets (Y)",
|
---|
1099 | " L N Limit subpacket length to N bytes (Z)",
|
---|
1100 | " l N Limit frame length to N bytes (l>=L) (Z)",
|
---|
1101 | " n send file if source newer (Z)",
|
---|
1102 | " N send file if source newer or longer (Z)",
|
---|
1103 | " o Use 16 bit CRC instead of 32 bit CRC (Z)",
|
---|
1104 | " p Protect existing destination file (Z)",
|
---|
1105 | " r Resume/Recover interrupted file transfer (Z)",
|
---|
1106 | " q Quiet (no progress reports)",
|
---|
1107 | #ifndef vax11c
|
---|
1108 | " u Unlink file after transmission",
|
---|
1109 | #endif
|
---|
1110 | " v Verbose - provide debugging information",
|
---|
1111 | " w N Window is N bytes (Z)",
|
---|
1112 | " Y Yes, overwrite existing file, skip if not present at rx (Z)",
|
---|
1113 | " y Yes, overwrite existing file (Z)",
|
---|
1114 | "- as pathname sends standard input as sPID.sz or environment ONAME",
|
---|
1115 | ""
|
---|
1116 | };
|
---|
1117 |
|
---|
1118 | int usage()
|
---|
1119 | {
|
---|
1120 | char **pp;
|
---|
1121 |
|
---|
1122 | for (pp=babble; **pp; ++pp)
|
---|
1123 | fprintf(stderr, "%s\n", *pp);
|
---|
1124 | fprintf(stderr, "%s for %s by Chuck Forsberg, Omen Technology INC\n",
|
---|
1125 | VERSION, OS);
|
---|
1126 | fprintf(stderr, "\t\t\042The High Reliability Software\042\n");
|
---|
1127 | cucheck();
|
---|
1128 | exit(SS_NORMAL);
|
---|
1129 | }
|
---|
1130 |
|
---|
1131 | /*
|
---|
1132 | * Get the receiver's init parameters
|
---|
1133 | */
|
---|
1134 | int getzrxinit()
|
---|
1135 | {
|
---|
1136 | register n;
|
---|
1137 | struct stat f;
|
---|
1138 |
|
---|
1139 | for (n=10; --n>=0; ) {
|
---|
1140 |
|
---|
1141 | switch (zgethdr(Rxhdr, 1)) {
|
---|
1142 | case ZCHALLENGE: /* Echo receiver's challenge numbr */
|
---|
1143 | stohdr(Rxpos);
|
---|
1144 | zshhdr(ZACK, Txhdr);
|
---|
1145 | continue;
|
---|
1146 | case ZCOMMAND: /* They didn't see out ZRQINIT */
|
---|
1147 | stohdr(0L);
|
---|
1148 | zshhdr(ZRQINIT, Txhdr);
|
---|
1149 | continue;
|
---|
1150 | case ZRINIT:
|
---|
1151 | Rxflags = 0377 & Rxhdr[ZF0];
|
---|
1152 | Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
|
---|
1153 | Zctlesc |= Rxflags & TESCCTL;
|
---|
1154 | Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
|
---|
1155 | if ( !(Rxflags & CANFDX))
|
---|
1156 | Txwindow = 0;
|
---|
1157 | vfile("Rxbuflen=%d Tframlen=%d", Rxbuflen, Tframlen);
|
---|
1158 | if ( !Fromcu)
|
---|
1159 | signal(SIGINT, SIG_IGN);
|
---|
1160 | #ifdef MODE2OK
|
---|
1161 | mode(2); /* Set cbreak, XON/XOFF, etc. */
|
---|
1162 | #endif
|
---|
1163 | #ifndef READCHECK
|
---|
1164 | #ifndef USG
|
---|
1165 | /* Use 1024 byte frames if no sample/interrupt */
|
---|
1166 | if (Rxbuflen < 32 || Rxbuflen > 1024) {
|
---|
1167 | Rxbuflen = 1024;
|
---|
1168 | vfile("Rxbuflen=%d", Rxbuflen);
|
---|
1169 | }
|
---|
1170 | #endif
|
---|
1171 | #endif
|
---|
1172 | /* Override to force shorter frame length */
|
---|
1173 | if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
|
---|
1174 | Rxbuflen = Tframlen;
|
---|
1175 | if ( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))
|
---|
1176 | Rxbuflen = Tframlen;
|
---|
1177 | vfile("Rxbuflen=%d", Rxbuflen);
|
---|
1178 |
|
---|
1179 | #ifndef vax11c
|
---|
1180 | /* If using a pipe for testing set lower buf len */
|
---|
1181 | fstat(iofd, &f);
|
---|
1182 | if ((f.st_mode & S_IFMT) != S_IFCHR) {
|
---|
1183 | Rxbuflen = 1024;
|
---|
1184 | }
|
---|
1185 | #endif
|
---|
1186 | #ifdef BADSEEK
|
---|
1187 | Canseek = 0;
|
---|
1188 | Txwindow = TXBSIZE - 1024;
|
---|
1189 | Txwspac = TXBSIZE/4;
|
---|
1190 | #endif
|
---|
1191 | /*
|
---|
1192 | * If input is not a regular file, force ACK's to
|
---|
1193 | * prevent running beyond the buffer limits
|
---|
1194 | */
|
---|
1195 | if ( !Command) {
|
---|
1196 | fstat(fileno(in), &f);
|
---|
1197 | if ((f.st_mode & S_IFMT) != S_IFREG) {
|
---|
1198 | Canseek = -1;
|
---|
1199 | #ifdef TXBSIZE
|
---|
1200 | Txwindow = TXBSIZE - 1024;
|
---|
1201 | Txwspac = TXBSIZE/4;
|
---|
1202 | #else
|
---|
1203 | return ERROR;
|
---|
1204 | #endif
|
---|
1205 | }
|
---|
1206 | }
|
---|
1207 | /* Set initial subpacket length */
|
---|
1208 | if (blklen < 1024) { /* Command line override? */
|
---|
1209 | if (Baudrate > 300)
|
---|
1210 | blklen = 256;
|
---|
1211 | if (Baudrate > 1200)
|
---|
1212 | blklen = 512;
|
---|
1213 | if (Baudrate > 2400)
|
---|
1214 | blklen = 1024;
|
---|
1215 | }
|
---|
1216 | if (Rxbuflen && blklen>Rxbuflen)
|
---|
1217 | blklen = Rxbuflen;
|
---|
1218 | if (blkopt && blklen > blkopt)
|
---|
1219 | blklen = blkopt;
|
---|
1220 | vfile("Rxbuflen=%d blklen=%d", Rxbuflen, blklen);
|
---|
1221 | vfile("Txwindow = %u Txwspac = %d", Txwindow, Txwspac);
|
---|
1222 |
|
---|
1223 | return (sendzsinit());
|
---|
1224 | case ZCAN:
|
---|
1225 | case TIMEOUT:
|
---|
1226 | return ERROR;
|
---|
1227 | case ZRQINIT:
|
---|
1228 | if (Rxhdr[ZF0] == ZCOMMAND)
|
---|
1229 | continue;
|
---|
1230 | default:
|
---|
1231 | zshhdr(ZNAK, Txhdr);
|
---|
1232 | continue;
|
---|
1233 | }
|
---|
1234 | }
|
---|
1235 | return ERROR;
|
---|
1236 | }
|
---|
1237 |
|
---|
1238 | /* Send send-init information */
|
---|
1239 | int sendzsinit()
|
---|
1240 | {
|
---|
1241 | register c;
|
---|
1242 |
|
---|
1243 | if (Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
|
---|
1244 | return OK;
|
---|
1245 | errors = 0;
|
---|
1246 | for (;;) {
|
---|
1247 | stohdr(0L);
|
---|
1248 | if (Zctlesc) {
|
---|
1249 | Txhdr[ZF0] |= TESCCTL; zshhdr(ZSINIT, Txhdr);
|
---|
1250 | }
|
---|
1251 | else
|
---|
1252 | zsbhdr(ZSINIT, Txhdr);
|
---|
1253 | zsdata(Myattn, 1+strlen(Myattn), ZCRCW);
|
---|
1254 | c = zgethdr(Rxhdr, 1);
|
---|
1255 | switch (c) {
|
---|
1256 | case ZCAN:
|
---|
1257 | return ERROR;
|
---|
1258 | case ZACK:
|
---|
1259 | return OK;
|
---|
1260 | default:
|
---|
1261 | if (++errors > 19)
|
---|
1262 | return ERROR;
|
---|
1263 | continue;
|
---|
1264 | }
|
---|
1265 | }
|
---|
1266 | }
|
---|
1267 |
|
---|
1268 | /* Send file name and related info */
|
---|
1269 | int zsendfile(buf, blen)
|
---|
1270 | char *buf;
|
---|
1271 | int blen;
|
---|
1272 | {
|
---|
1273 | register c;
|
---|
1274 | register UNSL long crc;
|
---|
1275 |
|
---|
1276 | for (;;) {
|
---|
1277 | Txhdr[ZF0] = Lzconv; /* file conversion request */
|
---|
1278 | Txhdr[ZF1] = Lzmanag; /* file management request */
|
---|
1279 | if (Lskipnocor)
|
---|
1280 | Txhdr[ZF1] |= ZMSKNOLOC;
|
---|
1281 | Txhdr[ZF2] = Lztrans; /* file transport request */
|
---|
1282 | Txhdr[ZF3] = 0;
|
---|
1283 | zsbhdr(ZFILE, Txhdr);
|
---|
1284 | zsdata(buf, blen, ZCRCW);
|
---|
1285 | again:
|
---|
1286 | c = zgethdr(Rxhdr, 1);
|
---|
1287 | switch (c) {
|
---|
1288 | case ZRINIT:
|
---|
1289 | while ((c = readline(50)) > 0)
|
---|
1290 | if (c == ZPAD) {
|
---|
1291 | goto again;
|
---|
1292 | }
|
---|
1293 | /* **** FALL THRU TO **** */
|
---|
1294 | default:
|
---|
1295 | continue;
|
---|
1296 | case ZCAN:
|
---|
1297 | case TIMEOUT:
|
---|
1298 | case ZABORT:
|
---|
1299 | case ZFIN:
|
---|
1300 | return ERROR;
|
---|
1301 | case ZCRC:
|
---|
1302 | crc = 0xFFFFFFFFL;
|
---|
1303 | if (Canseek >= 0) {
|
---|
1304 | while (((c = getc(in)) != EOF) && --Rxpos)
|
---|
1305 | crc = UPDC32(c, crc);
|
---|
1306 | crc = ~crc;
|
---|
1307 | clearerr(in); /* Clear EOF */
|
---|
1308 | fseek(in, 0L, 0);
|
---|
1309 | }
|
---|
1310 | stohdr(crc);
|
---|
1311 | zsbhdr(ZCRC, Txhdr);
|
---|
1312 | goto again;
|
---|
1313 | case ZSKIP:
|
---|
1314 | fclose(in); return c;
|
---|
1315 | case ZRPOS:
|
---|
1316 | /*
|
---|
1317 | * Suppress zcrcw request otherwise triggered by
|
---|
1318 | * lastyunc==bytcnt
|
---|
1319 | */
|
---|
1320 | if (Rxpos && fseek(in, Rxpos, 0))
|
---|
1321 | return ERROR;
|
---|
1322 | Lastsync = (bytcnt = Txpos = Rxpos) -1;
|
---|
1323 | return zsendfdata();
|
---|
1324 | }
|
---|
1325 | }
|
---|
1326 | }
|
---|
1327 |
|
---|
1328 | /* Send the data in the file */
|
---|
1329 | int zsendfdata()
|
---|
1330 | {
|
---|
1331 | register c, e, n;
|
---|
1332 | register int newcnt;
|
---|
1333 | register long tcount = 0;
|
---|
1334 | int junkcount; /* Counts garbage chars received by TX */
|
---|
1335 | static int tleft = 6; /* Counter for test mode */
|
---|
1336 |
|
---|
1337 | Lrxpos = 0;
|
---|
1338 | junkcount = 0;
|
---|
1339 | Beenhereb4 = FALSE;
|
---|
1340 | somemore:
|
---|
1341 | if (setjmp(intrjmp)) {
|
---|
1342 | waitack:
|
---|
1343 | junkcount = 0;
|
---|
1344 | c = getinsync(0);
|
---|
1345 | gotack:
|
---|
1346 | switch (c) {
|
---|
1347 | default:
|
---|
1348 | case ZCAN:
|
---|
1349 | fclose(in);
|
---|
1350 | return ERROR;
|
---|
1351 | case ZSKIP:
|
---|
1352 | fclose(in);
|
---|
1353 | return c;
|
---|
1354 | case ZACK:
|
---|
1355 | case ZRPOS:
|
---|
1356 | break;
|
---|
1357 | case ZRINIT:
|
---|
1358 | return OK;
|
---|
1359 | }
|
---|
1360 | #ifdef READCHECK
|
---|
1361 | /*
|
---|
1362 | * If the reverse channel can be tested for data,
|
---|
1363 | * this logic may be used to detect error packets
|
---|
1364 | * sent by the receiver, in place of setjmp/longjmp
|
---|
1365 | * rdchk(fdes) returns non 0 if a character is available
|
---|
1366 | */
|
---|
1367 | while (rdchk(iofd)) {
|
---|
1368 | #ifdef SV
|
---|
1369 | switch (checked)
|
---|
1370 | #else
|
---|
1371 | switch (readline(1))
|
---|
1372 | #endif
|
---|
1373 | {
|
---|
1374 | case CAN:
|
---|
1375 | case ZPAD:
|
---|
1376 | c = getinsync(1);
|
---|
1377 | goto gotack;
|
---|
1378 | case XOFF: /* Wait a while for an XON */
|
---|
1379 | case XOFF|0200:
|
---|
1380 | readline(100);
|
---|
1381 | }
|
---|
1382 | }
|
---|
1383 | #endif
|
---|
1384 | }
|
---|
1385 |
|
---|
1386 | if ( !Fromcu)
|
---|
1387 | signal(SIGINT, onintr);
|
---|
1388 | newcnt = Rxbuflen;
|
---|
1389 | Txwcnt = 0;
|
---|
1390 | stohdr(Txpos);
|
---|
1391 | zsbhdr(ZDATA, Txhdr);
|
---|
1392 |
|
---|
1393 | /*
|
---|
1394 | * Special testing mode. This should force receiver to Attn,ZRPOS
|
---|
1395 | * many times. Each time the signal should be caught, causing the
|
---|
1396 | * file to be started over from the beginning.
|
---|
1397 | */
|
---|
1398 | if (Test) {
|
---|
1399 | if ( --tleft)
|
---|
1400 | while (tcount < 20000) {
|
---|
1401 | printf(qbf); fflush(stdout);
|
---|
1402 | tcount += strlen(qbf);
|
---|
1403 | #ifdef READCHECK
|
---|
1404 | while (rdchk(iofd)) {
|
---|
1405 | #ifdef SV
|
---|
1406 | switch (checked)
|
---|
1407 | #else
|
---|
1408 | switch (readline(1))
|
---|
1409 | #endif
|
---|
1410 | {
|
---|
1411 | case CAN:
|
---|
1412 | case ZPAD:
|
---|
1413 | #ifdef TCFLSH
|
---|
1414 | ioctl(iofd, TCFLSH, 1);
|
---|
1415 | #endif
|
---|
1416 | goto waitack;
|
---|
1417 | case XOFF: /* Wait for XON */
|
---|
1418 | case XOFF|0200:
|
---|
1419 | readline(100);
|
---|
1420 | }
|
---|
1421 | }
|
---|
1422 | #endif
|
---|
1423 | }
|
---|
1424 | signal(SIGINT, SIG_IGN); canit();
|
---|
1425 | sleep(3); purgeline(); mode(0);
|
---|
1426 | printf("\nsz: Tcount = %ld\n", tcount);
|
---|
1427 | if (tleft) {
|
---|
1428 | printf("ERROR: Interrupts Not Caught\n");
|
---|
1429 | exit(1);
|
---|
1430 | }
|
---|
1431 | exit(SS_NORMAL);
|
---|
1432 | }
|
---|
1433 |
|
---|
1434 | do {
|
---|
1435 | n = zfilbuf();
|
---|
1436 | if (Eofseen)
|
---|
1437 | e = ZCRCE;
|
---|
1438 | else if (junkcount > 3)
|
---|
1439 | e = ZCRCW;
|
---|
1440 | else if (bytcnt == Lastsync)
|
---|
1441 | e = ZCRCW;
|
---|
1442 | else if (Rxbuflen && (newcnt -= n) <= 0)
|
---|
1443 | e = ZCRCW;
|
---|
1444 | else if (Txwindow && (Txwcnt += n) >= Txwspac) {
|
---|
1445 | Txwcnt = 0; e = ZCRCQ;
|
---|
1446 | }
|
---|
1447 | else
|
---|
1448 | e = ZCRCG;
|
---|
1449 | if (Verbose>1)
|
---|
1450 | fprintf(stderr, "\r%7ld ZMODEM%s ",
|
---|
1451 | Txpos, Crc32t?" CRC-32":"");
|
---|
1452 | zsdata(txbuf, n, e);
|
---|
1453 | bytcnt = Txpos += n;
|
---|
1454 | if (e == ZCRCW)
|
---|
1455 | goto waitack;
|
---|
1456 | #ifdef READCHECK
|
---|
1457 | /*
|
---|
1458 | * If the reverse channel can be tested for data,
|
---|
1459 | * this logic may be used to detect error packets
|
---|
1460 | * sent by the receiver, in place of setjmp/longjmp
|
---|
1461 | * rdchk(fdes) returns non 0 if a character is available
|
---|
1462 | */
|
---|
1463 | fflush(stdout);
|
---|
1464 | while (rdchk(iofd)) {
|
---|
1465 | #ifdef SV
|
---|
1466 | switch (checked)
|
---|
1467 | #else
|
---|
1468 | switch (readline(1))
|
---|
1469 | #endif
|
---|
1470 | {
|
---|
1471 | case CAN:
|
---|
1472 | case ZPAD:
|
---|
1473 | c = getinsync(1);
|
---|
1474 | if (c == ZACK)
|
---|
1475 | break;
|
---|
1476 | #ifdef TCFLSH
|
---|
1477 | ioctl(iofd, TCFLSH, 1);
|
---|
1478 | #endif
|
---|
1479 | /* zcrce - dinna wanna starta ping-pong game */
|
---|
1480 | zsdata(txbuf, 0, ZCRCE);
|
---|
1481 | goto gotack;
|
---|
1482 | case XOFF: /* Wait a while for an XON */
|
---|
1483 | case XOFF|0200:
|
---|
1484 | readline(100);
|
---|
1485 | default:
|
---|
1486 | ++junkcount;
|
---|
1487 | }
|
---|
1488 | }
|
---|
1489 | #endif /* READCHECK */
|
---|
1490 | if (Txwindow) {
|
---|
1491 | while ((tcount = Txpos - Lrxpos) >= Txwindow) {
|
---|
1492 | vfile("%ld window >= %u", tcount, Txwindow);
|
---|
1493 | if (e != ZCRCQ)
|
---|
1494 | zsdata(txbuf, 0, e = ZCRCQ);
|
---|
1495 | c = getinsync(1);
|
---|
1496 | if (c != ZACK) {
|
---|
1497 | #ifdef TCFLSH
|
---|
1498 | ioctl(iofd, TCFLSH, 1);
|
---|
1499 | #endif
|
---|
1500 | zsdata(txbuf, 0, ZCRCE);
|
---|
1501 | goto gotack;
|
---|
1502 | }
|
---|
1503 | }
|
---|
1504 | vfile("window = %ld", tcount);
|
---|
1505 | }
|
---|
1506 | } while (!Eofseen);
|
---|
1507 | if ( !Fromcu)
|
---|
1508 | signal(SIGINT, SIG_IGN);
|
---|
1509 |
|
---|
1510 | for (;;) {
|
---|
1511 | stohdr(Txpos);
|
---|
1512 | zsbhdr(ZEOF, Txhdr);
|
---|
1513 | switch (getinsync(0)) {
|
---|
1514 | case ZACK:
|
---|
1515 | continue;
|
---|
1516 | case ZRPOS:
|
---|
1517 | goto somemore;
|
---|
1518 | case ZRINIT:
|
---|
1519 | return OK;
|
---|
1520 | case ZSKIP:
|
---|
1521 | fclose(in);
|
---|
1522 | return c;
|
---|
1523 | default:
|
---|
1524 | fclose(in);
|
---|
1525 | return ERROR;
|
---|
1526 | }
|
---|
1527 | }
|
---|
1528 | }
|
---|
1529 |
|
---|
1530 | /*
|
---|
1531 | * Respond to receiver's complaint, get back in sync with receiver
|
---|
1532 | */
|
---|
1533 | int getinsync(flag)
|
---|
1534 | int flag;
|
---|
1535 | {
|
---|
1536 | register int c;
|
---|
1537 |
|
---|
1538 | for (;;) {
|
---|
1539 | if (Test) {
|
---|
1540 | printf("\r\n\n\n***** Signal Caught *****\r\n");
|
---|
1541 | Rxpos = 0; c = ZRPOS;
|
---|
1542 | } else
|
---|
1543 | c = zgethdr(Rxhdr, 0);
|
---|
1544 | switch (c) {
|
---|
1545 | case ZCAN:
|
---|
1546 | case ZABORT:
|
---|
1547 | case ZFIN:
|
---|
1548 | case TIMEOUT:
|
---|
1549 | return ERROR;
|
---|
1550 | case ZRPOS:
|
---|
1551 | /* ************************************* */
|
---|
1552 | /* If sending to a buffered modem, you */
|
---|
1553 | /* might send a break at this point to */
|
---|
1554 | /* dump the modem's buffer. */
|
---|
1555 | clearerr(in); /* In case file EOF seen */
|
---|
1556 | if (fseek(in, Rxpos, 0))
|
---|
1557 | return ERROR;
|
---|
1558 | Eofseen = 0;
|
---|
1559 | bytcnt = Lrxpos = Txpos = Rxpos;
|
---|
1560 | if (Lastsync == Rxpos) {
|
---|
1561 | if (++Beenhereb4 > 4)
|
---|
1562 | if (blklen > 32)
|
---|
1563 | blklen /= 2;
|
---|
1564 | }
|
---|
1565 | Lastsync = Rxpos;
|
---|
1566 | return c;
|
---|
1567 | case ZACK:
|
---|
1568 | Lrxpos = Rxpos;
|
---|
1569 | if (flag || Txpos == Rxpos)
|
---|
1570 | return ZACK;
|
---|
1571 | continue;
|
---|
1572 | case ZRINIT:
|
---|
1573 | case ZSKIP:
|
---|
1574 | fclose(in);
|
---|
1575 | return c;
|
---|
1576 | case ERROR:
|
---|
1577 | default:
|
---|
1578 | zsbhdr(ZNAK, Txhdr);
|
---|
1579 | continue;
|
---|
1580 | }
|
---|
1581 | }
|
---|
1582 | }
|
---|
1583 |
|
---|
1584 |
|
---|
1585 | /* Say "bibi" to the receiver, try to do it cleanly */
|
---|
1586 | void saybibi()
|
---|
1587 | {
|
---|
1588 | for (;;) {
|
---|
1589 | stohdr(0L); /* CAF Was zsbhdr - minor change */
|
---|
1590 | zshhdr(ZFIN, Txhdr); /* to make debugging easier */
|
---|
1591 | switch (zgethdr(Rxhdr, 0)) {
|
---|
1592 | case ZFIN:
|
---|
1593 | sendline('O'); sendline('O'); flushmo();
|
---|
1594 | case ZCAN:
|
---|
1595 | case TIMEOUT:
|
---|
1596 | return;
|
---|
1597 | }
|
---|
1598 | }
|
---|
1599 | }
|
---|
1600 |
|
---|
1601 | /* Local screen character display function */
|
---|
1602 | void bttyout(c)
|
---|
1603 | int c;
|
---|
1604 | {
|
---|
1605 | if (Verbose)
|
---|
1606 | putc(c, stderr);
|
---|
1607 | }
|
---|
1608 |
|
---|
1609 | /* Send command and related info */
|
---|
1610 | int zsendcmd(buf, blen)
|
---|
1611 | char *buf;
|
---|
1612 | int blen;
|
---|
1613 | {
|
---|
1614 | register c;
|
---|
1615 | long cmdnum;
|
---|
1616 |
|
---|
1617 | cmdnum = getpid();
|
---|
1618 | errors = 0;
|
---|
1619 | for (;;) {
|
---|
1620 | stohdr(cmdnum);
|
---|
1621 | Txhdr[ZF0] = Cmdack1;
|
---|
1622 | zsbhdr(ZCOMMAND, Txhdr);
|
---|
1623 | zsdata(buf, blen, ZCRCW);
|
---|
1624 | listen:
|
---|
1625 | Rxtimeout = 100; /* Ten second wait for resp. */
|
---|
1626 | c = zgethdr(Rxhdr, 1);
|
---|
1627 |
|
---|
1628 | switch (c) {
|
---|
1629 | case ZRINIT:
|
---|
1630 | goto listen; /* CAF 8-21-87 */
|
---|
1631 | case ERROR:
|
---|
1632 | case TIMEOUT:
|
---|
1633 | if (++errors > Cmdtries)
|
---|
1634 | return ERROR;
|
---|
1635 | continue;
|
---|
1636 | case ZCAN:
|
---|
1637 | case ZABORT:
|
---|
1638 | case ZFIN:
|
---|
1639 | case ZSKIP:
|
---|
1640 | case ZRPOS:
|
---|
1641 | return ERROR;
|
---|
1642 | default:
|
---|
1643 | if (++errors > 20)
|
---|
1644 | return ERROR;
|
---|
1645 | continue;
|
---|
1646 | case ZCOMPL:
|
---|
1647 | Exitcode = Rxpos;
|
---|
1648 | saybibi();
|
---|
1649 | return OK;
|
---|
1650 | case ZRQINIT:
|
---|
1651 | #ifdef vax11c /* YAMP :== Yet Another Missing Primitive */
|
---|
1652 | return ERROR;
|
---|
1653 | #else
|
---|
1654 | vfile("******** RZ *******");
|
---|
1655 | system("rz");
|
---|
1656 | vfile("******** SZ *******");
|
---|
1657 | goto listen;
|
---|
1658 | #endif
|
---|
1659 | }
|
---|
1660 | }
|
---|
1661 | }
|
---|
1662 |
|
---|
1663 | /*
|
---|
1664 | * If called as sb use YMODEM protocol
|
---|
1665 | */
|
---|
1666 | void chkinvok(s)
|
---|
1667 | char *s;
|
---|
1668 | {
|
---|
1669 | #ifdef vax11c
|
---|
1670 | Progname = "sz";
|
---|
1671 | #else
|
---|
1672 | register char *p;
|
---|
1673 |
|
---|
1674 | p = s;
|
---|
1675 | while (*p == '-')
|
---|
1676 | s = ++p;
|
---|
1677 | while (*p)
|
---|
1678 | if (*p++ == '/')
|
---|
1679 | s = p;
|
---|
1680 | if (*s == 'v') {
|
---|
1681 | Verbose=1; ++s;
|
---|
1682 | }
|
---|
1683 | Progname = s;
|
---|
1684 | if (s[0]=='s' && s[1]=='b') {
|
---|
1685 | Nozmodem = TRUE; blklen=1024;
|
---|
1686 | }
|
---|
1687 | if (s[0]=='s' && s[1]=='x') {
|
---|
1688 | Modem2 = TRUE;
|
---|
1689 | }
|
---|
1690 | #endif
|
---|
1691 | }
|
---|
1692 |
|
---|
1693 | void countem(argc, argv)
|
---|
1694 | int argc;
|
---|
1695 | register char **argv;
|
---|
1696 | {
|
---|
1697 | register c;
|
---|
1698 | struct stat f;
|
---|
1699 |
|
---|
1700 | for (Totalleft = 0, Filesleft = 0; --argc >=0; ++argv) {
|
---|
1701 | f.st_size = -1;
|
---|
1702 | if (Verbose>2) {
|
---|
1703 | fprintf(stderr, "\nCountem: %03d %s ", argc, *argv);
|
---|
1704 | fflush(stderr);
|
---|
1705 | }
|
---|
1706 | if (access(*argv, 04) >= 0 && stat(*argv, &f) >= 0) {
|
---|
1707 | c = f.st_mode & S_IFMT;
|
---|
1708 | if (c != S_IFDIR && c != S_IFBLK) {
|
---|
1709 | ++Filesleft; Totalleft += f.st_size;
|
---|
1710 | }
|
---|
1711 | }
|
---|
1712 | if (Verbose>2)
|
---|
1713 | fprintf(stderr, " %ld", f.st_size);
|
---|
1714 | }
|
---|
1715 | if (Verbose>2)
|
---|
1716 | fprintf(stderr, "\ncountem: Total %d %ld\n",
|
---|
1717 | Filesleft, Totalleft);
|
---|
1718 | }
|
---|
1719 |
|
---|
1720 | void chartest(m)
|
---|
1721 | int m;
|
---|
1722 | {
|
---|
1723 | register int n;
|
---|
1724 |
|
---|
1725 | mode(m);
|
---|
1726 | printf("\r\n\nCharacter Transparency Test Mode %d\r\n", m);
|
---|
1727 | printf("If Pro-YAM/ZCOMM is not displaying ^M hit ALT-V NOW.\r\n");
|
---|
1728 | printf("Hit Enter.\021"); fflush(stdout);
|
---|
1729 | readline(500);
|
---|
1730 |
|
---|
1731 | for (n = 0; n < 256; ++n) {
|
---|
1732 | if (!(n%8))
|
---|
1733 | printf("\r\n");
|
---|
1734 | printf("%02x ", n); fflush(stdout);
|
---|
1735 | sendline(n); flushmo();
|
---|
1736 | printf(" "); fflush(stdout);
|
---|
1737 | if (n == 127) {
|
---|
1738 | printf("Hit Enter.\021"); fflush(stdout);
|
---|
1739 | readline(500);
|
---|
1740 | printf("\r\n"); fflush(stdout);
|
---|
1741 | }
|
---|
1742 | }
|
---|
1743 | printf("\021\r\nEnter Characters, echo is in hex.\r\n");
|
---|
1744 | printf("Hit SPACE or pause 40 seconds for exit.\r\n");
|
---|
1745 |
|
---|
1746 | while (n != TIMEOUT && n != ' ') {
|
---|
1747 | n = readline(400);
|
---|
1748 | printf("%02x\r\n", n);
|
---|
1749 | fflush(stdout);
|
---|
1750 | }
|
---|
1751 | printf("\r\nMode %d character transparency test ends.\r\n", m);
|
---|
1752 | fflush(stdout);
|
---|
1753 | }
|
---|
1754 |
|
---|
1755 | /* End of sz.c */
|
---|