Annotation of embedaddon/lrzsz/src/lrz.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   lrz - receive files with x/y/zmodem
        !             3:   Copyright (C) until 1988 Chuck Forsberg (Omen Technology INC)
        !             4:   Copyright (C) 1994 Matt Porter, Michael D. Black
        !             5:   Copyright (C) 1996, 1997 Uwe Ohse
        !             6: 
        !             7:   This program is free software; you can redistribute it and/or modify
        !             8:   it under the terms of the GNU General Public License as published by
        !             9:   the Free Software Foundation; either version 2, or (at your option)
        !            10:   any later version.
        !            11:   
        !            12:   This program is distributed in the hope that it will be useful,
        !            13:   but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15:   GNU General Public License for more details.
        !            16: 
        !            17:   You should have received a copy of the GNU General Public License
        !            18:   along with this program; if not, write to the Free Software
        !            19:   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
        !            20:   02111-1307, USA.
        !            21: 
        !            22:   originally written by Chuck Forsberg
        !            23: */
        !            24: 
        !            25: #include "zglobal.h"
        !            26: 
        !            27: #define SS_NORMAL 0
        !            28: #include <stdio.h>
        !            29: #include <stdlib.h>
        !            30: #include <signal.h>
        !            31: #include <ctype.h>
        !            32: #include <errno.h>
        !            33: #include <getopt.h>
        !            34: 
        !            35: #ifdef HAVE_UTIME_H
        !            36: #include <utime.h>
        !            37: #endif
        !            38: 
        !            39: #include "timing.h"
        !            40: #include "long-options.h"
        !            41: #include "xstrtoul.h"
        !            42: #include "error.h"
        !            43: 
        !            44: #ifndef STRICT_PROTOTYPES
        !            45: extern time_t time();
        !            46: extern char *strerror();
        !            47: extern char *strstr();
        !            48: #endif
        !            49: 
        !            50: #ifndef HAVE_ERRNO_DECLARATION
        !            51: extern int errno;
        !            52: #endif
        !            53: 
        !            54: #define MAX_BLOCK 8192
        !            55: 
        !            56: /*
        !            57:  * Max value for HOWMANY is 255 if NFGVMIN is not defined.
        !            58:  *   A larger value reduces system overhead but may evoke kernel bugs.
        !            59:  *   133 corresponds to an XMODEM/CRC sector
        !            60:  */
        !            61: #ifndef HOWMANY
        !            62: #ifdef NFGVMIN
        !            63: #define HOWMANY MAX_BLOCK
        !            64: #else
        !            65: #define HOWMANY 255
        !            66: #endif
        !            67: #endif
        !            68: 
        !            69: unsigned Baudrate = 2400;
        !            70: 
        !            71: FILE *fout;
        !            72: 
        !            73: 
        !            74: int Lastrx;
        !            75: int Crcflg;
        !            76: int Firstsec;
        !            77: int errors;
        !            78: int Restricted=1;      /* restricted; no /.. or ../ in filenames */
        !            79: int Readnum = HOWMANY; /* Number of bytes to ask for in read() from modem */
        !            80: int skip_if_not_found;
        !            81: 
        !            82: char *Pathname;
        !            83: const char *program_name;              /* the name by which we were called */
        !            84: 
        !            85: int Topipe=0;
        !            86: int MakeLCPathname=TRUE;       /* make received pathname lower case */
        !            87: int Verbose=0;
        !            88: int Quiet=0;           /* overrides logic that would otherwise set verbose */
        !            89: int Nflag = 0;         /* Don't really transfer files */
        !            90: int Rxclob=FALSE;      /* Clobber existing file */
        !            91: int Rxbinary=FALSE;    /* receive all files in bin mode */
        !            92: int Rxascii=FALSE;     /* receive files in ascii (translate) mode */
        !            93: int Thisbinary;                /* current file is to be received in bin mode */
        !            94: int try_resume=FALSE;
        !            95: int allow_remote_commands=FALSE;
        !            96: int junk_path=FALSE;
        !            97: int no_timeout=FALSE;
        !            98: enum zm_type_enum protocol;
        !            99: int    under_rsh=FALSE;
        !           100: int zmodem_requested=FALSE;
        !           101: 
        !           102: #ifdef SEGMENTS
        !           103: int chinseg = 0;       /* Number of characters received in this data seg */
        !           104: char secbuf[1+(SEGMENTS+1)*MAX_BLOCK];
        !           105: #else
        !           106: char secbuf[MAX_BLOCK + 1];
        !           107: #endif
        !           108: 
        !           109: #ifdef ENABLE_TIMESYNC
        !           110: int timesync_flag=0;
        !           111: int in_timesync=0;
        !           112: #endif
        !           113: int in_tcpsync=0;
        !           114: int tcpsync_flag=1;
        !           115: int tcp_socket=-1;
        !           116: int tcp_flag=0;
        !           117: char *tcp_server_address=NULL;
        !           118: 
        !           119: char tcp_buf[256]="";
        !           120: #if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)
        !           121: static int o_sync = 0;
        !           122: #endif
        !           123: static int rzfiles __P ((struct zm_fileinfo *));
        !           124: static int tryz __P ((void));
        !           125: static void checkpath __P ((const char *name));
        !           126: static void chkinvok __P ((const char *s));
        !           127: static void report __P ((int sct));
        !           128: static void uncaps __P ((char *s));
        !           129: static int IsAnyLower __P ((const char *s));
        !           130: static int putsec __P ((struct zm_fileinfo *zi, char *buf, size_t n));
        !           131: static int make_dirs __P ((char *pathname));
        !           132: static int procheader __P ((char *name, struct zm_fileinfo *));
        !           133: static int wcgetsec __P ((size_t *Blklen, char *rxbuf, unsigned int maxtime));
        !           134: static int wcrx __P ((struct zm_fileinfo *));
        !           135: static int wcrxpn __P ((struct zm_fileinfo *, char *rpn));
        !           136: static int wcreceive __P ((int argc, char **argp));
        !           137: static int rzfile __P ((struct zm_fileinfo *));
        !           138: static void usage __P ((int exitcode, const char *what));
        !           139: static void usage1 __P ((int exitcode));
        !           140: static void exec2 __P ((const char *s));
        !           141: static int closeit __P ((struct zm_fileinfo *));
        !           142: static void ackbibi __P ((void));
        !           143: static int sys2 __P ((const char *s));
        !           144: static void zmputs __P ((const char *s));
        !           145: static size_t getfree __P ((void));
        !           146: 
        !           147: static long buffersize=32768;
        !           148: static unsigned long min_bps=0;
        !           149: static long min_bps_time=120;
        !           150: 
        !           151: char Lzmanag;          /* Local file management request */
        !           152: char zconv;            /* ZMODEM file conversion request */
        !           153: char zmanag;           /* ZMODEM file management request */
        !           154: char ztrans;           /* ZMODEM file transport request */
        !           155: int Zctlesc;           /* Encode control characters */
        !           156: int Zrwindow = 1400;   /* RX window size (controls garbage count) */
        !           157: 
        !           158: int tryzhdrtype=ZRINIT;        /* Header type to send corresponding to Last rx close */
        !           159: time_t stop_time;
        !           160: 
        !           161: #ifdef ENABLE_SYSLOG
        !           162: #  if defined(ENABLE_SYSLOG_FORCE) || defined(ENABLE_SYSLOG_DEFAULT)
        !           163: int enable_syslog=TRUE;
        !           164: #  else
        !           165: int enable_syslog=FALSE;
        !           166: #  endif
        !           167: #define DO_SYSLOG_FNAME(message) do { \
        !           168:        if (enable_syslog) { \
        !           169:                const char *shortname; \
        !           170:                if (!zi->fname) \
        !           171:                        shortname="no.name"; \
        !           172:                else { \
        !           173:                        shortname=strrchr(zi->fname,'/'); \
        !           174:                        if (!shortname) \
        !           175:                                shortname=zi->fname; \
        !           176:                        else \
        !           177:                                shortname++; \
        !           178:                } \
        !           179:         lsyslog message ; \
        !           180:        } \
        !           181: } while(0)
        !           182: #define DO_SYSLOG(message) do { \
        !           183:        if (enable_syslog) { \
        !           184:         lsyslog message ; \
        !           185:        } \
        !           186: } while(0)
        !           187: #else
        !           188: #define DO_SYSLOG_FNAME(message) do { } while(0)
        !           189: #define DO_SYSLOG(message) do { } while(0)
        !           190: #endif
        !           191: 
        !           192: 
        !           193: /* called by signal interrupt or terminate to clean things up */
        !           194: RETSIGTYPE
        !           195: bibi(int n)
        !           196: {
        !           197:        if (zmodem_requested)
        !           198:                zmputs(Attn);
        !           199:        canit(STDOUT_FILENO);
        !           200:        io_mode(0,0);
        !           201:        error(128+n,0,_("caught signal %d; exiting"), n);
        !           202: }
        !           203: 
        !           204: static struct option const long_options[] =
        !           205: {
        !           206:        {"append", no_argument, NULL, '+'},
        !           207:        {"ascii", no_argument, NULL, 'a'},
        !           208:        {"binary", no_argument, NULL, 'b'},
        !           209:        {"bufsize", required_argument, NULL, 'B'},
        !           210:        {"allow-commands", no_argument, NULL, 'C'},
        !           211:        {"allow-remote-commands", no_argument, NULL, 'C'},
        !           212:        {"escape", no_argument, NULL, 'e'},
        !           213:        {"rename", no_argument, NULL, 'E'},
        !           214:        {"help", no_argument, NULL, 'h'},
        !           215:        {"crc-check", no_argument, NULL, 'H'},
        !           216:        {"junk-path", no_argument, NULL, 'j'},
        !           217:        {"errors", required_argument, NULL, 3},
        !           218:        {"disable-timeouts", no_argument, NULL, 'O'},
        !           219:        {"disable-timeout", no_argument, NULL, 'O'}, /* i can't get it right */
        !           220:        {"min-bps", required_argument, NULL, 'm'},
        !           221:        {"min-bps-time", required_argument, NULL, 'M'},
        !           222:        {"newer", no_argument, NULL, 'n'},
        !           223:        {"newer-or-longer", no_argument, NULL, 'N'},
        !           224:        {"protect", no_argument, NULL, 'p'},
        !           225:        {"resume", no_argument, NULL, 'r'},
        !           226:        {"restricted", no_argument, NULL, 'R'},
        !           227:        {"quiet", no_argument, NULL, 'q'},
        !           228:        {"stop-at", required_argument, NULL, 's'},
        !           229:        {"timesync", no_argument, NULL, 'S'},
        !           230:        {"timeout", required_argument, NULL, 't'},
        !           231:        {"keep-uppercase", no_argument, NULL, 'u'},
        !           232:        {"unrestrict", no_argument, NULL, 'U'},
        !           233:        {"verbose", no_argument, NULL, 'v'},
        !           234:        {"windowsize", required_argument, NULL, 'w'},
        !           235:        {"with-crc", no_argument, NULL, 'c'},
        !           236:        {"xmodem", no_argument, NULL, 'X'},
        !           237:        {"ymodem", no_argument, NULL, 1},
        !           238:        {"zmodem", no_argument, NULL, 'Z'},
        !           239:        {"overwrite", no_argument, NULL, 'y'},
        !           240:        {"null", no_argument, NULL, 'D'},
        !           241:        {"syslog", optional_argument, NULL , 2},
        !           242:        {"delay-startup", required_argument, NULL, 4},
        !           243:        {"o-sync", no_argument, NULL, 5},
        !           244:        {"o_sync", no_argument, NULL, 5},
        !           245:        {"tcp-server", no_argument, NULL, 6},
        !           246:        {"tcp-client", required_argument, NULL, 7},
        !           247:        {NULL,0,NULL,0}
        !           248: };
        !           249: 
        !           250: static void
        !           251: show_version(void)
        !           252: {
        !           253:        printf ("%s (%s) %s\n", program_name, PACKAGE, VERSION);
        !           254: }
        !           255: 
        !           256: int
        !           257: main(int argc, char *argv[])
        !           258: {
        !           259:        register char *cp;
        !           260:        register int npats;
        !           261:        char **patts=NULL; /* keep compiler quiet */
        !           262:        int exitcode=0;
        !           263:        int c;
        !           264:        unsigned int startup_delay=0;
        !           265: 
        !           266:        Rxtimeout = 100;
        !           267:        setbuf(stderr, NULL);
        !           268:        if ((cp=getenv("SHELL")) && (strstr(cp, "rsh") || strstr(cp, "rksh")
        !           269:                || strstr(cp,"rbash") || strstr(cp, "rshell")))
        !           270:                under_rsh=TRUE;
        !           271:        if ((cp=getenv("ZMODEM_RESTRICTED"))!=NULL)
        !           272:                Restricted=2;
        !           273: 
        !           274:        /* make temporary and unfinished files */
        !           275:        umask(0077);
        !           276: 
        !           277:        from_cu();
        !           278:        chkinvok(argv[0]);      /* if called as [-]rzCOMMAND set flag */
        !           279: 
        !           280: #ifdef ENABLE_SYSLOG
        !           281:        openlog(program_name,LOG_PID,ENABLE_SYSLOG);
        !           282: #endif
        !           283: 
        !           284:        setlocale (LC_ALL, "");
        !           285:        bindtextdomain (PACKAGE, LOCALEDIR);
        !           286:        textdomain (PACKAGE);
        !           287: 
        !           288:     parse_long_options (argc, argv, show_version, usage1);
        !           289: 
        !           290:        while ((c = getopt_long (argc, argv, 
        !           291:                "a+bB:cCDeEhm:M:OprRqs:St:uUvw:XZy",
        !           292:                long_options, (int *) 0)) != EOF)
        !           293:        {
        !           294:                unsigned long int tmp;
        !           295:                char *tmpptr;
        !           296:                enum strtol_error s_err;
        !           297: 
        !           298:                switch (c)
        !           299:                {
        !           300:                case 0:
        !           301:                        break;
        !           302:                case '+': Lzmanag = ZF1_ZMAPND; break;
        !           303:                case 'a': Rxascii=TRUE;  break;
        !           304:                case 'b': Rxbinary=TRUE; break;
        !           305:                case 'B': 
        !           306:                        if (strcmp(optarg,"auto")==0) 
        !           307:                                buffersize=-1;
        !           308:                        else
        !           309:                                buffersize=strtol(optarg,NULL,10);
        !           310:                        break;
        !           311:                case 'c': Crcflg=TRUE; break;
        !           312:                case 'C': allow_remote_commands=TRUE; break;
        !           313:                case 'D': Nflag = TRUE; break;
        !           314:                case 'E': Lzmanag = ZF1_ZMCHNG; break;
        !           315:                case 'e': Zctlesc = 1; break;
        !           316:                case 'h': usage(0,NULL); break;
        !           317:                case 'H': Lzmanag= ZF1_ZMCRC; break;
        !           318:                case 'j': junk_path=TRUE; break;
        !           319:                case 'm':
        !           320:                        s_err = xstrtoul (optarg, &tmpptr, 0, &tmp, "km");
        !           321:                        min_bps = tmp;
        !           322:                        if (s_err != LONGINT_OK)
        !           323:                                STRTOL_FATAL_ERROR (optarg, _("min_bps"), s_err);
        !           324:                        break;
        !           325:                case 'M':
        !           326:                        s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
        !           327:                        min_bps_time = tmp;
        !           328:                        if (s_err != LONGINT_OK)
        !           329:                                STRTOL_FATAL_ERROR (optarg, _("min_bps_time"), s_err);
        !           330:                        if (min_bps_time<=1)
        !           331:                                usage(2,_("min_bps_time must be > 1"));
        !           332:                        break;
        !           333:                case 'N': Lzmanag = ZF1_ZMNEWL;  break;
        !           334:                case 'n': Lzmanag = ZF1_ZMNEW;  break;
        !           335:                case 'O': no_timeout=TRUE; break;
        !           336:                case 'p': Lzmanag = ZF1_ZMPROT;  break;
        !           337:                case 'q': Quiet=TRUE; Verbose=0; break;
        !           338:                case 's':
        !           339:                        if (isdigit((unsigned char) (*optarg))) {
        !           340:                                struct tm *tm;
        !           341:                                time_t t;
        !           342:                                int hh,mm;
        !           343:                                char *nex;
        !           344:                                
        !           345:                                hh = strtoul (optarg, &nex, 10);
        !           346:                                if (hh>23)
        !           347:                                        usage(2,_("hour to large (0..23)"));
        !           348:                                if (*nex!=':')
        !           349:                                        usage(2, _("unparsable stop time\n"));
        !           350:                                nex++;
        !           351:                 mm = strtoul (optarg, &nex, 10);
        !           352:                                if (mm>59)
        !           353:                                        usage(2,_("minute to large (0..59)"));
        !           354:                                
        !           355:                                t=time(NULL);
        !           356:                                tm=localtime(&t);
        !           357:                                tm->tm_hour=hh;
        !           358:                                tm->tm_min=hh;
        !           359:                                stop_time=mktime(tm);
        !           360:                                if (stop_time<t)
        !           361:                                        stop_time+=86400L; /* one day more */
        !           362:                                if (stop_time - t <10)
        !           363:                                        usage(2,_("stop time to small"));
        !           364:                        } else {
        !           365:                                s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
        !           366:                                stop_time = tmp + time(0);
        !           367:                                if (s_err != LONGINT_OK)
        !           368:                                        STRTOL_FATAL_ERROR (optarg, _("stop-at"), s_err);
        !           369:                                if (tmp<10)
        !           370:                                        usage(2,_("stop time to small"));
        !           371:                        }
        !           372:                        break;
        !           373: 
        !           374: 
        !           375:                case 'r': 
        !           376:                        if (try_resume) 
        !           377:                                Lzmanag= ZF1_ZMCRC;
        !           378:                        else
        !           379:                                try_resume=TRUE;  
        !           380:                        break;
        !           381:                case 'R': Restricted++;  break;
        !           382:                case 'S':
        !           383: #ifdef ENABLE_TIMESYNC
        !           384:                        timesync_flag++;
        !           385:                        if (timesync_flag==2) {
        !           386: #ifdef HAVE_SETTIMEOFDAY
        !           387:                                error(0,0,_("don't have settimeofday, will not set time\n"));
        !           388: #endif
        !           389:                                if (getuid()!=0)
        !           390:                                        error(0,0,
        !           391:                                _("not running as root (this is good!), can not set time\n"));
        !           392:                        }
        !           393: #endif
        !           394:                        break;
        !           395:                case 't':
        !           396:                        s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
        !           397:                        Rxtimeout = tmp;
        !           398:                        if (s_err != LONGINT_OK)
        !           399:                                STRTOL_FATAL_ERROR (optarg, _("timeout"), s_err);
        !           400:                        if (Rxtimeout<10 || Rxtimeout>1000)
        !           401:                                usage(2,_("timeout out of range 10..1000"));
        !           402:                        break;
        !           403:                case 'w':
        !           404:                        s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
        !           405:                        Zrwindow = tmp;
        !           406:                        if (s_err != LONGINT_OK)
        !           407:                                STRTOL_FATAL_ERROR (optarg, _("window size"), s_err);
        !           408:                        break;
        !           409:                case 'u':
        !           410:                        MakeLCPathname=FALSE; break;
        !           411:                case 'U':
        !           412:                        if (!under_rsh)
        !           413:                                Restricted=0;
        !           414:                        else  {
        !           415:                                DO_SYSLOG((LOG_INFO,"--unrestrict option used under restricted shell"));
        !           416:                                error(1,0,
        !           417:        _("security violation: can't do that under restricted shell\n"));
        !           418:                        }
        !           419:                        break;
        !           420:                case 'v':
        !           421:                        ++Verbose; break;
        !           422:                case 'X': protocol=ZM_XMODEM; break;
        !           423:                case 1:   protocol=ZM_YMODEM; break;
        !           424:                case 'Z': protocol=ZM_ZMODEM; break;
        !           425:                case 'y':
        !           426:                        Rxclob=TRUE; break;
        !           427:                case 2:
        !           428: #ifdef ENABLE_SYSLOG
        !           429: #  ifndef ENABLE_SYSLOG_FORCE
        !           430:                        if (optarg && (!strcmp(optarg,"off") || !strcmp(optarg,"no"))) {
        !           431:                                if (under_rsh)
        !           432:                                        error(0,0, _("cannot turnoff syslog"));
        !           433:                                else
        !           434:                                        enable_syslog=FALSE;
        !           435:                        }
        !           436:                        else
        !           437:                                enable_syslog=TRUE;
        !           438: #  else
        !           439:                        error(0,0, _("cannot turnoff syslog"));
        !           440: #  endif
        !           441: #endif
        !           442:                case 3:
        !           443:                        s_err = xstrtoul (optarg, NULL, 0, &tmp, "km");
        !           444:                        bytes_per_error = tmp;
        !           445:                        if (s_err != LONGINT_OK)
        !           446:                                STRTOL_FATAL_ERROR (optarg, _("bytes_per_error"), s_err);
        !           447:                        if (bytes_per_error<100)
        !           448:                                usage(2,_("bytes-per-error should be >100"));
        !           449:                        break;
        !           450:         case 4:
        !           451:                        s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
        !           452:                        startup_delay = tmp;
        !           453:                        if (s_err != LONGINT_OK)
        !           454:                                STRTOL_FATAL_ERROR (optarg, _("startup delay"), s_err);
        !           455:                        break;
        !           456:                case 5:
        !           457: #if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)
        !           458:                        o_sync=1;
        !           459: #else
        !           460:                        error(0,0, _("O_SYNC not supported by the kernel"));
        !           461: #endif
        !           462:                        break;
        !           463:                case 6:
        !           464:                        tcp_flag=2;
        !           465:                        break;
        !           466:                case 7:
        !           467:                        tcp_flag=3;
        !           468:                        tcp_server_address=(char *)strdup(optarg);
        !           469:                        if (!tcp_server_address)
        !           470:                                error(1,0,_("out of memory"));
        !           471:                        break;
        !           472:                default:
        !           473:                        usage(2,NULL);
        !           474:                }
        !           475: 
        !           476:        }
        !           477: 
        !           478:        if (getuid()!=geteuid()) {
        !           479:                error(1,0,
        !           480:                _("this program was never intended to be used setuid\n"));
        !           481:        }
        !           482:        /* initialize zsendline tab */
        !           483:        zsendline_init();
        !           484: #ifdef HAVE_SIGINTERRUPT
        !           485:        siginterrupt(SIGALRM,1);
        !           486: #endif
        !           487:        if (startup_delay)
        !           488:                sleep(startup_delay);
        !           489: 
        !           490:        npats = argc - optind;
        !           491:        patts=&argv[optind];
        !           492: 
        !           493:        if (npats > 1)
        !           494:                usage(2,_("garbage on commandline"));
        !           495:        if (protocol!=ZM_XMODEM && npats)
        !           496:                usage(2, _("garbage on commandline"));
        !           497:        if (protocol==ZM_XMODEM && !npats)
        !           498:                usage(2, _("need a file name to receive"));
        !           499:        if (Restricted && allow_remote_commands) {
        !           500:                allow_remote_commands=FALSE;
        !           501:        }
        !           502:        if (Fromcu && !Quiet) {
        !           503:                if (Verbose == 0)
        !           504:                        Verbose = 2;
        !           505:        }
        !           506: 
        !           507:        vfile("%s %s\n", program_name, VERSION);
        !           508: 
        !           509:        if (tcp_flag==2) {
        !           510:                char buf[256];
        !           511: #ifdef MAXHOSTNAMELEN
        !           512:                char hn[MAXHOSTNAMELEN];
        !           513: #else
        !           514:                char hn[256];
        !           515: #endif
        !           516:                char *p,*q;
        !           517:                int d;
        !           518: 
        !           519:                /* tell receiver to receive via tcp */
        !           520:                d=tcp_server(buf);
        !           521:                p=strchr(buf+1,'<');
        !           522:                p++;
        !           523:                q=strchr(p,'>');
        !           524:                *q=0;
        !           525:                if (gethostname(hn,sizeof(hn))==-1) {
        !           526:                        error(1,0, _("hostname too long\n"));
        !           527:                }
        !           528:                fprintf(stdout,"connect with lrz --tcp-client \"%s:%s\"\n",hn,p);
        !           529:                fflush(stdout);
        !           530:                /* ok, now that this file is sent we can switch to tcp */
        !           531: 
        !           532:                tcp_socket=tcp_accept(d);
        !           533:                dup2(tcp_socket,0);
        !           534:                dup2(tcp_socket,1);
        !           535:        }
        !           536:        if (tcp_flag==3) {
        !           537:                char buf[256];
        !           538:                char *p;
        !           539:                p=strchr(tcp_server_address,':');
        !           540:                if (!p)
        !           541:                        error(1,0, _("illegal server address\n"));
        !           542:                *p++=0;
        !           543:                sprintf(buf,"[%s] <%s>\n",tcp_server_address,p);
        !           544: 
        !           545:                fprintf(stdout,"connecting to %s\n",buf);
        !           546:                fflush(stdout);
        !           547: 
        !           548:                /* we need to switch to tcp mode */
        !           549:                tcp_socket=tcp_connect(buf);
        !           550:                dup2(tcp_socket,0);
        !           551:                dup2(tcp_socket,1);
        !           552:        }
        !           553: 
        !           554:        io_mode(0,1);
        !           555:        readline_setup(0, HOWMANY, MAX_BLOCK*2);
        !           556:        if (signal(SIGINT, bibi) == SIG_IGN) 
        !           557:                signal(SIGINT, SIG_IGN);
        !           558:        else
        !           559:                signal(SIGINT, bibi);
        !           560:        signal(SIGTERM, bibi);
        !           561:        signal(SIGPIPE, bibi);
        !           562:        if (wcreceive(npats, patts)==ERROR) {
        !           563:                exitcode=0200;
        !           564:                canit(STDOUT_FILENO);
        !           565:        }
        !           566:        io_mode(0,0);
        !           567:        if (exitcode && !zmodem_requested)      /* bellow again with all thy might. */
        !           568:                canit(STDOUT_FILENO);
        !           569:        if (Verbose)
        !           570:        {
        !           571:                fputs("\r\n",stderr);
        !           572:                if (exitcode)
        !           573:                        fputs(_("Transfer incomplete\n"),stderr);
        !           574:                else
        !           575:                        fputs(_("Transfer complete\n"),stderr);
        !           576:        }
        !           577:        exit(exitcode);
        !           578: }
        !           579: 
        !           580: static void
        !           581: usage1(int exitcode)
        !           582: {
        !           583:        usage(exitcode,NULL);
        !           584: }
        !           585: 
        !           586: static void
        !           587: usage(int exitcode, const char *what)
        !           588: {
        !           589:        FILE *f=stdout;
        !           590: 
        !           591:        if (exitcode)
        !           592:        {
        !           593:                if (what)
        !           594:                        fprintf(stderr, "%s: %s\n",program_name,what);
        !           595:                fprintf (stderr, _("Try `%s --help' for more information.\n"),
        !           596:                        program_name);
        !           597:                exit(exitcode);
        !           598:        }
        !           599: 
        !           600:        fprintf(f, _("%s version %s\n"), program_name,
        !           601:                VERSION);
        !           602: 
        !           603:        fprintf(f,_("Usage: %s [options] [filename.if.xmodem]\n"), program_name);
        !           604:        fputs(_("Receive files with ZMODEM/YMODEM/XMODEM protocol\n"),f);
        !           605:        fputs(_(
        !           606:                "    (X) = option applies to XMODEM only\n"
        !           607:                "    (Y) = option applies to YMODEM only\n"
        !           608:                "    (Z) = option applies to ZMODEM only\n"
        !           609:                ),f);
        !           610:        fputs(_(
        !           611: "  -+, --append                append to existing files\n"
        !           612: "  -a, --ascii                 ASCII transfer (change CR/LF to LF)\n"
        !           613: "  -b, --binary                binary transfer\n"
        !           614: "  -B, --bufsize N             buffer N bytes (N==auto: buffer whole file)\n"
        !           615: "  -c, --with-crc              Use 16 bit CRC (X)\n"
        !           616: "  -C, --allow-remote-commands allow execution of remote commands (Z)\n"
        !           617: "  -D, --null                  write all received data to /dev/null\n"
        !           618: "      --delay-startup N       sleep N seconds before doing anything\n"
        !           619: "  -e, --escape                Escape control characters (Z)\n"
        !           620: "  -E, --rename                rename any files already existing\n"
        !           621: "      --errors N              generate CRC error every N bytes (debugging)\n"
        !           622: "  -h, --help                  Help, print this usage message\n"
        !           623: "  -m, --min-bps N             stop transmission if BPS below N\n"
        !           624: "  -M, --min-bps-time N          for at least N seconds (default: 120)\n"
        !           625: "  -O, --disable-timeouts      disable timeout code, wait forever for data\n"
        !           626: "      --o-sync                open output file(s) in synchronous write mode\n"
        !           627: "  -p, --protect               protect existing files\n"
        !           628: "  -q, --quiet                 quiet, no progress reports\n"
        !           629: "  -r, --resume                try to resume interrupted file transfer (Z)\n"
        !           630: "  -R, --restricted            restricted, more secure mode\n"
        !           631: "  -s, --stop-at {HH:MM|+N}    stop transmission at HH:MM or in N seconds\n"
        !           632: "  -S, --timesync              request remote time (twice: set local time)\n"
        !           633: "      --syslog[=off]          turn syslog on or off, if possible\n"
        !           634: "  -t, --timeout N             set timeout to N tenths of a second\n"
        !           635: "  -u, --keep-uppercase        keep upper case filenames\n"
        !           636: "  -U, --unrestrict            disable restricted mode (if allowed to)\n"
        !           637: "  -v, --verbose               be verbose, provide debugging information\n"
        !           638: "  -w, --windowsize N          Window is N bytes (Z)\n"
        !           639: "  -X  --xmodem                use XMODEM protocol\n"
        !           640: "  -y, --overwrite             Yes, clobber existing file if any\n"
        !           641: "      --ymodem                use YMODEM protocol\n"
        !           642: "  -Z, --zmodem                use ZMODEM protocol\n"
        !           643: "\n"
        !           644: "short options use the same arguments as the long ones\n"
        !           645:        ),f);
        !           646:        exit(exitcode);
        !           647: }
        !           648: 
        !           649: /*
        !           650:  * Let's receive something already.
        !           651:  */
        !           652: 
        !           653: static int 
        !           654: wcreceive(int argc, char **argp)
        !           655: {
        !           656:        int c;
        !           657:        struct zm_fileinfo zi;
        !           658: #ifdef ENABLE_SYSLOG
        !           659:        const char *shortname=NULL;;
        !           660: #endif
        !           661:        zi.fname=NULL;
        !           662:        zi.modtime=0;
        !           663:        zi.mode=0;
        !           664:        zi.bytes_total=0;
        !           665:        zi.bytes_sent=0;
        !           666:        zi.bytes_received=0;
        !           667:        zi.bytes_skipped=0;
        !           668:        zi.eof_seen=0;
        !           669: 
        !           670:        if (protocol!=ZM_XMODEM || argc==0) {
        !           671:                Crcflg=1;
        !           672:                if ( !Quiet)
        !           673:                        vstringf(_("%s waiting to receive."), program_name);
        !           674:                if ((c=tryz())!=0) {
        !           675:                        if (c == ZCOMPL)
        !           676:                                return OK;
        !           677:                        if (c == ERROR)
        !           678:                                goto fubar;
        !           679:                        c = rzfiles(&zi);
        !           680: 
        !           681: #ifdef ENABLE_SYSLOG
        !           682:                        shortname=NULL;
        !           683: #endif
        !           684:                        if (c)
        !           685:                                goto fubar;
        !           686:                } else {
        !           687:                        for (;;) {
        !           688:                                if (Verbose > 1
        !           689: #ifdef ENABLE_SYSLOG
        !           690:                                        || enable_syslog
        !           691: #endif
        !           692:                                )
        !           693:                                        timing(1,NULL);
        !           694: #ifdef ENABLE_SYSLOG
        !           695:                                shortname=NULL;
        !           696: #endif
        !           697:                                if (wcrxpn(&zi,secbuf)== ERROR)
        !           698:                                        goto fubar;
        !           699:                                if (secbuf[0]==0)
        !           700:                                        return OK;
        !           701:                                if (procheader(secbuf, &zi) == ERROR)
        !           702:                                        goto fubar;
        !           703: #ifdef ENABLE_SYSLOG
        !           704:                                shortname=strrchr(zi.fname,'/');
        !           705:                                if (shortname)
        !           706:                                        shortname++;
        !           707:                                else
        !           708:                                        shortname=zi.fname;
        !           709: #endif
        !           710:                                if (wcrx(&zi)==ERROR)
        !           711:                                        goto fubar;
        !           712: 
        !           713:                                if (Verbose > 1
        !           714: #ifdef ENABLE_SYSLOG
        !           715:                                        || enable_syslog
        !           716: #endif
        !           717:                                ) {
        !           718:                                        double d;
        !           719:                                        long bps;
        !           720:                                        d=timing(0,NULL);
        !           721:                                        if (d==0)
        !           722:                                                d=0.5; /* can happen if timing uses time() */
        !           723:                                        bps=(zi.bytes_received-zi.bytes_skipped)/d;
        !           724: 
        !           725:                                        if (Verbose>1) {
        !           726:                                                vstringf(
        !           727:                                                        _("\rBytes received: %7ld/%7ld   BPS:%-6ld                \r\n"),
        !           728:                                                        (long) zi.bytes_received, (long) zi.bytes_total, bps);
        !           729:                                        }
        !           730: #ifdef ENABLE_SYSLOG
        !           731:                                        if (enable_syslog)
        !           732:                                                lsyslog(LOG_INFO,"%s/%s: %ld Bytes, %ld BPS",
        !           733:                                                        shortname,protname(),zi.bytes_received, bps);
        !           734: #endif
        !           735:                                }
        !           736:                        }
        !           737:                }
        !           738:        } else {
        !           739:                char dummy[128];
        !           740:                dummy[0]='\0'; /* pre-ANSI HPUX cc demands this */
        !           741:                dummy[1]='\0'; /* procheader uses name + 1 + strlen(name) */
        !           742:                zi.bytes_total = DEFBYTL;
        !           743: 
        !           744:                if (Verbose > 1
        !           745: #ifdef ENABLE_SYSLOG
        !           746:                        || enable_syslog
        !           747: #endif
        !           748:                        ) 
        !           749:                        timing(1,NULL);
        !           750:                procheader(dummy, &zi);
        !           751: 
        !           752:                if (Pathname)
        !           753:                        free(Pathname);
        !           754:                errno=0;
        !           755:                Pathname=malloc(PATH_MAX+1);
        !           756:                if (!Pathname)
        !           757:                        error(1,0,_("out of memory"));
        !           758: 
        !           759:                strcpy(Pathname, *argp);
        !           760:                checkpath(Pathname);
        !           761: #ifdef ENABLE_SYSLOG
        !           762:                shortname=strrchr(*argp,'/');
        !           763:                if (shortname)
        !           764:                        shortname++;
        !           765:                else
        !           766:                        shortname=*argp;
        !           767: #endif
        !           768:                vchar('\n');
        !           769:                vstringf(_("%s: ready to receive %s"), program_name, Pathname);
        !           770:                vstring("\r\n");
        !           771: 
        !           772:                if ((fout=fopen(Pathname, "w")) == NULL) {
        !           773: #ifdef ENABLE_SYSLOG
        !           774:                        if (enable_syslog)
        !           775:                                lsyslog(LOG_ERR,"%s/%s: cannot open: %m",
        !           776:                                        shortname,protname());
        !           777: #endif
        !           778:                        return ERROR;
        !           779:                }
        !           780:                if (wcrx(&zi)==ERROR) {
        !           781:                        goto fubar;
        !           782:                }
        !           783:                if (Verbose > 1
        !           784: #ifdef ENABLE_SYSLOG
        !           785:                        || enable_syslog
        !           786: #endif
        !           787:                        ) {
        !           788:                        double d;
        !           789:                        long bps;
        !           790:                        d=timing(0,NULL);
        !           791:                        if (d==0)
        !           792:                                d=0.5; /* can happen if timing uses time() */
        !           793:                        bps=(zi.bytes_received-zi.bytes_skipped)/d;
        !           794:                        if (Verbose) {
        !           795:                                vstringf(
        !           796:                                        _("\rBytes received: %7ld   BPS:%-6ld                \r\n"),
        !           797:                                        (long) zi.bytes_received, bps);
        !           798:                        }
        !           799: #ifdef ENABLE_SYSLOG
        !           800:                        if (enable_syslog)
        !           801:                                lsyslog(LOG_INFO,"%s/%s: %ld Bytes, %ld BPS",
        !           802:                                        shortname,protname(),zi.bytes_received, bps);
        !           803: #endif
        !           804:                }
        !           805:        }
        !           806:        return OK;
        !           807: fubar:
        !           808: #ifdef ENABLE_SYSLOG
        !           809:        if (enable_syslog)
        !           810:                lsyslog(LOG_ERR,"%s/%s: got error", 
        !           811:                        shortname ? shortname : "no.name", protname());
        !           812: #endif
        !           813:        canit(STDOUT_FILENO);
        !           814:        if (Topipe && fout) {
        !           815:                pclose(fout);  return ERROR;
        !           816:        }
        !           817:        if (fout)
        !           818:                fclose(fout);
        !           819: 
        !           820:        if (Restricted && Pathname) {
        !           821:                unlink(Pathname);
        !           822:                vstringf(_("\r\n%s: %s removed.\r\n"), program_name, Pathname);
        !           823:        }
        !           824:        return ERROR;
        !           825: }
        !           826: 
        !           827: 
        !           828: /*
        !           829:  * Fetch a pathname from the other end as a C ctyle ASCIZ string.
        !           830:  * Length is indeterminate as long as less than Blklen
        !           831:  * A null string represents no more files (YMODEM)
        !           832:  */
        !           833: static int 
        !           834: wcrxpn(struct zm_fileinfo *zi, char *rpn)
        !           835: {
        !           836:        register int c;
        !           837:        size_t Blklen=0;                /* record length of received packets */
        !           838: 
        !           839: #ifdef NFGVMIN
        !           840:        READLINE_PF(1);
        !           841: #else
        !           842:        purgeline(0);
        !           843: #endif
        !           844: 
        !           845: et_tu:
        !           846:        Firstsec=TRUE;
        !           847:        zi->eof_seen=FALSE;
        !           848:        sendline(Crcflg?WANTCRC:NAK);
        !           849:        flushmo();
        !           850:        purgeline(0); /* Do read next time ... */
        !           851:        while ((c = wcgetsec(&Blklen, rpn, 100)) != 0) {
        !           852:                if (c == WCEOT) {
        !           853:                        zperr( _("Pathname fetch returned EOT"));
        !           854:                        sendline(ACK);
        !           855:                        flushmo();
        !           856:                        purgeline(0);   /* Do read next time ... */
        !           857:                        READLINE_PF(1);
        !           858:                        goto et_tu;
        !           859:                }
        !           860:                return ERROR;
        !           861:        }
        !           862:        sendline(ACK);
        !           863:        flushmo();
        !           864:        return OK;
        !           865: }
        !           866: 
        !           867: /*
        !           868:  * Adapted from CMODEM13.C, written by
        !           869:  * Jack M. Wierda and Roderick W. Hart
        !           870:  */
        !           871: static int 
        !           872: wcrx(struct zm_fileinfo *zi)
        !           873: {
        !           874:        register int sectnum, sectcurr;
        !           875:        register char sendchar;
        !           876:        size_t Blklen;
        !           877: 
        !           878:        Firstsec=TRUE;sectnum=0; 
        !           879:        zi->eof_seen=FALSE;
        !           880:        sendchar=Crcflg?WANTCRC:NAK;
        !           881: 
        !           882:        for (;;) {
        !           883:                sendline(sendchar);     /* send it now, we're ready! */
        !           884:                flushmo();
        !           885:                purgeline(0);   /* Do read next time ... */
        !           886:                sectcurr=wcgetsec(&Blklen, secbuf, 
        !           887:                        (unsigned int) ((sectnum&0177) ? 50 : 130));
        !           888:                report(sectcurr);
        !           889:                if (sectcurr==((sectnum+1) &0377)) {
        !           890:                        sectnum++;
        !           891:                        /* if using xmodem we don't know how long a file is */
        !           892:                        if (zi->bytes_total && R_BYTESLEFT(zi) < Blklen)
        !           893:                                Blklen=R_BYTESLEFT(zi);
        !           894:                        zi->bytes_received+=Blklen;
        !           895:                        if (putsec(zi, secbuf, Blklen)==ERROR)
        !           896:                                return ERROR;
        !           897:                        sendchar=ACK;
        !           898:                }
        !           899:                else if (sectcurr==(sectnum&0377)) {
        !           900:                        zperr( _("Received dup Sector"));
        !           901:                        sendchar=ACK;
        !           902:                }
        !           903:                else if (sectcurr==WCEOT) {
        !           904:                        if (closeit(zi))
        !           905:                                return ERROR;
        !           906:                        sendline(ACK);
        !           907:                        flushmo();
        !           908:                        purgeline(0);   /* Do read next time ... */
        !           909:                        return OK;
        !           910:                }
        !           911:                else if (sectcurr==ERROR)
        !           912:                        return ERROR;
        !           913:                else {
        !           914:                        zperr( _("Sync Error"));
        !           915:                        return ERROR;
        !           916:                }
        !           917:        }
        !           918: }
        !           919: 
        !           920: /*
        !           921:  * Wcgetsec fetches a Ward Christensen type sector.
        !           922:  * Returns sector number encountered or ERROR if valid sector not received,
        !           923:  * or CAN CAN received
        !           924:  * or WCEOT if eot sector
        !           925:  * time is timeout for first char, set to 4 seconds thereafter
        !           926:  ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
        !           927:  *    (Caller must do that when he is good and ready to get next sector)
        !           928:  */
        !           929: static int
        !           930: wcgetsec(size_t *Blklen, char *rxbuf, unsigned int maxtime)
        !           931: {
        !           932:        register int checksum, wcj, firstch;
        !           933:        register unsigned short oldcrc;
        !           934:        register char *p;
        !           935:        int sectcurr;
        !           936: 
        !           937:        for (Lastrx=errors=0; errors<RETRYMAX; errors++) {
        !           938: 
        !           939:                if ((firstch=READLINE_PF(maxtime))==STX) {
        !           940:                        *Blklen=1024; goto get2;
        !           941:                }
        !           942:                if (firstch==SOH) {
        !           943:                        *Blklen=128;
        !           944: get2:
        !           945:                        sectcurr=READLINE_PF(1);
        !           946:                        if ((sectcurr+(oldcrc=READLINE_PF(1)))==0377) {
        !           947:                                oldcrc=checksum=0;
        !           948:                                for (p=rxbuf,wcj=*Blklen; --wcj>=0; ) {
        !           949:                                        if ((firstch=READLINE_PF(1)) < 0)
        !           950:                                                goto bilge;
        !           951:                                        oldcrc=updcrc(firstch, oldcrc);
        !           952:                                        checksum += (*p++ = firstch);
        !           953:                                }
        !           954:                                if ((firstch=READLINE_PF(1)) < 0)
        !           955:                                        goto bilge;
        !           956:                                if (Crcflg) {
        !           957:                                        oldcrc=updcrc(firstch, oldcrc);
        !           958:                                        if ((firstch=READLINE_PF(1)) < 0)
        !           959:                                                goto bilge;
        !           960:                                        oldcrc=updcrc(firstch, oldcrc);
        !           961:                                        if (oldcrc & 0xFFFF)
        !           962:                                                zperr( _("CRC"));
        !           963:                                        else {
        !           964:                                                Firstsec=FALSE;
        !           965:                                                return sectcurr;
        !           966:                                        }
        !           967:                                }
        !           968:                                else if (((checksum-firstch)&0377)==0) {
        !           969:                                        Firstsec=FALSE;
        !           970:                                        return sectcurr;
        !           971:                                }
        !           972:                                else
        !           973:                                        zperr( _("Checksum"));
        !           974:                        }
        !           975:                        else
        !           976:                                zperr(_("Sector number garbled"));
        !           977:                }
        !           978:                /* make sure eot really is eot and not just mixmash */
        !           979: #ifdef NFGVMIN
        !           980:                else if (firstch==EOT && READLINE_PF(1)==TIMEOUT)
        !           981:                        return WCEOT;
        !           982: #else
        !           983:                else if (firstch==EOT && READLINE_PF>0)
        !           984:                        return WCEOT;
        !           985: #endif
        !           986:                else if (firstch==CAN) {
        !           987:                        if (Lastrx==CAN) {
        !           988:                                zperr( _("Sender Cancelled"));
        !           989:                                return ERROR;
        !           990:                        } else {
        !           991:                                Lastrx=CAN;
        !           992:                                continue;
        !           993:                        }
        !           994:                }
        !           995:                else if (firstch==TIMEOUT) {
        !           996:                        if (Firstsec)
        !           997:                                goto humbug;
        !           998: bilge:
        !           999:                        zperr( _("TIMEOUT"));
        !          1000:                }
        !          1001:                else
        !          1002:                        zperr( _("Got 0%o sector header"), firstch);
        !          1003: 
        !          1004: humbug:
        !          1005:                Lastrx=0;
        !          1006:                {
        !          1007:                        int cnt=1000;
        !          1008:                        while(cnt-- && READLINE_PF(1)!=TIMEOUT)
        !          1009:                                ;
        !          1010:                }
        !          1011:                if (Firstsec) {
        !          1012:                        sendline(Crcflg?WANTCRC:NAK);
        !          1013:                        flushmo();
        !          1014:                        purgeline(0);   /* Do read next time ... */
        !          1015:                } else {
        !          1016:                        maxtime=40;
        !          1017:                        sendline(NAK);
        !          1018:                        flushmo();
        !          1019:                        purgeline(0);   /* Do read next time ... */
        !          1020:                }
        !          1021:        }
        !          1022:        /* try to stop the bubble machine. */
        !          1023:        canit(STDOUT_FILENO);
        !          1024:        return ERROR;
        !          1025: }
        !          1026: 
        !          1027: #define ZCRC_DIFFERS (ERROR+1)
        !          1028: #define ZCRC_EQUAL (ERROR+2)
        !          1029: /*
        !          1030:  * do ZCRC-Check for open file f.
        !          1031:  * check at most check_bytes bytes (crash recovery). if 0 -> whole file.
        !          1032:  * remote file size is remote_bytes.
        !          1033:  */
        !          1034: static int 
        !          1035: do_crc_check(FILE *f, size_t remote_bytes, size_t check_bytes) 
        !          1036: {
        !          1037:        struct stat st;
        !          1038:        unsigned long crc;
        !          1039:        unsigned long rcrc;
        !          1040:        size_t n;
        !          1041:        int c;
        !          1042:        int t1=0,t2=0;
        !          1043:        if (-1==fstat(fileno(f),&st)) {
        !          1044:                DO_SYSLOG((LOG_ERR,"cannot fstat open file: %s",strerror(errno)));
        !          1045:                return ERROR;
        !          1046:        }
        !          1047:        if (check_bytes==0 && ((size_t) st.st_size)!=remote_bytes)
        !          1048:                return ZCRC_DIFFERS; /* shortcut */
        !          1049: 
        !          1050:        crc=0xFFFFFFFFL;
        !          1051:        n=check_bytes;
        !          1052:        if (n==0)
        !          1053:                n=st.st_size;
        !          1054:        while (n-- && ((c = getc(f)) != EOF))
        !          1055:                crc = UPDC32(c, crc);
        !          1056:        crc = ~crc;
        !          1057:        clearerr(f);  /* Clear EOF */
        !          1058:        fseek(f, 0L, 0);
        !          1059: 
        !          1060:        while (t1<3) {
        !          1061:                stohdr(check_bytes);
        !          1062:                zshhdr(ZCRC, Txhdr);
        !          1063:                while(t2<3) {
        !          1064:                        size_t tmp;
        !          1065:                        c = zgethdr(Rxhdr, 0, &tmp);
        !          1066:                        rcrc=(unsigned long) tmp;
        !          1067:                        switch (c) {
        !          1068:                        default: /* ignore */
        !          1069:                                break;
        !          1070:                        case ZFIN:
        !          1071:                                return ERROR;
        !          1072:                        case ZRINIT:
        !          1073:                                return ERROR;
        !          1074:                        case ZCAN:
        !          1075:                                if (Verbose)
        !          1076:                                        vstringf(_("got ZCAN"));
        !          1077:                                return ERROR;
        !          1078:                                break;
        !          1079:                        case ZCRC:
        !          1080:                                if (crc!=rcrc)
        !          1081:                                        return ZCRC_DIFFERS;
        !          1082:                                return ZCRC_EQUAL;
        !          1083:                                break;
        !          1084:                        }
        !          1085:                }
        !          1086:        }
        !          1087:        return ERROR;
        !          1088: }
        !          1089: 
        !          1090: /*
        !          1091:  * Process incoming file information header
        !          1092:  */
        !          1093: static int
        !          1094: procheader(char *name, struct zm_fileinfo *zi)
        !          1095: {
        !          1096:        const char *openmode;
        !          1097:        char *p;
        !          1098:        static char *name_static=NULL;
        !          1099:        char *nameend;
        !          1100: 
        !          1101:        if (name_static)
        !          1102:                free(name_static);
        !          1103:        if (junk_path) {
        !          1104:                p=strrchr(name,'/');
        !          1105:                if (p) {
        !          1106:                        p++;
        !          1107:                        if (!*p) {
        !          1108:                                /* alert - file name ended in with a / */
        !          1109:                                if (Verbose)
        !          1110:                                        vstringf(_("file name ends with a /, skipped: %s\n"),name);
        !          1111:                                DO_SYSLOG((LOG_ERR,"file name ends with a /, skipped: %s", name));
        !          1112:                                return ERROR;
        !          1113:                        }
        !          1114:                        name=p;
        !          1115:                }
        !          1116:        }
        !          1117:        name_static=malloc(strlen(name)+1);
        !          1118:        if (!name_static)
        !          1119:                error(1,0,_("out of memory"));
        !          1120:        strcpy(name_static,name);
        !          1121:        zi->fname=name_static;
        !          1122: 
        !          1123:        if (Verbose>2) {
        !          1124:                vstringf(_("zmanag=%d, Lzmanag=%d\n"),zmanag,Lzmanag);
        !          1125:                vstringf(_("zconv=%d\n"),zconv);
        !          1126:        }
        !          1127: 
        !          1128:        /* set default parameters and overrides */
        !          1129:        openmode = "w";
        !          1130:        Thisbinary = (!Rxascii) || Rxbinary;
        !          1131:        if (Lzmanag)
        !          1132:                zmanag = Lzmanag;
        !          1133: 
        !          1134:        /*
        !          1135:         *  Process ZMODEM remote file management requests
        !          1136:         */
        !          1137:        if (!Rxbinary && zconv == ZCNL) /* Remote ASCII override */
        !          1138:                Thisbinary = 0;
        !          1139:        if (zconv == ZCBIN)     /* Remote Binary override */
        !          1140:                Thisbinary = TRUE;
        !          1141:        if (Thisbinary && zconv == ZCBIN && try_resume)
        !          1142:                zconv=ZCRESUM;
        !          1143:        if (zmanag == ZF1_ZMAPND && zconv!=ZCRESUM)
        !          1144:                openmode = "a";
        !          1145:        if (skip_if_not_found)
        !          1146:                openmode="r+";
        !          1147: 
        !          1148: #ifdef ENABLE_TIMESYNC
        !          1149:        in_timesync=0;
        !          1150:        if (timesync_flag && 0==strcmp(name,"$time$.t"))
        !          1151:                in_timesync=1;
        !          1152: #endif
        !          1153:        in_tcpsync=0;
        !          1154:        if (tcpsync_flag && 0==strcmp(name,"$tcp$.t"))
        !          1155:                in_tcpsync=1;
        !          1156: 
        !          1157:        zi->bytes_total = DEFBYTL;
        !          1158:        zi->mode = 0; 
        !          1159:        zi->eof_seen = 0; 
        !          1160:        zi->modtime = 0;
        !          1161: 
        !          1162:        nameend = name + 1 + strlen(name);
        !          1163:        if (*nameend) { /* file coming from Unix or DOS system */
        !          1164:                long modtime=0;
        !          1165:                long bytes_total=DEFBYTL;
        !          1166:                int mode=0;
        !          1167:                sscanf(nameend, "%ld%lo%o", &bytes_total, &modtime, &mode);
        !          1168:                zi->modtime=modtime;
        !          1169:                zi->bytes_total=bytes_total;
        !          1170:                zi->mode=mode;
        !          1171:                if (zi->mode & UNIXFILE)
        !          1172:                        ++Thisbinary;
        !          1173:        }
        !          1174: 
        !          1175:        /* Check for existing file */
        !          1176:        if (zconv != ZCRESUM && !Rxclob && (zmanag&ZF1_ZMMASK) != ZF1_ZMCLOB 
        !          1177:                && (zmanag&ZF1_ZMMASK) != ZF1_ZMAPND
        !          1178: #ifdef ENABLE_TIMESYNC
        !          1179:            && !in_timesync
        !          1180:            && !in_tcpsync
        !          1181: #endif
        !          1182:                && (fout=fopen(name, "r"))) {
        !          1183:                struct stat sta;
        !          1184:                char *tmpname;
        !          1185:                char *ptr;
        !          1186:                int i;
        !          1187:                if (zmanag == ZF1_ZMNEW || zmanag==ZF1_ZMNEWL) {
        !          1188:                        if (-1==fstat(fileno(fout),&sta)) {
        !          1189: #ifdef ENABLE_SYSLOG
        !          1190:                                int e=errno;
        !          1191: #endif
        !          1192:                                if (Verbose)
        !          1193:                                        vstringf(_("file exists, skipped: %s\n"),name);
        !          1194:                                DO_SYSLOG((LOG_ERR,"cannot fstat open file %s: %s",
        !          1195:                                        name,strerror(e)));
        !          1196:                                return ERROR;
        !          1197:                        }
        !          1198:                        if (zmanag == ZF1_ZMNEW) {
        !          1199:                                if (sta.st_mtime > zi->modtime) {
        !          1200:                                        DO_SYSLOG((LOG_INFO,"skipping %s: newer file exists", name));
        !          1201:                                        return ERROR; /* skips file */
        !          1202:                                }
        !          1203:                        } else {
        !          1204:                                /* newer-or-longer */
        !          1205:                                if (((size_t) sta.st_size) >= zi->bytes_total 
        !          1206:                                        && sta.st_mtime > zi->modtime) {
        !          1207:                                        DO_SYSLOG((LOG_INFO,"skipping %s: longer+newer file exists", name));
        !          1208:                                        return ERROR; /* skips file */
        !          1209:                                }
        !          1210:                        }
        !          1211:                        fclose(fout);
        !          1212:                } else if (zmanag==ZF1_ZMCRC) {
        !          1213:                        int r=do_crc_check(fout,zi->bytes_total,0);
        !          1214:                        if (r==ERROR) {
        !          1215:                                fclose(fout);
        !          1216:                                return ERROR;
        !          1217:                        }
        !          1218:                        if (r!=ZCRC_DIFFERS) {
        !          1219:                                return ERROR; /* skips */
        !          1220:                        }
        !          1221:                        fclose(fout);
        !          1222:                } else {
        !          1223:                        size_t namelen;
        !          1224:                        fclose(fout);
        !          1225:                        if ((zmanag & ZF1_ZMMASK)!=ZF1_ZMCHNG) {
        !          1226:                                if (Verbose)
        !          1227:                                        vstringf(_("file exists, skipped: %s\n"),name);
        !          1228:                                return ERROR;
        !          1229:                        }
        !          1230:                        /* try to rename */
        !          1231:                        namelen=strlen(name);
        !          1232:                        tmpname=alloca(namelen+5);
        !          1233:                        memcpy(tmpname,name,namelen);
        !          1234:                        ptr=tmpname+namelen;
        !          1235:                        *ptr++='.';
        !          1236:                        i=0;
        !          1237:                        do {
        !          1238:                                sprintf(ptr,"%d",i++);
        !          1239:                        } while (i<1000 && stat(tmpname,&sta)==0);
        !          1240:                        if (i==1000)
        !          1241:                                return ERROR;
        !          1242:                        free(name_static);
        !          1243:                        name_static=malloc(strlen(tmpname)+1);
        !          1244:                        if (!name_static)
        !          1245:                                error(1,0,_("out of memory"));
        !          1246:                        strcpy(name_static,tmpname);
        !          1247:                        zi->fname=name_static;
        !          1248:                }
        !          1249:        }
        !          1250: 
        !          1251:        if (!*nameend) {                /* File coming from CP/M system */
        !          1252:                for (p=name_static; *p; ++p)            /* change / to _ */
        !          1253:                        if ( *p == '/')
        !          1254:                                *p = '_';
        !          1255: 
        !          1256:                if ( *--p == '.')               /* zap trailing period */
        !          1257:                        *p = 0;
        !          1258:        }
        !          1259: 
        !          1260: #ifdef ENABLE_TIMESYNC
        !          1261:        if (in_timesync)
        !          1262:        {
        !          1263:                long t=time(0);
        !          1264:                long d=t-zi->modtime;
        !          1265:                if (d<0)
        !          1266:                        d=0;
        !          1267:                if ((Verbose && d>60) || Verbose > 1)
        !          1268:                        vstringf(_("TIMESYNC: here %ld, remote %ld, diff %ld seconds\n"),
        !          1269:                        (long) t, (long) zi->modtime, d);
        !          1270: #ifdef HAVE_SETTIMEOFDAY
        !          1271:                if (timesync_flag > 1 && d > 10)
        !          1272:                {
        !          1273:                        struct timeval tv;
        !          1274:                        tv.tv_sec=zi->modtime;
        !          1275:                        tv.tv_usec=0;
        !          1276:                        if (settimeofday(&tv,NULL))
        !          1277:                                vstringf(_("TIMESYNC: cannot set time: %s\n"),
        !          1278:                                        strerror(errno));
        !          1279:                }
        !          1280: #endif
        !          1281:                return ERROR; /* skips file */
        !          1282:        }
        !          1283: #endif /* ENABLE_TIMESYNC */
        !          1284:        if (in_tcpsync) {
        !          1285:                fout=tmpfile();
        !          1286:                if (!fout) {
        !          1287:                        error(1,errno,_("cannot tmpfile() for tcp protocol synchronization"));
        !          1288:                }
        !          1289:                zi->bytes_received=0;
        !          1290:                return OK;
        !          1291:        }
        !          1292: 
        !          1293: 
        !          1294:        if (!zmodem_requested && MakeLCPathname && !IsAnyLower(name_static)
        !          1295:          && !(zi->mode&UNIXFILE))
        !          1296:                uncaps(name_static);
        !          1297:        if (Topipe > 0) {
        !          1298:                if (Pathname)
        !          1299:                        free(Pathname);
        !          1300:                Pathname=malloc((PATH_MAX)*2);
        !          1301:                if (!Pathname)
        !          1302:                        error(1,0,_("out of memory"));
        !          1303:                sprintf(Pathname, "%s %s", program_name+2, name_static);
        !          1304:                if (Verbose) {
        !          1305:                        vstringf("%s: %s %s\n",
        !          1306:                                _("Topipe"),
        !          1307:                                Pathname, Thisbinary?"BIN":"ASCII");
        !          1308:                }
        !          1309:                if ((fout=popen(Pathname, "w")) == NULL)
        !          1310:                        return ERROR;
        !          1311:        } else {
        !          1312:                if (protocol==ZM_XMODEM)
        !          1313:                        /* we don't have the filename yet */
        !          1314:                        return OK; /* dummy */
        !          1315:                if (Pathname)
        !          1316:                        free(Pathname);
        !          1317:                Pathname=malloc((PATH_MAX)*2);
        !          1318:                if (!Pathname)
        !          1319:                        error(1,0,_("out of memory"));
        !          1320:                strcpy(Pathname, name_static);
        !          1321:                if (Verbose) {
        !          1322:                        /* overwrite the "waiting to receive" line */
        !          1323:                        vstring("\r                                                                     \r");
        !          1324:                        vstringf(_("Receiving: %s\n"), name_static);
        !          1325:                }
        !          1326:                checkpath(name_static);
        !          1327:                if (Nflag)
        !          1328:                {
        !          1329:                        /* cast because we might not have a prototyp for strdup :-/ */
        !          1330:                        free(name_static);
        !          1331:                        name_static=(char *) strdup("/dev/null");
        !          1332:                        if (!name_static)
        !          1333:                        {
        !          1334:                                fprintf(stderr,"%s: %s\n", program_name, _("out of memory"));
        !          1335:                                exit(1);
        !          1336:                        }
        !          1337:                }
        !          1338: #ifdef OMEN
        !          1339:                /* looks like a security hole -- uwe */
        !          1340:                if (name_static[0] == '!' || name_static[0] == '|') {
        !          1341:                        if ( !(fout = popen(name_static+1, "w"))) {
        !          1342:                                return ERROR;
        !          1343:                        }
        !          1344:                        Topipe = -1;  return(OK);
        !          1345:                }
        !          1346: #endif
        !          1347:                if (Thisbinary && zconv==ZCRESUM) {
        !          1348:                        struct stat st;
        !          1349:                        fout = fopen(name_static, "r+");
        !          1350:                        if (fout && 0==fstat(fileno(fout),&st))
        !          1351:                        {
        !          1352:                                int can_resume=TRUE;
        !          1353:                                if (zmanag==ZF1_ZMCRC) {
        !          1354:                                        int r=do_crc_check(fout,zi->bytes_total,st.st_size);
        !          1355:                                        if (r==ERROR) {
        !          1356:                                                fclose(fout);
        !          1357:                                                return ZFERR;
        !          1358:                                        }
        !          1359:                                        if (r==ZCRC_DIFFERS) {
        !          1360:                                                can_resume=FALSE;
        !          1361:                                        }
        !          1362:                                }
        !          1363:                                if ((unsigned long)st.st_size > zi->bytes_total) {
        !          1364:                                        can_resume=FALSE;
        !          1365:                                }
        !          1366:                                /* retransfer whole blocks */
        !          1367:                                zi->bytes_skipped = st.st_size & ~(1023);
        !          1368:                                if (can_resume) {
        !          1369:                                        if (fseek(fout, (long) zi->bytes_skipped, SEEK_SET)) {
        !          1370:                                                fclose(fout);
        !          1371:                                                return ZFERR;
        !          1372:                                        }
        !          1373:                                }
        !          1374:                                else
        !          1375:                                        zi->bytes_skipped=0; /* resume impossible, file has changed */
        !          1376:                                goto buffer_it;
        !          1377:                        }
        !          1378:                        zi->bytes_skipped=0;
        !          1379:                        if (fout)
        !          1380:                                fclose(fout);
        !          1381:                }
        !          1382:                fout = fopen(name_static, openmode);
        !          1383: #ifdef ENABLE_MKDIR
        !          1384:                if ( !fout && Restricted < 2) {
        !          1385:                        if (make_dirs(name_static))
        !          1386:                                fout = fopen(name_static, openmode);
        !          1387:                }
        !          1388: #endif
        !          1389:                if ( !fout)
        !          1390:                {
        !          1391: #ifdef ENABLE_SYSLOG
        !          1392:                        int e=errno;
        !          1393: #endif
        !          1394:                        zpfatal(_("cannot open %s"), name_static);
        !          1395:                        DO_SYSLOG((LOG_ERR,"%s: cannot open: %s",
        !          1396:                                protname(),strerror(e)));
        !          1397:                        return ERROR;
        !          1398:                }
        !          1399:        }
        !          1400: buffer_it:
        !          1401:        if (Topipe == 0) {
        !          1402:                static char *s=NULL;
        !          1403:                static size_t last_length=0;
        !          1404: #if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)
        !          1405:                if (o_sync) {
        !          1406:                        int oldflags;
        !          1407:                        oldflags = fcntl (fileno(fout), F_GETFD, 0);
        !          1408:                        if (oldflags>=0 && !(oldflags & O_SYNC)) {
        !          1409:                                oldflags|=O_SYNC;
        !          1410:                                fcntl (fileno(fout), F_SETFD, oldflags); /* errors don't matter */
        !          1411:                        }
        !          1412:                }
        !          1413: #endif
        !          1414: 
        !          1415:                if (buffersize==-1 && s) {
        !          1416:                        if (zi->bytes_total>last_length) {
        !          1417:                                free(s);
        !          1418:                                s=NULL;
        !          1419:                                last_length=0;
        !          1420:                        }
        !          1421:                }
        !          1422:                if (!s && buffersize) {
        !          1423:                        last_length=32768;
        !          1424:                        if (buffersize==-1) {
        !          1425:                                if (zi->bytes_total>0)
        !          1426:                                        last_length=zi->bytes_total;
        !          1427:                        } else 
        !          1428:                                last_length=buffersize;
        !          1429:                        /* buffer `4096' bytes pages */
        !          1430:                        last_length=(last_length+4095)&0xfffff000;
        !          1431:                        s=malloc(last_length);
        !          1432:                        if (!s) {
        !          1433:                                zpfatal(_("out of memory"));
        !          1434:                                exit(1);
        !          1435:                        }
        !          1436:                }
        !          1437:                if (s) {
        !          1438: #ifdef SETVBUF_REVERSED
        !          1439:                        setvbuf(fout,_IOFBF,s,last_length);
        !          1440: #else
        !          1441:                        setvbuf(fout,s,_IOFBF,last_length);
        !          1442: #endif
        !          1443:                }
        !          1444:        }
        !          1445:        zi->bytes_received=zi->bytes_skipped;
        !          1446: 
        !          1447:        return OK;
        !          1448: }
        !          1449: 
        !          1450: #ifdef ENABLE_MKDIR
        !          1451: /*
        !          1452:  *  Directory-creating routines from Public Domain TAR by John Gilmore
        !          1453:  */
        !          1454: 
        !          1455: /*
        !          1456:  * After a file/link/symlink/dir creation has failed, see if
        !          1457:  * it's because some required directory was not present, and if
        !          1458:  * so, create all required dirs.
        !          1459:  */
        !          1460: static int
        !          1461: make_dirs(char *pathname)
        !          1462: {
        !          1463:        register char *p;               /* Points into path */
        !          1464:        int madeone = 0;                /* Did we do anything yet? */
        !          1465:        int save_errno = errno;         /* Remember caller's errno */
        !          1466: 
        !          1467:        if (errno != ENOENT)
        !          1468:                return 0;               /* Not our problem */
        !          1469: 
        !          1470:        for (p = strchr(pathname, '/'); p != NULL; p = strchr(p+1, '/')) {
        !          1471:                /* Avoid mkdir of empty string, if leading or double '/' */
        !          1472:                if (p == pathname || p[-1] == '/')
        !          1473:                        continue;
        !          1474:                /* Avoid mkdir where last part of path is '.' */
        !          1475:                if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
        !          1476:                        continue;
        !          1477:                *p = 0;                         /* Truncate the path there */
        !          1478:                if ( !mkdir(pathname, 0777)) {  /* Try to create it as a dir */
        !          1479:                        vfile("Made directory %s\n", pathname);
        !          1480:                        madeone++;              /* Remember if we made one */
        !          1481:                        *p = '/';
        !          1482:                        continue;
        !          1483:                }
        !          1484:                *p = '/';
        !          1485:                if (errno == EEXIST)            /* Directory already exists */
        !          1486:                        continue;
        !          1487:                /*
        !          1488:                 * Some other error in the mkdir.  We return to the caller.
        !          1489:                 */
        !          1490:                break;
        !          1491:        }
        !          1492:        errno = save_errno;             /* Restore caller's errno */
        !          1493:        return madeone;                 /* Tell them to retry if we made one */
        !          1494: }
        !          1495: 
        !          1496: #endif /* ENABLE_MKDIR */
        !          1497: 
        !          1498: /*
        !          1499:  * Putsec writes the n characters of buf to receive file fout.
        !          1500:  *  If not in binary mode, carriage returns, and all characters
        !          1501:  *  starting with CPMEOF are discarded.
        !          1502:  */
        !          1503: static int 
        !          1504: putsec(struct zm_fileinfo *zi, char *buf, size_t n)
        !          1505: {
        !          1506:        register char *p;
        !          1507: 
        !          1508:        if (n == 0)
        !          1509:                return OK;
        !          1510:        if (Thisbinary) {
        !          1511:                if (fwrite(buf,n,1,fout)!=1)
        !          1512:                        return ERROR;
        !          1513:        }
        !          1514:        else {
        !          1515:                if (zi->eof_seen)
        !          1516:                        return OK;
        !          1517:                for (p=buf; n>0; ++p,n-- ) {
        !          1518:                        if ( *p == '\r')
        !          1519:                                continue;
        !          1520:                        if (*p == CPMEOF) {
        !          1521:                                zi->eof_seen=TRUE;
        !          1522:                                return OK;
        !          1523:                        }
        !          1524:                        putc(*p ,fout);
        !          1525:                }
        !          1526:        }
        !          1527:        return OK;
        !          1528: }
        !          1529: 
        !          1530: /* make string s lower case */
        !          1531: static void
        !          1532: uncaps(char *s)
        !          1533: {
        !          1534:        for ( ; *s; ++s)
        !          1535:                if (isupper((unsigned char)(*s)))
        !          1536:                        *s = tolower(*s);
        !          1537: }
        !          1538: /*
        !          1539:  * IsAnyLower returns TRUE if string s has lower case letters.
        !          1540:  */
        !          1541: static int 
        !          1542: IsAnyLower(const char *s)
        !          1543: {
        !          1544:        for ( ; *s; ++s)
        !          1545:                if (islower((unsigned char)(*s)))
        !          1546:                        return TRUE;
        !          1547:        return FALSE;
        !          1548: }
        !          1549: 
        !          1550: static void
        !          1551: report(int sct)
        !          1552: {
        !          1553:        if (Verbose>1)
        !          1554:        {
        !          1555:                vstringf(_("Blocks received: %d"),sct);
        !          1556:                vchar('\r');
        !          1557:        }
        !          1558: }
        !          1559: 
        !          1560: /*
        !          1561:  * If called as [-][dir/../]vrzCOMMAND set Verbose to 1
        !          1562:  * If called as [-][dir/../]rzCOMMAND set the pipe flag
        !          1563:  * If called as rb use YMODEM protocol
        !          1564:  */
        !          1565: static void
        !          1566: chkinvok(const char *s)
        !          1567: {
        !          1568:        const char *p;
        !          1569: 
        !          1570:        p = s;
        !          1571:        while (*p == '-')
        !          1572:                s = ++p;
        !          1573:        while (*p)
        !          1574:                if (*p++ == '/')
        !          1575:                        s = p;
        !          1576:        if (*s == 'v') {
        !          1577:                Verbose=1; ++s;
        !          1578:        }
        !          1579:        program_name = s;
        !          1580:        if (*s == 'l') 
        !          1581:                s++; /* lrz -> rz */
        !          1582:        protocol=ZM_ZMODEM;
        !          1583:        if (s[0]=='r' && s[1]=='x')
        !          1584:                protocol=ZM_XMODEM;
        !          1585:        if (s[0]=='r' && (s[1]=='b' || s[1]=='y'))
        !          1586:                protocol=ZM_YMODEM;
        !          1587:        if (s[2] && protocol!=ZM_XMODEM)
        !          1588:                Topipe = 1;
        !          1589: }
        !          1590: 
        !          1591: /*
        !          1592:  * Totalitarian Communist pathname processing
        !          1593:  */
        !          1594: static void 
        !          1595: checkpath(const char *name)
        !          1596: {
        !          1597:        if (Restricted) {
        !          1598:                const char *p;
        !          1599:                p=strrchr(name,'/');
        !          1600:                if (p)
        !          1601:                        p++;
        !          1602:                else
        !          1603:                        p=name;
        !          1604:                /* don't overwrite any file in very restricted mode.
        !          1605:                 * don't overwrite hidden files in restricted mode */
        !          1606:                if ((Restricted==2 || *name=='.') && fopen(name, "r") != NULL) {
        !          1607:                        canit(STDOUT_FILENO);
        !          1608:                        vstring("\r\n");
        !          1609:                        vstringf(_("%s: %s exists\n"), 
        !          1610:                                program_name, name);
        !          1611:                        bibi(-1);
        !          1612:                }
        !          1613:                /* restrict pathnames to current tree or uucppublic */
        !          1614:                if ( strstr(name, "../")
        !          1615: #ifdef PUBDIR
        !          1616:                 || (name[0]== '/' && strncmp(name, PUBDIR, 
        !          1617:                        strlen(PUBDIR)))
        !          1618: #endif
        !          1619:                ) {
        !          1620:                        canit(STDOUT_FILENO);
        !          1621:                        vstring("\r\n");
        !          1622:                        vstringf(_("%s:\tSecurity Violation"),program_name);
        !          1623:                        vstring("\r\n");
        !          1624:                        bibi(-1);
        !          1625:                }
        !          1626:                if (Restricted > 1) {
        !          1627:                        if (name[0]=='.' || strstr(name,"/.")) {
        !          1628:                                canit(STDOUT_FILENO);
        !          1629:                                vstring("\r\n");
        !          1630:                                vstringf(_("%s:\tSecurity Violation"),program_name);
        !          1631:                                vstring("\r\n");
        !          1632:                                bibi(-1);
        !          1633:                        }
        !          1634:                }
        !          1635:        }
        !          1636: }
        !          1637: 
        !          1638: /*
        !          1639:  * Initialize for Zmodem receive attempt, try to activate Zmodem sender
        !          1640:  *  Handles ZSINIT frame
        !          1641:  *  Return ZFILE if Zmodem filename received, -1 on error,
        !          1642:  *   ZCOMPL if transaction finished,  else 0
        !          1643:  */
        !          1644: static int
        !          1645: tryz(void)
        !          1646: {
        !          1647:        register int c, n;
        !          1648:        register int cmdzack1flg;
        !          1649:        int zrqinits_received=0;
        !          1650:        size_t bytes_in_block=0;
        !          1651: 
        !          1652:        if (protocol!=ZM_ZMODEM)                /* Check for "rb" program name */
        !          1653:                return 0;
        !          1654: 
        !          1655:        for (n=zmodem_requested?15:5; 
        !          1656:                 (--n + zrqinits_received) >=0 && zrqinits_received<10; ) {
        !          1657:                /* Set buffer length (0) and capability flags */
        !          1658: #ifdef SEGMENTS
        !          1659:                stohdr(SEGMENTS*MAX_BLOCK);
        !          1660: #else
        !          1661:                stohdr(0L);
        !          1662: #endif
        !          1663: #ifdef CANBREAK
        !          1664:                Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
        !          1665: #else
        !          1666:                Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
        !          1667: #endif
        !          1668: #ifdef ENABLE_TIMESYNC
        !          1669:                if (timesync_flag)
        !          1670:                        Txhdr[ZF1] |= ZF1_TIMESYNC;
        !          1671: #endif
        !          1672:                if (Zctlesc)
        !          1673:                        Txhdr[ZF0] |= TESCCTL; /* TESCCTL == ESCCTL */
        !          1674:                zshhdr(tryzhdrtype, Txhdr);
        !          1675: 
        !          1676:                if (tcp_socket==-1 && *tcp_buf) {
        !          1677:                        /* we need to switch to tcp mode */
        !          1678:                        tcp_socket=tcp_connect(tcp_buf);
        !          1679:                        tcp_buf[0]=0;
        !          1680:                        dup2(tcp_socket,0);
        !          1681:                        dup2(tcp_socket,1);
        !          1682:                }
        !          1683:                if (tryzhdrtype == ZSKIP)       /* Don't skip too far */
        !          1684:                        tryzhdrtype = ZRINIT;   /* CAF 8-21-87 */
        !          1685: again:
        !          1686:                switch (zgethdr(Rxhdr, 0, NULL)) {
        !          1687:                case ZRQINIT:
        !          1688:                        /* getting one ZRQINIT is totally ok. Normally a ZFILE follows 
        !          1689:                         * (and might be in our buffer, so don't purge it). But if we
        !          1690:                         * get more ZRQINITs than the sender has started up before us
        !          1691:                         * and sent ZRQINITs while waiting. 
        !          1692:                         */
        !          1693:                        zrqinits_received++;
        !          1694:                        continue;
        !          1695:                
        !          1696:                case ZEOF:
        !          1697:                        continue;
        !          1698:                case TIMEOUT:
        !          1699:                        continue;
        !          1700:                case ZFILE:
        !          1701:                        zconv = Rxhdr[ZF0];
        !          1702:                        if (!zconv)
        !          1703:                                /* resume with sz -r is impossible (at least with unix sz)
        !          1704:                                 * if this is not set */
        !          1705:                                zconv=ZCBIN;
        !          1706:                        if (Rxhdr[ZF1] & ZF1_ZMSKNOLOC) {
        !          1707:                                Rxhdr[ZF1] &= ~(ZF1_ZMSKNOLOC);
        !          1708:                                skip_if_not_found=TRUE;
        !          1709:                        }
        !          1710:                        zmanag = Rxhdr[ZF1];
        !          1711:                        ztrans = Rxhdr[ZF2];
        !          1712:                        tryzhdrtype = ZRINIT;
        !          1713:                        c = zrdata(secbuf, MAX_BLOCK,&bytes_in_block);
        !          1714:                        io_mode(0,3);
        !          1715:                        if (c == GOTCRCW)
        !          1716:                                return ZFILE;
        !          1717:                        zshhdr(ZNAK, Txhdr);
        !          1718:                        goto again;
        !          1719:                case ZSINIT:
        !          1720:                        /* this once was:
        !          1721:                         * Zctlesc = TESCCTL & Rxhdr[ZF0];
        !          1722:                         * trouble: if rz get --escape flag:
        !          1723:                         * - it sends TESCCTL to sz, 
        !          1724:                         *   get a ZSINIT _without_ TESCCTL (yeah - sender didn't know), 
        !          1725:                         *   overwrites Zctlesc flag ...
        !          1726:                         * - sender receives TESCCTL and uses "|=..."
        !          1727:                         * so: sz escapes, but rz doesn't unescape ... not good.
        !          1728:                         */
        !          1729:                        Zctlesc |= TESCCTL & Rxhdr[ZF0];
        !          1730:                        if (zrdata(Attn, ZATTNLEN,&bytes_in_block) == GOTCRCW) {
        !          1731:                                stohdr(1L);
        !          1732:                                zshhdr(ZACK, Txhdr);
        !          1733:                                goto again;
        !          1734:                        }
        !          1735:                        zshhdr(ZNAK, Txhdr);
        !          1736:                        goto again;
        !          1737:                case ZFREECNT:
        !          1738:                        stohdr(getfree());
        !          1739:                        zshhdr(ZACK, Txhdr);
        !          1740:                        goto again;
        !          1741:                case ZCOMMAND:
        !          1742:                        cmdzack1flg = Rxhdr[ZF0];
        !          1743:                        if (zrdata(secbuf, MAX_BLOCK,&bytes_in_block) == GOTCRCW) {
        !          1744:                                if (Verbose)
        !          1745:                                {
        !          1746:                                        vstringf("%s: %s\n", program_name,
        !          1747:                                                _("remote command execution requested"));
        !          1748:                                        vstringf("%s: %s\n", program_name, secbuf);
        !          1749:                                }
        !          1750:                                if (!allow_remote_commands) 
        !          1751:                                {
        !          1752:                                        if (Verbose)
        !          1753:                                                vstringf("%s: %s\n", program_name, 
        !          1754:                                                        _("not executed"));
        !          1755:                                        zshhdr(ZCOMPL, Txhdr);
        !          1756:                                        DO_SYSLOG((LOG_INFO,"rexec denied: %s",secbuf));
        !          1757:                                        return ZCOMPL;
        !          1758:                                }
        !          1759:                                DO_SYSLOG((LOG_INFO,"rexec allowed: %s",secbuf));
        !          1760:                                if (cmdzack1flg & ZCACK1)
        !          1761:                                        stohdr(0L);
        !          1762:                                else
        !          1763:                                        stohdr((size_t)sys2(secbuf));
        !          1764:                                purgeline(0);   /* dump impatient questions */
        !          1765:                                do {
        !          1766:                                        zshhdr(ZCOMPL, Txhdr);
        !          1767:                                }
        !          1768:                                while (++errors<20 && zgethdr(Rxhdr,1, NULL) != ZFIN);
        !          1769:                                ackbibi();
        !          1770:                                if (cmdzack1flg & ZCACK1)
        !          1771:                                        exec2(secbuf);
        !          1772:                                return ZCOMPL;
        !          1773:                        }
        !          1774:                        zshhdr(ZNAK, Txhdr);
        !          1775:                        goto again;
        !          1776:                case ZCOMPL:
        !          1777:                        goto again;
        !          1778:                default:
        !          1779:                        continue;
        !          1780:                case ZFIN:
        !          1781:                        ackbibi();
        !          1782:                        return ZCOMPL;
        !          1783:                case ZRINIT:
        !          1784:                        if (Verbose)
        !          1785:                                vstringf(_("got ZRINIT"));
        !          1786:                        return ERROR;
        !          1787:                case ZCAN:
        !          1788:                        if (Verbose)
        !          1789:                                vstringf(_("got ZCAN"));
        !          1790:                        return ERROR;
        !          1791:                }
        !          1792:        }
        !          1793:        return 0;
        !          1794: }
        !          1795: 
        !          1796: 
        !          1797: /*
        !          1798:  * Receive 1 or more files with ZMODEM protocol
        !          1799:  */
        !          1800: static int
        !          1801: rzfiles(struct zm_fileinfo *zi)
        !          1802: {
        !          1803:        register int c;
        !          1804: 
        !          1805:        for (;;) {
        !          1806:                timing(1,NULL);
        !          1807:                c = rzfile(zi);
        !          1808:                switch (c) {
        !          1809:                case ZEOF:
        !          1810:                        if (Verbose > 1
        !          1811: #ifdef ENABLE_SYSLOG
        !          1812:                                || enable_syslog
        !          1813: #endif
        !          1814:                        ) {
        !          1815:                                double d;
        !          1816:                                long bps;
        !          1817:                                d=timing(0,NULL);
        !          1818:                                if (d==0)
        !          1819:                                        d=0.5; /* can happen if timing uses time() */
        !          1820:                                bps=(zi->bytes_received-zi->bytes_skipped)/d;
        !          1821:                                if (Verbose > 1) {
        !          1822:                                        vstringf(
        !          1823:                                                _("\rBytes received: %7ld/%7ld   BPS:%-6ld                \r\n"),
        !          1824:                                                (long) zi->bytes_received, (long) zi->bytes_total, bps);
        !          1825:                                }
        !          1826:                                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: %ld Bytes, %ld BPS",shortname,
        !          1827:                                                   protname(), (long) zi->bytes_total,bps));
        !          1828:                        }
        !          1829:                        /* FALL THROUGH */
        !          1830:                case ZSKIP:
        !          1831:                        if (c==ZSKIP)
        !          1832:                        {
        !          1833:                                if (Verbose) 
        !          1834:                                        vstringf(_("Skipped"));
        !          1835:                                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: skipped",shortname,protname()));
        !          1836:                        }
        !          1837:                        switch (tryz()) {
        !          1838:                        case ZCOMPL:
        !          1839:                                return OK;
        !          1840:                        default:
        !          1841:                                return ERROR;
        !          1842:                        case ZFILE:
        !          1843:                                break;
        !          1844:                        }
        !          1845:                        continue;
        !          1846:                default:
        !          1847:                        return c;
        !          1848:                case ERROR:
        !          1849:                        DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error",shortname,protname()));
        !          1850:                        return ERROR;
        !          1851:                }
        !          1852:        }
        !          1853: }
        !          1854: 
        !          1855: /* "OOSB" means Out Of Sync Block. I once thought that if sz sents
        !          1856:  * blocks a,b,c,d, of which a is ok, b fails, we might want to save 
        !          1857:  * c and d. But, alas, i never saw c and d.
        !          1858:  */
        !          1859: #define SAVE_OOSB
        !          1860: #ifdef SAVE_OOSB
        !          1861: typedef struct oosb_t {
        !          1862:        size_t pos;
        !          1863:        size_t len;
        !          1864:        char *data;
        !          1865:        struct oosb_t *next;
        !          1866: } oosb_t;
        !          1867: struct oosb_t *anker=NULL;
        !          1868: #endif
        !          1869: 
        !          1870: /*
        !          1871:  * Receive a file with ZMODEM protocol
        !          1872:  *  Assumes file name frame is in secbuf
        !          1873:  */
        !          1874: static int
        !          1875: rzfile(struct zm_fileinfo *zi)
        !          1876: {
        !          1877:        register int c, n;
        !          1878:        long last_rxbytes=0;
        !          1879:        unsigned long last_bps=0;
        !          1880:        long not_printed=0;
        !          1881:        time_t low_bps=0;
        !          1882:        size_t bytes_in_block=0;
        !          1883: 
        !          1884:        zi->eof_seen=FALSE;
        !          1885: 
        !          1886:        n = 20;
        !          1887: 
        !          1888:        if (procheader(secbuf,zi) == ERROR) {
        !          1889:                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: procheader error",
        !          1890:                                   shortname,protname()));
        !          1891:                return (tryzhdrtype = ZSKIP);
        !          1892:        }
        !          1893: 
        !          1894:        for (;;) {
        !          1895: #ifdef SEGMENTS
        !          1896:                chinseg = 0;
        !          1897: #endif
        !          1898:                stohdr(zi->bytes_received);
        !          1899:                zshhdr(ZRPOS, Txhdr);
        !          1900:                goto skip_oosb;
        !          1901: nxthdr:
        !          1902: #ifdef SAVE_OOSB
        !          1903:                if (anker) {
        !          1904:                        oosb_t *akt,*last,*next;
        !          1905:                        for (akt=anker,last=NULL;akt;last= akt ? akt : last ,akt=next) {
        !          1906:                                if (akt->pos==zi->bytes_received) {
        !          1907:                                        putsec(zi, akt->data, akt->len);
        !          1908:                                        zi->bytes_received += akt->len;
        !          1909:                                        vfile("using saved out-of-sync-paket %lx, len %ld",
        !          1910:                                                  akt->pos,akt->len);
        !          1911:                                        goto nxthdr;
        !          1912:                                }
        !          1913:                                next=akt->next;
        !          1914:                                if (akt->pos<zi->bytes_received) {
        !          1915:                                        vfile("removing unneeded saved out-of-sync-paket %lx, len %ld",
        !          1916:                                                  akt->pos,akt->len);
        !          1917:                                        if (last)
        !          1918:                                                last->next=akt->next;
        !          1919:                                        else
        !          1920:                                                anker=akt->next;
        !          1921:                                        free(akt->data);
        !          1922:                                        free(akt);
        !          1923:                                        akt=NULL;
        !          1924:                                }
        !          1925:                        }
        !          1926:                }
        !          1927: #endif
        !          1928:        skip_oosb:
        !          1929:                c = zgethdr(Rxhdr, 0, NULL);
        !          1930:                switch (c) {
        !          1931:                default:
        !          1932:                        DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: zgethdr returned %d",shortname,
        !          1933:                                           protname(),c));
        !          1934:                        vfile("rzfile: zgethdr returned %d", c);
        !          1935:                        return ERROR;
        !          1936:                case ZNAK:
        !          1937:                case TIMEOUT:
        !          1938: #ifdef SEGMENTS
        !          1939:                        putsec(secbuf, chinseg);
        !          1940:                        chinseg = 0;
        !          1941: #endif
        !          1942:                        if ( --n < 0) {
        !          1943:                                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: zgethdr returned %s",shortname,
        !          1944:                                           protname(),c == ZNAK ? "ZNAK" : "TIMEOUT"));
        !          1945:                                vfile("rzfile: zgethdr returned %d", c);
        !          1946:                                return ERROR;
        !          1947:                        }
        !          1948:                case ZFILE:
        !          1949:                        zrdata(secbuf, MAX_BLOCK,&bytes_in_block);
        !          1950:                        continue;
        !          1951:                case ZEOF:
        !          1952: #ifdef SEGMENTS
        !          1953:                        putsec(secbuf, chinseg);
        !          1954:                        chinseg = 0;
        !          1955: #endif
        !          1956:                        if (rclhdr(Rxhdr) != (long) zi->bytes_received) {
        !          1957:                                /*
        !          1958:                                 * Ignore eof if it's at wrong place - force
        !          1959:                                 *  a timeout because the eof might have gone
        !          1960:                                 *  out before we sent our zrpos.
        !          1961:                                 */
        !          1962:                                errors = 0;  goto nxthdr;
        !          1963:                        }
        !          1964:                        if (closeit(zi)) {
        !          1965:                                tryzhdrtype = ZFERR;
        !          1966:                                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: closeit return <>0",
        !          1967:                                                   shortname, protname()));
        !          1968:                                vfile("rzfile: closeit returned <> 0");
        !          1969:                                return ERROR;
        !          1970:                        }
        !          1971:                        vfile("rzfile: normal EOF");
        !          1972:                        return c;
        !          1973:                case ERROR:     /* Too much garbage in header search error */
        !          1974: #ifdef SEGMENTS
        !          1975:                        putsec(secbuf, chinseg);
        !          1976:                        chinseg = 0;
        !          1977: #endif
        !          1978:                        if ( --n < 0) {
        !          1979:                                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: zgethdr returned %d",
        !          1980:                                                   shortname, protname(),c));
        !          1981:                                vfile("rzfile: zgethdr returned %d", c);
        !          1982:                                return ERROR;
        !          1983:                        }
        !          1984:                        zmputs(Attn);
        !          1985:                        continue;
        !          1986:                case ZSKIP:
        !          1987: #ifdef SEGMENTS
        !          1988:                        putsec(secbuf, chinseg);
        !          1989:                        chinseg = 0;
        !          1990: #endif
        !          1991:                        closeit(zi);
        !          1992:                        DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: sender skipped",
        !          1993:                                           shortname, protname()));
        !          1994:                        vfile("rzfile: Sender SKIPPED file");
        !          1995:                        return c;
        !          1996:                case ZDATA:
        !          1997:                        if (rclhdr(Rxhdr) != (long) zi->bytes_received) {
        !          1998: #if defined(SAVE_OOSB)
        !          1999:                                oosb_t *neu;
        !          2000:                                size_t pos=rclhdr(Rxhdr);
        !          2001: #endif
        !          2002:                                if ( --n < 0) {
        !          2003:                                        vfile("rzfile: out of sync");
        !          2004:                                        DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: out of sync",
        !          2005:                                           shortname, protname()));
        !          2006:                                        return ERROR;
        !          2007:                                }
        !          2008: #if defined(SAVE_OOSB)
        !          2009:                                switch (c = zrdata(secbuf, MAX_BLOCK,&bytes_in_block))
        !          2010:                                {
        !          2011:                                case GOTCRCW:
        !          2012:                                case GOTCRCG:
        !          2013:                                case GOTCRCE:
        !          2014:                                case GOTCRCQ:
        !          2015:                                        if (pos>zi->bytes_received) {
        !          2016:                                                neu=malloc(sizeof(oosb_t));
        !          2017:                                                if (neu)
        !          2018:                                                        neu->data=malloc(bytes_in_block);
        !          2019:                                                if (neu && neu->data) {
        !          2020: #ifdef ENABLE_SYSLOG
        !          2021: /* call syslog to tell me if this happens */
        !          2022:                                                        lsyslog(LOG_ERR, 
        !          2023:                                                                   "saving out-of-sync-block %lx, len %lu",
        !          2024:                                                                   pos, (unsigned long) bytes_in_block);
        !          2025: #endif
        !          2026:                                                        vfile("saving out-of-sync-block %lx, len %lu",pos,
        !          2027:                                                                  (unsigned long) bytes_in_block);
        !          2028:                                                        memcpy(neu->data,secbuf,bytes_in_block);
        !          2029:                                                        neu->pos=pos;
        !          2030:                                                        neu->len=bytes_in_block;
        !          2031:                                                        neu->next=anker;
        !          2032:                                                        anker=neu;
        !          2033:                                                }
        !          2034:                                                else if (neu)
        !          2035:                                                        free(neu);
        !          2036:                                        }
        !          2037:                                }
        !          2038: #endif
        !          2039: #ifdef SEGMENTS
        !          2040:                                putsec(secbuf, chinseg);
        !          2041:                                chinseg = 0;
        !          2042: #endif
        !          2043:                                zmputs(Attn);  continue;
        !          2044:                        }
        !          2045: moredata:
        !          2046:                        if ((Verbose>1 || min_bps || stop_time)
        !          2047:                                && (not_printed > (min_bps ? 3 : 7) 
        !          2048:                                        || zi->bytes_received > last_bps / 2 + last_rxbytes)) {
        !          2049:                                int minleft =  0;
        !          2050:                                int secleft =  0;
        !          2051:                                time_t now;
        !          2052:                                double d;
        !          2053:                                d=timing(0,&now);
        !          2054:                                if (d==0)
        !          2055:                                        d=0.5; /* timing() might use time() */
        !          2056:                                last_bps=zi->bytes_received/d;
        !          2057:                                if (last_bps > 0) {
        !          2058:                                        minleft =  (R_BYTESLEFT(zi))/last_bps/60;
        !          2059:                                        secleft =  ((R_BYTESLEFT(zi))/last_bps)%60;
        !          2060:                                }
        !          2061:                                if (min_bps) {
        !          2062:                                        if (low_bps) {
        !          2063:                                                if (last_bps<min_bps) {
        !          2064:                                                        if (now-low_bps>=min_bps_time) {
        !          2065:                                                                /* too bad */
        !          2066:                                                                vfile(_("rzfile: bps rate %ld below min %ld"), 
        !          2067:                                                                          last_bps, min_bps);
        !          2068:                                                                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: bps rate low: %ld < %ld",
        !          2069:                                                                                   shortname, protname(), last_bps, min_bps));
        !          2070:                                                                return ERROR;
        !          2071:                                                        }
        !          2072:                                                }
        !          2073:                                                else
        !          2074:                                                        low_bps=0;
        !          2075:                                        } else if (last_bps<min_bps) {
        !          2076:                                                low_bps=now;
        !          2077:                                        }
        !          2078:                                }
        !          2079:                                if (stop_time && now>=stop_time) {
        !          2080:                                        /* too bad */
        !          2081:                                        vfile(_("rzfile: reached stop time"));
        !          2082:                                        DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: reached stop time",
        !          2083:                                                           shortname, protname()));
        !          2084:                                        return ERROR;
        !          2085:                                }
        !          2086:                                
        !          2087:                                if (Verbose > 1) {
        !          2088:                                        vstringf(_("\rBytes received: %7ld/%7ld   BPS:%-6ld ETA %02d:%02d  "),
        !          2089:                                                (long) zi->bytes_received, (long) zi->bytes_total, 
        !          2090:                                                last_bps, minleft, secleft);
        !          2091:                                        last_rxbytes=zi->bytes_received;
        !          2092:                                        not_printed=0;
        !          2093:                                }
        !          2094:                        } else if (Verbose)
        !          2095:                                not_printed++;
        !          2096: #ifdef SEGMENTS
        !          2097:                        if (chinseg >= (MAX_BLOCK * SEGMENTS)) {
        !          2098:                                putsec(secbuf, chinseg);
        !          2099:                                chinseg = 0;
        !          2100:                        }
        !          2101:                        switch (c = zrdata(secbuf+chinseg, MAX_BLOCK,&bytes_in_block))
        !          2102: #else
        !          2103:                        switch (c = zrdata(secbuf, MAX_BLOCK,&bytes_in_block))
        !          2104: #endif
        !          2105:                        {
        !          2106:                        case ZCAN:
        !          2107: #ifdef SEGMENTS
        !          2108:                                putsec(secbuf, chinseg);
        !          2109:                                chinseg = 0;
        !          2110: #endif
        !          2111:                                vfile("rzfile: zrdata returned %d", c);
        !          2112:                                DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: zrdata returned ZCAN",
        !          2113:                                                   shortname, protname()));
        !          2114:                                return ERROR;
        !          2115:                        case ERROR:     /* CRC error */
        !          2116: #ifdef SEGMENTS
        !          2117:                                putsec(secbuf, chinseg);
        !          2118:                                chinseg = 0;
        !          2119: #endif
        !          2120:                                if ( --n < 0) {
        !          2121:                                        vfile("rzfile: zgethdr returned %d", c);
        !          2122:                                        DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: zrdata returned ERROR",
        !          2123:                                                           shortname, protname()));
        !          2124:                                        return ERROR;
        !          2125:                                }
        !          2126:                                zmputs(Attn);
        !          2127:                                continue;
        !          2128:                        case TIMEOUT:
        !          2129: #ifdef SEGMENTS
        !          2130:                                putsec(secbuf, chinseg);
        !          2131:                                chinseg = 0;
        !          2132: #endif
        !          2133:                                if ( --n < 0) {
        !          2134:                                        DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: zrdata returned TIMEOUT",
        !          2135:                                                           shortname, protname()));
        !          2136:                                        vfile("rzfile: zgethdr returned %d", c);
        !          2137:                                        return ERROR;
        !          2138:                                }
        !          2139:                                continue;
        !          2140:                        case GOTCRCW:
        !          2141:                                n = 20;
        !          2142: #ifdef SEGMENTS
        !          2143:                                chinseg += bytes_in_block;
        !          2144:                                putsec(zi, secbuf, chinseg);
        !          2145:                                chinseg = 0;
        !          2146: #else
        !          2147:                                putsec(zi, secbuf, bytes_in_block);
        !          2148: #endif
        !          2149:                                zi->bytes_received += bytes_in_block;
        !          2150:                                stohdr(zi->bytes_received);
        !          2151:                                zshhdr(ZACK | 0x80, Txhdr);
        !          2152:                                goto nxthdr;
        !          2153:                        case GOTCRCQ:
        !          2154:                                n = 20;
        !          2155: #ifdef SEGMENTS
        !          2156:                                chinseg += bytes_in_block;
        !          2157: #else
        !          2158:                                putsec(zi, secbuf, bytes_in_block);
        !          2159: #endif
        !          2160:                                zi->bytes_received += bytes_in_block;
        !          2161:                                stohdr(zi->bytes_received);
        !          2162:                                zshhdr(ZACK, Txhdr);
        !          2163:                                goto moredata;
        !          2164:                        case GOTCRCG:
        !          2165:                                n = 20;
        !          2166: #ifdef SEGMENTS
        !          2167:                                chinseg += bytes_in_block;
        !          2168: #else
        !          2169:                                putsec(zi, secbuf, bytes_in_block);
        !          2170: #endif
        !          2171:                                zi->bytes_received += bytes_in_block;
        !          2172:                                goto moredata;
        !          2173:                        case GOTCRCE:
        !          2174:                                n = 20;
        !          2175: #ifdef SEGMENTS
        !          2176:                                chinseg += bytes_in_block;
        !          2177: #else
        !          2178:                                putsec(zi, secbuf, bytes_in_block);
        !          2179: #endif
        !          2180:                                zi->bytes_received += bytes_in_block;
        !          2181:                                goto nxthdr;
        !          2182:                        }
        !          2183:                }
        !          2184:        }
        !          2185: }
        !          2186: 
        !          2187: /*
        !          2188:  * Send a string to the modem, processing for \336 (sleep 1 sec)
        !          2189:  *   and \335 (break signal)
        !          2190:  */
        !          2191: static void
        !          2192: zmputs(const char *s)
        !          2193: {
        !          2194:        const char *p;
        !          2195: 
        !          2196:        while (s && *s)
        !          2197:        {
        !          2198:                p=strpbrk(s,"\335\336");
        !          2199:                if (!p)
        !          2200:                {
        !          2201:                        write(1,s,strlen(s));
        !          2202:                        return;
        !          2203:                }
        !          2204:                if (p!=s)
        !          2205:                {
        !          2206:                        write(1,s,(size_t) (p-s));
        !          2207:                        s=p;
        !          2208:                }
        !          2209:                if (*p=='\336')
        !          2210:                        sleep(1);
        !          2211:                else
        !          2212:                        sendbrk(0);
        !          2213:                p++;
        !          2214:        }
        !          2215: }
        !          2216: 
        !          2217: /*
        !          2218:  * Close the receive dataset, return OK or ERROR
        !          2219:  */
        !          2220: static int
        !          2221: closeit(struct zm_fileinfo *zi)
        !          2222: {
        !          2223:        int ret;
        !          2224:        if (Topipe) {
        !          2225:                if (pclose(fout)) {
        !          2226:                        return ERROR;
        !          2227:                }
        !          2228:                return OK;
        !          2229:        }
        !          2230:        if (in_tcpsync) {
        !          2231:                rewind(fout);
        !          2232:                if (!fgets(tcp_buf,sizeof(tcp_buf),fout)) {
        !          2233:                        error(1,errno,_("fgets for tcp protocol synchronization failed: "));
        !          2234:                }       
        !          2235:                fclose(fout);
        !          2236:                return OK;
        !          2237:        }
        !          2238:        ret=fclose(fout);
        !          2239:        if (ret) {
        !          2240:                zpfatal(_("file close error"));
        !          2241:                /* this may be any sort of error, including random data corruption */
        !          2242: 
        !          2243:                unlink(Pathname);
        !          2244:                return ERROR;
        !          2245:        }
        !          2246:        if (zi->modtime) {
        !          2247: #ifdef HAVE_STRUCT_UTIMBUF
        !          2248:                struct utimbuf timep;
        !          2249:                timep.actime = time(NULL);
        !          2250:                timep.modtime = zi->modtime;
        !          2251:                utime(Pathname, &timep);
        !          2252: #else
        !          2253:                time_t timep[2];
        !          2254:                timep[0] = time(NULL);
        !          2255:                timep[1] = zi->modtime;
        !          2256:                utime(Pathname, timep);
        !          2257: #endif
        !          2258:        }
        !          2259: #ifdef S_ISREG
        !          2260:        if (S_ISREG(zi->mode)) {
        !          2261: #else
        !          2262:        if ((zi->mode&S_IFMT) == S_IFREG) {
        !          2263: #endif
        !          2264:                /* we must not make this program executable if running 
        !          2265:                 * under rsh, because the user might have uploaded an
        !          2266:                 * unrestricted shell.
        !          2267:                 */
        !          2268:                if (under_rsh)
        !          2269:                        chmod(Pathname, (00666 & zi->mode));
        !          2270:                else
        !          2271:                        chmod(Pathname, (07777 & zi->mode));
        !          2272:        }
        !          2273:        return OK;
        !          2274: }
        !          2275: 
        !          2276: /*
        !          2277:  * Ack a ZFIN packet, let byegones be byegones
        !          2278:  */
        !          2279: static void
        !          2280: ackbibi(void)
        !          2281: {
        !          2282:        int n;
        !          2283: 
        !          2284:        vfile("ackbibi:");
        !          2285:        Readnum = 1;
        !          2286:        stohdr(0L);
        !          2287:        for (n=3; --n>=0; ) {
        !          2288:                purgeline(0);
        !          2289:                zshhdr(ZFIN, Txhdr);
        !          2290:                switch (READLINE_PF(100)) {
        !          2291:                case 'O':
        !          2292:                        READLINE_PF(1); /* Discard 2nd 'O' */
        !          2293:                        vfile("ackbibi complete");
        !          2294:                        return;
        !          2295:                case RCDO:
        !          2296:                        return;
        !          2297:                case TIMEOUT:
        !          2298:                default:
        !          2299:                        break;
        !          2300:                }
        !          2301:        }
        !          2302: }
        !          2303: 
        !          2304: /*
        !          2305:  * Strip leading ! if present, do shell escape. 
        !          2306:  */
        !          2307: static int
        !          2308: sys2(const char *s)
        !          2309: {
        !          2310:        if (*s == '!')
        !          2311:                ++s;
        !          2312:        return system(s);
        !          2313: }
        !          2314: 
        !          2315: /*
        !          2316:  * Strip leading ! if present, do exec.
        !          2317:  */
        !          2318: static void 
        !          2319: exec2(const char *s)
        !          2320: {
        !          2321:        if (*s == '!')
        !          2322:                ++s;
        !          2323:        io_mode(0,0);
        !          2324:        execl("/bin/sh", "sh", "-c", s);
        !          2325:        zpfatal("execl");
        !          2326:        exit(1);
        !          2327: }
        !          2328: 
        !          2329: /*
        !          2330:  * Routine to calculate the free bytes on the current file system
        !          2331:  *  ~0 means many free bytes (unknown)
        !          2332:  */
        !          2333: static size_t 
        !          2334: getfree(void)
        !          2335: {
        !          2336:        return((size_t) (~0L)); /* many free bytes ... */
        !          2337: }
        !          2338: 
        !          2339: /* End of lrz.c */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>