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");
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_SectorPerBlock
= 1;
381 de
.de_BlocksPerTrack
=1;
383 de
.de_HighCyl
= cfg
->size
-1;
384 if (createFile(cfg
) == 0)
386 volume
= initVolume(afsbase
, NULL
, cfg
->image
, 0, 0, &de
, &error
);
389 if ((error
== 0) || (error
== ERROR_NOT_A_DOS_DISK
))
391 if (error
== ERROR_NOT_A_DOS_DISK
)
393 printf("Initialising disk ...");
394 format(afsbase
, volume
, cfg
->name
, cfg
->type
);
395 newMedium(NULL
, volume
);
398 retval
= copyData(cfg
, volume
);
399 flush(afsbase
, volume
);
402 printf("Error %ld!\n", error
);
403 uninitVolume(afsbase
, volume
);
406 printf("Error %ld!\n", error
);
411 void printUsage(char *prg
) {
412 printf("Usage: %s [options] <imagefile> <path1> [path2 ...] \n", prg
);
413 printf("\t--size\timage size\n"
414 "\t\tThis is either of type int (a multiple of 512) or the special\n"
415 "\t\tvalue 'floppy1440'.\n");
416 printf("\t--reserved\tnumber of reserved blocks (default: 2)\n");
417 printf("\t--bootblock\tnumber of bootblocks (default: 2)\n");
418 printf("\t--name\tlabel of the FS image\n");
419 printf("\t--type\tFS type (OFS, IOFS, FFS, IFFS(default))\n");
420 printf("\t--help\tthis help message\n");
423 void addPathElement(struct Config
*cfg
, struct PathElement
*pe
) {
424 struct PathElement
*next
;
426 next
= (struct PathElement
*)&cfg
->first
;
427 while (next
->next
!= NULL
)
433 int parseCommandLine(int argc
, char *argv
[], struct Config
*cfg
) {
436 struct PathElement
*pe
;
445 if ((argv
[i
][0] == '-') && (argv
[i
][0] == argv
[i
][1]))
447 if (strcasecmp(argv
[i
]+2, "help") == 0)
452 else if (strcasecmp(argv
[i
]+2, "size") == 0)
457 if (strcasecmp(argv
[i
], "floppy1440") == 0)
462 cfg
->size
= strtoul(argv
[i
], &end
, 10);
465 printf("%s: Integer error\n", argv
[i
-1]);
470 printf("%s: Value must be at least 8\n", argv
[i
-1]);
477 printf("%s: Missing argument to option\n", argv
[i
-1]);
481 else if (strcasecmp(argv
[i
]+2, "reserved") == 0)
487 cfg
->reserved
= strtoul(argv
[i
], &end
, 10);
490 printf("%s: Integer error\n", argv
[i
-1]);
496 printf("%s: Missing argument to option\n", argv
[i
-1]);
500 else if (strcasecmp(argv
[i
]+2, "bootblocks") == 0)
506 cfg
->bootblocks
= strtoul(argv
[i
], &end
, 10);
509 printf("%s: Integer error\n", argv
[i
-1]);
515 printf("%s: Missing argument to option\n", argv
[i
-1]);
519 else if (strcasecmp(argv
[i
]+2, "name") == 0)
526 printf("%s: Missing argument to option\n", argv
[i
-1]);
530 else if (strcasecmp(argv
[i
]+2, "type") == 0)
535 if (strcasecmp(argv
[i
], "OFS") == 0)
537 else if (strcasecmp(argv
[i
], "IOFS") == 0)
539 else if (strcasecmp(argv
[i
], "FFS") == 0)
541 else if (strcasecmp(argv
[i
], "IFFS") == 0)
545 printf("%s: Unknown fs type\n", argv
[i
-1]);
551 printf("%s: Missing argument to option\n", argv
[i
-1]);
557 printf("%s: Unknown option\n", argv
[i
]);
565 cfg
->image
= argv
[i
];
570 pe
= malloc(sizeof(struct PathElement
));
573 printf("Not enough memory\n");
577 addPathElement(cfg
, pe
);
581 if (cfg
->name
== NULL
)
582 cfg
->name
= "SomeDisk";
586 int main(int argc
, char *argv
[]) {
597 error
= parseCommandLine(argc
, argv
, &cfg
);
600 error
= doWork(&cfg
);