?? rz.c
字號:
#define VERSION "2.03 05-17-88"#define PUBDIR "/usr/spool/uucppublic"/*% cc -compat -M2 -Ox -K -i -DMD -DOMEN % -o rz; size rz;<-xtx-*> cc386 -Ox -DMD -DOMEN -DSEGMENTS=8 rz.c -o $B/rz; size $B/rz * * rz.c By Chuck Forsberg * * cc -O rz.c -o rz USG (3.0) Unix * cc -O -DV7 rz.c -o rz Unix V7, BSD 2.8 - 4.3 * * ln rz rb; ln rz rx For either system * * ln rz /usr/bin/rzrmail For remote mail. Make this the * login shell. rzrmail then calls * rmail(1) to deliver mail. * * To compile on VMS: * * define LNK$LIBRARY SYS$LIBRARY:VAXCRTL.OLB * cc rz.c * cc vvmodem.c * link rz,vvmodem * rz :== $disk:[username.subdir]rz.exe * * * Unix is a trademark of Western Electric Company * * A program for Unix to receive files and commands from computers running * Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM. * rz uses Unix buffered input to reduce wasted CPU time. * * Iff the program is invoked by rzCOMMAND, output is piped to * "COMMAND filename" (Unix only) * * Some systems (Venix, Coherent, Regulus) may not support tty raw mode * read(2) the same way as Unix. ONEREAD must be defined to force one * character reads for these systems. Added 7-01-84 CAF * * Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF * * BIX added 6-30-87 to support BIX(TM) upload protocol used by the * Byte Information Exchange. * * NFGVMIN Updated 2-18-87 CAF for Xenix systems where c_cc[VMIN] * doesn't work properly (even though it compiles without error!), * * SEGMENTS=n added 2-21-88 as a model for CP/M programs * for CP/M-80 systems that cannot overlap modem and disk I/O. * * VMS flavor hacks begin with rz version 2.00 * * -DMD may be added to compiler command line to compile in * Directory-creating routines from Public Domain TAR by John Gilmore * * HOWMANY may be tuned for best performance * * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin */#include <sys/types.h>#ifdef vax11c#include <types.h>#include <stat.h>#define LOGFILE "rzlog.tmp"#define OS "VMS"#define BUFREADextern int errno;#define SS_NORMAL SS$_NORMAL#else/* Not vax11c */#define SS_NORMAL 0#define LOGFILE "/tmp/rzlog"#endif#include <time.h>#include <ctype.h>#include <errno.h>#include <signal.h>#include <setjmp.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <utime.h>#include <stdio.h>#define OK 0#define FALSE 0#define TRUE 1#undef ERROR#define ERROR (-1)_PROTOTYPE(long getfree , (void));_PROTOTYPE(void alrm , (int sig ));_PROTOTYPE(int main , (int argc , char *argv []));_PROTOTYPE(int usage , (void));_PROTOTYPE(int wcreceive , (int argc , char **argp ));_PROTOTYPE(int wcrxpn , (char *rpn ));_PROTOTYPE(int wcrx , (void));_PROTOTYPE(int wcgetsec , (char *rxbuf , int maxtime ));_PROTOTYPE(int readline , (int timeout ));_PROTOTYPE(void purgeline , (void));_PROTOTYPE(int procheader , (char *name ));_PROTOTYPE(int make_dirs , (char *pathname ));_PROTOTYPE(int makedir , (char *dpath , int dmode ));_PROTOTYPE(int putsec , (char *buf , int n ));_PROTOTYPE(void sendline , (int c ));_PROTOTYPE(void flushmo , (void));_PROTOTYPE(void uncaps , (char *s ));_PROTOTYPE(int IsAnyLower , (char *s ));_PROTOTYPE(char *substr , (char *s , char *t ));void zperr();_PROTOTYPE(void canit , (void));_PROTOTYPE(void report , (int sct ));_PROTOTYPE(void chkinvok , (char *s ));_PROTOTYPE(void checkpath , (char *name ));_PROTOTYPE(int tryz , (void));_PROTOTYPE(int rzfiles , (void));_PROTOTYPE(int rzfile , (void));_PROTOTYPE(void zmputs , (char *s ));_PROTOTYPE(int closeit , (void));_PROTOTYPE(void ackbibi , (void));_PROTOTYPE(void bttyout , (int c ));_PROTOTYPE(int sys2 , (char *s ));_PROTOTYPE(void exec2 , (char *s ));/* * Max value for HOWMANY is 255. * A larger value reduces system overhead but may evoke kernel bugs. * 133 corresponds to an XMODEM/CRC sector */#ifndef HOWMANY#define HOWMANY 133#endif/* Ward Christensen / CP/M parameters - Don't change these! */#define ENQ 005#define CAN ('X'&037)#define XOFF ('s'&037)#define XON ('q'&037)#define SOH 1#define STX 2#define EOT 4#define ACK 6#define NAK 025#define CPMEOF 032#define WANTCRC 0103 /* send C not NAK to get crc not checksum */#define TIMEOUT (-2)#define RCDO (-3)#define ERRORMAX 5#define RETRYMAX 5#define WCEOT (-10)#define PATHLEN 257 /* ready for 4.2 bsd ? */#define UNIXFILE 0xF000 /* The S_IFMT file mask bit for stat */int Zmodem=0; /* ZMODEM protocol requested */int Nozmodem = 0; /* If invoked as "rb" */unsigned Baudrate = 2400;#ifdef vax11c#include "vrzsz.c" /* most of the system dependent stuff here */#else#include "rbsb.c" /* most of the system dependent stuff here */#endif#include "crctab.c"FILE *fout;/* * Routine to calculate the free bytes on the current file system * ~0 means many free bytes (unknown) */long getfree(){ return(~0L); /* many free bytes ... */}int Lastrx;int Crcflg;int Firstsec;int Eofseen; /* indicates cpm eof (^Z) has been received */int errors;int Restricted=0; /* restricted; no /.. or ../ in filenames */#ifdef ONEREAD/* Sorry, Regulus and some others don't work right in raw mode! */int Readnum = 1; /* Number of bytes to ask for in read() from modem */#elseint Readnum = HOWMANY; /* Number of bytes to ask for in read() from modem */#endif#define DEFBYTL 2000000000L /* default rx file size */long Bytesleft; /* number of bytes of incoming file left */long Modtime; /* Unix style mod time for incoming file */int Filemode; /* Unix style mode for incoming file */char Pathname[PATHLEN];char *Progname; /* the name by which we were called */int Batch=0;int Topipe=0;int MakeLCPathname=TRUE; /* make received pathname lower case */int Verbose=0;int Quiet=0; /* overrides logic that would otherwise set verbose */int Nflag = 0; /* Don't really transfer files */int Rxclob=FALSE; /* Clobber existing file */int Rxbinary=FALSE; /* receive all files in bin mode */int Rxascii=FALSE; /* receive files in ascii (translate) mode */int Thisbinary; /* current file is to be received in bin mode */int Blklen; /* record length of received packets */#ifdef SEGMENTSint chinseg = 0; /* Number of characters received in this data seg */char secbuf[1+(SEGMENTS+1)*1024];#elsechar secbuf[1025];#endifchar linbuf[HOWMANY];int Lleft=0; /* number of characters in linbuf */time_t timep[2];char Lzmanag; /* Local file management request */char zconv; /* ZMODEM file conversion request */char zmanag; /* ZMODEM file management request */char ztrans; /* ZMODEM file transport request */int Zctlesc; /* Encode control characters */int Zrwindow = 1400; /* RX window size (controls garbage count) */jmp_buf tohere; /* For the interrupt on RX timeout */#define xsendline(c) sendline(c)#include "zm.c"int tryzhdrtype=ZRINIT; /* Header type to send corresponding to Last rx close */void alrm(sig)int sig;{ longjmp(tohere, -1);}/* called by signal interrupt or terminate to clean things up */void bibi(n)int n;{ if (Zmodem) zmputs(Attn); canit(); mode(0); fprintf(stderr, "rz: caught signal %d; exiting\n", n); cucheck(); exit(128+n);}int main(argc, argv)int argc;char *argv[];{ register char *cp; register npats; char *virgin, **patts; int exitcode = 0; Rxtimeout = 100; setbuf(stderr, (char *)NULL); if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh"))) Restricted=TRUE; from_cu();#ifdef vax11c Progname = virgin = "rz";#else chkinvok(virgin=argv[0]); /* if called as [-]rzCOMMAND set flag */#endif npats = 0; while (--argc) { cp = *++argv; if (*cp == '-') { while( *++cp) { switch(*cp) { case '\\': cp[1] = toupper(cp[1]); continue; case '+': Lzmanag = ZMAPND; break; case 'a': Rxascii=TRUE; break; case 'b': Rxbinary=TRUE; break; case 'c': Crcflg=TRUE; break;#ifndef vax11c case 'D': Nflag = TRUE; break;#endif case 'e': Zctlesc = 1; break; case 'p': Lzmanag = ZMPROT; break; case 'q': Quiet=TRUE; Verbose=0; break; case 't': if (--argc < 1) { usage(); } Rxtimeout = atoi(*++argv); if (Rxtimeout<10 || Rxtimeout>1000) usage(); break; case 'w': if (--argc < 1) { usage(); } Zrwindow = atoi(*++argv); break; case 'u': MakeLCPathname=FALSE; break; case 'v': ++Verbose; break; case 'y': Rxclob=TRUE; break; default: usage(); } } } else if ( !npats && argc>0) { if (argv[0][0]) { npats=argc; patts=argv; } } } if (npats > 1) usage(); if (Batch && npats) usage(); if (Verbose) { if (freopen(LOGFILE, "a", stderr)==NULL) { printf("Can't open log file %s\n",LOGFILE); exit(0200); } setbuf(stderr, (char *)NULL); fprintf(stderr, "argv[0]=%s Progname=%s\n", virgin, Progname); } if (Fromcu && !Quiet) { if (Verbose == 0) Verbose = 2; } vfile("%s %s for %s\n", Progname, VERSION, OS); mode(1); if (signal(SIGINT, bibi) == SIG_IGN) { signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN); } else { signal(SIGINT, bibi); signal(SIGKILL, bibi); } signal(SIGTERM, bibi); if (wcreceive(npats, patts)==ERROR) { exitcode=0200; canit(); } mode(0); vfile("exitcode = %d\n",exitcode); if (exitcode && !Zmodem) /* bellow again with all thy might. */ canit(); if (exitcode) cucheck(); if (Verbose) putc('\n', stderr); exit(exitcode ? exitcode:SS_NORMAL);}int usage(){ cucheck();#ifdef vax11c fprintf(stderr,"Usage: rz [-abeuvy]\n");#else fprintf(stderr,"Usage: rz [-abeuvy] (ZMODEM)\n"); fprintf(stderr,"or rb [-abuvy] (YMODEM)\n"); fprintf(stderr,"or rx [-abcv] file (XMODEM or XMODEM-1k)\n");#endif fprintf(stderr," -a ASCII transfer (strip CR)\n"); fprintf(stderr," -b Binary transfer for all files\n");#ifndef vax11c fprintf(stderr," -c Use 16 bit CRC (XMODEM)\n");#endif fprintf(stderr," -e Escape control characters (ZMODEM)\n"); fprintf(stderr," -v Verbose more v's give more info\n"); fprintf(stderr," -y Yes, clobber existing file if any\n"); fprintf(stderr,"%s %s for %s by Chuck Forsberg, Omen Technology INC\n", Progname, VERSION, OS); fprintf(stderr, "\t\t\042The High Reliability Software\042\n"); exit(SS_NORMAL);}/* * Debugging information output interface routine *//* VARARGS1 */void vfile(f, a, b, c)register char *f,*a,*b,*c;{ if (Verbose > 2) { fprintf(stderr, f, a, b, c); fprintf(stderr, "\n"); }}/* * Let's receive something already. */char *rbmsg ="%s ready. To begin transfer, type \"%s file ...\" to your modem program\r\n\n";int wcreceive(argc, argp)int argc;char **argp;{ register c; if (Batch || argc==0) { Crcflg=1; if ( !Quiet) fprintf(stderr, rbmsg, Progname, Nozmodem?"sb":"sz"); if (c=tryz()) { if (c == ZCOMPL) return OK; if (c == ERROR) goto fubar; c = rzfiles(); if (c) goto fubar; } else { for (;;) { if (wcrxpn(secbuf)== ERROR) goto fubar; if (secbuf[0]==0) return OK; if (procheader(secbuf) == ERROR) goto fubar; if (wcrx()==ERROR) goto fubar; } } } else { Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L; procheader(""); strcpy(Pathname, *argp); checkpath(Pathname); fprintf(stderr, "\nrz: ready to receive %s\r\n", Pathname); if ((fout=fopen(Pathname, "w")) == NULL) return ERROR; if (wcrx()==ERROR) goto fubar; } return OK;fubar: canit();#ifndef vax11c if (Topipe && fout) { pclose(fout); return ERROR; }#endif if (fout) fclose(fout);#ifndef vax11c if (Restricted) { unlink(Pathname); fprintf(stderr, "\r\nrz: %s removed.\r\n", Pathname); }#endif return ERROR;}/* * Fetch a pathname from the other end as a C ctyle ASCIZ string. * Length is indeterminate as long as less than Blklen * A null string represents no more files (YMODEM) */int wcrxpn(rpn)char *rpn; /* receive a pathname */{ register c;#ifdef NFGVMIN readline(1);#else purgeline();#endifet_tu: Firstsec=TRUE; Eofseen=FALSE; sendline(Crcflg?WANTCRC:NAK); Lleft=0; /* Do read next time ... */ while ((c = wcgetsec(rpn, 100)) != 0) { if (c == WCEOT) { zperr( "Pathname fetch returned %d", c); sendline(ACK); Lleft=0; /* Do read next time ... */ readline(1); goto et_tu; } return ERROR; } sendline(ACK); return OK;}/* * Adapted from CMODEM13.C, written by * Jack M. Wierda and Roderick W. Hart */int wcrx()
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -