lclevy / adflib Goto Github PK
View Code? Open in Web Editor NEWA free, portable and open implementation of the Amiga filesystem
License: GNU General Public License v2.0
A free, portable and open implementation of the Amiga filesystem
License: GNU General Public License v2.0
Hi, I got an error when trying to unzip a .adf file on Ubuntu 20.04, this is the error
> unadf file.adf
unADF v1.0 : a unzip like for .ADF files, powered by ADFlib (v0.7.11a - January 20th, 2007)
Error <ReadRDSKblock : RDSK id not found>
Can't mount the dump device 'file.adf'.
From what I found on internet
the RDSK is a raw device path and it contains all drives that have not yet been formatted and are thus referred to as RAW
so I check /dev
on my computer and see no /dev/rdsk
there. I guess I have no RDSK on my computer so it can not mount the content. Can I do any work around from it or am I missing anything?
Thank you.
The following code in. add_dev.c
:
struct AdfDevice * adfDevOpen ( const char * const name,
const AdfAccessMode mode )
{
const struct AdfDeviceDriver * const driver = adfGetDeviceDriverByDevName ( name );
if ( driver == NULL || driver->openDev == NULL )
return NULL;
return driver->openDev ( name, mode );
}
seems to use name
as both name for the device name and the adf name.
Am I reading this correctly?
After writing my own native device handlers, it seems that the adfMountDev() returns nullptr if the disk (DD) doesn't already contain filesystem. (*adfEnv.wFct)("adfReadRootBlock : id not found");
Is there something I'm missing or why is this considered an error?
Steps to reproduce:
struct Device* device = adfCreateDumpDevice("test.adf", 80, 2, 11);
adfCreateFlop(device, "Floppy2ADF", 0);
struct Volume* vol = adfMount(device, 0, FALSE);
struct File* output = adfOpenFile(vol, (char*)base_name, "w");
char buf[1024] = {};
for (int i = 0; i < 1024; ++i) {
if (1024 != adfWriteFile(output, 1024, buf)) {
printf("OK, we didn't write all the bytes\n);
}
}
adfFlushFile(output);
This fails to print anything - it looks like block 879 is allocated over and over again when the floppy runs out of space, and the file written is garbage.
I guess we need to clarify what we do for the 0.8.0, prioritize a bit and close what really matters now, while leave other things for later.
I'd see the following priorities:
adfFileOpen()
(edit: done in 75004da)unadf
(#39)No other major or breaking changes that will take time to implement/fix (ie. no bumping requirements regarding build system software versions).
Let me know what you think.
I have started working on write support for fuseadf and have just found out that the library does not support updating existing files in ADF image. The write support modes (for adfOpenFile()
) are:
This is probably not the simplest feature to implement but a pretty crucial one (eg. at the moment, there is no reasonable way to implement write support in a filesystem using ADFlib) so it would be good to add it.
The main ideas:
Hi,
I wonder if it's possible to create a floppy that is Kickstart 1.3 compatible? I have the following code (with a bootblock from a floppy that is usable with 1.3) (error checks removed to reduce code size, but nothing fails in my test)
The following starts fine when I use 2.0, but won't work when I try with 1.3
#include <adflib.h>
#include <stdint.h>
extern uint8_t s_bootblock[1024];
void test_create_floppy() {
adfEnvInitDefault();
struct AdfDevice* device = adfCreateDumpDevice("dummy.adf", 80, 2, 11);
adfCreateFlop(device, "empty", FSMASK_INTL);
struct AdfVolume* volume = adfMount(device, 0, false);
adfInstallBootBlock(volume, s_bootblock);
adfUnMount(volume);
adfUnMountDev(device);
adfEnvCleanUp();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t s_bootblock[1024] = {
0x44, 0x4F, 0x53, 0x00, 0xE3, 0x3D, 0x0E, 0x73, 0x00, 0x00, 0x03, 0x70, 0x43, 0xFA, 0x00, 0x3E,
0x70, 0x25, 0x4E, 0xAE, 0xFD, 0xD8, 0x4A, 0x80, 0x67, 0x0C, 0x22, 0x40, 0x08, 0xE9, 0x00, 0x06,
0x00, 0x22, 0x4E, 0xAE, 0xFE, 0x62, 0x43, 0xFA, 0x00, 0x18, 0x4E, 0xAE, 0xFF, 0xA0, 0x4A, 0x80,
0x67, 0x0A, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4E, 0x75, 0x70, 0xFF, 0x4E, 0x75,
0x64, 0x6F, 0x73, 0x2E, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x65, 0x78, 0x70, 0x61,
0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x2E, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
I understand from your explanation that the implementation of the links in Amiga's OS is better to avoid... However, I was thinking about adding the support at least in some part (like reading linked files).
I investigated this a bit, it seems that reading hardlinked files should not be difficult. I think, It is a matter of (optional) opening the block of with file entry in place of the hard link in the function adfOpenFile()
, then the API would work as with regular file (and, if I understand well, in Amiga filesystems, a hardlink is just a pointer to real file/directory, so there is no metadata to update in it - but please correct me if I am wrong).
Would this be OK. to add something like this? (with some test I guess) If so, i prepare a PR.
Btw. For now, I am not sure about directories and the softlinks (maybe I resolve this on my side...) - but just let know if you'd eventually be willing to merge such changes as well (that is, if I figure out anything useful...).
Reviewing some pieces of bitmap allocation code (for #63) revealed a couple of potential issues:
(in)validity flag (of the bitmap) is not checked while mounting a volume
the use of the (in)validity flag is limited to only adfUpdateBitmap
(one function), while it seems is should be used to mark "dirty" bitmap while writing any block (data, directory, link) until the bitmap is updated accordingly, as the block can be (de)allocated by those operations (meaning the bitmap will be invalid if the operation gets interrupted for some reason)
(All this have to be checked further, this is just a brief note for now).
I believe I have detected a "new" bug in unADF. It is part of adflib-0.8.0-ubuntu.zip from June 26, 2023. I don't know when it was introduced but it was not present in version 0.7.11a-5 available from the Ubuntu package server.
The -d option for unADF no longer works. It's not just me, the patool archive tool can no longer successfully use unADF.
Issuing the command:
unadf '/home/dave/Desktop/Space.adf' -d '/home/dave/Desktop/DumpTarget'
Produces this result:
unADF v1.2 : a unzip like for .ADF files, powered by ADFlib (v0.8.0 - 2023-06-26)
Device : Floppy DD. Cylinders = 80, Heads = 2, Sectors = 11. Volumes = 1
Warning <adfReadBootBlock : incorrect checksum 0x444f5300, calculated 0xf4fbf2fb>
Volume : Floppy 880 KBytes, "Space" between sectors [0-1759]. OFS. Filled at 1.4%.
Warning <adfFileOpen : file "-d" not found.>
/home/dave/Desktop/Space.adf: can't find file -d in volume
/home/dave/Desktop/Space.adf: can't find directory /home in volume
This is not critical issue. Using unADF without the -d option will successfully extract the disk image into the current directory.
adf_show_metadata
crashed on the first ADF I tried. Works on other ADFs, but consistently fails with this one.
#0 __memcpy_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:488
#1 0x00007f854da5212c in adfReadBitmapBlock (vol=0x55b1644fe910, nSect=948, bitm=0x0) at adf_bitm.c:417
#2 0x00007f854da51544 in adfReadBitmap (vol=0x55b1644fe910, nBlock=1758, root=0x7fff5eb1e710) at adf_bitm.c:134
#3 0x00007f854da60d9a in adfMount (dev=0x55b1644fd6e0, nPart=0, readOnly=1) at adf_vol.c:215
#4 0x000055b163b1f22c in main (argc=2, argv=0x7fff5eb1ee88) at adf_show_metadata.c:57
(different optimization level, shows memcpy call)
#0 0x00007fa987a344df in memcpy (__len=512, __src=0x7fffba1f6218, __dest=0x0) at /usr/include/bits/string_fortified.h:29
#1 adfReadBitmapBlock (vol=vol@entry=0x5612fff70910, nSect=nSect@entry=948, bitm=0x0) at adf_bitm.c:417
#2 0x00007fa987a34b5a in adfReadBitmap (vol=vol@entry=0x5612fff70910, nBlock=<optimized out>, root=root@entry=0x7fffba1f6698) at adf_bitm.c:134
#3 0x00007fa987a3c882 in adfMount (dev=<optimized out>, nPart=<optimized out>, readOnly=<optimized out>) at adf_vol.c:215
#4 0x00005612fef5d0b9 in ?? ()
#5 0x00007fa987627cd0 in __libc_start_call_main (main=main@entry=0x5612fef5d020, argc=argc@entry=2, argv=argv@entry=0x7fffba1f6de8) at ../sysdeps/nptl/libc_start_call_main.h:58
#6 0x00007fa987627d8a in __libc_start_main_impl (main=0x5612fef5d020, argc=2, argv=0x7fffba1f6de8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffba1f6dd8) at ../csu/libc-start.c:360
#7 0x00005612fef5d175 in ?? ()
This is the memcpy() at https://github.com/lclevy/ADFlib/blob/master/src/adf_bitm.c#L417
adfReadBitmapBlock() is called with NULL bitm by adfReadBitmap() at https://github.com/lclevy/ADFlib/blob/master/src/adf_bitm.c#L134
The ADF is an image of a MED 3.0 (later OctaMED) OFS floppy. It will be made available on demand.
The adf_salv
module, with the very useful undel functions, needs improvements in terms of:
(Since in some cases possibly the error check should be avoided (even if a checksum is not correct, data could be recovered), the issue is created to take notes/comments on this).
2 issues have been found in the unadf command line option parser:
$ unadf -v
unADF v1.2 : a unzip like for .ADF files, powered by ADFlib (v0.8.0 - 2023-06-26)
Segmentation fault
$ unadf -d
unADF v1.2 : a unzip like for .ADF files, powered by ADFlib (v0.8.0 - 2023-06-26)
Segmentation fault
(gdb) r
Starting program: [...]/ADFlib/build/debug/examples/unadf -v
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
unADF v1.2 : a unzip like for .ADF files, powered by ADFlib (v0.8.0 - 2023-06-26)
Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142
142 ../sysdeps/x86_64/multiarch/strlen-sse2.S: No such file or directory.
(gdb) bt
#0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142
#1 0x00005555555a1f8d in __interceptor_strlen.part.0 ()
#2 0x000055555565895f in parse_args (argc=2, argv=0x7fffffffde68)
at [...]/ADFlib/examples/unadf.c:199
#3 0x00005555556580a4 in main (argc=2, argv=0x7fffffffde68)
at [...]/ADFlib/examples/unadf.c:94
$ ../unadf -dv 0 ../tests/arccsh.adf
unADF v1.2 : a unzip like for .ADF files, powered by ADFlib (v0.8.0 - 2023-06-26)
Device : Floppy DD. Cylinders = 80, Heads = 2, Sectors = 11. Volumes = 1
Volume : Floppy 880 KBytes, "cshell" between sectors [0-1759]. OFS. Filled at 75.2%.
x - 0/c/
x - 0/c/Format
x - 0/c/Mount
x - 0/c/Zip
x - 0/c/Type
x - 0/c/DMS
x - 0/c/cmd.txt
x - 0/c/UNLZX
x - 0/c/Relabel
x - 0/c/Info
x - 0/c/CPU
x - 0/c/Assign
x - 0/c/Deksid
x - 0/c/List
x - 0/c/transdisk
x - 0/c/LhA
x - 0/c/LoadWB
x - 0/c/LZX
x - 0/l/
x - 0/l/LZX.Keyfile
x - 0/devs/
x - 0/devs/DOSDrivers/
x - 0/devs/DOSDrivers/SD0.info
x - 0/devs/DOSDrivers/SD0
x - 0/devs/statram.device
x - 0/devs/SyStEm-CoNfIgUrAtIoN
x - 0/s/
x - 0/s/.cshrc
x - 0/s/aliases
x - 0/s/.login
x - 0/s/startup-sequence
x - 0/libs/
x - 0/libs/arp.library
x - 0/libs/asl.library
x - 0/libs/diskfont.library
x - 0/CSH
x - 0/LoadWB
x - 0/system-configuration
$ ls
0
$ ls 0
c CSH devs l libs LoadWB s system-configuration
Some WHDload sets are distributed as lha's (cause they're intended to be extracted on the amiga), but foreign emulators naturally want to do the same natively. I opened this issue showing the 'problem':
But it would be cool if this library had a simple example of taking a lha, extracting the bytes and paths and attributes and recreating a reproducible hdf image everytime as a proof of concept.
From my understanding if the files don't touch the actual native filesystem before being written to the hdf they won't lose the amiga attributes or get forbidden characters the amiga allows but native doesn't interfering.
As I have mentioned in the pull request, I ran on a problem with adfFileSeek()
, which when used with an offset larger than 35135 bytes (from the beginning of the file), just crashes the program with a segfault.
A simple test (like the ones you already have in regtests/Test/
) that triggers the issue:
#include <stdio.h>
#include"adflib.h"
int main ( int argc, char * argv[] )
{
adfEnvInitDefault();
// adfSetEnvFct(0,0,MyVer,0);
/* mount an existing device : OFS */
struct Device * const dev = adfMountDev ( argv[1], TRUE );
struct Volume * const vol = adfMount ( dev, 0, TRUE );
adfVolumeInfo ( vol );
/* test file seek OK.*/
//const unsigned int highest_not_failing_pos = 36864;
const unsigned int highest_not_failing_pos = 35135;
char large_file[] = "moon.gif";
struct File * file = adfOpenFile ( vol, large_file, "r" );
if ( ! file ) return 1;
printf ( "Seeking to a non-failing position (%d)\n",
highest_not_failing_pos );
adfFileSeek ( file, highest_not_failing_pos );
adfCloseFile ( file );
// test file seek that (currently) fail
file = adfOpenFile ( vol, large_file, "r" );
if ( ! file ) return 1;
printf ( "Seeking to the first failing position (%d)\n",
highest_not_failing_pos + 1 );
adfFileSeek ( file, highest_not_failing_pos + 1 ); // SEGFAULT(!)
adfCloseFile ( file );
// clean-up
adfUnMount ( vol );
adfUnMountDev ( dev );
adfEnvCleanUp();
return 0;
}
Just add something like:
echo "Executing file_seek_test..."
cp $OFSDUMP testofs_adf
file_seek_test testofs_adf
rm testofs_adf
echo "-----"
to regtests/Test/floppy.sh
.
Google runs OSS-Fuzz project, where they spend a lot of CPU cycles fuzz-testing free software. They also offer bounties for getting projects to signing up (which makes me think of Ratbert's rat dance)
Laurent, would you consider requesting? Google may or may not accept.
Even if Google don't accept it, it would help us to have a fuzz test framework, i.e. develop a program like unadf, but without writing the extracted results to disk, and looks through all volumes on the device, and does traversal both with and without dircache if dircache is present. Then give it some disk images, and the fuzzer does the rest, mutating the input in random / directed ways to try and make the code go down different paths and crash. It watches the code execution flow and looks at what memory comparisons were made.
I'm not sure how we could fuzz-test writing files. I like to think that the only way that it would crash is by some sequence of operations, e.g. Open, Write, Seek, Read, Seek, Write..., or even have multiple files being written simultaneously. How would we turn a single input buffer into such a sequence, so the fuzzer can direct it? Perhaps some single-character string language, like "O" means open a new random-named file, "D" means create a directory, ... and other commands like enter a directory, go back to parent directory, switch to the next open file handle in a ring, write a block, read a block, seek forward a block, seek back a block, close a file handle, etc.
Hi! while compiling this with GCC 10 I see the following 2 messages of note (the first seems a bit more important since it copies to a NULL pointer)...
/ADFlib/src/adf_link.c:48:5: warning: argument 1 null where non-null expected [-Wnonnull]
48 | memcpy(tmpPath,entryBlk.name,len);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/ADFlib/src/adf_disk.c:167:27: warning: self-comparison always evaluates to false [-Wtautological-compare]
167 | if (dev==NULL || nPart<nPart || nPart >= dev->nVol) {
|
Hi,
I'm trying to use this lib to add a (executable) file to a floppy. The floppy is a standard DD with a standard Bootblock with S directory, Startup-Sequence file which has "test_exe" in it.
I use this code (roughly) to add the file:
int main(int argc, const char* argv[])
{
struct Device* flop = 0;
struct Volume* vol = 0;
struct File* file = 0;
size_t fileSize = 0;
void* data = 0;
const char* output = argv[1];
const char* input = argv[2];
if (!(data = loadToMemory(input, &fileSize)))
{
printf("Unable to load file \"%s\" to memory\n", input);
return -1;
}
if (!(flop = adfMountDev((char*)output, 0)))
{
printf("%s : unable create newdev: %s\n", argv[0], output);
return 1;
}
if (!(vol = adfMount(flop, 0, 0)))
{
printf("%s : unable to mount floppy\n", argv[0]);
return 1;
}
if (!(file = adfOpenFile(vol, "test_exe", "w")))
{
printf("%s : unable to create test_exe\n", argv[0]);
return 1;
}
printf("fileSize %d\n", (int)fileSize);
if (adfWriteFile(file, fileSize, (uint8_t*)data) != fileSize)
{
printf("%s : unable to write test_exe\n", argv[0]);
return 1;
}
adfFlushFile(file);
adfUnMount(vol);
adfUnMountDev(flop);
return 0;
}
But when I try to boot it it simple will not boot the image. If run the executable manually it works, also if do install df0: it will work as expected. (Notice that I have already installed the floppy before adding the executable to it)
If I take a copy of the floppy and run install df0 on it again it works as expected. If I do a binary diff of the two images there are some places where they differ which is likely the cause of why the Amiga can't boot the image.
I compile this under MacOSX 64-bit (I have also made sure that LITT_ENDIAN is set to 1)
Any ideas of the cause of this?
Cheers!
Trying to write my own command line tool using this library and I'm having some weird issues.
Firstly adfEndOfFile() never triggers so the program gets stuck in the while loop and continues to make the output file larger.
Note: push() should add a file to the currently opened adf and pull() should extract a file from the adf.
Second issue is when trying to extract a file from the adf (manually setting the byte limit to get around the first issue) adfFileRead() seems to only output zeroed bytes.
There's a good chance I'm just doing something wrong but I can't figure out anything more from the seemingly outdated API.
void push()
{
if (!adf_open)
{
printf(" No ADF open!\n");
return;
}
char filename[INPUT_MAX];
printf("Filename: ");
scanf("%s", &filename);
FILE *fp = fopen(&filename[0], "rb");
if (!fp)
{
printf(" Failed to read file!\n");
return;
}
struct AdfFile *afp = adfFileOpen(vol, &filename[0], 'w');
if (!afp)
{
printf(" Failed to create file!\n");
fclose(fp);
return;
}
uint8_t byte;
int byte_return = 0;
while (1)
{
fread(&byte, 1, 1, fp);
byte_return = adfFileWrite(afp, 1, &byte);
if (byte_return != 1)
{
printf(" Disk Write Error.\n");
break;
}
if (feof(fp))
{
break;
}
}
adfFileClose(afp);
fclose(fp);
}
void pull()
{
if (!adf_open)
{
printf(" No ADF open!\n");
return;
}
char filename[INPUT_MAX];
printf("Filename: ");
scanf("%s", &filename);
FILE *fp = fopen(&filename[0], "wb");
if (!fp)
{
printf(" Failed to open output file!\n");
return;
}
struct AdfFile *afp = adfFileOpen(vol, &filename[0], 'r');
if (!afp)
{
printf(" Failed to open file!\n");
fclose(fp);
return;
}
uint8_t byte;
while (!adfEndOfFile(afp))
{
adfFileRead(afp, 1, &byte);
fwrite(&byte, 1, 1, fp);
}
adfFileClose(afp);
fclose(fp);
}
"dircache updates possible bug(s)? "
It was mentioned in README.md, but no more info.
(to check/investigate)
There is some initial version for "continuous" integration (or, at least, builds and some tests) that was added with #34. For now, it is set up only to start builds when there is an action (merge or push) on the citest
branch. It is done so to prevent unnecessary overuse (with each small commit), as some of the tests might be a bit I/O expensive (maybe they can be a bit optimized later, eg. to check less cases, but for now I would leave it that way).
I have created citest
branch in the lclevy/ADFlib
repo - but it seems, the repo does not have the "actions" enabled (I was useing this with my fork so far). So, @lclevy, you may want to eventually enable it, if you want the builds executed in this repo.
For the configuration itself, there can be more things/details to discuss about it - so an issue for this might be useful.
Amiga ROM kernel reference manual, devices
3rd edition
Pages 581-583
Currently, the file read operation (adfFileRead) stops reading the file in case of an incorrect block checksum. And there is no indication for the client code about the error - reading just stops.
Such situation was already encountered on several ADF images, so it seems there can be more cases like this, and it is troublesome that the files cannot be read "just" because of the incorrect checksum (having in fact correct contents).
So - there is a need to have a mechanism that:
Both things can be done either on the level of volume (mount) or file (open), eventually set with some additional function.
New rules regarding branching scheme:
The project will adapt the following model:
https://nvie.com/posts/a-successful-git-branching-model/
For now, this concerns branches: master
and devel
, the rest of existing branches are "feature" branches.
Briefly the rules are:
master
gets updated only from devel
, after thorough tests and acceptance (in fact, since 0.8.0, it will contain only the code from the latest release).devel
gets updated from feature branches, after tests and acceptanceOther things of the scheme may be used/adapted as needed (hotfixes for released code and such,
very likely release branch(es) will also appear).
Questions?
Line 227 in 69af1e5
the package already exist but is called unadf. Tomasz do you want to maintain it for debian? I can sponsor your packaging…
There is a lot of discussions already about it, I'd expect more, so maybe we can make a place for it (to list, brainstorm and set directions).
Some ideas to (eventually) consider (please update as needed):
include/
?)adfOpenDev()
and depend on the name (ie filename) of the devicehasRC()
- but it is not used anywhere...)errno
/last error info
Each of these might be a separated issue (or even issues), that could be linked here (so that it is easier to navigate).
RETCODE adfMountHd ( struct AdfDevice * const dev )
{
[...]
while( next!=-1 ) {
[...]
vol = (struct AdfVolume *) malloc (sizeof(struct AdfVolume));
[...]
vol->volName = (char*)malloc(len+1);
if (!vol->volName) {
adfFreeTmpVolList(listRoot);
(*adfEnv.eFct)("adfMount : malloc");
return RC_ERROR;
}
[...]
/* stores temporaly the volumes in a linked list */
if (listRoot==NULL)
vList = listRoot = newCell(NULL, (void*)vol);
else
vList = newCell(vList, (void*)vol);
[...]
If allocation for vol->volName
fails, vol
(allocated earlier, above) will never be deallocated.
(A rare case, only when a mem. allocation fails - so not caught by sanitizers).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.