10 #include "filehandles1.h"
11 #include "filehandles2.h"
18 struct PathElement
*next
;
24 struct PathElement
*first
;
27 unsigned int bootblocks
;
28 unsigned int reserved
;
32 char *filepart(char *path
) {
35 ptr
= path
+strlen(path
);
36 while ((ptr
!= path
) && (*ptr
!= '/'))
43 int copyFile(char *srcpath
, char *dstpath
, struct Volume
*volume
) {
49 struct AfsHandle
*fah
;
56 filename
= filepart(srcpath
);
57 printf("Copying %s to %s ...", filename
, dstpath
);
58 ah
= openf(NULL
, &volume
->ah
, dstpath
, MODE_OLDFILE
, &error
);
61 fd
= open(srcpath
, O_RDONLY
);
64 fah
= openfile(NULL
, ah
, filename
, MODE_NEWFILE
, 0, &error
);
68 while ((len
=read(fd
, buffer
, 2048))>0)
70 size
= writef(NULL
, fah
, buffer
, len
, &error
);
81 if (error
== ERROR_NO_FREE_STORE
)
82 printf("No more space left on device!\nNeed %ld more bytes to write file.\n", st
.st_size
-written
);
84 printf("%s: error %ld\n", filename
, error
);
94 printf("error %ld\n", error
);
102 printf("%s: error %ld\n", dstpath
, error
);
106 int makeDir(char *dirname
, struct Volume
*volume
) {
108 struct AfsHandle
*ah
;
109 struct AfsHandle
*dah
;
111 printf("Creating directory %s ...", dirname
);
112 ah
= openf(NULL
, &volume
->ah
, "", MODE_OLDFILE
, &error
);
115 dah
= createDir(NULL
, ah
, dirname
, 0, &error
);
124 if (error
== ERROR_OBJECT_EXISTS
)
126 printf("was already there\n");
130 printf("error %ld\n", error
);
135 printf("error %ld\n", error
);
139 int copyDir(char *path
, char *dstpath
, struct Volume
*volume
) {
150 while ((de
=readdir(dir
)) != NULL
)
152 if ((strcmp(de
->d_name
, ".")!=0) && (strcmp(de
->d_name
, "..")!=0))
154 ndpath
= malloc(strlen(path
)+1+strlen(de
->d_name
)+1);
158 sprintf(ndpath
, "%s/%s", path
, de
->d_name
);
159 if (stat(ndpath
, &st
) == 0)
161 if (S_ISDIR(st
.st_mode
))
163 nrpath
= malloc(strlen(path
)+1+strlen(de
->d_name
)+1);
167 strcpy(nrpath
, de
->d_name
);
169 sprintf(nrpath
, "%s/%s", dstpath
, de
->d_name
);
170 error
= makeDir(nrpath
, volume
);
172 error
= copyDir(ndpath
, nrpath
, volume
);
182 printf("No memory!\n");
187 else if (S_ISREG(st
.st_mode
))
189 error
= copyFile(ndpath
, dstpath
, volume
);
198 printf("%s: Unknown file type\n", ndpath
);
213 printf("No memory!\n");
230 int copyPath(char *path
, struct Volume
*volume
) {
233 if (stat(path
, &st
) == 0)
235 if (S_ISDIR(st
.st_mode
))
237 return copyDir(path
, "", volume
);
239 else if (S_ISREG(st
.st_mode
))
241 /* for now always copy to root */
242 return copyFile(path
, "", volume
);
245 printf("Unknown file type\n");
252 int copyData(struct Config
*cfg
, struct Volume
*volume
) {
253 struct PathElement
*pe
;
258 if (copyPath(pe
->path
, volume
) != 0)
265 int fillFile(char *image
, unsigned int size
) {
266 char buffer
[512]={0};
271 fh
= fopen(image
, "w");
276 if (fwrite(buffer
, 512, 1, fh
) != 1)
291 int createFile(struct Config
*cfg
) {
295 if (stat(cfg
->image
, &st
) == 0)
297 // printf("type=%d blocks=%ld blocksize=%ld\n", st.st_rdev, st.st_blocks, st.st_blksize);
298 if (S_ISBLK(st
.st_mode
))
300 printf("block device\n");
303 else if (S_ISREG(st
.st_mode
))
307 if (fillFile(cfg
->image
, cfg
->size
) == 0)
310 else if (st
.st_size
/512 < cfg
->size
)
312 printf("%s: File already exists and is too small\n", cfg
->image
);
319 printf("%s: This is not a regular file or blockdevice!\n", cfg
->image
);
326 if (fillFile(cfg
->image
, cfg
->size
) == 0)
337 int doWork(struct Config
*cfg
) {
339 struct PathElement
*pe
;
340 struct AFSBase
*afsbase
=NULL
;
341 struct DosEnvec de
={0};
343 struct Volume
*volume
;
345 printf("Image: %s\n", cfg
->image
);
346 printf("Size: %d 512 byte sectors\n", cfg
->size
);
347 printf("Name: %s\n", cfg
->name
);
352 printf("Old Filesystem\n");
353 cfg
->type
= ID_DOS_DISK
;
356 printf("Fast Filesystem\n");
357 cfg
->type
= ID_FFS_DISK
;
360 printf("International Old Filesystem\n");
361 cfg
->type
= ID_INTER_DOS_DISK
;
364 printf("International Fast Filesystem\n");
365 cfg
->type
= ID_INTER_FFS_DISK
;
372 printf("\t%s\n", pe
->path
);
375 de
.de_SizeBlock
= 512>>2;
376 de
.de_TableSize
= 20;
377 de
.de_BootBlocks
= cfg
->bootblocks
;
378 de
.de_Reserved
= cfg
->reserved
;
379 de
.de_NumBuffers
= 20;
381 de
.de_SectorPerBlock
= 1;
382 de
.de_BlocksPerTrack
=1;
384 de
.de_HighCyl
= cfg
->size
-1;
385 if (createFile(cfg
) == 0)
387 volume
= initVolume(afsbase
, NULL
, cfg
->image
, 0, 0, &de
, &error
);
390 if ((error
== 0) || (error
== ERROR_NOT_A_DOS_DISK
))
392 if (error
== ERROR_NOT_A_DOS_DISK
)
394 printf("Initialising disk ...");
395 format(afsbase
, volume
, cfg
->name
, cfg
->type
);
396 newMedium(NULL
, volume
);
399 retval
= copyData(cfg
, volume
);
400 flush(afsbase
, volume
);
403 printf("Error %ld!\n", error
);
404 uninitVolume(afsbase
, volume
);
407 printf("Error %ld!\n", error
);
412 void printUsage(char *prg
) {
413 printf("Usage: %s [options] <imagefile> <path1> [path2 ...] \n", prg
);
414 printf("\t--size\timage size\n"
415 "\t\tThis is either of type int (a multiple of 512) or the special\n"
416 "\t\tvalue 'floppy1440'.\n");
417 printf("\t--reserved\tnumber of reserved blocks (default: 2)\n");
418 printf("\t--bootblock\tnumber of bootblocks (default: 2)\n");
419 printf("\t--name\tlabel of the FS image\n");
420 printf("\t--type\tFS type (OFS, IOFS, FFS, IFFS(default))\n");
421 printf("\t--help\tthis help message\n");
424 void addPathElement(struct Config
*cfg
, struct PathElement
*pe
) {
425 struct PathElement
*next
;
427 next
= (struct PathElement
*)&cfg
->first
;
428 while (next
->next
!= NULL
)
434 int parseCommandLine(int argc
, char *argv
[], struct Config
*cfg
) {
437 struct PathElement
*pe
;
446 if ((argv
[i
][0] == '-') && (argv
[i
][0] == argv
[i
][1]))
448 if (strcasecmp(argv
[i
]+2, "help") == 0)
453 else if (strcasecmp(argv
[i
]+2, "size") == 0)
458 if (strcasecmp(argv
[i
], "floppy1440") == 0)
463 cfg
->size
= strtoul(argv
[i
], &end
, 10);
466 printf("%s: Integer error\n", argv
[i
-1]);
471 printf("%s: Value must be at least 8\n", argv
[i
-1]);
478 printf("%s: Missing argument to option\n", argv
[i
-1]);
482 else if (strcasecmp(argv
[i
]+2, "reserved") == 0)
488 cfg
->reserved
= strtoul(argv
[i
], &end
, 10);
491 printf("%s: Integer error\n", argv
[i
-1]);
497 printf("%s: Missing argument to option\n", argv
[i
-1]);
501 else if (strcasecmp(argv
[i
]+2, "bootblocks") == 0)
507 cfg
->bootblocks
= strtoul(argv
[i
], &end
, 10);
510 printf("%s: Integer error\n", argv
[i
-1]);
516 printf("%s: Missing argument to option\n", argv
[i
-1]);
520 else if (strcasecmp(argv
[i
]+2, "name") == 0)
527 printf("%s: Missing argument to option\n", argv
[i
-1]);
531 else if (strcasecmp(argv
[i
]+2, "type") == 0)
536 if (strcasecmp(argv
[i
], "OFS") == 0)
538 else if (strcasecmp(argv
[i
], "IOFS") == 0)
540 else if (strcasecmp(argv
[i
], "FFS") == 0)
542 else if (strcasecmp(argv
[i
], "IFFS") == 0)
546 printf("%s: Unknown fs type\n", argv
[i
-1]);
552 printf("%s: Missing argument to option\n", argv
[i
-1]);
558 printf("%s: Unknown option\n", argv
[i
]);
566 cfg
->image
= argv
[i
];
571 pe
= malloc(sizeof(struct PathElement
));
574 printf("Not enough memory\n");
578 addPathElement(cfg
, pe
);
582 if (cfg
->name
== NULL
)
583 cfg
->name
= "SomeDisk";
587 int main(int argc
, char *argv
[]) {
598 error
= parseCommandLine(argc
, argv
, &cfg
);
601 error
= doWork(&cfg
);