| /************************************************ |
| * |
| * 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)) == (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; |
| } |
| |
| 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; |
| |
| 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 (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; |
| } |