Пример #1
0
/*
 * Receive files with Zmodem, Ymodem or Xmodem.
 * This receiver will figure out what to do, you should
 * be able to send anything.
 */
int zmrcvfiles(int want1k, int wantg)
{
    int	    rc;

    Syslog('+', "%s: start receive", protname());

    get_frame_buffer();

    Rxtimeout = 10;
    if (secbuf == NULL) 
	secbuf = malloc(MAXBLOCK+1);
    tryzhdrtype = ZRINIT;

    if ((rc = tryz()) < 0) {
	Syslog('+', "%s: could not initiate receive, rc=%d", protname(), rc);
    } else {
	if (rc == 0) {
	    if (protocol == ZM_ZMODEM) {
		Syslog('+', "%s: switching to Ymodem", protname());
		protocol = ZM_YMODEM;
	    }
	    rc = ymrcvfiles(want1k, wantg);
	    goto fubar;
	}

	/*
	 * Zmodem receiver
	 */
	switch (rc) {
	    case ZCOMPL:    rc = 0; 
			    break;
	    case ZFILE:	    rc = rzfiles(); 
			    break;
	}
    }
    
fubar:
    if (fout) {
	if (closeit(0)) {
	    WriteError("%s: Error closing file", protname);
	}
    }

    if (secbuf)
	free(secbuf);
    secbuf = NULL;

    io_mode(0, 1);  /* Normal raw mode */
    /*
     * Some programs send some garbage after the transfer, eat these.
     * This also introduces a pause after the transfer, some clients
     * need this.
     */
    purgeline(200);
    
    Syslog('+', "%s: end receive rc=%d", protname(), rc);
    return abs(rc);
}
Пример #2
0
/* send cancel string to get the other end to shut up */
void
canit(int fd, int *func_write(int, char *, int))
{
	static char canistr[] = {
		24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 8, 8, 8, 8, 8, 8, 8, 8,
		8, 8, 0
	};

	purgeline(0);
	(*func_write) (fd, canistr, strlen(canistr));
}
Пример #3
0
static int wctx(struct zm_fileinfo *zi)
{
    register size_t thisblklen;
    register int sectnum, attempts, firstch;

    firstsec = TRUE;
    thisblklen = blklen;

    while ((firstch = READLINE_PF(Rxtimeout)) != NAK && firstch != WANTCRC && firstch != WANTG && firstch != TIMEOUT && firstch != CAN);
    if (firstch == CAN) {
        return ERROR;
    }
    if (firstch == WANTCRC)
        Crcflg = TRUE;
    if (firstch == WANTG)
        Crcflg = TRUE;
    sectnum = 0;
    for (;;) {
        if (zi->bytes_total <= (zi->bytes_sent + 896L))
            thisblklen = 128;
        if (!filbuf(txbuf, thisblklen))
            break;
        if (wcputsec(txbuf, ++sectnum, thisblklen) == ERROR)
            return ERROR;
        zi->bytes_sent += thisblklen;
    }
    fclose(input_f);
    attempts = 0;
    do {
        purgeline(io_mode_fd);
        sendline(EOT);
        flushmo();
        ++attempts;
    } while ((firstch = (READLINE_PF(Rxtimeout)) != ACK) && attempts < RETRYMAX);
    if (attempts == RETRYMAX) {
        return ERROR;
    } else
        return OK;
}
Пример #4
0
/*
 * Ack a ZFIN packet, let byegones be byegones
 */
