disk.c revision 104674
1141296Sdas/* 2141296Sdas * ---------------------------------------------------------------------------- 32116Sjkh * "THE BEER-WARE LICENSE" (Revision 42): 42116Sjkh * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you 52116Sjkh * can do whatever you want with this stuff. If we meet some day, and you think 62116Sjkh * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7141296Sdas * ---------------------------------------------------------------------------- 82116Sjkh */ 9141296Sdas 102116Sjkh#include <sys/cdefs.h> 112116Sjkh__FBSDID("$FreeBSD: head/lib/libdisk/disk.c 104674 2002-10-08 12:13:19Z nyan $"); 122116Sjkh 132116Sjkh#include <stdio.h> 14176451Sdas#include <stdlib.h> 15176451Sdas#include <unistd.h> 162116Sjkh#include <fcntl.h> 172116Sjkh#include <string.h> 182116Sjkh#include <err.h> 192116Sjkh#include <sys/sysctl.h> 202116Sjkh#include <sys/types.h> 212116Sjkh#include <sys/stat.h> 222116Sjkh#include <sys/ioctl.h> 232116Sjkh#include <sys/disklabel.h> 242116Sjkh#include <sys/diskslice.h> 252116Sjkh#ifndef PC98 262116Sjkh#include <sys/diskmbr.h> 272116Sjkh#endif 282116Sjkh#include <paths.h> 292116Sjkh#include "libdisk.h" 302116Sjkh 312116Sjkh#ifndef PC98 322116Sjkh#define DOSPTYP_EXTENDED 5 332116Sjkh#define DOSPTYP_ONTRACK 84 342116Sjkh#endif 352116Sjkh 362116Sjkhconst char *chunk_n[] = { 37141296Sdas "whole", 382116Sjkh "unknown", 392116Sjkh "fat", 402116Sjkh "freebsd", 412116Sjkh "extended", 42141296Sdas "part", 432116Sjkh "unused", 44141296Sdas NULL 452116Sjkh}; 46141296Sdas 472116Sjkhstruct disk * 482116SjkhOpen_Disk(const char *name) 492116Sjkh{ 502116Sjkh return Int_Open_Disk(name, 0); 512116Sjkh} 522116Sjkh 532116Sjkh#ifndef PC98 542116Sjkhstatic u_int32_t 552116SjkhRead_Int32(u_int32_t *p) 562116Sjkh{ 572116Sjkh u_int8_t *bp = (u_int8_t *)p; 582116Sjkh return bp[0] | (bp[1] << 8) | (bp[2] << 16) | (bp[3] << 24); 592116Sjkh} 602116Sjkh#endif 612116Sjkh 622116Sjkhstruct disk * 632116SjkhInt_Open_Disk(const char *name, u_long size) 642116Sjkh{ 652116Sjkh int i,fd; 662116Sjkh struct diskslices ds; 678870Srgrimes struct disklabel dl; 682116Sjkh char device[64], *buf; 692116Sjkh struct disk *d; 702116Sjkh u_long sector_size; 712116Sjkh#ifdef PC98 722116Sjkh unsigned char *p; 732116Sjkh#else 742116Sjkh struct dos_partition *dp; 752116Sjkh void *p; 762116Sjkh#endif 772116Sjkh u_long offset = 0; 782116Sjkh 792116Sjkh strcpy(device, _PATH_DEV); 802116Sjkh strcat(device, name); 812116Sjkh 822116Sjkh d = (struct disk *)malloc(sizeof *d); 832116Sjkh if(!d) return NULL; 842116Sjkh memset(d, 0, sizeof *d); 8597413Salfred 8697413Salfred fd = open(device, O_RDONLY); 872116Sjkh if (fd < 0) { 882116Sjkh#ifdef DEBUG 892116Sjkh warn("open(%s) failed", device); 902116Sjkh#endif 912116Sjkh return 0; 922116Sjkh } 932116Sjkh 942116Sjkh memset(&dl, 0, sizeof dl); 952116Sjkh ioctl(fd, DIOCGDINFO, &dl); 962116Sjkh i = ioctl(fd, DIOCGSLICEINFO, &ds); 972116Sjkh if (i < 0) { 982116Sjkh#ifdef DEBUG 992116Sjkh warn("DIOCGSLICEINFO(%s) failed", device); 1002116Sjkh#endif 1012116Sjkh close(fd); 1022116Sjkh return 0; 1032116Sjkh } 1042116Sjkh 1052116Sjkh#ifdef DEBUG 1062116Sjkh for(i = 0; i < ds.dss_nslices; i++) 1072116Sjkh if(ds.dss_slices[i].ds_openmask) 1082116Sjkh printf(" open(%d)=0x%2x", 1092116Sjkh i, ds.dss_slices[i].ds_openmask); 1102116Sjkh printf("\n"); 1112116Sjkh#endif 1122116Sjkh 1132116Sjkh/* XXX --- ds.dss_slice[WHOLE_DISK_SLICE].ds.size of MO disk is wrong!!! */ 1142116Sjkh#ifdef PC98 1152116Sjkh if (!size) 1162116Sjkh size = dl.d_ncylinders * dl.d_ntracks * dl.d_nsectors; 1172116Sjkh#else 1182116Sjkh if (!size) 1192116Sjkh size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size; 1202116Sjkh#endif 1212116Sjkh 1222116Sjkh /* determine media sector size */ 1232116Sjkh if ((buf = malloc(MAX_SEC_SIZE)) == NULL) 1242116Sjkh return NULL; 1252116Sjkh for (sector_size = MIN_SEC_SIZE; sector_size <= MAX_SEC_SIZE; sector_size *= 2) { 1262116Sjkh if (read(fd, buf, sector_size) == sector_size) { 1272116Sjkh d->sector_size = sector_size; 1282116Sjkh break; 1292116Sjkh } 1302116Sjkh } 1312116Sjkh free (buf); 1322116Sjkh if (sector_size > MAX_SEC_SIZE) 1332116Sjkh return NULL; /* could not determine sector size */ 1342116Sjkh 1352116Sjkh#ifdef PC98 1362116Sjkh p = (unsigned char*)read_block(fd, 1, sector_size); 1372116Sjkh#else 1382116Sjkh p = read_block(fd, 0, sector_size); 1392116Sjkh dp = (struct dos_partition*)(p + DOSPARTOFF); 1402116Sjkh for (i = 0; i < NDOSPART; i++) { 1412116Sjkh if (Read_Int32(&dp->dp_start) >= size) 14297413Salfred continue; 14397413Salfred if (Read_Int32(&dp->dp_start) + Read_Int32(&dp->dp_size) >= size) 1442116Sjkh continue; 1452116Sjkh if (!Read_Int32(&dp->dp_size)) 1462116Sjkh continue; 1472116Sjkh 1482116Sjkh if (dp->dp_typ == DOSPTYP_ONTRACK) { 1492116Sjkh d->flags |= DISK_ON_TRACK; 1502116Sjkh offset = 63; 151141296Sdas } 1522116Sjkh 1532116Sjkh } 1542116Sjkh free(p); 1552116Sjkh#endif 1562116Sjkh 1572116Sjkh d->bios_sect = dl.d_nsectors; 1582116Sjkh d->bios_hd = dl.d_ntracks; 1592116Sjkh 1602116Sjkh d->name = strdup(name); 1612116Sjkh 1622116Sjkh 1632116Sjkh if (dl.d_ntracks && dl.d_nsectors) 1642116Sjkh d->bios_cyl = size / (dl.d_ntracks * dl.d_nsectors); 1652116Sjkh 1662116Sjkh#ifdef PC98 1672116Sjkh if (Add_Chunk(d, -offset, size, name, whole, 0, 0, "-")) 1682116Sjkh#else 1692116Sjkh if (Add_Chunk(d, -offset, size, name, whole, 0, 0)) 1702116Sjkh#endif 1712116Sjkh#ifdef DEBUG 1722116Sjkh warn("Failed to add 'whole' chunk"); 1732116Sjkh#else 1742116Sjkh {} 1752116Sjkh#endif 1762116Sjkh 1772116Sjkh#ifdef __i386__ 1782116Sjkh#ifdef PC98 1792116Sjkh /* XXX -- Quick Hack! 1802116Sjkh * Check MS-DOS MO 181141296Sdas */ 1822116Sjkh if ((*p == 0xf0 || *p == 0xf8) && 1832116Sjkh (*(p+1) == 0xff) && 184141296Sdas (*(p+2) == 0xff)) { 1852116Sjkh Add_Chunk(d, 0, size, name, fat, 0xa0a0, 0, name); 1862116Sjkh free(p); 1872116Sjkh goto pc98_mo_done; 1882116Sjkh } 1892116Sjkh free(p); 1902116Sjkh#endif /* PC98 */ 1912116Sjkh for(i=BASE_SLICE;i<ds.dss_nslices;i++) { 1922116Sjkh char sname[20]; 1932116Sjkh chunk_e ce; 1942116Sjkh u_long flags=0; 1952116Sjkh int subtype=0; 1962116Sjkh 1972116Sjkh if (! ds.dss_slices[i].ds_size) 1982116Sjkh continue; 1992116Sjkh ds.dss_slices[i].ds_offset -= offset; 2002116Sjkh sprintf(sname, "%ss%d", name, i - 1); 2012116Sjkh#ifdef PC98 2022116Sjkh subtype = ds.dss_slices[i].ds_type | 2032116Sjkh ds.dss_slices[i].ds_subtype << 8; 2042116Sjkh switch (ds.dss_slices[i].ds_type & 0x7f) { 2052116Sjkh case 0x14: 2062116Sjkh ce = freebsd; 2072116Sjkh break; 2082116Sjkh case 0x20: 2092116Sjkh case 0x21: 2102116Sjkh case 0x22: 2112116Sjkh case 0x23: 2122116Sjkh case 0x24: 2132116Sjkh ce = fat; 2142116Sjkh break; 2152116Sjkh#else /* IBM-PC */ 2162116Sjkh subtype = ds.dss_slices[i].ds_type; 2172116Sjkh switch (ds.dss_slices[i].ds_type) { 2182116Sjkh case 0xa5: 2192116Sjkh ce = freebsd; 2202116Sjkh break; 2212116Sjkh case 0x1: 2222116Sjkh case 0x6: 2232116Sjkh case 0x4: 2242116Sjkh case 0xb: 2252116Sjkh case 0xc: 2262116Sjkh case 0xe: 2272116Sjkh ce = fat; 2282116Sjkh break; 2292116Sjkh case DOSPTYP_EXTENDED: 2302116Sjkh case 0xf: 2312116Sjkh ce = extended; 2322116Sjkh break; 2332116Sjkh#endif 2342116Sjkh default: 2352116Sjkh ce = unknown; 2362116Sjkh break; 2372116Sjkh } 2382116Sjkh#ifdef PC98 2392116Sjkh if (Add_Chunk(d, ds.dss_slices[i].ds_offset, 2402116Sjkh ds.dss_slices[i].ds_size, sname, ce, subtype, flags, 2412116Sjkh ds.dss_slices[i].ds_name)) 2422116Sjkh#else 2432116Sjkh if (Add_Chunk(d, ds.dss_slices[i].ds_offset, 2442116Sjkh ds.dss_slices[i].ds_size, sname, ce, subtype, flags)) 2452116Sjkh#endif 2462116Sjkh#ifdef DEBUG 2472116Sjkh warn("failed to add chunk for slice %d", i - 1); 2482116Sjkh#else 2492116Sjkh {} 2502116Sjkh#endif 2512116Sjkh 2522116Sjkh#ifdef PC98 2532116Sjkh if ((ds.dss_slices[i].ds_type & 0x7f) != 0x14) 2542116Sjkh#else 2552116Sjkh if (ds.dss_slices[i].ds_type != 0xa5) 2562116Sjkh#endif 2572116Sjkh continue; 2582116Sjkh { 2592116Sjkh struct disklabel dl; 2602116Sjkh char pname[20]; 2612116Sjkh int j, k; 2622116Sjkh 2632116Sjkh strcpy(pname, _PATH_DEV); 2642116Sjkh strcat(pname, sname); 2652116Sjkh j = open(pname, O_RDONLY); 2662116Sjkh if (j < 0) { 2672116Sjkh#ifdef DEBUG 2682116Sjkh warn("open(%s)", pname); 2692116Sjkh#endif 2702116Sjkh continue; 2712116Sjkh } 2722116Sjkh k = ioctl(j, DIOCGDINFO, &dl); 2732116Sjkh if (k < 0) { 2742116Sjkh#ifdef DEBUG 2752116Sjkh warn("ioctl(%s, DIOCGDINFO)", pname); 2762116Sjkh#endif 2772116Sjkh close(j); 2782116Sjkh continue; 2792116Sjkh } 2802116Sjkh close(j); 281141296Sdas 2822116Sjkh for(j = 0; j <= dl.d_npartitions; j++) { 2832116Sjkh if (j == RAW_PART) 2842116Sjkh continue; 2852116Sjkh if (j == 3) 2862116Sjkh continue; 2872116Sjkh if (j == dl.d_npartitions) { 2882116Sjkh j = 3; 2892116Sjkh dl.d_npartitions = 0; 2902116Sjkh } 2912116Sjkh if (!dl.d_partitions[j].p_size) 2922116Sjkh continue; 2932116Sjkh if (dl.d_partitions[j].p_size + 2942116Sjkh dl.d_partitions[j].p_offset > 2952116Sjkh ds.dss_slices[i].ds_size) 2962116Sjkh continue; 2972116Sjkh sprintf(pname, "%s%c", sname, j + 'a'); 2982116Sjkh if (Add_Chunk(d, 2992116Sjkh dl.d_partitions[j].p_offset + 3002116Sjkh ds.dss_slices[i].ds_offset, 3012116Sjkh dl.d_partitions[j].p_size, 3022116Sjkh pname,part, 3032116Sjkh dl.d_partitions[j].p_fstype, 3042116Sjkh#ifdef PC98 3052116Sjkh 0, 3062116Sjkh ds.dss_slices[i].ds_name) && j != 3) 3072116Sjkh#else 3082116Sjkh 0) && j != 3) 3092116Sjkh#endif 3102116Sjkh#ifdef DEBUG 3112116Sjkh warn( 3122116Sjkh "Failed to add chunk for partition %c [%lu,%lu]", 3132116Sjkh j + 'a', dl.d_partitions[j].p_offset, 3142116Sjkh dl.d_partitions[j].p_size); 3152116Sjkh#else 3162116Sjkh {} 3172116Sjkh#endif 3182116Sjkh } 3192116Sjkh } 3202116Sjkh } 3212116Sjkh#endif /* __i386__ */ 3222116Sjkh#ifdef __alpha__ 3232116Sjkh { 3242116Sjkh struct disklabel dl; 3252116Sjkh char pname[20]; 3262116Sjkh int j,k; 3272116Sjkh 3282116Sjkh strcpy(pname, _PATH_DEV); 3292116Sjkh strcat(pname, name); 3302116Sjkh j = open(pname, O_RDONLY); 3312116Sjkh if (j < 0) { 3322116Sjkh#ifdef DEBUG 3332116Sjkh warn("open(%s)", pname); 3342116Sjkh#endif 3352116Sjkh goto nolabel; 3362116Sjkh } 3372116Sjkh k = ioctl(j, DIOCGDINFO, &dl); 3382116Sjkh if (k < 0) { 3392116Sjkh#ifdef DEBUG 3402116Sjkh warn("ioctl(%s, DIOCGDINFO)", pname); 3412116Sjkh#endif 3422116Sjkh close(j); 3432116Sjkh goto nolabel; 3442116Sjkh } 3452116Sjkh close(j); 3462116Sjkh All_FreeBSD(d, 1); 3472116Sjkh 3482116Sjkh for(j = 0; j <= dl.d_npartitions; j++) { 3492116Sjkh if (j == RAW_PART) 3502116Sjkh continue; 3512116Sjkh if (j == 3) 3522116Sjkh continue; 3532116Sjkh if (j == dl.d_npartitions) { 3542116Sjkh j = 3; 3552116Sjkh dl.d_npartitions = 0; 3562116Sjkh } 3572116Sjkh if (!dl.d_partitions[j].p_size) 3582116Sjkh continue; 3592116Sjkh if (dl.d_partitions[j].p_size + 3602116Sjkh dl.d_partitions[j].p_offset > 3612116Sjkh ds.dss_slices[WHOLE_DISK_SLICE].ds_size) 3622116Sjkh continue; 3632116Sjkh sprintf(pname, "%s%c", name, j + 'a'); 3642116Sjkh if (Add_Chunk(d, 3652116Sjkh dl.d_partitions[j].p_offset, 3662116Sjkh dl.d_partitions[j].p_size, 3672116Sjkh pname,part, 3682116Sjkh dl.d_partitions[j].p_fstype, 3692116Sjkh 0) && j != 3) 3702116Sjkh#ifdef DEBUG 3712116Sjkh warn( 3722116Sjkh "Failed to add chunk for partition %c [%lu,%lu]", 3732116Sjkh j + 'a', dl.d_partitions[j].p_offset, 3742116Sjkh dl.d_partitions[j].p_size); 3752116Sjkh#else 3762116Sjkh {} 377#endif 378 } 379 nolabel:; 380 } 381#endif /* __alpha__ */ 382#ifdef PC98 383pc98_mo_done: 384#endif 385 close(fd); 386 Fixup_Names(d); 387 return d; 388} 389 390void 391Debug_Disk(struct disk *d) 392{ 393 printf("Debug_Disk(%s)", d->name); 394 printf(" flags=%lx", d->flags); 395#if 0 396 printf(" real_geom=%lu/%lu/%lu", d->real_cyl, d->real_hd, d->real_sect); 397#endif 398 printf(" bios_geom=%lu/%lu/%lu = %lu\n", 399 d->bios_cyl, d->bios_hd, d->bios_sect, 400 d->bios_cyl * d->bios_hd * d->bios_sect); 401#if defined(PC98) 402 printf(" boot1=%p, boot2=%p, bootipl=%p, bootmenu=%p\n", 403 d->boot1, d->boot2, d->bootipl, d->bootmenu); 404#elif defined(__i386__) 405 printf(" boot1=%p, boot2=%p, bootmgr=%p\n", 406 d->boot1, d->boot2, d->bootmgr); 407#elif defined(__alpha__) 408 printf(" boot1=%p, bootmgr=%p\n", 409 d->boot1, d->bootmgr); 410#endif 411 Debug_Chunk(d->chunks); 412} 413 414void 415Free_Disk(struct disk *d) 416{ 417 if(d->chunks) Free_Chunk(d->chunks); 418 if(d->name) free(d->name); 419#ifdef PC98 420 if(d->bootipl) free(d->bootipl); 421 if(d->bootmenu) free(d->bootmenu); 422#else 423 if(d->bootmgr) free(d->bootmgr); 424#endif 425 if(d->boot1) free(d->boot1); 426#if defined(__i386__) 427 if(d->boot2) free(d->boot2); 428#endif 429 free(d); 430} 431 432struct disk * 433Clone_Disk(struct disk *d) 434{ 435 struct disk *d2; 436 437 d2 = (struct disk*) malloc(sizeof *d2); 438 if(!d2) return NULL; 439 *d2 = *d; 440 d2->name = strdup(d2->name); 441 d2->chunks = Clone_Chunk(d2->chunks); 442#ifdef PC98 443 if(d2->bootipl) { 444 d2->bootipl = malloc(d2->bootipl_size); 445 memcpy(d2->bootipl, d->bootipl, d2->bootipl_size); 446 } 447 if(d2->bootmenu) { 448 d2->bootmenu = malloc(d2->bootmenu_size); 449 memcpy(d2->bootmenu, d->bootmenu, d2->bootmenu_size); 450 } 451#else 452 if(d2->bootmgr) { 453 d2->bootmgr = malloc(d2->bootmgr_size); 454 memcpy(d2->bootmgr, d->bootmgr, d2->bootmgr_size); 455 } 456#endif 457#if defined(__i386__) 458 if(d2->boot1) { 459 d2->boot1 = malloc(512); 460 memcpy(d2->boot1, d->boot1, 512); 461 } 462 if(d2->boot2) { 463 d2->boot2 = malloc(512 * 15); 464 memcpy(d2->boot2, d->boot2, 512 * 15); 465 } 466#elif defined(__alpha__) 467 if(d2->boot1) { 468 d2->boot1 = malloc(512 * 15); 469 memcpy(d2->boot1, d->boot1, 512 * 15); 470 } 471#endif 472 return d2; 473} 474 475#if 0 476void 477Collapse_Disk(struct disk *d) 478{ 479 480 while(Collapse_Chunk(d, d->chunks)) 481 ; 482} 483#endif 484 485#ifdef PC98 486static char * device_list[] = {"wd", "aacd", "ad", "da", "afd", "fla", "idad", "mlxd", "amrd", "twed", "ar", "fd", 0}; 487#else 488static char * device_list[] = {"aacd", "ad", "da", "afd", "fla", "idad", "mlxd", "amrd", "twed", "ar", "fd", 0}; 489#endif 490 491int qstrcmp(const void* a, const void* b) { 492 493 char *str1 = *(char**)a; 494 char *str2 = *(char**)b; 495 return strcmp(str1, str2); 496 497} 498 499char ** 500Disk_Names() 501{ 502 int i,j,disk_cnt; 503 char disk[25]; 504 char diskname[25]; 505 struct stat st; 506 struct diskslices ds; 507 int fd; 508 static char **disks; 509 int error; 510 size_t listsize; 511 char *disklist, **dp; 512 513 disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS)); 514 memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS)); 515 error = sysctlbyname("kern.disks", NULL, &listsize, NULL, 0); 516 if (!error) { 517 disklist = (char *)malloc(listsize); 518 error = sysctlbyname("kern.disks", disklist, &listsize, NULL, 0); 519 if (error) 520 return NULL; 521 disk_cnt = 0; 522 for (dp = disks; ((*dp = strsep(&disklist, " ")) != NULL) && 523 disk_cnt < MAX_NO_DISKS; disk_cnt++, dp++); 524 } else { 525 warn("kern.disks sysctl not available"); 526 disk_cnt = 0; 527 for (j = 0; device_list[j]; j++) { 528 if(disk_cnt >= MAX_NO_DISKS) 529 break; 530 for (i = 0; i < MAX_NO_DISKS; i++) { 531 sprintf(diskname, "%s%d", device_list[j], i); 532 sprintf(disk, _PATH_DEV"%s", diskname); 533 if (stat(disk, &st) || !(st.st_mode & S_IFCHR)) 534 continue; 535 if ((fd = open(disk, O_RDWR)) == -1) 536 continue; 537 if (ioctl(fd, DIOCGSLICEINFO, &ds) == -1) { 538#ifdef DEBUG 539 warn("DIOCGSLICEINFO %s", disk); 540#endif 541 close(fd); 542 continue; 543 } 544 close(fd); 545 disks[disk_cnt++] = strdup(diskname); 546 if(disk_cnt >= MAX_NO_DISKS) 547 break; 548 } 549 } 550 } 551 qsort(disks, disk_cnt, sizeof(char*), qstrcmp); 552 553 return disks; 554} 555 556#ifdef PC98 557void 558Set_Boot_Mgr(struct disk *d, const u_char *bootipl, const size_t bootipl_size, 559 const u_char *bootmenu, const size_t bootmenu_size) 560#else 561void 562Set_Boot_Mgr(struct disk *d, const u_char *b, const size_t s) 563#endif 564{ 565#ifdef PC98 566 if (bootipl_size % d->sector_size != 0) 567 return; 568 if (d->bootipl) 569 free(d->bootipl); 570 if (!bootipl) { 571 d->bootipl = NULL; 572 } else { 573 d->bootipl_size = bootipl_size; 574 d->bootipl = malloc(bootipl_size); 575 if(!d->bootipl) return; 576 memcpy(d->bootipl, bootipl, bootipl_size); 577 } 578 579 if (bootmenu_size % d->sector_size != 0) 580 return; 581 if (d->bootmenu) 582 free(d->bootmenu); 583 if (!bootmenu) { 584 d->bootmenu = NULL; 585 } else { 586 d->bootmenu_size = bootmenu_size; 587 d->bootmenu = malloc(bootmenu_size); 588 if(!d->bootmenu) return; 589 memcpy(d->bootmenu, bootmenu, bootmenu_size); 590 } 591#else 592 if (s % d->sector_size != 0) 593 return; 594 if (d->bootmgr) 595 free(d->bootmgr); 596 if (!b) { 597 d->bootmgr = NULL; 598 } else { 599 d->bootmgr_size = s; 600 d->bootmgr = malloc(s); 601 if(!d->bootmgr) return; 602 memcpy(d->bootmgr, b, s); 603 } 604#endif 605} 606 607int 608Set_Boot_Blocks(struct disk *d, const u_char *b1, const u_char *b2) 609{ 610#if defined(__i386__) 611 if (d->boot1) free(d->boot1); 612 d->boot1 = malloc(512); 613 if(!d->boot1) return -1; 614 memcpy(d->boot1, b1, 512); 615 if (d->boot2) free(d->boot2); 616 d->boot2 = malloc(15 * 512); 617 if(!d->boot2) return -1; 618 memcpy(d->boot2, b2, 15 * 512); 619#elif defined(__alpha__) 620 if (d->boot1) free(d->boot1); 621 d->boot1 = malloc(15 * 512); 622 if(!d->boot1) return -1; 623 memcpy(d->boot1, b1, 15 * 512); 624#endif 625 return 0; 626} 627 628const char * 629slice_type_name( int type, int subtype ) 630{ 631 switch (type) { 632 case 0: return "whole"; 633#ifndef PC98 634 case 1: switch (subtype) { 635 case 1: return "fat (12-bit)"; 636 case 2: return "XENIX /"; 637 case 3: return "XENIX /usr"; 638 case 4: return "fat (16-bit,<=32Mb)"; 639 case 5: return "extended DOS"; 640 case 6: return "fat (16-bit,>32Mb)"; 641 case 7: return "NTFS/HPFS/QNX"; 642 case 8: return "AIX bootable"; 643 case 9: return "AIX data"; 644 case 10: return "OS/2 bootmgr"; 645 case 11: return "fat (32-bit)"; 646 case 12: return "fat (32-bit,LBA)"; 647 case 14: return "fat (16-bit,>32Mb,LBA)"; 648 case 15: return "extended DOS, LBA"; 649 case 18: return "Compaq Diagnostic"; 650 case 84: return "OnTrack diskmgr"; 651 case 100: return "Netware 2.x"; 652 case 101: return "Netware 3.x"; 653 case 115: return "SCO UnixWare"; 654 case 128: return "Minix 1.1"; 655 case 129: return "Minix 1.5"; 656 case 130: return "linux_swap"; 657 case 131: return "ext2fs"; 658 case 166: return "OpenBSD FFS"; /* 0xA6 */ 659 case 169: return "NetBSD FFS"; /* 0xA9 */ 660 case 182: return "OpenBSD"; /* dedicated */ 661 case 183: return "bsd/os"; 662 case 184: return "bsd/os swap"; 663 case 238: return "EFI GPT"; 664 case 239: return "EFI Sys. Part."; 665 default: return "unknown"; 666 } 667#endif 668 case 2: return "fat"; 669 case 3: switch (subtype) { 670#ifdef PC98 671 case 0xc494: return "freebsd"; 672#else 673 case 165: return "freebsd"; 674#endif 675 default: return "unknown"; 676 } 677#ifndef PC98 678 case 4: return "extended"; 679 case 5: return "part"; 680 case 6: return "unused"; 681#endif 682 default: return "unknown"; 683 } 684} 685