home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / xmodem 3.10 / xmodem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-10  |  8.4 KB  |  305 lines  |  [TEXT/MPS ]

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