Annotation of sbbs/sbbs3/sexyz.c, revision 1.1.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.