home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / tu / tuucxx.c < prev    next >
C/C++ Source or Header  |  2001-10-30  |  7KB  |  211 lines

  1. char *vers = "copytape version 1.2, 15 May 1987";
  2.  
  3. /* copytape -- tape-to-tape copy program */
  4.  
  5. /*
  6.   F. da Cruz, Columbia University Center for Computing Activities, May 1987
  7.  
  8.   fdc@columbia.edu
  9.  
  10.   Parts cribbed from Jim Guyton's readtape and writetape programs, and from
  11.   ansitar.  If run with debug printout, output tape is slightly longer than
  12.   input tape.  Used in production for many years on SunOS 4.1.  Might need
  13.   adaption to other operating systems.
  14.  
  15.   Copyright 1987, Trustees of Columbia University in the City of New York.
  16.   Free redistribution and use allowed, all standard disclaimers apply.
  17. */
  18.  
  19. /* Includes */
  20.  
  21. #include <stdio.h>            /* standard i/o */
  22. #include <sys/types.h>            /* data types needed by below */
  23. #include <sys/mtio.h>            /* magtape i/o */
  24. #include <sys/ioctl.h>            /* i/o control */
  25.  
  26. /* I/O descriptors, flags, etc. */
  27.  
  28. int in, out;                /* input, output tapes */
  29. int teof;                /* input tape eof flag */
  30. int debug = 0, dv = 0;            /* command line option flags */
  31. long copyfile();            /* forward dcl of non-int function */
  32.  
  33. /* Tape stuff */
  34.  
  35. char *indef = "/dev/rmt12";        /* default input drive */
  36. char *outdef = "/dev/rmt13";        /* default output drive */
  37. char *intape = "";
  38. char *outape = "";
  39. struct mtop mtx;            /* tape i/o structure for ioctl */
  40.  
  41. /* Buffer stuff */
  42.  
  43. #define BLKSIZE 30*1024            /* I/O buffer size */
  44. #define BLOCKS 10            /* Number of buffers */
  45. int maxblock = BLKSIZE;
  46. char buf[BLOCKS][BLKSIZE];        /* Declare buffer array */
  47. int buflen[BLOCKS];            /* & array of data lengths per buf */
  48.  
  49. char errbuf[100];            /* Buffer for making error strings */
  50.  
  51. /* Main program */
  52.  
  53. main(argc,argv) int argc; char *argv[]; {
  54.  
  55.     long ct, files, bytes = 0L;
  56.     int filenum = 1;
  57.     char x, *xp;
  58.  
  59.     while (--argc > 0) {        /* Parse options */
  60.     argv++;
  61.     if (**argv == '-') {
  62.         x = *(*argv+1);        /* Option letter */
  63.         xp = *argv+1;        /* Point past dash */
  64.         while (x) {            /* Loop thru bundled options */
  65.         switch(x) {
  66.           case 'd':        /* Debugging display */
  67.             debug = 1;
  68.             break;
  69.           case 'f':        /* From device */
  70.             if (*(xp+1)) fatal("Invalid argument bundling");
  71.             intape = *++argv;
  72.             argc--;
  73.             if (*intape == '-' || argc <= 0)
  74.               fatal("-f argument missing");
  75.             break;
  76.           case 't':        /* To device */
  77.             if (*(xp+1)) fatal("Invalid argument bundling");
  78.             outape = *++argv;
  79.             argc--;
  80.             if (*outape == '-' || argc <= 0)
  81.               fatal("-t argument missing");
  82.             break;
  83.           case 'v':        /* Version info */
  84.             dv = 1;
  85.             break;
  86.           default  : usage();
  87.             }
  88.         x = *++xp;        /* See if options are bundled */
  89.         }
  90.     } else usage();
  91.     }
  92.     if (debug || dv) {            /* Display version info if asked */
  93.     fprintf(stderr,"%s\n",vers);
  94.     fprintf(stderr,"%d buffers, %d bytes each\n\n",BLOCKS,maxblock);
  95.     }
  96.   
  97.     if (!*intape) intape = indef;    /* Supply defaults */
  98.     if (!*outape) outape = outdef;
  99.     if (strcmp(intape,"0") == 0) intape = indef;
  100.     if (strcmp(intape,"1") == 0) intape = outdef;
  101.     if (strcmp(outape,"0") == 0) outape = indef;
  102.     if (strcmp(outape,"1") == 0) outape = outdef;
  103.     if (strcmp(outape,intape) == 0) {
  104.     fprintf(stderr,"You must specify two different tape drives\n");
  105.     exit(1);
  106.     }
  107.     if (debug) {
  108.     fprintf(stderr,"input drive: %s\n",intape);
  109.     fprintf(stderr,"output drive: %s\n",outape);
  110.     }
  111.     in = open(intape, 0);        /* Open input tape */
  112.     if (in > 0)
  113.       printf("Reading from tape '%s'\n", intape);
  114.     else {
  115.     sprintf(errbuf,"Can't open tape %s for reading",intape);
  116.     fatal(errbuf);
  117.     }
  118.     if (rew(in) < 0)             /* Rewind to load point */
  119.        fatal("Can't rewind input tape");
  120.  
  121.     out = open(outape, 1);        /* Open output tape */
  122.     if (out > 0)
  123.       printf("Writing to tape '%s'\n", outape);
  124.     else {
  125.     sprintf(errbuf,"Can't open tape %s for writing",outape);
  126.     fatal(errbuf);
  127.     }
  128.     if (rew(out) < 0)             /* Rewind to load point */
  129.        fatal("Can't rewind output tape");
  130.  
  131.     system("date");            /* Say when starting */
  132.     ct = files = 1;            /* Initialize counters */
  133.     while (ct) {            /* Copy each file on tape */
  134.       if (debug) fprintf(stderr,"\nfile %ld:", files);
  135.       ct = copyfile();            /* Copy the file */
  136.       files++;                /* Count the file */
  137.       bytes += ct;            /* Accumulate total byte count */
  138.     }
  139.     tapemark(out);            /* Write final tapemark */
  140.     close(out);                /* Close tape drives */
  141.     close(in);
  142.     system("date");            /* When done, print messages */
  143.     printf("\nDone, copied %ld bytes in %ld file(s)\n", bytes, (files - 1));
  144.     exit(0);
  145. }
  146.  
  147. long                    /* Copy a file from in to out */
  148. copyfile() {                /* Returns number of bytes read */
  149.  
  150.     int i, blks;            /* Loop control, block count */
  151.     long ct = 0;            /* Character count */
  152.  
  153.     teof = 0;                /* Copy tape blocks till tape eof */
  154.                     /* Do several buffers at a time */
  155.     while (!teof) {
  156.  
  157.     for (blks = i = 0; i < BLOCKS; i++) { /* Read some buffers */
  158.  
  159.         if ((buflen[i] = read(in, buf[i], BLKSIZE)) < 0)
  160.           fatal("I/O error reading tape");
  161.         else if (buflen[i] > 0) {
  162.         blks++;            /* Count this block */
  163.         if (debug) fprintf(stderr," %d:%d",i,buflen[i]);
  164.         } else {            /* Count of 0 means end of tape file */
  165.         if (debug) fprintf(stderr," eof"); 
  166.         teof = 1;        /* Flag tape file eof. */
  167.         break;
  168.         }
  169.     }
  170.     if (debug) fprintf(stderr," [%d]",blks); /* # of blocks read */
  171.  
  172.     for (i = 0; i < blks; i++) {    /* Write out the buffers. */
  173.  
  174.         if (debug) fprintf(stderr," w%d:%d",i,buflen[i]);
  175.         if (write(out, buf[i], buflen[i]) != buflen[i])
  176.           fatal("Write error");
  177.         ct += buflen[i];        /* Keep track of # of bytes written */
  178.         buflen[i] = 0;
  179.     }
  180.     }
  181.     if (debug) fprintf(stderr," tm");
  182.     if (tapemark(out) < 0)        /* Write file mark. */
  183.       fatal("Can't write tape mark");
  184.     return(ct);                /* Return output byte count. */
  185. }
  186.  
  187. tapemark(tf) int tf; {            /* Write a tapemark (file mark) */
  188.     mtx.mt_count = 1;
  189.     mtx.mt_op = MTWEOF;
  190.     return(ioctl(tf, MTIOCTOP, (char *) &mtx));
  191. }
  192.  
  193. rew(tf) int tf; {            /* Rewind tape */
  194.     mtx.mt_op = MTREW;
  195.     return(ioctl(tf, MTIOCTOP, (char *) &mtx));
  196. }
  197.  
  198. fatal(s) char *s; {            /* Fatal error message and exit */
  199.     perror(s);                /* Include last system error */
  200.     exit(1);
  201. }
  202.  
  203. usage() {
  204.     fprintf(stderr,"usage: copytape [-d -v -f intape -t outtape]\n");
  205.     fprintf(stderr,"-d=debug, -v=version, -f=from, -t=to\n");
  206.     fprintf(stderr,"intape default %s, outtape default %s\n",indef,outdef);
  207.     fprintf(stderr,"maximum blocksize: %ld.\n",maxblock);
  208.     fprintf(stderr,"number of blocks buffered: %d.\n",BLOCKS);
  209.     exit(1);
  210. }
  211.