home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume2 / mcat / mcat.c next >
Encoding:
C/C++ Source or Header  |  1991-08-07  |  5.5 KB  |  247 lines

  1. /*
  2.  * This file is mcat.c and contains a sort of cat utility for use with
  3.  * pmap devices.  It was originally written on sequent Dynix 2.1.1.
  4.  *
  5.  * to do:
  6.  *    mmap disk files.
  7.  *    mcat multiple files in, out.
  8.  *    -x write at offset x.
  9.  *    trunc old disk files.
  10.  *
  11.  * Original Author: K. Richard Magill Fri Nov 20 16:00:53 EST 1987
  12.  * Last Mod Fri Nov 27 18:06:15 EST 1987, by rich@oxtrap
  13.  *
  14.  *$Header: /u1/rich/bin/src/RCS/mcat.c,v 1.1 87/11/27 18:06:45 rich Exp $
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <sys/types.h>
  19. #include <sys/file.h>
  20. #include <sys/ioctl.h>
  21. #include <sys/mman.h>
  22. #include <sys/stat.h>
  23. #include <machine/pmap.h>
  24.  
  25. #define Perror(s)    {if(Silent==0)perror(s);}
  26.  
  27. char *valloc();
  28.  
  29. main(argc, argv)
  30. int argc;
  31. char *argv[];
  32. {
  33.     char *InBase = ((char *) 0);
  34.     char *OutBase = ((char *) 0);
  35.  
  36.     int BufferSize = BUFSIZ;
  37.     int InPut = fileno(stdin);
  38.     int OutPut = fileno(stdout);
  39.     int Silent = 0;
  40.     int Verbose = 0;
  41.     int WriteFlags = 0;
  42.     int c;
  43.  
  44.     struct pmap_ioc InSize, OutSize;
  45.     struct stat Readable;
  46.  
  47.     extern char *optarg;
  48.     extern int optind;
  49.  
  50. /*
  51.  * parse args.
  52.  */
  53.  
  54.     while ((c = getopt(argc, argv, "b:i:o:sv")) != EOF) {
  55.         switch (c) {
  56.  
  57.         case 'b':
  58.             BufferSize = atoi(optind);
  59.  
  60.             if (Verbose != 0) {
  61.                 (void) fprintf(stderr,
  62.                            "%s: Using %d byte i/o.\n",
  63.                            argv[0], BufferSize);
  64.             } /* verbose */
  65.  
  66.             break;
  67.  
  68.         case 'i':
  69.  
  70.             if ((InPut = open(optarg, O_RDONLY, 0666)) < 0) {
  71.                 Perror("opening input:");
  72.                 exit(1);
  73.             } /* on error opening for read */
  74.  
  75.             break;
  76.  
  77.         case 'o':
  78.             if (access(optarg, F_OK) == 0) {
  79.                 if (Verbose != 0) {
  80.                     (void) fprintf(stderr, "%s: output exists.\n", argv[0]);
  81.                 } /* verbose */
  82.  
  83.                 if (access(optarg, R_OK) == 0) {
  84.                     if (Verbose != 0) {
  85.                         (void) fprintf(stderr, "%s: output is readable.\n", argv[0]);
  86.                     } /* verbose */
  87.  
  88.                     WriteFlags |= O_RDWR;
  89.                 }
  90.  
  91.             } else {
  92.                 if (Verbose != 0) {
  93.                     (void) fprintf(stderr, "%s: output does not exist.  creating.\n", argv[0]);
  94.                 } /* verbose */
  95.  
  96.                 WriteFlags = O_CREAT | O_RDWR;
  97.             }
  98.  
  99.             if ((OutPut = open(optarg, WriteFlags, 0666)) < 0) {
  100.                 Perror("mcat: opening output");
  101.                 exit(1);
  102.             } /* on error opening for write */
  103.  
  104.             break;
  105.  
  106.         case 's':
  107.             Silent = 1;
  108.             break;
  109.  
  110.         case 'v':
  111.             Verbose = 1;
  112.             break;
  113.  
  114.         case '?':
  115.         default:
  116.             if (Silent == 0) {
  117.                 (void) fprintf(stderr, "%s: usage: -b buffer_size -i input_file -o output_file -s -v\n", argv[0]);
  118.             } /* not silent */
  119.  
  120.             exit(1);
  121.  
  122.         } /* switch on switch character */
  123.     } /* while there are switch characters */
  124.  
  125. /*
  126.  * I presume that if the ioctl fails, this is not a pmap device and we
  127.  * aren't mapping.  If you know of a better way to check a a descriptor
  128.  * for mmap'ability, (short of chasing the major number through the kernel),
  129.  * let me know.
  130.  */
  131.  
  132.     if (ioctl(InPut, PMAPIOCGETP, &InSize) == 0) { /* not pmap */
  133.         if ((InBase = valloc(InSize.pi_size)) == 0) {
  134.             Perror("valloc'ing output buffer:");
  135.             exit(1);
  136.         } /* on error valloc'ing */
  137.  
  138.         if (mmap(InBase, InSize.pi_size, PROT_READ, MAP_SHARED,
  139.              InPut, 0) != 0) {
  140.             Perror("on error mmap'ing input:");
  141.             exit(1);
  142.         } /* on error mmap'ing input */
  143.  
  144.         if (Verbose != 0) {
  145.             (void) fprintf(stderr, "%s: mmap'ing input.\n",
  146.                        argv[0]);
  147.         } /* verbose */
  148.  
  149.     } /* not mapped or not mappable */
  150.  
  151.     if ((ioctl(OutPut, PMAPIOCGETP, &OutSize) == 0)) { /* not mapping */
  152.         if  ((OutBase = valloc(OutSize.pi_size)) == 0) {
  153.             Perror("valloc'ing for output buffer:");
  154.             exit(1);
  155.         } /* on valloc error */
  156.  
  157.         if (mmap(OutBase, OutSize.pi_size, PROT_RDWR, MAP_SHARED,
  158.              OutPut, 0) != 0) {
  159.             Perror("mmap'ing output:");
  160.  
  161.             if (Silent == 0) {
  162.                 (void) fprintf(stderr, "%s: remember you can't redirect output.\n", argv[0]);
  163.             } /* not silent */
  164.  
  165.             exit(1);
  166.         } /* on error mmap'ing output */
  167.  
  168.         if (Verbose != 0) {
  169.             (void) fprintf(stderr, "%s: mmap'ing output.\n",
  170.                        argv[0]);
  171.         } /* verbose */
  172.  
  173.     } /* not mapped or not mappable */
  174.  
  175.     if (InBase != ((char *) NULL)) { /* mapping input */
  176.         if (OutBase != ((char *) NULL)) { /* and output */
  177.             bcopy(InBase, OutBase,
  178.                   (InSize.pi_size < OutSize.pi_size)
  179.                   ? InSize.pi_size : OutSize.pi_size);
  180.  
  181.         } else { /* map in, no map out */
  182.             int ReallyWrote;
  183.  
  184.             while (InSize.pi_size > 0) {
  185.                 if (BufferSize > InSize.pi_size) {
  186.                     BufferSize = InSize.pi_size;
  187.                 } /* if buffer now holds it all */
  188.  
  189.                 if ((ReallyWrote = write(OutPut, InBase,
  190.                              BufferSize)) == -1) {
  191.                     Perror("writing output:");
  192.                     exit(1);
  193.                 } /* on error writing */
  194.  
  195.                 InSize.pi_size -= ReallyWrote;
  196.                 InBase += ReallyWrote;
  197.             }    /* while data to write */
  198.         } /* if mapping output */
  199.  
  200.     } else { /* not mapping input */
  201.  
  202.         if (OutBase != ((char *) NULL)) { /* but mapping output */                int ReallyRead = 1;
  203.  
  204.             while (ReallyRead != 0 && OutSize.pi_size > 0) {
  205.                 if (BufferSize > OutSize.pi_size) {
  206.                     BufferSize = OutSize.pi_size;
  207.                 } /* if buffer now holds it all */
  208.  
  209.                 if ((ReallyRead = read(InPut, OutBase,
  210.                              BufferSize)) == -1) {
  211.                     Perror("reading input:");
  212.                     exit(1);
  213.                 } /* on error reading */
  214.  
  215.                 OutSize.pi_size -= ReallyRead;
  216.                 OutBase += ReallyRead;
  217.             }    /* while data to write */
  218.  
  219.         } else { /* mapping nothing, should use cat instead */
  220.             if (Silent == 0) {
  221.                 (void) fprintf(stderr, "%s: not mapping anything.  use cat instead.\n", argv[0]);
  222.             } /* not silent */
  223.  
  224.             exit(1);
  225.         } /* if mapping output */
  226.     } /* if mapping input */
  227.  
  228.     exit(0);
  229. } /* main() */
  230.  
  231. /*
  232.  * $Log:    mcat.c,v $
  233.  * Revision 1.1  87/11/27  18:06:45  rich
  234.  * Initial revision
  235.  * 
  236.  *
  237.  * Local Variables:
  238.  * comment-column: 0
  239.  * fill-column: 75
  240.  * fill-prefix: " * "
  241.  * mode: c
  242.  * version-control: t
  243.  * End:
  244.  */
  245.  
  246. /* end of mcat.c */
  247.