blob: dd5e8833c3d32275dc05899e3578dd72a0a23cc4 [file] [log] [blame]
Juergen Schmied04f7fe71999-11-13 22:32:21 +00001/************************************************
2 *
3 * Converting binary resources from/to *.rc files
4 *
5 * Copyright 1999 Juergen Schmied
6 *
7 * 11/99 first release
8 */
9
10#include "config.h"
11
12#ifdef HAVE_SYS_PARAM_H
13# include <sys/param.h>
14#endif
15#include <sys/types.h>
16#include <sys/stat.h>
17
18#include <ctype.h>
19#include <string.h>
20
21#include <stdio.h>
22#include <stdlib.h>
23
24#include <fcntl.h>
25#include <unistd.h>
Patrik Stridvall9af5e691999-12-11 23:02:15 +000026#ifdef HAVE_SYS_MMAN_H
27# include <sys/mman.h>
28#endif
François Gouget44a18222000-12-19 04:53:20 +000029
Jeremy Whited3e22d92000-02-10 19:03:02 +000030#include "windef.h"
François Gouget44a18222000-12-19 04:53:20 +000031#include "winbase.h"
Jeremy Whited3e22d92000-02-10 19:03:02 +000032#include "wingdi.h"
Juergen Schmied04f7fe71999-11-13 22:32:21 +000033#include "winuser.h"
34
35extern char* g_lpstrFileName;
36
37/* global options */
38
39char* g_lpstrFileName = NULL;
40char* g_lpstrInputFile = NULL;
41int b_to_binary = 0;
42int b_force_overwrite = 0;
Juergen Schmied04f7fe71999-11-13 22:32:21 +000043
44static char* errorOpenFile = "Unable to open file.\n";
45static char* errorRCFormat = "Unexpexted syntax in rc file line %i\n";
46
47void usage(void)
48{
49 printf("Usage: bin2res [-d bin] [input file]\n");
50 printf(" -d bin convert a *.res back to a binary\n");
51 printf(" -f force overwriting newer files\n");
52 exit(-1);
53}
54
55void parse_options(int argc, char **argv)
56{
57 int i;
58
59 switch( argc )
60 {
61 case 2:
62 g_lpstrInputFile = argv[1];
63 break;
64
65 case 3:
66 case 4:
67 case 5:
68 for( i = 1; i < argc - 1; i++ )
69 {
70 if( argv[i][0] != '-' ||
71 strlen(argv[i]) != 2 ) break;
72
73 if( argv[i][1] == 'd')
74 {
75 if (strcmp ("bin", argv[i+1])==0)
76 {
77 b_to_binary =1;
78 i++;
79 }
80 else
81 {
82 usage();
83 }
84
85 }
86 else if ( argv[i][1] == 'f')
87 {
88 b_force_overwrite = 1;
89 }
90 else
91 {
92 usage();
93 }
94 }
95 if( i == argc - 1 )
96 {
97 g_lpstrInputFile = argv[i];
98 break;
99 }
100 default: usage();
101 }
102}
103
104int insert_hex (char * infile, FILE * outfile)
105{
Hidenori Takeshimaa85b0a62000-11-25 23:54:12 +0000106#ifdef HAVE_MMAP
Joerg Mayerabe635c2000-11-11 00:38:37 +0000107 unsigned int i;
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000108 int fd;
109 struct stat st;
Hidenori Takeshimaa85b0a62000-11-25 23:54:12 +0000110 LPBYTE p_in_file = NULL;
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000111
112 if( (fd = open( infile, O_RDONLY))==-1 )
113 {
114 fprintf(stderr, errorOpenFile );
115 exit(1);
116 }
Peter Hunnisett6661bcc1999-11-21 01:01:42 +0000117 if ((fstat(fd, &st) == -1) || (p_in_file = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000118 {
119 fprintf(stderr, errorOpenFile );
120 close(fd);
121 exit(1);
122 }
123
124 fprintf (outfile, "{\n '");
125 i = 0;
126 while (1)
127 {
128 fprintf(outfile, "%02X", p_in_file[i]);
129 if (++i >= st.st_size) break;
130 fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
131 }
Alexandre Julliard1a61a031999-11-28 21:03:46 +0000132 fprintf (outfile, "'\n}");
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000133 munmap(p_in_file, st.st_size);
134 close(fd);
Hidenori Takeshimaa85b0a62000-11-25 23:54:12 +0000135 return 1;
136#else /* HAVE_MMAP */
137 FILE* fp;
138 struct stat st;
139 unsigned int i;
140 int c;
141
142 fp = fopen( infile, "r" );
143 if ( fp == NULL )
144 {
145 fprintf(stderr, errorOpenFile );
146 exit(1);
147 }
148 if (fstat(fileno(fp), &st) == -1)
149 {
150 fprintf(stderr, errorOpenFile );
151 fclose(fp);
152 exit(1);
153 }
154
155 fprintf (outfile, "{\n '");
156 i = 0;
157 while (1)
158 {
159 c = fgetc(fp);
160 if ( c == EOF )
161 {
162 fprintf(stderr, errorOpenFile );
163 fclose(fp);
164 exit(1);
165 }
166 fprintf(outfile, "%02X", c);
167 if (++i >= st.st_size) break;
168 fprintf(outfile, "%s", (i == (i & 0xfffffff0)) ? "'\n '" :" ");
169 }
170 fprintf (outfile, "'\n}");
171
172 fclose(fp);
173 return 1;
174#endif /* HAVE_MMAP */
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000175}
176
177int convert_to_res ()
178{
179 FILE *fin, *ftemp;
180 char buffer[255];
181 char infile[255];
Alexandre Julliard1b2e90e2001-01-17 01:55:21 +0000182 char tmpfile[255];
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000183 char *pos;
184 int c, len;
185 struct stat st;
186 int line = 0;
187 time_t tinput;
188 long startpos, endpos;
Alexandre Julliard1a61a031999-11-28 21:03:46 +0000189
190 strcpy( tmpfile, g_lpstrInputFile );
191 strcat( tmpfile, "-tmp" );
192 /* FIXME: should use better tmp name and create with O_EXCL */
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000193 if( (ftemp = fopen( tmpfile, "w")) == NULL ) goto error_open_file;
194
195 if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
196 tinput = st.st_ctime;
197
198 while ( NULL != fgets(buffer, 255, fin))
199 {
200 fputs(buffer, ftemp);
201 line++;
202 if ( (pos = strstr(buffer, "BINRES")) != NULL)
203 {
204 /* get the out-file name */
205 len = 0; pos += 6; startpos=0; endpos=0;
206 while ( *pos == ' ') pos++;
207 while ( pos[len] != ' ') len++;
208 strncpy(infile, pos, len);
209 infile[len]=0;
210
211 if ( (!stat(infile, &st) && st.st_ctime > tinput) || b_force_overwrite)
212 {
213 /* write a output file */
214 printf("[%s:c]", infile);
215 while((c = fgetc(fin))!='{' && c != EOF) fputc(c, ftemp);
216 if (c == EOF ) goto error_rc_format;
217 while((c = fgetc(fin))!='}' && c != EOF);
218 if (c == EOF ) goto error_rc_format;
219
220 insert_hex(infile, ftemp);
221 }
222 else
223 {
224 printf("[%s:s]", infile);
225 }
226 }
227 }
228
229 fclose(fin);
230 fclose(ftemp);
231 if (rename(tmpfile, g_lpstrInputFile) == -1)
232 {
233 perror("rename");
234 unlink(tmpfile);
235 return 0;
236 }
237 return 1;
238
239error_open_file:
240 fprintf(stderr, errorOpenFile );
241 return 0;
242
243error_rc_format:
244 fprintf(stderr, errorRCFormat, line);
245 return 0;
246}
247
248int convert_to_bin()
249{
250 FILE *fin, *fout;
251 char buffer[255];
252 char outfile[255];
253 char *pos;
254 int len, index, in_resource;
255 unsigned int byte;
256 struct stat st;
257 int line = 0;
258 time_t tinput;
259
260 if( (fin = fopen( g_lpstrInputFile, "r")) == NULL || stat(g_lpstrInputFile, &st)) goto error_open_file;
261 tinput = st.st_ctime;
262
263 while ( NULL != fgets(buffer, 255, fin))
264 {
265 line++;
266 if ( (pos = strstr(buffer, "BINRES")) != NULL)
267 {
268 /* get the out-file name */
269 len = 0; pos += 6;
270 while ( *pos == ' ') pos++;
271 while ( pos[len] != ' ') len++;
272 strncpy(outfile, pos, len);
273 outfile[len]=0;
274
275 if ( stat(outfile, &st) || st.st_ctime < tinput || b_force_overwrite)
276 {
277 /* write a output file */
278 printf("[%s:c]", outfile);
279 if ( (fout = fopen( outfile, "w")) == NULL) goto error_open_file;
280
281 in_resource = 0;
282 while (1)
283 {
284 if ( NULL == fgets(buffer, 255, fin)) goto error_rc_format;
285 line++;
286
287 /* parse a line */
288 for ( index = 0; buffer[index] != 0; index++ )
289 {
290 if ( ! in_resource )
291 {
292 if ( buffer[index] == '{' ) in_resource = 1;
293 continue;
294 }
295
296 if ( buffer[index] == ' ' || buffer[index] == '\''|| buffer[index] == '\n' ) continue;
297 if ( buffer[index] == '}' ) goto end_of_resource;
298 if ( ! isxdigit(buffer[index])) goto error_rc_format;
299 index += sscanf(&buffer[index], "%02x", &byte);
300 fputc(byte, fout);
301 }
302 }
303 fclose(fout);
304 }
305 else
306 {
307 printf("[%s:s]", outfile);
308 }
Patrik Stridvall0ee98cc2000-02-26 13:17:55 +0000309end_of_resource: ;
Juergen Schmied04f7fe71999-11-13 22:32:21 +0000310 }
311 }
312
313 fclose(fin);
314 return 1;
315
316error_open_file:
317 fprintf(stderr, errorOpenFile );
318 return 0;
319
320error_rc_format:
321 fprintf(stderr, errorRCFormat, line);
322 return 0;
323}
324
325int main(int argc, char **argv)
326{
327 parse_options( argc, argv);
328
329 if (b_to_binary == 0)
330 {
331 convert_to_res();
332 }
333 else
334 {
335 convert_to_bin();
336 }
337 printf("\n");
338 return 0;
339}