static void ackbibi(void)
{
	int n;

	vfile("ackbibi:");
	Readnum = 1;
	stohdr(0L);
	for (n = 3; --n >= 0;) {
		purgeline();
		zshhdr(ZFIN, Txhdr);
		switch (readline(100)) {
		case 'O':
			readline(1);	/* Discard 2nd 'O' */
			vfile("ackbibi complete");
			return;
		case RCDO:
			return;
		case TIMEOUT:
		default:
			break;
		}
	}
}
Пример #5
0
int bbs_zsendfile(char *filename, char *remote)
{
    struct stat f;

    if (stat(filename, &f) != 0)
        return ERROR;
    Totalleft = f.st_size;
    Filesleft = 1;
    calc_blklen(Totalleft);
    protocol = ZM_ZMODEM;
    io_mode_fd = 1;
    blklen = start_blklen = 1024;
    if (setjmp(zmodemjmp) == 0) {
        zsendline_init();
        io_mode(io_mode_fd, 1);
        readline_setup(io_mode_fd, 128, 256);
        raw_write(0, "rz\r", 3);

        /*   TODO : throw away received input */

        purgeline(io_mode_fd);
        stohdr(0L);
        zshhdr(ZRQINIT, Txhdr);
        zrqinits_sent++;
        oflush();

        Crcflg = FALSE;
        firstsec = TRUE;
        bytcnt = (size_t) - 1;
        Totsecs = 0;

        if (wcs(filename, remote) == ERROR) {
            readline_clean();
            return ERROR;
        }
        if (zmodem_requested)
            saybibi();
        else if (protocol != ZM_XMODEM) {
            struct zm_fileinfo zi;
            char *pa;

            pa = (char *)malloc(PATH_MAX + 1);
            *pa = '\0';
            zi.fname = pa;
            zi.modtime = 0;
            zi.mode = 0;
            zi.bytes_total = 0;
            zi.bytes_sent = 0;
            zi.bytes_received = 0;
            zi.bytes_skipped = 0;
            wctxpn(&zi);
            free(pa);
        }

        oflush();
        /* here needs a oflush */
        /* eat avalible input */
        /* better to eat some input here */
        io_mode(io_mode_fd, 0);
        readline_clean();
    } else {
        oflush();
        signal(SIGALRM, SIG_IGN);
        alarm(0);
        return ERROR;
    }
    return OK;
}
Пример #6
0
/*
 * Download files to the user.
 * Returns:
 *  0 - All seems well
 *  1 - No transfer protocol selected
 *  2 - No files to download.
 */
