More STATUS_ codes.
[wine/hacks.git] / tools / bin2res.c
blobb121da01f2d7604eb41497fc509f3c325441cb82
1 /************************************************
3 * Converting binary resources from/to *.rc files
5 * Copyright 1999 Juergen Schmied
7 * 11/99 first release
8 */
10 #include "config.h"
12 #ifdef HAVE_SYS_PARAM_H
13 # include <sys/param.h>
14 #endif
15 #include <sys/types.h>
16 #include <sys/stat.h>
18 #include <ctype.h>
19 #include <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #ifdef HAVE_SYS_MMAN_H
27 # include <sys/mman.h>
28 #endif
29 #include "winuser.h"
31 extern char* g_lpstrFileName;
33 /* global options */
35 char* g_lpstrFileName = NULL;
36 char* g_lpstrInputFile = NULL;
37 int b_to_binary = 0;
38 int b_force_overwrite = 0;
39 LPBYTE p_in_file = NULL;
41 static char* errorOpenFile = "Unable to open file.\n";
42 static char* errorRCFormat = "Unexpexted syntax in rc file line %i\n";
44 void usage(void)
46 printf("Usage: bin2res [-d bin] [input file]\n");
47 printf(" -d bin convert a *.res back to a binary\n");
48 printf(" -f force overwriting newer files\n");
49 exit(-1);
52 void parse_options(int argc, char **argv)
54 int i;
56 switch( argc )
58 case 2:
59 g_lpstrInputFile = argv[1];
60 break;
62 case 3:
63 case 4:
64 case 5:
65 for( i = 1; i < argc - 1; i++ )
67 if( argv[i][0] != '-' ||
68 strlen(argv[i]) != 2 ) break;
70 if( argv[i][1] == 'd')
72 if (strcmp ("bin", argv[i+1])==0)
74 b_to_binary =1;
75 i++;
77 else
79 usage();
83 else if ( argv[i][1] == 'f')
85 b_force_overwrite = 1;
87 else
89 usage();
92 if( i == argc - 1 )
94 g_lpstrInputFile = argv[i];
95 break;
97 default: usage();
101 int insert_hex (char * infile, FILE * outfile)
103 int i;
104 int fd;
105 struct stat st;
107 if( (fd = open( infile, O_RDONLY))==-1 )
109 fprintf(stderr, errorOpenFile );
110 exit(1);
112 if ((fstat(fd, &st) == -1) || (p_in_file = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
114 fprintf(stderr, errorOpenFile );
115 close(fd);
116 exit(1);
119 fprintf (outfile, "{\n '");
120 i = 0;
121 while (1)
123 fprintf(outfile, "%02X", p_in_file[i]);
124 if (++i >= st.st_size) break;
125 fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
127 fprintf (outfile, "'\n}");
128 munmap(p_in_file, st.st_size);
129 close(fd);
130 return 1;
133 int convert_to_res ()
135 FILE *fin, *ftemp;
136 char buffer[255];
137 char infile[255];
138 char tmpfile[L_tmpnam];
139 char *pos;
140 int c, len;
141 struct stat st;
142 int line = 0;
143 time_t tinput;
144 long startpos, endpos;
146 strcpy( tmpfile, g_lpstrInputFile );
147 strcat( tmpfile, "-tmp" );
148 /* FIXME: should use better tmp name and create with O_EXCL */
149 if( (ftemp = fopen( tmpfile, "w")) == NULL ) goto error_open_file;
151 if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
152 tinput = st.st_ctime;
154 while ( NULL != fgets(buffer, 255, fin))
156 fputs(buffer, ftemp);
157 line++;
158 if ( (pos = strstr(buffer, "BINRES")) != NULL)
160 /* get the out-file name */
161 len = 0; pos += 6; startpos=0; endpos=0;
162 while ( *pos == ' ') pos++;
163 while ( pos[len] != ' ') len++;
164 strncpy(infile, pos, len);
165 infile[len]=0;
167 if ( (!stat(infile, &st) && st.st_ctime > tinput) || b_force_overwrite)
169 /* write a output file */
170 printf("[%s:c]", infile);
171 while((c = fgetc(fin))!='{' && c != EOF) fputc(c, ftemp);
172 if (c == EOF ) goto error_rc_format;
173 while((c = fgetc(fin))!='}' && c != EOF);
174 if (c == EOF ) goto error_rc_format;
176 insert_hex(infile, ftemp);
178 else
180 printf("[%s:s]", infile);
185 fclose(fin);
186 fclose(ftemp);
187 if (rename(tmpfile, g_lpstrInputFile) == -1)
189 perror("rename");
190 unlink(tmpfile);
191 return 0;
193 return 1;
195 error_open_file:
196 fprintf(stderr, errorOpenFile );
197 return 0;
199 error_rc_format:
200 fprintf(stderr, errorRCFormat, line);
201 return 0;
204 int convert_to_bin()
206 FILE *fin, *fout;
207 char buffer[255];
208 char outfile[255];
209 char *pos;
210 int len, index, in_resource;
211 unsigned int byte;
212 struct stat st;
213 int line = 0;
214 time_t tinput;
216 if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
217 tinput = st.st_ctime;
219 while ( NULL != fgets(buffer, 255, fin))
221 line++;
222 if ( (pos = strstr(buffer, "BINRES")) != NULL)
224 /* get the out-file name */
225 len = 0; pos += 6;
226 while ( *pos == ' ') pos++;
227 while ( pos[len] != ' ') len++;
228 strncpy(outfile, pos, len);
229 outfile[len]=0;
231 if ( stat(outfile, &st) || st.st_ctime < tinput || b_force_overwrite)
233 /* write a output file */
234 printf("[%s:c]", outfile);
235 if ( (fout = fopen( outfile, "w")) == NULL) goto error_open_file;
237 in_resource = 0;
238 while (1)
240 if ( NULL == fgets(buffer, 255, fin)) goto error_rc_format;
241 line++;
243 /* parse a line */
244 for ( index = 0; buffer[index] != 0; index++ )
246 if ( ! in_resource )
248 if ( buffer[index] == '{' ) in_resource = 1;
249 continue;
252 if ( buffer[index] == ' ' || buffer[index] == '\''|| buffer[index] == '\n' ) continue;
253 if ( buffer[index] == '}' ) goto end_of_resource;
254 if ( ! isxdigit(buffer[index])) goto error_rc_format;
255 index += sscanf(&buffer[index], "%02x", &byte);
256 fputc(byte, fout);
259 fclose(fout);
261 else
263 printf("[%s:s]", outfile);
265 end_of_resource:
269 fclose(fin);
270 return 1;
272 error_open_file:
273 fprintf(stderr, errorOpenFile );
274 return 0;
276 error_rc_format:
277 fprintf(stderr, errorRCFormat, line);
278 return 0;
281 int main(int argc, char **argv)
283 parse_options( argc, argv);
285 if (b_to_binary == 0)
287 convert_to_res();
289 else
291 convert_to_bin();
293 printf("\n");
294 return 0;