Beispiel #1
0
static void checkpath(char *name)
{
	/* restrict pathnames to current tree or uucppublic */
	if (strstr(name, "../")) {
		canit();
		fprintf(stderr, "\r\nlrz:\tSecurity Violation\r\n");
		bibi(-1);
	}
	if (name[0] == '.' || strstr(name, "/.")) {
		canit();
		fprintf(stderr, "\r\nlrz:\tSecurity Violation\r\n");
		bibi(-1);
	}
}
Beispiel #2
0
/*
 * Nonblocking I/O is a bit different in System V, Release 2
 */
int 
rdchk(int fd)
{
	int lf, savestat;

	savestat = fcntl(fd, F_GETFL) ;
	if (savestat == -1)
		return 0;
#ifdef OVERLY_PARANOID
	if (-1==fcntl(fd, F_SETFL, savestat | O_NDELAY))
		return 0;
	lf = read(fd, &checked, 1) ;
	if (-1==fcntl(fd, F_SETFL, savestat)) {
#ifdef ENABLE_SYSLOG
		if (enable_syslog)
			lsyslog(LOG_CRIT,"F_SETFL failed in rdchk(): %s",	
				strerror(errno));
#endif
		zpfatal("rdchk: F_SETFL failed\n"); /* lose */
		/* there is really no way to recover. And we can't tell
		 * the other side what's going on if we can't write to
		 * fd, but we try.
		 */
		canit(fd);
		exit(1); 
	}
#else
	fcntl(fd, F_SETFL, savestat | O_NDELAY);
	lf = read(fd, &checked, 1) ;
	fcntl(fd, F_SETFL, savestat);
#endif
	return(lf == -1 && errno==EWOULDBLOCK ? 0 : lf) ;
}
Beispiel #3
0
/* called by signal interrupt or terminate to clean things up */
void bibi(int n)
{
    canit(0);
    oflush();
    io_mode(io_mode_fd, 0);
    if (n == SIGQUIT)
        abort();
    exit(128 + n);
}
Beispiel #4
0
/* called by signal interrupt or terminate to clean things up */
static void bibi(int signum)
{
	if (Zmodem)
		zmputs(Attn);
	canit();
	mode(0);
	closeit();
	fprintf(stderr, "lrz: caught signal %d; exiting", signum);
	exit(128 + signum);
}
Beispiel #5
0
/* called by signal interrupt or terminate to clean things up */
void
bibi(n)
{
	if (Zmodem)
		zmputs(Attn);
	canit(); mode(0);
	fprintf(stderr, "rz: caught signal %d; exiting", n);
	cucheck();
	exit(128+n);
}
Beispiel #6
0
static int wcreceive(int argc, char **argp)
{
	int c;

	if (Batch || argc == 0) {
		Crcflg = 1;
		if (!Quiet)
			fprintf(stderr, rbmsg, Progname, "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, "\n%s: ready to receive %s\r\n", Progname,
			Pathname);
		if ((fout = fopen(Pathname, "w")) == NULL)
			return ERROR;
		if (wcrx() == ERROR)
			goto fubar;
		timing(1);
	}
	return OK;
      fubar:
	canit();
	if (Topipe && fout) {
		pclose(fout);
		return ERROR;
	}
	if (fout)
		closeit();
	return ERROR;
}
Beispiel #7
0
static int wcgetsec(char *rxbuf, int maxtime)
{
	int checksum, wcj, firstch;
	unsigned short oldcrc;
	char *p;
	int sectcurr;

	for (Lastrx = errors = 0; errors < RETRYMAX; errors++) {

		if ((firstch = readline(maxtime)) == STX) {
			Blklen = 1024;
			goto get2;
		}
		if (firstch == SOH) {
			Blklen = 128;
		      get2:
			sectcurr = readline(1);
			if ((sectcurr + (oldcrc = readline(1))) == 0377) {
				oldcrc = checksum = 0;
				for (p = rxbuf, wcj = Blklen; --wcj >= 0;) {
					if ((firstch = readline(1)) < 0)
						goto bilge;
					oldcrc = updcrc(firstch, oldcrc);
					checksum += (*p++ = firstch);
				}
				if ((firstch = readline(1)) < 0)
					goto bilge;
				if (Crcflg) {
					oldcrc = updcrc(firstch, oldcrc);
					if ((firstch = readline(1)) < 0)
						goto bilge;
					oldcrc = updcrc(firstch, oldcrc);
					if (oldcrc & 0xFFFF)
						zperr("CRC");
					else {
						Firstsec = FALSE;
						return sectcurr;
					}
				}
					else
				    if (((checksum - firstch) & 0377) ==
					0) {
					Firstsec = FALSE;
					return sectcurr;
				} else
					zperr("Checksum");
			} else
				zperr("Sector number garbled");
		}
		/* make sure eot really is eot and not just mixmash */
		else if (firstch == EOT && readline(1) == TIMEOUT)
			return WCEOT;
		else if (firstch == CAN) {
			if (Lastrx == CAN) {
				zperr("Sender CANcelled");
				return ERROR;
			} else {
				Lastrx = CAN;
				continue;
			}
		} else if (firstch == TIMEOUT) {
			if (Firstsec)
				goto humbug;
		      bilge:
			zperr("TIMEOUT");
		} else
			zperr("Got 0%o sector header", firstch);

	      humbug:
		Lastrx = 0;
		while (readline(1) != TIMEOUT);
		if (Firstsec) {
			xsendline(Crcflg ? WANTCRC : NAK);
			Lleft = 0;	/* Do read next time ... */
		} else {
			maxtime = 40;
			xsendline(NAK);
			Lleft = 0;	/* Do read next time ... */
		}
	}
	/* try to stop the bubble machine. */
	canit();
	return ERROR;
}
Beispiel #8
0
int main(int argc, char *argv[])
{
	char *cp;
	int npats;
	char *virgin, **patts = NULL;
	int exitcode = 0;

	*pathsname = 0;
	*tempsname = 0;
	nodeinf = -1;

	dszlog = -1;

	Rxtimeout = 100;
	setbuf(stderr, NULL);

	chkinvok(virgin = argv[0]);	/* if called as [-]rzCOMMAND set flag */
	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;
				case 'g':
					if (--argc < 1) {
						usage();
					}

					iofd = open(*++argv, O_RDWR);
					break;
				case 'D':
					Nflag = TRUE;
					break;
				case 'e':
					Zctlesc = 1;
					break;
				case 'h':
					usage();
					break;
				case 'O':
					no_timeout = TRUE;
					break;
				case 'p':
					Lzmanag = ZMPROT;
					break;
				case 'q':
					Quiet = TRUE;
					Verbose = 0;
					break;
				case 'r':
					try_resume = TRUE;
					break;
				case 't':
					if (--argc < 1) {
						usage();
					}
					Rxtimeout = atoi(*++argv);
					if (Rxtimeout < 10
					    || Rxtimeout > 1000) usage();
					break;
				case 'f':
					if (--argc < 1) {
						usage();
					}
					strcpy(pathsname, *++argv);
					break;
				case 'F':
					if (--argc < 1) {
						usage();
					}
					strcpy(tempsname, *++argv);
					break;
				case 'n':
					if (--argc < 1) {
						usage();
					}
					nodeinf = open(*++argv, O_RDWR);
					read(nodeinf, &nin,
					     sizeof(struct
						    DayDream_NodeInfo));
					nin.ddn_flags |= (1L << 1);
					break;
				case 'l':
					if (--argc < 1) {
						usage();
					}
					dszlog =
					    open(*++argv,
						 O_WRONLY | O_CREAT, 0755);
					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) 
		setbuf(stderr, NULL);
	
	if (!Quiet) {
		if (Verbose == 0)
			Verbose = 2;
	}
	vfile("%s %s\n", Progname, VERSION);
	mode(1);
	signal(SIGTERM, bibi);
	if (wcreceive(npats, patts) == ERROR) {
		exitcode = 0200;
		canit();
	}
	mode(0);
	if (exitcode && !Zmodem)	/* bellow again with all thy might. */
		canit();
	exit(exitcode);

	return 0; /* compilers would complain */
}
Beispiel #9
0
static int wcs(const char *oname, const char *remotename)
{
#if !defined(S_ISDIR)
    int c;
#endif
    struct stat f;
    char *name;
    struct zm_fileinfo zi;

#ifdef HAVE_MMAP
    int dont_mmap_this = 0;
#endif


    if (Restricted) {
        /* restrict pathnames to current tree or uucppublic */
        if (strstr(oname, "../")
#ifdef PUBDIR
            || (oname[0] == '/' && strncmp(oname, MK_STRING(PUBDIR), strlen(MK_STRING(PUBDIR))))
#endif
            ) {
            canit(0);
            zmodem_error(1, 0, "security violation: not allowed to upload from %s", oname);
        }
    }

    if (0 == strcmp(oname, "-")) {
        char *p = getenv("ONAME");

        name = (char *)malloc(PATH_MAX + 1);
        if (p) {
            strcpy(name, p);
        } else {
            sprintf(name, "s%lu.lsz", (unsigned long) getpid());
        }
        input_f = stdin;
#ifdef HAVE_MMAP
        dont_mmap_this = 1;
#endif
    } else if ((input_f = fopen(oname, "r")) == NULL) {
        ++errcnt;
        return OK;              /* pass over it, there may be others */
    } else {
        name = (char *)malloc(PATH_MAX + 1);
        strcpy(name, oname);
    }
#ifdef HAVE_MMAP
    if (!use_mmap || dont_mmap_this)
#endif
    {
        static char *s = NULL;
        static size_t last_length = 0;
        struct stat st;

        if (fstat(fileno(input_f), &st) == -1)
            st.st_size = 1024 * 1024;
        if (buffersize == (size_t) - 1 && s) {
            if ((size_t) st.st_size > last_length) {
                free(s);
                s = NULL;
                last_length = 0;
            }
        }
        if (!s && buffersize) {
            last_length = 16384;
            if (buffersize == (size_t) - 1) {
                if (st.st_size > 0)
                    last_length = st.st_size;
            } else
                last_length = buffersize;
            /* buffer whole pages */
            last_length = (last_length + 4095) & 0xfffff000;
            s = malloc(last_length);
            if (!s) {
                exit(1);
            }
        }
        if (s) {
#ifdef SETVBUF_REVERSED
            setvbuf(input_f, _IOFBF, s, last_length);
#else
            setvbuf(input_f, s, _IOFBF, last_length);
#endif
        }
    }
    vpos = 0;
    /* Check for directory or block special files */
    fstat(fileno(input_f), &f);
#if defined(S_ISDIR)
    if (S_ISDIR(f.st_mode) || S_ISBLK(f.st_mode)) {
#else
    c = f.st_mode & S_IFMT;
    if (c == S_IFDIR || c == S_IFBLK) {
#endif
        fclose(input_f);
	free(name);
        return OK;
    }

    if (remotename) {
        /* disqualify const */
        union {
            const char *c;
            char *s;
        } cheat;

        cheat.c = remotename;
        zi.fname = cheat.s;
    } else
        zi.fname = name;
    zi.modtime = f.st_mtime;
    zi.mode = f.st_mode;
#if defined(S_ISFIFO)
    zi.bytes_total = (S_ISFIFO(f.st_mode)) ? DEFBYTL : f.st_size;
#else
    zi.bytes_total = c == S_IFIFO ? DEFBYTL : f.st_size;
#endif
    zi.bytes_sent = 0;
    zi.bytes_received = 0;
    zi.bytes_skipped = 0;
    zi.eof_seen = 0;

    ++Filcnt;
    free(name);
    switch (wctxpn(&zi)) {
    case ERROR:
        return ERROR;
    case ZSKIP:
        return OK;
    }
    if (!zmodem_requested && wctx(&zi) == ERROR) {
        return ERROR;
    }
    if (Unlinkafter)
        unlink(oname);

    return 0;
}

/*
 * generate and transmit pathname block consisting of
 *  pathname (null terminated),
 *  file length, mode time and file mode in octal
 *  as provided by the Unix fstat call.
 *  N.B.: modifies the passed name, may extend it!
 */
static int wctxpn(struct zm_fileinfo *zi)
{
    register char *p, *q;
    char *name2;
    struct stat f;

    name2 = (char *)malloc(PATH_MAX + 1);

    if (protocol == ZM_XMODEM) {
        free(name2);
        return OK;
    }
    if (!zmodem_requested)
        if (getnak()) {
            free(name2);
            return ERROR;
        }

    q = (char *) 0;
#if 0
    if (Dottoslash) {           /* change . to . */
        for (p = zi->fname; *p; ++p) {
            if (*p == '/')
                q = p;
            else if (*p == '.')
                *(q = p) = '/';
        }
        if (q && strlen(++q) > 8) {     /* If name>8 chars */
            q += 8;             /*   make it .ext */
            strcpy(name2, q);   /* save excess of name */
            *q = '.';
            strcpy(++q, name2); /* add it back */
        }
    }
#endif
    for (p = zi->fname, q = txbuf; *p;)
        if ((*q++ = *p++) == '/' && !Fullname)
            q = txbuf;
    *q++ = 0;
    p = q;
    while (q < (txbuf + MAX_BLOCK))
        *q++ = 0;
    /* note that we may lose some information here in case mode_t is wider than an 
     * int. But i believe sending %lo instead of %o _could_ break compatability
     */
    if (!Ascii && (input_f != stdin) && *zi->fname && fstat(fileno(input_f), &f) != -1)
        sprintf(p, "%lu %lo %o 0 %d %ld", (long) f.st_size, f.st_mtime, (unsigned int) ((no_unixmode) ? 0 : f.st_mode), Filesleft, Totalleft);
    Totalleft -= f.st_size;
    if (--Filesleft <= 0)
        Totalleft = 0;
    if (Totalleft < 0)
        Totalleft = 0;

    /* force 1k blocks if name won't fit in 128 byte block */
    if (txbuf[125])
        blklen = 1024;
    else {                      /* A little goodie for IMP/KMD */
        txbuf[127] = (f.st_size + 127) >> 7;
        txbuf[126] = (f.st_size + 127) >> 15;
    }
    if (zmodem_requested)
        free(name2);
        return zsendfile(zi, txbuf, 1 + strlen(p) + (p - txbuf));

	/*
    if (wcputsec(txbuf, 0, 128) == ERROR) {
        free(name2);
        return ERROR;
    }
    free(name2);
    return OK;
	*/
}

static int getnak(void)
{
    int firstch;
    int tries = 0;

    Lastrx = 0;
    for (;;) {
        tries++;
        switch (firstch = READLINE_PF(100)) {
        case ZPAD:
            if (getzrxinit())
                return ERROR;
            Ascii = 0;          /* Receiver does the conversion */
            return FALSE;
        case TIMEOUT:
            /* 30 seconds are enough */
            if (tries == 3) {
                return TRUE;
            }
            /* don't send a second ZRQINIT _directly_ after the
             * first one. Never send more then 4 ZRQINIT, because
             * omen rz stops if it saw 5 of them */
            if ((zrqinits_sent > 1 || tries > 1) && zrqinits_sent < 4) {
                /* if we already sent a ZRQINIT we are using zmodem
                 * protocol and may send further ZRQINITs 
                 */
                stohdr(0L);
                zshhdr(ZRQINIT, Txhdr);
                zrqinits_sent++;
            }
            continue;
        case WANTG:
            io_mode(io_mode_fd, 2);     /* Set cbreak, XON/XOFF, etc. */
            Optiong = TRUE;
            blklen = 1024;
        case WANTCRC:
            Crcflg = TRUE;
        case NAK:
            return FALSE;
        case CAN:
            if ((firstch = READLINE_PF(20)) == CAN && Lastrx == CAN)
                return TRUE;
        default:
            break;
        }
        Lastrx = firstch;
    }
}