|
|
1.1 ! root 1: /* ! 2: * readdisk ! 3: * ! 4: * Read files from Amiga disk files ! 5: * ! 6: * Copyright 1996 Bernd Schmidt ! 7: */ ! 8: ! 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: ! 12: unsigned char filemem[901120]; ! 13: ! 14: typedef struct afile ! 15: { ! 16: struct afile *sibling; ! 17: unsigned char *data; ! 18: ULONG size; ! 19: char name[32]; ! 20: } afile; ! 21: ! 22: typedef struct directory ! 23: { ! 24: struct directory *sibling; ! 25: struct directory *subdirs; ! 26: struct afile *files; ! 27: char name[32]; ! 28: } directory; ! 29: ! 30: static ULONG readlong (unsigned char *buffer, int pos) ! 31: { ! 32: return ((*(buffer + pos) << 24) + (*(buffer + pos + 1) << 16) ! 33: + (*(buffer + pos + 2) << 8) + *(buffer + pos + 3)); ! 34: } ! 35: ! 36: static afile *read_file (unsigned char *filebuf) ! 37: { ! 38: afile *a = (afile *)malloc(sizeof(afile)); ! 39: int sizeleft; ! 40: unsigned char *datapos; ! 41: ULONG numblocks, blockpos; ! 42: ! 43: /* BCPL strings... Yuk. */ ! 44: memset (a->name, 0, 32); ! 45: strncpy (a->name, (const char *)filebuf + 0x1B1, *(filebuf + 0x1B0)); ! 46: sizeleft = a->size = readlong (filebuf, 0x144); ! 47: a->data = (unsigned char *)malloc(a->size); ! 48: ! 49: numblocks = readlong (filebuf, 0x8); ! 50: blockpos = 0x134; ! 51: datapos = a->data; ! 52: while (numblocks) ! 53: { ! 54: unsigned char *databuf = filemem + 512*readlong (filebuf, blockpos); ! 55: int readsize = sizeleft > 488 ? 488 : sizeleft; ! 56: memcpy (datapos, databuf + 0x18, readsize); ! 57: datapos += readsize; ! 58: sizeleft -= readsize; ! 59: ! 60: blockpos -= 4; ! 61: numblocks--; ! 62: if (!numblocks) { ! 63: ULONG nextflb = readlong (filebuf, 0x1F8); ! 64: if (nextflb) { ! 65: filebuf = filemem + 512*nextflb; ! 66: blockpos = 0x134; ! 67: numblocks = readlong (filebuf, 0x8); ! 68: if (!filebuf) { ! 69: fprintf(stderr, "Disk structure corrupted. Use DISKDOCTOR to correct it.\n"); ! 70: abort (); ! 71: } ! 72: } ! 73: } ! 74: } ! 75: return a; ! 76: } ! 77: ! 78: static directory *read_dir (unsigned char *dirbuf) ! 79: { ! 80: directory *d = (directory *)malloc(sizeof(directory)); ! 81: ULONG hashsize; ! 82: ULONG i; ! 83: ! 84: memset (d->name, 0, 32); ! 85: strncpy (d->name, (const char *)dirbuf + 0x1B1, *(dirbuf + 0x1B0)); ! 86: d->sibling = 0; ! 87: d->subdirs = 0; ! 88: d->files = 0; ! 89: hashsize = readlong (dirbuf, 0xc); ! 90: if (!hashsize) ! 91: hashsize = 72; ! 92: if (hashsize != 72) ! 93: fprintf(stderr, "Warning: Hash table with != 72 entries.\n"); ! 94: for (i = 0; i < hashsize; i++) { ! 95: ULONG subblock = readlong (dirbuf, 0x18 + 4*i); ! 96: while (subblock) { ! 97: directory *subdir; ! 98: afile *subfile; ! 99: unsigned char *subbuf = filemem + 512*subblock; ! 100: ! 101: switch (readlong (subbuf, 0x1FC)) { ! 102: case 0x00000002: ! 103: subdir = read_dir (subbuf); ! 104: subdir->sibling = d->subdirs; ! 105: d->subdirs = subdir; ! 106: break; ! 107: ! 108: case 0xFFFFFFFD: ! 109: subfile = read_file (subbuf); ! 110: subfile->sibling = d->files; ! 111: d->files = subfile; ! 112: break; ! 113: ! 114: default: ! 115: fprintf(stderr, "Disk structure corrupted. Use DISKDOCTOR to correct it.\n"); ! 116: abort (); ! 117: } ! 118: subblock = readlong (subbuf, 0x1F0); ! 119: } ! 120: } ! 121: return d; ! 122: } ! 123: ! 124: static void writedir(directory *dir) ! 125: { ! 126: directory *subdir; ! 127: afile *f; ! 128: ! 129: if (mkdir (dir->name, 0777) < 0 && errno != EEXIST) { ! 130: fprintf(stderr, "Could not create directory \"%s\". Giving up.\n", dir->name); ! 131: exit (20); ! 132: } ! 133: if (chdir (dir->name) < 0) { ! 134: fprintf(stderr, "Could not enter directory \"%s\". Giving up.\n", dir->name); ! 135: exit (20); ! 136: } ! 137: for (subdir = dir->subdirs; subdir; subdir = subdir->sibling) ! 138: writedir (subdir); ! 139: for (f = dir->files; f; f = f->sibling) { ! 140: int fd = creat (f->name, 0666); ! 141: if (fd < 0) { ! 142: fprintf(stderr, "Could not create file. Giving up.\n"); ! 143: exit (20); ! 144: } ! 145: write (fd, f->data, f->size); ! 146: close (fd); ! 147: } ! 148: chdir (".."); ! 149: } ! 150: ! 151: int main(int argc, char **argv) ! 152: { ! 153: directory *root; ! 154: FILE *inf; ! 155: if (argc < 2 || argc > 3) { ! 156: fprintf(stderr, "Usage: readdisk <file> [<destdir>]\n"); ! 157: exit (20); ! 158: } ! 159: inf = fopen(argv[1], "rb"); ! 160: if (inf == NULL) { ! 161: fprintf(stderr, "can't open file\n"); ! 162: exit (20); ! 163: } ! 164: fread(filemem, 1, 901120, inf); ! 165: ! 166: if (strncmp((const char *)filemem, "DOS\0", 4) != 0) { ! 167: fprintf(stderr, "Not a DOS disk.\n"); ! 168: exit (20); ! 169: } ! 170: root = read_dir (filemem + 880*512); ! 171: ! 172: if (argc == 3) ! 173: if (chdir (argv[2]) < 0) { ! 174: fprintf(stderr, "Couldn't change to %s. Giving up.\n", argv[2]); ! 175: exit (20); ! 176: } ! 177: writedir (root); ! 178: return 0; ! 179: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.