ListRez utility to list resources.

This commit is contained in:
Kelvin Sherlock 2013-08-04 21:52:44 -04:00
parent 240c6d62ab
commit bd6050069d
4 changed files with 362 additions and 1 deletions

283
ListRez.c Normal file
View File

@ -0,0 +1,283 @@
/*
* Copyright (c) 2013, Kelvin W Sherlock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include "stdint.h"
#include "MacResource.h"
// n.b. - all data is big endian.
void hexdump(const uint8_t *data, ssize_t size)
{
const char *HexMap = "0123456789abcdef";
char buffer1[16 * 3 + 1 + 1];
char buffer2[16 + 1];
ssize_t offset = 0;
unsigned i, j;
while(size > 0)
{
unsigned linelen = 16;
memset(buffer1, ' ', sizeof(buffer1));
memset(buffer2, ' ', sizeof(buffer2));
if (size < linelen) linelen = size;
for (i = 0, j = 0; i < linelen; i++)
{
unsigned x = data[i];
buffer1[j++] = HexMap[x >> 4];
buffer1[j++] = HexMap[x & 0x0f];
j++;
if (i == 7) j++;
// isascii not part of std:: and may be a macro.
buffer2[i] = isascii(x) && isprint(x) ? x : '.';
}
buffer1[sizeof(buffer1)-1] = 0;
buffer2[sizeof(buffer2)-1] = 0;
printf("%06x:\t%s\t%s\n", (unsigned)offset, buffer1, buffer2);
offset += 16;
data += 16;
size -= 16;
}
printf("\n");
}
const char *TypeCode(uint8_t code[4])
{
static char buffer[12];
int ok = 1;
int i;
for (i = 0; i < 4; ++i)
{
if (isprint(code[i])) continue;
sprintf(buffer, "$%02x%02x%02x%02x",
code[0], code[1], code[2], code[3]);
return buffer;
}
sprintf(buffer, "'%c%c%c%c'",
code[0], code[1], code[2], code[3]);
return buffer;
}
int onefile(const char *file)
{
int fd;
ssize_t size;
off_t off;
uint8_t *mapdata;
uint8_t *typeListPtr;
uint8_t *namePtr;
int i, j;
MacResourceHeader header;
MacResourceMap map;
fd = open(file, O_RDONLY | O_BINARY | O_RSRC);
if (fd < 0)
{
fprintf(stderr, "# %s: Error opening file: %s\n", file, strerror(errno));
return -1;
}
size = read(fd, &header, sizeof(header));
if (size < 0)
{
fprintf(stderr, "# %s Error reading file: %s\n", file, strerror(errno));
close(fd);
return -1;
}
if (size < sizeof(header))
{
fprintf(stderr, "# %s: Not a macintosh resource fork.\n", file);
close(fd);
return -1;
}
mapdata = malloc(header.length_rmap);
if (!mapdata)
{
fprintf(stderr, "# %s Memory allocation failure: %s\n", file, strerror(errno));
close(fd);
return -1;
}
off = lseek(fd, header.offset_rmap, SEEK_SET);
if (off < 0)
{
fprintf(stderr, "# %s: Not a macintosh resource fork.\n", file);
close(fd);
free(mapdata);
return -1;
}
size = read(fd, mapdata, header.length_rmap);
if (size < 0)
{
fprintf(stderr, "# %s Error reading file: %s\n", file, strerror(errno));
close(fd);
free(mapdata);
return -1;
}
if (size != header.length_rmap)
{
fprintf(stderr, "# %s: Not a macintosh resource fork.\n", file);
close(fd);
free(mapdata);
return -1;
}
memcpy(&map, mapdata, sizeof(map));
typeListPtr = mapdata + map.offset_typelist + 2;
namePtr = mapdata + map.offset_namelist;
printf("Type ID Attr Size Name\n");
printf("----- ----- ----- ------- ----\n");
// 'CODE' $0004 $0020 $000018 SANELIB
for (i = map.count + 1; i; --i, typeListPtr += sizeof(MacResourceTypeList))
{
MacResourceTypeList typeList;
const char *tc;
uint8_t *refPtr;
memcpy(&typeList, typeListPtr, sizeof(typeList));
tc = TypeCode(typeList.ResourceType);
refPtr = mapdata + map.offset_typelist + typeList.offset;
for (j = typeList.count + 1; j; --j, refPtr += sizeof(MacReferenceList))
{
MacReferenceList ref;
char name[256];
uint32_t rSize;
uint32_t rOff;
memcpy(&ref, refPtr, sizeof(ref));
if (ref.offset_namelist != 0xffff)
{
int size = namePtr[ref.offset_namelist];
memcpy(name, namePtr + ref.offset_namelist + 1, size);
name[size] = 0;
}
else name[0] = 0;
rSize = 0;
// 24-bit ptr. yuck.
rOff = (ref.offset_data[0] << 16)
| (ref.offset_data[1] << 8)
| (ref.offset_data[2] << 0);
off = lseek(fd, header.offset_rdata + rOff, SEEK_SET);
if (off < 0)
{
fprintf(stderr, "# %s: Not a macintosh resource fork.\n", file);
close(fd);
free(mapdata);
return -1;
}
size = read(fd, &rSize, sizeof(rSize));
if (size < 0)
{
fprintf(stderr, "# %s Error reading file: %s\n", file, strerror(errno));
close(fd);
free(mapdata);
return -1;
}
if (size != sizeof(rSize))
{
fprintf(stderr, "# %s: Not a macintosh resource fork.\n", file);
close(fd);
free(mapdata);
return -1;
}
printf("%-10s $%04x $%04x $%06x %s\n",
tc,
ref.ResourceID,
ref.attr,
rSize, // todo -- size
name
);
}
}
return 0;
}
void help(int status)
{
printf("# ListRez\n");
printf("# Usage: ListRez [options] file");
printf("#\n");
exit(status);
}
int main(int argc, char **argv)
{
// options for resID, resType, list only
if (argc != 2)
help(1);
onefile(argv[1]);
return 0;
}

62
MacResource.h Normal file
View File

@ -0,0 +1,62 @@
/*
*
* Macintosh Resource structures
*
*/
#ifndef __MAC_RESOURCE__
#define __MAC_RESOURCE__
#include "stdint.h"
#define macresPreLoad 0x04
#define macresProtected 0x08
#define macresLocked 0x10
#define macresPurgeable 0x20
#define macresHeap 0x40
struct MacResourceHeader
{
uint32_t offset_rdata; /* offset to resource data */
uint32_t offset_rmap; /* offset to resource map */
uint32_t length_rdata; /* length of resource data */
uint32_t length_rmap; /* length of resource map */
};
typedef struct MacResourceHeader MacResourceHeader, *MacResourceHeaderPtr;
struct MacResourceMap
{
uint8_t Reserved[16]; /* For system use */
uint32_t NextResource; /* For system use */
uint16_t fileRef; /* For system use */
uint16_t attr; /* resource fork attributes */
uint16_t offset_typelist; /* offset from map to typelist */
uint16_t offset_namelist; /* offset from map to namelist */
uint16_t count; /* # of resources -1 */
};
typedef struct MacResourceMap MacResourceMap, *MacResourceMapPtr;
struct MacResourceTypeList
{
uint8_t ResourceType[4];
uint16_t count; /* # of resources -1 */
uint16_t offset; /* offset from typelist to ref. list */
};
typedef struct MacResourceTypeList MacResourceTypeList, *MacResourceTypeListPtr;
struct MacReferenceList
{
uint16_t ResourceID; /* ID of resource */
uint16_t offset_namelist; /* offset from reference list to name
or -1 for no name */
uint8_t attr; /* attributes */
uint8_t offset_data[3]; /* offset from resource data to this data */
uint32_t reserved; /* for system use */
};
typedef struct MacReferenceList MacReferenceList, *MacReferenceListPtr;
#endif

View File

@ -26,7 +26,7 @@ LDFLAGS = -w -c 'MPS ' -t MPST \
# LDFLAGS = -d -c 'MPS ' -t MPST
all: Help GetEnv Duplicate SetFile OverlayIIgs
all: Help GetEnv Duplicate SetFile OverlayIIgs ListRez
clean:
rm -f *.c.o
@ -50,6 +50,9 @@ SetFile: SetFile.c.o SetFile-flags.c.o
OverlayIIgs: OverlayIIgs.c.o OverlayIIgs-flags.c.o
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
ListRez: ListRez.c.o
mpw Link $(LDFLAGS) -o $@ $^ $(LIBS)
#SetFile.c : SetFile.rl
# ragel -G2 -p -m -o $@ $<

13
stdint.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef __STDINT_H__
#define __STDINT_H__
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef long int32_t;
typedef unsigned long uint32_t;
#endif