diff options
Diffstat (limited to 'src/extract.c')
| -rw-r--r-- | src/extract.c | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/src/extract.c b/src/extract.c deleted file mode 100644 index 305cd4a..0000000 --- a/src/extract.c +++ /dev/null @@ -1,197 +0,0 @@ -#include "unalf.h" -#include "addrs.h" - -int bad_checksum, bad_checksum_count = 0; -int new_file = 0; -unsigned int bytes_written = 0; -char *out_filename; - -void dpoke(int addr, u16 value) { - mem[addr] = value & 0xff; - mem[addr + 1] = value >> 8; -} - -u16 dpeek(int addr) { - return mem[addr] | (mem[addr + 1] << 8); -} - -static void bad_atari_filename(const char *msg) { - char fn[50] = ""; - char xbuf[5]; - int i; - u8 c; - - for(i = 0; (c = (u8)out_filename[i]) && i < 12; i++) { - if(c < ' ' || c > '|') { - /* not printable, insert a hex escape */ - sprintf(xbuf, "$%02X", c); - strcat(fn, xbuf); - } else { - strncat(fn, (char *)&c, 1); - } - } - - fprintf(stderr, "%s: bad Atari filename \"%s\": %s\n", self, fn, msg); -} - -/* note to self: it's tempting to use isalpha(), isprint(), etc - from ctype.h... but those are locale-aware. we want ASCII-only - versions. */ -static void sanity_check_filename(void) { - u8 c; - unsigned int i, bad = 0, dots = 0, uscore = 0; - - c = out_filename[0]; - if(!c) { - bad_atari_filename("empty! corrupt ALF file?"); - return; - } else if(c < 'A' || c > 'Z') { - bad_atari_filename("does not begin with A-Z"); - } - - for(i = 0; (c = out_filename[i]) && i < 12; i++) { - if(c >= 'A' && c <= 'Z') - continue; - if(c >= '0' && c <= '9') - continue; - if(c == '_') { - uscore++; - continue; - } - if(c == '.') { - dots++; - continue; - } - bad++; - } - - if(!dots) { - bad_atari_filename("no \".\""); - } else if(dots > 1) { - bad_atari_filename("more than one \".\""); - } - - if(bad) - bad_atari_filename("invalid characters. corrupt ALF file?"); - else if(uscore) - fprintf(stderr, "%s: filename has underscore, OK on Sparta/MyDOS, not Atari DOS 2.x\n", self); -} - -void fix_filename(void) { - char *p; - - if(!out_filename) return; - - if(strlen(out_filename) > 12) { - fprintf(stderr, "%s: filename in ALF header not null-terminated, fixing.\n", self); - out_filename[12] = '\0'; - } - - sanity_check_filename(); - - if(opts.lowercase) { - for(p = out_filename; *p; p++) - *p = tolower(*p); - } - - if(!opts.keepdot) { - for(p = out_filename; *p; p++) - if(p[0] == '.' && !p[1]) - *p = '\0'; - } -} - -void make_backup(void) { - /* up to 12-char FILENAME.EXT, plus a ~, plus null terminator = 14 */ - char backup[14]; - - strncpy(backup, out_filename, 13); - strncat(backup, "~", 13); - - /* silently ignore errors! */ - rename(out_filename, backup); -} - -void extract_alf(void) { - /* get ready to call fake 6502 stuff. set up memory like the Atari. */ - dpoke(MEMTOP, 0xbc1f); - - while(read_alf_header()) { - out_filename = (char *)(mem + alf_hdr_filename); - - fix_filename(); - - if(!file_wanted(out_filename)) { - if(fseek(in_file, getquad(alf_hdr_compsize0), SEEK_CUR) != 0) { - fprintf(stderr, "%s: fatal: seek failed on input!\n", self); - exit(1); - } - out_filename = 0; - continue; - } - - if(!opts.quiet) { - printf("%s %s\n", opts.testonly ? "Testing" : "Uncrunching", out_filename); - } - - if(opts.extract_to_stdout) { - out_file = stdout; - } else { - char *realname = out_filename; - - if(opts.testonly) { - out_filename = "/dev/null"; - } else if(!opts.overwrite) { - make_backup(); - } - - if(!(out_file = fopen(out_filename, "wb"))) { - fprintf(stderr, "%s: fatal: ", self); - perror(out_filename); - exit(1); - } - - out_filename = realname; - } - - bad_checksum = bytes_written = 0; - new_file = 1; - uncrunch_file(); - if(bad_checksum) bad_checksum_count++; - if(bytes_written != getquad(alf_hdr_origsize0)) - fprintf(stderr, "%s: %s should be %u bytes, but extracted to %u.\n", - self, out_filename, getquad(alf_hdr_origsize0), bytes_written); - - if(!opts.extract_to_stdout) fclose(out_file); - out_filename = 0; - } - - if(opts.testonly && !opts.quiet) { - if(bad_checksum_count) - printf("%d file%s with bad checksum!\n", - bad_checksum_count, - bad_checksum_count == 1 ? "" : "s"); - else - printf("All files OK.\n"); - } -} - -void chksum_err(void) { - bad_checksum = 1; - fprintf(stderr, "%s: checksum error on %s\n", self, out_filename); -} - -void truncated_err(void){ - fprintf(stderr, "%s: fatal: compressed data is truncated, EOF before end marker\n", self); - exit(1); -} - -void stack_underrun(void){ - fprintf(stderr, "%s: fatal: stack underrun\n", self); - exit(1); -} - -void stack_overrun(void){ - fprintf(stderr, "%s: fatal: stack overrun\n", self); - exit(1); -} |
