home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is mcat.c and contains a sort of cat utility for use with
- * pmap devices. It was originally written on sequent Dynix 2.1.1.
- *
- * to do:
- * mmap disk files.
- * mcat multiple files in, out.
- * -x write at offset x.
- * trunc old disk files.
- *
- * Original Author: K. Richard Magill Fri Nov 20 16:00:53 EST 1987
- * Last Mod Fri Nov 27 18:06:15 EST 1987, by rich@oxtrap
- *
- *$Header: /u1/rich/bin/src/RCS/mcat.c,v 1.1 87/11/27 18:06:45 rich Exp $
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <sys/ioctl.h>
- #include <sys/mman.h>
- #include <sys/stat.h>
- #include <machine/pmap.h>
-
- #define Perror(s) {if(Silent==0)perror(s);}
-
- char *valloc();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *InBase = ((char *) 0);
- char *OutBase = ((char *) 0);
-
- int BufferSize = BUFSIZ;
- int InPut = fileno(stdin);
- int OutPut = fileno(stdout);
- int Silent = 0;
- int Verbose = 0;
- int WriteFlags = 0;
- int c;
-
- struct pmap_ioc InSize, OutSize;
- struct stat Readable;
-
- extern char *optarg;
- extern int optind;
-
- /*
- * parse args.
- */
-
- while ((c = getopt(argc, argv, "b:i:o:sv")) != EOF) {
- switch (c) {
-
- case 'b':
- BufferSize = atoi(optind);
-
- if (Verbose != 0) {
- (void) fprintf(stderr,
- "%s: Using %d byte i/o.\n",
- argv[0], BufferSize);
- } /* verbose */
-
- break;
-
- case 'i':
-
- if ((InPut = open(optarg, O_RDONLY, 0666)) < 0) {
- Perror("opening input:");
- exit(1);
- } /* on error opening for read */
-
- break;
-
- case 'o':
- if (access(optarg, F_OK) == 0) {
- if (Verbose != 0) {
- (void) fprintf(stderr, "%s: output exists.\n", argv[0]);
- } /* verbose */
-
- if (access(optarg, R_OK) == 0) {
- if (Verbose != 0) {
- (void) fprintf(stderr, "%s: output is readable.\n", argv[0]);
- } /* verbose */
-
- WriteFlags |= O_RDWR;
- }
-
- } else {
- if (Verbose != 0) {
- (void) fprintf(stderr, "%s: output does not exist. creating.\n", argv[0]);
- } /* verbose */
-
- WriteFlags = O_CREAT | O_RDWR;
- }
-
- if ((OutPut = open(optarg, WriteFlags, 0666)) < 0) {
- Perror("mcat: opening output");
- exit(1);
- } /* on error opening for write */
-
- break;
-
- case 's':
- Silent = 1;
- break;
-
- case 'v':
- Verbose = 1;
- break;
-
- case '?':
- default:
- if (Silent == 0) {
- (void) fprintf(stderr, "%s: usage: -b buffer_size -i input_file -o output_file -s -v\n", argv[0]);
- } /* not silent */
-
- exit(1);
-
- } /* switch on switch character */
- } /* while there are switch characters */
-
- /*
- * I presume that if the ioctl fails, this is not a pmap device and we
- * aren't mapping. If you know of a better way to check a a descriptor
- * for mmap'ability, (short of chasing the major number through the kernel),
- * let me know.
- */
-
- if (ioctl(InPut, PMAPIOCGETP, &InSize) == 0) { /* not pmap */
- if ((InBase = valloc(InSize.pi_size)) == 0) {
- Perror("valloc'ing output buffer:");
- exit(1);
- } /* on error valloc'ing */
-
- if (mmap(InBase, InSize.pi_size, PROT_READ, MAP_SHARED,
- InPut, 0) != 0) {
- Perror("on error mmap'ing input:");
- exit(1);
- } /* on error mmap'ing input */
-
- if (Verbose != 0) {
- (void) fprintf(stderr, "%s: mmap'ing input.\n",
- argv[0]);
- } /* verbose */
-
- } /* not mapped or not mappable */
-
- if ((ioctl(OutPut, PMAPIOCGETP, &OutSize) == 0)) { /* not mapping */
- if ((OutBase = valloc(OutSize.pi_size)) == 0) {
- Perror("valloc'ing for output buffer:");
- exit(1);
- } /* on valloc error */
-
- if (mmap(OutBase, OutSize.pi_size, PROT_RDWR, MAP_SHARED,
- OutPut, 0) != 0) {
- Perror("mmap'ing output:");
-
- if (Silent == 0) {
- (void) fprintf(stderr, "%s: remember you can't redirect output.\n", argv[0]);
- } /* not silent */
-
- exit(1);
- } /* on error mmap'ing output */
-
- if (Verbose != 0) {
- (void) fprintf(stderr, "%s: mmap'ing output.\n",
- argv[0]);
- } /* verbose */
-
- } /* not mapped or not mappable */
-
- if (InBase != ((char *) NULL)) { /* mapping input */
- if (OutBase != ((char *) NULL)) { /* and output */
- bcopy(InBase, OutBase,
- (InSize.pi_size < OutSize.pi_size)
- ? InSize.pi_size : OutSize.pi_size);
-
- } else { /* map in, no map out */
- int ReallyWrote;
-
- while (InSize.pi_size > 0) {
- if (BufferSize > InSize.pi_size) {
- BufferSize = InSize.pi_size;
- } /* if buffer now holds it all */
-
- if ((ReallyWrote = write(OutPut, InBase,
- BufferSize)) == -1) {
- Perror("writing output:");
- exit(1);
- } /* on error writing */
-
- InSize.pi_size -= ReallyWrote;
- InBase += ReallyWrote;
- } /* while data to write */
- } /* if mapping output */
-
- } else { /* not mapping input */
-
- if (OutBase != ((char *) NULL)) { /* but mapping output */ int ReallyRead = 1;
-
- while (ReallyRead != 0 && OutSize.pi_size > 0) {
- if (BufferSize > OutSize.pi_size) {
- BufferSize = OutSize.pi_size;
- } /* if buffer now holds it all */
-
- if ((ReallyRead = read(InPut, OutBase,
- BufferSize)) == -1) {
- Perror("reading input:");
- exit(1);
- } /* on error reading */
-
- OutSize.pi_size -= ReallyRead;
- OutBase += ReallyRead;
- } /* while data to write */
-
- } else { /* mapping nothing, should use cat instead */
- if (Silent == 0) {
- (void) fprintf(stderr, "%s: not mapping anything. use cat instead.\n", argv[0]);
- } /* not silent */
-
- exit(1);
- } /* if mapping output */
- } /* if mapping input */
-
- exit(0);
- } /* main() */
-
- /*
- * $Log: mcat.c,v $
- * Revision 1.1 87/11/27 18:06:45 rich
- * Initial revision
- *
- *
- * Local Variables:
- * comment-column: 0
- * fill-column: 75
- * fill-prefix: " * "
- * mode: c
- * version-control: t
- * End:
- */
-
- /* end of mcat.c */
-