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
, FMF_READ
);
61 fd
= open(srcpath
, O_RDONLY
);
64 fah
= openfile(NULL
, ah
, filename
, FMF_READ
| FMF_WRITE
| FMF_CREATE
| FMF_LOCK
| FMF_CLEAR
, 0);
68 while ((len
=read(fd
, buffer
, 2048))>0)
70 size
= writef(NULL
, fah
, buffer
, len
);
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
, "", FMF_READ
);
115 dah
= createDir(NULL
, ah
, dirname
, 0);
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");
302 else if (S_ISREG(st
.st_mode
))
306 if (fillFile(cfg
->image
, cfg
->size
) == 0)
309 else if (st
.st_size
/512 < cfg
->size
)
311 printf("%s: File already exists and is too small\n", cfg
->image
);
318 printf("%s: This is not a regular file or blockdevice!\n", cfg
->image
);
325 if (fillFile(cfg
->image
, cfg
->size
) == 0)
336 int doWork(struct Config
*cfg
) {
338 struct PathElement
*pe
;
339 struct AFSBase
*afsbase
=NULL
;
340 struct DosEnvec de
={0};
342 struct Volume
*volume
;
344 printf("Image: %s\n", cfg
->image
);
345 printf("Size: %d 512 byte sectors\n", cfg
->size
);
346 printf("Name: %s\n", cfg
->name
);
351 printf("Old Filesystem\n");
352 cfg
->type
= ID_DOS_DISK
;
355 printf("Fast Filesystem\n");
356 cfg
->type
= ID_FFS_DISK
;
359 printf("International Old Filesystem\n");
360 cfg
->type
= ID_INTER_DOS_DISK
;
363 printf("International Fast Filesystem\n");
364 cfg
->type
= ID_INTER_FFS_DISK
;
371 printf("\t%s\n", pe
->path
);
374 de
.de_SizeBlock
= 512>>2;
375 de
.de_TableSize
= 20;
376 de
.de_BootBlocks
= cfg
->bootblocks
;
377 de
.de_Reserved
= cfg
->reserved
;
378 de
.de_NumBuffers
= 20;
380 de
.de_BlocksPerTrack
=1;
382 de
.de_HighCyl
= cfg
->size
-1;
383 if (createFile(cfg
) == 0)
385 volume
= initVolume(afsbase
, NULL
, cfg
->image
, 0, &de
, &error
);
388 if ((error
== 0) || (error
== ERROR_NOT_A_DOS_DISK
))
390 if (error
== ERROR_NOT_A_DOS_DISK
)
392 printf("Initialising disk ...");
393 format(afsbase
, volume
, cfg
->name
, cfg
->type
);
394 newMedium(NULL
, volume
);
397 retval
= copyData(cfg
, volume
);
398 flush(afsbase
, volume
);
401 printf("Error %ld!\n", error
);
402 uninitVolume(afsbase
, volume
);
405 printf("Error %ld!\n", error
);
410 void printUsage(char *prg
) {
411 printf("Usage: %s [options] <imagefile> <path1> [path2 ...] \n", prg
);
412 printf("\t--size\timage size\n"
413 "\t\tThis is either of type int (a multiple of 512) or the special\n"
414 "\t\tvalue 'floppy1440'.\n");
415 printf("\t--reserved\tnumber of reserved blocks (default: 2)\n");
416 printf("\t--bootblock\tnumber of bootblocks (default: 2)\n");
417 printf("\t--name\tlabel of the FS image\n");
418 printf("\t--type\tFS type (OFS, IOFS, FFS, IFFS(default))\n");
419 printf("\t--help\tthis help message\n");
422 void addPathElement(struct Config
*cfg
, struct PathElement
*pe
) {
423 struct PathElement
*next
;
425 next
= (struct PathElement
*)&cfg
->first
;
426 while (next
->next
!= NULL
)
432 int parseCommandLine(int argc
, char *argv
[], struct Config
*cfg
) {
435 struct PathElement
*pe
;
444 if ((argv
[i
][0] == '-') && (argv
[i
][0] == argv
[i
][1]))
446 if (strcasecmp(argv
[i
]+2, "help") == 0)
451 else if (strcasecmp(argv
[i
]+2, "size") == 0)
456 if (strcasecmp(argv
[i
], "floppy1440") == 0)
461 cfg
->size
= strtoul(argv
[i
], &end
, 10);
464 printf("%s: Integer error\n", argv
[i
-1]);
469 printf("%s: Value must be at least 8\n", argv
[i
-1]);
476 printf("%s: Missing argument to option\n", argv
[i
-1]);
480 else if (strcasecmp(argv
[i
]+2, "reserved") == 0)
486 cfg
->reserved
= strtoul(argv
[i
], &end
, 10);
489 printf("%s: Integer error\n", argv
[i
-1]);
495 printf("%s: Missing argument to option\n", argv
[i
-1]);
499 else if (strcasecmp(argv
[i
]+2, "bootblocks") == 0)
505 cfg
->bootblocks
= strtoul(argv
[i
], &end
, 10);
508 printf("%s: Integer error\n", argv
[i
-1]);
514 printf("%s: Missing argument to option\n", argv
[i
-1]);
518 else if (strcasecmp(argv
[i
]+2, "name") == 0)
525 printf("%s: Missing argument to option\n", argv
[i
-1]);
529 else if (strcasecmp(argv
[i
]+2, "type") == 0)
534 if (strcasecmp(argv
[i
], "OFS") == 0)
536 else if (strcasecmp(argv
[i
], "IOFS") == 0)
538 else if (strcasecmp(argv
[i
], "FFS") == 0)
540 else if (strcasecmp(argv
[i
], "IFFS") == 0)
544 printf("%s: Unknown fs type\n", argv
[i
-1]);
550 printf("%s: Missing argument to option\n", argv
[i
-1]);
556 printf("%s: Unknown option\n", argv
[i
]);
564 cfg
->image
= argv
[i
];
569 pe
= malloc(sizeof(struct PathElement
));
572 printf("Not enough memory\n");
576 addPathElement(cfg
, pe
);
580 if (cfg
->name
== NULL
)
581 cfg
->name
= "SomeDisk";
584 int main(int argc
, char *argv
[]) {
595 error
= parseCommandLine(argc
, argv
, &cfg
);
598 error
= doWork(&cfg
);