Annotation of sbbs/sbbs3/sexyz.c, revision 1.1

1.1     ! root        1: /* sexyz.c */
        !             2: 
        !             3: /* Synchronet External X/Y/ZMODEM Transfer Protocols */
        !             4: 
        !             5: /* $Id: sexyz.c,v 1.7 2004/09/11 09:36:19 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This program is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU General Public License                         *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU General Public License for more details: gpl.txt or                     *
        !            18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: /* 
        !            39:  * ZMODEM code based on zmtx/zmrx v1.02 (C) Mattheij Computer Service 1994
        !            40:  * by Jacques Mattheij <[email protected]        !            41:  */
        !            42: 
        !            43: #include <time.h>
        !            44: #include <stdio.h>
        !            45: #include <errno.h>
        !            46: #include <string.h>
        !            47: #include <stdlib.h>
        !            48: #include <stdarg.h>
        !            49: #include <sys/stat.h>
        !            50: 
        !            51: #include "conwrap.h"
        !            52: #include "genwrap.h"
        !            53: #include "dirwrap.h"
        !            54: #include "filewrap.h"
        !            55: #include "sockwrap.h"
        !            56: 
        !            57: #include "telnet.h"
        !            58: 
        !            59: #include "sexyz.h"
        !            60: 
        !            61: #define LOOP_NOPEN     50
        !            62: 
        !            63: #define MAX_FNAMES     100     /* Up to 100 filenames                                          */
        !            64: 
        !            65: /************************/
        !            66: /* Remote I/O Constants */
        !            67: /************************/
        !            68: 
        !            69:                                                        /* i/o mode and state flags */
        !            70: 
        !            71: void cancel(void);
        !            72: 
        !            73: /***************/
        !            74: /* Global Vars */
        !            75: /***************/
        !            76: long   mode=TELNET;                                    /* Program mode                                         */
        !            77: long   zmode=0L;                                               /* Zmodem mode                                          */
        !            78: uchar  block[1024];                                    /* Block buffer                                         */
        !            79: int    block_size;                                             /* Block size (128 or 1024)             */
        !            80: ulong  block_num;                                              /* Block number                                         */
        !            81: ulong  last_block_num;                                 /* Last block number sent                       */
        !            82: uint   flows=0;                                                /* Number of flow controls                      */
        !            83: time_t startall;
        !            84: 
        !            85: FILE*  errfp;
        !            86: FILE*  statfp;
        !            87: 
        !            88: char   revision[16];
        !            89: 
        !            90: SOCKET sock=INVALID_SOCKET;
        !            91: #define DCDHIGH                socket_check(sock, NULL, NULL, 0)
        !            92: 
        !            93: #define getcom(t)      recv_byte(sock,t,mode)
        !            94: #define putcom(ch)     send_byte(sock,ch,10,mode)
        !            95: 
        !            96: 
        !            97: #ifdef _WINSOCKAPI_
        !            98: 
        !            99: WSADATA WSAData;
        !           100: static BOOL WSAInitialized=FALSE;
        !           101: 
        !           102: static BOOL winsock_startup(void)
        !           103: {
        !           104:        int             status;             /* Status Code */
        !           105: 
        !           106:     if((status = WSAStartup(MAKEWORD(1,1), &WSAData))==0) {
        !           107:                fprintf(statfp,"%s %s\n",WSAData.szDescription, WSAData.szSystemStatus);
        !           108:                WSAInitialized=TRUE;
        !           109:                return(TRUE);
        !           110:        }
        !           111: 
        !           112:     fprintf(errfp,"!WinSock startup ERROR %d\n", status);
        !           113:        return(FALSE);
        !           114: }
        !           115: 
        !           116: #else /* No WINSOCK */
        !           117: 
        !           118: #define winsock_startup()      (TRUE)  
        !           119: 
        !           120: #endif
        !           121: 
        !           122: /********/
        !           123: /* Code */
        !           124: /********/
        !           125: 
        !           126: void newline(void)
        !           127: {
        !           128:        fprintf(statfp,"\n");
        !           129: }
        !           130: 
        !           131: /**************/
        !           132: /* Exit Point */
        !           133: /**************/
        !           134: void bail(int code)
        !           135: {
        !           136: 
        !           137:        if(mode&ALARM) {
        !           138:                BEEP(2000,500);
        !           139:                BEEP(1000,500);
        !           140:        }
        !           141:        newline();
        !           142:        fprintf(statfp,"Exiting - Error level: %d",code);
        !           143:        if(flows)
        !           144:                fprintf(statfp,"  Flow restraint count: %u",flows);
        !           145:        fprintf(statfp,"\n");
        !           146: 
        !           147:        if(/* code && */ mode&PAUSE_ABEND) {
        !           148:                printf("Hit enter to continue...");
        !           149:                getchar();
        !           150:        }
        !           151: 
        !           152:        exit(code);
        !           153: }
        !           154: 
        !           155: char *chr(uchar ch)
        !           156: {
        !           157:        static char str[25];
        !           158: 
        !           159:        switch(ch) {
        !           160:                case SOH:
        !           161:                        return("SOH");
        !           162:                case STX:
        !           163:                        return("STX");
        !           164:                case ETX:
        !           165:                        return("ETX");
        !           166:                case EOT:
        !           167:                        return("EOT");
        !           168:                case ACK:
        !           169:                        return("ACK");
        !           170:                case NAK:
        !           171:                        return("NAK");
        !           172:                case CAN:
        !           173:                        return("CAN");
        !           174:                default:
        !           175:                        if(ch>=' ' && ch<='~')
        !           176:                                sprintf(str,"'%c' (%02Xh)",ch,ch);
        !           177:                        else
        !           178:                                sprintf(str,"%u (%02Xh)",ch,ch);
        !           179:                        return(str); 
        !           180:        }
        !           181: }
        !           182: 
        !           183: void send_telnet_cmd(SOCKET sock, uchar cmd, uchar opt)
        !           184: {
        !           185:        uchar buf[3];
        !           186:        
        !           187:        buf[0]=TELNET_IAC;
        !           188:        buf[1]=cmd;
        !           189:        buf[2]=opt;
        !           190: 
        !           191:        fprintf(statfp,"\nSending telnet command: %s %s"
        !           192:                ,telnet_cmd_desc(buf[1]),telnet_opt_desc(buf[2]));
        !           193:        if(send(sock,buf,sizeof(buf),0)==sizeof(buf))
        !           194:                fprintf(statfp,"\n");
        !           195:        else
        !           196:                fprintf(statfp," FAILED!\n");
        !           197: }
        !           198: 
        !           199: #define DEBUG_TELNET FALSE
        !           200: 
        !           201: /****************************************************************************/
        !           202: /* Receive a byte from remote                                                                                          */
        !           203: /****************************************************************************/
        !           204: uint recv_byte(SOCKET sock, int timeout, long mode)
        !           205: {
        !           206:        int                     i;
        !           207:        uchar           ch;
        !           208:        fd_set          socket_set;
        !           209:        struct timeval  tv;
        !           210:        static uchar    telnet_cmd;
        !           211:        static int              telnet_cmdlen;
        !           212: 
        !           213:        while(1) {
        !           214: 
        !           215:                FD_ZERO(&socket_set);
        !           216:                FD_SET(sock,&socket_set);
        !           217:                tv.tv_sec=timeout;
        !           218:                tv.tv_usec=0;
        !           219: 
        !           220:                if(select(sock+1,&socket_set,NULL,NULL,&tv)<1) {
        !           221:                        if(timeout) {
        !           222:                                newline();
        !           223:                                fprintf(statfp,"Input timeout\n");
        !           224:                        }
        !           225:                        return(NOINP);
        !           226:                }
        !           227:                
        !           228:                i=recv(sock,&ch,sizeof(ch),0);
        !           229: 
        !           230:                if(i!=sizeof(ch)) {
        !           231:                        newline();
        !           232:                        if(i==0)
        !           233:                                fprintf(statfp,"No carrier\n");
        !           234:                        else
        !           235:                                fprintf(statfp,"!recv error %d (%d)\n",i,ERROR_VALUE);
        !           236:                        bail(1)        !           237:                }
        !           238: 
        !           239:                if(mode&TELNET) {
        !           240:                        if(ch==TELNET_IAC) {
        !           241: #if DEBUG_TELNET
        !           242:                                fprintf(statfp,"T<%s> ",telnet_cmd_desc(ch));
        !           243: #endif
        !           244:                                if(telnet_cmdlen==0) {
        !           245:                                        telnet_cmdlen=1;
        !           246:                                        continue;
        !           247:                                }
        !           248:                                if(telnet_cmdlen==1) {
        !           249:                                        telnet_cmdlen=0;
        !           250:                                        return(TELNET_IAC);
        !           251:                                }
        !           252:                        }
        !           253:                        if(telnet_cmdlen) {
        !           254:                                telnet_cmdlen++;
        !           255: #if DEBUG_TELNET
        !           256:                                if(telnet_cmdlen==2)
        !           257:                                        fprintf(statfp,"T<%s> ",telnet_cmd_desc(ch));
        !           258:                                else
        !           259:                                        fprintf(statfp,"T<%s> ",telnet_opt_desc(ch));
        !           260: #endif
        !           261:                                if(telnet_cmdlen==3 && telnet_cmd==TELNET_DO)
        !           262:                                        send_telnet_cmd(sock, TELNET_WILL,ch);
        !           263:        /*
        !           264:                                else if(telnet_cmdlen==3 && telnet_cmd==TELNET_WILL)
        !           265:                                        send_telnet_cmd(sock, TELNET_DO,ch);
        !           266:        */
        !           267:                                telnet_cmd=ch;
        !           268:                                if((telnet_cmdlen==2 && ch<TELNET_WILL) || telnet_cmdlen>2)
        !           269:                                        telnet_cmdlen=0;
        !           270:                                continue;
        !           271:                        }
        !           272:                }
        !           273:                return(ch);
        !           274:        }
        !           275: 
        !           276:        return(NOINP);
        !           277: }
        !           278:        
        !           279: /*************************/
        !           280: /* Send a byte to remote */
        !           281: /*************************/
        !           282: int send_byte(SOCKET sock, uchar ch, int timeout, long mode)
        !           283: {
        !           284:        uchar           buf[2] = { TELNET_IAC, TELNET_IAC };
        !           285:        int                     len=1;
        !           286:        int                     i;
        !           287:        fd_set          socket_set;
        !           288:        struct timeval  tv;
        !           289: 
        !           290:        FD_ZERO(&socket_set);
        !           291:        FD_SET(sock,&socket_set);
        !           292:        tv.tv_sec=timeout;
        !           293:        tv.tv_usec=0;
        !           294: 
        !           295:        if(select(sock+1,NULL,&socket_set,NULL,&tv)<1)
        !           296:                return(ERROR_VALUE);
        !           297: 
        !           298:        if(mode&TELNET && ch==TELNET_IAC)       /* escape IAC char */
        !           299:                len=2;
        !           300:        else
        !           301:                buf[0]=ch;
        !           302: 
        !           303:        i=send(sock,buf,len,0);
        !           304:        
        !           305:        if(i==len)
        !           306:                return(0);
        !           307: 
        !           308:        return(-1);
        !           309: }
        !           310: 
        !           311: int send_str(SOCKET sock, char* str, int timeout, long mode)
        !           312: {
        !           313:        char*   p;
        !           314:        int             i;
        !           315: 
        !           316:        for(p=str;*p;p++) {
        !           317:                if((i=send_byte(sock,*p,timeout,mode))!=0)
        !           318:                        return(i);
        !           319:        }
        !           320:        return(0);
        !           321: }
        !           322: 
        !           323: 
        !           324: /****************************************************************************/
        !           325: /* Returns the number of blocks required to send len bytes                                     */
        !           326: /****************************************************************************/
        !           327: long num_blocks(long len, long block_size)
        !           328: {
        !           329:        long blocks;
        !           330: 
        !           331:        blocks=len/block_size;
        !           332:        if(len%block_size)
        !           333:                blocks++;
        !           334:        return(blocks);
        !           335: }
        !           336: 
        !           337: /************************************************/
        !           338: /* Dump the current block contents - for debug  */
        !           339: /************************************************/
        !           340: void dump_block()
        !           341: {
        !           342:        int l;
        !           343: 
        !           344:        for(l=0;l<block_size;l++)
        !           345:                fprintf(statfp,"%02X  ",block[l]);
        !           346:        fprintf(statfp,"\n");
        !           347: }
        !           348: 
        !           349: void send_files(char** fname, uint fnames, FILE* log)
        !           350: {
        !           351:        char    path[MAX_PATH+1];
        !           352:        int             ch;
        !           353:        int             i;
        !           354:        uint    errors;
        !           355:        uint    fnum;
        !           356:        uint    cps;
        !           357:        glob_t  g;
        !           358:        int             gi;
        !           359:        BOOL    can;
        !           360:        BOOL    success;
        !           361:        long    b,l;
        !           362:        long    fsize;
        !           363:        uint    total_files=0,sent_files=0;
        !           364:        ulong   total_bytes=0,sent_bytes=0;
        !           365:        time_t  t,startfile;
        !           366:        FILE*   fp;
        !           367:        xmodem_t xm;
        !           368:        zmodem_t zm;
        !           369: 
        !           370:        /****************************************************/
        !           371:        /* Search through all to find total files and bytes */
        !           372:        /****************************************************/
        !           373:        for(fnum=0;fnum<fnames;fnum++) {
        !           374:                if(glob(fname[fnum],0,NULL,&g)) {
        !           375:                        fprintf(statfp,"%s not found\n",fname[fnum]);
        !           376:                        continue;
        !           377:                }
        !           378:                for(i=0;i<(int)g.gl_pathc;i++) {
        !           379:                        if(isdir(g.gl_pathv[i]))
        !           380:                                continue;
        !           381:                        total_files++;
        !           382:                        total_bytes+=flength(g.gl_pathv[i]);
        !           383:                } 
        !           384:                globfree(&g);
        !           385:        }
        !           386: 
        !           387:        if(fnames>1)
        !           388:                fprintf(statfp,"Sending %u files (%lu bytes total)\n"
        !           389:                        ,total_files,total_bytes);
        !           390: 
        !           391:        memset(&xm,0,sizeof(xm));
        !           392:        xm.sock=sock;
        !           393:        xm.mode=mode;
        !           394:        xm.errfp=errfp;
        !           395:        xm.statfp=statfp;
        !           396: 
        !           397:        memset(&zm,0,sizeof(zm));
        !           398:        zm.sock=sock;
        !           399:        zm.mode=mode;
        !           400:        zm.errfp=errfp;
        !           401:        zm.statfp=statfp;
        !           402:        zm.n_files_remaining = total_files;
        !           403:        zm.n_bytes_remaining = total_bytes;
        !           404: 
        !           405:        /***********************************************/
        !           406:        /* Send every file matching names or filespecs */
        !           407:        /***********************************************/
        !           408:        for(fnum=0;fnum<fnames;fnum++) {
        !           409:                if(glob(fname[fnum],0,NULL,&g)) {
        !           410:                        fprintf(statfp,"%s not found\n",fname[fnum]);
        !           411:                        continue;
        !           412:                }
        !           413:                for(gi=0;gi<(int)g.gl_pathc;gi++) {
        !           414:                        SAFECOPY(path,g.gl_pathv[gi]);
        !           415:                        if(isdir(path))
        !           416:                                continue;
        !           417: 
        !           418:                        if((fp=fopen(path,"rb"))==NULL) {
        !           419:                                fprintf(statfp,"!Error %d opening %s for read\n",errno,path);
        !           420:                                continue;
        !           421:                        }
        !           422: 
        !           423:                        if(mode&ZMODEM) {
        !           424: 
        !           425:                                for(errors=0;errors<MAXERRORS;errors++) {
        !           426:                                        fprintf(statfp,"\nSending ZRQINIT\n");
        !           427:                                        i = zmodem_get_zrinit(&zm);
        !           428:                                        if(i == ZRINIT) {
        !           429:                                                zmodem_parse_zrinit(&zm);
        !           430:                                                break;
        !           431:                                        }
        !           432:                                        fprintf(statfp,"\n!RX header: %d 0x%02X\n", i, i);
        !           433:                                }
        !           434: 
        !           435:                        } else {        /* X/Ymodem */
        !           436: 
        !           437:                                mode&=~GMODE;
        !           438:                                flows=0;
        !           439:                                for(errors=can=0;errors<MAXERRORS;errors++) {
        !           440:                                        i=getcom(10);
        !           441:                                        if(can && i!=CAN)
        !           442:                                                can=0;
        !           443:                                        if(i==NAK) {            /* csum */
        !           444:                                                mode&=~CRC;
        !           445:                                                break; 
        !           446:                                        }
        !           447:                                        if(i=='C') {
        !           448:                                                mode|=CRC;
        !           449:                                                break; 
        !           450:                                        }
        !           451:                                        if(i=='G') {
        !           452:                                                mode|=(GMODE|CRC);
        !           453:                                                break; 
        !           454:                                        }
        !           455:                                        if(i==CAN) {
        !           456:                                                if(can) {
        !           457:                                                        newline();
        !           458:                                                        fprintf(statfp,"Cancelled remotely\n");
        !           459:                                                        bail(1)        !           460:                                                }
        !           461:                                                can=1; 
        !           462:                                        }
        !           463: #if 0
        !           464:                                        rioctl(IOFB);   /* flush buffers cause we have crap-o-la */
        !           465: #endif
        !           466:                                        if(i!=NOINP) {
        !           467:                                                newline();
        !           468:                                                fprintf(statfp,"Received %s  Expected NAK, C, or G\n"
        !           469:                                                        ,chr((uchar)i)); 
        !           470:                                        } 
        !           471:                                }
        !           472:                        }
        !           473: 
        !           474:                        if(errors==MAXERRORS) {
        !           475:                                fprintf(statfp,"\n!Timeout waiting for receiver to start/accept file transfer\n");
        !           476:                                xmodem_cancel(&xm);
        !           477:                                bail(1)        !           478:                        } 
        !           479: 
        !           480:                        fsize=filelength(fileno(fp));
        !           481: 
        !           482:                        fprintf(statfp,"\nSending %s (%lu bytes) via %s %s\n"
        !           483:                                ,path,fsize
        !           484:                                ,mode&XMODEM ? "Xmodem" : mode&YMODEM ? mode&GMODE ? "Ymodem-G"
        !           485:                                        : "Ymodem" : "Zmodem"
        !           486:                                ,mode&ZMODEM ? (zm.can_fcs_32 ? "CRC-32" : "CRC-16")
        !           487:                                        : mode&CRC ? "CRC-16":"Checksum");
        !           488: 
        !           489:                        errors=0;
        !           490:                        success=0;
        !           491:                        startfile=time(NULL);
        !           492: 
        !           493:                        if(mode&ZMODEM) {
        !           494:                                if(zmodem_send_file(&zm,getfname(path),fp)==0) {
        !           495:                                        sent_files++;
        !           496:                                        sent_bytes+=fsize;
        !           497: 
        !           498:                                        t=time(NULL)-startfile;
        !           499:                                        if(!t) t=1;
        !           500:                                        fprintf(statfp,"\rSuccesssful - Time: %lu:%02lu  CPS: %lu\n"
        !           501:                                                ,t/60,t%60,fsize/t);
        !           502:                                        success=1; 
        !           503:                                }
        !           504:                                else {
        !           505:                                        newline();
        !           506:                                        fprintf(statfp,"Unsuccessful!\n");
        !           507:                                        t=time(NULL)-startfile;
        !           508:                                        if(!t) t=1; 
        !           509:                                }
        !           510: 
        !           511:                        } else {        /* X/Ymodem */
        !           512: 
        !           513:                                if(!(mode&XMODEM)) {
        !           514:                                        t=fdate(path);
        !           515:                                        memset(block,0,sizeof(block));
        !           516:                                        SAFECOPY(block,getfname(path));
        !           517:                                        sprintf(block+strlen(block)+1,"%lu %lo 0 0 %d %ld"
        !           518:                                                ,fsize,t,total_files-sent_files,total_bytes-sent_bytes);
        !           519:                                        /*
        !           520:                                        fprintf(statfp,"Sending Ymodem block '%s'\n",block+strlen(block)+1);
        !           521:                                        */
        !           522:                                        for(errors=0;errors<MAXERRORS;errors++) {
        !           523:                                                xmodem_put_block(&xm, block, 128 /* block_size */, 0 /* block_num */);
        !           524:                                                if(xmodem_get_ack(&xm,1))
        !           525:                                                        break; 
        !           526:                                        }
        !           527:                                        if(errors==MAXERRORS) {
        !           528:                                                newline();
        !           529:                                                fprintf(statfp,"Failed to send header block\n");
        !           530:                                                xmodem_cancel(&xm);
        !           531:                                                bail(1)        !           532:                                        }
        !           533:                                        mode&=~GMODE;
        !           534:                                        for(errors=can=0;errors<MAXERRORS;errors++) {
        !           535:                                                i=getcom(10);
        !           536:                                                if(can && i!=CAN)
        !           537:                                                        can=0;
        !           538:                                                if(i==NAK) {            /* csum */
        !           539:                                                        mode&=~CRC;
        !           540:                                                        break; 
        !           541:                                                }
        !           542:                                                if(i=='C') {
        !           543:                                                        mode|=CRC;
        !           544:                                                        break; 
        !           545:                                                }
        !           546:                                                if(i=='G') {
        !           547:                                                        mode|=(GMODE|CRC);
        !           548:                                                        break; 
        !           549:                                                }
        !           550:                                                if(i==CAN) {
        !           551:                                                        if(can) {
        !           552:                                                                newline();
        !           553:                                                                fprintf(statfp,"Cancelled remotely\n");
        !           554:                                                                bail(1)        !           555:                                                        }
        !           556:                                                        can=1; 
        !           557:                                                }
        !           558:        #if 0
        !           559:                                                rioctl(IOFB);
        !           560:        #endif
        !           561:                                                if(i!=NOINP) {
        !           562:                                                        newline();
        !           563:                                                        fprintf(statfp,"Received %s  Expected NAK, C, or G\n"
        !           564:                                                                ,chr((uchar)i)); 
        !           565:                                                } 
        !           566:                                        }
        !           567:                                        if(errors==MAXERRORS) {
        !           568:                                                newline();
        !           569:                                                fprintf(statfp,"Too many errors waiting for receiver\n");
        !           570:                                                xmodem_cancel(&xm);
        !           571:                                                bail(1)        !           572:                                        } 
        !           573:                                }
        !           574:                                last_block_num=block_num=1;
        !           575:                                errors=0;
        !           576:                                while((block_num-1)*block_size<(ulong)fsize && errors<MAXERRORS) {
        !           577:                                        if(last_block_num==block_num) {  /* block_num didn't increment */
        !           578:                                                fseek(fp,(block_num-1)*(long)block_size,SEEK_SET);
        !           579:                                                i=fread(block,1,block_size,fp);
        !           580:                                                while(i<block_size)
        !           581:                                                        block[i++]=CPMEOF; 
        !           582:                                        }
        !           583:                                        last_block_num=block_num;
        !           584:                                        xmodem_put_block(&xm, block, block_size, block_num);
        !           585:                                        i=fread(block,1,block_size,fp); /* read next block from disk */
        !           586:                                        while(i<(int)block_size)
        !           587:                                                block[i++]=CPMEOF;
        !           588:                                        t=time(NULL)-startfile;
        !           589:                                        if(!t) t=1;             /* t is time so far */
        !           590:                                        cps=(uint)((block_num*(long)block_size)/t);     /* cps so far */
        !           591:                                        if(!cps) cps=1;
        !           592:                                        l=fsize/cps;            /* total transfer est time */
        !           593:                                        l-=t;                           /* now, it's est time left */
        !           594:                                        if(l<0) l=0;
        !           595:                                        b=num_blocks(fsize,block_size);
        !           596:                                        fprintf(statfp,"\rBlock (%lu%s): %lu/%lu  Byte: %lu  "
        !           597:                                                "Time: %lu:%02lu/%lu:%02lu  CPS: %u  %lu%% "
        !           598:                                                ,block_size%1024L ? block_size: block_size/1024L
        !           599:                                                ,block_size%1024L ? "" : "k"
        !           600:                                                ,block_num
        !           601:                                                ,b
        !           602:                                                ,block_num*(long)block_size
        !           603:                                                ,t/60L
        !           604:                                                ,t%60L
        !           605:                                                ,l/60L
        !           606:                                                ,l%60L
        !           607:                                                ,cps
        !           608:                                                ,(long)(((float)block_num/(float)b)*100.0)
        !           609:                                                );
        !           610:                                        if(!xmodem_get_ack(&xm,5))
        !           611:                                                errors++;
        !           612:                                        else
        !           613:                                                block_num++; 
        !           614:                                }
        !           615:                                fclose(fp);
        !           616:                                if((long)(block_num-1)*(long)block_size>=fsize) {
        !           617:                                        sent_files++;
        !           618:                                        sent_bytes+=fsize;
        !           619:                                        fprintf(statfp,"\n");
        !           620: 
        !           621:                                        for(i=0;i<10;i++) {
        !           622:                                                fprintf(statfp,"\rSending EOT (%d)",i+1);
        !           623:        #if 0
        !           624:                                                rioctl(IOFI);
        !           625:        #endif
        !           626:                                                putcom(EOT);
        !           627:                                                ch=getcom(10);
        !           628:                                                if(ch==ACK)
        !           629:                                                        break;
        !           630:                                                if(ch==NAK && i==0 && (mode&(YMODEM|GMODE))==YMODEM)
        !           631:                                                        continue;  /* chuck's double EOT trick so don't complain */
        !           632:                                                if(ch!=NOINP) {
        !           633:                                                        newline();
        !           634:                                                        fprintf(statfp,"Received %s  Expected ACK\n"
        !           635:                                                                ,chr((uchar)ch)); 
        !           636:                                                } 
        !           637:                                        }
        !           638:                                        if(i==3)
        !           639:                                                fprintf(statfp,"\rNo ACK on EOT   \n");
        !           640:                                        t=time(NULL)-startfile;
        !           641:                                        if(!t) t=1;
        !           642:                                        fprintf(statfp,"\rSuccesssful - Time: %lu:%02lu  CPS: %lu\n"
        !           643:                                                ,t/60,t%60,fsize/t);
        !           644:                                        success=1; 
        !           645:                                }
        !           646:                                else {
        !           647:                                        newline();
        !           648:                                        fprintf(statfp,"Unsuccessful!\n");
        !           649:                                        t=time(NULL)-startfile;
        !           650:                                        if(!t) t=1; 
        !           651:                                }
        !           652:                        }
        !           653: 
        !           654:                        if(total_files>1 && total_files-sent_files>1)
        !           655:                                fprintf(statfp,"Remaining - Time: %lu:%02lu  Files: %u  Bytes: %lu\n"
        !           656:                                        ,((total_bytes-sent_bytes)/cps)/60
        !           657:                                        ,((total_bytes-sent_bytes)/cps)%60
        !           658:                                        ,total_files-sent_files
        !           659:                                        ,total_bytes-sent_bytes
        !           660:                                        );
        !           661: 
        !           662:                        /* DSZLOG entry */
        !           663:                        if(log) {
        !           664:                                if(mode&ZMODEM)
        !           665:                                        l=fsize;
        !           666:                                else {
        !           667:                                        l=(block_num-1)*(long)block_size;
        !           668:                                        if(l>fsize)
        !           669:                                                l=fsize;
        !           670:                                }
        !           671:                                fprintf(log,"%c %6lu %5u bps %4lu cps %3u errors %5u %4u "
        !           672:                                        "%s -1\n"
        !           673:                                        ,success ? (mode&ZMODEM ? 'z':'S') : 'E'
        !           674:                                        ,l
        !           675:                                        ,30000 /* baud */
        !           676:                                        ,l/t
        !           677:                                        ,errors
        !           678:                                        ,flows
        !           679:                                        ,block_size
        !           680:                                        ,path); 
        !           681:                        }
        !           682:                } 
        !           683:        }
        !           684:        if(mode&XMODEM)
        !           685:                bail(0);
        !           686:        if(mode&ZMODEM)
        !           687:                zmodem_send_zfin(&zm);
        !           688:        else {  /* YMODEM */
        !           689:                mode&=~GMODE;
        !           690:                i=getcom(10);
        !           691:                if(i==NAK)
        !           692:                        mode&=~CRC;
        !           693:                else if(i=='C')
        !           694:                        mode|=CRC;
        !           695:                else if(i=='G')
        !           696:                        mode|=(GMODE|CRC);
        !           697:                if(i!=NOINP && i!=NAK && i!='C' && i!='G') {
        !           698:                        newline();
        !           699:                        fprintf(statfp,"Received %s  Expected NAK, C, or G\n",chr((uchar)i)); 
        !           700:                }
        !           701:                else if(i!=NOINP) {
        !           702:                        block[0]=0;
        !           703:                        xmodem_put_block(&xm, block, 128 /* block_size */, 0 /* block_num */);
        !           704:                        if(!xmodem_get_ack(&xm,6)) {
        !           705:                                newline();
        !           706:                                fprintf(statfp,"Failed to receive ACK after terminating block\n"); 
        !           707:                        } 
        !           708:                }
        !           709:        }
        !           710:        if(total_files>1) {
        !           711:                t=time(NULL)-startall;
        !           712:                if(!t) t=1;
        !           713:                newline();
        !           714:                fprintf(statfp,"Overall - Time %02lu:%02lu  Bytes: %lu  CPS: %lu\n"
        !           715:                        ,t/60,t%60,sent_bytes,sent_bytes/t); 
        !           716:        }
        !           717: }
        !           718: 
        !           719: void receive_files(char** fname, int fnames, FILE* log)
        !           720: {
        !           721:        char    str[MAX_PATH+1];
        !           722:        int             i;
        !           723:        int             fnum=0;
        !           724:        uint    errors;
        !           725:        uint    total_files;
        !           726:        uint    cps;
        !           727:        uint    hdr_block_num;
        !           728:        long    b,l,m;
        !           729:        long    serial_num;
        !           730:        ulong   file_bytes=0,file_bytes_left=0;
        !           731:        ulong   total_bytes=0;
        !           732:        FILE*   fp;
        !           733:        time_t  t,startfile,ftime;
        !           734:        xmodem_t xm;
        !           735:        zmodem_t zm;
        !           736: 
        !           737:        if(fnames>1)
        !           738:                fprintf(statfp,"Receiving %u files\n",fnames);
        !           739: 
        !           740:        memset(&xm,0,sizeof(xm));
        !           741:        xm.sock=sock;
        !           742:        xm.mode=mode;
        !           743: 
        !           744:        memset(&zm,0,sizeof(zm));
        !           745:        zm.sock=sock;
        !           746:        zm.mode=mode;
        !           747: 
        !           748:        while(1) {
        !           749:                if(mode&XMODEM) {
        !           750:                        SAFECOPY(str,fname[0]);
        !           751:                        file_bytes=file_bytes_left=0x7fffffff;
        !           752:                        serial_num=-1; 
        !           753:                }
        !           754: 
        !           755:                else if(mode&YMODEM) {
        !           756:                        fprintf(statfp,"Fetching Ymodem header block\n");
        !           757:                        for(errors=0;errors<MAXERRORS;errors++) {
        !           758:                                if(errors>3 && mode&CRC && !(mode&GMODE))
        !           759:                                        mode&=~CRC;
        !           760:                                if(mode&GMODE)          /* G for Ymodem-G */
        !           761:                                        putcom('G');
        !           762:                                else if(mode&CRC)       /* C for CRC */
        !           763:                                        putcom('C');
        !           764:                                else                            /* NAK for checksum */
        !           765:                                        putcom(NAK);
        !           766: #if 0
        !           767:                                for(i=60;i;i--) {
        !           768:                                        if(rioctl(RXBC))        /* no chars in-bound */
        !           769:                                                break;
        !           770:                                        SLEEP(100);             /* so wait */
        !           771:                                }
        !           772:                                if(!i) {                                /* none after 6 secs */
        !           773:                                        if(errors)
        !           774:                                                fprintf(statfp,"Ymodem header timeout (%d)\n",errors);
        !           775:                                        continue; 
        !           776:                                }
        !           777: #endif
        !           778:                                if(xmodem_get_block(&xm, block,block_size,TRUE)==0) {    /* block received successfully */
        !           779:                                        putcom(ACK);
        !           780:                                        break; 
        !           781:                                } 
        !           782:                        }
        !           783:                        if(errors==MAXERRORS) {
        !           784:                                fprintf(statfp,"Error fetching Ymodem header block\n");
        !           785:                                xmodem_cancel(&xm);
        !           786:                                bail(1)        !           787:                        }
        !           788:                        if(!block[0]) {
        !           789:                                fprintf(statfp,"Received Ymodem termination block\n");
        !           790:                                bail(0)        !           791:                        }
        !           792:                        sscanf(block+strlen(block)+1,"%ld %lo %lo %lo %d %ld"
        !           793:                                ,&file_bytes                    /* file size (decimal) */
        !           794:                                ,&ftime                                 /* file time (octal unix format) */
        !           795:                                ,&m                                     /* file mode (not used) */
        !           796:                                ,&serial_num                    /* program serial number */
        !           797:                                ,&total_files                   /* remaining files to be sent */
        !           798:                                ,&total_bytes                   /* remaining bytes to be sent */
        !           799:                                );
        !           800:                        if(!file_bytes)
        !           801:                                file_bytes=0x7fffffff;
        !           802:                        file_bytes_left=file_bytes;
        !           803:                        if(!total_files)
        !           804:                                total_files=fnames-fnum;
        !           805:                        if(!total_files)
        !           806:                                total_files=1;
        !           807:                        if(total_bytes<file_bytes)
        !           808:                                total_bytes=file_bytes;
        !           809:                        if(!serial_num)
        !           810:                                serial_num=-1;
        !           811:                        fprintf(statfp,"Incoming filename: %.64s ",block);
        !           812:                        if(mode&DIR)
        !           813:                                sprintf(str,"%s%s",fname[0],getfname(block));
        !           814:                        else {
        !           815:                                SAFECOPY(str,getfname(block));
        !           816:                                for(i=0;i<fnames;i++) {
        !           817:                                        if(!fname[i][0])        /* name blank or already used */
        !           818:                                                continue;
        !           819:                                        if(!stricmp(getfname(fname[i]),str)) {
        !           820:                                                SAFECOPY(str,fname[i]);
        !           821:                                                fname[i][0]=0;
        !           822:                                                break; 
        !           823:                                        } 
        !           824:                                }
        !           825:                                if(i==fnames) {                                 /* Not found in list */
        !           826:                                        if(fnames)
        !           827:                                                fprintf(statfp," - Not in receive list!");
        !           828:                                        if(!fnames || fnum>=fnames || !fname[fnum][0])
        !           829:                                                SAFECOPY(str,getfname(block));  /* worst case */
        !           830:                                        else {
        !           831:                                                SAFECOPY(str,fname[fnum]);
        !           832:                                                fname[fnum][0]=0; 
        !           833:                                        } 
        !           834:                                } 
        !           835:                        }
        !           836:                        fprintf(statfp,"\n"); 
        !           837:                }
        !           838: 
        !           839:                else {  /* Zmodem */
        !           840: #if 0
        !           841:                        tryzhdrtype=ZRINIT;
        !           842:                        while(1) {
        !           843:                                Txhdr[ZF0]=(CANFC32|CANFDX|CANOVIO|CANRLE);
        !           844:                                /* add CANBRK if we can send break signal */
        !           845:                                if(zmode&CTRL_ESC)
        !           846:                                        Txhdr[ZF0]|=TESCCTL;
        !           847:                                Txhdr[ZF1]=CANVHDR;
        !           848:                                Txhdr[ZP0]=0;
        !           849:                                Txhdr[ZP1]=0;
        !           850:                                putzhhdr(tryzhdrtype);
        !           851:                                done=0;
        !           852:                                while(!done) {
        !           853:                                        done=1;
        !           854:                                        switch(getzhdr()) {
        !           855:                                                case ZRQINIT:
        !           856:                                                        if(Rxhdr[ZF3]&0x80)
        !           857:                                                                zmode|=VAR_HDRS;   /* we can var header */
        !           858:                                                        break;
        !           859:                                                case ZFILE:
        !           860:                                                        zconv=Rxhdr[ZF0];
        !           861:                                                        zmanag=Rxhdr[ZF1];
        !           862:                                                        ztrans=Rxhdr[ZF2];
        !           863:                                                        if(Rxhdr[ZF3]&ZCANVHDR)
        !           864:                                                                zmode|=VAR_HDRS;
        !           865:                                                        tryzhdrtype=ZRINIT;
        !           866:                                                        if(getzdata(block, 1024)==GOTCRCW) {
        !           867:                                                                /* something */
        !           868:                                                                done=1; 
        !           869:                                                        }
        !           870:                                                        putzhhdr(ZNAK);
        !           871:                                                        done=0;
        !           872:                                                        break;
        !           873:                                                case ZSINIT:
        !           874:                                                        if(Rxhdr[ZF0]&TESCCTL)
        !           875:                                                                zmode|=CTRL_ESC;
        !           876:                                                        if (getzdata(attn,ZATTNLEN)==GOTCRCW) {
        !           877:                                                                ltohdr(1L);
        !           878:                                                                putzhhdr(ZACK); 
        !           879:                                                        }
        !           880:                                                        else
        !           881:                                                                putzhhdr(ZNAK);
        !           882:                                                        done=0;
        !           883:                                                        break;
        !           884:                                                case ZFREECNT:
        !           885:                                                        ltohdr(0);                      /* should be free disk space */
        !           886:                                                        putzhhdr(ZACK);
        !           887:                                                        done=0;
        !           888:                                                        break;
        !           889:                                                case ZCOMMAND:
        !           890: /***
        !           891:                                                        cmdzack1flg = Rxhdr[ZF0];
        !           892:                                                        if(getzdata(block,1024)==GOTCRCW) {
        !           893:                                                                if (cmdzack1flg & ZCACK1)
        !           894:                                                                        ltohdr(0L);
        !           895:                                                                else
        !           896:                                                                        ltohdr((long)sys2(block));
        !           897:                                                                purgeline();    /* dump impatient questions */
        !           898:                                                                do {
        !           899:                                                                        zshhdr(4,ZCOMPL, Txhdr);
        !           900:                                                                }
        !           901:                                                                while (++errors<20 && zgethdr(Rxhdr,1)!=ZFIN);
        !           902:                                                                ackbibi();
        !           903:                                                                if (cmdzack1flg & ZCACK1)
        !           904:                                                                        exec2(block);
        !           905:                                                                return ZCOMPL;
        !           906:                                                        }
        !           907: ***/
        !           908:                                                        putzhhdr(ZNAK);
        !           909:                                                        done=0;
        !           910:                                                        break;
        !           911:                                                case ZCOMPL:
        !           912:                                                        done=0;
        !           913:                                                        break;
        !           914:                                                case ZFIN:
        !           915:                                                        ackbibi();
        !           916:                                                        return ZCOMPL;
        !           917:                                                case ZCAN:
        !           918:                                                        return ERROR; 
        !           919:                                } 
        !           920:                        }
        !           921: #endif
        !           922:                }
        !           923: 
        !           924:                fnum++;
        !           925: 
        !           926:                if(!(mode&DIR) && fnames && fnum>fnames) {
        !           927:                        newline();
        !           928:                        fprintf(statfp,"Attempt to send more files than specified\n");
        !           929:                        xmodem_cancel(&xm);
        !           930:                        break; 
        !           931:                }
        !           932: 
        !           933:                if(fexist(str) && !(mode&OVERWRITE)) {
        !           934:                        fprintf(statfp,"%s already exists\n",str);
        !           935:                        xmodem_cancel(&xm);
        !           936:                        bail(1)        !           937:                }
        !           938:                if((fp=fopen(str,"wb"))==NULL) {
        !           939:                        fprintf(statfp,"Error creating %s\n",str);
        !           940:                        xmodem_cancel(&xm);
        !           941:                        bail(1)        !           942:                }
        !           943:                setvbuf(fp,NULL,_IOFBF,8*1024);
        !           944:                startfile=time(NULL);
        !           945:                fprintf(statfp,"Receiving %s (%lu bytes) via %s %s\n"
        !           946:                        ,str
        !           947:                        ,mode&XMODEM ? 0 : file_bytes
        !           948:                        ,mode&XMODEM ? "Xmodem" : mode&YMODEM ? mode&GMODE ? "Ymodem-G"
        !           949:                        : "Ymodem" :"Zmodem"
        !           950:                        ,mode&CRC ? "CRC-16":"Checksum");
        !           951: 
        !           952:                errors=0;
        !           953:                block_num=0;
        !           954:                if(mode&GMODE)          /* G for Ymodem-G */
        !           955:                        putcom('G');
        !           956:                else if(mode&CRC)       /* C for CRC */
        !           957:                        putcom('C');
        !           958:                else                            /* NAK for checksum */
        !           959:                        putcom(NAK);
        !           960:                while(errors<MAXERRORS) {
        !           961:                        if(block_num && !(mode&GMODE))
        !           962:                                putcom(ACK);
        !           963:                        i=xmodem_get_block(&xm, block,block_size,FALSE);        /* returns block num */
        !           964:                        if(i<0) {
        !           965:                                if(i==-EOT)                     /* end of transfer */
        !           966:                                        break;
        !           967:                                /* other error */
        !           968:                                xmodem_cancel(&xm);
        !           969:                                bail(1)        !           970:                        }
        !           971:                        hdr_block_num=i;
        !           972:                        if(file_bytes_left<=0L)  { /* No more bytes to send */
        !           973:                                newline();
        !           974:                                fprintf(statfp,"Attempt to send more than header specified\n");
        !           975:                                break; 
        !           976:                        }
        !           977:                        if(hdr_block_num==(uchar)((block_num+1)&0xff)) {        /* correct block */
        !           978:                                block_num++;
        !           979:                                if(file_bytes_left<(ulong)block_size) {
        !           980:                                        if(fwrite(block,1,file_bytes_left,fp)
        !           981:                                                !=file_bytes_left) {
        !           982:                                                newline();
        !           983:                                                fprintf(statfp,"Error writing to file\n");
        !           984:                                                xmodem_cancel(&xm);
        !           985:                                                bail(1)        !           986:                                        } 
        !           987:                                }
        !           988:                                else {
        !           989:                                        if(fwrite(block,1,block_size,fp)
        !           990:                                                !=(uint)block_size) {
        !           991:                                                newline();
        !           992:                                                fprintf(statfp,"Error writing to file\n");
        !           993:                                                xmodem_cancel(&xm);
        !           994:                                                bail(1)        !           995:                                        } 
        !           996:                                }
        !           997:                                file_bytes_left-=block_size; 
        !           998:                        }
        !           999:                        else {
        !          1000:                                newline();
        !          1001:                                fprintf(statfp,"Block number %u instead of %u\n"
        !          1002:                                        ,hdr_block_num,(block_num+1)&0xff);
        !          1003:                                // dump_block();
        !          1004:                                errors++; 
        !          1005:                        }
        !          1006:                        t=time(NULL)-startfile;
        !          1007:                        if(!t) t=1;
        !          1008:                        cps=(uint)((block_num*(long)block_size)/t);     /* cps so far */
        !          1009:                        if(!cps) cps=1;
        !          1010:                        l=file_bytes/cps;  /* total transfer est time */
        !          1011:                        l-=t;                           /* now, it's est time left */
        !          1012:                        if(l<0) l=0;
        !          1013:                        b=num_blocks(file_bytes, block_size);
        !          1014:                        if(mode&YMODEM)
        !          1015:                                fprintf(statfp,"\rBlock (%lu%s): %lu/%lu  Byte: %lu  Time: %lu:%02lu/"
        !          1016:                                        "%lu:%02lu  CPS: %u  %lu%% "
        !          1017:                                        ,block_size%1024L ? block_size: block_size/1024L
        !          1018:                                        ,block_size%1024L ? "" : "k"
        !          1019:                                        ,block_num
        !          1020:                                        ,b
        !          1021:                                        ,block_num*(long)block_size
        !          1022:                                        ,t/60L
        !          1023:                                        ,t%60L
        !          1024:                                        ,l/60L
        !          1025:                                        ,l%60L
        !          1026:                                        ,cps
        !          1027:                                        ,(long)(((float)block_num/(float)b)*100.0)
        !          1028:                                        );
        !          1029:                        else    /* Xmodem */
        !          1030:                                fprintf(statfp,"\rBlock (%lu%s): %lu  Byte: %lu  Time: %lu:%02lu  "
        !          1031:                                        "CPS: %u "
        !          1032:                                        ,block_size%1024L ? block_size: block_size/1024L
        !          1033:                                        ,block_size%1024L ? "" : "k"
        !          1034:                                        ,block_num
        !          1035:                                        ,block_num*(long)block_size
        !          1036:                                        ,t/60L
        !          1037:                                        ,t%60L
        !          1038:                                        ,cps
        !          1039:                                        );
        !          1040:                }
        !          1041: 
        !          1042:                putcom(ACK);
        !          1043:                if(!(mode&XMODEM) && ftime)
        !          1044:                        setfdate(str,ftime); 
        !          1045:                /* Use correct file size */
        !          1046:                fflush(fp);
        !          1047:                if(file_bytes < (ulong)filelength(fileno(fp)));
        !          1048:                        chsize(fileno(fp),file_bytes);
        !          1049:                fclose(fp);
        !          1050:                t=time(NULL)-startfile;
        !          1051:                if(!t) t=1;
        !          1052:                l=(block_num-1)*block_size;
        !          1053:                if(l>(long)file_bytes)
        !          1054:                        l=file_bytes;
        !          1055:                newline();
        !          1056:                fprintf(statfp,"Successsful - Time: %lu:%02lu  CPS: %lu\n"
        !          1057:                        ,t/60,t%60,l/t);
        !          1058:                if(log) {
        !          1059:                        fprintf(log,"%c %6lu %5u bps %4lu cps %3u errors %5u %4u "
        !          1060:                                "%s %d\n"
        !          1061:                                ,mode&ZMODEM ? 'Z' : 'R'
        !          1062:                                ,l
        !          1063:                                ,30000 /* baud */
        !          1064:                                ,l/t
        !          1065:                                ,errors
        !          1066:                                ,flows
        !          1067:                                ,block_size
        !          1068:                                ,str
        !          1069:                                ,serial_num); 
        !          1070:                }
        !          1071:                if(mode&XMODEM)
        !          1072:                        break;
        !          1073:                total_files--;
        !          1074:                total_bytes-=file_bytes;
        !          1075:                if(total_files>1 && total_bytes)
        !          1076:                        fprintf(statfp,"Remaining - Time: %lu:%02lu  Files: %u  Bytes: %lu\n"
        !          1077:                                ,(total_bytes/cps)/60
        !          1078:                                ,(total_bytes/cps)%60
        !          1079:                                ,total_files
        !          1080:                                ,total_bytes
        !          1081:                                );
        !          1082:        }
        !          1083: }
        !          1084: 
        !          1085: static const char* usage=
        !          1086:        "usage: sexyz <socket> [opts] <cmd> [file | path | +list]\n\n"
        !          1087:        "socket = TCP socket descriptor\n"
        !          1088:        "opts   = o  to overwrite files when receiving\n"
        !          1089:        "         d  to disable dropped carrier detection\n"
        !          1090:        "         a  to sound alarm at start and stop of transfer\n"
        !          1091:        "         p  to pause after abnormal exit (error)\n"
        !          1092:        "cmd    = v  to display detailed version information\n"
        !          1093:        "         sx to send Xmodem     rx to recv Xmodem\n"
        !          1094:        "         sX to send Xmodem-1k  rc to recv Xmodem-CRC\n"
        !          1095:        "         sy to send Ymodem     ry to recv Ymodem\n"
        !          1096:        "         sY to send Ymodem-1k  rg to recv Ymodem-G\n"
        !          1097:        "         sz to send Zmodem     rz to recv Zmodem\n"
        !          1098:        "file   = filename to send or receive\n"
        !          1099:        "path   = path to receive files into\n"
        !          1100:        "list   = name of text file with list of filenames to send or receive\n";
        !          1101: 
        !          1102: /***************/
        !          1103: /* Entry Point */
        !          1104: /***************/
        !          1105: int main(int argc, char **argv)
        !          1106: {
        !          1107:        char    str[256],*p
        !          1108:                        ,*fname[MAX_FNAMES];
        !          1109:        int     i;
        !          1110:        uint    fnames=0;
        !          1111:        FILE*   fp;
        !          1112:        FILE*   log=NULL;
        !          1113:        BOOL    b;
        !          1114:        char    compiler[32];
        !          1115: 
        !          1116:        DESCRIBE_COMPILER(compiler);
        !          1117: 
        !          1118:        errfp=stderr;
        !          1119:        statfp=stdout;
        !          1120: 
        !          1121:        sscanf("$Revision: 1.7 $", "%*s %s", revision);
        !          1122: 
        !          1123:        fprintf(statfp,"\nSynchronet External X/Y/Zmodem  v%s-%s"
        !          1124:                "  Copyright 2003 Rob Swindell\n\n"
        !          1125:                ,revision
        !          1126:                ,PLATFORM_DESC
        !          1127:                );
        !          1128: 
        !          1129: #if 0
        !          1130:        if(argc>1) {
        !          1131:                fprintf(statfp,"Command line: ");
        !          1132:                for(i=1;i<argc;i++)
        !          1133:                        fprintf(statfp,"%s ",argv[i]);
        !          1134:                fprintf(statfp,"\n",statfp);
        !          1135:        }
        !          1136: #endif
        !          1137: 
        !          1138:        for(i=1;i<argc;i++) {
        !          1139: 
        !          1140:                if(sock==INVALID_SOCKET && isdigit(argv[i][0])) {
        !          1141:                        sock=atoi(argv[i]);
        !          1142:                        continue;
        !          1143:                }
        !          1144: 
        !          1145:                if(!(mode&(SEND|RECV))) {
        !          1146:                        if(toupper(argv[i][0])=='S' || toupper(argv[i][0])=='R') { /* cmd */
        !          1147:                                if(toupper(argv[i][0])=='R')
        !          1148:                                        mode|=RECV;
        !          1149:                                else
        !          1150:                                        mode|=SEND;
        !          1151: 
        !          1152:                                block_size=1024;
        !          1153: 
        !          1154:                                switch(argv[i][1]) {
        !          1155:                                        case 'c':
        !          1156:                                        case 'C':
        !          1157:                                                mode|=CRC;
        !          1158:                                        case 'x':
        !          1159:                                                block_size=128;
        !          1160:                                        case 'X':
        !          1161:                                                mode|=XMODEM;
        !          1162:                                                break;
        !          1163:                                        case 'y':
        !          1164:                                                block_size=128;
        !          1165:                                        case 'Y':
        !          1166:                                                mode|=(YMODEM|CRC);
        !          1167:                                                break;
        !          1168:                                        case 'g':
        !          1169:                                        case 'G':
        !          1170:                                                mode|=(YMODEM|CRC|GMODE);
        !          1171:                                                break;
        !          1172:                                        case 'z':
        !          1173:                                        case 'Z':
        !          1174:                                                mode|=(ZMODEM|CRC);
        !          1175:                                                break;
        !          1176:                                        default:
        !          1177:                                                fprintf(statfp,"Unrecognized command '%s'\n\n",argv[i]);
        !          1178:                                                fprintf(statfp,usage);
        !          1179:                                                exit(1)        !          1180:                                } 
        !          1181:                        }
        !          1182: 
        !          1183:                        else if(toupper(argv[i][0])=='V') {
        !          1184: 
        !          1185:                                fprintf(statfp,"%-8s %s\n",getfname(__FILE__)           ,revision);
        !          1186:                                fprintf(statfp,"%-8s %s\n",getfname(xmodem_source()),xmodem_ver(str));
        !          1187:                                fprintf(statfp,"%-8s %s\n",getfname(zmodem_source()),zmodem_ver(str));
        !          1188: #ifdef _DEBUG
        !          1189:                                fprintf(statfp,"Debug\n");
        !          1190: #endif
        !          1191:                                fprintf(statfp,"Compiled %s %.5s with %s\n",__DATE__,__TIME__,compiler);
        !          1192:                                fprintf(statfp,"%s\n",os_version(str));
        !          1193:                                exit(1);
        !          1194:                        }
        !          1195: 
        !          1196: 
        !          1197:                        else if(toupper(argv[i][0])=='O')
        !          1198:                                mode|=OVERWRITE;
        !          1199: 
        !          1200:                        else if(toupper(argv[i][0])=='D')
        !          1201:                                mode|=IGNORE_DCD;
        !          1202: 
        !          1203:                        else if(toupper(argv[i][0])=='A')
        !          1204:                                mode|=ALARM;
        !          1205: 
        !          1206:                        else if(toupper(argv[i][0])=='P')
        !          1207:                                mode|=PAUSE_ABEND;
        !          1208: 
        !          1209:                        else if(argv[i][0]=='*')
        !          1210:                                mode|=DEBUG; 
        !          1211:                }
        !          1212: 
        !          1213:                else if(argv[i][0]=='+') {
        !          1214:                        if(mode&DIR) {
        !          1215:                                fprintf(statfp,"Cannot specify both directory and filename\n");
        !          1216:                                exit(1)        !          1217:                        }
        !          1218:                        sprintf(str,"%s",argv[i]+1);
        !          1219:                        if((fp=fopen(str,"r"))==NULL) {
        !          1220:                                fprintf(statfp,"Error %d opening filelist: %s\n",errno,str);
        !          1221:                                exit(1)        !          1222:                        }
        !          1223:                        while(!feof(fp) && !ferror(fp) && fnames<MAX_FNAMES) {
        !          1224:                                if(!fgets(str,sizeof(str),fp))
        !          1225:                                        break;
        !          1226:                                truncsp(str);
        !          1227:                                if((fname[fnames]=(char *)malloc(strlen(str)+1))==NULL) {
        !          1228:                                        fprintf(statfp,"Error allocating memory for filename\n");
        !          1229:                                        exit(1)        !          1230:                                }
        !          1231:                                strcpy(fname[fnames++],str); 
        !          1232:                        }
        !          1233:                        fclose(fp); 
        !          1234:                }
        !          1235: 
        !          1236:                else if(mode&(SEND|RECV)){
        !          1237:                        if((fname[fnames]=(char *)malloc(strlen(argv[i])+1))==NULL) {
        !          1238:                                fprintf(statfp,"Error allocating memory for filename\n");
        !          1239:                                exit(1)        !          1240:                        }
        !          1241:                        strcpy(fname[fnames],argv[i]);
        !          1242:                        if(isdir(fname[fnames])) { /* is a directory */
        !          1243:                                if(mode&DIR) {
        !          1244:                                        fprintf(statfp,"Only one directory can be specified\n");
        !          1245:                                        exit(1)        !          1246:                                }
        !          1247:                                if(fnames) {
        !          1248:                                        fprintf(statfp,"Cannot specify both directory and filename\n");
        !          1249:                                        exit(1)        !          1250:                                }
        !          1251:                                if(mode&SEND) {
        !          1252:                                        fprintf(statfp,"Cannot send directory '%s'\n",fname[fnames]);
        !          1253:                                        exit(1);
        !          1254:                                }
        !          1255:                                mode|=DIR; 
        !          1256:                        }
        !          1257:                        fnames++; 
        !          1258:                } 
        !          1259:        }
        !          1260: 
        !          1261:        if(sock==INVALID_SOCKET || sock<1) {
        !          1262:                fprintf(statfp,"!No socket descriptor specified\n\n");
        !          1263:                fprintf(errfp,usage);
        !          1264:                exit(1);
        !          1265:        }
        !          1266: 
        !          1267:        if(!(mode&(SEND|RECV))) {
        !          1268:                fprintf(statfp,"!No command specified\n\n");
        !          1269:                fprintf(statfp,usage);
        !          1270:                exit(1)        !          1271:        }
        !          1272: 
        !          1273:        if(mode&(SEND|XMODEM) && !fnames) { /* Sending with any or recv w/Xmodem */
        !          1274:                fprintf(statfp,"!Must specify filename or filelist\n\n");
        !          1275:                fprintf(statfp,usage);
        !          1276:                exit(1)        !          1277:        }
        !          1278: 
        !          1279: 
        !          1280:        if(mode&DIR)
        !          1281:                backslash(fname[0]);
        !          1282: 
        !          1283:        if(mode&ALARM) {
        !          1284:                BEEP(1000,500);
        !          1285:                BEEP(2000,500);
        !          1286:        }
        !          1287: 
        !          1288:        if(!winsock_startup())
        !          1289:                bail(2);
        !          1290: #if 0
        !          1291:        /* Non-blocking socket I/O */
        !          1292:        val=1;
        !          1293:        ioctlsocket(sock,FIONBIO,&val); 
        !          1294: #endif
        !          1295: 
        !          1296:        /* Enable the Nagle Algorithm */
        !          1297:        b=0;
        !          1298:        setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(char*)&b,sizeof(b));
        !          1299: 
        !          1300:        if(!DCDHIGH) {
        !          1301:                newline();
        !          1302:                fprintf(statfp,"No carrier\n");
        !          1303:                bail(1)        !          1304:        }
        !          1305: 
        !          1306:        p=getenv("DSZLOG");
        !          1307:        if(p) {
        !          1308:                if((log=fopen(p,"w"))==NULL) {
        !          1309:                        fprintf(statfp,"Error opening DSZLOG file: %s\n",p);
        !          1310:                        bail(1)        !          1311:                }
        !          1312:        }
        !          1313: 
        !          1314:        startall=time(NULL);
        !          1315: 
        !          1316:        if(mode&RECV)
        !          1317:                receive_files(fname, fnames, log);
        !          1318:        else
        !          1319:                send_files(fname, fnames, log);
        !          1320: 
        !          1321:        bail(0);
        !          1322:        return(0);
        !          1323: }
        !          1324: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.