Now we do writes too.
This commit is contained in:
parent
af9c31e108
commit
2d5caf92d0
@ -1,14 +1,32 @@
|
||||
.PATH: /usr/src/sbin/disklabel
|
||||
OBJS= tst01.o blocks.o disklabel.o dkcksum.o chunk.o disk.o change.o \
|
||||
create_chunk.o rules.o write_disk.o
|
||||
create_chunk.o rules.o write_disk.o data.o
|
||||
CFLAGS+= -Wall -g
|
||||
|
||||
test: tst01
|
||||
cp tst01 /0
|
||||
./tst01 wd1
|
||||
|
||||
fd: tst01
|
||||
-umount /dev/fd1
|
||||
-umount /mnt
|
||||
mount /dev/fd1 /mnt
|
||||
strip tst01
|
||||
gzip < tst01 > /mnt/stand/disklayout
|
||||
chmod 755 /mnt/stand/disklayout
|
||||
-umount /mnt
|
||||
|
||||
BOOTS=/usr/mdec
|
||||
data.o:
|
||||
file2c 'const unsigned char boot1[] = {' '};' \
|
||||
< ${BOOTS}/boot1 > tmp.c
|
||||
file2c 'const unsigned char boot2[] = {' '};' \
|
||||
< ${BOOTS}/boot2 >> tmp.c
|
||||
cc ${CFLAGS} -o data.o -c tmp.c
|
||||
|
||||
tst01: ${OBJS}
|
||||
cc ${CFLAGS} -static -o tst01 ${OBJS} -lreadline -ltermcap
|
||||
#cc ${CFLAGS} -DREADLINE -static -o tst01 ${OBJS} -lreadline -ltermcap
|
||||
cc ${CFLAGS} -static -o tst01 ${OBJS}
|
||||
|
||||
clean:
|
||||
rm -f *.o *.core tst01
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
* $Id: blocks.c,v 1.2 1995/04/29 01:55:17 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -31,3 +31,11 @@ read_block(int fd, daddr_t block)
|
||||
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");
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: chunk.c,v 1.2 1995/04/29 01:55:19 phk Exp $
|
||||
* $Id: chunk.c,v 1.3 1995/04/29 04:00:54 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -190,7 +190,7 @@ Add_Chunk(struct disk *d, u_long offset, u_long size, char *name, chunk_e type,
|
||||
c2->size = c1->size = size;
|
||||
c2->end = c1->end = end;
|
||||
c1->name = strdup(name);
|
||||
c2->name = strdup(name);
|
||||
c2->name = strdup("-");
|
||||
c1->type = type;
|
||||
c2->type = unused;
|
||||
c1->flags = flags;
|
||||
@ -302,6 +302,7 @@ Delete_Chunk(struct disk *d, struct chunk *c)
|
||||
Free_Chunk(c3);
|
||||
goto scan;
|
||||
}
|
||||
Fixup_Names(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: create_chunk.c,v 1.2 1995/04/29 01:55:20 phk Exp $
|
||||
* $Id: create_chunk.c,v 1.3 1995/04/29 07:21:10 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,15 +24,16 @@
|
||||
void
|
||||
Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
|
||||
{
|
||||
struct chunk *c1, *c2, *c3;
|
||||
struct chunk *c1, *c3;
|
||||
int j;
|
||||
char *p=0;
|
||||
|
||||
if (!strcmp(c->name, "X")) return;
|
||||
for (c1 = c->part; c1 ; c1 = c1->next) {
|
||||
if (c1->type == unused) continue;
|
||||
if (c1->type == reserved) continue;
|
||||
if (strcmp(c1->name, "X")) continue;
|
||||
for(j=0;j<=8;j++) {
|
||||
for(j=0;j<8;j++) {
|
||||
if (j == 2)
|
||||
continue;
|
||||
p = malloc(12);
|
||||
@ -56,7 +57,7 @@ Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
|
||||
void
|
||||
Fixup_Extended_Names(struct disk *d, struct chunk *c)
|
||||
{
|
||||
struct chunk *c1, *c2, *c3;
|
||||
struct chunk *c1, *c3;
|
||||
int j;
|
||||
char *p=0;
|
||||
|
||||
@ -127,6 +128,8 @@ int
|
||||
Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
|
||||
{
|
||||
int i;
|
||||
u_long l1,l2,end = offset + size;
|
||||
|
||||
i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
|
||||
Fixup_Names(d);
|
||||
return i;
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: disk.c,v 1.4 1995/04/29 04:50:37 phk Exp $
|
||||
* $Id: disk.c,v 1.5 1995/04/29 07:21:11 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -40,21 +40,24 @@ Int_Open_Disk(char *name, u_long size)
|
||||
struct disklabel dl;
|
||||
char device[64];
|
||||
struct disk *d;
|
||||
struct dos_partition *dp;
|
||||
void *p;
|
||||
|
||||
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;
|
||||
}
|
||||
i = ioctl(fd,DIOCGDINFO,&dl);
|
||||
if (i < 0) {
|
||||
warn("DIOCGDINFO(%s) failed",device);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&dl,0,sizeof dl);
|
||||
ioctl(fd,DIOCGDINFO,&dl);
|
||||
i = ioctl(fd,DIOCGSLICEINFO,&ds);
|
||||
if (i < 0) {
|
||||
warn("DIOCGSLICEINFO(%s) failed",device);
|
||||
@ -62,18 +65,27 @@ Int_Open_Disk(char *name, u_long size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = (struct disk *)malloc(sizeof *d);
|
||||
if(!d) err(1,"malloc failed");
|
||||
if (!size)
|
||||
size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
|
||||
|
||||
memset(d,0,sizeof *d);
|
||||
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;
|
||||
|
||||
}
|
||||
free(p);
|
||||
|
||||
d->bios_sect = dl.d_nsectors;
|
||||
d->bios_hd = dl.d_ntracks;
|
||||
|
||||
d->name = strdup(name);
|
||||
|
||||
if (!size)
|
||||
size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
|
||||
|
||||
if (dl.d_ntracks && dl.d_nsectors)
|
||||
d->bios_cyl = size/(dl.d_ntracks*dl.d_nsectors);
|
||||
@ -85,7 +97,7 @@ Int_Open_Disk(char *name, u_long size)
|
||||
if (Add_Chunk(d, 0, 1, "-",reserved,0,0))
|
||||
warn("Failed to add MBR chunk");
|
||||
|
||||
for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
|
||||
for(i=BASE_SLICE;i < 12 && i<ds.dss_nslices;i++) {
|
||||
char sname[20];
|
||||
chunk_e ce;
|
||||
u_long flags=0;
|
||||
@ -132,18 +144,21 @@ Int_Open_Disk(char *name, u_long size)
|
||||
if (!dl->d_partitions[j].p_size)
|
||||
continue;
|
||||
if (Add_Chunk(d,
|
||||
dl->d_partitions[j].p_offset,
|
||||
dl->d_partitions[j].p_offset +
|
||||
ds.dss_slices[i].ds_offset,
|
||||
dl->d_partitions[j].p_size,
|
||||
pname,part,0,0))
|
||||
warn("Failed to add chunk for partition %c",j + 'a');
|
||||
warn(
|
||||
"Failed to add chunk for partition %c [%lu,%lu]",
|
||||
j + 'a',dl->d_partitions[j].p_offset,dl->d_partitions[j].p_size);
|
||||
}
|
||||
sprintf(pname,"%sd",sname);
|
||||
if (!dl->d_partitions[3].p_size)
|
||||
continue;
|
||||
Add_Chunk(d,
|
||||
dl->d_partitions[3].p_offset,
|
||||
dl->d_partitions[3].p_size,
|
||||
pname,part,0,0);
|
||||
if (dl->d_partitions[3].p_size)
|
||||
Add_Chunk(d,
|
||||
dl->d_partitions[3].p_offset +
|
||||
ds.dss_slices[i].ds_offset,
|
||||
dl->d_partitions[3].p_size,
|
||||
pname,part,0,0);
|
||||
}
|
||||
free(dl);
|
||||
}
|
||||
@ -159,6 +174,8 @@ Debug_Disk(struct disk *d)
|
||||
printf(" flags=%lx",d->flags);
|
||||
printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: libdisk.h,v 1.4 1995/04/29 04:50:38 phk Exp $
|
||||
* $Id: libdisk.h,v 1.5 1995/04/29 07:21:11 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -22,7 +22,6 @@ struct disk {
|
||||
char *name;
|
||||
u_long flags;
|
||||
# define DISK_ON_TRACK 1
|
||||
# define DISK_REAL_GEOM 2
|
||||
u_long real_cyl;
|
||||
u_long real_hd;
|
||||
u_long real_sect;
|
||||
@ -44,9 +43,6 @@ struct chunk {
|
||||
char *name;
|
||||
chunk_e type;
|
||||
int subtype;
|
||||
# define SUBTYPE_BSD_FS 1
|
||||
# define SUBTYPE_BSD_SWAP 2
|
||||
# define SUBTYPE_BSD_UNUSED 3
|
||||
u_long flags;
|
||||
# define CHUNK_PAST_1024 1
|
||||
/* this chunk cannot be booted from */
|
||||
@ -142,6 +138,40 @@ 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implementation details >>> DO NOT USE <<<
|
||||
*/
|
||||
@ -152,11 +182,9 @@ struct chunk * Clone_Chunk(struct chunk *);
|
||||
int Add_Chunk(struct disk *, u_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 *);
|
||||
int Aligned(struct disk *d, u_long offset);
|
||||
u_long Next_Aligned(struct disk *d, u_long offset);
|
||||
u_long Prev_Aligned(struct disk *d, u_long offset);
|
||||
struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e);
|
||||
struct disk * Int_Open_Disk(char *name, u_long size);
|
||||
|
||||
@ -181,6 +209,8 @@ struct disk * Int_Open_Disk(char *name, u_long size);
|
||||
* Make Create_DWIM().
|
||||
*
|
||||
* Make Is_Unchanged(struct disk *d1, struct chunk *c1)
|
||||
*
|
||||
* Make Set_Active_Slice()
|
||||
*
|
||||
*Sample output from tst01:
|
||||
*
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: rules.c,v 1.2 1995/04/29 04:00:56 phk Exp $
|
||||
* $Id: rules.c,v 1.3 1995/04/29 07:21:12 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#include "libdisk.h"
|
||||
|
||||
int
|
||||
Aligned(struct disk *d, u_long offset)
|
||||
Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return 1;
|
||||
@ -31,7 +31,7 @@ Aligned(struct disk *d, u_long offset)
|
||||
}
|
||||
|
||||
u_long
|
||||
Prev_Aligned(struct disk *d, u_long offset)
|
||||
Prev_Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
@ -39,11 +39,37 @@ Prev_Aligned(struct disk *d, u_long offset)
|
||||
}
|
||||
|
||||
u_long
|
||||
Next_Aligned(struct disk *d, u_long offset)
|
||||
Next_Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
return Prev_Aligned(d,offset + d->bios_sect);
|
||||
return Prev_Track_Aligned(d,offset + d->bios_sect);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -58,9 +84,13 @@ Rule_000(struct disk *d, struct chunk *c, char *msg)
|
||||
|
||||
if (c->type != whole)
|
||||
return;
|
||||
for (i=0, c1=c->part; c1; c1=c1->next)
|
||||
if (c1->type != unused)
|
||||
i++;
|
||||
for (i=0, c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->type != reserved)
|
||||
continue;
|
||||
if (c1->type != reserved)
|
||||
continue;
|
||||
i++;
|
||||
}
|
||||
if (i <= NDOSPART)
|
||||
return;
|
||||
sprintf(msg+strlen(msg),
|
||||
@ -86,13 +116,13 @@ Rule_001(struct disk *d, struct chunk *c, char *msg)
|
||||
continue;
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (!Aligned(d,c1->offset))
|
||||
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->end != c1->end && !Aligned(d,c1->end+1))
|
||||
if (c->end != c1->end && !Cyl_Aligned(d,c1->end+1))
|
||||
sprintf(msg+strlen(msg),
|
||||
"chunk '%s' [%ld..%ld] does not end on a track boundary\n",
|
||||
"chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n",
|
||||
c1->name,c1->offset,c1->end);
|
||||
}
|
||||
}
|
||||
@ -143,6 +173,29 @@ Rule_003(struct disk *d, struct chunk *c, char *msg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#4:
|
||||
* Max seven 'part' as children of 'freebsd'
|
||||
*/
|
||||
void
|
||||
Rule_004(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
int i;
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != freebsd)
|
||||
return;
|
||||
for (i=0, c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->type != part)
|
||||
continue;
|
||||
i++;
|
||||
}
|
||||
if (i > 7) {
|
||||
sprintf(msg+strlen(msg),
|
||||
"Max seven 'part' allowed as child of 'freebsd'\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Check_Chunk(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
@ -150,6 +203,7 @@ Check_Chunk(struct disk *d, struct chunk *c, char *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)
|
||||
|
@ -6,16 +6,19 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: tst01.c,v 1.4 1995/04/29 04:50:39 phk Exp $
|
||||
* $Id: tst01.c,v 1.5 1995/04/29 07:21:13 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.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"
|
||||
|
||||
@ -26,6 +29,9 @@ 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;
|
||||
@ -36,7 +42,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
d = Open_Disk(argv[1]);
|
||||
if (!d)
|
||||
err(1,"Coudn't open disk %s",argv[1]);
|
||||
err(1,"Couldn't open disk %s",argv[1]);
|
||||
|
||||
sprintf(myprompt,"%s %s> ",argv[0],argv[1]);
|
||||
while(1) {
|
||||
@ -47,12 +53,18 @@ main(int argc, char **argv)
|
||||
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")) != NULL;)
|
||||
for(cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
|
||||
if (**cp != '\0')
|
||||
cp++;
|
||||
ncmd = cp - cmds;
|
||||
@ -128,9 +140,16 @@ main(int argc, char **argv)
|
||||
d = db;
|
||||
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"))
|
||||
@ -138,6 +157,7 @@ main(int argc, char **argv)
|
||||
printf("CMDS:\n");
|
||||
printf("\tallfreebsd\n");
|
||||
printf("\tbios cyl hd sect\n");
|
||||
printf("\tboot\n");
|
||||
printf("\tcollapse [pointer]\n");
|
||||
printf("\tcreate offset size enum subtype flags\n");
|
||||
printf("\tdelete pointer\n");
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
* $Id: write_disk.c,v 1.1 1995/04/29 07:21:14 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -25,10 +25,166 @@
|
||||
|
||||
#define DOSPTYP_EXTENDED 5
|
||||
#define DOSPTYP_ONTRACK 84
|
||||
#define BBSIZE 8192
|
||||
|
||||
#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,i + c1->offset);
|
||||
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);
|
||||
|
||||
printf("--> Write_FreeBSD()\n");
|
||||
|
||||
for(c2=c1->part;c2;c2=c2->next) {
|
||||
if (c2->type == unused) continue;
|
||||
if (c2->type == reserved) 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 - c1->offset;
|
||||
|
||||
}
|
||||
|
||||
dl->d_bbsize = BBSIZE;
|
||||
|
||||
strcpy(dl->d_typename,c1->name);
|
||||
|
||||
dl->d_secperunit = new->chunks->size;
|
||||
dl->d_secpercyl = 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;
|
||||
|
||||
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 = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
printf("--> Write_Extended()\n");
|
||||
Print_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];
|
||||
void *mbr;
|
||||
struct dos_partition *dp;
|
||||
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,0);
|
||||
dp = (struct dos_partition*) (mbr + DOSPARTOFF);
|
||||
for (c1=d1->chunks->part; c1 ; c1 = c1->next) {
|
||||
if (c1->type == unused) continue;
|
||||
if (c1->type == reserved) continue;
|
||||
if (!strcmp(c1->name,"X")) continue;
|
||||
if (c1->type == extended)
|
||||
ret += Write_Extended(fd, d1,old,c1);
|
||||
if (c1->type == freebsd)
|
||||
ret += Write_FreeBSD(fd, d1,old,c1);
|
||||
j = c1->name[4] - '1';
|
||||
if (j < 0 || j > 3)
|
||||
continue;
|
||||
s[j]++;
|
||||
dp[j].dp_start = c1->offset;
|
||||
dp[j].dp_size = c1->size;
|
||||
|
||||
i = c1->offset;
|
||||
if (i >= 1024*d1->bios_sect*d1->bios_hd)
|
||||
i = 1024*d1->bios_sect*d1->bios_hd - 1;
|
||||
dp[j].dp_ssect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_ssect;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_ssect++;
|
||||
dp[j].dp_shd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_shd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_scyl = i;
|
||||
|
||||
i = c1->end;
|
||||
if (i >= 1024*d1->bios_sect*d1->bios_hd)
|
||||
i = 1024*d1->bios_sect*d1->bios_hd - 1;
|
||||
dp[j].dp_esect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_esect;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_esect++;
|
||||
dp[j].dp_ehd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_ehd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_ecyl = i;
|
||||
switch (c1->type) {
|
||||
case freebsd:
|
||||
dp[j].dp_typ = 0xa5;
|
||||
break;
|
||||
case fat:
|
||||
dp[j].dp_typ = 1;
|
||||
break;
|
||||
case extended:
|
||||
dp[j].dp_typ = 5;
|
||||
break;
|
||||
case foo:
|
||||
dp[j].dp_typ = - c1->subtype;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i=0;i<NDOSPART;i++)
|
||||
if (!s[i])
|
||||
memset(dp+i,0,sizeof *dp);
|
||||
|
||||
write_block(fd,WHERE(0,d1),mbr);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,32 @@
|
||||
.PATH: /usr/src/sbin/disklabel
|
||||
OBJS= tst01.o blocks.o disklabel.o dkcksum.o chunk.o disk.o change.o \
|
||||
create_chunk.o rules.o write_disk.o
|
||||
create_chunk.o rules.o write_disk.o data.o
|
||||
CFLAGS+= -Wall -g
|
||||
|
||||
test: tst01
|
||||
cp tst01 /0
|
||||
./tst01 wd1
|
||||
|
||||
fd: tst01
|
||||
-umount /dev/fd1
|
||||
-umount /mnt
|
||||
mount /dev/fd1 /mnt
|
||||
strip tst01
|
||||
gzip < tst01 > /mnt/stand/disklayout
|
||||
chmod 755 /mnt/stand/disklayout
|
||||
-umount /mnt
|
||||
|
||||
BOOTS=/usr/mdec
|
||||
data.o:
|
||||
file2c 'const unsigned char boot1[] = {' '};' \
|
||||
< ${BOOTS}/boot1 > tmp.c
|
||||
file2c 'const unsigned char boot2[] = {' '};' \
|
||||
< ${BOOTS}/boot2 >> tmp.c
|
||||
cc ${CFLAGS} -o data.o -c tmp.c
|
||||
|
||||
tst01: ${OBJS}
|
||||
cc ${CFLAGS} -static -o tst01 ${OBJS} -lreadline -ltermcap
|
||||
#cc ${CFLAGS} -DREADLINE -static -o tst01 ${OBJS} -lreadline -ltermcap
|
||||
cc ${CFLAGS} -static -o tst01 ${OBJS}
|
||||
|
||||
clean:
|
||||
rm -f *.o *.core tst01
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
* $Id: blocks.c,v 1.2 1995/04/29 01:55:17 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -31,3 +31,11 @@ read_block(int fd, daddr_t block)
|
||||
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");
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: chunk.c,v 1.2 1995/04/29 01:55:19 phk Exp $
|
||||
* $Id: chunk.c,v 1.3 1995/04/29 04:00:54 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -190,7 +190,7 @@ Add_Chunk(struct disk *d, u_long offset, u_long size, char *name, chunk_e type,
|
||||
c2->size = c1->size = size;
|
||||
c2->end = c1->end = end;
|
||||
c1->name = strdup(name);
|
||||
c2->name = strdup(name);
|
||||
c2->name = strdup("-");
|
||||
c1->type = type;
|
||||
c2->type = unused;
|
||||
c1->flags = flags;
|
||||
@ -302,6 +302,7 @@ Delete_Chunk(struct disk *d, struct chunk *c)
|
||||
Free_Chunk(c3);
|
||||
goto scan;
|
||||
}
|
||||
Fixup_Names(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: create_chunk.c,v 1.2 1995/04/29 01:55:20 phk Exp $
|
||||
* $Id: create_chunk.c,v 1.3 1995/04/29 07:21:10 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,15 +24,16 @@
|
||||
void
|
||||
Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
|
||||
{
|
||||
struct chunk *c1, *c2, *c3;
|
||||
struct chunk *c1, *c3;
|
||||
int j;
|
||||
char *p=0;
|
||||
|
||||
if (!strcmp(c->name, "X")) return;
|
||||
for (c1 = c->part; c1 ; c1 = c1->next) {
|
||||
if (c1->type == unused) continue;
|
||||
if (c1->type == reserved) continue;
|
||||
if (strcmp(c1->name, "X")) continue;
|
||||
for(j=0;j<=8;j++) {
|
||||
for(j=0;j<8;j++) {
|
||||
if (j == 2)
|
||||
continue;
|
||||
p = malloc(12);
|
||||
@ -56,7 +57,7 @@ Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
|
||||
void
|
||||
Fixup_Extended_Names(struct disk *d, struct chunk *c)
|
||||
{
|
||||
struct chunk *c1, *c2, *c3;
|
||||
struct chunk *c1, *c3;
|
||||
int j;
|
||||
char *p=0;
|
||||
|
||||
@ -127,6 +128,8 @@ int
|
||||
Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
|
||||
{
|
||||
int i;
|
||||
u_long l1,l2,end = offset + size;
|
||||
|
||||
i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
|
||||
Fixup_Names(d);
|
||||
return i;
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: disk.c,v 1.4 1995/04/29 04:50:37 phk Exp $
|
||||
* $Id: disk.c,v 1.5 1995/04/29 07:21:11 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -40,21 +40,24 @@ Int_Open_Disk(char *name, u_long size)
|
||||
struct disklabel dl;
|
||||
char device[64];
|
||||
struct disk *d;
|
||||
struct dos_partition *dp;
|
||||
void *p;
|
||||
|
||||
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;
|
||||
}
|
||||
i = ioctl(fd,DIOCGDINFO,&dl);
|
||||
if (i < 0) {
|
||||
warn("DIOCGDINFO(%s) failed",device);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&dl,0,sizeof dl);
|
||||
ioctl(fd,DIOCGDINFO,&dl);
|
||||
i = ioctl(fd,DIOCGSLICEINFO,&ds);
|
||||
if (i < 0) {
|
||||
warn("DIOCGSLICEINFO(%s) failed",device);
|
||||
@ -62,18 +65,27 @@ Int_Open_Disk(char *name, u_long size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = (struct disk *)malloc(sizeof *d);
|
||||
if(!d) err(1,"malloc failed");
|
||||
if (!size)
|
||||
size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
|
||||
|
||||
memset(d,0,sizeof *d);
|
||||
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;
|
||||
|
||||
}
|
||||
free(p);
|
||||
|
||||
d->bios_sect = dl.d_nsectors;
|
||||
d->bios_hd = dl.d_ntracks;
|
||||
|
||||
d->name = strdup(name);
|
||||
|
||||
if (!size)
|
||||
size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
|
||||
|
||||
if (dl.d_ntracks && dl.d_nsectors)
|
||||
d->bios_cyl = size/(dl.d_ntracks*dl.d_nsectors);
|
||||
@ -85,7 +97,7 @@ Int_Open_Disk(char *name, u_long size)
|
||||
if (Add_Chunk(d, 0, 1, "-",reserved,0,0))
|
||||
warn("Failed to add MBR chunk");
|
||||
|
||||
for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
|
||||
for(i=BASE_SLICE;i < 12 && i<ds.dss_nslices;i++) {
|
||||
char sname[20];
|
||||
chunk_e ce;
|
||||
u_long flags=0;
|
||||
@ -132,18 +144,21 @@ Int_Open_Disk(char *name, u_long size)
|
||||
if (!dl->d_partitions[j].p_size)
|
||||
continue;
|
||||
if (Add_Chunk(d,
|
||||
dl->d_partitions[j].p_offset,
|
||||
dl->d_partitions[j].p_offset +
|
||||
ds.dss_slices[i].ds_offset,
|
||||
dl->d_partitions[j].p_size,
|
||||
pname,part,0,0))
|
||||
warn("Failed to add chunk for partition %c",j + 'a');
|
||||
warn(
|
||||
"Failed to add chunk for partition %c [%lu,%lu]",
|
||||
j + 'a',dl->d_partitions[j].p_offset,dl->d_partitions[j].p_size);
|
||||
}
|
||||
sprintf(pname,"%sd",sname);
|
||||
if (!dl->d_partitions[3].p_size)
|
||||
continue;
|
||||
Add_Chunk(d,
|
||||
dl->d_partitions[3].p_offset,
|
||||
dl->d_partitions[3].p_size,
|
||||
pname,part,0,0);
|
||||
if (dl->d_partitions[3].p_size)
|
||||
Add_Chunk(d,
|
||||
dl->d_partitions[3].p_offset +
|
||||
ds.dss_slices[i].ds_offset,
|
||||
dl->d_partitions[3].p_size,
|
||||
pname,part,0,0);
|
||||
}
|
||||
free(dl);
|
||||
}
|
||||
@ -159,6 +174,8 @@ Debug_Disk(struct disk *d)
|
||||
printf(" flags=%lx",d->flags);
|
||||
printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: libdisk.h,v 1.4 1995/04/29 04:50:38 phk Exp $
|
||||
* $Id: libdisk.h,v 1.5 1995/04/29 07:21:11 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -22,7 +22,6 @@ struct disk {
|
||||
char *name;
|
||||
u_long flags;
|
||||
# define DISK_ON_TRACK 1
|
||||
# define DISK_REAL_GEOM 2
|
||||
u_long real_cyl;
|
||||
u_long real_hd;
|
||||
u_long real_sect;
|
||||
@ -44,9 +43,6 @@ struct chunk {
|
||||
char *name;
|
||||
chunk_e type;
|
||||
int subtype;
|
||||
# define SUBTYPE_BSD_FS 1
|
||||
# define SUBTYPE_BSD_SWAP 2
|
||||
# define SUBTYPE_BSD_UNUSED 3
|
||||
u_long flags;
|
||||
# define CHUNK_PAST_1024 1
|
||||
/* this chunk cannot be booted from */
|
||||
@ -142,6 +138,40 @@ 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implementation details >>> DO NOT USE <<<
|
||||
*/
|
||||
@ -152,11 +182,9 @@ struct chunk * Clone_Chunk(struct chunk *);
|
||||
int Add_Chunk(struct disk *, u_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 *);
|
||||
int Aligned(struct disk *d, u_long offset);
|
||||
u_long Next_Aligned(struct disk *d, u_long offset);
|
||||
u_long Prev_Aligned(struct disk *d, u_long offset);
|
||||
struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e);
|
||||
struct disk * Int_Open_Disk(char *name, u_long size);
|
||||
|
||||
@ -181,6 +209,8 @@ struct disk * Int_Open_Disk(char *name, u_long size);
|
||||
* Make Create_DWIM().
|
||||
*
|
||||
* Make Is_Unchanged(struct disk *d1, struct chunk *c1)
|
||||
*
|
||||
* Make Set_Active_Slice()
|
||||
*
|
||||
*Sample output from tst01:
|
||||
*
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: rules.c,v 1.2 1995/04/29 04:00:56 phk Exp $
|
||||
* $Id: rules.c,v 1.3 1995/04/29 07:21:12 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#include "libdisk.h"
|
||||
|
||||
int
|
||||
Aligned(struct disk *d, u_long offset)
|
||||
Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return 1;
|
||||
@ -31,7 +31,7 @@ Aligned(struct disk *d, u_long offset)
|
||||
}
|
||||
|
||||
u_long
|
||||
Prev_Aligned(struct disk *d, u_long offset)
|
||||
Prev_Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
@ -39,11 +39,37 @@ Prev_Aligned(struct disk *d, u_long offset)
|
||||
}
|
||||
|
||||
u_long
|
||||
Next_Aligned(struct disk *d, u_long offset)
|
||||
Next_Track_Aligned(struct disk *d, u_long offset)
|
||||
{
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
return Prev_Aligned(d,offset + d->bios_sect);
|
||||
return Prev_Track_Aligned(d,offset + d->bios_sect);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -58,9 +84,13 @@ Rule_000(struct disk *d, struct chunk *c, char *msg)
|
||||
|
||||
if (c->type != whole)
|
||||
return;
|
||||
for (i=0, c1=c->part; c1; c1=c1->next)
|
||||
if (c1->type != unused)
|
||||
i++;
|
||||
for (i=0, c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->type != reserved)
|
||||
continue;
|
||||
if (c1->type != reserved)
|
||||
continue;
|
||||
i++;
|
||||
}
|
||||
if (i <= NDOSPART)
|
||||
return;
|
||||
sprintf(msg+strlen(msg),
|
||||
@ -86,13 +116,13 @@ Rule_001(struct disk *d, struct chunk *c, char *msg)
|
||||
continue;
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (!Aligned(d,c1->offset))
|
||||
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->end != c1->end && !Aligned(d,c1->end+1))
|
||||
if (c->end != c1->end && !Cyl_Aligned(d,c1->end+1))
|
||||
sprintf(msg+strlen(msg),
|
||||
"chunk '%s' [%ld..%ld] does not end on a track boundary\n",
|
||||
"chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n",
|
||||
c1->name,c1->offset,c1->end);
|
||||
}
|
||||
}
|
||||
@ -143,6 +173,29 @@ Rule_003(struct disk *d, struct chunk *c, char *msg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#4:
|
||||
* Max seven 'part' as children of 'freebsd'
|
||||
*/
|
||||
void
|
||||
Rule_004(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
int i;
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != freebsd)
|
||||
return;
|
||||
for (i=0, c1=c->part; c1; c1=c1->next) {
|
||||
if (c1->type != part)
|
||||
continue;
|
||||
i++;
|
||||
}
|
||||
if (i > 7) {
|
||||
sprintf(msg+strlen(msg),
|
||||
"Max seven 'part' allowed as child of 'freebsd'\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Check_Chunk(struct disk *d, struct chunk *c, char *msg)
|
||||
{
|
||||
@ -150,6 +203,7 @@ Check_Chunk(struct disk *d, struct chunk *c, char *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)
|
||||
|
@ -6,16 +6,19 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: tst01.c,v 1.4 1995/04/29 04:50:39 phk Exp $
|
||||
* $Id: tst01.c,v 1.5 1995/04/29 07:21:13 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.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"
|
||||
|
||||
@ -26,6 +29,9 @@ 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;
|
||||
@ -36,7 +42,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
d = Open_Disk(argv[1]);
|
||||
if (!d)
|
||||
err(1,"Coudn't open disk %s",argv[1]);
|
||||
err(1,"Couldn't open disk %s",argv[1]);
|
||||
|
||||
sprintf(myprompt,"%s %s> ",argv[0],argv[1]);
|
||||
while(1) {
|
||||
@ -47,12 +53,18 @@ main(int argc, char **argv)
|
||||
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")) != NULL;)
|
||||
for(cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
|
||||
if (**cp != '\0')
|
||||
cp++;
|
||||
ncmd = cp - cmds;
|
||||
@ -128,9 +140,16 @@ main(int argc, char **argv)
|
||||
d = db;
|
||||
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"))
|
||||
@ -138,6 +157,7 @@ main(int argc, char **argv)
|
||||
printf("CMDS:\n");
|
||||
printf("\tallfreebsd\n");
|
||||
printf("\tbios cyl hd sect\n");
|
||||
printf("\tboot\n");
|
||||
printf("\tcollapse [pointer]\n");
|
||||
printf("\tcreate offset size enum subtype flags\n");
|
||||
printf("\tdelete pointer\n");
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
* $Id: write_disk.c,v 1.1 1995/04/29 07:21:14 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -25,10 +25,166 @@
|
||||
|
||||
#define DOSPTYP_EXTENDED 5
|
||||
#define DOSPTYP_ONTRACK 84
|
||||
#define BBSIZE 8192
|
||||
|
||||
#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,i + c1->offset);
|
||||
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);
|
||||
|
||||
printf("--> Write_FreeBSD()\n");
|
||||
|
||||
for(c2=c1->part;c2;c2=c2->next) {
|
||||
if (c2->type == unused) continue;
|
||||
if (c2->type == reserved) 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 - c1->offset;
|
||||
|
||||
}
|
||||
|
||||
dl->d_bbsize = BBSIZE;
|
||||
|
||||
strcpy(dl->d_typename,c1->name);
|
||||
|
||||
dl->d_secperunit = new->chunks->size;
|
||||
dl->d_secpercyl = 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;
|
||||
|
||||
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 = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
printf("--> Write_Extended()\n");
|
||||
Print_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];
|
||||
void *mbr;
|
||||
struct dos_partition *dp;
|
||||
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,0);
|
||||
dp = (struct dos_partition*) (mbr + DOSPARTOFF);
|
||||
for (c1=d1->chunks->part; c1 ; c1 = c1->next) {
|
||||
if (c1->type == unused) continue;
|
||||
if (c1->type == reserved) continue;
|
||||
if (!strcmp(c1->name,"X")) continue;
|
||||
if (c1->type == extended)
|
||||
ret += Write_Extended(fd, d1,old,c1);
|
||||
if (c1->type == freebsd)
|
||||
ret += Write_FreeBSD(fd, d1,old,c1);
|
||||
j = c1->name[4] - '1';
|
||||
if (j < 0 || j > 3)
|
||||
continue;
|
||||
s[j]++;
|
||||
dp[j].dp_start = c1->offset;
|
||||
dp[j].dp_size = c1->size;
|
||||
|
||||
i = c1->offset;
|
||||
if (i >= 1024*d1->bios_sect*d1->bios_hd)
|
||||
i = 1024*d1->bios_sect*d1->bios_hd - 1;
|
||||
dp[j].dp_ssect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_ssect;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_ssect++;
|
||||
dp[j].dp_shd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_shd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_scyl = i;
|
||||
|
||||
i = c1->end;
|
||||
if (i >= 1024*d1->bios_sect*d1->bios_hd)
|
||||
i = 1024*d1->bios_sect*d1->bios_hd - 1;
|
||||
dp[j].dp_esect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_esect;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_esect++;
|
||||
dp[j].dp_ehd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_ehd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_ecyl = i;
|
||||
switch (c1->type) {
|
||||
case freebsd:
|
||||
dp[j].dp_typ = 0xa5;
|
||||
break;
|
||||
case fat:
|
||||
dp[j].dp_typ = 1;
|
||||
break;
|
||||
case extended:
|
||||
dp[j].dp_typ = 5;
|
||||
break;
|
||||
case foo:
|
||||
dp[j].dp_typ = - c1->subtype;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i=0;i<NDOSPART;i++)
|
||||
if (!s[i])
|
||||
memset(dp+i,0,sizeof *dp);
|
||||
|
||||
write_block(fd,WHERE(0,d1),mbr);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user