/************************************************
 *
 * Converting binary resources from/to *.rc files
 *
 * Copyright 1999 Juergen Schmied
 *
 * 11/99 first release
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>

#include <ctype.h>
#include <string.h>

#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"

extern char*   g_lpstrFileName;

/* global options */

char*	g_lpstrFileName = NULL;
char*   g_lpstrInputFile = NULL;
int	b_to_binary = 0;
int	b_force_overwrite = 0;

static char*    errorOpenFile = "Unable to open file.\n";
static char*    errorRCFormat = "Unexpexted syntax in rc file line %i\n";

void usage(void)
{
    printf("Usage: bin2res [-d bin] [input file]\n");
    printf("  -d bin convert a *.res back to a binary\n");
    printf("  -f force overwriting newer files\n");
    exit(-1);
}

void parse_options(int argc, char **argv)
{
  int i;

  switch( argc )
  {
    case 2:
	 g_lpstrInputFile = argv[1];
	 break;

    case 3:
    case 4:
    case 5:
	 for( i = 1; i < argc - 1; i++ )
	 {
	   if( argv[i][0] != '-' ||
	       strlen(argv[i]) != 2 ) break;

	   if( argv[i][1] == 'd')
	   {
	     if (strcmp ("bin", argv[i+1])==0)
	     {
	       b_to_binary =1;
	       i++;
	     }
	     else
	     {
	       usage();
	     }

	   }
	   else if ( argv[i][1] == 'f')
	   {
	     b_force_overwrite = 1;
	   }
	   else
	   {
	     usage();
	   }
	 }
	 if( i == argc - 1 )
	 {
	   g_lpstrInputFile = argv[i];
	   break;
	 }
    default: usage();
  }
}

