aboutsummaryrefslogtreecommitdiff
path: root/src/extract.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-12-05 01:29:03 -0500
committerB. Watson <urchlay@slackware.uk>2025-12-05 01:29:03 -0500
commitd254450d9dcf29ee08df42e2594cb86abc1d54d3 (patch)
treedd452e3030e8933f34e6e098a6621c1bfef4bcca /src/extract.c
parent27e2056ec8f5aa2c8ac31ec7d0e34abb99a53cb5 (diff)
downloadalftools-d254450d9dcf29ee08df42e2594cb86abc1d54d3.tar.gz
unalf: Add -n and -s options.
Diffstat (limited to 'src/extract.c')
-rw-r--r--src/extract.c93
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) {