2 Copyright © 1995-2014, 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
)
87 printf("No more space left on device!\nNeed %ld more bytes to write file.\n", st
.st_size
-written
);
89 printf("%s: error %ld\n", filename
, (long int)error
);
99 printf("error %ld\n", (long int)error
);
107 printf("%s: error %ld\n", dstpath
, (long int)error
);
111 int makeDir(char *dirname
, struct Volume
*volume
) {
113 struct AfsHandle
*ah
;
114 struct AfsHandle
*dah
;
116 printf("Creating directory %s ...", dirname
);
117 ah
= openf(NULL
, &volume
->ah
, "", MODE_OLDFILE
, &error
);
120 dah
= createDir(NULL
, ah
, dirname
, 0, &error
);
129 if (error
== ERROR_OBJECT_EXISTS
)
131 printf("was already there\n");
135 printf("error %ld\n", (long)error
);
140 printf("error %ld\n", (long)error
);
144 int copyDir(char *path
, char *dstpath
, struct Volume
*volume
) {
155 while ((de
=readdir(dir
)) != NULL
)
157 if ((strcmp(de
->d_name
, ".")!=0) && (strcmp(de
->d_name
, "..")!=0))
159 ndpath
= malloc(strlen(path
)+1+strlen(de
->d_name
)+1);
163 sprintf(ndpath
, "%s/%s", path
, de
->d_name
);
164 if (stat(ndpath
, &st
) == 0)
166 if (S_ISDIR(st
.st_mode
))
168 nrpath
= malloc(strlen(path
)+1+strlen(de
->d_name
)+1);
172 strcpy(nrpath
, de
->d_name
);
174 sprintf(nrpath
, "%s/%s", dstpath
, de
->d_name
);
175 error
= makeDir(nrpath
, volume
);
177 error
= copyDir(ndpath
, nrpath
, volume
);
187 printf("No memory!\n");
192 else if (S_ISREG(st
.st_mode
))
194 error
= copyFile(ndpath
, dstpath
, volume
);
203 printf("%s: Unknown file type\n", ndpath
);
218 printf("No memory!\n");
235 int copyPath(char *path
, struct Volume
*volume
) {
238 if (stat(path
, &st
) == 0)
240 if (S_ISDIR(st
.st_mode
))
242 return copyDir(path
, "", volume
);
244 else if (S_ISREG(st
.st_mode
))
246 /* for now always copy to root */
247 return copyFile(path
, "", volume
);
250 printf("Unknown file type\n");
257 int copyData(struct Config
*cfg
, struct Volume
*volume
) {
258 struct PathElement
*pe
;
263 if (copyPath(pe
->path
, volume
) != 0)
270 int fillFile(char *image
, unsigned int size
) {
271 char buffer
[512]={0};
276 fh
= fopen(image
, "w");
281 if (fwrite(buffer
, 512, 1, fh
) != 1)
296 int createFile(struct Config
*cfg
) {
300 if (stat(cfg
->image
, &st
) == 0)
302 // printf("type=%d blocks=%ld blocksize=%ld\n", st.st_rdev, st.st_blocks, st.st_blksize);
303 if (S_ISBLK(st
.st_mode
))
305 printf("block device\n");
308 else if (S_ISREG(st
.st_mode
))
312 if (fillFile(cfg
->image
, cfg
->size
) == 0)
315 else if (st
.st_size
/512 < cfg
->size
)
317 printf("%s: File already exists and is too small\n", cfg
->image
);
324 printf("%s: This is not a regular file or blockdevice!\n", cfg
->image
);
331 if (fillFile(cfg
->image
, cfg
->size
) == 0)
342 int doWork(struct Config
*cfg
) {
344 struct PathElement
*pe
;
345 struct AFSBase
*afsbase
=NULL
;
346 struct DosEnvec de
={0};
348 struct Volume
*volume
;
350 printf("Image: %s\n", cfg
->image
);
351 printf("Size: %d 512 byte sectors\n", cfg
->size
);
352 printf("Name: %s\n", cfg
->name
);
357 printf("Old Filesystem\n");
358 cfg
->type
= ID_DOS_DISK
;
361 printf("Fast Filesystem\n");
362 cfg
->type
= ID_FFS_DISK
;
365 printf("International Old Filesystem\n");
366 cfg
->type
= ID_INTER_DOS_DISK
;
369 printf("International Fast Filesystem\n");
370 cfg
->type
= ID_INTER_FFS_DISK
;
377 printf("\t%s\n", pe
->path
);
380 de
.de_SizeBlock
= 512>>2;
381 de
.de_TableSize
= 20;
382 de
.de_BootBlocks
= cfg
->bootblocks
;
383 de
.de_Reserved
= cfg
->reserved
;
384 de
.de_NumBuffers
= 20;
386 de
.de_SectorPerBlock
= 1;
387 de
.de_BlocksPerTrack
=1;
389 de
.de_HighCyl
= cfg
->size
-1;
390 if (createFile(cfg
) == 0)
392 volume
= initVolume(afsbase
, NULL
, cfg
->image
, 0, 0, &de
, &error
);
395 if ((error
== 0) || (error
== ERROR_NOT_A_DOS_DISK
))
397 if (error
== ERROR_NOT_A_DOS_DISK
)
399 printf("Initialising disk ...");
400 format(afsbase
, volume
, cfg
->name
, cfg
->type
);
401 newMedium(NULL
, volume
);
404 retval
= copyData(cfg
, volume
);
405 flush(afsbase
, volume
);
408 printf("Error %ld!\n", (long)error
);
409 uninitVolume(afsbase
, volume
);
412 printf("Error %ld!\n", (long)error
);
417 void printUsage(char *prg
) {
418 printf("Usage: %s [options] <imagefile> <path1> [path2 ...] \n", prg
);
419 printf("\t--size\timage size\n"
420 "\t\tThis is either of type int (a multiple of 512) or the special\n"
421 "\t\tvalue 'floppy1440'.\n");
422 printf("\t--reserved\tnumber of reserved blocks (default: 2)\n");
423 printf("\t--bootblock\tnumber of bootblocks (default: 2)\n");
424 printf("\t--name\tlabel of the FS image\n");
425 printf("\t--type\tFS type (OFS, IOFS, FFS, IFFS(default))\n");
426 printf("\t--help\tthis help message\n");
429 void addPathElement(struct Config
*cfg
, struct PathElement
*pe
) {
430 struct PathElement
*next
;
432 next
= (struct PathElement
*)&cfg
->first
;
433 while (next
->next
!= NULL
)
439 int parseCommandLine(int argc
, char *argv
[], struct Config
*cfg
) {
442 struct PathElement
*pe
;
451 if ((argv
[i
][0] == '-') && (argv
[i
][0] == argv
[i
][1]))
453 if (strcasecmp(argv
[i
]+2, "help") == 0)
458 else if (strcasecmp(argv
[i
]+2, "size") == 0)
463 if (strcasecmp(argv
[i
], "floppy1440") == 0)
468 cfg
->size
= strtoul(argv
[i
], &end
, 10);
471 printf("%s: Integer error\n", argv
[i
-1]);
476 printf("%s: Value must be at least 8\n", argv
[i
-1]);
483 printf("%s: Missing argument to option\n", argv
[i
-1]);
487 else if (strcasecmp(argv
[i
]+2, "reserved") == 0)
493 cfg
->reserved
= strtoul(argv
[i
], &end
, 10);
496 printf("%s: Integer error\n", argv
[i
-1]);
502 printf("%s: Missing argument to option\n", argv
[i
-1]);
506 else if (strcasecmp(argv
[i
]+2, "bootblocks") == 0)
512 cfg
->bootblocks
= strtoul(argv
[i
], &end
, 10);
515 printf("%s: Integer error\n", argv
[i
-1]);
521 printf("%s: Missing argument to option\n", argv
[i
-1]);
525 else if (strcasecmp(argv
[i
]+2, "name") == 0)
532 printf("%s: Missing argument to option\n", argv
[i
-1]);
536 else if (strcasecmp(argv
[i
]+2, "type") == 0)
541 if (strcasecmp(argv
[i
], "OFS") == 0)
543 else if (strcasecmp(argv
[i
], "IOFS") == 0)
545 else if (strcasecmp(argv
[i
], "FFS") == 0)
547 else if (strcasecmp(argv
[i
], "IFFS") == 0)
551 printf("%s: Unknown fs type\n", argv
[i
-1]);
557 printf("%s: Missing argument to option\n", argv
[i
-1]);
563 printf("%s: Unknown option\n", argv
[i
]);
571 cfg
->image
= argv
[i
];
576 pe
= malloc(sizeof(struct PathElement
));
579 printf("Not enough memory\n");
583 addPathElement(cfg
, pe
);
587 if (cfg
->name
== NULL
)
588 cfg
->name
= "SomeDisk";
592 int main(int argc
, char *argv
[]) {
603 error
= parseCommandLine(argc
, argv
, &cfg
);
606 error
= doWork(&cfg
);