int insert_hex (char * infile, FILE * outfile)
{
#ifdef	HAVE_MMAP
	unsigned int i;
	int 		fd;
	struct stat	st;
	LPBYTE p_in_file = NULL;

	if( (fd = open( infile, O_RDONLY))==-1 )
	{
	  fprintf(stderr, errorOpenFile );
	  exit(1);
	}
        if ((fstat(fd, &st) == -1) || (p_in_file = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
        {
	  fprintf(stderr, errorOpenFile );
          close(fd);
	  exit(1);
        }

	fprintf (outfile, "{\n '");
	i = 0;
	while (1)
	{
	  fprintf(outfile, "%02X", p_in_file[i]);
	  if (++i >= st.st_size) break;
	  fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
	}
	fprintf (outfile, "'\n}");
        munmap(p_in_file, st.st_size);
        close(fd);
	return 1;
#else	/* HAVE_MMAP */
	FILE*	fp;
	struct stat	st;
	unsigned int	i;
	int		c;

	fp = fopen( infile, "r" );
	if ( fp == NULL )
	{
	  fprintf(stderr, errorOpenFile );
	  exit(1);
	}
	if (fstat(fileno(fp), &st) == -1)
	{
	  fprintf(stderr, errorOpenFile );
	  fclose(fp);
	  exit(1);
	}

	fprintf (outfile, "{\n '");
	i = 0;
	while (1)
	{
	  c = fgetc(fp);
	  if ( c == EOF )
	  {
	    fprintf(stderr, errorOpenFile );
	    fclose(fp);
	    exit(1);
	  }
	  fprintf(outfile, "%02X", c);
	  if (++i >= st.st_size) break;
	  fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
	}
	fprintf (outfile, "'\n}");

	fclose(fp);
	return 1;
#endif	/* HAVE_MMAP */
}

int convert_to_res ()
{
	FILE 	*fin, *ftemp;
	char	buffer[255];
	char	infile[255];
	char	tmpfile[255];
	char	*pos;
	int	c, len;
	struct stat	st;
	int line = 0;
	time_t	tinput;
	long startpos, endpos;

        strcpy( tmpfile, g_lpstrInputFile );
        strcat( tmpfile, "-tmp" );
        /* FIXME: should use better tmp name and create with O_EXCL */
	if( (ftemp = fopen( tmpfile, "w")) == NULL ) goto error_open_file;

	if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
	tinput = st.st_ctime;

	while ( NULL != fgets(buffer, 255, fin))
	{
	  fputs(buffer, ftemp);
	  line++;
	  if ( (pos = strstr(buffer, "BINRES")) != NULL)
	  {
	    /* get the out-file name */
	    len = 0; pos += 6; startpos=0; endpos=0;
	    while ( *pos == ' ') pos++;
	    while ( pos[len] != ' ') len++;
	    strncpy(infile, pos, len);
	    infile[len]=0;

	    if ( (!stat(infile, &st) && st.st_ctime > tinput) || b_force_overwrite)
	    {
	      /* write a output file */
	      printf("[%s:c]", infile);
	      while((c = fgetc(fin))!='{' && c != EOF) fputc(c, ftemp);
	      if (c == EOF ) goto error_rc_format;
	      while((c = fgetc(fin))!='}' && c != EOF);
	      if (c == EOF ) goto error_rc_format;

	      insert_hex(infile, ftemp);
	    }
	    else
	    {
	      printf("[%s:s]", infile);
	    }
	  }
	}

        fclose(fin);
	fclose(ftemp);

	if (unlink(g_lpstrInputFile) == -1)
	{
            perror("unlink");
            unlink(tmpfile);
            return 0;
	}
	if (rename(tmpfile, g_lpstrInputFile) == -1)
        {
            perror("rename");
            unlink(tmpfile);
            return 0;
        }
	return 1;

error_open_file:
	fprintf(stderr, errorOpenFile );
	return 0;

error_rc_format:
	fprintf(stderr, errorRCFormat, line);
	return 0;
}

int convert_to_bin()
{
	FILE 	*fin, *fout;
	char	buffer[255];
	char	outfile[255];
	char	*pos;
	int	len, index, in_resource;
	unsigned int	byte;
	struct stat	st;
	int line = 0;
	time_t	tinput;

	if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
	tinput = st.st_ctime;

	while ( NULL != fgets(buffer, 255, fin))
	{
	  line++;
	  if ( (pos = strstr(buffer, "BINRES")) != NULL)
	  {
	    /* get the out-file name */
	    len = 0; pos += 6;
	    while ( *pos == ' ') pos++;
	    while ( pos[len] != ' ') len++;
	    strncpy(outfile, pos, len);
	    outfile[len]=0;

	    if ( stat(outfile, &st) || st.st_ctime < tinput || b_force_overwrite)
	    {
	      /* write a output file */
	      printf("[%s:c]", outfile);
	      if ( (fout = fopen( outfile, "w")) == NULL) goto error_open_file;

	      in_resource = 0;
	      while (1)
	      {
	        if ( NULL == fgets(buffer, 255, fin)) goto error_rc_format;
	        line++;

	        /* parse a line */
	        for ( index = 0; buffer[index] != 0; index++ )
	        {
	          if ( ! in_resource )
		  {
		    if ( buffer[index] == '{' ) in_resource = 1;
		    continue;
		  }

	          if ( buffer[index] == ' ' || buffer[index] == '\''|| buffer[index] == '\n' ) continue;
	          if ( buffer[index] == '}' ) goto end_of_resource;
	          if ( ! isxdigit(buffer[index])) goto error_rc_format;
		  index += sscanf(&buffer[index], "%02x", &byte);
		  fputc(byte, fout);
	        }
	      }
	      fclose(fout);
	    }
	    else
	    {
	      printf("[%s:s]", outfile);
	    }
end_of_resource: ;
	  }
	}

        fclose(fin);
	return 1;

error_open_file:
	fprintf(stderr, errorOpenFile );
	return 0;

error_rc_format:
	fprintf(stderr, errorRCFormat, line);
	return 0;
}

int main(int argc, char **argv)
{
	parse_options( argc, argv);

	if (b_to_binary == 0)
	{
	  convert_to_res();
	}
	else
	{
	  convert_to_bin();
	}
	printf("\n");
	return 0;
}
