3 * (c) 2004 Laurent Vivier <Laurent@Vivier.EU>
22 extern void scanbus(void);
23 extern void diskinfo(char*);
30 ACTION_STARTUP = 0x04,
31 ACTION_SCANBUS = 0x08,
48 static struct option long_options[] =
50 {"help", 0, NULL, ARG_HELP },
51 {"flags", 1, NULL, ARG_FLAGS },
52 {"type", 1, NULL, ARG_TYPE },
53 {"startup", 0, NULL, ARG_STARTUP },
54 {"scanbus", 0, NULL, ARG_SCANBUS },
55 {"verbose", 0, NULL, ARG_VERBOSE },
56 {"get-driver", 1, NULL, ARG_GET },
57 {"put-driver", 1, NULL, ARG_PUT },
61 static void usage(int argc, char** argv)
63 fprintf(stderr, "Usage: %s [OPTIONS] [<disk>]\n", argv[0]);
64 fprintf(stderr, " %s [OPTIONS] [<partition>|<disk> <part number>]\n", argv[0]);
65 fprintf(stderr, " -h, --help display this text\n");
66 fprintf(stderr, " -v, --verbose verbose mode\n");
67 fprintf(stderr, " --scanbus "
68 "scan all available SCSI devices\n");
69 fprintf(stderr, " -s, --startup "
70 "set the startup partition\n");
71 fprintf(stderr, " -t, --type=TYPE "
72 "set the type of the partition\n");
73 fprintf(stderr, " -f, --flags=FLAGS "
74 "set the type of the partition\n");
75 fprintf(stderr, " -g, --get-driver=FILE "
76 "get the driver from the partition\n");
77 fprintf(stderr, " -p, --put-driver=FILE "
78 "put the driver to the partition\n");
79 fprintf(stderr, "\nbuild: \n%s\n", SIGNATURE);
82 static int get_driver(map_t *map, int partition, char* appledriver)
85 int block_size, block_count;
87 int block, size, type, part;
88 int partition_base, partition_size;
89 int bootstart, bootsize, bootaddr, bootentry, checksum;
95 map_read(map, partition);
96 if (strncmp(map_get_partition_type(map),
97 "Apple_Driver", strlen("Apple_Driver")) != 0)
100 "ERROR: the type of the partition must begin with \"Apple_Driver\"\n");
103 if (strcmp(map_get_partition_name(map), "Macintosh") != 0)
106 "ERROR: the name of the partition must be \"Macintosh\"\n");
110 map_geometry(map, &block_size, &block_count);
111 printf("block size: %d\n", block_size);
113 map_get_partition_geometry(map, &partition_base, &partition_size);
114 printf("partition base: %d, size %d\n", partition_base, partition_size);
116 driver_number = map_get_driver_number(map);
117 if (driver_number == 0)
119 fprintf(stderr, "ERROR: no driver on this device\n");
123 for (driver = 0; driver < driver_number; driver++)
125 map_get_driver_info(map, driver, &block, &size, &type);
126 part = map_seek_driver_partition(map,
127 block * block_size / 512 );
128 if (part == partition)
131 if (emile_is_apple_driver(map))
134 part = map_seek_driver_partition(map, block);
135 if (part == partition)
138 if (emile_is_apple_driver(map))
142 if (part != partition)
145 "ERROR: cannot find partition in driver table\n");
148 printf("Found driver %d for partition %d\n", driver, partition + 1);
149 printf("base: %d size: %d type: %d\n", block * block_size / 512,
150 size * block_size / 512 , type);
151 map_get_bootinfo(map, &bootstart, &bootsize, &bootaddr,
152 &bootentry, &checksum, processor);
153 printf("Bootstart: %d, Bootsize: %d, Bootaddr: %d, Bootentry: %d\n",
154 bootstart, bootsize, bootaddr, bootentry);
155 printf("Checksum: 0x%04x, Processor: %s\n", checksum, processor);
157 if (strcmp(processor, "68000") != 0)
160 "ERROR: cannot manage processor %s (not 68000)\n", processor);
164 code = (unsigned char*)malloc(partition_size * 512);
167 fprintf(stderr, "ERROR: cannot malloc() to load driver in memory\n");
171 ret = map_read_sector(map, 0, (char*)code, partition_size * 512);
174 fprintf(stderr, "ERROR: cannot read driver (read())\n");
179 ret = emile_checksum(code, bootsize);
181 fprintf(stderr, "WARNING: checksum is invalid (0x%x)\n",
184 printf("Checksum OK\n");
186 fd = open(appledriver, O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR);
189 fprintf(stderr, "ERROR: cannot open %s to save driver\n",
195 ret = write(fd, code, bootsize);
201 fprintf(stderr, "ERROR: cannot save driver to %s\n",
208 static int put_driver(map_t *map, int partition, char* appledriver)
210 int block_size, block_count;
216 int block, count, checksum;
218 map_read(map, partition);
220 if (strncmp(map_get_partition_type(map),
221 "Apple_Driver", strlen("Apple_Driver")) != 0)
224 "ERROR: the type of the partition must begin with \"Apple_Driver\"\n");
227 if (strcmp(map_get_partition_name(map), "Macintosh") != 0)
230 "ERROR: the name of the partition must be \"Macintosh\"\n");
234 map_geometry(map, &block_size, &block_count);
236 /* read driver from file */
238 fd = open(appledriver, O_RDONLY);
241 fprintf(stderr, "ERROR: cannot open file %s\n", appledriver);
245 ret = fstat(fd, &st);
248 fprintf(stderr, "ERROR: cannot stat file %s\n", appledriver);
252 code = malloc(st.st_size);
255 fprintf(stderr, "ERROR: cannot malloc %ld\n", st.st_size);
259 ret = read(fd, code, st.st_size);
263 if (ret != st.st_size)
265 fprintf(stderr, "ERROR: cannot read file %s\n", appledriver);
269 /* compute driver checksum */
271 checksum = emile_checksum(code, st.st_size);
272 printf("Driver checksum: 0x%x\n", checksum);
274 /* write file in partition */
276 ret = map_write_sector(map, 0, (char*)code, st.st_size);
281 fprintf(stderr, "ERROR: cannot write driver (write())\n");
287 map_set_bootinfo(map, 0, st.st_size, 0, 0, checksum, "68000");
288 map_partition_set_flags(map, 0x17F);
290 /* add driver in drivers list */
292 driver_number = map_get_driver_number(map);
293 if (driver_number == -1)
295 fprintf(stderr, "ERROR: cannot read drivers number\n");
298 if (driver_number != 1) {
299 fprintf(stderr, "ERROR: cannot manage more than one driver\n");
303 ret = map_get_partition_geometry(map, &block, &count);
306 fprintf(stderr, "ERROR: cannot read partition geometry\n");
310 ret = map_set_driver_info(map, driver_number - 1,
311 block / (block_size / 512) ,
312 count / (block_size / 512), 1);
315 fprintf(stderr, "ERROR: cannot set driver info\n");
319 ret = map_write(map, partition);
320 if (ret != partition)
322 fprintf(stderr, "ERROR: cannot set partition information\n");
326 ret = map_block0_write(map);
329 fprintf(stderr, "ERROR: cannot set drivers information\n");
336 int main(int argc, char** argv)
345 int action = ACTION_NONE;
346 char *dev_name = NULL;
347 char *appledriver = NULL;
355 open_flags = O_RDONLY;
358 c = getopt_long(argc, argv, "hvg:p:sf:t:", long_options,
371 action |= ACTION_FLAGS;
372 flags = strtol(optarg, NULL, 0);
375 action |= ACTION_TYPE;
379 action |= ACTION_STARTUP;
383 action |= ACTION_SCANBUS;
386 action |= ACTION_GET;
387 appledriver = optarg;
390 action |= ACTION_PUT;
391 appledriver = optarg;
397 dev_name = argv[optind++];
400 partition = strtol(argv[optind++], NULL, 0);
404 "ERROR: partition number cannot be 0 !\n");
409 if ( !action && dev_name)
414 if (action & ACTION_SCANBUS) {
415 if (action & ~ACTION_SCANBUS) {
417 "ERROR: \"--scanbus\" cannot be used with other arguments\n");
424 if ((action & ACTION_GET) && (action & ACTION_PUT)) {
425 fprintf(stderr, "You should use --get-driver OR --put-driver\n");
429 if (dev_name == NULL)
431 fprintf(stderr, "ERROR: you must specify a device\n");
436 ret = emile_scsi_get_rdev(dev_name, &driver, &disk, &partition);
438 ret = emile_scsi_get_rdev(dev_name, &driver, &disk, NULL);
442 disk_name = dev_name;
448 fprintf(stderr, "ERROR: cannot find disk of %s\n", dev_name);
453 emile_get_dev_name(buffer, driver, disk, 0);
460 "ERROR: you must provide device of a partition\n");
464 device_sector_size = 512;
465 device.write_sector = (stream_write_sector_t)device_write_sector;
466 device.read_sector = (stream_read_sector_t)device_read_sector;
467 device.close = (stream_close_t)device_close;
468 device.get_blocksize = (stream_get_blocksize_t)device_get_blocksize;
469 device.data = (void*)device_open(disk_name, open_flags);
471 map = map_open(&device);
474 fprintf(stderr, "ERROR: cannot open partition map\n");
478 if (action & ACTION_STARTUP)
480 if (action & ~ACTION_STARTUP)
483 "ERROR: don't use --startup with other flags\n");
487 ret = map_set_startup(map, partition - 1);
492 if (action & ACTION_GET)
494 if (appledriver == NULL) {
495 fprintf(stderr, "ERROR: filename missing\n");
500 ret = get_driver(map, partition - 1, appledriver);
503 "ERROR: cannot put driver from partition %d to file %s\n",
504 partition, appledriver);
513 if (action & ACTION_PUT)
515 if (appledriver == NULL) {
516 fprintf(stderr, "ERROR: filename missing\n");
521 ret = put_driver(map, partition - 1, appledriver);
524 "ERROR: cannot put driver to partition %d from file %s\n",
525 partition, appledriver);
535 ret = map_read(map, partition - 1);
536 if (ret != partition - 1)
539 "ERROR: cannot read partition %d info\n", partition);
543 if (action & ACTION_FLAGS)
545 map_partition_set_flags(map, flags);
548 if (action & ACTION_TYPE)
550 ret = map_set_partition_type(map, type);
554 "ERROR: cannot set partition type to %s\n", type);
559 ret = map_write(map, partition - 1);
560 if (ret != partition - 1)
563 "ERROR: cannot write partition %d info\n", partition);