From 25380d9b6846574b1bad03708226f7bf346b8391 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Sat, 29 Nov 2025 04:12:07 -0500 Subject: alf: Sanity-check generated Atari filenames. --- src/Makefile | 6 +++-- src/alf.c | 2 ++ src/extract.c | 65 ++--------------------------------------------------- src/sanity.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sanity.h | 2 ++ 5 files changed, 82 insertions(+), 65 deletions(-) create mode 100644 src/sanity.c create mode 100644 src/sanity.h diff --git a/src/Makefile b/src/Makefile index da19876..6e0100c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -43,9 +43,9 @@ CFLAGS=-DVERSION='"$(VERSION)"' -Wall -I../f65 $(COPT) BINS=alf alfsum unalf MANS=alf.1 alfsum.1 unalf.1 -UNALF_OBJS=unalf.o io.o listalf.o extract.o f65.o glob.o opts.o usage.o self.o asmcode.o +UNALF_OBJS=unalf.o io.o listalf.o extract.o f65.o glob.o opts.o usage.o self.o asmcode.o sanity.o ALFSUM_OBJS=alfsum.o self.o -ALF_OBJS=alf.o self.o alfusage.o +ALF_OBJS=alf.o self.o alfusage.o sanity.o .PHONY: all clean install crosswin windows windows-upload realclean @@ -88,6 +88,8 @@ listalf.o: listalf.c addrs.h unalf.h ../f65/f65.h extract.o: extract.c addrs.h unalf.h ../f65/f65.h +sanity.o: sanity.c sanity.h + ver.rst: echo '.. |version| replace:: $(VERSION)' > ver.rst diff --git a/src/alf.c b/src/alf.c index 916958d..7559eae 100644 --- a/src/alf.c +++ b/src/alf.c @@ -7,6 +7,7 @@ #include #include +#include "sanity.h" #include "self.h" #ifndef u8 @@ -155,6 +156,7 @@ void create_header(void) { atarify_filename(hdr_filename); printf("Crunching %s\n", hdr_filename); + sanity_check_filename(hdr_filename); if(opt_alftime) time = 0x03130588; diff --git a/src/extract.c b/src/extract.c index 6d940a2..f6b36e7 100644 --- a/src/extract.c +++ b/src/extract.c @@ -1,5 +1,6 @@ #include "unalf.h" #include "addrs.h" +#include "sanity.h" #include #include @@ -17,68 +18,6 @@ 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; @@ -89,7 +28,7 @@ void fix_filename(void) { out_filename[12] = '\0'; } - sanity_check_filename(); + sanity_check_filename(out_filename); if(opts.lowercase) { for(p = out_filename; *p; p++) diff --git a/src/sanity.c b/src/sanity.c new file mode 100644 index 0000000..ccbcae1 --- /dev/null +++ b/src/sanity.c @@ -0,0 +1,72 @@ +#include +#include + +#ifndef u8 +#define u8 unsigned char +#endif + +extern const char *self; + +void bad_atari_filename(const char *fname, const char *msg) { + char fn[50] = ""; + char xbuf[5]; + int i; + u8 c; + + for(i = 0; (c = (u8)fname[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: warning: 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. */ +void sanity_check_filename(const char *fname) { + u8 c; + unsigned int i, bad = 0, dots = 0, uscore = 0; + + c = fname[0]; + if(!c) { + bad_atari_filename(fname, "empty!"); + return; + } else if(c < 'A' || c > 'Z') { + bad_atari_filename(fname, "does not begin with A-Z"); + } + + for(i = 0; (c = fname[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(fname, "no \".\""); + } else if(dots > 1) { + bad_atari_filename(fname, "more than one \".\""); + } + + if(bad) + bad_atari_filename(fname, "invalid characters."); + else if(uscore) + fprintf(stderr, "%s: filename has underscore, OK on Sparta/MyDOS, not Atari DOS 2.x\n", self); +} + + diff --git a/src/sanity.h b/src/sanity.h new file mode 100644 index 0000000..b1f3821 --- /dev/null +++ b/src/sanity.h @@ -0,0 +1,2 @@ +void bad_atari_filename(const char *msg); +void sanity_check_filename(const char *fname); -- cgit v1.2.3