|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.