[9] | 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 */
|
---|