├── BUGS ├── Bootblocks ├── CCSBootV30.bb ├── CS2.adf.bb ├── Memory_Controller_V12.bb ├── MiniNukeV10.bb ├── NoBoot.bb ├── OS13.bb ├── OS20_FFS.bb ├── SCA_Virus.bb ├── ScoopexUtilityBootV10.bb └── ScoopexUtilityBootV13.bb ├── History ├── Makefile ├── README ├── TODO ├── adfcopy.c ├── adfcreate.c ├── adfdelete.c ├── adfdump.c ├── adfextract.c ├── adfinfo.c ├── adfinstall.c ├── adflist.c ├── adfmakedir.c ├── bootblocks.c ├── bootblocks.h ├── error.c ├── error.h ├── misc.c ├── misc.h ├── version.c ├── version.h ├── zfile.c └── zfile.h /BUGS: -------------------------------------------------------------------------------- 1 | adftools 2 | -------- 3 | * adfcopy can only copy directories recursively. This means you cannot do 4 | something like "adfcopy * foo.adf" and expect it only to copy the root 5 | files to the image. 6 | 7 | * adfdelete can't handle wildcards. 8 | * adfdelete can't delete recursively. 9 | 10 | 11 | 12 | adflib 13 | ------ 14 | * Make "unsigned char buf[LOGICAL_BLOCK_SIZE]" (in adf_dump.c) static, else 15 | there will be garbage in the end of new adf-files (found 2002-02-24) 16 | 17 | * Rewrite the function so it actually writes the bytes, instead of creating 18 | a file containing holes (using fseek()). Garbage could show up when 19 | seeking, but I haven't investigated this deeply yet (2002-02-25) 20 | 21 | * adfMountDev() should return NULL if device type is unknown (2002-03-05) 22 | 23 | * adfOpenFile() truncates the filename to 31 chars, amigados expects a 24 | filename to be at most 30 characters in length. (2002-04-06) 25 | 26 | * In adfOpenFile() (adf_dir.c), myToUpper() allocates memory for 31 chars 27 | but overwrites the memory if the filename is bigger. This is a serious 28 | bug. Solution is to truncate the filename if it exceeds 31 (30?) chars, 29 | and print a warning. (2002-04-09) 30 | 31 | * When writing files bigger than the amount of free space, NO ERROR IS 32 | REPORTED! This is a FATAL BUG in adfWriteFile()! (2002-05-27) 33 | 34 | -------------------------------------------------------------------------------- /Bootblocks/CCSBootV30.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/CCSBootV30.bb -------------------------------------------------------------------------------- /Bootblocks/CS2.adf.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/CS2.adf.bb -------------------------------------------------------------------------------- /Bootblocks/Memory_Controller_V12.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/Memory_Controller_V12.bb -------------------------------------------------------------------------------- /Bootblocks/MiniNukeV10.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/MiniNukeV10.bb -------------------------------------------------------------------------------- /Bootblocks/NoBoot.bb: -------------------------------------------------------------------------------- 1 | DOS -------------------------------------------------------------------------------- /Bootblocks/OS13.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/OS13.bb -------------------------------------------------------------------------------- /Bootblocks/OS20_FFS.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/OS20_FFS.bb -------------------------------------------------------------------------------- /Bootblocks/SCA_Virus.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/SCA_Virus.bb -------------------------------------------------------------------------------- /Bootblocks/ScoopexUtilityBootV10.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/ScoopexUtilityBootV10.bb -------------------------------------------------------------------------------- /Bootblocks/ScoopexUtilityBootV13.bb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bos4711/adftools/bb838ec4470eec1fcd7805caacdcacf135c8b9cc/Bootblocks/ScoopexUtilityBootV13.bb -------------------------------------------------------------------------------- /History: -------------------------------------------------------------------------------- 1 | 2002-07-05, v0.1: First release (unofficial) 2 | 3 | 2002-08-06, v0.2a: Initial release 4 | 5 | 2003-02-16, v0.2b: Minor bugfix: adfcopy.c had a memleak. 6 | 7 | 2013-11-22, v0.3: Added support for reading and writing compressed adf-files. 8 | 9 | 2015-02-17, v0.3: Added to github 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LIBS= -ladf 2 | SOURCES=error.c misc.c version.c zfile.c 3 | OBJS= $(SOURCES:.c=.o) 4 | PROGS= adfcopy adfcreate adfdelete adfdump adfextract adfinfo adfinstall adflist adfmakedir 5 | CC= gcc 6 | CFLAGS= -Wall -ggdb 7 | 8 | all: $(PROGS) 9 | 10 | adfcopy: $(OBJS) adfcopy.c 11 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 12 | 13 | adfcreate: $(OBJS) adfcreate.c 14 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 15 | 16 | adfdelete: $(OBJS) adfdelete.c 17 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 18 | 19 | adfdump: $(OBJS) adfdump.c 20 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 21 | 22 | adfextract: $(OBJS) adfextract.c 23 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 24 | 25 | adfinfo: $(OBJS) adfinfo.c 26 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 27 | 28 | adfinstall: $(OBJS) adfinstall.c bootblocks.o 29 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) bootblocks.o $@.c 30 | 31 | adflist: $(OBJS) adflist.c 32 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 33 | 34 | adfmakedir: $(OBJS) adfmakedir.c 35 | $(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) $@.c 36 | 37 | bootblocks: 38 | $(CC) $(CFLAGS) -c -o $@.o $@.c 39 | 40 | clean: 41 | rm -f $(PROGS) *.o *~ core *.bb 42 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is adftools. 2 | 3 | adftools is a package containing various command line utilities for 4 | ADF-files, which is a raw dump of an Amiga disk. 5 | 6 | The current version is v0.3 and contains the following tools: 7 | 8 | adfcopy - copy files from host to the ADF 9 | adfcreate - create an ADF 10 | adfdelete - delete files / dirs within an ADF 11 | adfdump - dump the bootblock from an ADF 12 | adfextract - extract complete file structure from an ADF 13 | adfinfo - show info about an ADF 14 | adfinstall - install a bootblock to an ADF 15 | adflist - list all contents of an ADF 16 | adfmakedir - create a directory within an ADF 17 | 18 | Some of the tools utilizes zlib and will therefore work with 19 | compressed ADF-files (.adf.gz, .adz, ...). The tools that does not 20 | utilize zlib does not tell you about it, so until this is implemented 21 | you might in particular want to be cautious with the tool "adfinstall" 22 | which will try to install a bootblock on a compressed ADF-file. 23 | 24 | The workaround for this tool is to unpack the ADF before installing 25 | the bootblock. Here's what happens: 26 | 27 | bos:~/git/adftools$ adfinfo apa.adf.gz 28 | apa.adf.gz 29 | ========== 30 | Label : v 31 | Type : Floppy Double Density - 880Kb 32 | Filesystem : DOS0 (OFS) 33 | Cylinders : 80 34 | Heads : 2 35 | Sectors/Cyl : 11 36 | Blocks : 1760 (0 - 1759) 37 | Blocks used : 1661 38 | Blocks free : 99 39 | 40 | All Done. 41 | bos:~/git/adftools$ adfinstall -i apa.adf.gz 42 | Installing an OS1.3-bootblock to 'apa.adf.gz': Done. 43 | All Done. 44 | Segmentation fault 45 | bos:~/git/adftools$ adfinfo apa.adf.gz 46 | 47 | gzip: apa.adf.gz: invalid compressed data--format violated 48 | Segmentation fault 49 | 50 | 51 | Compiling adftools 52 | ================== 53 | 54 | adftools requires ADFLib which is made by Laurent Clévy. Without this 55 | lib you will not be able to compile adftools. Consult the 56 | documentation for ADFLib about how to install it. 57 | 58 | When you have a working ADFLib installed, simply hit "make" in the 59 | adftool directory. There is no need for running configure or anything 60 | fancy like that, and in case you are not interested in debug info you 61 | might want to change the CFLAGS in the Makefile, like removing --ggdb: 62 | 63 | CFLAGS= -Wall --ggdb 64 | 65 | 66 | 67 | 68 | 69 | adftools (C)2002-2015 Rikard Bosnjakovic 70 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | adftools 2 | -------- 3 | * Make a check in adfinstall that checks if the disk contains a non-dos 4 | structure. If not, warn the user that installing the bootblock might 5 | corrupt the bootloader. (2002-04-06) 6 | 7 | 8 | adflib 9 | ------ 10 | * Implement adfRootDir(volume) (or similiar) that calls adfParentDir(volume) 11 | a couple of times until the root-dir is reached. (2002-03-09) 12 | 13 | * adfAccess2String needs a prototype in , or include the 14 | adf_dir-header. (2002-04-06) 15 | 16 | * Implement a function that can rename (relabel) volumes. (2002-08-06) 17 | -------------------------------------------------------------------------------- /adfcopy.c: -------------------------------------------------------------------------------- 1 | /* adfcopy.c - Copy file(s) to an adf-image 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "error.h" 23 | #include "misc.h" 24 | #include "version.h" 25 | 26 | /* the name of this program */ 27 | char *program_name = ADFCOPY; 28 | 29 | /* we need to determine the maximum size of a path, using PATH_MAX */ 30 | #ifdef PATH_MAX 31 | static int pathmax = PATH_MAX; 32 | #else 33 | static int pathmax = 0; 34 | #endif 35 | 36 | /* function type that's called for each filename in the tree walker */ 37 | typedef int adf_ftw_t (char *, const struct stat *, int); 38 | 39 | /* some global counters for the files */ 40 | static long n_files, n_dirs; 41 | 42 | /* contains full path for every file in the tree walker */ 43 | static char *fullpath; 44 | 45 | /* contains path relative to the starting path */ 46 | static char *adf_path; 47 | 48 | /* sector value for the current directory */ 49 | static SECTNUM sector; 50 | 51 | /* should directories be created when copying files the non-recursively way? */ 52 | static int opt_force; 53 | 54 | /* the structures for the adf-image */ 55 | static struct Device *device; 56 | static struct Volume *volume; 57 | 58 | /* options */ 59 | static struct option long_options[] = 60 | { 61 | {"force", no_argument, 0, 'f'}, 62 | {"help", no_argument, 0, 'h'}, 63 | {"version", no_argument, 0, 'V'}, 64 | 65 | /* end of options */ 66 | {NULL, 0, NULL, 0} 67 | }; 68 | 69 | /********************************************************************/ 70 | /* disk file-functions */ 71 | /********************************************************************/ 72 | /* copies file time from the source file to the adf-file */ 73 | void 74 | adf_copy_file_time (struct Volume *vol, char *filename) { 75 | struct File *file; 76 | /* SECTNUM nSect; */ 77 | struct bEntryBlock entry, parent; 78 | struct DateTime dt; 79 | struct stat st_buf; 80 | struct tm *local; 81 | /* char *adf_filename = filename; //strdup(filename); */ 82 | 83 | /* when copying a whole directory, the filename will be something 84 | like foo/devs/bar, where "foo" will not be an actual element in 85 | the adf-file so we'll strip it off */ 86 | /* printf("APFIS?\n"); */ 87 | /* while (*adf_filename) { */ 88 | /* printf ("%c", *adf_filename); */ 89 | /* if (*adf_filename == '/') */ 90 | /* break; */ 91 | /* adf_filename++; */ 92 | /* } */ 93 | /* adf_filename++; */ 94 | /* printf("\nZE FILENAME = %s\n", adf_filename); */ 95 | 96 | adfReadEntryBlock (vol, vol->curDirPtr, &parent); 97 | /* nSect = adfNameToEntryBlk (vol, parent.hashTable, basename (filename), &entry, NULL); */ 98 | adfNameToEntryBlk (vol, parent.hashTable, basename (filename), &entry, NULL); 99 | 100 | file = (struct File*) malloc (sizeof (struct File)); 101 | if (!file) { 102 | error (0, "Can't allocate memory for timestamp copy #1"); 103 | return; 104 | } 105 | 106 | file->fileHdr = (struct bFileHeaderBlock*) malloc (sizeof (struct bFileHeaderBlock)); 107 | if (!file->fileHdr) { 108 | error (0, "Can't allocate memory for timestamp copy #2"); 109 | return; 110 | } 111 | 112 | file->currentData = malloc (512 * sizeof (unsigned char)); 113 | if (!file->currentData) { 114 | error (0, "Can't allocate memory for timestamp copy #3"); 115 | return; 116 | } 117 | 118 | file->volume = vol; 119 | file->pos = 0; 120 | file->posInExtBlk = 0; 121 | file->posInDataBlk = 0; 122 | file->writeMode = 1; 123 | file->currentExt = NULL; 124 | file->nDataBlock = 0; 125 | 126 | memcpy(file->fileHdr, &entry, sizeof(struct bFileHeaderBlock)); 127 | file->eof = TRUE; 128 | 129 | stat (filename, &st_buf); 130 | local = localtime (&st_buf.st_mtime); 131 | dt.year = local->tm_year; 132 | dt.mon = local->tm_mon + 1; 133 | dt.day = local->tm_mday; 134 | dt.hour = local->tm_hour; 135 | dt.min = local->tm_min; 136 | dt.sec = local->tm_sec; 137 | 138 | /* printf("filename is %s\n", filename); */ 139 | /* printf("year, month, date is %d %d %d\n", dt.year, dt.mon, dt.day); */ 140 | 141 | adfTime2AmigaTime(dt, 142 | &(file->fileHdr->days), 143 | &(file->fileHdr->mins), 144 | &(file->fileHdr->ticks) 145 | ); 146 | 147 | adfWriteFileHdrBlock(file->volume, file->fileHdr->headerKey, file->fileHdr); 148 | adfUpdateBitmap(file->volume); 149 | } 150 | 151 | /* validate and change directory within an adf-file */ 152 | /* input might be something like 'Work/Programming/Gfx/' */ 153 | int 154 | adf_validate_directory (char *dir) 155 | { 156 | /* backup the directory name */ 157 | char *directory = strdup (dir); 158 | 159 | /* a single '/' means to copy to the root directory */ 160 | if ((strlen (directory) == 1) && 161 | (strcmp (directory, "/") == 0)) 162 | free (directory); 163 | return 1; 164 | 165 | /* delete leading and trailing slashes (/) in the string (if any) */ 166 | while (directory[strlen (directory) - 1] == '/') 167 | directory[strlen (directory) - 1] = '\0'; 168 | while (directory[0] == '/') 169 | directory++; 170 | 171 | /* looks like there were more directories, check them all */ 172 | if (strchr (directory, '/')) { 173 | char *tmp = strdup (directory); 174 | 175 | /* loop through the directories */ 176 | while (splitc (tmp, directory)) { 177 | /* check if the adf-dir exists */ 178 | if (adfChangeDir (volume, tmp) != RC_OK) { 179 | free (directory); 180 | free (tmp); 181 | return 0; 182 | } 183 | } 184 | 185 | free (tmp); 186 | } 187 | 188 | /* last element is left in 'directory' */ 189 | if (adfChangeDir (volume, directory) != RC_OK) 190 | free (directory); 191 | return 0; 192 | 193 | /* all went fine. update the global sector variable */ 194 | sector = volume->curDirPtr; 195 | 196 | free (directory); 197 | return 1; 198 | } 199 | 200 | /* mostly based on the one in adfmakedir.c */ 201 | void 202 | adf_make_dir (const char *path) 203 | { 204 | char *directory = strdup (path); 205 | 206 | if (!path || !strlen (path)) { 207 | /* directory is empty*/ 208 | free (directory); 209 | return; 210 | } 211 | 212 | /* delete leading and trailing slashes (/) in the string (if any) */ 213 | while (directory[strlen (directory) - 1] == '/') 214 | directory[strlen (directory) - 1] = '\0'; 215 | while (directory[0] == '/') 216 | directory++; 217 | 218 | if ((strncmp (directory, "./", 2) == 0) && 219 | (strlen (directory) > 2)) { 220 | /* skip ./ */ 221 | adf_make_dir (directory + 2); 222 | free (directory); 223 | return; 224 | } 225 | 226 | /* we need two versions */ 227 | if (!strchr (directory, '/')) { 228 | /*************************************************************************************/ 229 | /* CASE 1: no subdirs specified (no "/" in dir name). create directory in root level */ 230 | /*************************************************************************************/ 231 | /* try to change to the dir first, to see if it already exists */ 232 | if (adfChangeDir (volume, directory) == RC_OK) { 233 | notify ("Directory '%s' exists, skipping.\n", directory); 234 | sector = volume->curDirPtr; 235 | 236 | free (directory); 237 | return; 238 | } 239 | 240 | /* no subdirs, create in the root directory */ 241 | if (adfCreateDir (volume, sector, directory) == RC_OK) { 242 | /* internally change to the dir we just created */ 243 | if (adfChangeDir (volume, directory) != RC_OK) 244 | error (0, "Created directory '%s', but couldn't set it as working directory. Weird", directory); 245 | else 246 | notify ("Created directory '%s'.\n", directory); 247 | 248 | sector = volume->curDirPtr; 249 | } else 250 | error (0, "Could not create directory '%s', no idea why"); 251 | } else { 252 | /***********************************************************/ 253 | /* CASE 2: subdirs specified. strip the / and go recursive */ 254 | /***********************************************************/ 255 | char *tmp = strdup (directory); 256 | char *tmp2 = strdup (directory); 257 | 258 | /* repeat as long as there is a / in the directory to be created */ 259 | while (splitc (tmp, tmp2)) 260 | continue; 261 | 262 | /* last element is left in 'directory' */ 263 | adf_make_dir (tmp2); 264 | 265 | free (tmp); 266 | free (tmp2); 267 | } 268 | 269 | free (directory); 270 | } 271 | 272 | int 273 | copy_file_to_adf (char *filename) 274 | { 275 | struct File* file; 276 | FILE* in; 277 | long n, len; 278 | unsigned char buf[BUFSIZE]; 279 | 280 | in = fopen (filename, "rb"); 281 | if (!in) { 282 | /* adfCloseFile (file); */ // Is this needed? /bos 2013-11-22 283 | /* add more error handling */ 284 | error (0, "Can't open '%s' for reading: %s", filename, strerror (errno)); 285 | return 0; 286 | }; 287 | 288 | file = adfOpenFile (volume, basename (filename), "w"); 289 | if (!file) { 290 | /* add more error handling */ 291 | error (0, "Can't open '%s' for writing. No idea why, perhaps the file exists", filename); 292 | return 0; 293 | }; 294 | 295 | len = BUFSIZE; 296 | n = fread (buf, sizeof (unsigned char), len, in); 297 | while (!feof (in)) { 298 | /* WARNING - adfWriteFile() DOES NOT REPORT ANY ERRORS IF THE DISK IS FULL! */ 299 | adfWriteFile (file, n, buf); 300 | n = fread (buf, sizeof (unsigned char), len, in); 301 | } 302 | 303 | if (n > 0) 304 | adfWriteFile (file, n, buf); 305 | 306 | fclose (in); 307 | adfCloseFile (file); 308 | 309 | // adfUpdateBitmap() breaks! 310 | adf_copy_file_time (volume, filename); 311 | // adfUpdateBitmap() breaks! 312 | 313 | /* notify user what file got copied */ 314 | notify ("%s -> %s:%s\n", filename, adf_path, filename); 315 | 316 | return 1; 317 | } 318 | 319 | /* checks in the directory really is a directory */ 320 | int 321 | check_destination_dir (const char *directory) 322 | { 323 | struct stat statbuf; 324 | 325 | if (lstat (directory, &statbuf) < 0) { 326 | error (0, "Could not stat destination directory: %s", strerror (errno)); 327 | return 0; 328 | } 329 | 330 | if (!S_ISDIR (statbuf.st_mode)) 331 | /* not a dir */ 332 | return 0; 333 | else 334 | return 1; 335 | } 336 | 337 | /* allocate a buffer big enough to contain the biggest pathname possible */ 338 | char * 339 | allocate_path () 340 | { 341 | char *ptr; 342 | 343 | #ifndef PATH_MAX 344 | if (pathmax == 0) { 345 | /* first time */ 346 | errno = 0; 347 | if ((pathmax = pathconf ("/", _PC_PATH_MAX)) < 0) { 348 | if (errno == 0) { 349 | /* no PATH_MAX available */ 350 | pathmax = PATH_MAX_GUESS; 351 | } else { 352 | error (1, "Error while fetching PATH_MAX: %s", strerror (errno)); 353 | } 354 | } else 355 | /* need to add one for the slash (PATH_MAX does not account for it) */ 356 | pathmax++; 357 | } 358 | #endif 359 | 360 | ptr = malloc (pathmax + 1); 361 | 362 | /* could be NULL */ 363 | return ptr; 364 | } 365 | 366 | /* this function handles all entries, one by one */ 367 | static int 368 | adf_ftw_callback (char *pathname, const struct stat *statptr, int type) 369 | { 370 | switch (type) { 371 | /* not a directory */ 372 | case ADF_FTW_F: 373 | switch (statptr->st_mode & S_IFMT) { 374 | case S_IFREG: 375 | /* regular file */ 376 | copy_file_to_adf (pathname); 377 | n_files++; 378 | break; 379 | 380 | case S_IFDIR: 381 | /* directory */ 382 | notify ("This should *not* happen. Blame Canada, then do a bug-report.\n"); 383 | 384 | default: 385 | /* block special, links, sockets etc are ignored */ 386 | notify ("Ignoring '%s', the file is not a regular file or directory.\n", pathname); 387 | break; 388 | } 389 | break; 390 | 391 | case ADF_FTW_D: 392 | /* directory */ 393 | adf_make_dir (pathname); 394 | n_dirs++; 395 | break; 396 | 397 | case ADF_FTW_DNR: 398 | /* unreadable directory */ 399 | error (0, "Can't read directory '%s': %s", pathname, strerror (errno)); 400 | break; 401 | 402 | case ADF_FTW_NS: 403 | /* nonstatable file */ 404 | error (0, "Can't stat '%s': %s", pathname, strerror (errno)); 405 | break; 406 | 407 | default: 408 | /* error */ 409 | error (0, "Unknown type %d for '%s'", type, pathname); 410 | } 411 | 412 | return 1; 413 | } 414 | 415 | /* descend through the hierarchy, starting at "fullpath". if "fullpath" 416 | is anything other than a directory, we lstat() it, call func() and 417 | return. for a directory, we call ourself recursively for each name 418 | in the directory */ 419 | static int 420 | process_path (adf_ftw_t *func) 421 | { 422 | char *ptr; 423 | DIR *dp; 424 | int ret; 425 | struct dirent *dirp; 426 | struct stat statbuf; 427 | 428 | if (lstat (fullpath, &statbuf) < 0) 429 | /* stat error */ 430 | return (func (fullpath, &statbuf, ADF_FTW_NS)); 431 | 432 | if (!S_ISDIR (statbuf.st_mode)) 433 | /* not a directory */ 434 | return (func (fullpath, &statbuf, ADF_FTW_F)); 435 | 436 | /* it's a directory. first call func() for the directory, then process 437 | each filename in the directory */ 438 | ret = func (fullpath, &statbuf, ADF_FTW_D); 439 | if (!ret) 440 | return ret; 441 | 442 | /* point to end of fullpath */ 443 | ptr = fullpath + strlen (fullpath); 444 | *ptr++ = '/'; 445 | *ptr = 0; 446 | 447 | if ((dp = opendir (fullpath)) == NULL) 448 | /* can't read directory */ 449 | return (func (fullpath, &statbuf, ADF_FTW_DNR)); 450 | 451 | /* process all entries in the directory */ 452 | while ((dirp = readdir (dp)) != NULL) { 453 | /* ignore dot and dot-dot */ 454 | if ((strcmp (dirp->d_name, ".") == 0) || 455 | (strcmp (dirp->d_name, "..") == 0)) 456 | continue; 457 | 458 | /* append name after slash */ 459 | strcpy (ptr, dirp->d_name); 460 | 461 | /* recursive */ 462 | ret = process_path (func); 463 | if (!ret) 464 | /* something went wrong, time to quit */ 465 | break; 466 | } 467 | 468 | /* erase everything from the slash onwards */ 469 | ptr[-1] = 0; 470 | 471 | if (closedir (dp) < 0) 472 | error (0, "Can't close directory '%s': %s", fullpath, strerror (errno)); 473 | 474 | /* we're back from the directory. go to the parent directory in the adf 475 | and update the sector counter */ 476 | adfParentDir (volume); 477 | sector = volume->curDirPtr; 478 | 479 | return ret; 480 | } 481 | 482 | /* entry function */ 483 | static int 484 | adf_ftw (char *pathname, adf_ftw_t *func) 485 | { 486 | /* allocate PATH_MAX+1 bytes */ 487 | fullpath = allocate_path (); 488 | if (!fullpath) 489 | error (1, "Can't allocate memory for pathname: %s", strerror (errno)); 490 | 491 | strcpy (fullpath, pathname); 492 | 493 | /* we return whatever func() returns */ 494 | return (process_path (func)); 495 | } 496 | 497 | /********************************************************************/ 498 | /* print version, usage, etc */ 499 | /********************************************************************/ 500 | void 501 | print_usage (int status) 502 | { 503 | if (!status) { 504 | notify ("Try '%s --help' for more information.\n", program_name); 505 | } else { 506 | printf ("Usage: %s ADF-FILE FILE(s) DIR(s) ADF-DIRECTORY\n", program_name); 507 | printf ("Copy file(s) to an adf-image.\n\n"); 508 | printf ("\t-h, --help \tdisplay this help and exit\n"); 509 | printf ("\t-V, --version \tdisplay version information and exit\n"); 510 | printf ("\n"); 511 | print_footer (); 512 | } 513 | 514 | exit (0); 515 | } 516 | 517 | /********************************************************************/ 518 | /* here we go */ 519 | /********************************************************************/ 520 | int 521 | main (int argc, char *argv[]) 522 | { 523 | char *adf_image; 524 | int c; 525 | int n_args; 526 | 527 | init_adflib(); 528 | 529 | /* parse the options */ 530 | while ((c = getopt_long (argc, argv, "hfV", long_options, NULL)) != -1) { 531 | switch (c) { 532 | case 0: 533 | break; 534 | 535 | case 'h': 536 | print_usage (1); 537 | break; 538 | 539 | case 'f': 540 | opt_force = 1; 541 | break; 542 | 543 | case 'V': 544 | print_version (); 545 | exit (0); 546 | 547 | default: 548 | print_usage (0); 549 | } 550 | } 551 | 552 | /* first argument is (should be) the adf-file */ 553 | adf_image = argv[optind++]; 554 | 555 | n_args = argc - optind; 556 | if (n_args < 0) { 557 | /* no args at all */ 558 | error (0, "No adf-file specified"); 559 | print_usage (0); 560 | } else if (n_args < 2) { 561 | /* adf-file exists, but not at least one file and no destination */ 562 | error (0, "Too few arguments"); 563 | print_usage (0); 564 | } 565 | 566 | /* mount the adf-file */ 567 | if (!mount_adf (adf_image, &device, &volume, READ_WRITE)) 568 | exit(1); 569 | 570 | adf_path = allocate_path (); 571 | if (!adf_path) 572 | error (1, "Can't allocate memory: %s", strerror (errno)); 573 | 574 | strcpy (adf_path, basename (adf_image)); 575 | 576 | if (optind < argc) { 577 | char *adf_destination = argv[--argc]; 578 | int ret; 579 | 580 | /* make sure the selected destination in the image exists */ 581 | ret = adf_validate_directory (adf_destination); 582 | if (!ret && !opt_force) 583 | error (1, "No such directory in the adf-file: '%s'", adf_destination); 584 | 585 | sector = volume->curDirPtr; 586 | while (optind < argc) { 587 | char *file = argv[optind++]; 588 | 589 | if (check_destination_dir (file)) { 590 | /* file is a dir, go recursive */ 591 | ret = adf_ftw (file, adf_ftw_callback); 592 | } else { 593 | /* file is a file */ 594 | copy_file_to_adf (file); 595 | } 596 | } 597 | } else { 598 | error (1, "Something's wrong"); 599 | } 600 | 601 | printf ("All Done.\n"); 602 | 603 | cleanup_adflib(); 604 | return 1; 605 | } 606 | -------------------------------------------------------------------------------- /adfcreate.c: -------------------------------------------------------------------------------- 1 | /* adfcreate.c - Create and format new image-files 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "error.h" 17 | #include "misc.h" 18 | #include "version.h" 19 | 20 | /* the name of this program */ 21 | char *program_name = ADFCREATE; 22 | 23 | /* controls whether to use high density or not */ 24 | static int opt_high_density; 25 | 26 | /* long options that have no short eqvivalent short option */ 27 | enum { 28 | HD_OPTION = 1 29 | }; 30 | 31 | /* options */ 32 | static struct option long_options[] = 33 | { 34 | {"file-system", required_argument, 0, 'f'}, 35 | {"hd", no_argument, 0, HD_OPTION}, 36 | {"help", no_argument, 0, 'h'}, 37 | {"label", required_argument, 0, 'l'}, 38 | {"version", no_argument, 0, 'V'}, 39 | 40 | /* end of options */ 41 | {NULL, 0, NULL, 0} 42 | }; 43 | 44 | /********************************************************************/ 45 | /* disk file-functions */ 46 | /********************************************************************/ 47 | /* create a disk file with the correct size and put a filesystem on it */ 48 | int 49 | create_disk_image (char *filename, char *disklabel, int filesystem) 50 | { 51 | int n_tracks = TRACKS; /* 80 */ 52 | int n_heads = HEADS; /* 2 */ 53 | int n_sectors = SECTORS; /* 11 for DD, 22 for HD */ 54 | struct Device* device; 55 | 56 | if (opt_high_density) 57 | n_sectors *= 2; 58 | 59 | device = adfCreateDumpDevice (filename, n_tracks, n_heads, n_sectors); 60 | if (!device) { 61 | error (0, "Can't open '%s': %s", filename, strerror (errno)); 62 | return 0; 63 | } 64 | 65 | if (adfCreateFlop (device, disklabel, filesystem) != RC_OK) { 66 | error (0, "Can't format '%s': %s", filename, strerror (errno)); 67 | free (device); 68 | return 0; 69 | } 70 | 71 | return 1; 72 | } 73 | 74 | /********************************************************************/ 75 | /* print version, usage, etc */ 76 | /********************************************************************/ 77 | void 78 | print_usage (int status) 79 | { 80 | if (!status) { 81 | notify ("Try '%s --help' for more information.\n", program_name); 82 | } else { 83 | printf ("Usage: %s [OPTIONS]... FILE...\n", program_name); 84 | printf ("Create and format new adf-files.\n\n"); 85 | printf ("\t-f, --file-system=INT\tfile-system for the disk\n"); 86 | printf ("\t \t 0 - OFS (default)\n"); 87 | printf ("\t \t 1 - FFS\n"); 88 | printf ("\t \t 2 - I-OFS\n"); 89 | printf ("\t \t 3 - I-FFS\n"); 90 | printf ("\t \t 4 - DC-OFS\n"); 91 | printf ("\t \t 5 - DC-FFS\n"); 92 | printf ("\t-H --hd \tformat with high density\n"); 93 | printf ("\t-l, --label=NAME \tuse NAME as disk label\n"); 94 | printf ("\t-h, --help \tdisplay this help and exit\n"); 95 | printf ("\t-V, --version \tdisplay version information and exit\n"); 96 | printf ("\n"); 97 | print_footer (); 98 | } 99 | 100 | exit (0); 101 | } 102 | 103 | /********************************************************************/ 104 | /* here we go */ 105 | /********************************************************************/ 106 | int 107 | main (int argc, char *argv[]) 108 | { 109 | char *label_buf = ""; 110 | int c; 111 | int filesystem = 0; 112 | int n_files; 113 | 114 | init_adflib(); 115 | 116 | /* parse the options */ 117 | while ((c = getopt_long (argc, argv, "f:hl:V", long_options, NULL)) != -1) { 118 | switch (c) { 119 | case 0: 120 | break; 121 | 122 | case 'f': 123 | if (!isdigits (optarg)) 124 | error (1, "Value specified ('%s') for filesystem is not 1-5", optarg); 125 | 126 | filesystem = atoi (optarg); 127 | if (filesystem > 5) filesystem = 5; 128 | if (filesystem < 0) filesystem = 0; 129 | break; 130 | 131 | case 'h': 132 | print_usage (1); 133 | break; 134 | 135 | case 'l': 136 | /* disk label */ 137 | label_buf = optarg; 138 | break; 139 | 140 | case 'V': 141 | print_version (); 142 | exit (0); 143 | 144 | case HD_OPTION: 145 | /* format high density disks */ 146 | opt_high_density = 1; 147 | break; 148 | 149 | default: 150 | print_usage (0); 151 | } 152 | } 153 | 154 | n_files = argc - optind; 155 | if (n_files == 0) { 156 | error (0, "No files specified, nothing to do"); 157 | print_usage (0); 158 | } 159 | 160 | /* all remaining arguments should be files */ 161 | if (optind < argc) { 162 | /* int i = 1; */ 163 | 164 | while (optind < argc) { 165 | /* label and filename for the image */ 166 | char label[MAXNAMELEN+1]; 167 | char *name = argv[optind++]; 168 | 169 | if (!strncmp (label_buf, "", sizeof (label))) 170 | /* no label is specified */ 171 | // snprintf (label, sizeof (label), "Empty #%d (%s %s)", i++, PACKAGE_NAME, PACKAGE_VERSION); 172 | snprintf (label, sizeof (label), "%s %s ", PACKAGE_NAME, PACKAGE_VERSION); 173 | else { 174 | strncpy (label, label_buf, sizeof (label)); 175 | } 176 | 177 | if (create_disk_image (name, label, filesystem)) 178 | notify ("Created %s.\n", name); 179 | } 180 | } 181 | 182 | notify ("Done.\n"); 183 | 184 | cleanup_adflib(); 185 | return 1; 186 | } 187 | -------------------------------------------------------------------------------- /adfdelete.c: -------------------------------------------------------------------------------- 1 | /* adfdelete.c - Delete file(s) from an adf-image 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "error.h" 20 | #include "misc.h" 21 | #include "version.h" 22 | 23 | /* the name of this program */ 24 | char *program_name = ADFDELETE; 25 | 26 | /* options */ 27 | static struct option long_options[] = 28 | { 29 | {"help", no_argument, 0, 'h'}, 30 | {"version", no_argument, 0, 'V'}, 31 | 32 | /* end of options */ 33 | {NULL, 0, NULL, 0} 34 | }; 35 | 36 | /********************************************************************/ 37 | /* disk file-functions */ 38 | /********************************************************************/ 39 | /* the actual remover. the last argument is only used in case of an error */ 40 | void 41 | do_delete_file (struct Volume *volume, SECTNUM parent, char *file, char *fullpath) 42 | { 43 | struct File *f; 44 | 45 | /* check if the file exists, since adfRemoveEntry() only returns YES or NO */ 46 | f = adfOpenFile (volume, file, "r"); 47 | if (f == NULL) 48 | error (0, "No such file or directory '%s'", fullpath); 49 | else if (adfRemoveEntry (volume, parent, file) != RC_OK) { 50 | if (adfChangeDir (volume, file) == RC_OK) 51 | error (0, "non-empty directory '%s'. Register to be able to delete recursively :)", fullpath); 52 | else 53 | error (0, "Could not delete '%s'. No idea why", fullpath); 54 | 55 | adfCloseFile (f); 56 | } else 57 | notify ("Removed '%s'.\n", fullpath); 58 | } 59 | 60 | /* entry function */ 61 | void 62 | delete_file (struct Volume *volume, char *file) 63 | { 64 | char *fullpath = strdup(file); 65 | SECTNUM parent; 66 | 67 | /* we need two versions */ 68 | if (!strchr (file, '/')) { 69 | /******************************************************/ 70 | /* CASE 1: no subdirs specified (no "/" in file name) */ 71 | /******************************************************/ 72 | parent = volume->curDirPtr; 73 | 74 | do_delete_file (volume, parent, file, fullpath); 75 | } else { 76 | char *tmp = strdup (file); 77 | 78 | while (splitc (tmp, file)) 79 | if (adfChangeDir (volume, tmp) != RC_OK) { 80 | notify ("Could not enter directory '%s', no idea why.", tmp); 81 | free (tmp); 82 | 83 | return; 84 | } 85 | 86 | parent = volume->curDirPtr; 87 | 88 | do_delete_file (volume, parent, file, fullpath); 89 | 90 | free (tmp); 91 | } 92 | 93 | free (fullpath); 94 | } 95 | 96 | /********************************************************************/ 97 | /* print version, usage, etc */ 98 | /********************************************************************/ 99 | void 100 | print_usage (int status) 101 | { 102 | if (!status) { 103 | notify ("Try '%s --help' for more information.\n", program_name); 104 | } else { 105 | printf ("Usage: %s ADF-IMAGE FILE...\n", program_name); 106 | printf ("Delete FILE from ADF-IMAGE. Full path to FILE is required.\n\n"); 107 | printf ("\t-h, --help \tdisplay this help and exit\n"); 108 | printf ("\t-V, --version \tdisplay version information and exit\n"); 109 | printf ("\n"); 110 | print_footer (); 111 | } 112 | 113 | exit (0); 114 | } 115 | 116 | /********************************************************************/ 117 | /* here we go */ 118 | /********************************************************************/ 119 | int 120 | main (int argc, char *argv[]) 121 | { 122 | char *firstarg; 123 | int c; 124 | int n_files; 125 | struct Device *device; 126 | struct Volume *volume; 127 | 128 | init_adflib(); 129 | 130 | /* parse the options */ 131 | while ((c = getopt_long (argc, argv, "hV", long_options, NULL)) != -1) { 132 | switch (c) { 133 | case 0: 134 | break; 135 | 136 | case 'h': 137 | print_usage (1); 138 | break; 139 | 140 | case 'V': 141 | print_version (); 142 | exit (0); 143 | 144 | default: 145 | print_usage (0); 146 | } 147 | } 148 | 149 | /* first argument is (should be) the adf-file */ 150 | firstarg = argv[optind++]; 151 | 152 | n_files = argc - optind; 153 | if (n_files < 0) { 154 | error (0, "No adf-file specified"); 155 | print_usage (0); 156 | } else if (n_files == 0) { 157 | error (0, "Too few arguments"); 158 | print_usage (0); 159 | } 160 | 161 | /* all remaining arguments should be directories to create */ 162 | if (optind < argc) { 163 | /* mount the adf-file */ 164 | if (!mount_adf (firstarg, &device, &volume, READ_WRITE)) 165 | exit(1); 166 | 167 | /* step through the remaining arguments */ 168 | notify ("\nProcessing %s:\n", firstarg); 169 | 170 | while (optind < argc) { 171 | char *file_to_delete = argv[optind++]; 172 | 173 | change_to_root_dir (volume); 174 | delete_file (volume, file_to_delete); 175 | } 176 | } 177 | 178 | printf ("All Done.\n"); 179 | 180 | cleanup_adflib(); 181 | return 1; 182 | } 183 | -------------------------------------------------------------------------------- /adfdump.c: -------------------------------------------------------------------------------- 1 | /* adfdump.c - Read/dump bootblocks from adf-images 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "bootblocks.h" 20 | #include "error.h" 21 | #include "misc.h" 22 | #include "version.h" 23 | 24 | /* the name of this program */ 25 | char *program_name = ADFDUMP; 26 | 27 | /* controls whether to dump to stdout or not */ 28 | static int opt_dump_to_stdout; 29 | 30 | /* options */ 31 | static struct option long_options[] = 32 | { 33 | {"dir", required_argument, 0, 'd'}, 34 | {"stdout", no_argument, 0, 's'}, 35 | {"help", no_argument, 0, 'h'}, 36 | {"version", no_argument, 0, 'V'}, 37 | 38 | /* end of options */ 39 | {NULL, 0, NULL, 0} 40 | }; 41 | 42 | /********************************************************************/ 43 | /* disk file-functions */ 44 | /********************************************************************/ 45 | /* TODO: create 'path' if it does not exist */ 46 | /* perhaps use realpath() instead of this sloppy solution? */ 47 | int 48 | dump_bootblock_to_file (unsigned char *bootblock, char *path, char *filename) 49 | { 50 | char path_and_filename[BUFSIZE]; 51 | char *tmp_filename; 52 | FILE *file; 53 | 54 | tmp_filename = malloc (strlen (filename) + 3); 55 | if (!tmp_filename) 56 | return 0; 57 | 58 | /* strip extension from file and wipe the path (if any) from it */ 59 | tmp_filename = strip_extension (basename (filename)); 60 | 61 | /* if the user did not specify to dump to a dir, path will be NULL */ 62 | if (!path) 63 | path = ""; 64 | 65 | if (strlen (path) == 0) 66 | snprintf (path_and_filename, BUFSIZE, "%s.bb", tmp_filename); 67 | else 68 | snprintf (path_and_filename, BUFSIZE, "%s%c%s.bb", strip_trailing_slashes (path), DIRSEP, tmp_filename); 69 | 70 | file = fopen (path_and_filename, "w"); 71 | if (!file) { 72 | free (tmp_filename); 73 | return 0; 74 | } 75 | 76 | if (fwrite (bootblock, BOOTBLOCK_SIZE, 1, file) != 1) { 77 | free (tmp_filename); 78 | fclose (file); 79 | return 0; 80 | } 81 | 82 | notify ("Saved to '%s'.\n", path_and_filename); 83 | 84 | free (tmp_filename); 85 | fclose (file); 86 | return 1; 87 | } 88 | 89 | /********************************************************************/ 90 | /* print version, usage, etc */ 91 | /********************************************************************/ 92 | void 93 | print_usage (int status) 94 | { 95 | if (!status) { 96 | notify ("Try '%s --help' for more information.\n", program_name); 97 | } else { 98 | printf ("Usage: %s [OPTIONS]... FILE(s)...\n", program_name); 99 | printf ("Dump bootblock from adf-files.\n\n"); 100 | printf ("\t-d, --dir=NAME \tdump bootblock(s) to directory NAME\n"); 101 | printf ("\t-s, --stdout \twrite everything to stdout\n"); 102 | printf ("\t-h, --help \tdisplay this help and exit\n"); 103 | printf ("\t-V, --version \tdisplay version information and exit\n"); 104 | printf ("\n"); 105 | print_footer (); 106 | } 107 | 108 | exit (0); 109 | } 110 | 111 | /********************************************************************/ 112 | /* here we go */ 113 | /********************************************************************/ 114 | int 115 | main (int argc, char *argv[]) 116 | { 117 | char *dir = NULL; 118 | int c; 119 | int n_files; 120 | 121 | init_adflib(); 122 | 123 | /* parse the options */ 124 | while ((c = getopt_long (argc, argv, "sd:hV", long_options, NULL)) != -1) { 125 | switch (c) { 126 | case 0: 127 | break; 128 | 129 | case 'd': 130 | dir = optarg; 131 | break; 132 | 133 | case 'h': 134 | print_usage (1); 135 | break; 136 | 137 | case 's': 138 | opt_dump_to_stdout = 1; 139 | break; 140 | 141 | case 'V': 142 | print_version (); 143 | exit (0); 144 | 145 | default: 146 | print_usage (0); 147 | } 148 | } 149 | 150 | n_files = argc - optind; 151 | if (n_files == 0) { 152 | error (0, "No files specified, nothing to do"); 153 | print_usage (0); 154 | } 155 | 156 | /* all remaining arguments should be files */ 157 | if (optind < argc) { 158 | while (optind < argc) { 159 | int ret; 160 | char *filename = argv[optind++]; 161 | unsigned char *bootblock = NULL; 162 | 163 | bootblock = read_bootblock (filename); 164 | if (!bootblock) { 165 | error (0, "Can't read bootblock from '%s': %s", filename, strerror (errno)); 166 | continue; 167 | } 168 | 169 | if (!is_adf_file (bootblock)) { 170 | error (0, "'%s' doesn't look like an adf-file to me", filename); 171 | continue; 172 | } 173 | 174 | /* output dir was specified, check if we can write into it */ 175 | if (dir) { 176 | if (access (dir, F_OK) == -1) { 177 | /* dir does not exist, create it */ 178 | if (mkdir (dir, 0755) == -1) { 179 | error (1, "Can't create '%s': %s", filename, strerror (errno)); 180 | } else { 181 | notify ("Created '%s'.\n", dir); 182 | } 183 | } 184 | } 185 | 186 | notify ("Dumping bootblock of '%s': ", filename); 187 | if (opt_dump_to_stdout) 188 | write (1, bootblock, 1024); 189 | else { 190 | /* grab the bootblock */ 191 | /* if dir was specified, the path will be in 'dir' */ 192 | ret = dump_bootblock_to_file (bootblock, dir, filename); 193 | 194 | if (!ret) { 195 | notify ("Error when dumping: %s", strerror (errno)); 196 | free (bootblock); 197 | continue; 198 | } 199 | } 200 | 201 | free (bootblock); 202 | } 203 | } 204 | 205 | notify ("All Done.\n"); 206 | 207 | cleanup_adflib(); 208 | return 1; 209 | } 210 | -------------------------------------------------------------------------------- /adfextract.c: -------------------------------------------------------------------------------- 1 | /* adfextract.c - Copy/extract files from adf-images 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "error.h" 22 | #include "misc.h" 23 | #include "version.h" 24 | 25 | /* the name of this program */ 26 | char *program_name = ADFEXTRACT; 27 | 28 | /* long options that have no short eqvivalent short option */ 29 | enum { 30 | EXTRACT_OPTION = 1 31 | }; 32 | 33 | /* options */ 34 | static struct option long_options[] = 35 | { 36 | {"extract", required_argument, 0, EXTRACT_OPTION}, 37 | {"list", no_argument, 0, 'l'}, 38 | {"tree", no_argument, 0, 'r'}, 39 | {"help", no_argument, 0, 'h'}, 40 | {"version", no_argument, 0, 'V'}, 41 | 42 | /* end of options */ 43 | {NULL, 0, NULL, 0} 44 | }; 45 | 46 | /* struct array for timestamps */ 47 | #define MAX_FTS 8 48 | 49 | struct fts { 50 | char *filename; 51 | struct utimbuf utime_buf; 52 | }; 53 | 54 | struct fts *file_timestamps; 55 | static int n_fts = 0; 56 | static int max_fts = MAX_FTS; 57 | 58 | /********************************************************************/ 59 | /* disk file-functions */ 60 | /********************************************************************/ 61 | /* save the timestamp from the adf-file for later update */ 62 | void 63 | update_timestamp(char *filename, struct Entry *entry) 64 | { 65 | struct tm time_str; 66 | struct utimbuf *utime_buf; 67 | time_t time_ret; 68 | 69 | if (n_fts == max_fts) { 70 | /* array is full, increase it */ 71 | max_fts += MAX_FTS; 72 | file_timestamps = realloc (file_timestamps, sizeof (struct fts) * max_fts); 73 | } 74 | 75 | utime_buf = &file_timestamps[n_fts].utime_buf; 76 | 77 | time_str.tm_year = entry->year - 1900; 78 | time_str.tm_mon = entry->month - 1; 79 | time_str.tm_mday = entry->days; 80 | time_str.tm_hour = entry->hour; 81 | time_str.tm_min = entry->mins; 82 | time_str.tm_sec = entry->secs; 83 | time_str.tm_isdst = -1; 84 | 85 | time_ret = mktime(&time_str); 86 | if (time_ret == -1) 87 | error (0, "cannot set timestamp for %s", filename); 88 | else { 89 | utime_buf->actime = time_ret; 90 | utime_buf->modtime = time_ret; 91 | file_timestamps[n_fts].filename = strdup (filename); 92 | /* strcpy(file_timestamps[n_fts].filename, filename); */ 93 | n_fts++; 94 | } 95 | } 96 | void 97 | do_extract_file(struct Volume *vol, struct Entry *entry, char* path, unsigned char *extbuf) 98 | { 99 | char *filename; 100 | char *name = entry->name; 101 | FILE *out; 102 | long n_bytes; 103 | struct File *file; 104 | 105 | /* allocate memory for the path, separator, filename and the trailing separator */ 106 | filename = malloc (strlen (path) + 1 + strlen (name) + 1); 107 | if (!filename) { 108 | error (0, "%s: %s", name, strerror (errno)); 109 | return; 110 | } 111 | 112 | /* construct a full pathname for the file to be extracted (to) */ 113 | sprintf (filename, "%s%c%s", path, DIRSEP, name); 114 | out = fopen (filename, "wb"); 115 | if (!out) { 116 | error (0, "%s: Can't open file for output: %s", filename, strerror (errno)); 117 | return; 118 | } 119 | 120 | /* open the file in the image */ 121 | file = adfOpenFile (vol, name, "r"); 122 | if (!file) { 123 | error (0, "%s: Can't read file from image. Access bits: '%s'", filename, access2str (entry->access)); 124 | fclose (out); 125 | return; 126 | } 127 | 128 | /* read the file from the image */ 129 | n_bytes = adfReadFile(file, BUFSIZE, extbuf); 130 | while (!adfEndOfFile (file)) { 131 | fwrite (extbuf, sizeof (unsigned char), n_bytes, out); 132 | n_bytes = adfReadFile (file, BUFSIZE, extbuf); 133 | } 134 | 135 | /* write any remaining bytes */ 136 | if (n_bytes > 0) 137 | fwrite (extbuf, sizeof (unsigned char), n_bytes, out); 138 | 139 | /* we're done. print some extracting info */ 140 | printf ("Extracted file '%s'\n", filename); 141 | 142 | /* save a copy of the timestamp */ 143 | update_timestamp (filename, entry); 144 | 145 | /* close both files */ 146 | adfCloseFile (file); 147 | fclose (out); 148 | 149 | free (filename); 150 | } 151 | 152 | /* the Recursive Extracter(tm) */ 153 | void 154 | do_extract_tree (struct Volume *vol, struct List* tree, char *path, unsigned char *extbuf) 155 | { 156 | struct Entry* entry; 157 | char *dir; 158 | 159 | while(tree) { 160 | entry = tree->content; 161 | if (entry->type == ST_DIR) { 162 | /* dir */ 163 | dir = malloc (strlen (path) + 1 + strlen (entry->name) + 1); 164 | if (!dir) { 165 | error (0, "Can't allocate memory for %s: %s", entry->name, strerror (errno)); 166 | return; 167 | } 168 | 169 | /* dir to create */ 170 | sprintf (dir, "%s%c%s", path, DIRSEP, entry->name); 171 | 172 | /* show extracting information */ 173 | // printf ("%s%c\n", dir, DIRSEP); 174 | 175 | if (access (dir, F_OK) == -1) { 176 | /* dir does not exist, let's create it */ 177 | if (mkdir (dir, 0755) == -1) { 178 | error (1, "Can't create '%s': %s", dir, strerror (errno)); 179 | } else { 180 | notify ("Created dir '%s'.\n", dir); 181 | update_timestamp (dir, entry); 182 | } 183 | } 184 | 185 | if (tree->subdir != NULL) { 186 | if (adfChangeDir (vol, entry->name) == RC_OK) { 187 | if (dir) { 188 | do_extract_tree (vol, tree->subdir, dir, extbuf); 189 | free (dir); 190 | } else 191 | do_extract_tree (vol, tree->subdir, entry->name, extbuf); 192 | adfParentDir (vol); 193 | } else { 194 | fprintf (stderr, "ExtractTree: dir \"%s/%s\" not found.\n", path,entry->name); 195 | } 196 | } 197 | } else if (entry->type == ST_FILE) { 198 | /* file */ 199 | do_extract_file (vol, entry, path, extbuf); 200 | } 201 | 202 | tree = tree->next; 203 | } 204 | } 205 | 206 | /* entry function for the recursive extracter */ 207 | void 208 | extract_tree (char *filename, char *path, struct Volume *volume) 209 | { 210 | struct List *cell, *list; 211 | unsigned char *buf; 212 | 213 | buf = malloc (BUFSIZE); 214 | if (!buf) { 215 | error (0, "Can't allocate memory for extraction of '%s': %s", filename, strerror (errno)); 216 | return; 217 | } 218 | 219 | print_volume_header (filename, volume); 220 | 221 | if (strlen (path) == 0) 222 | /* create a directory with the same name as the image, modulo extension */ 223 | path = strip_extension (basename (filename)); 224 | 225 | /* make sure the dir to extract to exists, else create it */ 226 | if (access (path, F_OK) == -1) { 227 | /* dir does not exist, let's create it */ 228 | if (mkdir (path, 0755) == -1) { 229 | error (1, "Can't create '%s': %s", path, strerror (errno)); 230 | } else { 231 | notify ("Created extraction dir '%s'.\n", path); 232 | } 233 | } 234 | 235 | cell = list = adfGetRDirEnt (volume, volume->curDirPtr, 1); 236 | do_extract_tree (volume, cell, path, buf); 237 | 238 | putchar ('\n'); 239 | adfFreeDirList (list); 240 | } 241 | 242 | /********************************************************************/ 243 | /* print version, usage, etc */ 244 | /********************************************************************/ 245 | void 246 | print_usage (int status) 247 | { 248 | if (!status) { 249 | notify ("Try '%s --help' for more information.\n", program_name); 250 | } else { 251 | printf ("Usage: %s [OPTIONS]... FILE(s)...\n", program_name); 252 | printf ("List/extract files from an adf-image.\n\n"); 253 | printf ("\t-e \tcreates a directory and extracts all contents\n"); 254 | printf ("\t \tof the image into there (default)\n"); 255 | printf ("\t --extract=DIR \tsame as -e, but extracts to DIR instead\n"); 256 | printf ("\t-l, --list \tlists root directory contents\n"); 257 | printf ("\t-r, --tree \tlists directory tree contents\n"); 258 | printf ("\t-h, --help \tdisplay this help and exit\n"); 259 | printf ("\t-V, --version \tdisplay version information and exit\n"); 260 | printf ("\n"); 261 | print_footer (); 262 | } 263 | 264 | exit (0); 265 | } 266 | 267 | /********************************************************************/ 268 | /* here we go */ 269 | /********************************************************************/ 270 | int 271 | main (int argc, char *argv[]) 272 | { 273 | char *extract_dir = ""; 274 | int c, i; 275 | int n_files; 276 | struct Device *device; 277 | struct Volume *volume; 278 | 279 | init_adflib(); 280 | 281 | /* parse the options */ 282 | while ((c = getopt_long (argc, argv, "ehV", long_options, NULL)) != -1) { 283 | switch (c) { 284 | case 0: 285 | break; 286 | 287 | case EXTRACT_OPTION: 288 | extract_dir = optarg; 289 | break; 290 | 291 | case 'e': 292 | extract_dir = ""; 293 | break; 294 | 295 | case 'h': 296 | print_usage (1); 297 | break; 298 | 299 | case 'V': 300 | print_version (); 301 | exit (0); 302 | 303 | default: 304 | print_usage (0); 305 | } 306 | } 307 | 308 | n_files = argc - optind; 309 | if (n_files == 0) { 310 | error (0, "Nothing to do"); 311 | print_usage (0); 312 | } 313 | 314 | /* all remaining arguments should be files */ 315 | if (optind < argc) { 316 | /* initiate the array for timestamps */ 317 | file_timestamps = malloc (sizeof(struct fts) * MAX_FTS); 318 | 319 | while (optind < argc) { 320 | char *filename = argv[optind++]; 321 | 322 | /* lazy way to mount both the device and the volume (if possible) */ 323 | if (!mount_adf (filename, &device, &volume, READ_ONLY)) 324 | continue; 325 | 326 | extract_tree (filename, extract_dir, volume); 327 | 328 | printf ("Updating timestamps...\n"); 329 | for (i = 0; i < n_fts; i++) { 330 | char *filename = file_timestamps[i].filename; 331 | 332 | utime(filename, &file_timestamps[i].utime_buf); 333 | } 334 | } 335 | 336 | if (file_timestamps) 337 | free (file_timestamps); 338 | } 339 | 340 | printf ("All Done.\n"); 341 | 342 | cleanup_adflib(); 343 | return 1; 344 | } 345 | -------------------------------------------------------------------------------- /adfinfo.c: -------------------------------------------------------------------------------- 1 | /* adfinfo.c - Display information about an adf-image 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* #include "adfextract.h" */ 20 | #include "error.h" 21 | #include "misc.h" 22 | #include "version.h" 23 | #include "zfile.h" 24 | 25 | /* the name of this program */ 26 | char *program_name = ADFINFO; 27 | 28 | /* options */ 29 | static struct option long_options[] = 30 | { 31 | {"info", no_argument, 0, 'i'}, 32 | {"help", no_argument, 0, 'h'}, 33 | {"version", no_argument, 0, 'V'}, 34 | 35 | /* end of options */ 36 | {NULL, 0, NULL, 0} 37 | }; 38 | 39 | /********************************************************************/ 40 | /* disk file-functions */ 41 | /********************************************************************/ 42 | int 43 | print_image_info (char *filename) 44 | { 45 | int i; 46 | struct Device *dev; 47 | struct Volume *vol; 48 | 49 | mount_adf(filename, &dev, &vol, READ_ONLY); 50 | 51 | /* dev = adfMountDev (n_zfile_open(filename, "r"), 1); */ 52 | if ( (!dev) || (!vol) ) 53 | return 0; 54 | /* if (!dev) */ 55 | /* return 0; */ 56 | 57 | /* vol = adfMount (dev, 0, 1); */ 58 | /* if (!vol) */ 59 | /* return 0; */ 60 | 61 | for (i = 0; i < dev->nVol; i++) { 62 | register long j; 63 | printf ("%s\n", filename); 64 | for (j = 0; j < strlen (filename); j++) 65 | putchar ('='); 66 | printf ("\nLabel : %-30s\n", (dev->volList[i]->volName) ? dev->volList[i]->volName : "(Unknown)"); 67 | printf ("Type : "); 68 | 69 | switch (vol->dev->devType) { 70 | case DEVTYPE_FLOPDD: 71 | printf ("Floppy Double Density - 880Kb\n"); 72 | break; 73 | case DEVTYPE_FLOPHD: 74 | printf ("Floppy High Density - 1760Kb\n"); 75 | break; 76 | case DEVTYPE_HARDDISK: 77 | printf ("Hard Disk partition - %3.1fKb\n", 78 | ((vol->lastBlock - vol->firstBlock + 1) * 512.0) / 1024.0); 79 | break; 80 | case DEVTYPE_HARDFILE: 81 | printf ("Hardfile - %3.1fKb\n", 82 | ((vol->lastBlock - vol->firstBlock + 1) * 512.0) / 1024.0); 83 | break; 84 | default: 85 | printf ("Unknown device type.\n"); 86 | } 87 | 88 | printf ("Filesystem : %s\n", get_adf_dostype (dev->volList[0]->dosType)); 89 | printf ("Cylinders : %ld\n", (long int)dev->cylinders); 90 | printf ("Heads : %ld\n", (long int)dev->heads); 91 | printf ("Sectors/Cyl : %ld\n", (long int)dev->sectors); 92 | printf ("Blocks : %ld (%ld - %ld)\n", (long int)(vol->lastBlock + 1), (long int)vol->firstBlock, (long int)vol->lastBlock); 93 | j = adfCountFreeBlocks (vol); 94 | printf ("Blocks used : %ld\n", (vol->lastBlock - j) + 1); 95 | printf ("Blocks free : %ld\n\n", j); 96 | } 97 | 98 | adfUnMount (vol); 99 | adfUnMountDev (dev); 100 | return 1; 101 | } 102 | 103 | /********************************************************************/ 104 | /* print version, usage, etc */ 105 | /********************************************************************/ 106 | void 107 | print_usage (int status) 108 | { 109 | if (!status) { 110 | notify ("Try '%s --help' for more information.\n", program_name); 111 | } else { 112 | printf ("Usage: %s FILE(s)...\n", program_name); 113 | printf ("Display information about an adf-image.\n\n"); 114 | printf ("\t-h, --help \tdisplay this help and exit\n"); 115 | printf ("\t-V, --version \tdisplay version information and exit\n"); 116 | printf ("\n"); 117 | print_footer (); 118 | } 119 | 120 | exit (0); 121 | } 122 | 123 | /********************************************************************/ 124 | /* here we go */ 125 | /********************************************************************/ 126 | int 127 | main (int argc, char *argv[]) 128 | { 129 | int c; 130 | int n_files; 131 | 132 | init_adflib(); 133 | 134 | /* parse the options */ 135 | while ((c = getopt_long (argc, argv, "hV", long_options, NULL)) != -1) { 136 | switch (c) { 137 | case 0: 138 | break; 139 | 140 | case 'h': 141 | print_usage (1); 142 | break; 143 | 144 | case 'V': 145 | print_version (); 146 | exit (0); 147 | 148 | default: 149 | print_usage (0); 150 | } 151 | } 152 | 153 | n_files = argc - optind; 154 | if (n_files == 0) { 155 | error (0, "Nothing to do"); 156 | print_usage (0); 157 | } 158 | 159 | /* all remaining arguments should be files */ 160 | if (optind < argc) 161 | while (optind < argc) { 162 | char *filename = argv[optind++]; 163 | 164 | print_image_info (filename); 165 | /* if (!print_image_info (filename)) */ 166 | /* notify ("Can't mount '%s', not a DOS-disk (or not an adf-file).\n", filename); */ 167 | } 168 | 169 | printf ("All Done.\n"); 170 | 171 | cleanup_adflib(); 172 | return 1; 173 | } 174 | -------------------------------------------------------------------------------- /adfinstall.c: -------------------------------------------------------------------------------- 1 | /* adfinstall.c - Create bootblocks on adf-images 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "bootblocks.h" 20 | #include "error.h" 21 | #include "misc.h" 22 | #include "version.h" 23 | 24 | /* the name of this program */ 25 | char *program_name = ADFINSTALL; 26 | 27 | /* install using a specified bootblock */ 28 | static int opt_install; 29 | 30 | /* install w/o argument => install a default bootblock */ 31 | static int opt_install_no_arg; 32 | 33 | /* long options that have no short eqvivalent short option */ 34 | enum { 35 | INSTALL_OPTION = 1 36 | }; 37 | 38 | /* options */ 39 | static struct option long_options[] = 40 | { 41 | {"install", required_argument, 0, INSTALL_OPTION}, 42 | {"help", no_argument, 0, 'h'}, 43 | {"version", no_argument, 0, 'V'}, 44 | 45 | /* end of options */ 46 | {NULL, 0, NULL, 0} 47 | }; 48 | 49 | /********************************************************************/ 50 | /* disk file-functions */ 51 | /********************************************************************/ 52 | /* the reason for not using adfInstallBootBlock() is that the function */ 53 | /* requires a mounted image, which in turn requires a filesystem. the */ 54 | /* way we're doing below handles trackdisks as well, i.e. reinstalling */ 55 | /* a bootblock for a corrupt trackdisk-demo will be completely legal. */ 56 | 57 | /* FIXME: add a check in the bootblock-writer for the 1024-limit */ 58 | int 59 | install_bootblock (unsigned char *bootblock, char *filename) 60 | { 61 | FILE *file; 62 | long seek_pos = 0; 63 | 64 | file = fopen (filename, "r+"); 65 | if (!file) 66 | return 0; 67 | 68 | /* if and only if the disk already contains a filesystem, skip ahead over */ 69 | /* the marker ('D', 'O', 'S' + filesystem-flag) to let them remain intact */ 70 | if (is_adf_file (bootblock)) 71 | seek_pos = 4; 72 | 73 | /* we must do this to let the 4 bytes ("DOS"+filesystem) remain intact */ 74 | if (fseek (file, seek_pos, SEEK_SET) == -1) { 75 | fclose (file); 76 | return 0; 77 | } 78 | 79 | if (fwrite ((bootblock + seek_pos), (BOOTBLOCK_SIZE - seek_pos), 1, file) != 1) { 80 | if (ferror (file)) { 81 | /* error */ 82 | fclose (file); 83 | return 0; 84 | } else if (!feof (file)) { 85 | /* no error and not end of file(?) */ 86 | fclose (file); 87 | return 0; 88 | } 89 | } 90 | 91 | fclose (file); 92 | return 1; 93 | } 94 | 95 | /********************************************************************/ 96 | /* print version, usage, etc */ 97 | /********************************************************************/ 98 | void 99 | print_usage (int status) 100 | { 101 | if (!status) { 102 | notify ("Try '%s --help' for more information.\n", program_name); 103 | } else { 104 | printf ("Usage: %s [OPTIONS]... FILE...\n", program_name); 105 | printf ("Install bootblock on adf-files.\n\n"); 106 | printf ("\t --install[=FILE] \tinstall bootblock `FILE'\n"); 107 | printf ("\t-i \tlike --install, but does not accept an argument and\n"); 108 | printf ("\t \ta standard OS1.3-bootblock will be installed (default)\n"); 109 | printf ("\t-h, --help \tdisplay this help and exit\n"); 110 | printf ("\t-V, --version \tdisplay version information and exit\n"); 111 | printf ("\n"); 112 | print_footer (); 113 | } 114 | 115 | exit (0); 116 | } 117 | 118 | /********************************************************************/ 119 | /* here we go */ 120 | /********************************************************************/ 121 | int 122 | main (int argc, char *argv[]) 123 | { 124 | char *bootblock_filename = NULL; 125 | int c; 126 | int n_files; 127 | 128 | init_adflib(); 129 | 130 | /* parse the options */ 131 | while ((c = getopt_long (argc, argv, "isd:hV", long_options, NULL)) != -1) { 132 | switch (c) { 133 | case 0: 134 | break; 135 | 136 | case INSTALL_OPTION: 137 | bootblock_filename = optarg; 138 | opt_install = 1; 139 | break; 140 | 141 | case 'h': 142 | print_usage (1); 143 | break; 144 | 145 | case 'i': 146 | opt_install_no_arg = 1; 147 | break; 148 | 149 | case 'V': 150 | print_version (); 151 | exit (0); 152 | 153 | default: 154 | print_usage (0); 155 | } 156 | } 157 | 158 | n_files = argc - optind; 159 | if (n_files == 0) { 160 | error (0, "No files specified, nothing to do"); 161 | print_usage (0); 162 | } 163 | 164 | /* -i is default */ 165 | if (!opt_install && !opt_install_no_arg) 166 | opt_install_no_arg = 1; 167 | 168 | /* all remaining arguments should be files */ 169 | if (optind < argc) 170 | while (optind < argc) { 171 | int ret; 172 | char *filename = argv[optind++]; 173 | unsigned char *bootblock = NULL; 174 | 175 | /* read bootblock from the adf-file that should be installed */ 176 | unsigned char *diskbuf = read_bootblock (filename); 177 | 178 | if (!diskbuf) { 179 | error (0, "Can't read bootblock from '%s': %s", filename, strerror (errno)); 180 | continue; 181 | } 182 | 183 | if (!is_adf_file (diskbuf)) { 184 | error (0, "The file '%s' is not a valid adf-file", filename); 185 | continue; 186 | } 187 | 188 | if (bootblock_filename && opt_install && !opt_install_no_arg) { 189 | /**************************/ 190 | /* case 1: --install FILE */ 191 | /**************************/ 192 | bootblock = read_bootblock (bootblock_filename); 193 | if (!bootblock) { 194 | error (0, "Can't read bootblock from '%s': %s", filename, strerror (errno)); 195 | continue; 196 | } 197 | 198 | if (!is_adf_file (bootblock)) { 199 | error (0, "The file '%s' is not an valid bootblock", bootblock_filename); 200 | continue; 201 | } 202 | } else if (opt_install_no_arg && !opt_install) { 203 | /**************/ 204 | /* case 2: -i */ 205 | /**************/ 206 | extern unsigned char OS13_bootblock[49]; 207 | 208 | bootblock = allocate_bootblock_buf(); 209 | if (!bootblock) 210 | error (1, "Can't allocate memory for bootblock: %s", strerror (errno)); 211 | 212 | memcpy (bootblock, &OS13_bootblock, sizeof (OS13_bootblock)); 213 | } else if (opt_install_no_arg && opt_install) { 214 | /****************************/ 215 | /* case 3: -i and --install */ 216 | /****************************/ 217 | error (0, "Both --install and -i? You make me confused"); 218 | print_usage (0); 219 | } else if (!opt_install_no_arg && !opt_install) { 220 | /*******************************************/ 221 | /* case 4: The meaning of life disappeared */ 222 | /*******************************************/ 223 | notify ("Internal error. What the heck did you do?"); 224 | abort (); 225 | } 226 | 227 | ret = install_bootblock (bootblock, filename); 228 | if (!ret) 229 | notify ("FAILED - ", strerror (errno)); 230 | 231 | if (opt_install_no_arg) 232 | notify ("Installing an OS1.3-bootblock to '%s': ", filename); 233 | else if (opt_install) 234 | notify ("Installing '%s' to '%s': ", bootblock_filename, filename); 235 | 236 | if (ret) 237 | notify ("Done.\n"); 238 | else 239 | notify ("%s - FAILED.\n", strerror (errno)); 240 | } 241 | 242 | printf ("All Done.\n"); 243 | 244 | cleanup_adflib(); 245 | return 1; 246 | } 247 | -------------------------------------------------------------------------------- /adflist.c: -------------------------------------------------------------------------------- 1 | /* adflist.c - List files in adf-images 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "error.h" 20 | #include "misc.h" 21 | #include "version.h" 22 | 23 | /* the name of this program */ 24 | char *program_name = ADFLIST; 25 | 26 | /* size of all files */ 27 | static long total_size; 28 | static int num_dirs; 29 | static int num_files; 30 | 31 | /* options */ 32 | static struct option long_options[] = 33 | { 34 | {"help", no_argument, 0, 'h'}, 35 | {"version", no_argument, 0, 'V'}, 36 | 37 | /* end of options */ 38 | {NULL, 0, NULL, 0} 39 | }; 40 | 41 | /********************************************************************/ 42 | /* disk file-functions */ 43 | /********************************************************************/ 44 | /* output information for/from an Entry-block */ 45 | void 46 | print_entry (struct Entry* entry, char *path) 47 | { 48 | /* skip links, ADFlib do not support them properly (yet) */ 49 | if ((entry->type == ST_LFILE) || 50 | (entry->type == ST_LDIR) || 51 | (entry->type == ST_LSOFT)) 52 | return; 53 | 54 | /* directories do not have sizes */ 55 | if (entry->type == ST_DIR) { 56 | printf (" (DIR) "); 57 | num_dirs++; 58 | } else { 59 | printf ("%8ld ", (long int) entry->size); 60 | total_size += entry->size; 61 | num_files++; 62 | } 63 | 64 | printf ("%4d-%02d-%02d %02d:%02d:%02d ", 65 | entry->year, entry->month, entry->days, 66 | entry->hour, entry->mins, entry->secs); 67 | 68 | if (strlen (path) > 0) 69 | printf("%s", path); 70 | 71 | /* append a slash to directories */ 72 | if (entry->type == ST_DIR) { 73 | size_t len = strlen(entry->name); 74 | entry->name[len] = '/'; 75 | entry->name[len + 1] = '\0'; 76 | } 77 | 78 | printf ("%-31s ", entry->name); 79 | 80 | /* no comment */ 81 | if (entry->comment && strlen (entry->comment)) 82 | printf ("(%s)", entry->comment); 83 | 84 | putchar('\n'); 85 | } 86 | 87 | /* print entire directory tree (recursive) */ 88 | void 89 | print_dir (struct Volume *volume, struct List *tree, char *path) 90 | { 91 | char *buf; 92 | struct Entry* entry; 93 | 94 | while (tree) { 95 | print_entry (tree->content, path); 96 | if (tree->subdir) { 97 | entry = tree->content; 98 | if (strlen (path)) { 99 | buf = malloc (strlen (path) + 1 + strlen (entry->name) + 1); 100 | if (!buf) { 101 | error (0, "Can't allocate memory: %s", strerror (errno)); 102 | return; 103 | } 104 | sprintf (buf, "%s%s", path, entry->name); 105 | print_dir (volume, tree->subdir, buf); 106 | free (buf); 107 | } 108 | else 109 | print_dir (volume, tree->subdir, entry->name); 110 | } 111 | tree = tree->next; 112 | } 113 | } 114 | 115 | /* entry function */ 116 | void 117 | list_root_tree (char *filename, struct Volume *volume) 118 | { 119 | char *path = ""; 120 | float proc = 0.0; 121 | register short int i; 122 | // long disk_size; 123 | struct List *cell, *list; 124 | 125 | /* print the name of the volume */ 126 | print_volume_header (filename, volume); 127 | 128 | /* get directory tree, recursively */ 129 | cell = list = adfGetRDirEnt (volume, volume->curDirPtr, 1); 130 | print_dir (volume, cell, path); 131 | 132 | for (i = 0; i < 30; i++) 133 | putchar ('='); 134 | 135 | // proc = (float)total_size / (float)((volume->lastBlock + 1) * 512); 136 | proc = (float)total_size / (float)((volume->lastBlock + 1) * volume->blockSize); 137 | // disk_size = (volume->lastBlock + 1) * volume->blockSize; 138 | 139 | putchar ('\n'); 140 | printf ("%8d file(s)\n", num_files); 141 | printf ("%8d dir(s)\n", num_dirs); 142 | printf ("%8ld bytes used (%5.2f%% full)\n", total_size, proc * 100.0); 143 | // printf ("\n%8ld of %ld bytes used (%5.2f%% full)\n", total_size, disk_size, proc * 100.0); 144 | 145 | // adfFreeDirList(list); 146 | putchar ('\n'); 147 | } 148 | 149 | /********************************************************************/ 150 | /* print version, usage, etc */ 151 | /********************************************************************/ 152 | void 153 | print_usage (int status) 154 | { 155 | if (!status) { 156 | notify ("Try '%s --help' for more information.\n", program_name); 157 | } else { 158 | printf ("Usage: %s [OPTIONS]... FILE(s)...\n", program_name); 159 | printf ("List files in an adf-image.\n\n"); 160 | printf ("\t-h, --help \tdisplay this help and exit\n"); 161 | printf ("\t-V, --version \tdisplay version information and exit\n"); 162 | printf ("\n"); 163 | print_footer (); 164 | } 165 | 166 | exit (0); 167 | } 168 | 169 | /********************************************************************/ 170 | /* here we go */ 171 | /********************************************************************/ 172 | int 173 | main (int argc, char *argv[]) 174 | { 175 | int c; 176 | int n_files; 177 | struct Device *device; 178 | struct Volume *volume; 179 | 180 | init_adflib(); 181 | 182 | /* parse the options */ 183 | while ((c = getopt_long (argc, argv, "hV", long_options, NULL)) != -1) { 184 | switch (c) { 185 | case 0: 186 | break; 187 | 188 | case 'h': 189 | print_usage (1); 190 | break; 191 | 192 | case 'V': 193 | print_version (); 194 | exit (0); 195 | 196 | default: 197 | print_usage (0); 198 | } 199 | } 200 | 201 | n_files = argc - optind; 202 | if (n_files == 0) { 203 | error (0, "No files specified"); 204 | print_usage (0); 205 | } 206 | 207 | /* all remaining arguments should be files */ 208 | if (optind < argc) 209 | while (optind < argc) { 210 | char *filename = argv[optind++]; 211 | 212 | /* lazy way to mount both the device and the volume (if possible) */ 213 | if (!mount_adf (filename, &device, &volume, READ_ONLY)) 214 | continue; 215 | 216 | total_size = 0; 217 | num_files = 0; 218 | num_dirs = 0; 219 | list_root_tree (filename, volume); 220 | } 221 | 222 | printf ("All Done.\n"); 223 | 224 | cleanup_adflib(); 225 | return 1; 226 | } 227 | -------------------------------------------------------------------------------- /adfmakedir.c: -------------------------------------------------------------------------------- 1 | /* adfmakedir.c - Create directories within adf-images 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "error.h" 20 | #include "misc.h" 21 | #include "version.h" 22 | 23 | /* the name of this program */ 24 | char *program_name = ADFMAKEDIR; 25 | 26 | /* we need to maintain a global sector value for the current */ 27 | /* directory if we are going to create subdirectories in it */ 28 | static SECTNUM sector; 29 | 30 | /* options */ 31 | static struct option long_options[] = 32 | { 33 | {"help", no_argument, 0, 'h'}, 34 | {"version", no_argument, 0, 'V'}, 35 | 36 | /* end of options */ 37 | {NULL, 0, NULL, 0} 38 | }; 39 | 40 | /********************************************************************/ 41 | /* disk file-functions */ 42 | /********************************************************************/ 43 | /* this function is recursive */ 44 | void 45 | make_dir (struct Volume *volume, char *directory, SECTNUM sect) 46 | { 47 | /* we need two versions */ 48 | if (!strchr (directory, '/')) { 49 | /*************************************************************************************/ 50 | /* CASE 1: no subdirs specified (no "/" in dir name). create directory in root level */ 51 | /*************************************************************************************/ 52 | /* try to change to the dir first, to see if it already exists */ 53 | if (adfChangeDir (volume, directory) == RC_OK) { 54 | notify ("Directory '%s' exists, skipping.\n", directory); 55 | sector = volume->curDirPtr; 56 | 57 | return; 58 | } 59 | 60 | /* no subdirs, create in the root directory */ 61 | if (adfCreateDir (volume, sector, directory) == RC_OK) { 62 | /* internally change to the dir we just created */ 63 | if (adfChangeDir (volume, directory) != RC_OK) 64 | error (0, "Created directory '%s', but couldn't set it as working directory. Weird", directory); 65 | else 66 | notify ("Created directory '%s'.\n", directory); 67 | 68 | sector = volume->curDirPtr; 69 | } else 70 | error (0, "Could not create directory '%s', no idea why"); 71 | } else { 72 | /***********************************************************/ 73 | /* CASE 2: subdirs specified. strip the / and go recursive */ 74 | /***********************************************************/ 75 | char *tmp = strdup (directory); 76 | 77 | /* repeat as long as there is a / in the directory to be created */ 78 | while (splitc (tmp, directory)) 79 | make_dir (volume, tmp, sector); 80 | 81 | /* last element is left in 'directory' */ 82 | make_dir (volume, directory, sector); 83 | 84 | free (tmp); 85 | } 86 | } 87 | 88 | /********************************************************************/ 89 | /* print version, usage, etc */ 90 | /********************************************************************/ 91 | void 92 | print_usage (int status) 93 | { 94 | if (!status) { 95 | notify ("Try '%s --help' for more information.\n", program_name); 96 | } else { 97 | printf ("Usage: %s FILE DIRECTORY\n", program_name); 98 | printf (" or: %s FILE DIRECTORIES\n", program_name); 99 | printf ("Create directories within adf-images.\n\n"); 100 | printf ("\t-h, --help \tdisplay this help and exit\n"); 101 | printf ("\t-V, --version \tdisplay version information and exit\n"); 102 | printf ("\n"); 103 | print_footer (); 104 | } 105 | 106 | exit (0); 107 | } 108 | 109 | /********************************************************************/ 110 | /* here we go */ 111 | /********************************************************************/ 112 | int 113 | main (int argc, char *argv[]) 114 | { 115 | char *firstarg; 116 | int c; 117 | int n_files; 118 | struct Device *device; 119 | struct Volume *volume; 120 | 121 | init_adflib(); 122 | 123 | /* parse the options */ 124 | while ((c = getopt_long (argc, argv, "hV", long_options, NULL)) != -1) { 125 | switch (c) { 126 | case 0: 127 | break; 128 | 129 | case 'h': 130 | print_usage (1); 131 | break; 132 | 133 | case 'V': 134 | print_version (); 135 | exit (0); 136 | 137 | default: 138 | print_usage (0); 139 | } 140 | } 141 | 142 | /* first argument is (should be) the adf-file */ 143 | firstarg = argv[optind++]; 144 | 145 | n_files = argc - optind; 146 | if (n_files < 0) { 147 | error (0, "No adf-file specified"); 148 | print_usage (0); 149 | } else if (n_files == 0) { 150 | error (0, "Too few arguments"); 151 | print_usage (0); 152 | } 153 | 154 | /* all remaining arguments should be directories to create */ 155 | if (optind < argc) { 156 | /* mount the adf-file */ 157 | if (!mount_adf (firstarg, &device, &volume, READ_WRITE)) 158 | exit(1); 159 | 160 | /* step through the remaining arguments */ 161 | while (optind < argc) { 162 | char *directory = argv[optind++]; 163 | 164 | change_to_root_dir (volume); 165 | sector = volume->rootBlock; 166 | make_dir (volume, directory, sector); 167 | } 168 | } 169 | 170 | printf ("All Done.\n"); 171 | 172 | cleanup_adflib(); 173 | return 1; 174 | } 175 | -------------------------------------------------------------------------------- /bootblocks.c: -------------------------------------------------------------------------------- 1 | /* bootblocks.c - some common bootblocks 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | 9 | /* bootblocks must *NOT* be greater than 1024 bytes. */ 10 | /* all trailing zeros can be omitted. */ 11 | 12 | /* these bootblocks are autogenerated with the bb2c shell-script */ 13 | 14 | /* standard OS1.3-bootblock */ 15 | unsigned char OS13_bootblock[49] = { 16 | 0x44, 0x4f, 0x53, 0x00, 0xc0, 0x20, 0x0f, 0x19, 0x00, 0x00, 0x03, 0x70, 0x43, 0xfa, 0x00, 0x18, 0x4e, 0xae, 0xff, 0xa0, 17 | 0x4a, 0x80, 0x67, 0x0a, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 0x70, 0xff, 0x60, 0xfa, 0x64, 0x6f, 18 | 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79 19 | }; 20 | 21 | /* standard OS2.0-bootblock */ 22 | unsigned char OS20_bootblock[93] = { 23 | 0x44, 0x4f, 0x53, 0x00, 0xe3, 0x3d, 0x0e, 0x73, 0x00, 0x00, 0x03, 0x70, 0x43, 0xfa, 0x00, 0x3e, 0x70, 0x25, 0x4e, 0xae, 24 | 0xfd, 0xd8, 0x4a, 0x80, 0x67, 0x0c, 0x22, 0x40, 0x08, 0xe9, 0x00, 0x06, 0x00, 0x22, 0x4e, 0xae, 0xfe, 0x62, 0x43, 0xfa, 25 | 0x00, 0x18, 0x4e, 0xae, 0xff, 0xa0, 0x4a, 0x80, 0x67, 0x0a, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 26 | 0x70, 0xff, 0x4e, 0x75, 0x64, 0x6f, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x65, 0x78, 0x70, 0x61, 27 | 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79 28 | }; 29 | 30 | /* Scoopex Utility Boot V1.0, Nomad / Scoopex */ 31 | unsigned char ScoopexUtilityBootV10_bootblock[1023] = { 32 | 0x44, 0x4f, 0x53, 0x00, 0x0f, 0x0f, 0xde, 0x06, 0x00, 0x00, 0x03, 0x70, 0x48, 0xe7, 0xff, 0x7e, 0x23, 0x7c, 0x00, 0x03, 33 | 0x00, 0x00, 0x00, 0x28, 0x4e, 0xae, 0xfe, 0x38, 0x33, 0x7c, 0x00, 0x09, 0x00, 0x1c, 0x42, 0xa9, 0x00, 0x24, 0x4e, 0xae, 34 | 0xfe, 0x38, 0x41, 0xfa, 0x03, 0xc2, 0x22, 0x69, 0x00, 0x14, 0x20, 0xa9, 0x00, 0x3c, 0x22, 0x69, 0x00, 0x38, 0x2f, 0x29, 35 | 0x00, 0x32, 0x2f, 0x09, 0x0c, 0x6e, 0x00, 0x08, 0x00, 0x3e, 0x66, 0x06, 0x4a, 0xae, 0x00, 0x4e, 0x67, 0x08, 0x43, 0xfa, 36 | 0x02, 0xda, 0x32, 0xbc, 0x4e, 0x20, 0x20, 0x7a, 0x03, 0x96, 0x41, 0xe8, 0x00, 0x34, 0x4a, 0x98, 0x67, 0x08, 0x4a, 0x98, 37 | 0x67, 0x04, 0x4a, 0x98, 0x66, 0x0e, 0x43, 0xfa, 0x02, 0xae, 0x32, 0xbc, 0x4e, 0x20, 0x43, 0xfa, 0x03, 0x8a, 0x42, 0x11, 38 | 0x2c, 0x57, 0x33, 0xfc, 0x00, 0xa0, 0x00, 0xdf, 0xf0, 0x96, 0x43, 0xfa, 0x02, 0x2c, 0x2d, 0x49, 0x00, 0x32, 0x43, 0xf9, 39 | 0x00, 0x07, 0x00, 0x00, 0x42, 0x99, 0xb3, 0xfc, 0x00, 0x07, 0xf0, 0x00, 0x66, 0xf6, 0x2c, 0x57, 0x41, 0xf9, 0x00, 0x04, 40 | 0x10, 0x00, 0x70, 0x01, 0x22, 0x3c, 0x00, 0x00, 0x03, 0x00, 0x24, 0x3c, 0x00, 0x00, 0x01, 0x00, 0x4e, 0xae, 0xfe, 0x7a, 41 | 0x23, 0xfc, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x10, 0x08, 0x43, 0xf9, 0x00, 0x04, 0x11, 0x00, 0x4e, 0xae, 0xff, 0x3a, 42 | 0x23, 0xfc, 0x00, 0x04, 0x10, 0x00, 0x00, 0x04, 0x11, 0x04, 0x43, 0xf9, 0x00, 0x04, 0x11, 0x00, 0x70, 0x01, 0x4e, 0xae, 43 | 0xfe, 0xaa, 0x61, 0x3c, 0x33, 0xfc, 0x83, 0x80, 0x00, 0xdf, 0xf0, 0x96, 0x2c, 0x78, 0x00, 0x04, 0x4a, 0xae, 0x00, 0x2a, 44 | 0x66, 0x0c, 0x4a, 0xae, 0x00, 0x2e, 0x66, 0x06, 0x4a, 0xae, 0x02, 0x2a, 0x67, 0x72, 0x43, 0xfa, 0x02, 0xaf, 0x13, 0x7c, 45 | 0x00, 0x20, 0x00, 0x1a, 0x12, 0xfc, 0x00, 0x20, 0x12, 0xbc, 0x00, 0x41, 0x43, 0xfa, 0x01, 0xd4, 0x32, 0xbc, 0x0a, 0x00, 46 | 0x61, 0x02, 0x60, 0x54, 0x4b, 0xfa, 0x01, 0xce, 0x2f, 0x04, 0x2c, 0x6f, 0x00, 0x08, 0x43, 0xf9, 0x00, 0x04, 0x11, 0x00, 47 | 0x42, 0x84, 0x26, 0x3c, 0x00, 0x00, 0x00, 0x32, 0x18, 0x1d, 0x67, 0x34, 0x61, 0x10, 0x06, 0x83, 0x00, 0x00, 0x01, 0x80, 48 | 0x61, 0x00, 0x00, 0x08, 0x4b, 0xed, 0x00, 0x1f, 0x60, 0xd8, 0x43, 0xf9, 0x00, 0x04, 0x11, 0x00, 0x20, 0x03, 0x22, 0x04, 49 | 0x4e, 0xae, 0xff, 0x10, 0x43, 0xf9, 0x00, 0x04, 0x11, 0x00, 0x20, 0x4d, 0x20, 0x3c, 0x00, 0x00, 0x00, 0x1f, 0x4e, 0xae, 50 | 0xff, 0xc4, 0x4e, 0x75, 0x28, 0x1f, 0x4e, 0x75, 0x28, 0x3c, 0x00, 0x0f, 0xf0, 0x00, 0x53, 0x84, 0x67, 0x00, 0x00, 0x88, 51 | 0x4b, 0xf9, 0x00, 0xbf, 0xe0, 0x01, 0x08, 0x15, 0x00, 0x06, 0x67, 0x00, 0x00, 0x7a, 0x10, 0x39, 0x00, 0xbf, 0xec, 0x01, 52 | 0x42, 0x39, 0x00, 0xbf, 0xec, 0x01, 0x46, 0x00, 0xb0, 0x3c, 0x00, 0xa0, 0x67, 0x00, 0x00, 0xe0, 0xb0, 0x3c, 0x00, 0xa2, 53 | 0x66, 0x1e, 0x47, 0xfa, 0x01, 0x72, 0x45, 0xfa, 0x02, 0x52, 0x08, 0x52, 0x00, 0x01, 0x4a, 0x12, 0x66, 0x06, 0x36, 0xbc, 54 | 0x4e, 0x20, 0x60, 0x04, 0x36, 0xbc, 0x46, 0x46, 0x61, 0x00, 0xff, 0x5a, 0xb0, 0x3c, 0x00, 0xa4, 0x66, 0x12, 0x2c, 0x78, 55 | 0x00, 0x04, 0x42, 0xae, 0x00, 0x26, 0x4b, 0xf9, 0x00, 0xfc, 0x00, 0xd0, 0x4e, 0xee, 0xff, 0xe2, 0xb0, 0x3c, 0x00, 0xa6, 56 | 0x67, 0x5c, 0xb0, 0x3c, 0x00, 0xa8, 0x67, 0xe2, 0xb0, 0x3c, 0x00, 0xaa, 0x66, 0x04, 0x08, 0x55, 0x00, 0x01, 0xb0, 0x3c, 57 | 0x00, 0xac, 0x67, 0xd2, 0xb0, 0x3c, 0x00, 0xae, 0x67, 0x04, 0x60, 0x00, 0xff, 0x76, 0x43, 0xfa, 0x01, 0xfa, 0x4a, 0x11, 58 | 0x67, 0x10, 0x20, 0x7a, 0x01, 0xe2, 0x41, 0xe8, 0x00, 0x34, 0x70, 0xff, 0x20, 0xc0, 0x20, 0xc0, 0x20, 0x80, 0x61, 0x12, 59 | 0x43, 0xfa, 0x01, 0xd4, 0x4e, 0xae, 0xff, 0xa0, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 0x20, 0x5f, 60 | 0x2c, 0x5f, 0x2d, 0x5f, 0x00, 0x32, 0x4c, 0xdf, 0x7e, 0xff, 0x2f, 0x08, 0x4e, 0x75, 0x61, 0xee, 0x33, 0x7c, 0x00, 0x05, 61 | 0x00, 0x1c, 0x41, 0xf9, 0x00, 0x05, 0x00, 0x00, 0x61, 0x1a, 0x33, 0x7c, 0x00, 0x03, 0x00, 0x1c, 0x61, 0x0c, 0x33, 0x7c, 62 | 0x00, 0x04, 0x00, 0x1c, 0x61, 0x04, 0x60, 0x00, 0xfd, 0xac, 0x41, 0xf9, 0x00, 0x03, 0x00, 0x00, 0x23, 0x48, 0x00, 0x28, 63 | 0x23, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x24, 0x42, 0xa9, 0x00, 0x2c, 0x4e, 0xae, 0xfe, 0x38, 0x4e, 0x75, 0x20, 0x78, 64 | 0x00, 0x04, 0x4b, 0xf9, 0x00, 0xfc, 0x02, 0x80, 0x0c, 0x65, 0x21, 0xfc, 0x66, 0xfa, 0x99, 0xcc, 0x4d, 0xf9, 0x00, 0x00, 65 | 0x06, 0x76, 0x47, 0xf9, 0x00, 0x08, 0x00, 0x00, 0x43, 0xf9, 0x00, 0xdf, 0xf0, 0x96, 0x20, 0x3c, 0x7f, 0xff, 0x7f, 0xff, 66 | 0x22, 0xc0, 0x22, 0xc0, 0x4e, 0xe8, 0xff, 0xe2, 0x01, 0x00, 0x22, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x92, 0x00, 0x20, 67 | 0x00, 0x94, 0x00, 0xd8, 0x00, 0x8e, 0x30, 0x00, 0x00, 0x90, 0x30, 0xff, 0x00, 0xe0, 0x00, 0x07, 0x00, 0xe2, 0x08, 0x70, 68 | 0x00, 0xe4, 0x00, 0x07, 0x00, 0xe6, 0x08, 0xa0, 0x01, 0x86, 0x0a, 0xaa, 0x01, 0x84, 0x0e, 0xee, 0x01, 0x82, 0x07, 0x77, 69 | 0x01, 0x80, 0x00, 0x05, 0xff, 0xff, 0xff, 0xfe, 0x20, 0x20, 0x20, 0x53, 0x43, 0x4f, 0x4f, 0x50, 0x45, 0x58, 0x20, 0x55, 70 | 0x54, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x20, 0x42, 0x4f, 0x4f, 0x54, 0x20, 0x20, 0x56, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x20, 71 | 0x2a, 0x44, 0x52, 0x49, 0x56, 0x45, 0x53, 0x20, 0x41, 0x52, 0x45, 0x3a, 0x20, 0x4f, 0x46, 0x46, 0x20, 0x20, 0x4d, 0x45, 72 | 0x4d, 0x4f, 0x52, 0x59, 0x20, 0x49, 0x53, 0x3a, 0x20, 0x4f, 0x46, 0x46, 0x3a, 0x46, 0x31, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 73 | 0x52, 0x59, 0x20, 0x4f, 0x46, 0x46, 0x20, 0x20, 0x46, 0x32, 0x20, 0x54, 0x4f, 0x47, 0x47, 0x4c, 0x45, 0x20, 0x44, 0x52, 74 | 0x49, 0x56, 0x45, 0x53, 0x43, 0x46, 0x33, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x20, 0x4f, 0x4e, 0x20, 0x20, 0x20, 75 | 0x46, 0x34, 0x20, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x20, 0x42, 0x4f, 0x4f, 0x54, 0x20, 0x4c, 0x46, 0x35, 0x20, 76 | 0x48, 0x41, 0x52, 0x44, 0x20, 0x52, 0x45, 0x53, 0x45, 0x54, 0x20, 0x20, 0x46, 0x36, 0x20, 0x54, 0x4f, 0x47, 0x47, 0x4c, 77 | 0x45, 0x20, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x55, 0x46, 0x37, 0x20, 0x4b, 0x49, 0x4c, 0x4c, 0x20, 0x56, 0x49, 0x52, 78 | 0x55, 0x53, 0x20, 0x20, 0x46, 0x38, 0x20, 0x45, 0x58, 0x49, 0x54, 0x20, 0x54, 0x4f, 0x20, 0x43, 0x4c, 0x49, 0x2e, 0x20, 79 | 0x64, 0x20, 0x20, 0x4e, 0x4f, 0x20, 0x56, 0x49, 0x52, 0x55, 0x53, 0x20, 0x48, 0x41, 0x53, 0x20, 0x42, 0x45, 0x45, 0x4e, 80 | 0x20, 0x44, 0x45, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x21, 0x20, 0x20, 0x6e, 0x43, 0x4f, 0x44, 0x45, 0x44, 0x20, 0x42, 81 | 0x59, 0x20, 0x20, 0x4e, 0x2e, 0x4f, 0x2e, 0x4d, 0x2e, 0x41, 0x2e, 0x44, 0x20, 0x20, 0x4f, 0x46, 0x20, 0x53, 0x43, 0x4f, 82 | 0x4f, 0x50, 0x45, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x6f, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 83 | 0x79, 0x00, 0x02 84 | }; 85 | 86 | /* Scoopex Utility Boot V1.3, Photon / Scoopex */ 87 | unsigned char ScoopexUtilityBootV13_bootblock[1023] = { 88 | 0x44, 0x4f, 0x53, 0x00, 0x93, 0x3e, 0x3e, 0x65, 0x00, 0x00, 0x03, 0x70, 0x48, 0xe7, 0x7f, 0xfe, 0x49, 0xfa, 0xff, 0xea, 89 | 0x28, 0xc9, 0x2a, 0x4c, 0x41, 0xf9, 0x00, 0x06, 0xc9, 0xa0, 0x3e, 0x3c, 0x0d, 0x97, 0x42, 0xa8, 0x36, 0x60, 0x20, 0xdc, 90 | 0x51, 0xcf, 0xff, 0xf8, 0x49, 0xf9, 0x00, 0xdf, 0xf0, 0x06, 0x45, 0xf9, 0x00, 0xfc, 0x00, 0x00, 0x0c, 0x9a, 0x7c, 0x18, 91 | 0xfc, 0x3c, 0x66, 0xf8, 0x0c, 0x9a, 0xf8, 0xfe, 0xfe, 0x3c, 0x66, 0xf0, 0x70, 0x09, 0x61, 0x00, 0x01, 0xa2, 0x43, 0xfa, 92 | 0x03, 0x96, 0x4e, 0xae, 0xfe, 0x0e, 0x20, 0x40, 0x41, 0xe8, 0x00, 0x34, 0x2b, 0x48, 0xff, 0xf0, 0x4a, 0x90, 0x67, 0x06, 93 | 0x3b, 0x7c, 0x46, 0x46, 0x03, 0x24, 0xbd, 0xfc, 0x00, 0x20, 0x00, 0x00, 0x6c, 0x06, 0x3b, 0x7c, 0x46, 0x46, 0x03, 0x12, 94 | 0x41, 0xfa, 0x02, 0x5e, 0x47, 0xf9, 0x00, 0x07, 0x00, 0xb8, 0x70, 0x3e, 0x72, 0x7f, 0x7e, 0x04, 0x24, 0x18, 0x7c, 0x1f, 95 | 0x0d, 0x02, 0x67, 0x0e, 0x16, 0x80, 0x17, 0x41, 0x00, 0x50, 0x17, 0x41, 0x00, 0xa0, 0x17, 0x40, 0x00, 0xf0, 0x52, 0x4b, 96 | 0x51, 0xce, 0xff, 0xea, 0x47, 0xeb, 0x01, 0x70, 0x51, 0xcf, 0xff, 0xde, 0x41, 0xfa, 0x02, 0xf7, 0x32, 0x3c, 0x12, 0x41, 97 | 0x61, 0x12, 0x41, 0xfa, 0x02, 0x34, 0x32, 0x3c, 0x0a, 0x0f, 0x61, 0x08, 0x39, 0x7c, 0x83, 0xd0, 0x00, 0x90, 0x60, 0x40, 98 | 0x70, 0x00, 0x74, 0x00, 0x14, 0x18, 0x67, 0x36, 0x6a, 0x08, 0x70, 0x00, 0x06, 0x41, 0x02, 0xd0, 0x60, 0xf0, 0x0c, 0x02, 99 | 0x00, 0x09, 0x66, 0x04, 0x50, 0x40, 0x60, 0xe6, 0x43, 0xf2, 0x20, 0xb8, 0x47, 0xf9, 0x00, 0x07, 0x00, 0x50, 0xd6, 0xc0, 100 | 0xd6, 0xc1, 0x7e, 0x07, 0x16, 0x91, 0x43, 0xe9, 0x00, 0xc0, 0x47, 0xeb, 0x00, 0x50, 0x51, 0xcf, 0xff, 0xf4, 0x52, 0x40, 101 | 0x60, 0xc4, 0x4e, 0x75, 0x4a, 0xae, 0x00, 0x2a, 0x66, 0x0c, 0x4a, 0xae, 0x00, 0x2e, 0x66, 0x06, 0x4a, 0xae, 0x02, 0x2a, 102 | 0x67, 0x0c, 0x41, 0xfa, 0x02, 0x8c, 0x32, 0x3c, 0x12, 0x36, 0x61, 0xa4, 0x61, 0xa4, 0x41, 0xfa, 0x01, 0x30, 0x29, 0x48, 103 | 0x00, 0x7a, 0x0c, 0x2e, 0x00, 0x32, 0x02, 0x12, 0x67, 0x10, 0x41, 0xfa, 0x02, 0x95, 0x32, 0x3c, 0x12, 0x3c, 0x61, 0x88, 104 | 0x70, 0x31, 0x61, 0x58, 0x60, 0x68, 0x47, 0xf9, 0x00, 0xbf, 0xec, 0x01, 0x1a, 0x13, 0x41, 0xeb, 0xf4, 0x00, 0x08, 0x2c, 105 | 0x00, 0x0a, 0x00, 0x10, 0x67, 0x50, 0x08, 0x10, 0x00, 0x06, 0x67, 0x00, 0x00, 0xb4, 0x10, 0x13, 0xb0, 0x05, 0x67, 0xe6, 106 | 0x1a, 0x00, 0x04, 0x00, 0x00, 0x5f, 0x67, 0x48, 0x54, 0x00, 0x66, 0x0e, 0x46, 0x2d, 0x03, 0xe5, 0x0a, 0x6d, 0x08, 0x66, 107 | 0x03, 0x24, 0x60, 0x00, 0xfe, 0xea, 0x54, 0x00, 0x66, 0x04, 0x08, 0x50, 0x00, 0x01, 0x54, 0x00, 0x66, 0xc0, 0x70, 0x03, 108 | 0x61, 0x5c, 0x70, 0x04, 0x61, 0x58, 0x70, 0x09, 0x61, 0x54, 0x60, 0xb2, 0x4a, 0x14, 0x6a, 0xfc, 0x4a, 0x14, 0x6b, 0xfc, 109 | 0x51, 0xc8, 0xff, 0xf6, 0x4e, 0x75, 0x42, 0xae, 0x00, 0x26, 0x21, 0xfc, 0x00, 0xfc, 0x00, 0x02, 0x00, 0x80, 0x4e, 0x40, 110 | 0x0c, 0x2d, 0x00, 0x46, 0x03, 0x12, 0x67, 0xea, 0x39, 0x7c, 0x7f, 0xff, 0x00, 0x90, 0x39, 0x7c, 0x7f, 0xff, 0x00, 0x94, 111 | 0x4c, 0xdf, 0x7f, 0xfe, 0x4b, 0xf9, 0x00, 0xfc, 0x02, 0x80, 0x0c, 0x65, 0x21, 0xfc, 0x66, 0xfa, 0x20, 0x4e, 0x99, 0xcc, 112 | 0x4d, 0xf8, 0x06, 0x76, 0x47, 0xf9, 0x00, 0x08, 0x00, 0x00, 0x4e, 0xe8, 0xff, 0xe2, 0x22, 0x6d, 0xff, 0xfc, 0x33, 0x40, 113 | 0x00, 0x1c, 0x23, 0x7c, 0x00, 0x06, 0xc9, 0xa0, 0x00, 0x28, 0x23, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x24, 0x42, 0xa9, 114 | 0x00, 0x2c, 0x42, 0xa9, 0x00, 0x24, 0x4e, 0xae, 0xfe, 0x38, 0x4e, 0x75, 0x70, 0x00, 0x10, 0x3a, 0x01, 0xcd, 0x20, 0x6d, 115 | 0xff, 0xf0, 0x81, 0x98, 0x81, 0x98, 0x81, 0x90, 0x2c, 0x56, 0x2c, 0x56, 0x20, 0x6e, 0x00, 0x26, 0x29, 0x48, 0x00, 0x7a, 116 | 0x58, 0x48, 0x0c, 0x58, 0x01, 0x80, 0x66, 0x06, 0x42, 0x50, 0x42, 0x68, 0x00, 0x04, 0x42, 0xac, 0x01, 0x7a, 0x4c, 0xdf, 117 | 0x7f, 0xfe, 0x43, 0xfa, 0x01, 0xac, 0x4e, 0xae, 0xff, 0xa0, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 118 | 0x00, 0xe0, 0x00, 0x07, 0x00, 0xe2, 0x00, 0x50, 0x00, 0xe4, 0x00, 0x07, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x96, 0x00, 0x20, 119 | 0x01, 0x00, 0xa6, 0x00, 0x01, 0x02, 0x00, 0x20, 0x00, 0x8e, 0x53, 0x81, 0x00, 0x90, 0xfe, 0xc1, 0x00, 0x92, 0x00, 0x3c, 120 | 0x00, 0x94, 0x00, 0xd4, 0x4f, 0x07, 0xff, 0xfe, 0x01, 0x80, 0x0f, 0x00, 0x01, 0x82, 0x0f, 0x93, 0x01, 0x92, 0x02, 0x00, 121 | 0x50, 0x07, 0xff, 0xfe, 0x01, 0x80, 0x06, 0x00, 0x70, 0x07, 0xff, 0xfe, 0x01, 0x02, 0x00, 0x10, 0x01, 0x82, 0x0f, 0x66, 122 | 0x8d, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x0f, 0xee, 0xa5, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x0f, 0x66, 0xf0, 0x07, 0xff, 0xfe, 123 | 0x01, 0x82, 0x05, 0x00, 0x01, 0x92, 0x07, 0x00, 0xfe, 0x07, 0xff, 0xfe, 0x01, 0x80, 0x0f, 0x00, 0xff, 0x07, 0xff, 0xfe, 124 | 0x01, 0x80, 0x01, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x73, 0x31, 0x9c, 0x69, 0x84, 0x4a, 0x52, 0x89, 0x64, 0x4a, 0x5c, 0xe6, 125 | 0x14, 0x4a, 0x50, 0x89, 0xe3, 0x31, 0x90, 0x69, 0x09, 0x09, 0x55, 0x54, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x2d, 0x42, 0x4f, 126 | 0x4f, 0x54, 0x20, 0x56, 0x31, 0x2e, 0x33, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0x09, 0x46, 0x41, 0x53, 0x54, 0x4d, 0x45, 127 | 0x4d, 0x20, 0x69, 0x73, 0x20, 0x4f, 0x4e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x52, 0x49, 0x56, 0x45, 0x53, 0x20, 0x61, 128 | 0x72, 0x65, 0x20, 0x4f, 0x4e, 0x20, 0xf6, 0xf6, 0x09, 0x09, 0x46, 0x31, 0x3a, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x20, 129 | 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0xf6, 0x09, 0x09, 0x46, 0x32, 0x3a, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x20, 0x44, 130 | 0x72, 0x69, 0x76, 0x65, 0x73, 0xf6, 0x09, 0x09, 0x46, 0x33, 0x3a, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x20, 0x46, 0x69, 131 | 0x6c, 0x74, 0x65, 0x72, 0xf6, 0x09, 0x09, 0x46, 0x34, 0x3a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x20, 0x42, 0x6f, 132 | 0x6f, 0x74, 0xf6, 0xf6, 0x4c, 0x45, 0x46, 0x54, 0x2d, 0x45, 0x78, 0x69, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x43, 0x4c, 0x49, 133 | 0x09, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x74, 0xf6, 0x09, 134 | 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x6e, 0x00, 0x4e, 0x4f, 0x20, 0x56, 0x49, 0x52, 0x55, 135 | 0x53, 0x20, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x00, 0x21, 0x20, 0x48, 0x41, 0x52, 0x44, 0x2d, 0x52, 0x45, 0x53, 0x45, 0x54, 136 | 0x20, 0x54, 0x4f, 0x20, 0x4b, 0x49, 0x4c, 0x4c, 0x20, 0x49, 0x54, 0x21, 0x00, 0x4e, 0x54, 0x53, 0x43, 0x20, 0x21, 0x20, 137 | 0x53, 0x4f, 0x46, 0x54, 0x2d, 0x52, 0x45, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x2e, 0x2e, 0x2e, 0x00, 0x64, 0x69, 138 | 0x73, 0x6b, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x64, 0x6f, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 139 | 0x61, 0x72, 0x79 140 | }; 141 | 142 | /* MiniNuke V1.0, Shagratt / LSD */ 143 | unsigned char MiniNukeV10_bootblock[1022] = { 144 | 0x44, 0x4f, 0x53, 0x00, 0x07, 0xdb, 0x6f, 0xcb, 0x00, 0x00, 0x03, 0x70, 0xb9, 0xfc, 0x00, 0x08, 0x00, 0x00, 0x6d, 0x1c, 145 | 0x49, 0xf9, 0x00, 0x07, 0x00, 0x00, 0x41, 0xfa, 0xff, 0xe4, 0x30, 0x3c, 0x03, 0xff, 0x19, 0xb0, 0x00, 0x00, 0x00, 0x00, 146 | 0x51, 0xc8, 0xff, 0xf8, 0x4e, 0xec, 0x00, 0x0c, 0x48, 0xe7, 0xff, 0xfe, 0x22, 0x69, 0x00, 0x14, 0x2c, 0x69, 0x00, 0x38, 147 | 0x23, 0xce, 0x00, 0x00, 0x01, 0xc0, 0x43, 0xf9, 0x00, 0x07, 0x84, 0x00, 0x24, 0x49, 0x30, 0x3c, 0x10, 0x00, 0x42, 0x99, 148 | 0x51, 0xc8, 0xff, 0xfc, 0x49, 0xf9, 0x00, 0xdf, 0xf0, 0x00, 0x39, 0x7c, 0x01, 0xa0, 0x00, 0x96, 0x41, 0xf9, 0x00, 0x07, 149 | 0x80, 0x00, 0x21, 0x4a, 0x00, 0x08, 0x70, 0x01, 0x22, 0x3c, 0x00, 0x00, 0x02, 0x80, 0x24, 0x3c, 0x00, 0x00, 0x00, 0xc8, 150 | 0x4e, 0xae, 0xfe, 0x7a, 0x43, 0xf9, 0x00, 0x07, 0x81, 0x00, 0x4e, 0xae, 0xff, 0x3a, 0x43, 0xf9, 0x00, 0x07, 0x81, 0x00, 151 | 0x23, 0x7c, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04, 0x70, 0x01, 0x4e, 0xae, 0xfe, 0xaa, 0x4b, 0xfa, 0x01, 0xc6, 0x61, 0x00, 152 | 0x01, 0x2c, 0x39, 0x7c, 0x83, 0x80, 0x00, 0x96, 0x43, 0xfa, 0x01, 0x54, 0x29, 0x49, 0x00, 0x80, 0x2c, 0x78, 0x00, 0x04, 153 | 0x42, 0x80, 0x80, 0xae, 0x00, 0x2a, 0x80, 0xae, 0x00, 0x2e, 0x80, 0xae, 0x00, 0x32, 0x80, 0xae, 0x02, 0x22, 0x80, 0xae, 154 | 0x02, 0x26, 0x80, 0xae, 0x02, 0x2a, 0x4a, 0x80, 0x66, 0x3e, 0x4b, 0xfa, 0x01, 0xcb, 0x61, 0x00, 0x00, 0xf4, 0x28, 0x3c, 155 | 0x00, 0x08, 0x00, 0x00, 0x08, 0x39, 0x00, 0x06, 0x00, 0xbf, 0xe0, 0x01, 0x67, 0x04, 0x53, 0x84, 0x66, 0xf2, 0x22, 0x79, 156 | 0x00, 0x00, 0x01, 0xc0, 0x29, 0x69, 0x00, 0x26, 0x00, 0x80, 0x4c, 0xdf, 0x7f, 0xff, 0x43, 0xfa, 0x01, 0x56, 0x4e, 0xae, 157 | 0xff, 0xa0, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 0x43, 0xfa, 0x01, 0x18, 0x45, 0xfa, 0x01, 0x24, 158 | 0x41, 0xfa, 0x00, 0xf4, 0x30, 0x3c, 0x0f, 0x00, 0x33, 0x40, 0x00, 0x06, 0x35, 0x40, 0x00, 0x06, 0x30, 0x3c, 0x04, 0x00, 159 | 0x33, 0x40, 0x00, 0x0e, 0x35, 0x40, 0x00, 0x0e, 0x31, 0x40, 0x00, 0x02, 0x20, 0x6e, 0x00, 0x2a, 0x0c, 0x90, 0x48, 0x7a, 160 | 0x00, 0x10, 0x67, 0x7c, 0x20, 0x6e, 0x02, 0x22, 0xb1, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x67, 0x2a, 0xd1, 0xfc, 0x00, 0x00, 161 | 0x00, 0x0a, 0x20, 0x50, 0x20, 0x10, 0x0c, 0x80, 0x54, 0x54, 0x56, 0x31, 0x67, 0x64, 0x0c, 0x80, 0x72, 0x61, 0x6d, 0x64, 162 | 0x66, 0x10, 0x4b, 0xfa, 0x01, 0xcd, 0x61, 0x5c, 0x28, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x60, 0x00, 0xff, 0x68, 0x4b, 0xfa, 163 | 0x01, 0x69, 0x61, 0x4c, 0x08, 0x39, 0x00, 0x06, 0x00, 0xbf, 0xe0, 0x01, 0x67, 0x24, 0x08, 0x2c, 0x00, 0x02, 0x00, 0x16, 164 | 0x66, 0xee, 0x28, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x60, 0x00, 0xff, 0x46, 0x61, 0x2e, 0x4b, 0xfa, 0x01, 0xc6, 0x61, 0x28, 165 | 0x08, 0x39, 0x00, 0x06, 0x00, 0xbf, 0xe0, 0x01, 0x66, 0xf6, 0x2c, 0x78, 0x00, 0x04, 0x42, 0xae, 0x00, 0x26, 0x4b, 0xf9, 166 | 0x00, 0xfc, 0x00, 0xd0, 0x4e, 0xee, 0xff, 0xe2, 0x4b, 0xfa, 0x02, 0x1d, 0x60, 0xd6, 0x4b, 0xfa, 0x01, 0xf9, 0x60, 0xd0, 167 | 0x2c, 0x79, 0x00, 0x00, 0x01, 0xc0, 0x42, 0x80, 0x42, 0x81, 0x10, 0x1d, 0x12, 0x1d, 0x43, 0xf9, 0x00, 0x07, 0x81, 0x00, 168 | 0x4e, 0xae, 0xff, 0x10, 0x42, 0x80, 0x43, 0xf9, 0x00, 0x07, 0x81, 0x00, 0x10, 0x1d, 0x20, 0x4d, 0xdb, 0xc0, 0x4e, 0xae, 169 | 0xff, 0xc4, 0x0c, 0x15, 0x00, 0x00, 0x66, 0xd0, 0x4e, 0x75, 0x01, 0x00, 0x92, 0x00, 0x01, 0x02, 0x00, 0x01, 0x01, 0x08, 170 | 0x00, 0x00, 0x01, 0x82, 0x0f, 0xff, 0x01, 0x80, 0x00, 0x04, 0x00, 0x92, 0x00, 0x3c, 0x00, 0x94, 0x00, 0xd4, 0x00, 0x8e, 171 | 0x2c, 0x81, 0x00, 0x90, 0x00, 0xc1, 0x00, 0xe0, 0x00, 0x07, 0x00, 0xe2, 0x84, 0x00, 0x30, 0x07, 0xff, 0xfe, 0x01, 0x80, 172 | 0x00, 0x0f, 0x32, 0x07, 0xff, 0xfe, 0x01, 0x80, 0x00, 0x00, 0xfd, 0x07, 0xff, 0xfe, 0x01, 0x80, 0x00, 0x0f, 0xff, 0x07, 173 | 0xff, 0xfe, 0x01, 0x80, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x64, 0x6f, 174 | 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0xdc, 0x1e, 0x14, 0xbb, 0xbb, 0xbb, 0xbb, 0x20, 0x4d, 0x49, 175 | 0x4e, 0x49, 0x2d, 0x4e, 0x55, 0x4b, 0x45, 0x21, 0x20, 0xab, 0xab, 0xab, 0xab, 0xff, 0x2d, 0x0c, 0x56, 0x65, 0x72, 0x73, 176 | 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x61, 0xe1, 0x3c, 0x13, 0xa9, 0x20, 0x53, 0x68, 0x61, 0x67, 0x72, 0x61, 0x74, 177 | 0x74, 0x2f, 0x4c, 0x53, 0x44, 0x20, 0x31, 0x39, 0x39, 0x32, 0x00, 0xc8, 0x96, 0x18, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 178 | 0x73, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x2d, 0x20, 0x41, 0x4c, 0x4c, 0x20, 0x4f, 0x4b, 0x7d, 0xa5, 179 | 0x27, 0x4e, 0x6f, 0x20, 0x43, 0x4f, 0x4f, 0x4c, 0x43, 0x41, 0x50, 0x54, 0x55, 0x52, 0x45, 0x2f, 0x4b, 0x49, 0x43, 0x4b, 180 | 0x54, 0x41, 0x47, 0x50, 0x54, 0x52, 0x20, 0x76, 0x69, 0x72, 0x75, 0x73, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 181 | 0x00, 0x6e, 0x96, 0x2a, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 182 | 0x2d, 0x20, 0x50, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x76, 0x69, 0x72, 0x75, 0x73, 0x20, 0x69, 0x6e, 0x20, 183 | 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x91, 0xb4, 0x23, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x4d, 0x42, 0x20, 0x74, 184 | 0x6f, 0x20, 0x52, 0x45, 0x53, 0x45, 0x54, 0x20, 0x6f, 0x72, 0x20, 0x52, 0x4d, 0x42, 0x20, 0x74, 0x6f, 0x20, 0x49, 0x47, 185 | 0x4e, 0x4f, 0x52, 0x45, 0x00, 0x73, 0x96, 0x29, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x43, 0x68, 0x61, 0x6e, 186 | 0x67, 0x65, 0x64, 0x20, 0x2d, 0x20, 0x60, 0x52, 0x41, 0x44, 0x27, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x6e, 187 | 0x64, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x00, 0x41, 0xa0, 0x33, 0x55, 0x73, 0x65, 0x20, 0x4e, 0x55, 0x4b, 188 | 0x45, 0x21, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 189 | 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x72, 0x65, 0x63, 0x65, 190 | 0x6e, 0x74, 0x6c, 0x79, 0x9b, 0xb4, 0x21, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x4d, 0x42, 0x20, 0x74, 0x6f, 0x20, 191 | 0x4b, 0x49, 0x4c, 0x4c, 0x20, 0x76, 0x69, 0x72, 0x75, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 192 | 0x00, 0xbe, 0x8c, 0x1a, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2d, 0x20, 0x42, 0x47, 0x53, 0x39, 0x20, 0x76, 193 | 0x69, 0x72, 0x75, 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x00, 0xb4, 0x8c, 0x1c, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 194 | 0x67, 0x20, 0x2d, 0x20, 0x53, 0x61, 0x64, 0x64, 0x61, 0x6d, 0x20, 0x76, 0x69, 0x72, 0x75, 0x73, 0x20, 0x66, 0x6f, 0x75, 195 | 0x6e, 0x64 196 | }; 197 | 198 | /* CCS-Boot 3.0, PHS / CCS */ 199 | unsigned char CCSBootV30_bootblock[1021] = { 200 | 0x44, 0x4f, 0x53, 0x00, 0x6d, 0xc2, 0x3b, 0xd2, 0x00, 0x00, 0x03, 0x70, 0x48, 0xe7, 0x3f, 0xfe, 0x33, 0x7c, 0x00, 0x09, 201 | 0x00, 0x1c, 0x42, 0xa9, 0x00, 0x24, 0x4e, 0xae, 0xfe, 0x38, 0x42, 0x07, 0x0c, 0x6e, 0x00, 0x08, 0x00, 0x3e, 0x66, 0x06, 202 | 0x4a, 0xae, 0x00, 0x4e, 0x67, 0x04, 0x1e, 0x3c, 0x00, 0x01, 0x42, 0x80, 0x43, 0xfa, 0x03, 0xba, 0x4e, 0xae, 0xfe, 0x0e, 203 | 0x20, 0x40, 0x41, 0xe8, 0x00, 0x34, 0x4a, 0x98, 0x67, 0x08, 0x4a, 0x98, 0x67, 0x04, 0x4a, 0x98, 0x66, 0x04, 0x00, 0x07, 204 | 0x00, 0x02, 0x3f, 0x07, 0x41, 0xfa, 0x03, 0x13, 0x08, 0x07, 0x00, 0x00, 0x67, 0x04, 0x41, 0xfa, 0x02, 0xff, 0x10, 0xbc, 205 | 0x00, 0xab, 0x41, 0xfa, 0x03, 0x21, 0x08, 0x07, 0x00, 0x01, 0x67, 0x04, 0x41, 0xfa, 0x03, 0x0d, 0x10, 0xbc, 0x00, 0xab, 206 | 0x2c, 0x56, 0x2c, 0x56, 0x43, 0xf9, 0x00, 0x07, 0x00, 0x00, 0x28, 0x49, 0x42, 0x99, 0x30, 0x09, 0x4a, 0x40, 0x6a, 0xf8, 207 | 0x43, 0xfa, 0x02, 0x24, 0x45, 0xec, 0x40, 0x00, 0x4b, 0xf9, 0x00, 0xdf, 0xf0, 0x96, 0x3a, 0xbc, 0x00, 0x20, 0x2f, 0x2e, 208 | 0x00, 0x32, 0x2d, 0x4a, 0x00, 0x32, 0x34, 0xd9, 0x6a, 0xfc, 0x4c, 0x99, 0x00, 0x0f, 0x61, 0x1a, 0x61, 0x16, 0x92, 0x42, 209 | 0x78, 0x04, 0x61, 0x22, 0x51, 0xcc, 0xff, 0xfc, 0x61, 0x0a, 0x61, 0x08, 0x42, 0x41, 0x61, 0x06, 0x64, 0xe4, 0x65, 0x48, 210 | 0x92, 0x42, 0x34, 0xc0, 0x24, 0xfc, 0xff, 0xfe, 0x01, 0x80, 0x34, 0xc1, 0x06, 0x40, 0x01, 0x00, 0x4e, 0x75, 0x61, 0xee, 211 | 0x34, 0xfc, 0x01, 0x82, 0x34, 0xc3, 0x34, 0xfc, 0x01, 0x86, 0x34, 0xc3, 0x04, 0x43, 0x01, 0x11, 0x06, 0x40, 0x02, 0x00, 212 | 0x4e, 0x75, 0x61, 0x06, 0x95, 0xc4, 0x06, 0x42, 0x01, 0x80, 0x22, 0x4b, 0x20, 0x02, 0x22, 0x03, 0x4e, 0xae, 0xff, 0x10, 213 | 0x20, 0x4a, 0x20, 0x04, 0x4e, 0xae, 0xff, 0xc4, 0xd5, 0xc4, 0x4e, 0x75, 0x41, 0xec, 0xfe, 0x00, 0x24, 0x48, 0x70, 0x01, 214 | 0x32, 0x3c, 0x03, 0x00, 0x34, 0x3c, 0x01, 0x00, 0x4e, 0xae, 0xfe, 0x7a, 0x25, 0x4c, 0x00, 0x08, 0x43, 0xec, 0xff, 0x00, 215 | 0x26, 0x49, 0x4e, 0xae, 0xff, 0x3a, 0x27, 0x4a, 0x00, 0x04, 0x70, 0x01, 0x4e, 0xae, 0xfe, 0xaa, 0x3a, 0xbc, 0x83, 0x80, 216 | 0x45, 0xfa, 0x01, 0xc8, 0x42, 0x43, 0x74, 0x34, 0x16, 0x1a, 0x67, 0x16, 0x78, 0x1f, 0x61, 0xa2, 0x60, 0xf4, 0x42, 0xad, 217 | 0x00, 0x72, 0x42, 0xad, 0x00, 0xae, 0x53, 0x47, 0x66, 0x14, 0x10, 0x12, 0x66, 0x04, 0x45, 0xfa, 0x02, 0x27, 0x34, 0x3c, 218 | 0x01, 0x76, 0x76, 0x49, 0x78, 0x01, 0x61, 0x82, 0x7e, 0x03, 0x22, 0x4b, 0x70, 0x03, 0x72, 0x00, 0x74, 0x00, 0x76, 0x42, 219 | 0x38, 0x3c, 0x03, 0x00, 0x7a, 0x4a, 0x4e, 0xae, 0xfe, 0x74, 0x0c, 0x2d, 0x00, 0xff, 0xff, 0x70, 0x66, 0x00, 0xff, 0xf8, 220 | 0x10, 0x39, 0x00, 0xbf, 0xec, 0x01, 0x46, 0x00, 0xe2, 0x48, 0x65, 0xb6, 0x04, 0x00, 0x00, 0x50, 0x65, 0xb0, 0x0c, 0x00, 221 | 0x00, 0x04, 0x64, 0xaa, 0x2d, 0x5f, 0x00, 0x32, 0x3a, 0xbc, 0x80, 0x20, 0x32, 0x1f, 0x4c, 0xdf, 0x7f, 0xfc, 0x4a, 0x00, 222 | 0x66, 0x06, 0x08, 0x01, 0x00, 0x00, 0x67, 0x64, 0x0c, 0x00, 0x00, 0x01, 0x66, 0x06, 0x08, 0x01, 0x00, 0x00, 0x66, 0x2a, 223 | 0x0c, 0x00, 0x00, 0x02, 0x66, 0x06, 0x08, 0x01, 0x00, 0x01, 0x67, 0x6a, 0x0c, 0x00, 0x00, 0x03, 0x66, 0x06, 0x08, 0x01, 224 | 0x00, 0x01, 0x66, 0x46, 0x43, 0xfa, 0x01, 0xfe, 0x4e, 0xae, 0xff, 0xa0, 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 225 | 0x4e, 0x75, 0x20, 0x4e, 0x4b, 0xf9, 0x00, 0xfc, 0x02, 0x80, 0x0c, 0x65, 0x21, 0xfc, 0x66, 0xfa, 0x99, 0xcc, 0x4d, 0xf8, 226 | 0x06, 0x76, 0x47, 0xf9, 0x00, 0x08, 0x00, 0x00, 0x43, 0xf9, 0x00, 0xdf, 0xf0, 0x96, 0x20, 0x3c, 0x7f, 0xff, 0x7f, 0xff, 227 | 0x22, 0xc0, 0x22, 0xc0, 0x4e, 0xe8, 0xff, 0xe2, 0x42, 0xb8, 0x00, 0x04, 0x60, 0x18, 0x43, 0xf9, 0x00, 0x07, 0xf0, 0x00, 228 | 0x41, 0xfa, 0x00, 0x1a, 0x2d, 0x49, 0x00, 0x2e, 0x70, 0x1f, 0x22, 0xd8, 0x51, 0xc8, 0xff, 0xfc, 0x61, 0x1c, 0x4b, 0xf9, 229 | 0x00, 0xfc, 0x00, 0xd0, 0x4e, 0xee, 0xff, 0xe2, 0x42, 0xae, 0x00, 0x2e, 0x41, 0xfa, 0x00, 0x20, 0x21, 0x6e, 0xff, 0x9c, 230 | 0x00, 0x40, 0x2d, 0x48, 0xff, 0x9c, 0x41, 0xee, 0x00, 0x22, 0x42, 0x40, 0x72, 0x17, 0xd0, 0x58, 0x51, 0xc9, 0xff, 0xfc, 231 | 0x46, 0x40, 0x30, 0x80, 0x4e, 0x75, 0x0c, 0x69, 0x64, 0x69, 0x00, 0x1a, 0x66, 0x36, 0x48, 0xe7, 0xff, 0xbc, 0x41, 0xfa, 232 | 0x00, 0x3a, 0x20, 0x08, 0x34, 0x3c, 0x00, 0xff, 0x32, 0x19, 0x0c, 0x41, 0x00, 0x05, 0x66, 0x02, 0x52, 0x41, 0x30, 0xc1, 233 | 0x51, 0xca, 0xff, 0xf2, 0x24, 0x69, 0xfe, 0x16, 0x95, 0xc9, 0xd5, 0xc8, 0x21, 0x4a, 0xfe, 0x16, 0x22, 0x40, 0x4c, 0xdf, 234 | 0x3d, 0xff, 0x2d, 0x7a, 0x00, 0x06, 0xff, 0x9c, 0x4e, 0xf9, 0x01, 0x00, 0x22, 0x00, 0x01, 0x02, 0x00, 0x10, 0x00, 0x92, 235 | 0x00, 0x20, 0x00, 0x94, 0x00, 0xd8, 0x00, 0x8e, 0x2c, 0x01, 0x00, 0x90, 0x00, 0xff, 0x00, 0xe0, 0x00, 0x07, 0x00, 0xe2, 236 | 0x06, 0x00, 0x00, 0xe4, 0x00, 0x07, 0x00, 0xe6, 0x05, 0xd0, 0x01, 0x80, 0x00, 0x00, 0x01, 0x84, 0x80, 0x00, 0x34, 0x01, 237 | 0x0a, 0x28, 0x02, 0x02, 0x0c, 0xa8, 0x50, 0x01, 0x0a, 0x28, 0x02, 0x02, 0x0b, 0x97, 0x90, 0x01, 0x02, 0x8a, 0x00, 0x22, 238 | 0x0a, 0x86, 0xd0, 0x01, 0x08, 0xa2, 0x02, 0x20, 0x0b, 0x97, 0xec, 0x01, 0x08, 0xa2, 0x02, 0x20, 0x0c, 0xa8, 0x1b, 0x43, 239 | 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x69, 240 | 0x6e, 0x67, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x29, 0x41, 0x32, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20, 241 | 0x20, 0x43, 0x43, 0x53, 0x2d, 0x42, 0x4f, 0x4f, 0x54, 0x20, 0x33, 0x2e, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x35, 242 | 0x30, 0x30, 0x69, 0x45, 0x78, 0x74, 0x72, 0x61, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x20, 0x5b, 0x46, 0x31, 0x5d, 243 | 0x20, 0x4f, 0x4e, 0x20, 0x20, 0x5b, 0x46, 0x32, 0x5d, 0x20, 0x4f, 0x46, 0x46, 0x20, 0x77, 0x45, 0x78, 0x74, 0x72, 0x61, 244 | 0x20, 0x44, 0x72, 0x69, 0x76, 0x65, 0x73, 0x20, 0x5b, 0x46, 0x33, 0x5d, 0x20, 0x4f, 0x4e, 0x20, 0x20, 0x5b, 0x46, 0x34, 245 | 0x5d, 0x20, 0x4f, 0x46, 0x46, 0x20, 0x00, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x75, 0x70, 0x65, 0x72, 0x20, 0x75, 0x74, 246 | 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x62, 247 | 0x79, 0x20, 0x50, 0x48, 0x53, 0x20, 0x6f, 0x66, 0x20, 0x43, 0x43, 0x53, 0x2e, 0x20, 0x59, 0x6f, 0x75, 0x20, 0x6d, 0x61, 248 | 0x79, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x69, 0x66, 249 | 0x20, 0x79, 0x6f, 0x75, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x21, 0x20, 0x20, 0x00, 0x64, 0x6f, 0x73, 0x2e, 250 | 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x64, 0x69, 0x73, 0x6b, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 251 | 0x65 252 | }; 253 | 254 | /* TiP Memory Controller V1.2 */ 255 | unsigned char Memory_Controller_V12_bootblock[1022] = { 256 | 0x44, 0x4f, 0x53, 0x00, 0x86, 0xb7, 0xe4, 0x80, 0x47, 0xf9, 0x00, 0xdf, 0x48, 0xf9, 0xff, 0xff, 0x00, 0x07, 0xe0, 0x00, 257 | 0x47, 0xf9, 0x00, 0xdf, 0xf0, 0x00, 0x28, 0x7c, 0x00, 0x07, 0xf0, 0x00, 0x42, 0x87, 0x41, 0xfa, 0xff, 0xe8, 0xb1, 0xfc, 258 | 0x00, 0xc7, 0xf0, 0x00, 0x66, 0x16, 0x7e, 0xff, 0x08, 0xeb, 0x00, 0x0b, 0x00, 0x34, 0x08, 0x2b, 0x00, 0x0a, 0x00, 0x16, 259 | 0x67, 0xf8, 0x61, 0x00, 0x01, 0x1e, 0x60, 0x2c, 0x4a, 0xae, 0x00, 0x4e, 0x66, 0x1c, 0x0c, 0xb9, 0x42, 0x4f, 0x4f, 0x54, 260 | 0x00, 0xc7, 0xff, 0x00, 0x66, 0x00, 0x00, 0xee, 0x42, 0xb9, 0x00, 0xc7, 0xff, 0x00, 0x61, 0x00, 0x00, 0xfe, 0x60, 0x00, 261 | 0x00, 0xe0, 0x43, 0xfa, 0x01, 0x22, 0x4e, 0xae, 0xfe, 0x68, 0x2a, 0x40, 0x41, 0xfa, 0x01, 0x2a, 0x43, 0xfa, 0x02, 0xce, 262 | 0x24, 0x4c, 0x14, 0xd8, 0xb3, 0xc8, 0x66, 0xfa, 0x27, 0x4c, 0x00, 0x80, 0x37, 0x7c, 0x83, 0x80, 0x00, 0x96, 0x08, 0x39, 263 | 0x00, 0x06, 0x00, 0xbf, 0xe0, 0x01, 0x66, 0x00, 0x00, 0x90, 0x4a, 0x07, 0x67, 0x0a, 0x4c, 0xf9, 0xff, 0xff, 0x00, 0x07, 264 | 0xe0, 0x00, 0x4e, 0xd5, 0x41, 0xfa, 0xff, 0x66, 0x43, 0xfa, 0x02, 0x9a, 0x45, 0xf9, 0x00, 0xc7, 0xf0, 0x00, 0x14, 0xd8, 265 | 0xb3, 0xc8, 0x66, 0xfa, 0x23, 0xfc, 0x42, 0x4f, 0x4f, 0x54, 0x00, 0xc7, 0xff, 0x00, 0x13, 0xfc, 0x00, 0x03, 0x00, 0xbf, 266 | 0xe2, 0x01, 0x13, 0xfc, 0x00, 0x02, 0x00, 0xbf, 0xe0, 0x01, 0x30, 0x3c, 0x7f, 0xff, 0x37, 0x40, 0x00, 0x9a, 0x37, 0x40, 267 | 0x00, 0x9c, 0x37, 0x40, 0x00, 0x96, 0x37, 0x7c, 0x02, 0x00, 0x01, 0x00, 0x37, 0x7c, 0x00, 0x00, 0x01, 0x10, 0x37, 0x7c, 268 | 0x04, 0x44, 0x01, 0x80, 0x4d, 0xf9, 0x00, 0x00, 0x04, 0x00, 0x9c, 0xfc, 0xfd, 0x8a, 0x41, 0xf9, 0x00, 0xc0, 0x00, 0x00, 269 | 0x43, 0xf9, 0x00, 0xdc, 0x00, 0x00, 0x28, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0c, 0x2e, 0x7c, 0x00, 0x04, 0x00, 0x00, 270 | 0x2c, 0x3c, 0xff, 0xff, 0xff, 0xff, 0x4e, 0xf9, 0x00, 0xfc, 0x02, 0x08, 0x08, 0x2b, 0x00, 0x0a, 0x00, 0x16, 0x66, 0x00, 271 | 0xff, 0x5e, 0x4a, 0x07, 0x67, 0x06, 0x4e, 0xf9, 0x00, 0xfc, 0x01, 0xce, 0x27, 0x6d, 0x00, 0x26, 0x00, 0x80, 0x22, 0x4d, 272 | 0x4e, 0xae, 0xfe, 0x62, 0x4c, 0xf9, 0xff, 0xff, 0x00, 0x07, 0xe0, 0x00, 0x43, 0xfa, 0x00, 0x30, 0x4e, 0xae, 0xff, 0xa0, 273 | 0x20, 0x40, 0x20, 0x68, 0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 0x2d, 0x7c, 0x00, 0xc7, 0xf0, 0x00, 0x00, 0x2a, 0x42, 0x81, 274 | 0x41, 0xee, 0x00, 0x22, 0x30, 0x3c, 0x00, 0x16, 0xd2, 0x58, 0x51, 0xc8, 0xff, 0xfc, 0x46, 0x41, 0x3d, 0x41, 0x00, 0x52, 275 | 0x4e, 0x75, 0x64, 0x6f, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 276 | 0x63, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 277 | 0x00, 0x92, 0x00, 0x68, 0x00, 0x94, 0x00, 0xa0, 0x01, 0x82, 0x00, 0xff, 0x87, 0x07, 0xff, 0xfe, 0x01, 0x00, 0x10, 0x00, 278 | 0x00, 0xe0, 0x00, 0x07, 0x00, 0xe2, 0xf0, 0x78, 0x89, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x00, 0xdf, 0x8b, 0x07, 0xff, 0xfe, 279 | 0x01, 0x82, 0x00, 0xbf, 0x8d, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x0f, 0x0f, 0x8f, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x00, 0x7f, 280 | 0x91, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x00, 0x5f, 0x93, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x00, 0x3f, 0x95, 0x07, 0xff, 0xfe, 281 | 0x01, 0x82, 0x00, 0x1f, 0x97, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x00, 0x0e, 0x99, 0x07, 0xff, 0xfe, 0x01, 0x82, 0x00, 0x0c, 282 | 0x9a, 0x07, 0xff, 0xfe, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x12, 0xf4, 0xbd, 0xc9, 0x1e, 0xf7, 0x3e, 0xe7, 283 | 0xa1, 0x0f, 0x70, 0x92, 0x3c, 0x28, 0x0f, 0xd0, 0x1e, 0x87, 0xa5, 0x29, 0x10, 0x94, 0x88, 0x94, 0xa1, 0x08, 0x48, 0x96, 284 | 0x04, 0x48, 0x02, 0x48, 0x12, 0xe4, 0xa5, 0xc6, 0x10, 0x94, 0x88, 0xe4, 0xa1, 0x0e, 0x70, 0xf2, 0x3c, 0x4e, 0xa3, 0xc8, 285 | 0x12, 0x84, 0xa5, 0x22, 0x10, 0x94, 0x88, 0x94, 0xa1, 0x08, 0x48, 0x62, 0x20, 0x4a, 0x42, 0x08, 0x12, 0xf4, 0xbd, 0x2c, 286 | 0x1e, 0xf4, 0x88, 0x97, 0xbd, 0xef, 0x48, 0x62, 0xbc, 0x2e, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 287 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 288 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 289 | 0x01, 0x0f, 0x7b, 0xe3, 0x92, 0xfb, 0xef, 0x70, 0x3d, 0xc8, 0x48, 0xf4, 0xaf, 0x12, 0xf4, 0x80, 0x01, 0x08, 0x40, 0x82, 290 | 0x52, 0x20, 0x89, 0x49, 0x25, 0x28, 0x48, 0x84, 0xa9, 0x1e, 0x87, 0x80, 0x01, 0x0e, 0x70, 0x83, 0x92, 0x20, 0x89, 0x48, 291 | 0x25, 0x28, 0x30, 0x87, 0xaf, 0x12, 0xe4, 0x80, 0x01, 0x08, 0x40, 0x82, 0x52, 0x20, 0x89, 0x49, 0x25, 0x28, 0x10, 0x84, 292 | 0xa8, 0x12, 0x84, 0x80, 0x01, 0xef, 0x40, 0x83, 0x9e, 0x20, 0x8f, 0x48, 0x3d, 0x2f, 0x60, 0xf4, 0xa8, 0x12, 0xf4, 0x80, 293 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0xe9, 294 | 0x7c, 0x72, 0x5f, 0x7d, 0xee, 0x07, 0xa5, 0x08, 0x12, 0xf4, 0x80, 0x00, 0x00, 0x00, 0x95, 0x09, 0x10, 0x4a, 0x44, 0x11, 295 | 0x29, 0x24, 0x25, 0x08, 0x1e, 0x87, 0x80, 0x00, 0x00, 0x00, 0xe5, 0x6f, 0x10, 0x72, 0x44, 0x11, 0x29, 0x07, 0x25, 0x08, 296 | 0x12, 0xe4, 0x80, 0x00, 0x00, 0x00, 0x95, 0x29, 0x10, 0x4a, 0x44, 0x11, 0x29, 0x24, 0x25, 0x08, 0x12, 0x84, 0x80, 0x00, 297 | 0x00, 0x00, 0x95, 0xe9, 0x10, 0x73, 0xc4, 0x11, 0xe9, 0x04, 0x3d, 0xef, 0x12, 0xf4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 298 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 299 | 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7c, 0x18, 0x18, 0x18, 0x78, 0xfe, 0x00, 0x7c, 0x3c, 0x00, 0x18, 0x18, 0x7c, 0x00, 0x78, 300 | 0x7c, 0xc6, 0xee, 0x00, 0x18, 0xc0, 0xce, 0x05, 0x77, 0x70, 0x77, 0x65, 0x76, 0x50, 0x00, 0x00, 0xee, 0x78, 0x18, 0x18, 301 | 0x18, 0x60, 0xde, 0x00, 0x66, 0x18, 0x00, 0x18, 0x18, 0x60, 0x00, 0x60, 0x78, 0xc6, 0xfe, 0x00, 0x18, 0xc0, 0xc6, 0x05, 302 | 0x44, 0x20, 0x44, 0x57, 0x55, 0x50, 0x00, 0x00, 0xee, 0x6c, 0x18, 0x18, 0x18, 0x60, 0xce, 0x00, 0x66, 0x18, 0x00, 0x18, 303 | 0x18, 0x60, 0x00, 0x60, 0x6c, 0xc6, 0xd6, 0x00, 0x18, 0xc0, 0xc6, 0x05, 0x67, 0x26, 0x56, 0x65, 0x75, 0x20, 0x00, 0x00, 304 | 0xc6, 0x66, 0x18, 0x18, 0x18, 0x66, 0xc6, 0x00, 0x66, 0x18, 0x00, 0x18, 0x18, 0x60, 0x00, 0x60, 0x66, 0x6c, 0xd6, 0x00, 305 | 0x18, 0x66, 0x66, 0x07, 0x41, 0x20, 0x54, 0x55, 0x55, 0x40, 0x00, 0x00, 0xc6, 0xe3, 0x7e, 0x3c, 0x3c, 0xfe, 0xc2, 0x00, 306 | 0xfc, 0x3c, 0x00, 0x3c, 0x7e, 0xf0, 0x00, 0xf0, 0xe3, 0x38, 0xc6, 0x00, 0x3c, 0x3c, 0x3e, 0x05, 0x77, 0x20, 0x77, 0x55, 307 | 0x55, 0x40 308 | }; 309 | -------------------------------------------------------------------------------- /bootblocks.h: -------------------------------------------------------------------------------- 1 | unsigned char OS13_bootblock[49]; 2 | unsigned char OS20_bootblock[93]; 3 | unsigned char ScoopexUtilityBootV10_bootblock[1023]; 4 | unsigned char ScoopexUtilityBootV13_bootblock[1023]; 5 | unsigned char MiniNukeV10_bootblock[1022]; 6 | unsigned char CCSBootV30_bootblock[1021]; 7 | -------------------------------------------------------------------------------- /error.c: -------------------------------------------------------------------------------- 1 | /* error.c - error and debug-routines 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | #include "misc.h" 13 | 14 | /* set by all programs in the adftools-package */ 15 | extern char *program_name; 16 | 17 | /* notify the user something harmless (to stderr) */ 18 | void 19 | notify (char *fmt, ...) 20 | { 21 | char buf[BUFSIZE]; 22 | char *logbuffer; 23 | va_list ap; 24 | 25 | memset (&buf, 0, BUFSIZE); 26 | va_start (ap, fmt); 27 | vsnprintf (buf, BUFSIZE, fmt, ap); 28 | 29 | logbuffer = (char *) malloc (sizeof (buf)); 30 | strcpy (logbuffer, buf); 31 | 32 | fprintf (stderr, "%s", logbuffer); 33 | 34 | free (logbuffer); 35 | } 36 | 37 | /* something happened */ 38 | void 39 | error (int action, char *fmt, ...) 40 | { 41 | char buf[BUFSIZE]; 42 | char *logbuffer; 43 | va_list ap; 44 | 45 | memset (&buf, 0, BUFSIZE); 46 | va_start (ap, fmt); 47 | vsnprintf (buf, BUFSIZE, fmt, ap); 48 | 49 | logbuffer = (char *) malloc (sizeof (buf)); 50 | strcpy (logbuffer, buf); 51 | 52 | fprintf (stderr, "%s: %s.\n", program_name, logbuffer); 53 | 54 | free (logbuffer); 55 | 56 | /* something *real* bad happened! */ 57 | if (action) 58 | exit (42); 59 | } 60 | -------------------------------------------------------------------------------- /error.h: -------------------------------------------------------------------------------- 1 | void notify (char *fmt, ...); 2 | void error (int action, char *fmt, ...); 3 | -------------------------------------------------------------------------------- /misc.c: -------------------------------------------------------------------------------- 1 | /* misc.c - common routines 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "error.h" 16 | #include "misc.h" 17 | #include "zfile.h" 18 | 19 | /* "12345678" -> 1, "12354foo1234" -> 0 */ 20 | int 21 | isdigits (char *str) 22 | { 23 | register int i; 24 | 25 | for (i = 0; i < strlen (str); i++) 26 | if (!isdigit (str[i])) 27 | return 0; 28 | 29 | return 1; 30 | } 31 | 32 | /* checks if the buffer (the bootblock) is an adf-file */ 33 | int 34 | is_adf_file (unsigned char *buf) 35 | { 36 | if ((buf[0] != 'D') && 37 | (buf[1] != 'O') && 38 | (buf[2] != 'S')) 39 | return 0; 40 | 41 | return 1; 42 | } 43 | 44 | /* "apan.apan.ap.jpg.gurka.iff" -> "apan.apan.ap.jpg.gurka" */ 45 | char * 46 | strip_extension (char *str) 47 | { 48 | char *p, *s; 49 | 50 | s = strdup (str); 51 | p = rindex (s, '.'); 52 | if (p != NULL) 53 | /* found extension */ 54 | *p = 0; 55 | 56 | return s; 57 | } 58 | 59 | char * 60 | strip_trailing_slashes (char *path) 61 | { 62 | char *p = path; 63 | 64 | while (p[strlen (p)-1] == '/') 65 | p[strlen (p)-1] = '\0'; 66 | 67 | return p; 68 | } 69 | 70 | /* "/foo/bar/gazonk.jpg" -> "gazonk.jpg" */ 71 | char * 72 | basename (char *filename) 73 | { 74 | char *p; 75 | 76 | for (p = filename; *p == '/'; ++p) 77 | /* do nothing if "/", "//" etc */ 78 | ; 79 | 80 | if (*p == '\0') 81 | return (p - 1); 82 | 83 | p = strrchr (filename, '/'); 84 | if (p == NULL) 85 | return (filename); 86 | else 87 | return (p + 1); 88 | } 89 | 90 | /* old code */ 91 | /* char * */ 92 | /* basename (char *filename) */ 93 | /* { */ 94 | /* char *p, *s; */ 95 | /* s = strdup (filename); */ 96 | /* p = rindex (s, '/'); */ 97 | /* if (p != NULL) */ 98 | /* s = (p + 1); */ 99 | /* return s; */ 100 | /* } */ 101 | 102 | /* "/foo/bar/gazonk.jpg" -> "/foo/bar" */ 103 | /* char * */ 104 | /* dirname (char *filename) */ 105 | /* { */ 106 | /* char *p, *s; */ 107 | /* s = strdup (filename); */ 108 | /* p = rindex (s, '/'); */ 109 | /* if (p != NULL) */ 110 | /* *p = 0; */ 111 | /* return s; */ 112 | /* } */ 113 | 114 | /* string representation of dosType */ 115 | char * 116 | get_adf_dostype (char dostype) 117 | { 118 | switch (dostype) { 119 | case 0: 120 | return "DOS0 (OFS)"; 121 | case 1: 122 | return "DOS1 (FFS)"; 123 | case 2: 124 | return "DOS2 (I-OFS))"; 125 | case 3: 126 | return "DOS3 (I-FFS)"; 127 | case 4: 128 | return "DOS4 (DC-OFS)"; 129 | case 5: 130 | return "DOS5 (DC-FFS)"; 131 | default: 132 | return "Unknown-FS"; 133 | } 134 | 135 | return "ApanAP-FS"; 136 | } 137 | 138 | /* mounts an adf-image */ 139 | int 140 | mount_adf (char *filename, struct Device **dev, struct Volume **vol, int rw) 141 | { 142 | char *errmsg = "Can't mount the device '%s' (perhaps not a DOS-disk or adf-file)"; 143 | 144 | /* check existence and readability of the file */ 145 | if (access (filename, F_OK | R_OK) == -1) { 146 | notify ("Can't access '%s': %s.\n", filename, strerror (errno)); 147 | return 0; 148 | } 149 | 150 | if (rw == READ_WRITE) 151 | *dev = adfMountDev (n_zfile_open(filename, "rw", 1), rw); 152 | else 153 | *dev = adfMountDev (n_zfile_open(filename, "r", 0), rw); 154 | 155 | if (!*dev) { 156 | error (0, errmsg, filename); 157 | return 0; 158 | } 159 | 160 | *vol = adfMount (*dev, 0, rw); 161 | if (!*vol) { 162 | error (0, errmsg, filename); 163 | adfUnMountDev (*dev); 164 | return 0; 165 | } 166 | 167 | return 1; 168 | } 169 | 170 | /* prints a nice header for the adf-image. it *must* be mounted */ 171 | void 172 | print_volume_header (char *filename, struct Volume *volume) 173 | { 174 | register int i; 175 | 176 | if (!volume) 177 | return; 178 | 179 | /* print header, consisting of filename and the (mounted) volume name */ 180 | /* volName can be NULL for some hardfiles, no idea why. */ 181 | if (volume->volName) { 182 | printf ("%s (%s)\n", filename, volume->volName); 183 | for (i = 0; i < (strlen (filename) + 3 + strlen (volume->volName)); i++) 184 | putchar ('='); 185 | putchar ('\n'); 186 | } else { 187 | printf ("%s\n", filename); 188 | for (i = 0; i < strlen (filename); i++) 189 | putchar ('='); 190 | putchar ('\n'); 191 | } 192 | } 193 | 194 | /* a null-function callback for adf-lib */ 195 | static void 196 | null_function (void) 197 | { 198 | }; 199 | 200 | /* initialize the adf-lib */ 201 | /* TODO: add an atexit() */ 202 | void 203 | init_adflib (void) 204 | { 205 | int true = 1; 206 | 207 | adfEnvInitDefault(); 208 | /* redirect errors and warnings to the big black void */ 209 | adfChgEnvProp (PR_EFCT, null_function); 210 | adfChgEnvProp (PR_WFCT, null_function); 211 | 212 | /* yes, we want to use directory caching */ 213 | adfChgEnvProp (PR_USEDIRC, (void *)&true); 214 | } 215 | 216 | /* shut down the adflib */ 217 | void 218 | cleanup_adflib (void) 219 | { 220 | adfEnvCleanUp(); 221 | zfile_exit(); 222 | } 223 | 224 | /* puts access bits in a readable string */ 225 | char * 226 | access2str (long access) 227 | { 228 | static char str[8+1]; 229 | 230 | strcpy (str, "----RWED"); 231 | if (hasD (access)) str[7] = '-'; 232 | if (hasE (access)) str[6] = '-'; 233 | if (hasW (access)) str[5] = '-'; 234 | if (hasR (access)) str[4] = '-'; 235 | if (hasA (access)) str[3] = 'A'; 236 | if (hasP (access)) str[2] = 'P'; 237 | if (hasS (access)) str[1] = 'S'; 238 | if (hasH (access)) str[0] = 'H'; 239 | 240 | return (str); 241 | } 242 | 243 | /* a temporary function until it's implemeted in adflib */ 244 | void 245 | change_to_root_dir (struct Volume *volume) 246 | { 247 | register int i; 248 | 249 | for (i = 0; i < 42; i++) 250 | adfParentDir (volume); 251 | } 252 | 253 | /* split first word off of rest and put it in first */ 254 | char * 255 | splitc (char *first, char *rest) 256 | { 257 | char *p; 258 | p = strchr (rest, '/'); 259 | if (p == NULL) { 260 | if ((first != rest) && (first != NULL)) 261 | first[0] = 0; 262 | return NULL; 263 | } 264 | 265 | *p = 0; 266 | if (first != NULL) strcpy (first, rest); 267 | if (first != rest) strcpy (rest, p + 1); 268 | 269 | return rest; 270 | } 271 | 272 | /* allocate a buffer big enough for a bootblock */ 273 | unsigned char * 274 | allocate_bootblock_buf (void) 275 | { 276 | unsigned char *bootblock; 277 | 278 | bootblock = malloc (BOOTBLOCK_SIZE); 279 | if (!bootblock) 280 | return NULL; 281 | 282 | memset (bootblock, 0, BOOTBLOCK_SIZE); 283 | return bootblock; 284 | } 285 | 286 | /* read bootblock bytes into a buffer */ 287 | unsigned char * 288 | read_bootblock (char *filename) 289 | { 290 | unsigned char *bootblock; 291 | FILE *file; 292 | 293 | bootblock = allocate_bootblock_buf(); 294 | if (!bootblock) 295 | return NULL; 296 | 297 | memset (bootblock, 0, BOOTBLOCK_SIZE); 298 | file = f_zfile_open (filename, "r", 0); 299 | if (!file) { 300 | free (bootblock); 301 | return NULL; 302 | } 303 | 304 | if (fread (bootblock, BOOTBLOCK_SIZE, 1, file) != 1) { 305 | /* error? */ 306 | if (ferror (file)) { 307 | /* yes */ 308 | free (bootblock); 309 | fclose (file); 310 | return NULL; 311 | } else if (!feof (file)) 312 | /* no error, but not end of file either. bloody hell! */ 313 | return NULL; 314 | } 315 | 316 | /* all went fine */ 317 | fclose (file); 318 | return bootblock; 319 | } 320 | -------------------------------------------------------------------------------- /misc.h: -------------------------------------------------------------------------------- 1 | #ifndef ADFTOOLS_MISC_H 2 | #define ADFTOOLS_MISC_H 1 3 | 4 | #include 5 | 6 | #define BUFSIZE 1024 7 | 8 | #define BOOTBLOCK_SIZE LOGICAL_BLOCK_SIZE*2 9 | #define TRACKS 80 10 | #define SECTORS 11 11 | #define HEADS 2 12 | 13 | #ifdef WIN32 14 | #define DIRSEP '\\' 15 | #define MKDIR "md" 16 | #else 17 | #define DIRSEP '/' 18 | #define MKDIR "mkdir" 19 | #endif 20 | 21 | #define ADF_FTW_F 1 /* anything but a directory */ 22 | #define ADF_FTW_D 2 /* directory */ 23 | #define ADF_FTW_DNR 3 /* unreadable directory */ 24 | #define ADF_FTW_NS 4 /* file that we can't stat */ 25 | 26 | #define READ_ONLY 1 27 | #define READ_WRITE 0 28 | 29 | /* if PATH_MAX is indeterminatable, take a guess */ 30 | #define PATH_MAX_GUESS 1024 31 | 32 | /* needed for the callback-handler by libadf */ 33 | ENV_DECLARATION; 34 | 35 | int isdigits (char *str); 36 | char *strip_extension (char *str); 37 | char *basename (char *filename); 38 | char *dirname (char *filename); 39 | char *strip_trailing_slashes (char *path); 40 | int is_adf_file (unsigned char *buf); 41 | char *get_adf_dostype (char dostype); 42 | int mount_adf (char *filename, struct Device **dev, struct Volume **vol, int rw); 43 | void print_volume_header (char *filename, struct Volume *volume); 44 | void init_adflib (void); 45 | void cleanup_adflib (void); 46 | char *access2str (long access); 47 | void change_to_root_dir (struct Volume *volume); 48 | char *splitc (char *first, char *rest); 49 | unsigned char *allocate_bootblock_buf (void); 50 | unsigned char *read_bootblock (char *filename); 51 | 52 | #endif /* ADFTOOLS_MISC_H */ 53 | -------------------------------------------------------------------------------- /version.c: -------------------------------------------------------------------------------- 1 | /* version.c - common version printing routines 2 | * 3 | * adftools - A complete package for maintaining image-files for the best 4 | * Amiga-emulator out there: UAE - http://www.freiburg.linux.de/~uae/ 5 | * 6 | * Copyright (C)2002-2015 Rikard Bosnjakovic 7 | */ 8 | #include 9 | 10 | #include "version.h" 11 | 12 | /* set by all programs in the adftools-package */ 13 | extern char *program_name; 14 | 15 | void 16 | print_header () 17 | { 18 | printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); 19 | printf ("Copyright (C) %s Rikard Bosnjakovic.\n\n", PACKAGE_DATE); 20 | 21 | printf ("This is free software; see the source for copying conditions. There is no\n"); 22 | printf ("warranty; not even for merchantability or fitness for a particular purpose.\n\n"); 23 | } 24 | 25 | void 26 | print_footer () 27 | { 28 | printf ("Report bugs to .\n"); 29 | } 30 | 31 | void 32 | print_version () 33 | { 34 | print_header (); 35 | print_footer (); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | #define PACKAGE_NAME "adftools" 2 | #define PACKAGE_VERSION "0.3a" 3 | #define PACKAGE_DATE "2013" 4 | #define ADFCOPY "adfcopy" 5 | #define ADFCREATE "adfcreate" 6 | #define ADFDELETE "adfdelete" 7 | #define ADFDUMP "adfdump" 8 | #define ADFFORMAT "adfformat" 9 | #define ADFEXTRACT "adfextract" 10 | #define ADFINFO "adfinfo" 11 | #define ADFINSTALL "adfinstall" 12 | #define ADFLIST "adflist" 13 | #define ADFMAKEDIR "adfmakedir" 14 | #define ADFRELABEL "adfrelabel" 15 | #define ADFRENAME "adfrename" 16 | 17 | void print_header (void); 18 | void print_footer (void); 19 | void print_version (void); 20 | -------------------------------------------------------------------------------- /zfile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * UAE - The Un*x Amiga Emulator 3 | * 4 | * routines to handle compressed file automatically 5 | * 6 | * (c) 1996 Samuel Devulder, Tim Gunn 7 | * 8 | * Modified 2013-11-22 by Rikard Bosnjakovic for 9 | * use in the adftools package. 10 | */ 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "zfile.h" 20 | 21 | static struct zfile 22 | { 23 | struct zfile *next; 24 | FILE *f; 25 | unsigned short compressed; 26 | unsigned short re_compress; 27 | char orgname[256]; 28 | char name[256]; 29 | } *zlist; 30 | 31 | /* 32 | * gzip decompression 33 | */ 34 | static int 35 | gunzip (const char *decompress, const char *src, const char *dst) 36 | { 37 | char cmd[1024]; 38 | if (!dst) 39 | return 1; 40 | sprintf (cmd, "%s -c -d \"%s\" > \"%s\"", decompress, src, dst); 41 | 42 | return !system (cmd); 43 | } 44 | 45 | /* 46 | * decompresses the file (or check if dest is null) 47 | */ 48 | static int 49 | uncompress (const char *name, char *dest) 50 | { 51 | char *ext = strrchr (name, '.'); 52 | char nam[1024]; 53 | 54 | if (ext != NULL && access (name, 0) >= 0) { 55 | ext++; 56 | if (strcasecmp (ext, "z") == 0 57 | || strcasecmp (ext, "gz") == 0 58 | || strcasecmp (ext, "adz") == 0 59 | || strcasecmp (ext, "roz") == 0) 60 | return gunzip ("gzip", name, dest); 61 | if (strcasecmp (ext, "bz") == 0) 62 | return gunzip ("bzip", name, dest); 63 | if (strcasecmp (ext, "bz2") == 0) 64 | return gunzip ("bzip2", name, dest); 65 | } 66 | 67 | if (access (strcat (strcpy (nam, name), ".z"), 0) >= 0 68 | || access (strcat (strcpy (nam, name), ".Z"), 0) >= 0 69 | || access (strcat (strcpy (nam, name), ".gz"), 0) >= 0 70 | || access (strcat (strcpy (nam, name), ".GZ"), 0) >= 0 71 | || access (strcat (strcpy (nam, name), ".adz"), 0) >= 0 72 | || access (strcat (strcpy (nam, name), ".roz"), 0) >= 0) 73 | return gunzip ("gzip", nam, dest); 74 | 75 | if (access (strcat (strcpy (nam, name), ".bz"), 0) >= 0 76 | || access (strcat (strcpy (nam, name), ".BZ"), 0) >= 0) 77 | return gunzip ("bzip", nam, dest); 78 | 79 | if (access (strcat (strcpy (nam, name), ".bz2"), 0) >= 0 80 | || access (strcat (strcpy (nam, name), ".BZ2"), 0) >= 0) 81 | return gunzip ("bzip2", nam, dest); 82 | 83 | return 0; 84 | } 85 | 86 | static int 87 | compress (const char *src, const char *dst) 88 | { 89 | char cmd[1024]; 90 | if (!dst) 91 | return 1; 92 | 93 | if (access (dst, W_OK) == 0) { 94 | sprintf (cmd, "gzip -9nc \"%s\" > \"%s\"", src, dst); 95 | return !system (cmd); 96 | } 97 | 98 | return 0; 99 | } 100 | 101 | /* 102 | * fopen() for a compressed file 103 | */ 104 | struct zfile * 105 | zfile_open (const char *name, const char *mode, unsigned short re_compress) 106 | { 107 | struct zfile *l; 108 | int fd = 0; 109 | 110 | l = malloc (sizeof *l); 111 | if (!l) 112 | return NULL; 113 | 114 | strcpy (l->orgname, name); 115 | if (!uncompress (name, NULL)) { 116 | strcpy (l->name, name); 117 | l->f = fopen (l->name, mode); 118 | l->compressed = 0; 119 | 120 | return l; 121 | } 122 | 123 | tmpnam (l->name); 124 | 125 | /* On the amiga this would make ixemul loose the break handler */ 126 | /* ==> fixed in exmul v4.6 */ 127 | fd = creat (l->name, 0666); 128 | if (fd < 0) 129 | return NULL; 130 | 131 | if (!uncompress (name, l->name)) { 132 | free (l); 133 | close (fd); 134 | unlink (l->name); 135 | return NULL; 136 | } else { 137 | l->compressed = 1; 138 | l->re_compress = re_compress; 139 | } 140 | 141 | l->f = fopen (l->name, mode); 142 | 143 | if (l->f == NULL) { 144 | free (l); 145 | return NULL; 146 | } 147 | 148 | l->next = zlist; 149 | zlist = l; 150 | 151 | return l; 152 | } 153 | 154 | FILE * 155 | f_zfile_open (const char *name, const char *mode, unsigned short re_compress) 156 | { 157 | return zfile_open (name, mode, re_compress)->f; 158 | } 159 | 160 | char * 161 | n_zfile_open (const char *name, const char *mode, unsigned short re_compress) 162 | { 163 | return zfile_open (name, mode, re_compress)->name; 164 | } 165 | 166 | /* 167 | * called on exit() 168 | */ 169 | void 170 | zfile_exit (void) 171 | { 172 | struct zfile *l; 173 | 174 | while ((l = zlist)) { 175 | zlist = l->next; 176 | 177 | /* try to compress uncompressed files before cleaning up */ 178 | if (l->compressed && l->re_compress) 179 | compress(l->name, l->orgname); 180 | 181 | fclose(l->f); 182 | unlink(l->name); /* sam: in case unlink() after fopen() fails */ 183 | free(l); 184 | } 185 | } 186 | 187 | /* 188 | * fclose() but for a compressed file 189 | */ 190 | int 191 | zfile_close (FILE *f) 192 | { 193 | struct zfile *pl = NULL; 194 | struct zfile *l = zlist; 195 | int ret; 196 | 197 | while(l && l->f!=f) { 198 | pl = l; 199 | l = l->next; 200 | } 201 | if (!l) 202 | return fclose(f); 203 | ret = fclose(l->f); 204 | 205 | if(!pl) 206 | zlist = l->next; 207 | else 208 | pl->next = l->next; 209 | free(l); 210 | 211 | return ret; 212 | } 213 | -------------------------------------------------------------------------------- /zfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * UAE - The Un*x Amiga Emulator 3 | * 4 | * routines to handle compressed file automatically 5 | * 6 | * (c) 1996 Samuel Devulder 7 | */ 8 | 9 | extern struct zfile *zfile_open(const char *, const char *, unsigned short re_compress); 10 | extern FILE *f_zfile_open(const char *, const char *, unsigned short re_compress); 11 | extern char *n_zfile_open(const char *, const char *, unsigned short re_compress); 12 | extern int zfile_close(FILE *); 13 | extern void zfile_exit(void); 14 | --------------------------------------------------------------------------------