Annotation of embedaddon/lrzsz/src/lrz.c, revision 1.1.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>