This is really a quick hack to read AmiBack backups - I don't know if it works with floppy based backups - but probably the source below is most useful for understanding the format.
I used it succesfully to restore all of my backups that were stored on QIC Tape (45/150mb).
/*--------------------------------------------------------------------------- * * Title: AmiBack extraction utility * * File: amiread.cpp * * Date: May 2005 * * Description: * Reads/extracts files from a dumped amibackup format archive. * * Rev By Description Date * 1.0 R.J.Harrison Implement 05-05-2005 * * Copyright © 2005 R.J.Harrison *---------------------------------------------------------------------------*/ #pragma warning(disable : 4786) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <direct.h> #include <io.h> #include <fcntl.h> #include <vector> #include <string> #pragma pack(1) typedef struct { char header[4]; // FHDR char name[108];// fname long aa; //??? long filesize; long ee; long ff; long gg; long hh; char depth; char type; // content follows. (unless filesize 0); }AmiHeader; void check_path(const char *path) { FILE *q; static char *ptr,*name, *end, tmp [200]; strcpy (tmp,path); end = ptr = tmp+strlen(tmp); while (*--ptr && *ptr != '/'); if(*ptr) { *++ptr = 0; /* Remove file name */ name = ptr = tmp; do { while (*ptr && *ptr != '/') ptr++; if(*ptr) { *ptr = 0; if(!(q=fopen(name,"r"))) { mkdir (name); } else { fclose (q); } *ptr++ = '/'; } }while (*ptr && ptr < end); } } main() { FILE *f = fopen("N:/Users/Richard/tape/Tapes/amiga_wb_work.amiback","rb"); std::vector<std::string> dirz(100); #define BUFFER_SIZE 1000 /* k */ int buffer_size = BUFFER_SIZE; buffer_size *= 1024; void *file_buffer = malloc(buffer_size + 10); if (!f) { fprintf (stderr, "Not found\n"); exit(-1); } char hdr[512]; #define SWAP_LONG(v) (((v & 0xff000000) >> 24) | ((v & 0xff0000) >> 8) | ((v & 0xff00) << 8) | ((v & 0xff) << 24)) fread(hdr,1,sizeof(hdr),f); printf ("%d\n",sizeof(AmiHeader)); int fc=0; std::string fname; chdir("C:/temp/amiga/"); while(!feof(f)) { AmiHeader fhdr; fread (&fhdr, 1, sizeof(fhdr),f); fhdr.filesize = SWAP_LONG(fhdr.filesize); if (fc == 9175) printf("%x\n", ftell(f)); //? Colon in name is new device... if (strncmp(fhdr.header, "FHDR", 4)) printf ("???Header???"); printf ("%5d: %10d - ",fc++,fhdr.filesize); fname = std::string(); switch (fhdr.type) { case 0x2: { char *s = strchr(fhdr.name, ':'); if (s) *s = 0; // zoink colon from devname dirz[0] = fhdr.name; } break; case 0x0: dirz[fhdr.depth] = fhdr.name; break; default: for (size_t i = 0; i < fhdr.depth; i++) { // printf ("%s/",dirz[i].c_str()); fname = fname + dirz[i] + "/"; } break; } fname = fname + fhdr.name; printf ("%s\n",fname.c_str()); if (fhdr.filesize) { bool list = false; int size = fhdr.filesize; int of; if(!list) { check_path(fname.c_str()); of = open(fname.c_str(), O_BINARY | O_CREAT | O_WRONLY | O_TRUNC, 0x666);// need mode..hdr.mode); if(!of) fprintf(stderr,"unable to open %s\n", fname.c_str()); } while(size >= buffer_size) { fread(file_buffer, 1, buffer_size, f); if(!list) write(of, file_buffer, buffer_size); size -= buffer_size; } if(size > 0) { fread(file_buffer, 1, size, f); if(!list ) write(of, file_buffer, size); } if (!list ) close(of); // if (fseek(f, fhdr.filesize, SEEK_CUR)) // { // fprintf (stderr,"Seek failed\n"); // exit(-1); // } } else { printf ("Directory\n"); if (fhdr.type) printf ("Type %d\n", fhdr.type); } //ii[0] - 0x2 = device; //ii[0] - 0x0 = dir; //ii[0] - 0x1 = file? } }