home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * Copyright P.J.Ruczynski 1990
- * This software is free for redistribution and re-use as long as this
- * copyright is included in all source files. This software is supplied
- * as is and no responsibilty is taken by the author for any problems
- * arising from this code.
- *
- * File name - hd.c
- *
- * Module name - HD
- *
- * Author - P.J.Ruczynski <pjr@pyra.co.uk>
- *
- * First Release - 16 Feb 1990
- *
- * Version number - 1.4
- *
- * Description - A hexdump formatting tool, this can take input from
- * stdin or a file and print it to stdout in a neat
- * hexdump format.
- * Basically, a better/different(*) version of od.
- *
- * (*) delete as you think appropriate :-)
- *
- * Revision List
- *
- * pjr 08.05.89 Added offset numbering.
- *
- * pjr 11.05.89 Added compressed output format.
- *
- * pjr 30.05.89 Changed to allow any block size to be used, default
- * is still 1024 though.
- *
- * pjr 31.05.89 Added version printing option.
- *
- * pjr 02.06.89 Added start and end block specification.
- *
- ******************************************************************************/
-
- #define VERSION "1.4 (14.09.89)"
- #define PRINTUSAGE fprintf(stderr,"Usage: %s [-cnov] [-b n] [-sp|-sn n] [-sb n] [-eb n] [filename]\n", progname);
-
- /*
- * This file contains the following routines:
- *
- * main()
- * get_options()
- * openfile()
- * closefile()
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <string.h>
- #include <fcntl.h>
- #include "hexprint.h"
-
- #define MAXLINE 256 /* Length of character strings. */
- #define MAX_BUFSIZ 1024 /* default read bufer size */
-
- /*
- * these are control vars for the hexprint routine
- */
- extern int offset_print; /* only print offsets on request */
- extern long offset; /* default start offset for printing */
- extern int hex_compression; /* compress identical lines */
-
- /*
- * option variables
- */
- char progname[MAXLINE]; /* Name of this program. */
- int b_start = 1; /* start block no to be printed */
- int b_end = 0; /* end block no to be printed */
- int b_size = MAX_BUFSIZ; /* block size */
- int blocking_on = FALSE; /* only block up on request */
- char fname[MAXLINE]; /* name of input file (if any) */
- int block_numbering = FALSE; /* output number of each block ? */
- int print_start_block = FALSE; /* print the very first diff size block ? */
- int sb_size = 0; /* staring block size */
- long n_blocks = 0; /* no blocks to print, 0 => all */
-
- /*
- * get_options
- *
- * Read and process command line options.
- */
- /*****************************************************************************/
- void get_options(argc,argv)
- /*****************************************************************************/
- int argc;
- char *argv[];
- {
- int i;
-
- fname[0] = 0; /* indicate no filename input */
- argc-- ; argv++ ; /* skip the program name */
-
- while (argc > 0) /* now get the rest */
- {
- if (argv[0][0] == '-')
- switch (argv[0][1])
- {
- case 'b' : /* block size to output */
- argv++;
- b_size = (int)strtol(&argv[0][0], (char **)NULL, 0);
- printf("block size = %d (0x%x) bytes\n",
- b_size,(unsigned)b_size);
- blocking_on = TRUE;
- argc--;
- break;
- case 'c' :
- case 'n' :
- case 'o' :
- case 'v' :
- i = 1;
- while (argv[0][i])
- {
- switch (argv[0][i])
- {
- case 'c' : /* compress identical lines */
- hex_compression = TRUE;
- break;
- case 'n' : /* switch on block numbering */
- block_numbering = TRUE;
- blocking_on = TRUE;
- break;
- case 'o' : /* switch on offset printing */
- offset_print = TRUE;
- break;
- case 'v' : /* print the version of this hd */
- printf("%s version %s Author P.Ruczynski\n",
- progname,VERSION);
- break;
- default : PRINTUSAGE
- exit(1);
- } /* end of switch */
- i++;
- } /* end of while */
- break;
- case 'e' : /* end block options */
- switch (argv[0][2])
- {
- case 'b' : /* do not print starting block */
- argv++;
- b_end = strtol(&argv[0][0], (char **)NULL, 0);
- printf("last block printed = %d (0x%x) bytes\n",
- b_end,(unsigned)b_end);
- argc--;
- break;
- default: PRINTUSAGE
- exit(1);
- }
- break;
- case 's' : /* starting block options */
- switch (argv[0][2])
- {
- case 'p' : /* print the starting block */
- print_start_block = TRUE;
- /* FALL THROUGH */
- case 'n' : /* do not print starting block */
- argv++;
- sb_size = strtol(&argv[0][0], (char **)NULL, 0);
- printf("starting block size = %d (0x%x) bytes\n",
- sb_size,(unsigned)sb_size);
- argc--;
- break;
- case 'b' : /* get the starting block number */
- argv++;
- b_start = strtol(&argv[0][0], (char **)NULL, 0);
- printf("first block printed = %d (0x%x) bytes\n",
- b_start,(unsigned)b_start);
- argc--;
- break;
- default: PRINTUSAGE
- exit(1);
- }
- break;
- case '?' :
- default : PRINTUSAGE
- exit(1);
- } /* end of case */
- else /* not an option so must be file name */
- {
- strcpy(&fname[0], &argv[0][0]);
- printf("input file = %s\n",fname);
- }
-
- argc-- ;
- argv++ ;
-
- } /* end of while loop */
-
- } /* end of get_options */
-
-
- /*
- * openfile
- *
- * open the requested file or assign stdin for reading
- */
- /*****************************************************************************/
- int openfile(fname)
- /*****************************************************************************/
- char *fname;
- {
- int fd; /* file descriptor to read from */
-
- if (fname[0] != 0)
- if ((fd = open(fname, O_RDONLY)) < 0)
- {
- perror(progname);
- exit(1);
- }
- else
- return(fd);
- else
- return(0); /* if no file then stdin */
- } /* end of openfile */
-
-
- /*
- * closefile
- *
- * close the given file descriptor
- */
- /*****************************************************************************/
- void closefile(fd)
- /*****************************************************************************/
- int fd;
- {
- if (fd != 0)
- close(fd);
- } /* end of closefile */
-
-
- /*
- * printfile
- *
- * print the given file descriptor
- */
- /*****************************************************************************/
- void printfile(fd)
- /*****************************************************************************/
- int fd;
- {
- char *buf; /*[MAX_BUFSIZ]; */
- int n, x=0, y=0, i;
- long bn = 1;
-
- if ((buf = (char *)malloc(b_size)) == (char *)NULL)
- {
- printf("%s: error in block size memory allocation\n",progname);
- exit(1);
- }
-
- /*
- * this first 'if' handles the start block case (if there is one)
- */
- if (sb_size != 0)
- {
- x = sb_size % MAX_BUFSIZ; /* the very last bit */
- y = sb_size / MAX_BUFSIZ; /* the no of full bufs */
- sb_size = MAX_BUFSIZ; /* optimum read size. 1K */
-
- if ((block_numbering) && (print_start_block))
- printf("start block\n");
-
- for (i=0; i<=y; i++)
- {
- if (i==y)
- sb_size = x;
-
- if (((n=read(fd, &buf[0], sb_size)) > 0) &&
- (print_start_block))
- hexprint(&buf[0], n);
-
- offset += n;
- }
-
- if (((blocking_on) || (hex_compression))
- && (print_start_block))
- printf("\n");
- }
-
- while ((n = read(fd, &buf[0], b_size)) > 0)
- {
- if ((block_numbering) && (bn >= b_start) &&
- ((bn <= b_end) || (b_end == 0)))
- {
- printf("block number %d (0x%x) ", bn, bn);
- if (n < b_size)
- printf("size = %d",n);
- printf("\n");
- }
-
- if (blocking_on)
- {
- if (bn >= b_start)
- {
- if (b_end == 0)
- {
- hexprint(&buf[0], n);
- offset += n;
- }
- else if (bn <= b_end)
- {
- hexprint(&buf[0], n);
- offset += n;
- }
- }
- bn++;
- }
- else
- {
- hexprint(&buf[0], n);
- offset += n;
- }
-
- if (((blocking_on) || (hex_compression)) &&
- (bn >= b_start) && ((bn <= b_end) || (b_end == 0)))
- printf("\n");
- }
-
- free(buf);
-
- } /* end of printfile */
-
- /*
- * main
- */
- /*****************************************************************************/
- main(argc,argv)
- /*****************************************************************************/
- int argc;
- char **argv;
- {
- int fd; /* file descriptor to read from */
-
- strcpy(progname, argv[0]); /* Save this program name. */
- get_options(argc,argv); /* Read and process command line options. */
-
- fd = openfile(fname); /* do this cos input maybe stdin */
- printfile(fd);
- closefile(fd);
-
- exit(0);
-
- } /* end of main */
-
-
-