int download(down_list *download_list)
{
    down_list	    *tmpf;
    int		    err, maxrc = 0, Count = 0;
    char	    *temp, *symTo, *symFrom;
    unsigned int    Size = 0;
    struct dirent   *dp;
    DIR		    *dirp;
    struct timeval  starttime, endtime;
    struct timezone tz;

    Syslog('b', "download()");
    for (tmpf = download_list; tmpf; tmpf = tmpf->next) {
	Syslog('b', "%s,%s,%ld,%ld,%ld,%s,%s,%s", tmpf->local, tmpf->remote, tmpf->cps, tmpf->area, tmpf->size,
		tmpf->kfs ?"KFS":"KEEP", tmpf->sent ?"SENT":"N/A", tmpf->failed ?"FAILED":"N/A");
    }

    /*
     * If user has no default protocol, make sure he has one.
     */
    if (!ForceProtocol()) {
	return 1;
    }

    symTo   = calloc(PATH_MAX, sizeof(char));
    symFrom = calloc(PATH_MAX, sizeof(char));
    temp    = calloc(PATH_MAX, sizeof(char));

    /*
     * Build symlinks into the users tag directory.
     */
    chdir("./tag");
    for (tmpf = download_list; tmpf; tmpf = tmpf->next) {
        if (!tmpf->sent && !tmpf->failed) {
	    snprintf(symFrom, PATH_MAX, "%s/%s/tag/%s", CFG.bbs_usersdir, exitinfo.Name, tmpf->remote);
	    Syslog('b', "test \"%s\" \"%s\"", symFrom, tmpf->local);
	    if (strcmp(symFrom, tmpf->local)) {
		Syslog('b', "different, need a symlink");
		unlink(tmpf->remote);
		snprintf(symFrom, PATH_MAX, "%s", tmpf->remote);
		snprintf(symTo, PATH_MAX, "%s", tmpf->local);
		if (symlink(symTo, symFrom)) {
		    WriteError("$Can't create symlink %s %s %d", symTo, symFrom, errno);
		    tmpf->failed = TRUE;
		} else {
		    Syslog('b', "Created symlink %s -> %s", symFrom, symTo);
		}
		tmpf->kfs = FALSE;
	    } else {
		Syslog('b', "the same, file is in tag directory");
	    }

	    /*
	     * Check if file or symlink is really there.
	     */
	    snprintf(symFrom, PATH_MAX, "%s", tmpf->remote);
	    if ((access(symFrom, F_OK)) != 0) {
	        WriteError("File or symlink %s check failed, unmarking download", symFrom);
	        tmpf->failed = TRUE;
	    } else {
	        Count++;
		Size += tmpf->size;
	    }
	}
    }
    Home();

    if (!Count) {
        /*
         * Nothing to download
         */
        free(temp);
        free(symTo);
        free(symFrom);
        return 2;
    }

    clear();
    /* File(s)     : */
    pout(YELLOW, BLACK, (char *) Language(349)); snprintf(temp, PATH_MAX, "%d", Count);     PUTSTR(temp); Enter(1);
    /* Size        : */
    pout(  CYAN, BLACK, (char *) Language(350)); snprintf(temp, PATH_MAX, "%u", Size);      PUTSTR(temp); Enter(1);
    /* Protocol    : */
    pout(  CYAN, BLACK, (char *) Language(351)); snprintf(temp, PATH_MAX, "%s", sProtName); PUTSTR(temp); Enter(1);

    Syslog('+', "Download files start, protocol: %s", sProtName);

    PUTSTR(sProtAdvice);
    Enter(2);

    /*
     * Wait a while before download
     */
    sleep(2);
    
    if (uProtInternal) {
	snprintf(temp, PATH_MAX, "%s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
	chdir(temp);
	if (strncasecmp(sProtName, "zmodem-8k", 9) == 0) {
	    maxrc = zmsndfiles(download_list, TRUE);
	    Home();
	} else if (strncasecmp(sProtName, "zmodem", 6) == 0) {
	    maxrc = zmsndfiles(download_list, FALSE);
	    Home();
	} else if ((strncasecmp(sProtName, "xmodem", 6) == 0) || (strncasecmp(sProtName, "ymodem", 6) == 0)) {
	    if (strncasecmp(sProtName, "xmodem", 6) == 0)
		protocol = ZM_XMODEM;
	    else
		protocol = ZM_YMODEM;
	    if (strstr(sProtName, "1K") || strstr(sProtName, "1k"))
		maxrc = ymsndfiles(download_list, TRUE);
	    else
		maxrc = ymsndfiles(download_list, FALSE);
	    Home();
	} else {
	    Syslog('!', "Warning internal protocol %s not supported", sProtName);
	    maxrc = 1;
	}
    } else {
	gettimeofday(&starttime, &tz);

	/*
	 * Transfer the files. Set the Client/Server time at the maximum
	 * time the user has plus 10 minutes. The overall timer 10 seconds
	 * less. Not a nice but working solution.
	 */
	alarm_set(((exitinfo.iTimeLeft + 10) * 60) - 10);
	Altime((exitinfo.iTimeLeft + 10) * 60);

	snprintf(temp, PATH_MAX, "%s/%s/tag", CFG.bbs_usersdir, exitinfo.Name);
	if ((dirp = opendir(temp)) == NULL) {
	    WriteError("$Download: Can't open dir: %s", temp);
	    free(temp);
	} else {
	    chdir(temp);
	    free(temp);
	    temp = NULL;
	    while ((dp = readdir(dirp)) != NULL ) {
		if (*(dp->d_name) != '.') {
		    if (temp != NULL) {
			temp = xstrcat(temp, (char *)" ");
			temp = xstrcat(temp, dp->d_name);
		    } else {
			temp = xstrcpy(dp->d_name);
		    }
		}
	    }
	    if (temp != NULL) {
		if ((err = execute_str(sProtDn, temp, NULL, NULL, NULL, NULL))) {
		    WriteError("$Download error %d, prot: %s", err, sProtDn);
		}
		/*
		 * Restore rawport
		 */
		rawport();
		free(temp);
	    } else {
		WriteError("No filebatch created");
	    }
	    closedir(dirp);
	}

	purgeline(200); /* Wait a while, some Wintendo programs ignore input for a few seconds */
	Altime(0);
	alarm_off();
	alarm_on();
	Home();
	gettimeofday(&endtime, &tz);

	/*
	 * Checking the successfull sent files, they are missing from
	 * the ./tag directory. Failed files are still there.
	 */
	Count = Size = 0;

	for (tmpf = download_list; tmpf && (maxrc < 2); tmpf = tmpf->next) {
	    if (!tmpf->sent && !tmpf->failed) {
		snprintf(symTo, PATH_MAX, "./tag/%s", tmpf->remote);
		/*
		 * If symlink is gone the file is sent.
		 */
		if ((access(symTo, R_OK)) != 0) {
		    Syslog('+', "File %s from area %d sent ok", tmpf->remote, tmpf->area);
		    tmpf->sent = TRUE;
		    Size += tmpf->size;
		    Count++;
		} else {
		    Syslog('+', "Failed to sent %s from area %d", Tag.LFile, Tag.Area);
		}
	    }
	}

	/*
	 * Work out transfer rate in seconds by dividing the
	 * Size of the File by the amount of time it took to download 
	 * the file.
	 */
	Syslog('+', "Download %s in %d file(s)", transfertime(starttime, endtime, (unsigned int)Size, TRUE), Count);
    }
    
    free(symTo);
    free(symFrom);

    for (tmpf = download_list; tmpf; tmpf = tmpf->next) {
	Syslog('b', "%s,%s,%ld,%ld,%ld,%s,%s,%s", tmpf->local, tmpf->remote, tmpf->cps, tmpf->area, tmpf->size,
		tmpf->kfs ?"KFS":"KEEP", tmpf->sent ?"SENT":"N/A", tmpf->failed ?"FAILED":"N/A");
    }

    Syslog('b', "download() rc=%d", maxrc);
    return maxrc;
}