mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-24 18:54:52 +00:00
Remove libdisk from the old location.
This commit is contained in:
parent
8a8fb1236d
commit
d93b514f1a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=15398
|
@ -1,23 +0,0 @@
|
|||
LIB= disk
|
||||
SRCS= blocks.c disklabel.c dkcksum.c chunk.c disk.c change.c \
|
||||
create_chunk.c rules.c write_disk.c data.c
|
||||
|
||||
CFLAGS+= -Wall -g
|
||||
CLEANFILES+= tmp.c tst01 tst01.o data.c
|
||||
VPATH= ${.CURDIR}/../../sbin/disklabel
|
||||
NOPROFILE= yes
|
||||
NOSHARED= yes
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
||||
BOOTS=/usr/mdec
|
||||
|
||||
data.c: libdisk.h ${BOOTS}/boot1 ${BOOTS}/boot2
|
||||
file2c 'const unsigned char boot1[] = {' '};' \
|
||||
< ${BOOTS}/boot1 > tmp.c
|
||||
file2c 'const unsigned char boot2[] = {' '};' \
|
||||
< ${BOOTS}/boot2 >> tmp.c
|
||||
mv tmp.c data.c
|
||||
|
||||
tst01: tst01.o libdisk.a
|
||||
cc ${CFLAGS} -static tst01.o -o tst01 libdisk.a
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: blocks.c,v 1.2 1995/04/29 01:55:17 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
void *
|
||||
read_block(int fd, daddr_t block)
|
||||
{
|
||||
void *foo;
|
||||
|
||||
foo = malloc(512);
|
||||
if (!foo)
|
||||
err(1,"malloc");
|
||||
if (-1 == lseek(fd,block * 512,SEEK_SET))
|
||||
err(1,"lseek");
|
||||
if (512 != read(fd,foo, 512))
|
||||
err(1,"read");
|
||||
return foo;
|
||||
}
|
||||
|
||||
void
|
||||
write_block(int fd, daddr_t block, void *foo)
|
||||
{
|
||||
if (-1 == lseek(fd,block * 512,SEEK_SET))
|
||||
err(1,"lseek");
|
||||
if (512 != write(fd,foo, 512))
|
||||
err(1,"write");
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: change.c,v 1.9.2.1 1995/09/20 10:43:01 jkh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <sys/types.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#if 0
|
||||
struct disk *
|
||||
Set_Phys_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect)
|
||||
{
|
||||
struct disk *d = Int_Open_Disk(disk->name,cyl*hd*sect);
|
||||
d->real_cyl = cyl;
|
||||
d->real_hd = hd;
|
||||
d->real_sect = sect;
|
||||
d->bios_cyl = disk->bios_cyl;
|
||||
d->bios_hd = disk->bios_hd;
|
||||
d->bios_sect = disk->bios_sect;
|
||||
d->flags = disk->flags;
|
||||
Free_Disk(disk);
|
||||
return d;
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
Bios_Limit_Chunk(disk->chunks,1024*hd*sect);
|
||||
}
|
||||
|
||||
void
|
||||
All_FreeBSD(struct disk *d, int force_all)
|
||||
{
|
||||
struct chunk *c;
|
||||
|
||||
again:
|
||||
for (c=d->chunks->part;c;c=c->next)
|
||||
if (c->type != unused) {
|
||||
Delete_Chunk(d,c);
|
||||
goto again;
|
||||
}
|
||||
c=d->chunks;
|
||||
Create_Chunk(d,c->offset,c->size,freebsd,0xa5,
|
||||
force_all? CHUNK_FORCE_ALL: 0);
|
||||
}
|
|
@ -1,433 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: chunk.c,v 1.14.2.2 1995/06/05 02:24:25 jkh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#define new_chunk() memset(malloc(sizeof(struct chunk)), 0, sizeof(struct chunk))
|
||||
|
||||
/* Is c2 completely inside c1 ? */
|
||||
|
||||
static int
|
||||
Chunk_Inside(struct chunk *c1, 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;
|
||||
}
|
||||
|
||||
struct chunk *
|
||||
Find_Mother_Chunk(struct chunk *chunks, u_long offset, u_long 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;
|
||||
default:
|
||||
warn("Unsupported mother (0x%x) in Find_Mother_Chunk");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Free_Chunk(struct chunk *c1)
|
||||
{
|
||||
if(!c1) return;
|
||||
if(c1->private && c1->private_free)
|
||||
(*c1->private_free)(c1->private);
|
||||
if(c1->part)
|
||||
Free_Chunk(c1->part);
|
||||
if(c1->next)
|
||||
Free_Chunk(c1->next);
|
||||
free(c1->name);
|
||||
free(c1);
|
||||
}
|
||||
|
||||
struct chunk *
|
||||
Clone_Chunk(struct chunk *c1)
|
||||
{
|
||||
struct chunk *c2;
|
||||
if(!c1)
|
||||
return 0;
|
||||
c2 = new_chunk();
|
||||
if (!c2) err(1,"malloc failed");
|
||||
*c2 = *c1;
|
||||
if (c1->private && c1->private_clone)
|
||||
c2->private = c2->private_clone(c2->private);
|
||||
c2->name = strdup(c2->name);
|
||||
c2->next = Clone_Chunk(c2->next);
|
||||
c2->part = Clone_Chunk(c2->part);
|
||||
return c2;
|
||||
}
|
||||
|
||||
int
|
||||
Insert_Chunk(struct chunk *c2, u_long offset, u_long size, char *name, chunk_e type, int subtype, u_long flags)
|
||||
{
|
||||
struct chunk *ct,*cs;
|
||||
|
||||
/* We will only insert into empty spaces */
|
||||
if (c2->type != unused)
|
||||
return __LINE__;
|
||||
|
||||
ct = new_chunk();
|
||||
if (!ct) err(1,"malloc failed");
|
||||
memset(ct,0,sizeof *ct);
|
||||
ct->disk = c2->disk;
|
||||
ct->offset = offset;
|
||||
ct->size = size;
|
||||
ct->end = offset + size - 1;
|
||||
ct->type = type;
|
||||
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) {
|
||||
cs = new_chunk();
|
||||
if (!cs) err(1,"malloc failed");
|
||||
memset(cs,0,sizeof *cs);
|
||||
cs->disk = c2->disk;
|
||||
cs->offset = offset;
|
||||
cs->size = size;
|
||||
cs->end = offset + size - 1;
|
||||
cs->type = unused;
|
||||
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) err(1,"malloc failed");
|
||||
*cs = *c2;
|
||||
cs->disk = c2->disk;
|
||||
cs->offset = ct->end + 1;
|
||||
cs->size = c2->end - ct->end;
|
||||
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->name = ct->name;
|
||||
c2->type = ct->type;
|
||||
c2->part = ct->part;
|
||||
c2->subtype = ct->subtype;
|
||||
c2->flags = ct->flags;
|
||||
ct->name = 0;
|
||||
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, long offset, u_long size, char *name, chunk_e type,
|
||||
int subtype, u_long flags)
|
||||
{
|
||||
struct chunk *c1,*c2,ct;
|
||||
u_long end = offset + size - 1;
|
||||
ct.offset = offset;
|
||||
ct.end = end;
|
||||
ct.size = size;
|
||||
|
||||
if (type == whole) {
|
||||
d->chunks = c1 = new_chunk();
|
||||
if (!c1) err(1,"malloc failed");
|
||||
memset(c1,0,sizeof *c1);
|
||||
c2 = c1->part = new_chunk();
|
||||
if (!c2) err(1,"malloc failed");
|
||||
memset(c2,0,sizeof *c2);
|
||||
c2->disk = c1->disk = d;
|
||||
c2->offset = c1->offset = offset;
|
||||
c2->size = c1->size = size;
|
||||
c2->end = c1->end = end;
|
||||
c1->name = strdup(name);
|
||||
c2->name = strdup("-");
|
||||
c1->type = type;
|
||||
c2->type = unused;
|
||||
c1->flags = flags;
|
||||
c1->subtype = subtype;
|
||||
return 0;
|
||||
}
|
||||
if (type == freebsd)
|
||||
subtype = 0xa5;
|
||||
c1 = 0;
|
||||
if(!c1 && (type == freebsd || type == fat || type == unknown))
|
||||
c1 = Find_Mother_Chunk(d->chunks,offset,end,extended);
|
||||
if(!c1 && (type == freebsd || type == fat || type == unknown))
|
||||
c1 = Find_Mother_Chunk(d->chunks,offset,end,whole);
|
||||
if(!c1 && type == extended)
|
||||
c1 = Find_Mother_Chunk(d->chunks,offset,end,whole);
|
||||
if(!c1 && type == part)
|
||||
c1 = Find_Mother_Chunk(d->chunks,offset,end,freebsd);
|
||||
if(!c1)
|
||||
return __LINE__;
|
||||
for(c2=c1->part;c2;c2=c2->next) {
|
||||
if (c2->type != unused)
|
||||
continue;
|
||||
if(Chunk_Inside(c2,&ct)) {
|
||||
if (type != freebsd)
|
||||
goto doit;
|
||||
if (!(flags & CHUNK_ALIGN))
|
||||
goto doit;
|
||||
if (offset == d->chunks->offset
|
||||
&& end == d->chunks->end)
|
||||
goto doit;
|
||||
|
||||
/* 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;
|
||||
|
||||
doit:
|
||||
return Insert_Chunk(c2,offset,size,name,
|
||||
type,subtype,flags);
|
||||
}
|
||||
}
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
char *
|
||||
ShowChunkFlags(struct chunk *c)
|
||||
{
|
||||
static char ret[10];
|
||||
|
||||
int i=0;
|
||||
if (c->flags & CHUNK_BSD_COMPAT) ret[i++] = 'C';
|
||||
if (c->flags & CHUNK_ACTIVE) ret[i++] = 'A';
|
||||
if (c->flags & CHUNK_ALIGN) ret[i++] = '=';
|
||||
if (c->flags & CHUNK_PAST_1024) ret[i++] = '>';
|
||||
if (c->flags & CHUNK_IS_ROOT) ret[i++] = 'R';
|
||||
if (c->flags & CHUNK_BAD144) ret[i++] = 'B';
|
||||
ret[i++] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
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(' ');
|
||||
printf("%p %8ld %8lu %8lu %-8s %-8s 0x%02x %s",
|
||||
c1, c1->offset, c1->size, c1->end, c1->name,
|
||||
chunk_n[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);
|
||||
}
|
||||
|
||||
void
|
||||
Bios_Limit_Chunk(struct chunk *c1, u_long limit)
|
||||
{
|
||||
if (c1->part)
|
||||
Bios_Limit_Chunk(c1->part,limit);
|
||||
if (c1->next)
|
||||
Bios_Limit_Chunk(c1->next,limit);
|
||||
if (c1->end >= limit) {
|
||||
c1->flags |= CHUNK_PAST_1024;
|
||||
} else {
|
||||
c1->flags &= ~CHUNK_PAST_1024;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Delete_Chunk(struct disk *d, struct chunk *c)
|
||||
{
|
||||
struct chunk *c1=0,*c2,*c3;
|
||||
chunk_e type = c->type;
|
||||
|
||||
if(type == whole)
|
||||
return 1;
|
||||
if(!c1 && (type == freebsd || type == fat || type == unknown))
|
||||
c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,extended);
|
||||
if(!c1 && (type == freebsd || type == fat || type == unknown))
|
||||
c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole);
|
||||
if(!c1 && type == extended)
|
||||
c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole);
|
||||
if(!c1 && type == part)
|
||||
c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,freebsd);
|
||||
if(!c1)
|
||||
return 1;
|
||||
for(c2=c1->part;c2;c2=c2->next) {
|
||||
if (c2 == c) {
|
||||
c2->type = unused;
|
||||
c2->subtype = 0;
|
||||
c2->flags = 0;
|
||||
free(c2->name);
|
||||
c2->name = strdup("-");
|
||||
Free_Chunk(c2->part);
|
||||
c2->part =0;
|
||||
goto scan;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
scan:
|
||||
for(c2=c1->part;c2;c2=c2->next) {
|
||||
if (c2->type != unused)
|
||||
continue;
|
||||
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) err(1,"malloc failed");
|
||||
*c2 = *c1;
|
||||
c1->next = c2;
|
||||
c1->disk = d;
|
||||
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
|
|
@ -1,359 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: create_chunk.c,v 1.21.2.6 1995/11/18 10:02:10 jkh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskslice.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <err.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
/* Clone these two from sysinstall because we need our own copies
|
||||
* due to link order problems with `crunch'. Feh!
|
||||
*/
|
||||
static int
|
||||
isDebug()
|
||||
{
|
||||
static int debug = 0; /* Allow debugger to tweak it */
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
/* Write something to the debugging port */
|
||||
static void
|
||||
msgDebug(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *dbg;
|
||||
static int DebugFD = -1;
|
||||
|
||||
if (DebugFD == -1)
|
||||
DebugFD = open("/dev/ttyv1", O_RDWR);
|
||||
dbg = (char *)alloca(FILENAME_MAX);
|
||||
strcpy(dbg, "DEBUG: ");
|
||||
va_start(args, fmt);
|
||||
vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
write(DebugFD, dbg, strlen(dbg));
|
||||
}
|
||||
|
||||
void
|
||||
Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
|
||||
{
|
||||
struct chunk *c1, *c3;
|
||||
int j;
|
||||
|
||||
if (!strcmp(c->name, "X")) return;
|
||||
|
||||
/* reset all names to "X" */
|
||||
for (c1 = c->part; c1 ; c1 = c1->next) {
|
||||
c1->oname = c1->name;
|
||||
c1->name = malloc(12);
|
||||
if(!c1->name) err(1,"Malloc failed");
|
||||
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[] = "efghabd";
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fixup_Extended_Names(struct disk *d, 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) err(1,"malloc failed");
|
||||
sprintf(c1->name,"%ss%d",d->chunks->name,j++);
|
||||
if (c1->type == freebsd)
|
||||
Fixup_FreeBSD_Names(d,c1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fixup_Names(struct disk *d)
|
||||
{
|
||||
struct chunk *c1, *c2, *c3;
|
||||
int i,j;
|
||||
|
||||
c1 = d->chunks;
|
||||
for(i=1,c2 = c1->part; c2 ; c2 = c2->next) {
|
||||
c2->flags &= ~CHUNK_BSD_COMPAT;
|
||||
if (c2->type == unused)
|
||||
continue;
|
||||
if (strcmp(c2->name,"X"))
|
||||
continue;
|
||||
c2->oname = malloc(12);
|
||||
if(!c2->oname) err(1,"malloc failed");
|
||||
for(j=1;j<=NDOSPART;j++) {
|
||||
sprintf(c2->oname,"%ss%d",c1->name,j);
|
||||
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);
|
||||
}
|
||||
for(c2 = c1->part; c2 ; c2 = c2->next) {
|
||||
if (c2->type == freebsd) {
|
||||
c2->flags |= CHUNK_BSD_COMPAT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(c2 = c1->part; c2 ; c2 = c2->next) {
|
||||
if (c2->type == freebsd)
|
||||
Fixup_FreeBSD_Names(d,c2);
|
||||
if (c2->type == extended)
|
||||
Fixup_Extended_Names(d,c2);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
|
||||
{
|
||||
int i;
|
||||
u_long l;
|
||||
|
||||
if(!(flags & CHUNK_FORCE_ALL))
|
||||
{
|
||||
/* Never use the first track */
|
||||
if (!offset) {
|
||||
offset += d->bios_sect;
|
||||
size -= d->bios_sect;
|
||||
}
|
||||
|
||||
/* Always end on cylinder boundary */
|
||||
l = (offset+size) % (d->bios_sect * d->bios_hd);
|
||||
size -= l;
|
||||
}
|
||||
|
||||
i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
|
||||
Fixup_Names(d);
|
||||
return i;
|
||||
}
|
||||
|
||||
struct chunk *
|
||||
Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags)
|
||||
{
|
||||
int i;
|
||||
struct chunk *c1;
|
||||
u_long offset,edge;
|
||||
|
||||
if (!parent)
|
||||
parent = d->chunks;
|
||||
for (c1=parent->part; c1 ; c1 = c1->next) {
|
||||
if (c1->type != unused) continue;
|
||||
if (c1->size < size) continue;
|
||||
offset = c1->offset;
|
||||
goto found;
|
||||
}
|
||||
warn("Not enough unused space");
|
||||
return 0;
|
||||
found:
|
||||
if (parent->flags & CHUNK_BAD144) {
|
||||
edge = c1->end - d->bios_sect - 127;
|
||||
if (offset > edge)
|
||||
return 0;
|
||||
if (offset + size > edge)
|
||||
size = edge - offset + 1;
|
||||
}
|
||||
i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
|
||||
if (i) {
|
||||
warn("Didn't cut it");
|
||||
return 0;
|
||||
}
|
||||
Fixup_Names(d);
|
||||
for (c1=parent->part; c1 ; c1 = c1->next)
|
||||
if (c1->offset == offset)
|
||||
return c1;
|
||||
err(1,"Serious internal trouble");
|
||||
}
|
||||
|
||||
int
|
||||
MakeDev(struct chunk *c1, char *path)
|
||||
{
|
||||
char *p = c1->name;
|
||||
u_long cmaj, bmaj, min, unit, part, slice;
|
||||
char buf[BUFSIZ], buf2[BUFSIZ];
|
||||
|
||||
*buf2 = '\0';
|
||||
if (isDebug())
|
||||
msgDebug("MakeDev: Called with %s on path %s\n", p, path);
|
||||
if (!strcmp(p, "X"))
|
||||
return 0;
|
||||
|
||||
if (!strncmp(p, "wd", 2))
|
||||
bmaj = 0, cmaj = 3;
|
||||
else if (!strncmp(p, "sd", 2))
|
||||
bmaj = 4, cmaj = 13;
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
p += 2;
|
||||
if (!isdigit(*p)) {
|
||||
msgDebug("MakeDev: Invalid disk unit passed: %s\n", p);
|
||||
return 0;
|
||||
}
|
||||
unit = *p - '0';
|
||||
p++;
|
||||
if (!*p) {
|
||||
slice = 1;
|
||||
part = 2;
|
||||
goto done;
|
||||
}
|
||||
else if (isdigit(*p)) {
|
||||
unit *= 10;
|
||||
unit += (*p - '0');
|
||||
p++;
|
||||
}
|
||||
if (*p != 's') {
|
||||
msgDebug("MakeDev: `%s' is not a valid slice delimiter\n", p);
|
||||
return 0;
|
||||
}
|
||||
p++;
|
||||
if (!isdigit(*p)) {
|
||||
msgDebug("MakeDev: `%s' is an invalid slice number\n", p);
|
||||
return 0;
|
||||
}
|
||||
slice = *p - '0';
|
||||
p++;
|
||||
if (isdigit(*p)) {
|
||||
slice *= 10;
|
||||
slice += (*p - '0');
|
||||
p++;
|
||||
}
|
||||
slice = slice + 1;
|
||||
if (!*p) {
|
||||
part = 2;
|
||||
if(c1->type == freebsd)
|
||||
sprintf(buf2, "%sc", c1->name);
|
||||
goto done;
|
||||
}
|
||||
if (*p < 'a' || *p > 'h') {
|
||||
msgDebug("MakeDev: `%s' is not a valid partition name.\n", p);
|
||||
return 0;
|
||||
}
|
||||
part = *p - 'a';
|
||||
done:
|
||||
if (isDebug())
|
||||
msgDebug("MakeDev: Unit %d, Slice %d, Part %d\n", unit, slice, part);
|
||||
if (unit > 32)
|
||||
return 0;
|
||||
if (slice > 32)
|
||||
return 0;
|
||||
min = unit * 8 + 65536 * slice + part;
|
||||
sprintf(buf, "%s/r%s", path, c1->name);
|
||||
unlink(buf);
|
||||
if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
|
||||
msgDebug("mknod of %s returned failure status!\n", buf);
|
||||
return 0;
|
||||
}
|
||||
if (*buf2) {
|
||||
sprintf(buf, "%s/r%s", path, buf2);
|
||||
unlink(buf);
|
||||
if (mknod(buf, S_IFCHR|0640, makedev(cmaj,min)) == -1) {
|
||||
msgDebug("mknod of %s returned failure status!\n", buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sprintf(buf, "%s/%s", path, c1->name);
|
||||
unlink(buf);
|
||||
if (mknod(buf, S_IFBLK|0640, makedev(bmaj,min)) == -1) {
|
||||
msgDebug("mknod of %s returned failure status!\n", buf);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
MakeDevChunk(struct chunk *c1, char *path)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = MakeDev(c1, path);
|
||||
if (c1->next)
|
||||
MakeDevChunk(c1->next, path);
|
||||
if (c1->part)
|
||||
MakeDevChunk(c1->part, path);
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
MakeDevDisk(struct disk *d, char *path)
|
||||
{
|
||||
return MakeDevChunk(d->chunks, path);
|
||||
}
|
|
@ -1,327 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: disk.c,v 1.19.2.2 1995/06/05 02:24:27 jkh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#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/diskslice.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#define DOSPTYP_EXTENDED 5
|
||||
#define DOSPTYP_ONTRACK 84
|
||||
|
||||
char *chunk_n[] = {
|
||||
"whole",
|
||||
"unknown",
|
||||
"fat",
|
||||
"freebsd",
|
||||
"extended",
|
||||
"part",
|
||||
"unused",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct disk *
|
||||
Open_Disk(char *name)
|
||||
{
|
||||
return Int_Open_Disk(name,0);
|
||||
}
|
||||
|
||||
struct disk *
|
||||
Int_Open_Disk(char *name, u_long size)
|
||||
{
|
||||
int i,fd;
|
||||
struct diskslices ds;
|
||||
struct disklabel dl;
|
||||
char device[64];
|
||||
struct disk *d;
|
||||
struct dos_partition *dp;
|
||||
void *p;
|
||||
u_long offset = 0;
|
||||
|
||||
strcpy(device,"/dev/r");
|
||||
strcat(device,name);
|
||||
|
||||
d = (struct disk *)malloc(sizeof *d);
|
||||
if(!d) err(1,"malloc failed");
|
||||
memset(d,0,sizeof *d);
|
||||
|
||||
fd = open(device,O_RDONLY);
|
||||
if (fd < 0) {
|
||||
warn("open(%s) failed",device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&dl,0,sizeof dl);
|
||||
ioctl(fd,DIOCGDINFO,&dl);
|
||||
i = ioctl(fd,DIOCGSLICEINFO,&ds);
|
||||
if (i < 0) {
|
||||
warn("DIOCGSLICEINFO(%s) failed",device);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for(i=0;i<ds.dss_nslices;i++)
|
||||
if(ds.dss_slices[i].ds_openmask)
|
||||
printf(" open(%d)=0x%2x",
|
||||
i,ds.dss_slices[i].ds_openmask);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if (!size)
|
||||
size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
|
||||
|
||||
p = read_block(fd,0);
|
||||
dp = (struct dos_partition*)(p+DOSPARTOFF);
|
||||
for(i=0;i<NDOSPART;i++) {
|
||||
if (dp->dp_start >= size) continue;
|
||||
if (dp->dp_start+dp->dp_size >= size) continue;
|
||||
if (!dp->dp_size) continue;
|
||||
|
||||
if (dp->dp_typ == DOSPTYP_ONTRACK) {
|
||||
d->flags |= DISK_ON_TRACK;
|
||||
offset = 63;
|
||||
}
|
||||
|
||||
}
|
||||
free(p);
|
||||
|
||||
d->bios_sect = dl.d_nsectors;
|
||||
d->bios_hd = dl.d_ntracks;
|
||||
|
||||
d->name = strdup(name);
|
||||
|
||||
|
||||
if (dl.d_ntracks && dl.d_nsectors)
|
||||
d->bios_cyl = size/(dl.d_ntracks*dl.d_nsectors);
|
||||
|
||||
if (Add_Chunk(d, -offset, size, name,whole,0,0))
|
||||
warn("Failed to add 'whole' chunk");
|
||||
|
||||
for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
|
||||
char sname[20];
|
||||
chunk_e ce;
|
||||
u_long flags=0;
|
||||
int subtype=0;
|
||||
if (! ds.dss_slices[i].ds_size)
|
||||
continue;
|
||||
ds.dss_slices[i].ds_offset -= offset;
|
||||
sprintf(sname,"%ss%d",name,i-1);
|
||||
subtype = ds.dss_slices[i].ds_type;
|
||||
switch (ds.dss_slices[i].ds_type) {
|
||||
case 0xa5:
|
||||
ce = freebsd;
|
||||
break;
|
||||
case 0x1:
|
||||
case 0x6:
|
||||
case 0x4:
|
||||
ce = fat;
|
||||
break;
|
||||
case DOSPTYP_EXTENDED:
|
||||
ce = extended;
|
||||
break;
|
||||
default:
|
||||
ce = unknown;
|
||||
break;
|
||||
}
|
||||
if (Add_Chunk(d,ds.dss_slices[i].ds_offset,
|
||||
ds.dss_slices[i].ds_size, sname,ce,subtype,flags))
|
||||
warn("failed to add chunk for slice %d",i - 1);
|
||||
|
||||
if (ds.dss_slices[i].ds_type != 0xa5)
|
||||
continue;
|
||||
{
|
||||
struct disklabel dl;
|
||||
char pname[20];
|
||||
int j,k;
|
||||
|
||||
strcpy(pname,"/dev/r");
|
||||
strcat(pname,sname);
|
||||
j = open(pname,O_RDONLY);
|
||||
if (j < 0) {
|
||||
warn("open(%s)",pname);
|
||||
continue;
|
||||
}
|
||||
k = ioctl(j,DIOCGDINFO,&dl);
|
||||
if (k < 0) {
|
||||
warn("ioctl(%s,DIOCGDINFO)",pname);
|
||||
close(j);
|
||||
continue;
|
||||
}
|
||||
close(j);
|
||||
|
||||
for(j=0; j <= dl.d_npartitions; j++) {
|
||||
if (j == RAW_PART)
|
||||
continue;
|
||||
if (j == 3)
|
||||
continue;
|
||||
if (j == dl.d_npartitions) {
|
||||
j = 3;
|
||||
dl.d_npartitions=0;
|
||||
}
|
||||
if (!dl.d_partitions[j].p_size)
|
||||
continue;
|
||||
if (dl.d_partitions[j].p_size +
|
||||
dl.d_partitions[j].p_offset >
|
||||
ds.dss_slices[i].ds_size)
|
||||
continue;
|
||||
sprintf(pname,"%s%c",sname,j+'a');
|
||||
if (Add_Chunk(d,
|
||||
dl.d_partitions[j].p_offset +
|
||||
ds.dss_slices[i].ds_offset,
|
||||
dl.d_partitions[j].p_size,
|
||||
pname,part,
|
||||
dl.d_partitions[j].p_fstype,
|
||||
0) && j != 3)
|
||||
warn(
|
||||
"Failed to add chunk for partition %c [%lu,%lu]",
|
||||
j + 'a',dl.d_partitions[j].p_offset,
|
||||
dl.d_partitions[j].p_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
Fixup_Names(d);
|
||||
Bios_Limit_Chunk(d->chunks,1024*d->bios_hd*d->bios_sect);
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
Debug_Disk(struct disk *d)
|
||||
{
|
||||
printf("Debug_Disk(%s)",d->name);
|
||||
printf(" flags=%lx",d->flags);
|
||||
#if 0
|
||||
printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
|
||||
#endif
|
||||
printf(" bios_geom=%lu/%lu/%lu\n",d->bios_cyl,d->bios_hd,d->bios_sect);
|
||||
printf(" boot1=%p, boot2=%p, bootmgr=%p\n",
|
||||
d->boot1,d->boot2,d->bootmgr);
|
||||
Debug_Chunk(d->chunks);
|
||||
}
|
||||
|
||||
void
|
||||
Free_Disk(struct disk *d)
|
||||
{
|
||||
if(d->chunks) Free_Chunk(d->chunks);
|
||||
if(d->name) free(d->name);
|
||||
if(d->bootmgr) free(d->bootmgr);
|
||||
if(d->boot1) free(d->boot1);
|
||||
if(d->boot2) free(d->boot2);
|
||||
free(d);
|
||||
}
|
||||
|
||||
struct disk *
|
||||
Clone_Disk(struct disk *d)
|
||||
{
|
||||
struct disk *d2;
|
||||
|
||||
d2 = (struct disk*) malloc(sizeof *d2);
|
||||
if(!d2) err(1,"malloc failed");
|
||||
*d2 = *d;
|
||||
d2->name = strdup(d2->name);
|
||||
d2->chunks = Clone_Chunk(d2->chunks);
|
||||
if(d2->bootmgr) {
|
||||
d2->bootmgr = malloc(DOSPARTOFF);
|
||||
memcpy(d2->bootmgr,d->bootmgr,DOSPARTOFF);
|
||||
}
|
||||
if(d2->boot1) {
|
||||
d2->boot1 = malloc(512);
|
||||
memcpy(d2->boot1,d->boot1,512);
|
||||
}
|
||||
if(d2->boot2) {
|
||||
d2->boot2 = malloc(512*15);
|
||||
memcpy(d2->boot2,d->boot2,512*15);
|
||||
}
|
||||
return d2;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
Collapse_Disk(struct disk *d)
|
||||
{
|
||||
|
||||
while(Collapse_Chunk(d,d->chunks))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char * device_list[] = {"wd","sd",0};
|
||||
|
||||
char **
|
||||
Disk_Names()
|
||||
{
|
||||
int i,j,k;
|
||||
char disk[25];
|
||||
char diskname[25];
|
||||
struct stat st;
|
||||
struct diskslices ds;
|
||||
int fd;
|
||||
static char **disks;
|
||||
|
||||
disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS));
|
||||
memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS));
|
||||
k = 0;
|
||||
for (j = 0; device_list[j]; j++) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
sprintf(diskname, "%s%d", device_list[j], i);
|
||||
sprintf(disk, "/dev/r%s", diskname);
|
||||
if (stat(disk, &st) || !(st.st_mode & S_IFCHR))
|
||||
continue;
|
||||
if ((fd = open(disk, O_RDWR)) == -1)
|
||||
continue;
|
||||
if (ioctl(fd, DIOCGSLICEINFO, &ds) == -1) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
disks[k++] = strdup(diskname);
|
||||
if(k == MAX_NO_DISKS)
|
||||
return disks;
|
||||
}
|
||||
}
|
||||
return disks;
|
||||
}
|
||||
|
||||
void
|
||||
Set_Boot_Mgr(struct disk *d, u_char *b)
|
||||
{
|
||||
if (d->bootmgr)
|
||||
free(d->bootmgr);
|
||||
if (!b) {
|
||||
d->bootmgr = 0;
|
||||
} else {
|
||||
d->bootmgr = malloc(DOSPARTOFF);
|
||||
if(!d->bootmgr) err(1,"malloc failed");
|
||||
memcpy(d->bootmgr,b,DOSPARTOFF);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Set_Boot_Blocks(struct disk *d, u_char *b1, u_char *b2)
|
||||
{
|
||||
if (d->boot1) free(d->boot1);
|
||||
d->boot1 = malloc(512);
|
||||
if(!d->boot1) err(1,"malloc failed");
|
||||
memcpy(d->boot1,b1,512);
|
||||
if (d->boot2) free(d->boot2);
|
||||
d->boot2 = malloc(15*512);
|
||||
if(!d->boot2) err(1,"malloc failed");
|
||||
memcpy(d->boot2,b2,15*512);
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
struct disklabel *
|
||||
read_disklabel(int fd, daddr_t block)
|
||||
{
|
||||
struct disklabel *dp;
|
||||
|
||||
dp = (struct disklabel *) read_block(fd,block);
|
||||
if (dp->d_magic != DISKMAGIC)
|
||||
return 0;
|
||||
if (dp->d_magic2 != DISKMAGIC)
|
||||
return 0;
|
||||
if (dkcksum(dp) != 0)
|
||||
return 0;
|
||||
return dp;
|
||||
}
|
|
@ -1,324 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: libdisk.h,v 1.19.2.2 1995/10/13 08:19:12 jkh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#define MAX_NO_DISKS 20
|
||||
/* Max # of disks Disk_Names() will return */
|
||||
|
||||
typedef enum {
|
||||
whole,
|
||||
unknown,
|
||||
fat,
|
||||
freebsd,
|
||||
extended,
|
||||
part,
|
||||
unused,
|
||||
} chunk_e;
|
||||
|
||||
extern char *chunk_n[];
|
||||
|
||||
struct disk {
|
||||
char *name;
|
||||
u_long flags;
|
||||
# define DISK_ON_TRACK 1
|
||||
#if 0
|
||||
u_long real_cyl;
|
||||
u_long real_hd;
|
||||
u_long real_sect;
|
||||
#endif
|
||||
u_long bios_cyl;
|
||||
u_long bios_hd;
|
||||
u_long bios_sect;
|
||||
u_char *bootmgr;
|
||||
u_char *boot1;
|
||||
u_char *boot2;
|
||||
struct chunk *chunks;
|
||||
};
|
||||
|
||||
struct chunk {
|
||||
struct chunk *next;
|
||||
struct chunk *part;
|
||||
struct disk *disk;
|
||||
long offset;
|
||||
u_long size;
|
||||
u_long end;
|
||||
char *name;
|
||||
char *oname;
|
||||
/* Used during Fixup_Names() to avoid renaming more than
|
||||
* absolutely needed.
|
||||
*/
|
||||
chunk_e type;
|
||||
int subtype;
|
||||
u_long flags;
|
||||
# define CHUNK_PAST_1024 1
|
||||
/* this chunk cannot be booted from because it
|
||||
* extends past cylinder 1024
|
||||
*/
|
||||
# define CHUNK_BSD_COMPAT 2
|
||||
/* this chunk is in the BSD-compatibility, and has a
|
||||
* short name too, ie wd0s4f -> wd0f
|
||||
*/
|
||||
# define CHUNK_BAD144 4
|
||||
/* this chunk has bad144 mapping */
|
||||
# define CHUNK_ALIGN 8
|
||||
/* This chunk should be aligned */
|
||||
# define CHUNK_IS_ROOT 16
|
||||
/* This 'part' is a rootfs, allocate 'a' */
|
||||
# define CHUNK_ACTIVE 32
|
||||
/* This is the active slice in the MBR */
|
||||
# define CHUNK_FORCE_ALL 64
|
||||
/* Force a dedicated disk for FreeBSD, bypassing
|
||||
* all BIOS geometry considerations
|
||||
*/
|
||||
|
||||
void (*private_free)(void*);
|
||||
void *(*private_clone)(void*);
|
||||
void *private;
|
||||
/* 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.
|
||||
*/
|
||||
};
|
||||
|
||||
struct disk *
|
||||
Open_Disk(char *devname);
|
||||
/* Will open the named disk, and return populated tree.
|
||||
*/
|
||||
|
||||
struct disk *
|
||||
Clone_Disk(struct disk *disk);
|
||||
/* Clone a copy of a tree. Useful for "Undo" functionality
|
||||
*/
|
||||
|
||||
void
|
||||
Free_Disk(struct disk *disk);
|
||||
/* Free a tree made with Open_Disk() or Clone_Disk()
|
||||
*/
|
||||
|
||||
void
|
||||
Debug_Disk(struct disk *disk);
|
||||
/* Print the content of the tree to stdout
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct disk *
|
||||
Set_Phys_Geom(struct disk *disk, u_long cyl, u_long heads, u_long sects);
|
||||
/* Use a different physical geometry. Makes sense for ST506 disks only.
|
||||
* The tree returned is read from the disk, using this geometry.
|
||||
*/
|
||||
#endif
|
||||
|
||||
void
|
||||
Set_Bios_Geom(struct disk *disk, u_long cyl, u_long heads, u_long sects);
|
||||
/* Set the geometry the bios uses.
|
||||
*/
|
||||
|
||||
int
|
||||
Delete_Chunk(struct disk *disk, struct chunk *);
|
||||
/* Free a chunk of disk_space
|
||||
*/
|
||||
|
||||
void
|
||||
Collapse_Disk(struct disk *disk);
|
||||
/* Experimental, do not use.
|
||||
*/
|
||||
int
|
||||
Collapse_Chunk(struct disk *disk, struct chunk *chunk);
|
||||
/* Experimental, do not use.
|
||||
*/
|
||||
|
||||
int
|
||||
Create_Chunk(struct disk *disk, u_long offset, u_long size, chunk_e type, int subtype, u_long flags);
|
||||
/* Create a chunk with the specified paramters
|
||||
*/
|
||||
|
||||
void
|
||||
All_FreeBSD(struct disk *d, int force_all);
|
||||
/* Make one FreeBSD chunk covering the entire disk;
|
||||
* if force_all is set, bypass all BIOS geometry
|
||||
* considerations.
|
||||
*/
|
||||
|
||||
char *
|
||||
CheckRules(struct disk *);
|
||||
/* Return char* to warnings about broken design rules in this disklayout
|
||||
*/
|
||||
|
||||
char **
|
||||
Disk_Names();
|
||||
/* Return char** with all disk's names (wd0, wd1 ...). You must free
|
||||
* each pointer, as well as the array by hand
|
||||
*/
|
||||
|
||||
void
|
||||
Set_Boot_Mgr(struct disk *d, u_char *bootmgr);
|
||||
/* Use this boot-manager on this disk. Gets written when Write_Disk()
|
||||
* is called
|
||||
*/
|
||||
|
||||
void
|
||||
Set_Boot_Blocks(struct disk *d, u_char *boot1, u_char *boot2);
|
||||
/* Use these boot-blocks on this disk. Gets written when Write_Disk()
|
||||
* is called
|
||||
*/
|
||||
|
||||
int
|
||||
Write_Disk(struct disk *d);
|
||||
/* Write all the MBRs, disklabels, bootblocks and boot managers
|
||||
*/
|
||||
|
||||
int
|
||||
Cyl_Aligned(struct disk *d, u_long offset);
|
||||
/* Check if offset is aligned on a cylinder according to the
|
||||
* bios geometry
|
||||
*/
|
||||
|
||||
u_long
|
||||
Next_Cyl_Aligned(struct disk *d, u_long offset);
|
||||
/* Round offset up to next cylinder according to the bios-geometry
|
||||
*/
|
||||
|
||||
u_long
|
||||
Prev_Cyl_Aligned(struct disk *d, u_long offset);
|
||||
/* Round offset down to previous cylinder according to the bios-
|
||||
* geometry
|
||||
*/
|
||||
|
||||
int
|
||||
Track_Aligned(struct disk *d, u_long offset);
|
||||
/* Check if offset is aligned on a track according to the
|
||||
* bios geometry
|
||||
*/
|
||||
|
||||
u_long
|
||||
Next_Track_Aligned(struct disk *d, u_long offset);
|
||||
/* Round offset up to next track according to the bios-geometry
|
||||
*/
|
||||
|
||||
u_long
|
||||
Prev_Track_Aligned(struct disk *d, u_long offset);
|
||||
/* Check if offset is aligned on a track according to the
|
||||
* bios geometry
|
||||
*/
|
||||
|
||||
struct chunk *
|
||||
Create_Chunk_DWIM(struct disk *d, struct chunk *parent , u_long size, chunk_e type, int subtype, u_long flags);
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
int
|
||||
MakeDev(struct chunk *c, char *path);
|
||||
|
||||
int
|
||||
MakeDevDisk(struct disk *d,char *path);
|
||||
/* Make device nodes for all chunks on this disk */
|
||||
|
||||
char *
|
||||
ShowChunkFlags(struct chunk *c);
|
||||
/* Return string to show flags. */
|
||||
|
||||
char *
|
||||
ChunkCanBeRoot(struct chunk *c);
|
||||
/* Return NULL if chunk can be /, explanation otherwise */
|
||||
|
||||
/*
|
||||
* Implementation details >>> DO NOT USE <<<
|
||||
*/
|
||||
|
||||
void Debug_Chunk(struct chunk *);
|
||||
void Free_Chunk(struct chunk *);
|
||||
struct chunk * Clone_Chunk(struct chunk *);
|
||||
int Add_Chunk(struct disk *, long , u_long , char *, chunk_e, int , u_long);
|
||||
void Bios_Limit_Chunk(struct chunk *, u_long);
|
||||
void * read_block(int, daddr_t );
|
||||
void write_block(int fd, daddr_t block, void *foo);
|
||||
struct disklabel * read_disklabel(int, daddr_t);
|
||||
u_short dkcksum(struct disklabel *);
|
||||
struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e);
|
||||
struct disk * Int_Open_Disk(char *name, u_long size);
|
||||
void Fixup_Names(struct disk *);
|
||||
|
||||
#define dprintf printf
|
||||
|
||||
/* TODO
|
||||
*
|
||||
* Need a 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 real_geom=0/0/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>
|
||||
*
|
||||
*
|
||||
*/
|
|
@ -1,316 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: rules.c,v 1.10.2.1 1995/06/03 08:40:33 jkh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/diskslice.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <err.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
int
|
||||
Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return 1;
|
||||
if (offset % d->bios_sect)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
u_long
|
||||
Prev_Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
return (offset / d->bios_sect) * d->bios_sect;
|
||||
}
|
||||
|
||||
u_long
|
||||
Next_Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
return Prev_Track_Aligned(d,offset + d->bios_sect-1);
|
||||
}
|
||||
|
||||
int
|
||||
Cyl_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect || !d->bios_hd)
|
||||
return 1;
|
||||
if (offset % (d->bios_sect * d->bios_hd))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
u_long
|
||||
Prev_Cyl_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect || !d->bios_hd)
|
||||
return offset;
|
||||
return (offset / (d->bios_sect*d->bios_hd)) * d->bios_sect * d->bios_hd;
|
||||
}
|
||||
|
||||
u_long
|
||||
Next_Cyl_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect || !d->bios_hd)
|
||||
return offset;
|
||||
return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd)-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#0:
|
||||
* Chunks of type 'whole' can have max NDOSPART children.
|
||||
* Only one of them can have the "active" flag
|
||||
*/
|
||||
void
|
||||
Rule_000(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
int i=0,j=0;
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != whole)
|
||||
return;
|
||||
for (c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->type != unused) continue;
|
||||
if (c1->flags & CHUNK_ACTIVE)
|
||||
j++;
|
||||
i++;
|
||||
}
|
||||
if (i > NDOSPART)
|
||||
sprintf(msg+strlen(msg),
|
||||
"%d is too many children of the 'whole' chunk. Max is %d\n",
|
||||
i, NDOSPART);
|
||||
if (j > 1)
|
||||
sprintf(msg+strlen(msg),
|
||||
"Too many active children of 'whole'");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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'
|
||||
*/
|
||||
void
|
||||
Rule_001(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
int i;
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != whole && c->type != extended)
|
||||
return;
|
||||
for (i=0, c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->type == unused) continue;
|
||||
c1->flags |= CHUNK_ALIGN;
|
||||
if (!Track_Aligned(d,c1->offset))
|
||||
sprintf(msg+strlen(msg),
|
||||
"chunk '%s' [%ld..%ld] does not start on a track boundary\n",
|
||||
c1->name,c1->offset,c1->end);
|
||||
if ((c->type == whole || c->end == c1->end)
|
||||
|| Cyl_Aligned(d,c1->end+1))
|
||||
;
|
||||
else
|
||||
sprintf(msg+strlen(msg),
|
||||
"chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n",
|
||||
c1->name,c1->offset,c1->end);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#2:
|
||||
* Max one 'fat' as child of 'whole'
|
||||
*/
|
||||
void
|
||||
Rule_002(struct disk *d, 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'
|
||||
*/
|
||||
void
|
||||
Rule_003(struct disk *d, 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'
|
||||
* If Bad144, space for table must exist.
|
||||
* If Bad144 & root, bad144 table must be inside 1024
|
||||
*/
|
||||
void
|
||||
Rule_004(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
int i=0,k=0;
|
||||
struct chunk *c1;
|
||||
u_long l;
|
||||
|
||||
if (c->type != freebsd)
|
||||
return;
|
||||
|
||||
if (c->flags & CHUNK_BAD144) {
|
||||
l = c->end - 127 - d->bios_sect + 1;
|
||||
for (c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->end < l || c1->type == unused)
|
||||
continue;
|
||||
sprintf(msg+strlen(msg),
|
||||
"Blocks %lu to %lu are needed for bad144 information, but isn't unused.\n",
|
||||
l, c->end);
|
||||
break;
|
||||
}
|
||||
if (c->flags & CHUNK_PAST_1024) {
|
||||
for (c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->flags & CHUNK_IS_ROOT) {
|
||||
sprintf(msg+strlen(msg),
|
||||
"You have assigned root to a slice which uses bad144, and\n extends past the first 1023 cylinders, and thus cannot be booted from.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->type != part)
|
||||
continue;
|
||||
if (c1->flags & CHUNK_IS_ROOT) {
|
||||
k++;
|
||||
if (c1->flags & CHUNK_PAST_1024)
|
||||
sprintf(msg+strlen(msg),
|
||||
"Root filesystem extends past cylinder 1024, and cannot be booted from\n");
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Check_Chunk(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
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);
|
||||
|
||||
if (c->end >= 1024*d->bios_hd*d->bios_sect)
|
||||
c->flags |= CHUNK_PAST_1024;
|
||||
else
|
||||
c->flags &= ~CHUNK_PAST_1024;
|
||||
}
|
||||
|
||||
char *
|
||||
CheckRules(struct disk *d)
|
||||
{
|
||||
char msg[BUFSIZ];
|
||||
|
||||
*msg = '\0';
|
||||
Check_Chunk(d,d->chunks,msg);
|
||||
if (*msg)
|
||||
return strdup(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
ChunkCanBeRoot(struct chunk *c)
|
||||
{
|
||||
struct chunk *c1;
|
||||
struct disk *d = c->disk;
|
||||
char msg[BUFSIZ];
|
||||
|
||||
*msg = '\0';
|
||||
if (c->flags & CHUNK_PAST_1024) {
|
||||
strcat(msg,
|
||||
"The root partition must end before cylinder 1024 seen from\n");
|
||||
strcat(msg,
|
||||
"the BIOS' point of view, or it cannot be booted from.\n");
|
||||
return strdup(msg);
|
||||
}
|
||||
for (c1=d->chunks->part;;) {
|
||||
for (; c1; c1=c1->next)
|
||||
if (c1->offset <= c->offset && c1->end >= c->end)
|
||||
break;
|
||||
if (!c1) {
|
||||
strcat(msg,
|
||||
"Internal trouble, cannot find this chunk in the chunk-tree\n");
|
||||
return strdup(msg);
|
||||
}
|
||||
if (c1->type == freebsd)
|
||||
break;
|
||||
c1 = c1->part;
|
||||
}
|
||||
|
||||
if (c1->type != freebsd) {
|
||||
strcat(msg,
|
||||
"The root partition must be in a FreeBSD slice, otherwise\n");
|
||||
strcat(msg,
|
||||
"the kernel cannot be booted from it\n");
|
||||
return strdup(msg);
|
||||
}
|
||||
|
||||
if ((c1->flags & CHUNK_BAD144) && (c1->flags & CHUNK_PAST_1024)) {
|
||||
strcat(msg,
|
||||
"This partition is unsuitable for root, because the FreeBSD slice\n");
|
||||
strcat(msg,
|
||||
"it is inside has bad144 enabled, but the badblock data lives past\n");
|
||||
strcat(msg,
|
||||
"the 1024th cylinder, and the bootblocks cannot get to it there.\n");
|
||||
return strdup(msg);
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -1,313 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: tst01.c,v 1.15.2.1 1995/09/20 10:43:04 jkh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#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 "libdisk.h"
|
||||
|
||||
u_char mbr[] = {
|
||||
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
|
||||
};
|
||||
|
||||
int
|
||||
scan_block(int fd, daddr_t block)
|
||||
{
|
||||
u_char foo[512];
|
||||
|
||||
if (-1 == lseek(fd,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,"/dev/r");
|
||||
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(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,"mknod")) {
|
||||
MakeDevDisk(d,"/tmp");
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"delete") && ncmd == 2) {
|
||||
printf("delete = %d\n",
|
||||
Delete_Chunk(d,
|
||||
(struct chunk *)strtol(cmds[1],0,0)));
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"allfreebsd")) {
|
||||
All_FreeBSD(d, 0);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"dedicate")) {
|
||||
All_FreeBSD(d, 1);
|
||||
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;
|
||||
}
|
||||
#if 0
|
||||
if (!strcasecmp(*cmds,"phys") && ncmd == 4) {
|
||||
d = Set_Phys_Geom(d,
|
||||
strtol(cmds[1],0,0),
|
||||
strtol(cmds[2],0,0),
|
||||
strtol(cmds[3],0,0));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
if (!strcasecmp(*cmds,"collapse")) {
|
||||
if (cmds[1])
|
||||
while (Collapse_Chunk(d,
|
||||
(struct chunk *)strtol(cmds[1],0,0)))
|
||||
;
|
||||
else
|
||||
Collapse_Disk(d);
|
||||
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;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"create") && ncmd == 6) {
|
||||
|
||||
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),
|
||||
strtol(cmds[5],0,0)));
|
||||
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;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"bteasy")) {
|
||||
Set_Boot_Mgr(d,bteasy17);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"mbr")) {
|
||||
Set_Boot_Mgr(d,mbr);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"boot")) {
|
||||
extern u_char boot1[],boot2[];
|
||||
Set_Boot_Blocks(d,boot1,boot2);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"write")) {
|
||||
printf("Write=%d\n",
|
||||
Write_Disk(d));
|
||||
Free_Disk(d);
|
||||
d = Open_Disk(d->name);
|
||||
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");
|
||||
printf("\tbteasy17\n");
|
||||
#if 0
|
||||
printf("\tcollapse [pointer]\n");
|
||||
#endif
|
||||
printf("\tcreate offset size enum subtype flags\n");
|
||||
printf("\t\tsubtype(part): swap=1, ffs=7\n");
|
||||
printf("\tdelete pointer\n");
|
||||
printf("\tlist\n");
|
||||
printf("\tmbr\n");
|
||||
#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");
|
||||
for(i=0;chunk_n[i];i++)
|
||||
printf("%d = %s%s",i,chunk_n[i],i == 4 ? "\n\t" : " ");
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
exit (0);
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: write_disk.c,v 1.15 1995/08/26 04:57:03 davidg Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#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/diskslice.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#define DOSPTYP_EXTENDED 5
|
||||
#define BBSIZE 8192
|
||||
#define SBSIZE 8192
|
||||
#define DEF_RPM 3600
|
||||
#define DEF_INTERLEAVE 1
|
||||
|
||||
#define WHERE(offset,disk) (disk->flags & DISK_ON_TRACK ? offset + 63 : offset)
|
||||
int
|
||||
Write_FreeBSD(int fd, struct disk *new, struct disk *old, struct chunk *c1)
|
||||
{
|
||||
struct disklabel *dl;
|
||||
struct chunk *c2;
|
||||
int i,j;
|
||||
void *p;
|
||||
u_char buf[BBSIZE];
|
||||
|
||||
for(i=0;i<BBSIZE/512;i++) {
|
||||
p = read_block(fd,WHERE(i + c1->offset,new));
|
||||
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);
|
||||
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[5] - 'a';
|
||||
if (j < 0 || j >= MAXPARTITIONS || j == RAW_PART) {
|
||||
warn("Weird parititon letter %c",c2->name[5]);
|
||||
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 = SBSIZE;
|
||||
dl->d_interleave = DEF_INTERLEAVE;
|
||||
dl->d_rpm = DEF_RPM;
|
||||
|
||||
strcpy(dl->d_typename,c1->name);
|
||||
|
||||
dl->d_secsize = 512;
|
||||
dl->d_secperunit = new->chunks->size;
|
||||
#if 0
|
||||
dl->d_ncylinders = new->real_cyl ? new->real_cyl : new->bios_cyl;
|
||||
dl->d_ntracks = new->real_hd ? new->real_hd : new->bios_hd;
|
||||
dl->d_nsectors = new->real_sect ? new->real_sect : new->bios_sect;
|
||||
#else
|
||||
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' ? DTYPE_SCSI : DTYPE_ESDI;
|
||||
dl->d_partitions[RAW_PART].p_size = c1->size;
|
||||
dl->d_partitions[RAW_PART].p_offset = c1->offset;
|
||||
|
||||
if(new->flags & DISK_ON_TRACK)
|
||||
for(i=0;i<MAXPARTITIONS;i++)
|
||||
if (dl->d_partitions[i].p_size)
|
||||
dl->d_partitions[i].p_offset += 63;
|
||||
dl->d_magic = DISKMAGIC;
|
||||
dl->d_magic2 = DISKMAGIC;
|
||||
dl->d_checksum = dkcksum(dl);
|
||||
|
||||
for(i=0;i<BBSIZE/512;i++) {
|
||||
write_block(fd,WHERE(i + c1->offset,new),buf+512*i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Write_Extended(int fd, struct disk *new, struct disk *old, struct chunk *c1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Write_Disk(struct disk *d1)
|
||||
{
|
||||
int fd,i,j;
|
||||
struct disk *old = 0;
|
||||
struct chunk *c1;
|
||||
int ret = 0;
|
||||
char device[64];
|
||||
u_char *mbr;
|
||||
struct dos_partition *dp,work[NDOSPART];
|
||||
int s[4];
|
||||
|
||||
strcpy(device,"/dev/r");
|
||||
strcat(device,d1->name);
|
||||
|
||||
fd = open(device,O_RDWR);
|
||||
if (fd < 0) {
|
||||
warn("open(%s) failed",device);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(s,0,sizeof s);
|
||||
mbr = read_block(fd,WHERE(0,d1));
|
||||
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[4] - '1';
|
||||
if (j < 0 || j > 3)
|
||||
continue;
|
||||
s[j]++;
|
||||
if (c1->type == extended)
|
||||
ret += Write_Extended(fd, d1,old,c1);
|
||||
if (c1->type == freebsd)
|
||||
ret += Write_FreeBSD(fd, d1,old,c1);
|
||||
|
||||
dp[j].dp_start = c1->offset;
|
||||
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;
|
||||
} 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;
|
||||
|
||||
mbr = read_block(fd,WHERE(0,d1));
|
||||
if (d1->bootmgr)
|
||||
memcpy(mbr,d1->bootmgr,DOSPARTOFF);
|
||||
memcpy(mbr+DOSPARTOFF,dp,sizeof *dp * NDOSPART);
|
||||
mbr[512-2] = 0x55;
|
||||
mbr[512-1] = 0xaa;
|
||||
write_block(fd,WHERE(0,d1),mbr);
|
||||
|
||||
i = 1;
|
||||
i = ioctl(fd,DIOCSYNCSLICEINFO,&i);
|
||||
if (i != 0)
|
||||
warn("ioctl(DIOCSYNCSLICEINFO)");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in a new issue