diff options
| author | B. Watson <urchlay@slackware.uk> | 2025-12-05 01:29:03 -0500 |
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2025-12-05 01:29:03 -0500 |
| commit | d254450d9dcf29ee08df42e2594cb86abc1d54d3 (patch) | |
| tree | dd452e3030e8933f34e6e098a6621c1bfef4bcca /src/extract.c | |
| parent | 27e2056ec8f5aa2c8ac31ec7d0e34abb99a53cb5 (diff) | |
| download | alftools-d254450d9dcf29ee08df42e2594cb86abc1d54d3.tar.gz | |
unalf: Add -n and -s options.
Diffstat (limited to 'src/extract.c')
| -rw-r--r-- | src/extract.c | 93 |
1 files changed, 72 insertions, 21 deletions
diff --git a/src/extract.c b/src/extract.c index 98523db..6f24c0d 100644 --- a/src/extract.c +++ b/src/extract.c @@ -76,27 +76,81 @@ void set_datetime() { } } -void make_backup(void) { +void make_backup(const char *fname) { /* up to 12-char FILENAME.EXT, plus a ~, plus null terminator = 14 */ - char backup[14]; + /* has to handle up to 16 chars for -s option: LONGFILE.NAME.ALF */ + char backup[20]; - strncpy(backup, out_filename, 13); - strncat(backup, "~", 13); + strncpy(backup, fname, 19); + strncat(backup, "~", 19); /* silently ignore errors! */ - rename(out_filename, backup); + rename(fname, backup); +} + +void open_out_file(const char *fname) { + if(opts.testonly) { + fname = "/dev/null"; + } else if(!opts.overwrite) { + make_backup(fname); + } + + if(!(out_file = fopen(fname, "wb"))) { + fprintf(stderr, "%s: fatal: ", self); + perror(fname); + exit(1); + } +} + +void truncated_err(void); + +void write_split_file(void) { + int i, c; + unsigned int len; + char splitname[20]; + + strncpy(splitname, out_filename, 13); + strncat(splitname, ".ALF", 6); + + if(!opts.quiet) + printf("Writing %s\n", splitname); + + len = getquad(alf_hdr_compsize0); + + open_out_file(splitname); + fwrite(&mem[alf_header], 1, 29, out_file); + for(i = 0; i < len; i++) { + c = fgetc(in_file); + if(c == EOF) { + truncated_err(); + } + fputc(c, out_file); + } + fclose(out_file); } void extract_alf(void) { + int files_extracted = 0, skip, file_number = 0; + /* get ready to call fake 6502 stuff. set up memory like the Atari. */ dpoke(MEMTOP, 0xbc1f); while(read_alf_header()) { + file_number++; + skip = 0; + out_filename = (char *)(mem + alf_hdr_filename); fix_filename(); - if(!file_wanted(out_filename)) { + if(opts.extract_num) + skip = (opts.extract_num != file_number); + else + skip = !file_wanted(out_filename); + + if(skip) { + if(!opts.quiet) + printf("Skipping %s\n", 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); @@ -105,6 +159,13 @@ void extract_alf(void) { continue; } + files_extracted++; + + if(opts.split) { + write_split_file(); + continue; + } + if(!opts.quiet) { printf("%s %s\n", opts.testonly ? "Testing" : "Uncrunching", out_filename); } @@ -112,21 +173,7 @@ void extract_alf(void) { 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; + open_out_file(out_filename); } bad_checksum = bytes_written = 0; @@ -153,6 +200,10 @@ void extract_alf(void) { else printf("All files OK.\n"); } + + if(!opts.quiet && !files_extracted) { + printf("No files %s!\n", opts.testonly ? "tested" : "extracted"); + } } void chksum_err(void) { |
