Ask Question

Name:
Title:
Your Question:

Answer Question

Name:
Your Answer:
User Submitted Source Code!


Description:
  bin2exe
Language: C/C++
Code:
/** \file
 \brief Binary to hex converter
 \author Tomasz Ostrowski, ot at epf dot pl
 \date October 2006
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

/** Flag set by `--verbose'. */
static int verbose_flag;

char fin[255];                ///< input filename
char fout[255];           ///< output filename
char strtmp[255];           ///< temporary string
char separator[255];      ///< separator for output strings
int bytes_per_string;      ///< how many bytes convert to string? (byte/word/quad/... data)
unsigned int wrap_line;     ///< wrap line after about N chars
/** \brief Print some help */
void help(char *exename)
{
    puts("\nBinary to hex string (C-like) converter");
    printf("\nUsage: %s --i <input_filename> --o <output_filename>\n", exename);
    puts(" i.e. bin2hex --i myfile.dat --o myfile.c");
    puts("Other options:");
    puts(" --s <separator> select separator for output string (i.e. comma or comma+space)");
    puts(" --b <bytes_per_string> read byte (default), word, int (0xAB/0xABCD/0x89ABCDEF)");
    puts(" --w <wrap_line> wrap line after specified number of chars (default: 70)");
    puts(" multi-bytes values treated as little endian");
    puts("\nauthor: Tomasz Ostrowski, ot at epf dot pl");
    puts("created: 2006.10.23\n");
}


/** \brief Init default options (if not exist in command line) */
void init_options(void)
{
    strcpy(fin,"");
    strcpy(fout,"hex_out.c");
    strcpy(separator, ", ");       //default separator
     bytes_per_string = 1;          //read bytes (not words or ints) from file
     wrap_line = 70;
}


int
main (argc, argv)
int argc;
char **argv;
{
    int c;
    int i;
    unsigned int chars_in_line=0;     ///< number of chars in current line
    int stringlength;     ///< length of single converted string
    long lSize;               ///< filesize
    unsigned char *buffer;          ///< pointer to buffer for input file
    int option_count=0; ///< command-line options counter
    FILE *fileIn, *fileOut; ///< input and output file


    init_options();

    while (1)
    {
        static struct option long_options[] =
            {
                /* Flag-type options */
                {"verbose", no_argument,       &verbose_flag, 1
                },
                /* Non-flag options distinguished by their indices. */
                {"add",     no_argument,       0, 'a'
                },
                {"bytes_per_string",    required_argument, 0, 'b'
                },
                {"in",  required_argument, 0, 'i'
                },
                {"out",  required_argument, 0, 'o'
                },
                {"separator",    required_argument, 0, 's'
                },
                {"wrap_line",    required_argument, 0, 'w'
                },
                {0, 0, 0, 0
                }
            };
        /* getopt_long stores the option index here. */
        int option_index = 0;

        c = getopt_long (argc, argv, "abc:d:f:",
                         long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
        {
            if(option_count<1)
                help(argv[0]); // print help if no arguments
            break;
        }
        option_count++;

        switch (c)
        {
            case 0:
            /* If this option set a flag, do nothing else now. */
            if (long_options[option_index].flag != 0)
                break;
            printf ("option %s", long_options[option_index].name);
            if (optarg)
                printf (" with arg %s", optarg);
            printf ("\n");
            break;

            case 'a':
            puts ("option -a\n");
            break;

            case 'b':
            printf ("option -b with value `%s'\n", optarg);
            bytes_per_string = atoi(optarg);
            if(bytes_per_string<1 || bytes_per_string>10)
            {
                puts("Required 0<bytes_per_string<=10");
                exit(1);
            }
            break;

            case 'c':
            printf ("option -c with value `%s'\n", optarg);
            break;

            case 'i':
            printf ("option -i with value `%s'\n", optarg);
            strcpy(fin, optarg);
            break;

            case 'o':
            printf ("option -o with value `%s'\n", optarg);
            strcpy(fout, optarg);
            break;

            case 's':
            printf ("option -s with value `%s'\n", optarg);
            strcpy(separator, optarg);
            break;

            case '?':
            /* getopt_long already printed an error message. */
            help(argv[0]);
            break;

            default:
            abort ();
        }
    }


    if (verbose_flag)
        puts ("verbose flag is set");

    /* Print any remaining command line arguments (not options). */
    if (optind < argc)
    {
        printf ("non-option ARGV-elements: ");
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        putchar ('\n');
    }

    // start processing
    fileIn = fopen(fin, "rb"); // open input file (binary)
    if (fileIn==NULL)
    {
        puts("Error opening input file");
        exit (1);
    }

    // open output file
    fileOut = fopen(fout, "wt");
    if (fileOut==NULL)
    {
        puts("Error opening output file for write");
        exit (1);
    }


    // obtain file size.
    fseek (fileIn , 0 , SEEK_END);
    lSize = ftell (fileIn);
    rewind (fileIn);
     printf("Filesize: %d bytes.\n", lSize);
     if(lSize%bytes_per_string)
     {
          puts("Error: length of file isn't multiplication of bytes_per_string value.");
          puts("Please modify input file or select other formatting");
          exit (3);
     }

    // allocate memory to contain the whole file.
    buffer = (unsigned char*) malloc (lSize);
    if (buffer == NULL)
    {
         puts("malloc for input file buffer failed (not enough memory?)");
        exit (2);
    }

    // copy the file into the buffer.
    fread (buffer,1,lSize,fileIn);

    switch(bytes_per_string)
    {
         case 1:
               stringlength = 4 + strlen(separator);     //length of single converted string
               for(i=0; i<lSize-1; i++)
               {
                    fprintf(fileOut,"%02X%s",buffer[i],separator);
                    chars_in_line += stringlength;
                    if(chars_in_line >= wrap_line)
                    {
                         fprintf(fileOut, "\n");
                         chars_in_line = 0;
                    }
               }
               fprintf(fileOut,"%02X",buffer[i]);     //no separator after last string
               break;
         case 2:
               stringlength = 6 + strlen(separator);
               for(i=0; i<lSize-2; i+=2)
               {
                    fprintf(fileOut,"%04X%s",(unsigned int)(buffer[i]*256 +
                         buffer[i+1]), separator);
                    chars_in_line += stringlength;
                    if(chars_in_line >= wrap_line)
                    {
                         fprintf(fileOut, "\n");
                         chars_in_line = 0;
                    }
               }
               fprintf(fileOut,"%04X",(unsigned int)(buffer[i]*256 +
                    buffer[i+1]));
               break;
         case 4:
               stringlength = 10 + strlen(separator);
               for(i=0; i<lSize-4; i+=4)
               {
                    fprintf(fileOut,"%08X%s",(unsigned int)(buffer[i]*16777216 +
                         buffer[i+1]*65536 + buffer[i+2]*256 +
                         buffer[i+3]), separator);
                    chars_in_line += stringlength;
                    if(chars_in_line >= wrap_line)
                    {
                         fprintf(fileOut, "\n");
                         chars_in_line = 0;
                    }
               }
               fprintf(fileOut,"0%08X",(unsigned int)(buffer[i]*16777216 +
                    buffer[i+1]*65536 + buffer[i+2]*256 +
                    buffer[i+3]));
               break;
         default:
         puts("Sorry, processing for this bytes_per_string value not implemented yet");
    }
     printf("%d strings printed to file\n", i/bytes_per_string+1);

     if(fileIn) fclose (fileIn);
     if(fileOut) fclose (fileOut);
     if(buffer) free (buffer);
    exit (0);
}
Comments: