With the old sade removed, libdisk is no longer used by anything in HEAD

and uses a number of problematic pre-gpart interfaces. Since it has been
entirely obsoleted by interfaces in geom, remove it.
This commit is contained in:
Nathan Whitehorn 2012-12-30 16:28:06 +00:00
parent c3761c3848
commit c857d06af7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=244865
24 changed files with 3 additions and 4756 deletions

View File

@ -38,6 +38,9 @@
# xargs -n1 | sort | uniq -d;
# done
# 20121230: libdisk removed
OLD_FILES+=usr/share/man/man3/libdisk.3.gz usr/include/libdisk.h
OLD_FILES+=usr/lib/libdisk.a usr/lib32/libdisk.a
# 20121230: remove wrongly created directories for auditdistd
OLD_DIRS+=var/dist
OLD_DIRS+=var/remote

View File

@ -69,7 +69,6 @@ SUBDIR= ${SUBDIR_ORDERED} \
libcompat \
libdevinfo \
libdevstat \
libdisk \
libdwarf \
libedit \
${_libefi} \

View File

@ -1,43 +0,0 @@
# $FreeBSD$
.if ${MACHINE_CPUARCH} == "ia64"
_open_disk= open_ia64_disk.c
.else
_change = change.c
_open_disk= open_disk.c
.endif
LIB= disk
SRCS= blocks.c ${_change} chunk.c create_chunk.c disk.c ${_open_disk} \
rules.c write_disk.c
SRCS+= write_${MACHINE}_disk.c
INCS= libdisk.h
WARNS?= 2
CFLAGS+= -I${.CURDIR}/../../sys/geom
.if ${MACHINE} == "pc98"
CFLAGS+= -DPC98
.endif
CLEANFILES+= tmp.c tst01 tst01.o
NO_PROFILE=
NO_PIC=
MAN= libdisk.3
.include <bsd.lib.mk>
tst01: tst01.o libdisk.a
cc ${CFLAGS} -static tst01.o -o tst01 libdisk.a
ad0: all install tst01
./tst01 ad0
da0: all install tst01
./tst01 da0
da1: all install tst01
./tst01 da1

View File

@ -1,50 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "libdisk.h"
void *
read_block(int fd, daddr_t block, u_long sector_size)
{
void *foo;
int i;
foo = malloc(sector_size);
if (foo == NULL)
return (NULL);
if (-1 == lseek(fd, (off_t)block * sector_size, SEEK_SET)) {
free (foo);
return (NULL);
}
i = read(fd, foo, sector_size);
if ((int)sector_size != i) {
free (foo);
return (NULL);
}
return foo;
}
int
write_block(int fd, daddr_t block, const void *foo, u_long sector_size)
{
int i;
if (-1 == lseek(fd, (off_t)block * sector_size, SEEK_SET))
return (-1);
i = write(fd, foo, sector_size);
if ((int)sector_size != i)
return (-1);
return 0;
}

View File

@ -1,129 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include "libdisk.h"
void
Set_Bios_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect)
{
disk->bios_cyl = cyl;
disk->bios_hd = hd;
disk->bios_sect = sect;
}
void
Sanitize_Bios_Geom(struct disk *disk)
{
int sane;
sane = 1;
if (disk->bios_cyl >= 65536)
sane = 0;
#ifdef PC98
if (disk->bios_hd >= 256)
sane = 0;
if (disk->bios_sect >= 256)
sane = 0;
#else
if (disk->bios_hd > 256)
sane = 0;
if (disk->bios_sect > 63)
sane = 0;
#endif
#if 0 /* Disable a check on a disk size. It's too strict. */
if (disk->bios_cyl * disk->bios_hd * disk->bios_sect !=
disk->chunks->size)
sane = 0;
#endif
if (sane)
return;
/* First try something that IDE can handle */
disk->bios_sect = 63;
disk->bios_hd = 16;
disk->bios_cyl = disk->chunks->size /
(disk->bios_sect * disk->bios_hd);
#ifdef PC98
if (disk->bios_cyl < 65536)
#else
if (disk->bios_cyl < 1024)
#endif
return;
/* Hmm, try harder... */
/* Assume standard SCSI parameter */
#ifdef PC98
disk->bios_sect = 128;
disk->bios_hd = 8;
#else
disk->bios_hd = 255;
#endif
disk->bios_cyl = disk->chunks->size /
(disk->bios_sect * disk->bios_hd);
#ifdef PC98
if (disk->bios_cyl < 65536)
return;
/* Assume UIDE-133/98-A Challenger BIOS 0.9821C parameter */
disk->bios_sect = 255;
disk->bios_hd = 16;
disk->bios_cyl = disk->chunks->size /
(disk->bios_sect * disk->bios_hd);
if (disk->bios_cyl < 65536)
return;
/* BIG-na-Drive? */
disk->bios_hd = 255;
disk->bios_cyl = disk->chunks->size /
(disk->bios_sect * disk->bios_hd);
#endif
}
void
All_FreeBSD(struct disk *d, int force_all)
{
struct chunk *c;
int type;
#ifdef PC98
type = 0xc494;
#else
type = 0xa5;
#endif
again:
for (c = d->chunks->part; c; c = c->next)
if (c->type != unused) {
Delete_Chunk(d, c);
goto again;
}
c = d->chunks;
if (force_all) {
Sanitize_Bios_Geom(d);
Create_Chunk(d, c->offset, c->size, freebsd, type,
CHUNK_FORCE_ALL, "FreeBSD");
} else {
Create_Chunk(d, c->offset, c->size, freebsd, type, 0,
"FreeBSD");
}
}

View File

@ -1,595 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include "libdisk.h"
struct chunk *
New_Chunk(void)
{
struct chunk *c;
c = malloc(sizeof *c);
if (c != NULL)
memset(c, 0, sizeof *c);
return (c);
}
/* Is c2 completely inside c1 ? */
static int
Chunk_Inside(const struct chunk *c1, const struct chunk *c2)
{
/* if c1 ends before c2 do */
if (c1->end < c2->end)
return 0;
/* if c1 starts after c2 do */
if (c1->offset > c2->offset)
return 0;
return 1;
}
static struct chunk *
Find_Mother_Chunk(struct chunk *chunks, daddr_t offset, daddr_t end,
chunk_e type)
{
struct chunk *c1, *c2, ct;
ct.offset = offset;
ct.end = end;
switch (type) {
case whole:
if (Chunk_Inside(chunks, &ct))
return chunks;
case extended:
for (c1 = chunks->part; c1; c1 = c1->next) {
if (c1->type != type)
continue;
if (Chunk_Inside(c1, &ct))
return c1;
}
return 0;
case freebsd:
for (c1 = chunks->part; c1; c1 = c1->next) {
if (c1->type == type)
if (Chunk_Inside(c1, &ct))
return c1;
if (c1->type != extended)
continue;
for (c2 = c1->part; c2; c2 = c2->next)
if (c2->type == type && Chunk_Inside(c2, &ct))
return c2;
}
return 0;
#ifdef __powerpc__
case apple:
for (c1 = chunks->part; c1; c1 = c1->next) {
if (c1->type == type)
if (Chunk_Inside(c1, &ct))
return c1;
}
return 0;
#endif
default:
warn("Unsupported mother type in Find_Mother_Chunk");
return 0;
}
}
void
Free_Chunk(struct chunk *c1)
{
if(c1 == NULL)
return;
if(c1->private_data && c1->private_free)
(*c1->private_free)(c1->private_data);
if(c1->part != NULL)
Free_Chunk(c1->part);
if(c1->next != NULL)
Free_Chunk(c1->next);
if (c1->name != NULL)
free(c1->name);
if (c1->sname != NULL)
free(c1->sname);
free(c1);
}
struct chunk *
Clone_Chunk(const struct chunk *c1)
{
struct chunk *c2;
if(!c1)
return NULL;
c2 = New_Chunk();
if (c2 == NULL)
return NULL;
*c2 = *c1;
if (c1->private_data && c1->private_clone)
c2->private_data = c2->private_clone(c2->private_data);
c2->name = strdup(c2->name);
if (c2->sname != NULL)
c2->sname = strdup(c2->sname);
c2->next = Clone_Chunk(c2->next);
c2->part = Clone_Chunk(c2->part);
return c2;
}
int
Insert_Chunk(struct chunk *c2, daddr_t offset, daddr_t size, const char *name,
chunk_e type, int subtype, u_long flags, const char *sname)
{
struct chunk *ct,*cs;
/* We will only insert into empty spaces */
if (c2->type != unused)
return __LINE__;
ct = New_Chunk();
if (ct == NULL)
return __LINE__;
ct->disk = c2->disk;
ct->offset = offset;
ct->size = size;
ct->end = offset + size - 1;
ct->type = type;
if (sname != NULL)
ct->sname = strdup(sname);
ct->name = strdup(name);
ct->subtype = subtype;
ct->flags = flags;
if (!Chunk_Inside(c2, ct)) {
Free_Chunk(ct);
return __LINE__;
}
if ((type == freebsd || type == extended || type == apple)) {
cs = New_Chunk();
if (cs == NULL)
return __LINE__;
cs->disk = c2->disk;
cs->offset = offset;
cs->size = size;
cs->end = offset + size - 1;
cs->type = unused;
if (sname != NULL)
cs->sname = strdup(sname);
cs->name = strdup("-");
ct->part = cs;
}
/* Make a new chunk for any trailing unused space */
if (c2->end > ct->end) {
cs = New_Chunk();
if (cs == NULL)
return __LINE__;
*cs = *c2;
cs->disk = c2->disk;
cs->offset = ct->end + 1;
cs->size = c2->end - ct->end;
if (c2->sname != NULL)
cs->sname = strdup(c2->sname);
if (c2->name)
cs->name = strdup(c2->name);
c2->next = cs;
c2->size -= c2->end - ct->end;
c2->end = ct->end;
}
/* If no leading unused space just occupy the old chunk */
if (c2->offset == ct->offset) {
c2->sname = ct->sname;
c2->name = ct->name;
c2->type = ct->type;
c2->part = ct->part;
c2->subtype = ct->subtype;
c2->flags = ct->flags;
ct->sname = NULL;
ct->name = NULL;
ct->part = 0;
Free_Chunk(ct);
return 0;
}
/* else insert new chunk and adjust old one */
c2->end = ct->offset - 1;
c2->size -= ct->size;
ct->next = c2->next;
c2->next = ct;
return 0;
}
int
Add_Chunk(struct disk *d, daddr_t offset, daddr_t size, const char *name,
chunk_e type, int subtype, u_long flags, const char *sname)
{
struct chunk *c1, *c2, ct;
daddr_t end = offset + size - 1;
ct.offset = offset;
ct.end = end;
ct.size = size;
if (type == whole) {
d->chunks = c1 = New_Chunk();
if (c1 == NULL)
return __LINE__;
c2 = c1->part = New_Chunk();
if (c2 == NULL)
return __LINE__;
c2->disk = c1->disk = d;
c2->offset = c1->offset = offset;
c2->size = c1->size = size;
c2->end = c1->end = end;
c1->sname = strdup(sname);
c2->sname = strdup("-");
c1->name = strdup(name);
c2->name = strdup("-");
c1->type = type;
c2->type = unused;
c1->flags = flags;
c1->subtype = subtype;
return 0;
}
c1 = 0;
/* PLATFORM POLICY BEGIN ------------------------------------- */
switch(platform) {
case p_i386:
case p_amd64:
switch (type) {
case fat:
case gpt:
case mbr:
case extended:
case freebsd:
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
break;
case part:
c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
break;
default:
return(-1);
}
break;
case p_ia64:
switch (type) {
case freebsd:
subtype = 0xa5;
/* FALL THROUGH */
case fat:
case efi:
case mbr:
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
break;
case part:
c1 = Find_Mother_Chunk(d->chunks, offset, end,
freebsd);
if (!c1)
c1 = Find_Mother_Chunk(d->chunks, offset, end,
whole);
break;
default:
return (-1);
}
break;
case p_pc98:
switch (type) {
case fat:
case pc98:
case freebsd:
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
break;
case part:
c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
break;
default:
return(-1);
}
break;
case p_sparc64:
case p_alpha:
switch (type) {
case freebsd:
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
break;
case part:
c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
break;
default:
return(-1);
}
break;
case p_ppc:
switch (type) {
case apple:
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
break;
case part:
c1 = Find_Mother_Chunk(d->chunks, offset, end, apple);
break;
default:
return (-1);
}
break;
default:
return (-1);
}
/* PLATFORM POLICY END ---------------------------------------- */
if(!c1)
return __LINE__;
for(c2 = c1->part; c2; c2 = c2->next) {
if (c2->type != unused)
continue;
if(!Chunk_Inside(c2, &ct))
continue;
/* PLATFORM POLICY BEGIN ------------------------------------- */
if (platform == p_sparc64) {
offset = Prev_Cyl_Aligned(d, offset);
size = Next_Cyl_Aligned(d, size);
} else if (platform == p_i386 || platform == p_pc98 ||
platform == p_amd64) {
if (type != freebsd)
break;
if (!(flags & CHUNK_ALIGN))
break;
if (offset == d->chunks->offset &&
end == d->chunks->end)
break;
/* Round down to prev cylinder */
offset = Prev_Cyl_Aligned(d,offset);
/* Stay inside the parent */
if (offset < c2->offset)
offset = c2->offset;
/* Round up to next cylinder */
offset = Next_Cyl_Aligned(d, offset);
/* Keep one track clear in front of parent */
if (offset == c1->offset)
offset = Next_Track_Aligned(d, offset + 1);
/* Work on the (end+1) */
size += offset;
/* Round up to cylinder */
size = Next_Cyl_Aligned(d, size);
/* Stay inside parent */
if ((size-1) > c2->end)
size = c2->end + 1;
/* Round down to cylinder */
size = Prev_Cyl_Aligned(d, size);
/* Convert back to size */
size -= offset;
}
break;
/* PLATFORM POLICY END ------------------------------------- */
}
if (c2 == NULL)
return (__LINE__);
return Insert_Chunk(c2, offset, size, name, type, subtype, flags,
sname);
}
char *
ShowChunkFlags(struct chunk *c)
{
static char ret[10];
int i = 0;
if (c->flags & CHUNK_ACTIVE)
ret[i++] = 'A';
if (c->flags & CHUNK_ALIGN)
ret[i++] = '=';
if (c->flags & CHUNK_IS_ROOT)
ret[i++] = 'R';
ret[i++] = '\0';
return ret;
}
static void
Print_Chunk(struct chunk *c1, int offset)
{
int i;
if (!c1)
return;
for (i = 0; i < offset - 2; i++)
putchar(' ');
for (; i < offset; i++)
putchar('-');
putchar('>');
for (; i < 10; i++)
putchar(' ');
#ifndef __ia64__
printf("%p ", c1);
#endif
printf("%8jd %8jd %8jd %-8s %-16s %-8s 0x%02x %s",
(intmax_t)c1->offset, (intmax_t)c1->size, (intmax_t)c1->end,
c1->name, c1->sname, chunk_name(c1->type), c1->subtype,
ShowChunkFlags(c1));
putchar('\n');
Print_Chunk(c1->part, offset + 2);
Print_Chunk(c1->next, offset);
}
void
Debug_Chunk(struct chunk *c1)
{
Print_Chunk(c1, 2);
}
int
Delete_Chunk(struct disk *d, struct chunk *c)
{
return (Delete_Chunk2(d, c, 0));
}
int
Delete_Chunk2(struct disk *d, struct chunk *c, int rflags)
{
struct chunk *c1, *c2, *c3;
daddr_t offset = c->offset;
switch (c->type) {
case whole:
case unused:
return 1;
case extended:
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, whole);
break;
case part:
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, freebsd);
#ifdef __ia64__
if (c1 == NULL)
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
whole);
#endif
#ifdef __powerpc__
if (c1 == NULL)
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
apple);
#endif
break;
default:
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, extended);
if (c1 == NULL)
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
whole);
break;
}
if (c1 == NULL)
return 1;
for (c2 = c1->part; c2; c2 = c2->next) {
if (c2 == c) {
c2->type = unused;
c2->subtype = 0;
c2->flags = 0;
if (c2->sname != NULL)
free(c2->sname);
c2->sname = strdup("-");
free(c2->name);
c2->name = strdup("-");
Free_Chunk(c2->part);
c2->part =0;
goto scan;
}
}
return 1;
scan:
/*
* Collapse multiple unused elements together, and attempt
* to extend the previous chunk into the freed chunk.
*
* We only extend non-unused elements which are marked
* for newfs (we can't extend working filesystems), and
* only if we are called with DELCHUNK_RECOVER.
*/
for (c2 = c1->part; c2; c2 = c2->next) {
if (c2->type != unused) {
if (c2->offset + c2->size != offset ||
(rflags & DELCHUNK_RECOVER) == 0 ||
(c2->flags & CHUNK_NEWFS) == 0) {
continue;
}
/* else extend into free area */
}
if (!c2->next)
continue;
if (c2->next->type != unused)
continue;
c3 = c2->next;
c2->size += c3->size;
c2->end = c3->end;
c2->next = c3->next;
c3->next = 0;
Free_Chunk(c3);
goto scan;
}
Fixup_Names(d);
return 0;
}
#if 0
int
Collapse_Chunk(struct disk *d, struct chunk *c1)
{
struct chunk *c2, *c3;
if (c1->next && Collapse_Chunk(d, c1->next))
return 1;
if (c1->type == unused && c1->next && c1->next->type == unused) {
c3 = c1->next;
c1->size += c3->size;
c1->end = c3->end;
c1->next = c3->next;
c3->next = 0;
Free_Chunk(c3);
return 1;
}
c3 = c1->part;
if (!c3)
return 0;
if (Collapse_Chunk(d, c1->part))
return 1;
if (c1->type == whole)
return 0;
if (c3->type == unused && c3->size == c1->size) {
Delete_Chunk(d, c1);
return 1;
}
if (c3->type == unused) {
c2 = New_Chunk();
if (c2 == NULL)
barfout(1, "malloc failed");
*c2 = *c1;
c1->next = c2;
c1->disk = d;
c1->sname = strdup("-");
c1->name = strdup("-");
c1->part = 0;
c1->type = unused;
c1->flags = 0;
c1->subtype = 0;
c1->size = c3->size;
c1->end = c3->end;
c2->offset += c1->size;
c2->size -= c1->size;
c2->part = c3->next;
c3->next = 0;
Free_Chunk(c3);
return 1;
}
for (c2 = c3; c2->next; c2 = c2->next)
c3 = c2;
if (c2 && c2->type == unused) {
c3->next = 0;
c2->next = c1->next;
c1->next = c2;
c1->size -= c2->size;
c1->end -= c2->size;
return 1;
}
return 0;
}
#endif

View File

@ -1,296 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/param.h>
#include <sys/disklabel.h>
#ifdef PC98
#include <sys/diskpc98.h>
#else
#include <sys/diskmbr.h>
#endif
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <grp.h>
#include <paths.h>
#include <pwd.h>
#include "libdisk.h"
static int
Fixup_FreeBSD_Names(struct chunk *c)
{
struct chunk *c1, *c3;
uint j;
if (!strcmp(c->name, "X"))
return 0;
/* reset all names to "X" */
for (c1 = c->part; c1; c1 = c1->next) {
c1->oname = c1->name;
c1->name = malloc(12);
if (!c1->name)
return -1;
strcpy(c1->name,"X");
}
/* Allocate the first swap-partition we find */
for (c1 = c->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
if (c1->subtype != FS_SWAP)
continue;
sprintf(c1->name, "%s%c", c->name, SWAP_PART + 'a');
break;
}
/* Allocate the first root-partition we find */
for (c1 = c->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
if (!(c1->flags & CHUNK_IS_ROOT))
continue;
sprintf(c1->name, "%s%c", c->name, 0 + 'a');
break;
}
/* Try to give them the same as they had before */
for (c1 = c->part; c1; c1 = c1->next) {
if (strcmp(c1->name, "X"))
continue;
for (c3 = c->part; c3 ; c3 = c3->next)
if (c1 != c3 && !strcmp(c3->name, c1->oname))
goto newname;
strcpy(c1->name, c1->oname);
newname:
;
}
/* Allocate the rest sequentially */
for (c1 = c->part; c1; c1 = c1->next) {
const char order[] = "defghab";
if (c1->type == unused)
continue;
if (strcmp("X", c1->name))
continue;
for (j = 0; j < strlen(order); j++) {
sprintf(c1->name, "%s%c", c->name, order[j]);
for (c3 = c->part; c3 ; c3 = c3->next)
if (c1 != c3 && !strcmp(c3->name, c1->name))
goto match;
break;
match:
strcpy(c1->name, "X");
continue;
}
}
for (c1 = c->part; c1; c1 = c1->next) {
free(c1->oname);
c1->oname = 0;
}
return 0;
}
#ifndef PC98
static int
Fixup_Extended_Names(struct chunk *c)
{
struct chunk *c1;
int j = 5;
for (c1 = c->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
free(c1->name);
c1->name = malloc(12);
if (!c1->name)
return -1;
sprintf(c1->name, "%ss%d", c->disk->chunks->name, j++);
if (c1->type == freebsd)
if (Fixup_FreeBSD_Names(c1) != 0)
return -1;
}
return 0;
}
#endif
#ifdef __powerpc__
static int
Fixup_Apple_Names(struct chunk *c)
{
struct chunk *c1;
for (c1 = c->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
free(c1->name);
c1->name = strdup(c->name);
if (!c1->name)
return (-1);
}
return 0;
}
#endif
int
Fixup_Names(struct disk *d)
{
struct chunk *c1, *c2;
#if defined(__i386__) || defined(__ia64__) || defined(__amd64__)
struct chunk *c3;
int j, max;
#endif
c1 = d->chunks;
for (c2 = c1->part; c2 ; c2 = c2->next) {
if (c2->type == unused)
continue;
if (strcmp(c2->name, "X"))
continue;
#if defined(__i386__) || defined(__ia64__) || defined(__amd64__)
c2->oname = malloc(12);
if (!c2->oname)
return -1;
#ifdef __ia64__
max = d->gpt_size;
#else
max = NDOSPART;
#endif
for (j = 1; j <= max; j++) {
#ifdef __ia64__
sprintf(c2->oname, "%s%c%d", c1->name,
(c1->type == whole) ? 'p' : 's', j);
#else
sprintf(c2->oname, "%ss%d", c1->name, j);
#endif
for (c3 = c1->part; c3; c3 = c3->next)
if (c3 != c2 && !strcmp(c3->name, c2->oname))
goto match;
free(c2->name);
c2->name = c2->oname;
c2->oname = 0;
break;
match:
continue;
}
if (c2->oname)
free(c2->oname);
#else
free(c2->name);
c2->name = strdup(c1->name);
#endif /*__i386__*/
}
for (c2 = c1->part; c2; c2 = c2->next) {
if (c2->type == freebsd)
Fixup_FreeBSD_Names(c2);
#ifdef __powerpc__
else if (c2->type == apple)
Fixup_Apple_Names(c2);
#endif
#ifndef PC98
else if (c2->type == extended)
Fixup_Extended_Names(c2);
#endif
}
return 0;
}
int
Create_Chunk(struct disk *d, daddr_t offset, daddr_t size, chunk_e type,
int subtype, u_long flags, const char *sname)
{
int i;
#ifndef __ia64__
if (!(flags & CHUNK_FORCE_ALL)) {
daddr_t l;
#ifdef PC98
/* Never use the first cylinder */
if (!offset) {
offset += (d->bios_sect * d->bios_hd);
size -= (d->bios_sect * d->bios_hd);
}
#else
/* Never use the first track */
if (!offset) {
offset += d->bios_sect;
size -= d->bios_sect;
}
#endif /* PC98 */
/* Always end on cylinder boundary */
l = (offset + size) % (d->bios_sect * d->bios_hd);
size -= l;
}
#endif
i = Add_Chunk(d, offset, size, "X", type, subtype, flags, sname);
Fixup_Names(d);
return i;
}
struct chunk *
Create_Chunk_DWIM(struct disk *d, struct chunk *parent, daddr_t size,
chunk_e type, int subtype, u_long flags)
{
int i;
struct chunk *c1;
daddr_t offset;
if (!parent)
parent = d->chunks;
if ((parent->type == freebsd && type == part && parent->part == NULL)
|| (parent->type == apple && type == part && parent->part == NULL)) {
c1 = New_Chunk();
if (c1 == NULL)
return (NULL);
c1->disk = parent->disk;
c1->offset = parent->offset;
c1->size = parent->size;
c1->end = parent->offset + parent->size - 1;
c1->type = unused;
if (parent->sname != NULL)
c1->sname = strdup(parent->sname);
c1->name = strdup("-");
parent->part = c1;
}
for (c1 = parent->part; c1; c1 = c1->next) {
if (c1->type != unused)
continue;
if (c1->size < size)
continue;
offset = c1->offset;
goto found;
}
return 0;
found:
i = Add_Chunk(d, offset, size, "X", type, subtype, flags, "-");
if (i)
return 0;
Fixup_Names(d);
for (c1 = parent->part; c1; c1 = c1->next)
if (c1->offset == offset)
return c1;
/* barfout(1, "Serious internal trouble"); */
return 0;
}

View File

@ -1,411 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <inttypes.h>
#include <err.h>
#include <sys/sysctl.h>
#include <sys/stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <sys/uuid.h>
#include <sys/gpt.h>
#include <paths.h>
#include "libdisk.h"
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <uuid.h>
const enum platform platform =
#if defined (P_DEBUG)
P_DEBUG
#elif defined (PC98)
p_pc98
#elif defined(__i386__)
p_i386
#elif defined(__alpha__)
p_alpha
#elif defined(__sparc64__)
p_sparc64
#elif defined(__ia64__)
p_ia64
#elif defined(__ppc__)
p_ppc
#elif defined(__amd64__)
p_amd64
#elif defined(__arm__)
p_arm
#elif defined(__mips__)
p_mips
#else
IHAVENOIDEA
#endif
;
const char *
chunk_name(chunk_e type)
{
switch(type) {
case unused: return ("unused");
case mbr: return ("mbr");
case part: return ("part");
case gpt: return ("gpt");
case pc98: return ("pc98");
case sun: return ("sun");
case freebsd: return ("freebsd");
case fat: return ("fat");
case spare: return ("spare");
case efi: return ("efi");
case apple: return ("apple");
default: return ("??");
}
}
struct disk *
Open_Disk(const char *name)
{
struct disk *d;
char *conftxt;
size_t txtsize;
int error;
error = sysctlbyname("kern.geom.conftxt", NULL, &txtsize, NULL, 0);
if (error) {
warn("kern.geom.conftxt sysctl not available, giving up!");
return (NULL);
}
conftxt = malloc(txtsize+1);
if (conftxt == NULL) {
warn("cannot malloc memory for conftxt");
return (NULL);
}
error = sysctlbyname("kern.geom.conftxt", conftxt, &txtsize, NULL, 0);
if (error) {
warn("error reading kern.geom.conftxt from the system");
free(conftxt);
return (NULL);
}
conftxt[txtsize] = '\0'; /* in case kernel bug is still there */
d = Int_Open_Disk(name, conftxt);
free(conftxt);
return (d);
}
void
Debug_Disk(struct disk *d)
{
printf("Debug_Disk(%s)", d->name);
#ifndef __ia64__
printf(" bios_geom=%lu/%lu/%lu = %lu\n",
d->bios_cyl, d->bios_hd, d->bios_sect,
d->bios_cyl * d->bios_hd * d->bios_sect);
#if defined(PC98)
printf(" boot1=%p, boot2=%p, bootipl=%p, bootmenu=%p\n",
d->boot1, d->boot2, d->bootipl, d->bootmenu);
#elif defined(__i386__) || defined(__amd64__)
printf(" boot1=%p, boot2=%p, bootmgr=%p\n",
d->boot1, d->boot2, d->bootmgr);
#elif defined(__alpha__)
printf(" boot1=%p, bootmgr=%p\n",
d->boot1, d->bootmgr);
#else
/* Should be: error "Debug_Disk: unknown arch"; */
#endif
#else /* __ia64__ */
printf(" media size=%lu, sector size=%lu\n", d->media_size,
d->sector_size);
#endif
Debug_Chunk(d->chunks);
}
void
Free_Disk(struct disk *d)
{
if (d->chunks)
Free_Chunk(d->chunks);
if (d->name)
free(d->name);
#ifdef PC98
if (d->bootipl)
free(d->bootipl);
if (d->bootmenu)
free(d->bootmenu);
#else
#if !defined(__ia64__)
if (d->bootmgr)
free(d->bootmgr);
#endif
#endif
#if !defined(__ia64__)
if (d->boot1)
free(d->boot1);
#endif
#if defined(__i386__) || defined(__amd64__)
if (d->boot2)
free(d->boot2);
#endif
free(d);
}
#if 0
void
Collapse_Disk(struct disk *d)
{
while (Collapse_Chunk(d, d->chunks))
;
}
#endif
static int
qstrcmp(const void* a, const void* b)
{
const char *str1 = *(char* const*)a;
const char *str2 = *(char* const*)b;
return strcmp(str1, str2);
}
char **
Disk_Names()
{
int disk_cnt;
char **disks;
int error;
size_t listsize;
char *disklist, *disk1, *disk2;
error = sysctlbyname("kern.disks", NULL, &listsize, NULL, 0);
if (error) {
warn("kern.disks sysctl not available");
return NULL;
}
if (listsize == 0)
return (NULL);
disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS));
if (disks == NULL)
return NULL;
disk1 = disklist = (char *)malloc(listsize + 1);
if (disklist == NULL) {
free(disks);
return NULL;
}
memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS));
memset(disklist, 0, listsize + 1);
error = sysctlbyname("kern.disks", disklist, &listsize, NULL, 0);
if (error || disklist[0] == 0) {
free(disklist);
free(disks);
return NULL;
}
for (disk_cnt = 0; disk_cnt < MAX_NO_DISKS; disk_cnt++) {
disk2 = strsep(&disk1, " ");
if (disk2 == NULL)
break;
disks[disk_cnt] = strdup(disk2);
if (disks[disk_cnt] == NULL) {
for (disk_cnt--; disk_cnt >= 0; disk_cnt--)
free(disks[disk_cnt]);
free(disklist);
free(disks);
return (NULL);
}
}
qsort(disks, disk_cnt, sizeof(char*), qstrcmp);
free(disklist);
return disks;
}
#ifdef PC98
void
Set_Boot_Mgr(struct disk *d, const u_char *bootipl, const size_t bootipl_size,
const u_char *bootmenu, const size_t bootmenu_size)
#else
void
Set_Boot_Mgr(struct disk *d, const u_char *b, const size_t s)
#endif
{
#if !defined(__ia64__)
#ifdef PC98
if (d->sector_size == 0)
return;
if (bootipl_size % d->sector_size != 0)
return;
if (d->bootipl)
free(d->bootipl);
if (!bootipl) {
d->bootipl = NULL;
} else {
d->bootipl_size = bootipl_size;
d->bootipl = malloc(bootipl_size);
if (!d->bootipl)
return;
memcpy(d->bootipl, bootipl, bootipl_size);
}
if (bootmenu_size % d->sector_size != 0)
return;
if (d->bootmenu)
free(d->bootmenu);
if (!bootmenu) {
d->bootmenu = NULL;
} else {
d->bootmenu_size = bootmenu_size;
d->bootmenu = malloc(bootmenu_size);
if (!d->bootmenu)
return;
memcpy(d->bootmenu, bootmenu, bootmenu_size);
}
#else
if (d->sector_size == 0)
return;
if (s % d->sector_size != 0)
return;
if (d->bootmgr)
free(d->bootmgr);
if (!b) {
d->bootmgr = NULL;
} else {
d->bootmgr_size = s;
d->bootmgr = malloc(s);
if (!d->bootmgr)
return;
memcpy(d->bootmgr, b, s);
}
#endif
#endif
}
int
Set_Boot_Blocks(struct disk *d, const u_char *b1, const u_char *b2)
{
#if defined(__i386__) || defined(__amd64__)
if (d->boot1)
free(d->boot1);
d->boot1 = malloc(512);
if (!d->boot1)
return -1;
memcpy(d->boot1, b1, 512);
if (d->boot2)
free(d->boot2);
d->boot2 = malloc(15 * 512);
if (!d->boot2)
return -1;
memcpy(d->boot2, b2, 15 * 512);
#elif defined(__alpha__)
if (d->boot1)
free(d->boot1);
d->boot1 = malloc(15 * 512);
if (!d->boot1)
return -1;
memcpy(d->boot1, b1, 15 * 512);
#elif defined(__sparc64__)
if (d->boot1 != NULL)
free(d->boot1);
d->boot1 = malloc(16 * 512);
if (d->boot1 == NULL)
return (-1);
memcpy(d->boot1, b1, 16 * 512);
#elif defined(__ia64__)
/* nothing */
#else
/* Should be: #error "Set_Boot_Blocks: unknown arch"; */
#endif
return 0;
}
const char *
slice_type_name( int type, int subtype )
{
switch (type) {
case whole:
return "whole";
case mbr:
switch (subtype) {
case 1: return "fat (12-bit)";
case 2: return "XENIX /";
case 3: return "XENIX /usr";
case 4: return "fat (16-bit,<=32Mb)";
case 5: return "extended DOS";
case 6: return "fat (16-bit,>32Mb)";
case 7: return "NTFS/HPFS/QNX";
case 8: return "AIX bootable";
case 9: return "AIX data";
case 10: return "OS/2 bootmgr";
case 11: return "fat (32-bit)";
case 12: return "fat (32-bit,LBA)";
case 14: return "fat (16-bit,>32Mb,LBA)";
case 15: return "extended DOS, LBA";
case 18: return "Compaq Diagnostic";
case 57: return "Plan 9";
case 77: return "QNX 4.X";
case 78: return "QNX 4.X 2nd part";
case 79: return "QNX 4.X 3rd part";
case 84: return "OnTrack diskmgr";
case 100: return "Netware 2.x";
case 101: return "Netware 3.x";
case 115: return "SCO UnixWare";
case 128: return "Minix 1.1";
case 129: return "Minix 1.5";
case 130: return "linux_swap";
case 131: return "ext2fs";
case 133: return "linux extended";
case 166: return "OpenBSD FFS"; /* 0xA6 */
case 168: return "Mac OS-X";
case 169: return "NetBSD FFS"; /* 0xA9 */
case 171: return "Mac OS-X Boot";
case 182: return "OpenBSD"; /* dedicated */
case 183: return "bsd/os";
case 184: return "bsd/os swap";
case 191: return "Solaris (new)";
case 238: return "EFI GPT";
case 239: return "EFI Sys. Part.";
default: return "unknown";
}
case fat:
return "fat";
case freebsd:
switch (subtype) {
#ifdef PC98
case 0xc494: return "freebsd";
#else
case 165: return "freebsd";
#endif
default: return "unknown";
}
case extended:
return "extended";
case part:
return "part";
case efi:
return "efi";
case unused:
return "unused";
default:
return "unknown";
}
}

View File

@ -1,341 +0,0 @@
.\"
.\" Copyright (c) 1996 Joerg Wunsch
.\"
.\" All rights reserved.
.\"
.\" This program is free software.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\" "
.Dd January 30, 2006
.Dt LIBDISK 3
.Os
.Sh NAME
.Nm Open_Disk ,
.Nm Free_Disk ,
.Nm Debug_Disk ,
.Nm Set_Bios_Geom ,
.Nm Delete_Chunk ,
.Nm Collapse_Disk ,
.Nm Collapse_Chunk ,
.Nm Create_Chunk ,
.Nm All_FreeBSD ,
.Nm CheckRules ,
.Nm Disk_Names ,
.Nm Set_Boot_Mgr ,
.Nm Set_Boot_Blocks ,
.Nm Write_Disk ,
.Nm Cyl_Aligned ,
.Nm Next_Cyl_Aligned ,
.Nm Prev_Cyl_Aligned ,
.Nm Track_Aligned ,
.Nm Next_Track_Aligned ,
.Nm Prev_Track_Aligned ,
.Nm Create_Chunk_DWIM ,
.Nm MakeDev ,
.Nm MakeDevDisk ,
.Nm ShowChunkFlags ,
.Nm chunk_name ,
.Nm slice_type_name
.Nd library interface to slice and partition labels
.Sh LIBRARY
.Lb libdisk
.Sh SYNOPSIS
.In sys/types.h
.In libdisk.h
.Pp
.Ft struct disk *
.Fn Open_Disk "const char *devname"
.Ft void
.Fn Free_Disk "struct disk *disk"
.Ft void
.Fn Debug_Disk "struct disk *disk"
.Ft void
.Fn Set_Bios_Geom "struct disk *disk" "u_long cyl" "u_long heads" "u_long sects"
.Ft int
.Fn Delete_Chunk "struct disk *disk" "struct chunk *"
.Ft void
.Fn Collapse_Disk "struct disk *disk"
.Ft int
.Fn Collapse_Chunk "struct disk *disk" "struct chunk *chunk"
.Ft int
.Fn Create_Chunk "struct disk *disk" "daddr_t offset" "daddr_t size" "chunk_e type" "int subtype" "u_long flags" "const char *sname"
.Ft void
.Fn All_FreeBSD "struct disk *d" "int force_all"
.Ft char *
.Fn CheckRules "const struct disk *"
.Ft char **
.Fn Disk_Names "void"
.Ft void
.Fn Set_Boot_Mgr "struct disk *d" "const u_char *bootmgr" "const size_t bootmgr_size"
.Ft int
.Fn Set_Boot_Blocks "struct disk *d" "const u_char *boot1" "const u_char *boot2"
.Ft int
.Fn Write_Disk "const struct disk *d"
.Ft int
.Fn Cyl_Aligned "struct disk *d" "daddr_t offset"
.Ft daddr_t
.Fn Next_Cyl_Aligned "const struct disk *d" "daddr_t offset"
.Ft daddr_t
.Fn Prev_Cyl_Aligned "const struct disk *d" "daddr_t offset"
.Ft int
.Fn Track_Aligned "const struct disk *d" "daddr_t offset"
.Ft daddr_t
.Fn Next_Track_Aligned "const struct disk *d" "daddr_t offset"
.Ft daddr_t
.Fn Prev_Track_Aligned "const struct disk *d" "daddr_t offset"
.Ft struct chunk *
.Fn Create_Chunk_DWIM "struct disk *d" "struct chunk *parent" "daddr_t size" "chunk_e type" "int subtype" "u_long flags"
.Ft int
.Fn MakeDev "struct chunk *c" "const char *path"
.Ft int
.Fn MakeDevDisk "struct disk *d" "const char *path"
.Ft char *
.Fn ShowChunkFlags "struct chunk *c"
.Ft const char *
.Fn chunk_name "chunk_e type"
.Ft const char *
.Fn slice_type_name "int type" "int subtype"
.Sh DESCRIPTION
.Bf Sy
.Nm libdisk
is just for the use of
.Xr sysinstall 8 .
You should consider using
.Xr libgeom 3
instead.
.Ef
.Pp
The
.Nm libdisk
library provides an interface to the low-level disk slice and partition labels.
Most functions operate with arguments of the types
.Ql struct disk ,
or
.Ql struct chunk .
.Pp
While both types are mostly opaque to the programmer, the internal
structure is mentioned below for the sake of completeness.
.Bd -literal -offset indent
struct disk {
char *name;
u_long flags;
u_long bios_cyl;
u_long bios_hd;
u_long bios_sect;
u_char *bootmgr;
u_char *boot1;
u_char *boot2;
struct chunk *chunks;
u_long sector_size;
};
.Ed
The only flag value by now is
.Ql DISK_ON_TRACK ,
meaning that this disk is handled by the On-Track Disk Manager.
.Bd -literal -offset indent
struct chunk {
struct chunk *next;
struct chunk *part;
struct disk *disk;
daddr_t offset;
daddr_t size;
daddr_t end;
char *name;
char *oname;
chunk_e type;
int subtype;
u_long flags;
void (*private_free)(void*);
void *(*private_clone)(void*);
void *private_data;
};
.Ed
The
.Ql type
field can be one of the following values:
.Ql whole, unknown, fat, freebsd, extended, part, unused .
.Pp
These are the valid
.Ql flags
values for a
.Ql struct chunk .
.Bl -tag -offset indent -width CHUNK_AUTO_SIZEXX
.It CHUNK_ALIGN
This chunk should be aligned.
.It CHUNK_IS_ROOT
This
.Ql part
is a rootfs, allocate partition
.Sq a .
.It CHUNK_ACTIVE
This is the active slice in the MBR.
.It CHUNK_FORCE_ALL
Force a dedicated disk for
.Fx ,
bypassing all BIOS geometry considerations.
.It CHUNK_AUTO_SIZE
This chunk was auto-sized and can fill out any deleted following chunks.
.It CHUNK_NEWFS
newfs pending, used to enable auto-resizing on delete (along with AUTO_SIZE).
.El
.Pp
The
.Ql private_data ,
.Ql private_free ,
and
.Ql private_clone
fields are for data private to the application, and the management
thereof.
If the functions are not provided, no storage management is
done, cloning will just copy the pointer and freeing will just forget
it.
.Pp
.Fn Open_Disk
will open the named disk, and return populated tree.
.Pp
.Fn Free_Disk
frees a tree made with
.Fn Open_Disk
or
.Fn Clone_Disk .
.Pp
.Fn Debug_Disk
prints the content of the tree to
.Dv stdout .
.Pp
.Fn Set_Bios_Geom
sets the geometry the bios uses.
.Pp
.Fn Delete_Chunk
frees a chunk of disk_space.
.Pp
.Fn Collapse_Disk
and
.Fn Collapse_Chunk
are experimental, do not use.
.Pp
.Fn Create_Chunk
creates a chunk with the specified parameters.
.Pp
.Fn All_FreeBSD
makes one
.Fx
chunk covering the entire disk; if
.Ql force_all
is set, bypass all BIOS geometry considerations.
.Pp
.Fn CheckRules
returns
.Ql char*
to warnings about broken design rules in this disklayout.
.Pp
.Fn Disk_Names
returns
.Ql char**
with all disk's names (wd0, wd1 ...).
You must free each pointer, as
well as the array by hand.
.Pp
.Fn Set_Boot_Mgr
sets this boot-manager for use on this disk.
Gets written when
.Fn Write_Disk
is called.
.Pp
.Fn Set_Boot_Blocks
sets the boot-blocks for use on this disk.
Gets written when
.Fn Write_Disk
is called.
.Pp
.Fn Write_Disk
writes all the MBRs, disklabels, bootblocks and boot managers.
.Pp
.Fn Cyl_Aligned
checks if
.Ql offset
is aligned on a cylinder according to the BIOS geometry.
.Pp
.Fn Next_Cyl_Aligned
rounds
.Ql offset
up to next cylinder according to the BIOS geometry.
.Pp
.Fn Prev_Cyl_Aligned
rounds
.Ql offset
down to previous cylinder according to the BIOS geometry.
.Pp
.Fn Track_Aligned
checks if
.Ql offset
is aligned on a track according to the BIOS geometry.
.Pp
.Fn Next_Track_Aligned
rounds
.Ql offset
up to next track according to the BIOS geometry.
.Pp
.Fn Prev_Track_Aligned
rounds
.Ql offset
up to previous track according to the BIOS geometry.
.Pp
.Fn Create_Chunk_DWIM
creates a partition inside the given parent of the given size, and
returns a pointer to it.
The first unused chunk big enough is used.
.Pp
.Fn MakeDev
makes the device nodes for this chunk.
.Pp
.Fn MakeDevDisk
makes the device nodes for all chunks on this disk.
.Pp
.Fn ShowChunkFlags
returns a string to show flags.
.Pp
The
.Fn chunk_name
function takes the enumerated chunk type and returns its name.
.Fn chunk_name
replaces the old external array
.Va chunk_n .
.Pp
.Fn slice_type_name
returns the name strings associated with the specified
.Ql type .
.Ql subtype .
If
.Fn slice_type_name
returns "unknown" for slices it is not familiar with.
.Sh AUTHORS
.An -nosplit
The
.Nm libdisk
library was written by
.An Poul-Henning Kamp .
.Pp
This manual page was written by
.An J\(:org Wunsch .

View File

@ -1,368 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $FreeBSD$
*
*/
#ifndef _LIBDISK_H_
#define _LIBDISK_H_
/* #define DEBUG 1 */
/* You can define a particular architecture here if you are debugging. */
/* #define P_DEBUG p_sparc64 */
#define MAX_NO_DISKS 32
/* Max # of disks Disk_Names() will return */
#define MAX_SEC_SIZE 2048 /* maximum sector size that is supported */
#define MIN_SEC_SIZE 512 /* the sector size to end sensing at */
enum platform {
p_any, /* for debugging ! */
p_alpha,
p_i386,
p_pc98,
p_sparc64,
p_ia64,
p_ppc,
p_amd64,
p_arm,
p_mips
};
extern const enum platform platform;
typedef enum {
whole,
unknown,
sun,
pc98,
mbr,
gpt,
efi,
fat,
freebsd,
extended,
part,
spare,
unused,
apple
} chunk_e;
__BEGIN_DECLS
#ifndef __ia64__
struct disk {
char *name;
u_long bios_cyl;
u_long bios_hd;
u_long bios_sect;
#ifdef PC98
u_char *bootipl;
size_t bootipl_size;
u_char *bootmenu;
size_t bootmenu_size;
#else
u_char *bootmgr;
size_t bootmgr_size;
#endif
u_char *boot1;
#if defined(__i386__) || defined(__amd64__) /* the i386 needs extra help... */
u_char *boot2;
#endif
struct chunk *chunks;
u_long sector_size; /* media sector size, a power of 2 */
};
#else /* !__ia64__ */
struct disk {
char *name;
struct chunk *chunks;
u_long media_size;
u_long sector_size;
u_long lba_start;
u_long lba_end;
u_int gpt_size; /* Number of entries */
};
#endif
struct chunk {
struct chunk *next;
struct chunk *part;
struct disk *disk;
daddr_t offset;
daddr_t size;
daddr_t end;
char *sname; /* PC98 field */
char *name;
char *oname;
/* Used during Fixup_Names() to avoid renaming more than
* absolutely needed.
*/
chunk_e type;
int subtype;
u_long flags;
void (*private_free)(void*);
void *(*private_clone)(void*);
void *private_data;
/* For data private to the application, and the management
* thereof. If the functions are not provided, no storage
* management is done, Cloning will just copy the pointer
* and freeing will just forget it.
*/
};
/*
* flags:
*
* ALIGN - This chunk should be aligned
* IS_ROOT - This 'part' is a rootfs, allocate 'a'
* ACTIVE - This is the active slice in the MBR
* FORCE_ALL - Force a dedicated disk for FreeBSD, bypassing
* all BIOS geometry considerations
* AUTO_SIZE - This chunk was auto-sized and can fill-out a
* following chunk if the following chunk is deleted.
* NEWFS - newfs pending, used to enable auto-resizing on
* delete (along with AUTO_SIZE).
*/
#define CHUNK_ALIGN 0x0008
#define CHUNK_IS_ROOT 0x0010
#define CHUNK_ACTIVE 0x0020
#define CHUNK_FORCE_ALL 0x0040
#define CHUNK_AUTO_SIZE 0x0080
#define CHUNK_NEWFS 0x0100
#define CHUNK_HAS_INDEX 0x0200
#define CHUNK_ITOF(i) ((i & 0xFFFF) << 16)
#define CHUNK_FTOI(f) ((f >> 16) & 0xFFFF)
#define DELCHUNK_NORMAL 0x0000
#define DELCHUNK_RECOVER 0x0001
const char *chunk_name(chunk_e);
const char *
slice_type_name(int, int);
/* "chunk_n" for subtypes too */
struct disk *
Open_Disk(const char *);
/* Will open the named disk, and return populated tree. */
void
Free_Disk(struct disk *);
/* Free a tree made with Open_Disk() or Clone_Disk() */
void
Debug_Disk(struct disk *);
/* Print the content of the tree to stdout */
void
Set_Bios_Geom(struct disk *, u_long, u_long, u_long);
/* Set the geometry the bios uses. */
void
Sanitize_Bios_Geom(struct disk *);
/* Set the bios geometry to something sane */
int
Insert_Chunk(struct chunk *, daddr_t, daddr_t, const char *, chunk_e, int,
u_long, const char *);
int
Delete_Chunk2(struct disk *, struct chunk *, int);
/* Free a chunk of disk_space modified by the passed flags. */
int
Delete_Chunk(struct disk *, struct chunk *);
/* Free a chunk of disk_space */
void
Collapse_Disk(struct disk *);
/* Experimental, do not use. */
int
Collapse_Chunk(struct disk *, struct chunk *);
/* Experimental, do not use. */
int
Create_Chunk(struct disk *, daddr_t, daddr_t, chunk_e, int, u_long, const char *);
/* Create a chunk with the specified paramters */
void
All_FreeBSD(struct disk *, int);
/*
* Make one FreeBSD chunk covering the entire disk;
* if force_all is set, bypass all BIOS geometry
* considerations.
*/
char *
CheckRules(const struct disk *);
/* Return char* to warnings about broken design rules in this disklayout */
char **
Disk_Names(void);
/*
* Return char** with all disk's names (wd0, wd1 ...). You must free
* each pointer, as well as the array by hand
*/
#ifdef PC98
void
Set_Boot_Mgr(struct disk *, const u_char *, const size_t, const u_char *,
const size_t);
#else
void
Set_Boot_Mgr(struct disk *, const u_char *, const size_t);
#endif
/*
* Use this boot-manager on this disk. Gets written when Write_Disk()
* is called
*/
int
Set_Boot_Blocks(struct disk *, const u_char *, const u_char *);
/*
* Use these boot-blocks on this disk. Gets written when Write_Disk()
* is called. Returns nonzero upon failure.
*/
int
Write_Disk(const struct disk *);
/* Write all the MBRs, disklabels, bootblocks and boot managers */
daddr_t
Next_Cyl_Aligned(const struct disk *, daddr_t);
/* Round offset up to next cylinder according to the bios-geometry */
daddr_t
Prev_Cyl_Aligned(const struct disk *, daddr_t);
/* Round offset down to previous cylinder according to the bios-geometry */
int
Track_Aligned(const struct disk *, daddr_t);
/* Check if offset is aligned on a track according to the bios geometry */
daddr_t
Next_Track_Aligned(const struct disk *, daddr_t);
/* Round offset up to next track according to the bios-geometry */
daddr_t
Prev_Track_Aligned(const struct disk *, daddr_t);
/* Check if offset is aligned on a track according to the bios geometry */
struct chunk *
Create_Chunk_DWIM(struct disk *, struct chunk *, daddr_t, chunk_e, int,
u_long);
/*
* This one creates a partition inside the given parent of the given
* size, and returns a pointer to it. The first unused chunk big
* enough is used.
*/
char *
ShowChunkFlags(struct chunk *);
/* Return string to show flags. */
/*
* Implementation details >>> DO NOT USE <<<
*/
struct disklabel;
void Fill_Disklabel(struct disklabel *, const struct disk *,
const struct chunk *);
void Debug_Chunk(struct chunk *);
struct chunk *New_Chunk(void);
void Free_Chunk(struct chunk *);
struct chunk *Clone_Chunk(const struct chunk *);
int Add_Chunk(struct disk *, daddr_t, daddr_t, const char *, chunk_e, int,
u_long, const char *);
void *read_block(int, daddr_t, u_long);
int write_block(int, daddr_t, const void *, u_long);
struct disklabel *read_disklabel(int, daddr_t, u_long);
struct disk *Int_Open_Disk(const char *, char *);
int Fixup_Names(struct disk *);
int MakeDevChunk(const struct chunk *, const char *);
__END_DECLS
/* TODO
*
* Need an error string mechanism from the functions instead of warn()
*
* Make sure only FreeBSD start at offset==0
*
* Collapse must align.
*
* Make Write_Disk(struct disk*)
*
* Consider booting from OnTrack'ed disks.
*
* Get Bios-geom, ST506 & OnTrack from driver (or otherwise)
*
* Make Create_DWIM().
*
* Make Is_Unchanged(struct disk *d1, struct chunk *c1)
*
* don't rename slices unless we have to
*
*Sample output from tst01:
*
* Debug_Disk(wd0) flags=0 bios_geom=0/0/0
* >> 0x3d040 0 1411200 1411199 wd0 0 whole 0 0
* >>>> 0x3d080 0 960120 960119 wd0s1 3 freebsd 0 8
* >>>>>> 0x3d100 0 40960 40959 wd0s1a 5 part 0 0
* >>>>>> 0x3d180 40960 131072 172031 wd0s1b 5 part 0 0
* >>>>>> 0x3d1c0 172032 409600 581631 wd0s1e 5 part 0 0
* >>>>>> 0x3d200 581632 378488 960119 wd0s1f 5 part 0 0
* >>>> 0x3d140 960120 5670 965789 wd0s2 4 extended 0 8
* >>>>>> 0x3d2c0 960120 63 960182 - 6 unused 0 0
* >>>>>> 0x3d0c0 960183 5607 965789 wd0s5 2 fat 0 8
* >>>> 0x3d280 965790 1890 967679 wd0s3 1 foo -2 8
* >>>> 0x3d300 967680 443520 1411199 wd0s4 3 freebsd 0 8
* >>>>>> 0x3d340 967680 443520 1411199 wd0s4a 5 part 0 0
*
* ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
* level chunkptr start size end name type subtype flags
*
* Underlying data structure:
*
* Legend:
* <struct chunk> --> part
* |
* v next
*
* <wd0> --> <wd0s1> --> <wd0s1a>
* | |
* | v
* | <wd0s1b>
* | |
* | v
* | <wd0s1e>
* | |
* | v
* | <wd0s1f>
* |
* v
* <wd0s2> --> <unused>
* | |
* | v
* | <wd0s5>
* |
* v
* <wd0s3>
* |
* v
* <wd0s4> --> <wd0s4a>
*
*
*/
#endif /* _LIBDISK_H_ */

View File

@ -1,311 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <inttypes.h>
#include <err.h>
#include <sys/sysctl.h>
#include <sys/stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <sys/gpt.h>
#include <paths.h>
#include "libdisk.h"
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#ifdef DEBUG
#define DPRINT(x) warn x
#define DPRINTX(x) warnx x
#else
#define DPRINT(x)
#define DPRINTX(x)
#endif
struct disk *
Int_Open_Disk(const char *name, char *conftxt)
{
struct disk *d;
int i, line = 1;
char *p, *q, *r, *a, *b, *n, *t, *sn;
daddr_t o, len, off;
u_int l, s, ty, sc, hd, alt;
daddr_t lo[10];
/*
* Locate the disk (by name) in our sysctl output
*/
for (p = conftxt; p != NULL && *p; p = strchr(p, '\n'), line++) {
if (*p == '\n')
p++;
a = strsep(&p, " ");
/* Skip anything not with index 0 */
if (strcmp(a, "0"))
continue;
/* Skip anything not a disk */
a = strsep(&p, " ");
if (strcmp(a, "DISK"))
continue;
a = strsep(&p, " ");
if (strcmp(a, name))
continue;
break;
}
q = strchr(p, '\n');
if (q != NULL)
*q++ = '\0';
d = (struct disk *)calloc(sizeof *d, 1);
if(d == NULL)
return NULL;
d->name = strdup(name);
a = strsep(&p, " "); /* length in bytes */
len = strtoimax(a, &r, 0);
if (*r) {
printf("libdisk: Int_Open_Disk(%s): can't parse length in line %d (r='%s')\n",
name, line, r);
return NULL;
}
a = strsep(&p, " "); /* sectorsize */
s = strtoul(a, &r, 0);
if (*r) {
printf("libdisk: Int_Open_Disk(%s): can't parse sector size in line %d (r='%s')\n",
name, line, r);
return NULL;
}
if (s == 0)
return (NULL);
d->sector_size = s;
len /= s; /* media size in number of sectors. */
if (Add_Chunk(d, 0, len, name, whole, 0, 0, "-")) {
DPRINT(("Failed to add 'whole' chunk"));
}
/* Try to parse any fields after the sector size in the DISK entry line */
for (;;) {
a = strsep(&p, " ");
if (a == NULL)
break;
b = strsep(&p, " ");
o = strtoimax(b, &r, 0);
if (*r) {
printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
name, a, line, r);
return NULL;
}
if (!strcmp(a, "hd"))
d->bios_hd = o;
else if (!strcmp(a, "sc"))
d->bios_sect = o;
else
printf("libdisk: Int_Open_Disk(%s): unknown parameter '%s' with value '%s' in line %d, ignored\n",
name, a, b, line);
}
/* Sanitize the parameters. */
Sanitize_Bios_Geom(d);
/*
* Calculate the number of cylinders this disk must have. If we have
* an obvious insanity, we set the number of cylinders to zero.
*/
o = d->bios_hd * d->bios_sect;
d->bios_cyl = (o != 0) ? len / o : 0;
p = q; line++; /* p is now the start of the line _after_ the DISK entry */
lo[0] = 0;
for (; p != NULL && *p; p = q, line++) {
sn = NULL;
q = strchr(p, '\n');
if (q != NULL)
*q++ = '\0';
a = strsep(&p, " "); /* Index */
/*
* If we find index 0 again, this means we've encountered another disk, so it's safe to assume this disk
* has been processed.
*/
if (!strcmp(a, "0"))
break;
l = strtoimax(a, &r, 0);
if (*r) {
printf("libdisk: Int_Open_Disk(%s): can't parse depth '%s' in line %d (r='%s')\n",
name, a, line, r);
return NULL;
}
t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */
n = strsep(&p, " "); /* name */
a = strsep(&p, " "); /* len */
len = strtoimax(a, &r, 0);
if (*r) {
printf("libdisk: Int_Open_Disk(%s): can't parse length '%s' in line %d (r='%s')\n",
name, a, line, r);
continue;
}
a = strsep(&p, " "); /* secsize */
s = strtoimax(a, &r, 0);
if (*r) {
printf("libdisk: Int_Open_Disk(%s): can't parse sector size '%s' in line %d (r='%s')\n",
name, a, line, r);
continue;
}
for (;;) {
a = strsep(&p, " ");
if (a == NULL)
break;
/* XXX: Slice name may include a space. */
if (!strcmp(a, "sn")) {
sn = p;
break;
}
b = strsep(&p, " ");
o = strtoimax(b, &r, 0);
/* APPLE have ty as a string */
if ((*r) && strcmp(t, "APPLE") &&
strcmp(t, "GPT") && strcmp(t, "PART")) {
printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
name, a, line, r);
break;
}
if (!strcmp(a, "o"))
off = o;
else if (!strcmp(a, "i"))
i = (!strcmp(t, "PART")) ? o - 1 : o;
else if (!strcmp(a, "ty"))
ty = o;
else if (!strcmp(a, "sc"))
sc = o;
else if (!strcmp(a, "hd"))
hd = o;
else if (!strcmp(a, "alt"))
alt = o;
else if (!strcmp(a, "xs"))
t = b;
else if (!strcmp(a, "xt")) {
if (*r)
sn = b;
else
ty = o;
}
}
/* PLATFORM POLICY BEGIN ----------------------------------- */
if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2)
continue;
if (platform == p_sparc64 && !strcmp(t, "SUN") &&
d->chunks->part->part == NULL) {
d->bios_hd = hd;
d->bios_sect = sc;
o = d->chunks->size / (hd * sc);
o *= (hd * sc);
o -= alt * hd * sc;
if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
DPRINT(("Failed to add 'freebsd' chunk"));
}
}
if (platform == p_alpha && !strcmp(t, "BSD") &&
d->chunks->part->part == NULL) {
if (Add_Chunk(d, 0, d->chunks->size, name, freebsd,
0, 0, "-")) {
DPRINT(("Failed to add 'freebsd' chunk"));
}
}
if (!strcmp(t, "BSD") && i == RAW_PART)
continue;
/* PLATFORM POLICY END ------------------------------------- */
off /= s;
len /= s;
off += lo[l - 1];
lo[l] = off;
if (!strcmp(t, "SUN"))
i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
else if (!strncmp(t, "MBR", 3)) {
switch (ty) {
case 0xa5:
i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 0);
break;
case 0x01:
case 0x04:
case 0x06:
case 0x0b:
case 0x0c:
case 0x0e:
i = Add_Chunk(d, off, len, n, fat, ty, 0, 0);
break;
case 0xef: /* EFI */
i = Add_Chunk(d, off, len, n, efi, ty, 0, 0);
break;
default:
i = Add_Chunk(d, off, len, n, mbr, ty, 0, 0);
break;
}
} else if (!strcmp(t, "BSD"))
i = Add_Chunk(d, off, len, n, part, ty, 0, 0);
else if (!strcmp(t, "PC98")) {
switch (ty & 0x7f) {
case 0x14:
i = Add_Chunk(d, off, len, n, freebsd, ty, 0,
sn);
break;
case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
i = Add_Chunk(d, off, len, n, fat, ty, 0, sn);
break;
default:
i = Add_Chunk(d, off, len, n, pc98, ty, 0, sn);
break;
}
} else if (!strcmp(t, "GPT"))
i = Add_Chunk(d, off, len, n, gpt, 0, 0, b);
else if (!strcmp(t, "APPLE"))
i = Add_Chunk(d, off, len, n, apple, 0, 0, sn);
else
; /* Ignore unknown classes. */
}
/* PLATFORM POLICY BEGIN ------------------------------------- */
/* We have a chance to do things on a blank disk here */
if (platform == p_sparc64 && d->chunks->part->part == NULL) {
hd = d->bios_hd;
sc = d->bios_sect;
o = d->chunks->size / (hd * sc);
o *= (hd * sc);
o -= 2 * hd * sc;
if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
DPRINT(("Failed to add 'freebsd' chunk"));
}
}
/* PLATFORM POLICY END --------------------------------------- */
return (d);
i = 0;
}

View File

@ -1,239 +0,0 @@
/*
* Copyright (c) 2003 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/disklabel.h>
#include <sys/diskmbr.h>
#include <sys/gpt.h>
#include <sys/uuid.h>
#include <fcntl.h>
#include <inttypes.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libdisk.h"
static struct disk *
parse_disk(char *conftxt, const char *name)
{
char devname[64];
struct disk *disk;
struct dos_partition *part;
struct gpt_hdr *gpt;
char *buffer, *p, *q;
int fd, i;
disk = (struct disk *)calloc(sizeof *disk, 1);
if (disk == NULL)
return (NULL);
disk->name = strdup(name);
p = strsep(&conftxt, " "); /* media size */
disk->media_size = strtoimax(p, &q, 0);
if (*q)
goto fail;
p = strsep(&conftxt, " "); /* sector size */
disk->sector_size = strtoul(p, &q, 0);
if (*q)
goto fail;
if (disk->sector_size == 0)
disk->sector_size = 512;
if (disk->media_size % disk->sector_size)
goto fail;
/*
* We need to read the disk to get GPT specific information.
*/
snprintf(devname, sizeof(devname), "%s%s", _PATH_DEV, name);
fd = open(devname, O_RDONLY);
if (fd == -1)
goto fail;
buffer = malloc(2 * disk->sector_size);
if (buffer == NULL) {
close (fd);
goto fail;
}
if (read(fd, buffer, 2 * disk->sector_size) == -1) {
free(buffer);
close(fd);
goto fail;
}
close(fd);
gpt = (struct gpt_hdr *)(buffer + disk->sector_size);
if (memcmp(gpt->hdr_sig, GPT_HDR_SIG, sizeof(gpt->hdr_sig))) {
/*
* No GPT present. Check if the MBR is empty (if present)
* or is a PMBR before declaring this disk as empty. If
* the MBR isn't empty, bail out. Let's not risk nuking a
* disk.
*/
if (*(u_short *)(buffer + DOSMAGICOFFSET) == DOSMAGIC) {
for (i = 0; i < 4; i++) {
part = (struct dos_partition *)
(buffer + DOSPARTOFF + i * DOSPARTSIZE);
if (part->dp_typ != 0 &&
part->dp_typ != DOSPTYP_PMBR)
break;
}
if (i < 4) {
free(buffer);
goto fail;
}
}
disk->gpt_size = 128;
disk->lba_start = (disk->gpt_size * sizeof(struct gpt_ent)) /
disk->sector_size + 2;
disk->lba_end = (disk->media_size / disk->sector_size) -
disk->lba_start;
} else {
disk->lba_start = gpt->hdr_lba_start;
disk->lba_end = gpt->hdr_lba_end;
disk->gpt_size = gpt->hdr_entries;
}
free(buffer);
Add_Chunk(disk, disk->lba_start, disk->lba_end - disk->lba_start + 1,
name, whole, 0, 0, "-");
return (disk);
fail:
free(disk->name);
free(disk);
return (NULL);
}
struct disk *
Int_Open_Disk(const char *name, char *conftxt)
{
struct chunk chunk;
struct disk *disk;
char *p, *q, *r, *s, *sd;
u_long i;
p = conftxt;
while (p != NULL && *p != 0) {
q = strsep(&p, " ");
if (strcmp(q, "0") == 0) {
q = strsep(&p, " ");
if (strcmp(q, "DISK") == 0) {
q = strsep(&p, " ");
if (strcmp(q, name) == 0)
break;
}
}
p = strchr(p, '\n');
if (p != NULL && *p == '\n')
p++;
conftxt = p;
}
if (p == NULL || *p == 0)
return (NULL);
conftxt = strchr(p, '\n');
if (conftxt != NULL)
*conftxt++ = '\0';
disk = parse_disk(p, name);
if (disk == NULL)
return (NULL);
while (conftxt != NULL && *conftxt != 0) {
p = conftxt;
conftxt = strchr(p, '\n');
if (conftxt != NULL)
*conftxt++ = '\0';
/*
* 1 PART da0p4 34359738368 512
* i 4 o 52063912960 ty freebsd-ufs
* xs GPT xt 516e7cb6-6ecf-11d6-8ff8-00022d09712b
*/
sd = strsep(&p, " "); /* depth */
if (strcmp(sd, "0") == 0)
break;
q = strsep(&p, " "); /* type */
if (strcmp(q, "PART") != 0)
continue;
chunk.name = strsep(&p, " "); /* name */
q = strsep(&p, " "); /* length */
i = strtoimax(q, &r, 0);
if (*r)
abort();
chunk.end = i / disk->sector_size;
q = strsep(&p, " "); /* sector size */
for (;;) {
q = strsep(&p, " ");
if (q == NULL)
break;
r = strsep(&p, " ");
i = strtoimax(r, &s, 0);
if (strcmp(q, "ty") == 0 && *s != '\0') {
if (!strcmp(r, "efi"))
chunk.type = efi;
else if (!strcmp(r, "freebsd")) {
chunk.type = freebsd;
chunk.subtype = 0xa5;
} else if (!strcmp(r, "freebsd-swap")) {
chunk.type = part;
chunk.subtype = FS_SWAP;
} else if (!strcmp(r, "freebsd-ufs")) {
chunk.type = part;
chunk.subtype = FS_BSDFFS;
} else {
chunk.type = part;
chunk.subtype = FS_OTHER;
}
} else {
if (!strcmp(q, "o"))
chunk.offset = i / disk->sector_size;
else if (!strcmp(q, "i"))
chunk.flags = CHUNK_ITOF(i) |
CHUNK_HAS_INDEX;
}
}
Add_Chunk(disk, chunk.offset, chunk.end, chunk.name,
chunk.type, chunk.subtype, chunk.flags, 0);
}
return (disk);
}

View File

@ -1,296 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/stdint.h>
#include <sys/disklabel.h>
#ifdef PC98
#include <sys/diskpc98.h>
#else
#include <sys/diskmbr.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "libdisk.h"
int
Track_Aligned(const struct disk *d, daddr_t offset)
{
#ifndef __ia64__
if (!d->bios_sect)
return 1;
if (offset % d->bios_sect)
return 0;
#endif /* __ia64__ */
return 1;
}
daddr_t
Prev_Track_Aligned(const struct disk *d, daddr_t offset)
{
#ifndef __ia64__
if (!d->bios_sect)
return offset;
return (offset / d->bios_sect) * d->bios_sect;
#else
return 1;
#endif
}
daddr_t
Next_Track_Aligned(const struct disk *d, daddr_t offset)
{
#ifndef __ia64__
if (!d->bios_sect)
return offset;
return Prev_Track_Aligned(d, offset + d->bios_sect-1);
#else
return 1;
#endif
}
static int
Cyl_Aligned(const struct disk *d, daddr_t offset)
{
#ifndef __ia64__
if (!d->bios_sect || !d->bios_hd)
return 1;
if (offset % (d->bios_sect * d->bios_hd))
return 0;
#endif
return 1;
}
daddr_t
Prev_Cyl_Aligned(const struct disk *d, daddr_t offset)
{
#ifndef __ia64__
if (!d->bios_sect || !d->bios_hd)
return offset;
return (offset / (d->bios_sect * d->bios_hd)) * d->bios_sect *
d->bios_hd;
#else
return 1;
#endif
}
daddr_t
Next_Cyl_Aligned(const struct disk *d, daddr_t offset)
{
#ifndef __ia64__
if (!d->bios_sect || !d->bios_hd)
return offset;
return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd) - 1);
#else
return 1;
#endif
}
/*
* Rule#0:
* Chunks of type 'whole' can have max NDOSPART children.
* Only one of them can have the "active" flag
*/
static void
Rule_000(__unused const struct disk *d, const struct chunk *c, char *msg)
{
#ifdef PC98
int i = 0;
#else
int i = 0, j = 0;
#endif
struct chunk *c1;
if (c->type != whole)
return;
for (c1 = c->part; c1; c1 = c1->next) {
if (c1->type != unused)
continue;
#ifndef PC98
if (c1->flags & CHUNK_ACTIVE)
j++;
#endif
i++;
}
if (i > NDOSPART)
sprintf(msg + strlen(msg),
"%d is too many children of the 'whole' chunk."
" Max is %d\n", i, NDOSPART);
#ifndef PC98
if (j > 1)
sprintf(msg + strlen(msg),
"Too many active children of 'whole'");
#endif
}
/*
* Rule#1:
* All children of 'whole' and 'extended' must be track-aligned.
* Exception: the end can be unaligned if it matches the end of 'whole'
*/
static void
Rule_001(const struct disk *d, const struct chunk *c, char *msg)
{
struct chunk *c1;
if (c->type != whole && c->type != extended)
return;
for (c1 = c->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
c1->flags |= CHUNK_ALIGN;
#ifdef PC98
if (!Cyl_Aligned(d, c1->offset))
#else
if (!Track_Aligned(d, c1->offset))
#endif
sprintf(msg + strlen(msg),
#ifdef PC98
"chunk '%s' [%jd..%jd] does not start"
" on a cylinder boundary\n",
#else
"chunk '%s' [%jd..%jd] does not start"
" on a track boundary\n",
#endif
c1->name, (intmax_t)c1->offset, (intmax_t)c1->end);
if ((c->type == whole || c->end == c1->end)
|| Cyl_Aligned(d, c1->end + 1))
;
else
sprintf(msg + strlen(msg),
"chunk '%s' [%jd..%jd] does not end"
" on a cylinder boundary\n",
c1->name, (intmax_t)c1->offset, (intmax_t)c1->end);
}
}
/*
* Rule#2:
* Max one 'fat' as child of 'whole'
*/
static void
Rule_002(__unused const struct disk *d, const struct chunk *c, char *msg)
{
int i;
struct chunk *c1;
if (c->type != whole)
return;
for (i = 0, c1 = c->part; c1; c1 = c1->next) {
if (c1->type != fat)
continue;
i++;
}
if (i > 1) {
sprintf(msg + strlen(msg),
"Max one 'fat' allowed as child of 'whole'\n");
}
}
/*
* Rule#3:
* Max one extended as child of 'whole'
*/
static void
Rule_003(__unused const struct disk *d, const struct chunk *c, char *msg)
{
int i;
struct chunk *c1;
if (c->type != whole)
return;
for (i = 0, c1 = c->part; c1; c1 = c1->next) {
if (c1->type != extended)
continue;
i++;
}
if (i > 1) {
sprintf(msg + strlen(msg),
"Max one 'extended' allowed as child of 'whole'\n");
}
}
/*
* Rule#4:
* Max seven 'part' as children of 'freebsd'
* Max one CHUNK_IS_ROOT child per 'freebsd'
*/
static void
Rule_004(__unused const struct disk *d, const struct chunk *c, char *msg)
{
int i = 0, k = 0;
struct chunk *c1;
if (c->type != freebsd)
return;
for (c1 = c->part; c1; c1 = c1->next) {
if (c1->type != part)
continue;
if (c1->flags & CHUNK_IS_ROOT)
k++;
i++;
}
if (i > 7) {
sprintf(msg + strlen(msg),
"Max seven partitions per freebsd slice\n");
}
if (k > 1) {
sprintf(msg + strlen(msg),
"Max one root partition child per freebsd slice\n");
}
}
static void
Check_Chunk(const struct disk *d, const struct chunk *c, char *msg)
{
switch (platform) {
case p_i386:
case p_amd64:
Rule_000(d, c, msg);
Rule_001(d, c, msg);
Rule_002(d, c, msg);
Rule_003(d, c, msg);
Rule_004(d, c, msg);
if (c->part)
Check_Chunk(d, c->part, msg);
if (c->next)
Check_Chunk(d, c->next, msg);
break;
case p_pc98:
Rule_000(d, c, msg);
Rule_001(d, c, msg);
Rule_004(d, c, msg);
if (c->part)
Check_Chunk(d, c->part, msg);
if (c->next)
Check_Chunk(d, c->next, msg);
break;
default:
break;
}
}
char *
CheckRules(const struct disk *d)
{
char msg[BUFSIZ];
*msg = '\0';
Check_Chunk(d, d->chunks, msg);
if (*msg)
return strdup(msg);
return 0;
}

View File

@ -1,323 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <err.h>
#ifdef READLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif
#include <sys/types.h>
#include <paths.h>
#include "libdisk.h"
#ifndef PC98
u_char mbrboot[] = {
250,51,192,142,208,188,0,124,139,244,80,7,80,31,251,252,191,0,6,185,0,1,
242,165,234,29,6,0,0,190,190,7,179,4,128,60,128,116,14,128,60,0,117,28,
131,198,16,254,203,117,239,205,24,139,20,139,76,2,139,238,131,198,16,254,
203,116,26,128,60,0,116,244,190,139,6,172,60,0,116,11,86,187,7,0,180,14,
205,16,94,235,240,235,254,191,5,0,187,0,124,184,1,2,87,205,19,95,115,12,
51,192,205,19,79,117,237,190,163,6,235,211,190,194,6,191,254,125,129,61,
85,170,117,199,139,245,234,0,124,0,0,73,110,118,97,108,105,100,32,112,97,
114,116,105,116,105,111,110,32,116,97,98,108,101,0,69,114,114,111,114,32,
108,111,97,100,105,110,103,32,111,112,101,114,97,116,105,110,103,32,115,
121,115,116,101,109,0,77,105,115,115,105,110,103,32,111,112,101,114,97,
116,105,110,103,32,115,121,115,116,101,109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,
1,1,0,4,15,63,60,63,0,0,0,241,239,0,0,0,0,1,61,5,15,63,243,48,240,0,0,144,
208,2,0,0,0,1,244,165,15,63,170,192,192,3,0,144,208,2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,85,170
};
u_char bteasy17[] = {
51,192,142,192,142,216,142,208,188,0,124,252,139,244,191,0,6,185,0,1,242,
165,234,96,6,0,0,139,213,88,162,72,7,60,53,116,28,180,16,246,228,5,174,
4,150,246,68,4,255,116,62,198,4,128,232,218,0,138,116,1,139,76,2,235,8,
232,207,0,185,1,0,50,209,187,0,124,184,1,2,205,19,114,30,129,191,254,1,
85,170,117,22,234,0,124,0,0,128,250,129,116,2,178,128,139,234,66,128,242,
179,136,22,58,7,191,190,7,185,4,0,198,6,45,7,49,50,246,136,45,138,69,4,
60,0,116,35,60,5,116,31,254,198,190,42,7,232,113,0,190,72,7,70,70,139,28,
10,255,116,5,50,125,4,117,243,141,183,114,7,232,90,0,131,199,16,254,6,45,
7,226,203,128,62,117,4,2,116,11,190,59,7,10,246,117,10,205,24,235,172,190,
42,7,232,57,0,232,54,0,50,228,205,26,139,218,131,195,96,180,1,205,22,180,
0,117,11,205,26,59,211,114,242,160,72,7,235,10,205,22,138,196,60,28,116,
243,4,246,60,49,114,214,60,53,119,210,80,190,40,7,187,27,6,83,252,172,80,
36,127,180,14,205,16,88,168,128,116,242,195,86,184,1,3,187,0,6,185,1,0,
50,246,205,19,94,198,6,72,7,63,195,13,138,13,10,70,48,32,46,32,46,32,46,
160,100,105,115,107,32,49,13,10,10,68,101,102,97,117,108,116,58,32,70,63,
160,0,1,0,4,0,6,3,7,7,10,10,99,14,100,14,101,20,128,20,129,25,130,30,147,
36,165,39,159,43,117,47,82,47,219,50,64,55,242,61,0,100,111,243,72,80,70,
211,79,115,178,85,110,105,248,78,111,118,101,108,236,77,105,110,105,248,
76,105,110,117,248,65,109,111,101,98,225,66,83,196,66,83,68,233,80,67,73,
216,67,80,205,86,101,110,105,248,68,111,115,115,101,227,63,191,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,85,170
};
#endif
int
scan_block(int fd, daddr_t block)
{
u_char foo[512];
if (-1 == lseek(fd, (off_t)block * 512, SEEK_SET))
err(1, "lseek");
if (512 != read(fd, foo, 512))
return 1;
return 0;
}
void
Scan_Disk(struct disk *d)
{
char device[64];
u_long l;
int i, j, fd;
strcpy(device, _PATH_DEV);
strcat(device, d->name);
fd = open(device, O_RDWR);
if (fd < 0) {
warn("open(%s) failed", device);
return;
}
for (i = -1, l = 0; ; l++) {
j = scan_block(fd, l);
if (j != i) {
if (i == -1) {
printf("%c: %lu.",j ? 'B' : 'G', l);
fflush(stdout);
} else if (i == 0) {
printf(".%lu\nB: %lu.", l - 1, l);
fflush(stdout);
} else {
printf(".%lu\nG: %lu.", l - 1, l);
fflush(stdout);
}
i = j;
}
}
close(fd);
}
int
main(int argc, char **argv)
{
struct disk *d,*db;
char myprompt[BUFSIZ];
#ifndef READLINE
char input[BUFSIZ];
#endif
char *p,*q = 0;
char **cp, *cmds[200];
int ncmd, i;
if (argc < 2) {
fprintf(stderr, "Usage:\n\t%s diskname\n", argv[0]);
exit(1);
}
d = Open_Disk(argv[1]);
if (!d)
err(1, "Couldn't open disk %s", argv[1]);
sprintf(myprompt, "%s %s> ", argv[0], argv[1]);
while (1) {
printf("--==##==--\n");
p = CheckRules(d);
Debug_Disk(d);
if (p) {
printf("%s",p);
free(p);
}
#ifdef READLINE
if (q)
free(q);
q = p = readline(myprompt);
#else
printf("%s", myprompt);
fflush(stdout);
q = p = fgets(input, sizeof(input), stdin);
#endif
if(!p)
break;
for (cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
if (**cp != '\0')
cp++;
ncmd = cp - cmds;
if (!ncmd)
continue;
if (!strcasecmp(*cmds, "quit"))
break;
if (!strcasecmp(*cmds, "exit"))
break;
if (!strcasecmp(*cmds, "q"))
break;
if (!strcasecmp(*cmds, "x"))
break;
if (!strcasecmp(*cmds, "dwim") && ncmd == 6) {
printf("dwim = %p\n",
Create_Chunk_DWIM(d,
(struct chunk *)strtol(cmds[1], 0, 0),
strtol(cmds[2], 0, 0),
strtol(cmds[3], 0, 0),
strtol(cmds[4], 0, 0),
strtol(cmds[5], 0, 0)));
continue;
}
if (!strcasecmp(*cmds, "delete") && ncmd == 2) {
printf("delete = %d\n",
Delete_Chunk(d,
(struct chunk *)strtol(cmds[1], 0, 0)));
continue;
}
#ifndef __ia64__
if (!strcasecmp(*cmds, "allfreebsd")) {
All_FreeBSD(d, 0);
continue;
}
if (!strcasecmp(*cmds, "dedicate")) {
All_FreeBSD(d, 1);
continue;
}
if (!strcasecmp(*cmds, "sanitize")) {
Sanitize_Bios_Geom(d);
continue;
}
if (!strcasecmp(*cmds, "bios") && ncmd == 4) {
Set_Bios_Geom(d, strtol(cmds[1], 0, 0),
strtol(cmds[2], 0, 0),
strtol(cmds[3], 0, 0));
continue;
}
#endif
if (!strcasecmp(*cmds, "list")) {
cp = Disk_Names();
printf("Disks:");
for (i = 0; cp[i]; i++) {
printf(" %s", cp[i]);
free(cp[i]);
}
free(cp);
continue;
}
#ifdef PC98
if (!strcasecmp(*cmds, "create") && ncmd == 7) {
#else
if (!strcasecmp(*cmds,"create") && ncmd == 6) {
#endif
printf("Create=%d\n",
Create_Chunk(d,
strtol(cmds[1], 0, 0),
strtol(cmds[2], 0, 0),
strtol(cmds[3], 0, 0),
strtol(cmds[4], 0, 0),
#ifdef PC98
strtol(cmds[5], 0, 0), cmds[6]));
#else
strtol(cmds[5], 0, 0), NULL));
#endif
continue;
}
if (!strcasecmp(*cmds,"read")) {
db = d;
if (ncmd > 1)
d = Open_Disk(cmds[1]);
else
d = Open_Disk(argv[1]);
if (d)
Free_Disk(db);
else
d = db;
continue;
}
if (!strcasecmp(*cmds,"scan")) {
Scan_Disk(d);
continue;
}
#ifndef PC98
if (!strcasecmp(*cmds,"bteasy")) {
Set_Boot_Mgr(d, bteasy17, sizeof (bteasy17));
continue;
}
if (!strcasecmp(*cmds, "mbr")) {
Set_Boot_Mgr(d, mbrboot, sizeof (mbrboot));
continue;
}
#endif
#if 0 /* XXX boot1 undefined, fix me */
if (!strcasecmp(*cmds, "boot")) {
Set_Boot_Blocks(d, boot1, boot2);
continue;
}
#endif
if (!strcasecmp(*cmds, "write")) {
printf("Write=%d\n",
Write_Disk(d));
Free_Disk(d);
d = Open_Disk(argv[1]);
continue;
}
if (strcasecmp(*cmds, "help"))
printf("\007ERROR\n");
printf("CMDS:\n");
printf("\tallfreebsd\n");
printf("\tdedicate\n");
printf("\tbios cyl hd sect\n");
printf("\tboot\n");
#ifndef PC98
printf("\tbteasy17\n");
#endif
#if 0
printf("\tcollapse [pointer]\n");
#endif
#ifdef PC98
printf("\tcreate offset size enum subtype flags name\n");
#else
printf("\tcreate offset size enum subtype flags\n");
#endif
printf("\t\tsubtype(part): swap=1, ffs=7\n");
printf("\tdelete pointer\n");
printf("\tlist\n");
#ifndef PC98
printf("\tmbr\n");
#endif
#if 0
printf("\tphys cyl hd sect\n");
#endif
printf("\tquit\n");
printf("\tread [disk]\n");
printf("\tscan\n");
printf("\twrite\n");
printf("\nENUM:\n\t");
#if 0
for (i = 0; chunk_n[i]; i++)
printf("%d = %s%s", i, chunk_n[i],
i == 4 ? "\n\t" : " ");
#endif
printf("\n");
}
exit (0);
}

View File

@ -1,204 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/disklabel.h>
#include <sys/diskmbr.h>
#include <paths.h>
#include "libdisk.h"
/*
* XXX: A lot of hardcoded 512s probably should be foo->sector_size;
* I'm not sure which, so I leave it like it worked before. --schweikh
*/
static int
Write_FreeBSD(int fd, const struct disk *new, const struct chunk *c1)
{
struct disklabel *dl;
int i;
void *p;
u_char buf[BBSIZE];
for (i = 0; i < BBSIZE/512; i++) {
if (!(p = read_block(fd, i + c1->offset, 512)))
return (1);
memcpy(buf + 512 * i, p, 512);
free(p);
}
if (new->boot1)
memcpy(buf, new->boot1, 512);
if (new->boot2)
memcpy(buf + 512, new->boot2, BBSIZE - 512);
dl = (struct disklabel *)(buf + 512 * LABELSECTOR + LABELOFFSET);
Fill_Disklabel(dl, new, c1);
for (i = 0; i < BBSIZE / 512; i++)
write_block(fd, i + c1->offset, buf + 512 * i, 512);
return 0;
}
static void
Write_Int32(u_int32_t *p, u_int32_t v)
{
u_int8_t *bp = (u_int8_t *)p;
bp[0] = (v >> 0) & 0xff;
bp[1] = (v >> 8) & 0xff;
bp[2] = (v >> 16) & 0xff;
bp[3] = (v >> 24) & 0xff;
}
/*
* Special install-time configuration for the i386 boot0 boot manager.
*/
static void
Cfg_Boot_Mgr(u_char *mbr, int edd)
{
if (mbr[0x1b0] == 0x66 && mbr[0x1b1] == 0xbb) {
if (edd)
mbr[0x1bb] |= 0x80; /* Packet mode on */
else
mbr[0x1bb] &= 0x7f; /* Packet mode off */
}
}
int
Write_Disk(const struct disk *d1)
{
int fd, j;
uint i;
struct chunk *c1;
int ret = 0;
char device[64];
u_char *mbr;
struct dos_partition *dp,work[NDOSPART];
int s[4];
int need_edd = 0; /* Need EDD (packet interface) */
strcpy(device, _PATH_DEV);
strcat(device, d1->name);
fd = open(device, O_RDWR);
if (fd < 0)
return 1;
memset(s, 0, sizeof s);
if (!(mbr = read_block(fd, 0, d1->sector_size))) {
close (fd);
return (1);
}
dp = (struct dos_partition *)(mbr + DOSPARTOFF);
memcpy(work, dp, sizeof work);
dp = work;
free(mbr);
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
if (!strcmp(c1->name, "X"))
continue;
j = c1->name[strlen(d1->name) + 1] - '1';
if (j < 0 || j > 3)
continue;
s[j]++;
if (c1->type == freebsd)
ret += Write_FreeBSD(fd, d1, c1);
Write_Int32(&dp[j].dp_start, c1->offset);
Write_Int32(&dp[j].dp_size, c1->size);
i = c1->offset;
if (i >= 1024 * d1->bios_sect * d1->bios_hd) {
dp[j].dp_ssect = 0xff;
dp[j].dp_shd = 0xff;
dp[j].dp_scyl = 0xff;
need_edd++;
} else {
dp[j].dp_ssect = i % d1->bios_sect;
i -= dp[j].dp_ssect++;
i /= d1->bios_sect;
dp[j].dp_shd = i % d1->bios_hd;
i -= dp[j].dp_shd;
i /= d1->bios_hd;
dp[j].dp_scyl = i;
i -= dp[j].dp_scyl;
dp[j].dp_ssect |= i >> 2;
}
#ifdef DEBUG
printf("S:%lu = (%x/%x/%x)", c1->offset,
dp[j].dp_scyl, dp[j].dp_shd, dp[j].dp_ssect);
#endif
i = c1->end;
dp[j].dp_esect = i % d1->bios_sect;
i -= dp[j].dp_esect++;
i /= d1->bios_sect;
dp[j].dp_ehd = i % d1->bios_hd;
i -= dp[j].dp_ehd;
i /= d1->bios_hd;
if (i > 1023)
i = 1023;
dp[j].dp_ecyl = i;
i -= dp[j].dp_ecyl;
dp[j].dp_esect |= i >> 2;
#ifdef DEBUG
printf(" E:%lu = (%x/%x/%x)\n", c1->end,
dp[j].dp_ecyl, dp[j].dp_ehd, dp[j].dp_esect);
#endif
dp[j].dp_typ = c1->subtype;
if (c1->flags & CHUNK_ACTIVE)
dp[j].dp_flag = 0x80;
else
dp[j].dp_flag = 0;
}
j = 0;
for (i = 0; i < NDOSPART; i++) {
if (!s[i])
memset(dp + i, 0, sizeof *dp);
if (dp[i].dp_flag)
j++;
}
if (!j)
for(i = 0; i < NDOSPART; i++)
if (dp[i].dp_typ == 0xa5)
dp[i].dp_flag = 0x80;
if (!(mbr = read_block(fd, 0, d1->sector_size))) {
close (fd);
return (1);
}
if (d1->bootmgr) {
memcpy(mbr, d1->bootmgr, DOSPARTOFF);
Cfg_Boot_Mgr(mbr, need_edd);
}
memcpy(mbr + DOSPARTOFF, dp, sizeof *dp * NDOSPART);
mbr[512-2] = 0x55;
mbr[512-1] = 0xaa;
write_block(fd, 0, mbr, d1->sector_size);
if (d1->bootmgr && d1->bootmgr_size > d1->sector_size)
for (i = 1; i * d1->sector_size <= d1->bootmgr_size; i++)
write_block(fd, i, &d1->bootmgr[i * d1->sector_size],
d1->sector_size);
close(fd);
return 0;
}

View File

@ -1,47 +0,0 @@
/*-
* Copyright (c) 2006 Olivier Houchard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <paths.h>
#include "libdisk.h"
int
Write_Disk(const struct disk *d1)
{
return (0);
}

View File

@ -1,76 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <paths.h>
#include "libdisk.h"
void
Fill_Disklabel(struct disklabel *dl, const struct disk *new,
const struct chunk *c1)
{
struct chunk *c2;
int j;
memset(dl, 0, sizeof *dl);
for (c2 = c1->part; c2; c2 = c2->next) {
if (c2->type == unused)
continue;
if (!strcmp(c2->name, "X"))
continue;
j = c2->name[strlen(c2->name) - 1] - 'a';
if (j < 0 || j >= MAXPARTITIONS || j == RAW_PART)
continue;
dl->d_partitions[j].p_size = c2->size;
dl->d_partitions[j].p_offset = c2->offset;
dl->d_partitions[j].p_fstype = c2->subtype;
}
dl->d_bbsize = BBSIZE;
/*
* Add in defaults for superblock size, interleave, and rpms
*/
dl->d_sbsize = 0;
strcpy(dl->d_typename, c1->name);
dl->d_secsize = 512;
dl->d_secperunit = new->chunks->size;
#ifndef __ia64__
dl->d_ncylinders = new->bios_cyl;
dl->d_ntracks = new->bios_hd;
dl->d_nsectors = new->bios_sect;
#endif
dl->d_secpercyl = dl->d_ntracks * dl->d_nsectors;
dl->d_npartitions = MAXPARTITIONS;
dl->d_type = new->name[0] == 's' || new->name[0] == 'd' ||
new->name[0] == 'o' ? DTYPE_SCSI : DTYPE_ESDI;
dl->d_partitions[RAW_PART].p_size = c1->size;
dl->d_partitions[RAW_PART].p_offset = c1->offset;
dl->d_rpm = 3600;
dl->d_interleave = 1;
dl->d_magic = DISKMAGIC;
dl->d_magic2 = DISKMAGIC;
dl->d_checksum = dkcksum(dl);
}

View File

@ -1,204 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/disklabel.h>
#include <sys/diskmbr.h>
#include <paths.h>
#include "libdisk.h"
/*
* XXX: A lot of hardcoded 512s probably should be foo->sector_size;
* I'm not sure which, so I leave it like it worked before. --schweikh
*/
static int
Write_FreeBSD(int fd, const struct disk *new, const struct chunk *c1)
{
struct disklabel *dl;
int i;
void *p;
u_char buf[BBSIZE];
for (i = 0; i < BBSIZE/512; i++) {
if (!(p = read_block(fd, i + c1->offset, 512)))
return (1);
memcpy(buf + 512 * i, p, 512);
free(p);
}
if (new->boot1)
memcpy(buf, new->boot1, 512);
if (new->boot2)
memcpy(buf + 512, new->boot2, BBSIZE - 512);
dl = (struct disklabel *)(buf + 512 * LABELSECTOR + LABELOFFSET);
Fill_Disklabel(dl, new, c1);
for (i = 0; i < BBSIZE / 512; i++)
write_block(fd, i + c1->offset, buf + 512 * i, 512);
return 0;
}
static void
Write_Int32(u_int32_t *p, u_int32_t v)
{
u_int8_t *bp = (u_int8_t *)p;
bp[0] = (v >> 0) & 0xff;
bp[1] = (v >> 8) & 0xff;
bp[2] = (v >> 16) & 0xff;
bp[3] = (v >> 24) & 0xff;
}
/*
* Special install-time configuration for the i386 boot0 boot manager.
*/
static void
Cfg_Boot_Mgr(u_char *mbrblk, int edd)
{
if (mbrblk[0x1b0] == 0x66 && mbrblk[0x1b1] == 0xbb) {
if (edd)
mbrblk[0x1bb] |= 0x80; /* Packet mode on */
else
mbrblk[0x1bb] &= 0x7f; /* Packet mode off */
}
}
int
Write_Disk(const struct disk *d1)
{
int fd, j;
uint i;
struct chunk *c1;
int ret = 0;
char device[64];
u_char *mbrblk;
struct dos_partition *dp,work[NDOSPART];
int s[4];
int need_edd = 0; /* Need EDD (packet interface) */
strcpy(device, _PATH_DEV);
strcat(device, d1->name);
fd = open(device, O_RDWR);
if (fd < 0)
return 1;
memset(s, 0, sizeof s);
if (!(mbrblk = read_block(fd, 0, d1->sector_size))) {
close (fd);
return (1);
}
dp = (struct dos_partition *)(mbrblk + DOSPARTOFF);
memcpy(work, dp, sizeof work);
dp = work;
free(mbrblk);
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
if (!strcmp(c1->name, "X"))
continue;
j = c1->name[strlen(d1->name) + 1] - '1';
if (j < 0 || j > 3)
continue;
s[j]++;
if (c1->type == freebsd)
ret += Write_FreeBSD(fd, d1, c1);
Write_Int32(&dp[j].dp_start, c1->offset);
Write_Int32(&dp[j].dp_size, c1->size);
i = c1->offset;
if (i >= 1024 * d1->bios_sect * d1->bios_hd) {
dp[j].dp_ssect = 0xff;
dp[j].dp_shd = 0xff;
dp[j].dp_scyl = 0xff;
need_edd++;
} else {
dp[j].dp_ssect = i % d1->bios_sect;
i -= dp[j].dp_ssect++;
i /= d1->bios_sect;
dp[j].dp_shd = i % d1->bios_hd;
i -= dp[j].dp_shd;
i /= d1->bios_hd;
dp[j].dp_scyl = i;
i -= dp[j].dp_scyl;
dp[j].dp_ssect |= i >> 2;
}
#ifdef DEBUG
printf("S:%lu = (%x/%x/%x)", c1->offset,
dp[j].dp_scyl, dp[j].dp_shd, dp[j].dp_ssect);
#endif
i = c1->end;
dp[j].dp_esect = i % d1->bios_sect;
i -= dp[j].dp_esect++;
i /= d1->bios_sect;
dp[j].dp_ehd = i % d1->bios_hd;
i -= dp[j].dp_ehd;
i /= d1->bios_hd;
if (i > 1023)
i = 1023;
dp[j].dp_ecyl = i;
i -= dp[j].dp_ecyl;
dp[j].dp_esect |= i >> 2;
#ifdef DEBUG
printf(" E:%lu = (%x/%x/%x)\n", c1->end,
dp[j].dp_ecyl, dp[j].dp_ehd, dp[j].dp_esect);
#endif
dp[j].dp_typ = c1->subtype;
if (c1->flags & CHUNK_ACTIVE)
dp[j].dp_flag = 0x80;
else
dp[j].dp_flag = 0;
}
j = 0;
for (i = 0; i < NDOSPART; i++) {
if (!s[i])
memset(dp + i, 0, sizeof *dp);
if (dp[i].dp_flag)
j++;
}
if (!j)
for(i = 0; i < NDOSPART; i++)
if (dp[i].dp_typ == 0xa5)
dp[i].dp_flag = 0x80;
if (!(mbrblk = read_block(fd, 0, d1->sector_size))) {
close (fd);
return (1);
}
if (d1->bootmgr) {
memcpy(mbrblk, d1->bootmgr, DOSPARTOFF);
Cfg_Boot_Mgr(mbrblk, need_edd);
}
memcpy(mbrblk + DOSPARTOFF, dp, sizeof *dp * NDOSPART);
mbrblk[512-2] = 0x55;
mbrblk[512-1] = 0xaa;
write_block(fd, 0, mbrblk, d1->sector_size);
if (d1->bootmgr && d1->bootmgr_size > d1->sector_size)
for (i = 1; i * d1->sector_size <= d1->bootmgr_size; i++)
write_block(fd, i, &d1->bootmgr[i * d1->sector_size],
d1->sector_size);
close(fd);
return 0;
}

View File

@ -1,423 +0,0 @@
/*
* Copyright (c) 2003 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* CRC32 code derived from work by Gary S. Brown.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/disklabel.h>
#include <sys/diskmbr.h>
#include <sys/gpt.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <uuid.h>
#include "libdisk.h"
static uuid_t _efi = GPT_ENT_TYPE_EFI;
static uuid_t _fbsd = GPT_ENT_TYPE_FREEBSD;
static uuid_t _swap = GPT_ENT_TYPE_FREEBSD_SWAP;
static uuid_t _ufs = GPT_ENT_TYPE_FREEBSD_UFS;
static uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
static uint32_t
crc32(const void *buf, size_t size)
{
const uint8_t *p;
uint32_t crc;
p = buf;
crc = ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return (crc ^ ~0U);
}
static int
write_pmbr(int fd, const struct disk *disk)
{
struct dos_partition dp;
char *buffer;
u_long nsects;
int error;
error = 0;
nsects = disk->media_size / disk->sector_size;
nsects--; /* The GPT starts at LBA 1 */
buffer = calloc(disk->sector_size, 1);
if (buffer == NULL)
return (ENOMEM);
buffer[DOSMAGICOFFSET] = DOSMAGIC & 0xff;
buffer[DOSMAGICOFFSET + 1] = DOSMAGIC >> 8;
dp.dp_flag = 0;
dp.dp_shd = dp.dp_ssect = dp.dp_scyl = 0xff;
dp.dp_typ = DOSPTYP_PMBR;
dp.dp_ehd = dp.dp_esect = dp.dp_ecyl = 0xff;
dp.dp_start = 1;
dp.dp_size = (nsects > 0xffffffffu) ? ~0u : nsects;
memcpy(buffer + DOSPARTOFF, &dp, DOSPARTSIZE);
if (lseek(fd, 0L, SEEK_SET) != 0L ||
write(fd, buffer, disk->sector_size) != disk->sector_size)
error = (errno) ? errno : EAGAIN;
free(buffer);
return (error);
}
static int
read_gpt(int fd, const struct disk *disk, struct gpt_hdr *hdr,
struct gpt_ent *tbl)
{
char *buffer;
off_t off;
size_t nsects, sz;
int error, i;
error = 0;
nsects = disk->gpt_size * sizeof(struct gpt_ent) / disk->sector_size;
nsects++;
sz = nsects * disk->sector_size;
buffer = malloc(sz);
if (buffer == NULL)
return (ENOMEM);
if (lseek(fd, disk->sector_size, SEEK_SET) != disk->sector_size ||
read(fd, buffer, disk->sector_size) != disk->sector_size) {
error = (errno) ? errno : EAGAIN;
goto bail;
}
if (memcmp(buffer, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0) {
/*
* No GPT on disk. Create one out of thin air.
*/
bzero(&hdr[0], sizeof(struct gpt_hdr));
memcpy(hdr[0].hdr_sig, GPT_HDR_SIG, sizeof(hdr[0].hdr_sig));
hdr[0].hdr_revision = GPT_HDR_REVISION;
hdr[0].hdr_size = offsetof(struct gpt_hdr, padding);
hdr[0].hdr_lba_self = 1;
hdr[0].hdr_lba_alt = disk->media_size / disk->sector_size - 1L;
hdr[0].hdr_lba_start = disk->lba_start;
hdr[0].hdr_lba_end = disk->lba_end;
uuid_create(&hdr[0].hdr_uuid, NULL);
hdr[0].hdr_lba_table = 2;
hdr[0].hdr_entries = disk->gpt_size;
hdr[0].hdr_entsz = sizeof(struct gpt_ent);
hdr[1] = hdr[0];
hdr[1].hdr_lba_self = hdr[0].hdr_lba_alt;
hdr[1].hdr_lba_alt = hdr[0].hdr_lba_self;
hdr[1].hdr_lba_table = disk->lba_end + 1;
for (i = 0; i < disk->gpt_size; i++) {
bzero(&tbl[i], sizeof(struct gpt_ent));
uuid_create(&tbl[i].ent_uuid, NULL);
}
goto bail;
}
/*
* We have a GPT on disk. Read it.
*/
memcpy(&hdr[0], buffer, sizeof(struct gpt_hdr));
off = hdr->hdr_lba_table * disk->sector_size;
if (lseek(fd, off, SEEK_SET) != off ||
read(fd, buffer, sz) != sz) {
error = (errno) ? errno : EAGAIN;
goto bail;
}
memcpy(tbl, buffer, sizeof(struct gpt_ent) * disk->gpt_size);
off = hdr->hdr_lba_alt * disk->sector_size;
if (lseek(fd, off, SEEK_SET) != off ||
read(fd, buffer, disk->sector_size) != disk->sector_size) {
error = (errno) ? errno : EAGAIN;
goto bail;
}
memcpy(&hdr[1], buffer, sizeof(struct gpt_hdr));
bail:
free(buffer);
return (error);
}
static int
update_gpt(int fd, const struct disk *disk, struct gpt_hdr *hdr,
struct gpt_ent *tbl)
{
struct gpt_ent *save;
char *buffer;
struct chunk *c;
off_t off;
size_t bufsz;
int error, idx, sav;
error = 0;
/*
* Save the entries of those chunks that have an index. They are
* the ones that exist on disk already.
*/
sav = 0;
for (c = disk->chunks->part; c != NULL; c = c->next) {
if ((c->flags & CHUNK_HAS_INDEX))
sav++;
}
if (sav > 0) {
save = malloc(sav * sizeof(struct gpt_ent));
if (save == NULL)
abort();
sav = 0;
for (c = disk->chunks->part; c != NULL; c = c->next) {
if ((c->flags & CHUNK_HAS_INDEX)) {
idx = CHUNK_FTOI(c->flags);
save[sav] = tbl[idx];
c->flags ^= CHUNK_ITOF(idx);
c->flags |= CHUNK_ITOF(sav);
sav++;
}
}
} else
save = NULL;
/*
* Clear the table entries.
*/
for (idx = 0; idx < disk->gpt_size; idx++) {
uuid_create_nil(&tbl[idx].ent_type, NULL);
tbl[idx].ent_lba_start = 0;
tbl[idx].ent_lba_end = 0;
tbl[idx].ent_attr = 0;
bzero(tbl[idx].ent_name, sizeof(tbl[idx].ent_name));
}
/*
* Repopulate the table from the chunks, possibly using saved
* information.
*/
idx = 0;
for (c = disk->chunks->part; c != NULL; c = c->next) {
if (!(c->flags & CHUNK_HAS_INDEX)) {
switch (c->type) {
case freebsd:
tbl[idx].ent_type = _fbsd;
break;
case efi:
tbl[idx].ent_type = _efi;
break;
case part:
switch (c->subtype) {
case FS_SWAP:
tbl[idx].ent_type = _swap;
break;
case FS_BSDFFS:
tbl[idx].ent_type = _ufs;
break;
default:
return (EINVAL);
}
break;
default:
return (EINVAL);
}
} else {
sav = CHUNK_FTOI(c->flags);
tbl[idx].ent_type = save[sav].ent_type;
memcpy(tbl[idx].ent_name, save[sav].ent_name,
sizeof(tbl[idx].ent_name));
}
tbl[idx].ent_lba_start = c->offset;
tbl[idx].ent_lba_end = c->end;
idx++;
if (idx == disk->gpt_size)
return (ENOSPC);
}
if (save != NULL)
free(save);
hdr[0].hdr_crc_table = crc32(tbl,
disk->gpt_size * sizeof(struct gpt_ent));
hdr[0].hdr_crc_self = 0;
hdr[0].hdr_crc_self = crc32(&hdr[0], hdr[0].hdr_size);
hdr[1].hdr_crc_table = hdr[0].hdr_crc_table;
hdr[1].hdr_crc_self = 0;
hdr[1].hdr_crc_self = crc32(&hdr[1], hdr[1].hdr_size);
/*
* Write the new GPT back to the disk.
*/
bufsz = disk->gpt_size * sizeof(struct gpt_ent);
if (bufsz == 0 || bufsz % disk->sector_size)
bufsz += disk->sector_size;
bufsz = (bufsz / disk->sector_size) * disk->sector_size;
buffer = calloc(1, bufsz);
memcpy(buffer, &hdr[0], sizeof(struct gpt_hdr));
off = hdr[0].hdr_lba_self * disk->sector_size;
if (lseek(fd, off, SEEK_SET) != off ||
write(fd, buffer, disk->sector_size) != disk->sector_size) {
error = (errno) ? errno : EAGAIN;
goto bail;
}
memcpy(buffer, &hdr[1], sizeof(struct gpt_hdr));
off = hdr[1].hdr_lba_self * disk->sector_size;
if (lseek(fd, off, SEEK_SET) != off ||
write(fd, buffer, disk->sector_size) != disk->sector_size) {
error = (errno) ? errno : EAGAIN;
goto bail;
}
memcpy(buffer, tbl, disk->gpt_size * sizeof(struct gpt_ent));
off = hdr[0].hdr_lba_table * disk->sector_size;
if (lseek(fd, off, SEEK_SET) != off ||
write(fd, buffer, bufsz) != bufsz) {
error = (errno) ? errno : EAGAIN;
goto bail;
}
off = hdr[1].hdr_lba_table * disk->sector_size;
if (lseek(fd, off, SEEK_SET) != off ||
write(fd, buffer, bufsz) != bufsz) {
error = (errno) ? errno : EAGAIN;
goto bail;
}
bail:
free(buffer);
return (error);
}
int
Write_Disk(const struct disk *disk)
{
char devname[64];
struct gpt_hdr *hdr;
struct gpt_ent *tbl;
int error, fd;
hdr = malloc(sizeof(struct gpt_hdr) * 2);
if (hdr == NULL)
return (ENOMEM);
tbl = malloc(sizeof(struct gpt_ent) * disk->gpt_size);
if (tbl == NULL) {
free(hdr);
return (ENOMEM);
}
snprintf(devname, sizeof(devname), "%s%s", _PATH_DEV, disk->name);
fd = open(devname, O_RDWR);
if (fd == -1) {
free(tbl);
free(hdr);
return (errno);
}
/*
* We can always write the PMBR, because we reject disks that do not
* have a PMBR and are not virgin.
*/
error = write_pmbr(fd, disk);
if (error)
goto bail;
/*
* Read the existing GPT from disk or otherwise create one out of
* thin air. This way we can preserve the UUIDs and the entry names
* when updating it.
*/
error = read_gpt(fd, disk, hdr, tbl);
if (error)
goto bail;
/*
* Update and write the in-memory copy of the GPT.
*/
error = update_gpt(fd, disk, hdr, tbl);
bail:
close(fd);
free(tbl);
free(hdr);
return (error);
}

View File

@ -1,48 +0,0 @@
/*-
* Copyright (c) 2006 Olivier Houchard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <paths.h>
#include "libdisk.h"
int
Write_Disk(const struct disk *d1)
{
return (0);
}

View File

@ -1,179 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <sys/diskpc98.h>
#include <paths.h>
#include "libdisk.h"
/*
* XXX: A lot of hardcoded 512s probably should be foo->sector_size;
* I'm not sure which, so I leave it like it worked before. --schweikh
*/
static int
Write_FreeBSD(int fd, const struct disk *new, const struct chunk *c1)
{
struct disklabel *dl;
int i;
void *p;
u_char buf[BBSIZE];
for (i = 0; i < BBSIZE / 512; i++) {
if (!(p = read_block(fd, i + c1->offset, 512)))
return (1);
memcpy(buf + 512 * i, p, 512);
free(p);
}
if (new->boot1)
memcpy(buf, new->boot1, 512);
if (new->boot2)
memcpy(buf + 512, new->boot2, BBSIZE - 512);
dl = (struct disklabel *)(buf + 512 * LABELSECTOR + LABELOFFSET);
Fill_Disklabel(dl, new, c1);
for (i = 0; i < BBSIZE / 512; i++)
write_block(fd, i + c1->offset, buf + 512 * i, 512);
return 0;
}
int
Write_Disk(const struct disk *d1)
{
int fd, i, j;
struct chunk *c1;
int ret = 0;
char device[64];
u_char *mbrblk;
struct pc98_partition *dp, work[NDOSPART];
int s[7];
int PC98_EntireDisk = 0;
strcpy(device, _PATH_DEV);
strcat(device, d1->name);
/* XXX - for entire FreeBSD(98) */
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
if ((c1->type == freebsd) || (c1->offset == 0))
device[9] = 0;
}
fd = open(device, O_RDWR);
if (fd < 0) {
#ifdef DEBUG
warn("open(%s) failed", device);
#endif
return 1;
}
memset(s, 0, sizeof s);
if (!(mbrblk = read_block(fd, 1, d1->sector_size))) {
close (fd);
return (1);
}
dp = (struct pc98_partition *)(mbrblk + DOSPARTOFF);
memcpy(work, dp, sizeof work);
dp = work;
free(mbrblk);
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
if (c1->type == unused)
continue;
if (!strcmp(c1->name, "X"))
continue;
j = c1->name[strlen(d1->name) + 1] - '1';
if (j < 0 || j > 7)
continue;
s[j]++;
if (c1->type == freebsd)
ret += Write_FreeBSD(fd, d1, c1);
i = c1->offset;
dp[j].dp_ssect = dp[j].dp_ipl_sct = i % d1->bios_sect;
i -= dp[j].dp_ssect;
i /= d1->bios_sect;
dp[j].dp_shd = dp[j].dp_ipl_head = i % d1->bios_hd;
i -= dp[j].dp_shd;
i /= d1->bios_hd;
dp[j].dp_scyl = dp[j].dp_ipl_cyl = i;
#ifdef DEBUG
printf("S:%lu = (%x/%x/%x)", c1->offset,
dp[j].dp_scyl, dp[j].dp_shd, dp[j].dp_ssect);
#endif
i = c1->end;
#if 1
dp[j].dp_esect = dp[j].dp_ehd = 0;
dp[j].dp_ecyl = i / (d1->bios_sect * d1->bios_hd);
#else
dp[j].dp_esect = i % d1->bios_sect;
i -= dp[j].dp_esect;
i /= d1->bios_sect;
dp[j].dp_ehd = i % d1->bios_hd;
i -= dp[j].dp_ehd;
i /= d1->bios_hd;
dp[j].dp_ecyl = i;
#endif
#ifdef DEBUG
printf(" E:%lu = (%x/%x/%x)\n", c1->end,
dp[j].dp_ecyl, dp[j].dp_ehd, dp[j].dp_esect);
#endif
dp[j].dp_mid = c1->subtype & 0xff;
dp[j].dp_sid = c1->subtype >> 8;
if (c1->flags & CHUNK_ACTIVE)
dp[j].dp_mid |= 0x80;
strncpy(dp[j].dp_name, c1->sname, 16);
}
j = 0;
for (i = 0; i < NDOSPART; i++) {
if (!s[i])
memset(dp + i, 0, sizeof *dp);
}
if (d1->bootipl)
write_block(fd, 0, d1->bootipl, d1->sector_size);
if (!(mbrblk = read_block(fd, 1, d1->sector_size))) {
close (fd);
return (1);
}
memcpy(mbrblk + DOSPARTOFF, dp, sizeof *dp * NDOSPART);
/* XXX - for entire FreeBSD(98) */
for (c1 = d1->chunks->part; c1; c1 = c1->next)
if (((c1->type == freebsd) || (c1->type == fat))
&& (c1->offset == 0))
PC98_EntireDisk = 1;
if (PC98_EntireDisk == 0)
write_block(fd, 1, mbrblk, d1->sector_size);
if (d1->bootmenu)
for (i = 0; i * d1->sector_size < d1->bootmenu_size; i++)
write_block(fd, 2 + i,
&d1->bootmenu[i * d1->sector_size],
d1->sector_size);
close(fd);
return 0;
}

View File

@ -1,64 +0,0 @@
/*-
* Copyright (c) 2004 Suleiman Souhlal.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <paths.h>
#include "libdisk.h"
int
Write_Disk(const struct disk *d1)
{
/*
* We don't have to write any label, so we only check that we can
* open the disk.
*/
int fd;
char device[64];
strcpy(device, _PATH_DEV);
strcat(device, d1->name);
fd = open(device, O_RDWR);
if (fd < 0) {
close(fd);
return 1;
}
close(fd);
return 0;
}

View File

@ -1,106 +0,0 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/sun_disklabel.h>
#include <paths.h>
#include <errno.h>
#include "libdisk.h"
#include "geom_sunlabel_enc.c"
int
Write_Disk(const struct disk *d1)
{
struct sun_disklabel *sl;
struct chunk *c, *c1, *c2;
int i;
char *p;
u_long secpercyl;
char device[64];
u_char buf[SUN_SIZE];
int fd;
strcpy(device, _PATH_DEV);
strcat(device, d1->name);
fd = open(device, O_RDWR);
if (fd < 0) {
warn("open(%s) failed", device);
return (1);
}
sl = calloc(sizeof *sl, 1);
c = d1->chunks;
c2 = c->part;
secpercyl = d1->bios_sect * d1->bios_hd;
sl->sl_pcylinders = c->size / secpercyl;
sl->sl_ncylinders = c2->size / secpercyl;
sl->sl_acylinders = sl->sl_pcylinders - sl->sl_ncylinders;
sl->sl_magic = SUN_DKMAGIC;
sl->sl_nsectors = d1->bios_sect;
sl->sl_ntracks = d1->bios_hd;
if (c->size > 4999 * 1024 * 2) {
sprintf(sl->sl_text, "FreeBSD%luG cyl %u alt %u hd %u sec %u",
(c->size + 1024 * 1024) / (2 * 1024 * 1024),
sl->sl_ncylinders, sl->sl_acylinders,
sl->sl_ntracks, sl->sl_nsectors);
} else {
sprintf(sl->sl_text, "FreeBSD%luM cyl %u alt %u hd %u sec %u",
(c->size + 1024) / (2 * 1024),
sl->sl_ncylinders, sl->sl_acylinders,
sl->sl_ntracks, sl->sl_nsectors);
}
sl->sl_interleave = 1;
sl->sl_sparespercyl = 0;
sl->sl_rpm = 3600;
for (c1 = c2->part; c1 != NULL; c1 = c1->next) {
p = c1->name;
p += strlen(p);
p--;
if (*p < 'a')
continue;
i = *p - 'a';
if (i >= SUN_NPART)
continue;
sl->sl_part[i].sdkp_cyloffset = c1->offset / secpercyl;
sl->sl_part[i].sdkp_nsectors = c1->size;
for (i = 1; i < 16; i++) {
write_block(fd, c1->offset + i, d1->boot1 + (i * 512),
512);
}
}
/*
* We need to fill in the "RAW" partition as well. Emperical data
* seems to indicate that this covers the "obviously" visible part
* of the disk, ie: sl->sl_ncylinders.
*/
sl->sl_part[SUN_RAWPART].sdkp_cyloffset = 0;
sl->sl_part[SUN_RAWPART].sdkp_nsectors = sl->sl_ncylinders * secpercyl;
memset(buf, 0, sizeof buf);
sunlabel_enc(buf, sl);
write_block(fd, 0, buf, sizeof buf);
close(fd);
return 0;
}

View File

@ -45,7 +45,6 @@ LIBCURSES?= ${DESTDIR}${LIBDIR}/libcurses.a
LIBDEVINFO?= ${DESTDIR}${LIBDIR}/libdevinfo.a
LIBDEVSTAT?= ${DESTDIR}${LIBDIR}/libdevstat.a
LIBDIALOG?= ${DESTDIR}${LIBDIR}/libdialog.a
LIBDISK?= ${DESTDIR}${LIBDIR}/libdisk.a
LIBDNS?= ${DESTDIR}${LIBDIR}/libdns.a
LIBDTRACE?= ${DESTDIR}${LIBDIR}/libdtrace.a
LIBDWARF?= ${DESTDIR}${LIBDIR}/libdwarf.a
@ -54,7 +53,6 @@ LIBELF?= ${DESTDIR}${LIBDIR}/libelf.a
LIBFETCH?= ${DESTDIR}${LIBDIR}/libfetch.a
LIBFL?= "don't use LIBFL, use LIBL"
LIBFORM?= ${DESTDIR}${LIBDIR}/libform.a
LIBFTPIO?= ${DESTDIR}${LIBDIR}/libftpio.a
LIBG2C?= ${DESTDIR}${LIBDIR}/libg2c.a
LIBGCC?= ${DESTDIR}${LIBDIR}/libgcc.a
LIBGCC_PIC?= ${DESTDIR}${LIBDIR}/libgcc_pic.a