New tool to convert the binary resources in *.rc files (hexdumps) from
and to a binary.

diff --git a/documentation/resources b/documentation/resources
new file mode 100644
index 0000000..d516d67
--- /dev/null
+++ b/documentation/resources
@@ -0,0 +1,45 @@
+This document desribes tools for handling resources within wine
+
+### bin2res ###
+
+ This tool allows the editing of embeded binary resources within 
+ *.rc files. These resources are stored as hex dump so they can be
+ stored within the cvs. This makes the editing of the embeded
+ bitmaps and icons harder.
+ 
+ ### Create binary files from.rc ###
+
+  the resources in the.rc file has to be marked by a header:
+
+	/* BINRES idb_std_small.bmp */
+ 	IDB_STD_SMALL BITMAP LOADONCALL DISCARDABLE
+	{
+	 '42 4D 20 07 00 00 00 00 00 00 76 00 00 00 28 00'
+
+  BINRES is the keyword followed by a filename.
+  "bin2res -d bin rsrc.rc" generates binary files from all marked
+  resources. If the binary file is newer it gets not overwritten.
+  To force overwriting use the -f switch.
+  
+ ### Create a .rc file from binaries ###
+
+  Put a header followed by empty brackets in the.rc file.
+
+	/* BINRES idb_std_small.bmp */
+	{}
+
+  Then run "bin2res rsrc.rc". It will merge the resources into the
+  .rc file if the binary resources are newer than the.rc file.
+  To force the resources into the.rc file use the -f switch.
+  If there is already a resource with the same filename in the.rc 
+  file it gets overwritten.
+
+  ### output of bin2res ###
+
+	bash-2.03# ../../tools/bin2res -d bin shres.rc
+	[000.ico:c][003.ico:c][008.ico:s][015.ico:s][034.ico:s]
+	
+   s means skiped, c means changed
+---
+
+juergen.schmied@debitel.net (11/99)
diff --git a/tools/.cvsignore b/tools/.cvsignore
index 149c7d9..d8a491f 100644
--- a/tools/.cvsignore
+++ b/tools/.cvsignore
@@ -1,4 +1,5 @@
 Makefile
+bin2res
 build
 fnt2bdf
 makedep
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 16f7a1e..7745fb7 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -4,10 +4,10 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 
-PROGRAMS = build@PROGEXT@ makedep@PROGEXT@ fnt2bdf@PROGEXT@
+PROGRAMS = build@PROGEXT@ makedep@PROGEXT@ fnt2bdf@PROGEXT@ bin2res@PROGEXT@
 MODULE   = none
 
-C_SRCS = build.c makedep.c fnt2bdf.c
+C_SRCS = build.c makedep.c fnt2bdf.c bin2res.c
 
 all: $(PROGRAMS)
 
@@ -22,4 +22,7 @@
 fnt2bdf@PROGEXT@: fnt2bdf.o
 	$(CC) $(CFLAGS) -o fnt2bdf@PROGEXT@ fnt2bdf.o
 
+bin2res@PROGEXT@: bin2res.o
+	$(CC) $(CFLAGS) -o bin2res@PROGEXT@ bin2res.o
+
 ### Dependencies:
diff --git a/tools/bin2res.c b/tools/bin2res.c
new file mode 100644
index 0000000..5830739
--- /dev/null
+++ b/tools/bin2res.c
@@ -0,0 +1,291 @@
+/************************************************
+ *
+ * Converting binary resources from/to *.rc files
+ *
+ * Copyright 1999 Juergen Schmied
+ *
+ * 11/99 first release
+ */
+
+#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>
+#include <unistd.h>
+#include <sys/mman.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;
+LPBYTE p_in_file = NULL;
+
+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)
+{
+	int i;
+	int 		fd;
+	struct stat	st;
+
+	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)) == MAP_FAILED)
+        {
+	  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}\n");
+        munmap(p_in_file, st.st_size);
+        close(fd);
+	return 1;	
+}
+
+int convert_to_res ()
+{
+	FILE 	*fin, *ftemp;
+	char	buffer[255];
+	char	infile[255];
+	char	tmpfile[L_tmpnam];
+	char	*pos;
+	int	c, len;
+	struct stat	st;
+	int line = 0;
+	time_t	tinput;
+	long startpos, endpos;
+		
+	tmpnam(tmpfile);
+	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 (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;
+}