2 Copyright © 1995-2019, The AROS Development Team. All rights reserved.
15 #include "filehandles1.h"
16 #include "filehandles2.h"
23 struct PathElement
*next
;
29 struct PathElement
*first
;
32 unsigned int bootblocks
;
33 unsigned int reserved
;
37 char *filepart(char *path
) {
40 ptr
= path
+strlen(path
);
41 while ((ptr
!= path
) && (*ptr
!= '/'))
48 int copyFile(char *srcpath
, char *dstpath
, struct Volume
*volume
) {
54 struct AfsHandle
*fah
;
61 filename
= filepart(srcpath
);
62 printf("Copying %s to %s ...", filename
, dstpath
);
63 ah
= openf(NULL
, &volume
->ah
, dstpath
, MODE_OLDFILE
, &error
);
66 fd
= open(srcpath
, O_RDONLY
);
69 fah
= openfile(NULL
, ah
, filename
, MODE_NEWFILE
, 0, &error
);
73 while ((len
=read(fd
, buffer
, 2048))>0)
75 size
= writef(NULL
, fah
, buffer
, len
, &error
);
86 if (error
== ERROR_NO_FREE_STORE
)
88 printf("No more space left on device!\nNeed %lld more bytes to write file.\n", (long long int)(st
.st_size
-written
));
91 printf("%s: error %ld\n", filename
, (long int)error
);
101 printf("error %ld\n", (long int)error
);
109 printf("%s: error %ld\n", dstpath
, (long int)error
);
113 int makeDir(char *dirname
, struct Volume
*volume
) {
115 struct AfsHandle
*ah
;
116 struct AfsHandle
*dah
;
118 printf("Creating directory %s ...", dirname
);
119 ah
= openf(NULL
, &volume
->ah
, "", MODE_OLDFILE
, &error
);
122 dah
= createDir(NULL
, ah
, dirname
, 0, &error
);
131 if (error
== ERROR_OBJECT_EXISTS
)
133 printf("was already there\n");
137 printf("error %ld\n", (long)error
);
142 printf("error %ld\n", (long)error
);
146 int copyDir(char *path
, char *dstpath
, struct Volume
*volume
) {
157 while ((de
=readdir(dir
)) != NULL
)
159 if ((strcmp(de
->d_name
, ".")!=0) && (strcmp(de
->d_name
, "..")!=0))
161 ndpath
= malloc(strlen(path
)+1+strlen(de
->d_name
)+1);
165 sprintf(ndpath
, "%s/%s", path
, de
->d_name
);
166 if (stat(ndpath
, &st
) == 0)
168 if (S_ISDIR(st
.st_mode
))
170 nrpath
= malloc(strlen(path
)+1+strlen(de
->d_name
)+1);
174 strcpy(nrpath
, de
->d_name
);
176 sprintf(nrpath
, "%s/%s", dstpath
, de
->d_name
);
177 error
= makeDir(nrpath
, volume
);
179 error
= copyDir(ndpath
, nrpath
, volume
);
189 printf("No memory!\n");
194 else if (S_ISREG(st
.st_mode
))
196 error
= copyFile(ndpath
, dstpath
, volume
);
205 printf("%s: Unknown file type\n", ndpath
);
220 printf("No memory!\n");
237 int copyPath(char *path
, struct Volume
*volume
) {
240 if (stat(path
, &st
) == 0)
242 if (S_ISDIR(st
.st_mode
))
244 return copyDir(path
, "", volume
);
246 else if (S_ISREG(st
.st_mode
))
248 /* for now always copy to root */
249 return copyFile(path
, "", volume
);
252 printf("Unknown file type\n");
259 int copyData(struct Config
*cfg
, struct Volume
*volume
) {
260 struct PathElement
*pe
;
265 if (copyPath(pe
->path
, volume
) != 0)
272 int fillFile(char *image
, unsigned int size
) {
273 char buffer
[512]={0};
278 fh
= fopen(image
, "w");
283 if (fwrite(buffer
, 512, 1, fh
) != 1)
298 int createFile(struct Config
*cfg
) {
302 if (stat(cfg
->image
, &st
) == 0)
304 // printf("type=%d blocks=%ld blocksize=%ld\n", st.st_rdev, st.st_blocks, st.st_blksize);
305 if (S_ISBLK(st
.st_mode
))
307 printf("block device\n");
310 else if (S_ISREG(st
.st_mode
))
314 if (fillFile(cfg
->image
, cfg
->size
) == 0)
317 else if (st
.st_size
/512 < cfg
->size
)
319 printf("%s: File already exists and is too small\n", cfg
->image
);
326 printf("%s: This is not a regular file or blockdevice!\n", cfg
->image
);
333 if (fillFile(cfg
->image
, cfg
->size
) == 0)
344 int doWork(struct Config
*cfg
) {
346 struct PathElement
*pe
;
347 struct AFSBase
*afsbase
=NULL
;
348 struct DosEnvec de
={0};
350 struct Volume
*volume
;
352 printf("Image: %s\n", cfg
->image
);
353 printf("Size: %d 512 byte sectors\n", cfg
->size
);
354 printf("Name: %s\n", cfg
->name
);
359 printf("Old Filesystem\n");
360 cfg
->type
= ID_DOS_DISK
;
363 printf("Fast Filesystem\n");
364 cfg
->type
= ID_FFS_DISK
;
367 printf("International Old Filesystem\n");
368 cfg
->type
= ID_INTER_DOS_DISK
;
371 printf("International Fast Filesystem\n");
372 cfg
->type
= ID_INTER_FFS_DISK
;
379 printf("\t%s\n", pe
->path
);
382 de
.de_SizeBlock
= 512>>2;
383 de
.de_TableSize
= 20;
384 de
.de_BootBlocks
= cfg
->bootblocks
;
385 de
.de_Reserved
= cfg
->reserved
;
386 de
.de_NumBuffers
= 20;
388 de
.de_SectorPerBlock
= 1;
389 de
.de_BlocksPerTrack
=1;
391 de
.de_HighCyl
= cfg
->size
-1;
392 if (createFile(cfg
) == 0)
394 volume
= initVolume(afsbase
, NULL
, cfg
->image
, 0, 0, &de
, &error
);
397 if ((error
== 0) || (error
== ERROR_NOT_A_DOS_DISK
))
399 if (error
== ERROR_NOT_A_DOS_DISK
)
401 printf("Initialising disk ...");
402 format(afsbase
, volume
, cfg
->name
, cfg
->type
);
403 newMedium(NULL
, volume
);
406 retval
= copyData(cfg
, volume
);
407 flush(afsbase
, volume
);
410 printf("Error %ld!\n", (long)error
);
411 uninitVolume(afsbase
, volume
);
414 printf("Error %ld!\n", (long)error
);
419 void printUsage(char *prg
) {
420 printf("Usage: %s [options] <imagefile> <path1> [path2 ...] \n", prg
);
421 printf("\t--size\timage size\n"
422 "\t\tThis is either of type int (a multiple of 512) or the special\n"
423 "\t\tvalue 'floppy1440'.\n");
424 printf("\t--reserved\tnumber of reserved blocks (default: 2)\n");
425 printf("\t--bootblock\tnumber of bootblocks (default: 2)\n");
426 printf("\t--name\tlabel of the FS image\n");
427 printf("\t--type\tFS type (OFS, IOFS, FFS, IFFS(default))\n");
428 printf("\t--help\tthis help message\n");
431 void addPathElement(struct Config
*cfg
, struct PathElement
*pe
) {
432 struct PathElement
*next
;
434 next
= (struct PathElement
*)&cfg
->first
;
435 while (next
->next
!= NULL
)
441 int parseCommandLine(int argc
, char *argv
[], struct Config
*cfg
) {
444 struct PathElement
*pe
;
453 if ((argv
[i
][0] == '-') && (argv
[i
][0] == argv
[i
][1]))
455 if (strcasecmp(argv
[i
]+2, "help") == 0)
460 else if (strcasecmp(argv
[i
]+2, "size") == 0)
465 if (strcasecmp(argv
[i
], "floppy1440") == 0)
470 cfg
->size
= strtoul(argv
[i
], &end
, 10);
473 printf("%s: Integer error\n", argv
[i
-1]);
478 printf("%s: Value must be at least 8\n", argv
[i
-1]);
485 printf("%s: Missing argument to option\n", argv
[i
-1]);
489 else if (strcasecmp(argv
[i
]+2, "reserved") == 0)
495 cfg
->reserved
= strtoul(argv
[i
], &end
, 10);
498 printf("%s: Integer error\n", argv
[i
-1]);
504 printf("%s: Missing argument to option\n", argv
[i
-1]);
508 else if (strcasecmp(argv
[i
]+2, "bootblocks") == 0)
514 cfg
->bootblocks
= strtoul(argv
[i
], &end
, 10);
517 printf("%s: Integer error\n", argv
[i
-1]);
523 printf("%s: Missing argument to option\n", argv
[i
-1]);
527 else if (strcasecmp(argv
[i
]+2, "name") == 0)
534 printf("%s: Missing argument to option\n", argv
[i
-1]);
538 else if (strcasecmp(argv
[i
]+2, "type") == 0)
543 if (strcasecmp(argv
[i
], "OFS") == 0)
545 else if (strcasecmp(argv
[i
], "IOFS") == 0)
547 else if (strcasecmp(argv
[i
], "FFS") == 0)
549 else if (strcasecmp(argv
[i
], "IFFS") == 0)
553 printf("%s: Unknown fs type\n", argv
[i
-1]);
559 printf("%s: Missing argument to option\n", argv
[i
-1]);
565 printf("%s: Unknown option\n", argv
[i
]);
573 cfg
->image
= argv
[i
];
578 pe
= malloc(sizeof(struct PathElement
));
581 printf("Not enough memory\n");
585 addPathElement(cfg
, pe
);
589 if (cfg
->name
== NULL
)
590 cfg
->name
= "SomeDisk";
594 int main(int argc
, char *argv
[]) {
605 error
= parseCommandLine(argc
, argv
, &cfg
);
608 error
= doWork(&cfg
);