#include <stdio.h>
#include <string.h>

char puffer[4096];

int readLEWord (FILE * fh)
{
    int hi, lo;

    if ((lo = fgetc (fh)) == EOF)
	return EOF;

    if ((hi = fgetc (fh)) == EOF)
	return EOF;

    return (hi << 8) | lo;
}

int readLELong (FILE * fh)
{
    int l1, l2, l3, l4;

    l1 = fgetc (fh);
    l2 = fgetc (fh);
    l3 = fgetc (fh);
    l4 = fgetc (fh);

    return (l4 << 24) | (l3 << 16) | (l2 << 8) | l1;
}

void writeFile (FILE * in, char * name, int len)
{
    FILE * fh;
    int block;

    fh = fopen (name, "w");

    while (len > 0)
    {
	block = (len > sizeof (puffer)) ? sizeof (puffer) : len;

	if (fread (puffer, block, 1, in) != 1)
	    break;

	fwrite (puffer, block, 1, fh);

	len -= block;
    }

    fclose (fh);
}

int main (int argc, char ** argv)
{
    FILE * fh = fopen ("PERRY_RHODAN:PRSHOW/PR.RDA", "r");
    int chunk;
    int len;
    int t;
    int listMode = 0;

    if (!fh)
	return 10;

    if (argc == 2 && !stricmp (argv[1], "LIST"))
	listMode = 1;

    while ((chunk = readLEWord (fh)) != EOF)
    {
	switch (chunk)
	{
	case 0x302e: /* string */
	    len = readLEWord (fh);

	    if (len == EOF)
		goto exit;

	    if (len > sizeof (puffer))
	    {
		printf ("Len out of range (%d)\n", len);
		goto exit;
	    }

	    if (fread (puffer, len, 1, fh) != 1)
	    {
		perror ("Error reading file");
		goto exit;
	    }

	    puffer[len] = 0;

	    len = readLELong (fh);

	    if (argc != 1)
	    {
		for (t=1; t<argc; t++)
		{
		    if (!strcmp (argv[t], puffer))
			break;
		}
	    }
	    else
		t = 0;

	    if (listMode)
		printf ("FILE %s (%d)\n", puffer, len);

	    if (t != argc && !listMode)
	    {
		printf ("FILE %s (%d)\n", puffer, len);

		writeFile (fh, puffer, len);
	    }
	    else
	    {
		if (fseek (fh, len, SEEK_CUR) == -1)
		{
		    perror ("Error seeking");
		    goto exit;
		}
	    }

	    break;

	default:
	    len = readLEWord (fh);

	    printf ("Unknown chunk 0x%04x, len = %d\n", chunk, len);
	    goto exit;
	}
    }

exit:
    return 0;
}
