home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / xmodem3.9 / part01 / xmodem.c < prev   
C/C++ Source or Header  |  1991-01-08  |  8KB  |  298 lines

  1. /*
  2.  *  XMODEM -- Implements the Christensen XMODEM protocol, 
  3.  *            for packetized file up/downloading.    
  4.  *
  5.  *    See the README file for some notes on SYS V adaptations.
  6.  *    The program has been successfully run on VAXes (4.3BSD) and SUN-3/4s
  7.  *    (SunOS 3.x) against MEX-PC and ZCOMM/DSZ.
  8.  *
  9.  *  See the README and update.doc files for history and change notes.
  10.  *
  11.  *  Please send bug fixes, additions and comments to:
  12.  *    grandi@noao.edu
  13.  */
  14.  
  15. #include "xmodem.h"
  16.  
  17. main(argc, argv)
  18. int argc;
  19. char **argv;
  20. {
  21.     char *getenv();
  22.     FILE *fopen();
  23.     char *unix_cpm();
  24.     char *strcpy();
  25.     char *strcat();
  26.     char *prtype();
  27.     
  28.     char *fname = filename;        /* convenient place to stash file names */
  29.     char *logfile = "xmodem.log";    /* Name of LOG File */
  30.     
  31.     char *stamptime();        /* for timestamp */
  32.  
  33.     char *defname = "xmodem.in";    /* default file name if none given */
  34.  
  35.     struct stat filestatbuf;    /* file status info */
  36.  
  37.     int index;
  38.     char flag;
  39.     long expsect;
  40.     int fd;
  41.  
  42.     /* initialize option flags */
  43.  
  44.     XMITTYPE = 't';        /* assume text transfer */
  45.     DEBUG = FALSE;        /* keep debugging info in log */
  46.     RECVFLAG = FALSE;    /* not receive */
  47.     SENDFLAG = FALSE;    /* not send either */
  48.     BATCH = FALSE;        /* nor batch */
  49.     CRCMODE = FALSE;    /* use checksums for now */
  50.     DELFLAG = FALSE;    /* don't delete old log file */
  51.     LOGFLAG = TRUE;        /* keep log */
  52.     LONGPACK = FALSE;     /* do not use long packets on transmit */
  53.     MDM7BAT = FALSE;    /* no MODEM7 batch mode */
  54.     YMDMBAT = FALSE;    /* no YMODEM batch mode */
  55.     TOOBUSY = FALSE;    /* not too busy for sleeping in packet read */
  56.     TIPFLAG = FALSE;    /* no special logging on stderr */
  57.     DELAYFLAG = FALSE;    /* don't delay startup for a while */
  58.     NOEOT = FALSE;        /* don't suppress EOT verification */
  59.     CANCAN = FALSE;        /* don't allow CAN-CAN aborts in mid-transfer */
  60.     YMODEMG = FALSE;    /* no YMODEM-G */
  61.  
  62.     fprintf(stderr, "XMODEM Version %s", VERSION);
  63.     fprintf(stderr, " -- UNIX-Microcomputer File Transfer Facility\n");
  64.  
  65.     if (argc == 1)
  66.         {
  67.         help();
  68.         exit(-1);
  69.         }
  70.  
  71.     index = 0;        /* set index for flag loop */
  72.  
  73.     stopsig();        /* suppress keyboard stop signal */
  74.  
  75.     while ((flag = argv[1][index++]) != '\0')
  76.         switch (flag) {
  77.         case '-' : break;
  78.         case 'X' :
  79.         case 'x' : DEBUG = TRUE;  /* turn on debugging log */
  80.                break;
  81.         case 'C' :
  82.         case 'c' : CRCMODE = TRUE; /* enable CRC on receive */
  83.                break;
  84.         case 'D' :
  85.         case 'd' : DELFLAG = TRUE;  /* delete log file */
  86.                break;
  87.         case 'L' :
  88.         case 'l' : LOGFLAG = FALSE;  /* turn off log  */
  89.                break;
  90.         case 'm' :
  91.         case 'M' : MDM7BAT = TRUE;  /* turn on MODEM7 batch protocol */
  92.                BATCH   = TRUE;
  93.                break;
  94.         case 'y' :
  95.         case 'Y' : YMDMBAT = TRUE;  /* turn on YMODEM batch protocol */
  96.                BATCH   = TRUE;
  97.                break;
  98.         case 'k' :
  99.         case 'K' : LONGPACK = TRUE;  /* use 1K packets on transmit */
  100.                break;
  101.         case 't' :
  102.         case 'T' : TOOBUSY = TRUE;  /* turn off sleeping */
  103.                break;
  104.         case 'p' :
  105.         case 'P' : TIPFLAG = TRUE;  /* turn on special handling for SunOS tip */
  106.                break;
  107.         case 'w' :
  108.         case 'W' : DELAYFLAG = TRUE;  /* delay startup */
  109.                break;
  110.         case 'e' :
  111.         case 'E' : NOEOT = TRUE;  /* turn off EOT verification */
  112.                break;
  113.         case 'n' :
  114.         case 'N' : CANCAN = TRUE;  /* allow mid-transfer CAN-CAN */
  115.                break;
  116.         case 'g' :
  117.         case 'G' : YMODEMG = TRUE;  /* YMODEM-G mode */
  118.                CANCAN = TRUE;
  119.                CRCMODE = TRUE;
  120.                YMDMBAT = TRUE;
  121.                break;
  122.         case 'R' :
  123.         case 'r' : RECVFLAG = TRUE;  /* receive file */
  124.                XMITTYPE = gettype(argv[1][index++]);  /* get t/b */
  125.                break;
  126.         case 'S' :
  127.         case 's' : SENDFLAG = TRUE;  /* send file */
  128.                XMITTYPE = gettype(argv[1][index++]);
  129.                break;
  130.         default  : fprintf(stderr, "Invalid Flag %c ignored\n", flag);
  131.                break;
  132.        }
  133.  
  134.     if (DEBUG)
  135.         LOGFLAG = TRUE;
  136.  
  137.     if (LOGFLAG)
  138.        { 
  139.          if ((fname = getenv("HOME")) == 0)    /* Get HOME variable */
  140.         error("XMODEM Fatal Error- Can't get Environment!", FALSE);
  141.          fname = strcat(fname, "/");
  142.          fname = strcat(fname, logfile);
  143.          if (!DELFLAG)
  144.         LOGFP = fopen(fname, "a");  /* append to LOG file */
  145.          else
  146.         LOGFP = fopen(fname, "w");  /* new LOG file */
  147.          if (!LOGFP)
  148.         error("XMODEM Fatal Error- Can't Open Log File", FALSE);
  149.  
  150.          fprintf(LOGFP,"\n++++++++  %s", stamptime());
  151.          fprintf(LOGFP,"XMODEM Version %s\n", VERSION);
  152.          fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
  153.          for (index=2; index<argc; ++index)
  154.         fprintf(LOGFP, " %s", argv[index]);
  155.          fprintf(LOGFP, "\n");
  156.        }
  157.  
  158.     getspeed();        /* get tty-speed for time estimates */
  159.  
  160.     if (RECVFLAG && SENDFLAG)
  161.         error("XMODEM Fatal Error- Both Send and Receive Functions Specified", FALSE);
  162.  
  163.     if (MDM7BAT && (YMDMBAT || YMODEMG))
  164.         error("XMODEM Fatal Error - Both YMODEM and MODEM7 Batch Protocols Specified", FALSE);
  165.  
  166.     if (!RECVFLAG && !SENDFLAG)
  167.         error("XMODEM Fatal Error - Either Send or Receive Function must be chosen!",FALSE);
  168.     
  169.     if (SENDFLAG && argc==2)
  170.         error("XMODEM Fatal Error - No file specified to send",FALSE);
  171.  
  172.     if (RECVFLAG && argc==2)
  173.         {
  174.         /* assume we really want CRC-16 in batch, unless we specify MODEM7 mode, unless we explicitly set CRCMODE */ 
  175.         if (!CRCMODE)
  176.             CRCMODE = MDM7BAT ? FALSE : TRUE;
  177.         fprintf(stderr, "Ready for BATCH RECEIVE");
  178.         fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
  179.         if (!TIPFLAG)
  180.             fprintf(stderr, "Send several Control-X characters to cancel\n");
  181.         logit("Batch Receive Started");
  182.         logitarg(" in %s mode\n", prtype(XMITTYPE));
  183.         strcpy(fname, defname);
  184.         }
  185.  
  186.     if (RECVFLAG && argc>2)
  187.         {
  188.         if(open(argv[2], 0) != -1)  /* check for overwriting */
  189.             {
  190.             logit("Warning -- Target File Exists and is Being Overwritten\n");
  191.             fprintf(stderr, "Warning -- Target File Exists and is Being Overwritten\n");
  192.             }
  193.         fprintf(stderr, "Ready to RECEIVE File %s", argv[2]);
  194.         fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
  195.         if (!TIPFLAG)
  196.             fprintf(stderr, "Send several Control-X characters to cancel\n");
  197.         logitarg("Receiving in %s mode\n", prtype(XMITTYPE));
  198.         strcpy(fname,argv[2]);
  199.         }
  200.  
  201.     if (RECVFLAG)
  202.         {  
  203.         if (DELAYFLAG)        /* delay if -w requested */
  204.             sleep(TIPDELAY);
  205.         setmodes();        /* set tty modes for transfer */
  206.  
  207.         while(rfile(fname) != FALSE);  /* receive files */
  208.  
  209.         flushin();
  210.         restoremodes(FALSE);    /* restore normal tty modes */
  211.  
  212.         sleep(2);        /* give other side time to return to terminal mode */
  213.         exit(0);
  214.         }
  215.  
  216.     if (SENDFLAG && BATCH) 
  217.         {
  218.         if (YMDMBAT)
  219.             {
  220.             ytotleft = 0l;
  221.             yfilesleft = 0;
  222.             for (index=2; index<argc; index++) {
  223.                 if (stat(argv[index], &filestatbuf) == 0) {
  224.                     yfilesleft++;
  225.                     ytotleft += filestatbuf.st_size;
  226.                     if (XMITTYPE == 't') {
  227.                         if((fd=open(argv[index],0)) >= 0) {
  228.                             ytotleft += countnl(fd);
  229.                             close(fd);
  230.                             }
  231.                         }
  232.                     }
  233.                 }
  234.             if (DEBUG)
  235.                 fprintf(LOGFP, "DEBUG YMODEM file count: %d, %ld bytes\n", yfilesleft, ytotleft);
  236.  
  237.             fprintf(stderr, "Ready to YMODEM BATCH SEND");
  238.             fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
  239.             logit("YMODEM Batch Send Started");
  240.             logitarg(" in %s mode\n", prtype(XMITTYPE));
  241.             }
  242.         else if (MDM7BAT)
  243.             {
  244.             fprintf(stderr, "Ready to MODEM7 BATCH SEND");
  245.             fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
  246.             logit("MODEM7 Batch Send Started");
  247.             logitarg(" in %s mode\n", prtype(XMITTYPE));
  248.             }
  249.         if (!TIPFLAG)
  250.             fprintf(stderr, "Send several Control-X characters to cancel\n");
  251.  
  252.         if (DELAYFLAG)        /* delay if -w requested */
  253.             sleep(TIPDELAY);
  254.         setmodes();
  255.         for (index=2; index<argc; index++) {
  256.             if (stat(argv[index], &filestatbuf) < 0) {
  257.                 logitarg("\nFile %s not found\n", argv[index]);
  258.                 tlogitarg("\nFile %s not found\n", argv[index]);
  259.                 continue;
  260.             }
  261.             sfile(argv[index]);
  262.         }
  263.         sfile("");
  264.         flushin();
  265.         restoremodes(FALSE);
  266.  
  267.         logit("Batch Send Complete\n");
  268.         tlogit("Batch Send Complete\n");
  269.         sleep(2);
  270.         exit (0);
  271.         }
  272.  
  273.     if (SENDFLAG && !BATCH) 
  274.         {
  275.         if (stat(argv[2], &filestatbuf) < 0)
  276.             error("Can't find requested file", FALSE);
  277.         expsect = (filestatbuf.st_size/128)+1;
  278.             
  279.         fprintf(stderr, "File %s Ready to SEND", argv[2]);
  280.         fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
  281.         fprintf(stderr, "Estimated File Size %ldK, %ld Sectors, %ld Bytes\n",
  282.               (filestatbuf.st_size/1024)+1, expsect,
  283.             filestatbuf.st_size);
  284.         projtime(expsect, stdout);
  285.         if (!TIPFLAG)
  286.             fprintf(stderr, "Send several Control-X characters to cancel\n");
  287.         logitarg("Sending in %s mode\n", prtype(XMITTYPE));
  288.  
  289.         setmodes();
  290.         sfile(argv[2]);
  291.         flushin();
  292.         restoremodes(FALSE);
  293.  
  294.         sleep(2);
  295.         exit(0);
  296.         }
  297. }
  298.