Skip to content

Commit

Permalink
- Fix dos33.c getopt for BSAVE arguments
Browse files Browse the repository at this point in the history
    #18

- tested on OSX and Debian arm64
- bugfix display of length when `-d` debug is used
- small fixes to usage terms
  • Loading branch information
jquast authored and root committed Aug 16, 2023
1 parent 82fa020 commit 4fa77b5
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 8 deletions.
60 changes: 52 additions & 8 deletions utils/dos33fs-utils/dos33.c
Original file line number Diff line number Diff line change
Expand Up @@ -955,9 +955,9 @@ static void display_help(char *name, int version_only) {
printf(" Where disk_image is a valid dos3.3 disk image\n"
" and COMMAND is one of the following:\n");
printf("\tCATALOG\n");
printf("\tLOAD apple_file <local_file>\n");
printf("\tSAVE type local_file <apple_file>\n");
printf("\tBSAVE [-a addr] [-l len] local_file <apple_file>\n");
printf("\tLOAD apple_file [local_file]\n");
printf("\tSAVE type local_file [apple_file]\n");
printf("\tBSAVE [-a addr] [-l len] local_file [apple_file]\n");
printf("\tDELETE apple_file\n");
printf("\tLOCK apple_file\n");
printf("\tUNLOCK apple_file\n");
Expand Down Expand Up @@ -1058,6 +1058,7 @@ int main(int argc, char **argv) {
char *temp,*endptr;
int c;
int address=0, length=0;
int swp_optind=0;
unsigned char vtoc[BYTES_PER_SECTOR];
int retval=0;

Expand All @@ -1075,7 +1076,7 @@ int main(int argc, char **argv) {
break;
case 'l':
length=strtol(optarg,&endptr,0);
if (debug) fprintf(stderr,"Length=%d\n",address);
if (debug) fprintf(stderr,"Length=%d\n",length);
break;
#if 0
case 't':
Expand Down Expand Up @@ -1223,18 +1224,61 @@ int main(int argc, char **argv) {

if (debug) printf("\ttype=%c\n",type);

if (command==COMMAND_BSAVE) {
// Find position of 'BSAVE' command in argv, and call getopt(3) a
// second time to forward position of optind beyond optional -a and
// -l arguments on BSD.
//
// This is necessary because BSD and Linux getopt(3) differs, linux
// will process '-a' and '-l' options and mutate argv for the value
// of optind to point to remaining arguments, "local_filename //
// [apple_file]".
//
// While BSD does not mutate argv, leaving optind at the position of
// the first unknown option, 'BSAVE' with remaining arguments, "[-a
// addr] [-l len] local_filename [apple_file]" still remaining for
// processing, and this is why we must call getopt(3) a second time,
// in such a peculiar way.
optind = 1;
while ((strncmp(argv[swp_optind], "BSAVE", 5)) && swp_optind < argc)
{
swp_optind++;
}
swp_optind++;

// forward argv and decrement argc past BSAVE command and reset optind
argv += (swp_optind - 1);
argc -= (swp_optind - 1);
optind = 1;
while ((c = getopt(argc, argv, "a:l:")) != -1)
{
switch (c) {
case 'h':
display_help(argv[0], 0);
return 0;
case 'a':
address=strtol(optarg,&endptr,0);
if (debug) fprintf(stderr,"Address=%d\n",address);
break;
case 'l':
length=strtol(optarg,&endptr,0);
if (debug) fprintf(stderr,"Length=%d\n",length);
break;
}
}
}

if (argc==optind) {
fprintf(stderr,"Error! Need file_name\n");
fprintf(stderr,"Error! local_file argument required\n");

if (command==COMMAND_BSAVE) {
fprintf(stderr,"%s %s BSAVE "
"file_name apple_filename\n\n",
"[-a addr] [-l len] local_file [apple_file]\n\n",
argv[0],image);

}
else {
fprintf(stderr,"%s %s SAVE type "
"file_name apple_filename\n\n",
"local_file [apple_file]\n\n",
argv[0],image);
}
retval=-ERROR_INVALID_PARAMATER;
Expand Down
1 change: 1 addition & 0 deletions utils/dos33fs-utils/tests/run_all_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
./test.sh
./test_undelete2.sh
./test_undelete.sh
./test_bsave.sh
36 changes: 36 additions & 0 deletions utils/dos33fs-utils/tests/test_bsave.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
echo "Testing dos33 BSAVE"

fail() {
echo "$1" >&2
num_failed=$(($num_failed + 1))
}
num_failed=0

tempfile=$(mktemp -t temp.XXXXXXXXXX)
run_test() {
cmd_args=$1
shift
expect_strings="$@"
# run and assert return code is zero
../dos33 -d ./test.dsk $cmd_args >"$tempfile" 2>&1 || fail "Command failed: $(cat "$tempfile")"
# assert all expected strings are present in output
for expect_str in $expect_strings
do
grep "$expect_str" "$tempfile" >/dev/null || fail "Command output missing expected string, '$expect_str'"
done
}

cp empty.dsk test.dsk
run_test "BSAVE SINCOS" \
"type=b" "Local filename: SINCOS" "Apple filename: SINCOS"
run_test "BSAVE SINCOS EX1" \
"type=b" "Local filename: SINCOS" "Apple filename: EX1"
run_test "BSAVE -a 0x2000 SINCOS EX2" \
"type=b" "Local filename: SINCOS" "Apple filename: EX2" "Address=8192"
run_test "BSAVE -a 0x2000 -l 146 SINCOS EX3" \
"type=b" "Local filename: SINCOS" "Apple filename: EX3" "Address=8192" "Length=146"
rm "$tempfile"
if [ "$num_failed" -gt 0 ]; then
echo "Test failed. $num_failed tests failed."
exit 1
fi

0 comments on commit 4fa77b5

Please sign in to comment.