/* hexreader.c Hexdump file reader by Adam Rogoyski (apoc@laker.net) Temperance
 * Copyright (C) 1998 Adam Rogoyski
 * Reads output generated by hexdumper.c ((C) Adam Rogoyski) and writes the
 * file back in it's original binary form.  I use both of these files as a 
 * simple way to edit binary files, by using hexdumper to dump the file, 
 * edit that and then rewrite it in binary with this hexreader.  
 * Accepts input from stdin, piped input, or as a file.
 * usage: hexreader dumpedfile -o binaryfile
 *        hexreader --help for more info
 * compile gcc -o hexreader hexreader.c
 * --- GNU General Public License Disclamer ---
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#define LINELENGTH 79

void usage (char *); 


int
main (int argc, char **argv)
{
   char buf[LINELENGTH + 1];
   unsigned char b[16];
   unsigned int bytes[16];
   int i = 0;
   int n = 0;
   int offset = 0;
   FILE *fpin = stdin;
   FILE *fpout = stdout;
   i = 1;
   while (*(argv + i) != NULL)
   {
      if (**(argv + i) == '-')
      {
         switch (*(*(argv + i) + 1))
         {
            case 'o':
               if (*(argv + i + 1) == NULL)
               {
                  usage (*argv);
                  return 0;
               }
               fpout = fopen (*(argv + i + 1), "w");
               if (fpout == NULL)
               {
                  perror (*(argv + i + 1));
                  return EXIT_FAILURE;
               }
               i++;
               break;
            case 'h':
               usage (*argv);
               exit (EXIT_SUCCESS);
               break;
            case '-':
               if (!strncmp (*(argv + i), "--help", 6))
               {
                  usage (*argv);
                  exit (EXIT_SUCCESS);
               }
               break;
         }
      }
      else
      {
         fpin = fopen (*(argv + i), "r");
         if (fpin == NULL)
         {
            perror (*(argv + i));
            return EXIT_FAILURE;
         }
      }
      i++;
   }
   i = 0;
   memset (buf, 0, LINELENGTH + 1);
   memset (bytes, 0, 16 * sizeof (unsigned int));
   memset (b, 0, 16);
   while (fgets(buf, LINELENGTH + 1, fpin) != NULL)
   {
      n = sscanf (buf, "%X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X", &offset,
              &bytes[0], &bytes[1], &bytes[2], &bytes[3], &bytes[4], &bytes[5],
              &bytes[6], &bytes[7], &bytes[8], &bytes[9], &bytes[10],
              &bytes[11], &bytes[12], &bytes[13], &bytes[14], &bytes[15]);
      for (i = 0; i < n - 1; i++)
         b[i] = (unsigned char) bytes[i];
      fwrite (b, sizeof (unsigned char), n - 1, fpout);
      memset (buf, 0, LINELENGTH);
      memset (bytes, 0, 16 * sizeof (unsigned int));
      memset (b, 0, 16);
   }
   fclose (fpin);
   fclose (fpout);
   return EXIT_SUCCESS;
}


void
usage (char *filename)
{
   fprintf (stderr, "hexreader by Adam Rogoyski (apoc@laker.net)\n");
   fprintf (stderr, "usage: %s infile                this will write to stdout\n", filename);
   fprintf (stderr, "usage: %s infile -o outfile\n", filename);
   fprintf (stderr, "usage: unix commands | %s -o outfile\n", filename);
   fprintf (stderr, "flags: -o [filename]    output to filename\n");
   fprintf (stderr, "       -h               this help screen\n");
   fprintf (stderr, "       --help           this help screen\n");
}
