disk.c revision 8157
124139Sjoerg/*
224139Sjoerg * ----------------------------------------------------------------------------
324139Sjoerg * "THE BEER-WARE LICENSE" (Revision 42):
424139Sjoerg * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
524139Sjoerg * can do whatever you want with this stuff. If we meet some day, and you think
624139Sjoerg * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
724139Sjoerg * ----------------------------------------------------------------------------
824139Sjoerg *
924139Sjoerg * $Id: disk.c,v 1.2 1995/04/29 01:55:21 phk Exp $
1024139Sjoerg *
1124139Sjoerg */
1224139Sjoerg
1324139Sjoerg#include <stdio.h>
1424139Sjoerg#include <stdlib.h>
1524139Sjoerg#include <unistd.h>
1624139Sjoerg#include <fcntl.h>
1724139Sjoerg#include <string.h>
1824139Sjoerg#include <err.h>
1924139Sjoerg#include <sys/types.h>
2024139Sjoerg#include <sys/ioctl.h>
2124139Sjoerg#include <sys/disklabel.h>
2224139Sjoerg#include <sys/diskslice.h>
2324139Sjoerg#include "libdisk.h"
2424139Sjoerg
2524139Sjoerg#define DOSPTYP_EXTENDED        5
2624139Sjoerg#define DOSPTYP_ONTRACK         84
2724139Sjoerg
2824139Sjoergstruct disk *
2924139SjoergOpen_Disk(char *name)
3024139Sjoerg{
3124139Sjoerg	return Int_Open_Disk(name,0);
3224139Sjoerg}
3324139Sjoerg
3424139Sjoergstruct disk *
3524139SjoergInt_Open_Disk(char *name, u_long size)
3624139Sjoerg{
3724139Sjoerg	int i,fd;
3824139Sjoerg	struct diskslices ds;
3924139Sjoerg	char device[64];
4024139Sjoerg	struct disk *d;
4124139Sjoerg
4224139Sjoerg	strcpy(device,"/dev/r");
4324139Sjoerg	strcat(device,name);
4424139Sjoerg
4524139Sjoerg	fd = open(device,O_RDONLY);
4624139Sjoerg	if (fd < 0) {
4724139Sjoerg		warn("open(%s) failed",device);
4824139Sjoerg		return 0;
4924139Sjoerg	}
5024139Sjoerg	i = ioctl(fd,DIOCGSLICEINFO,&ds);
5124139Sjoerg	if (i < 0) {
5224139Sjoerg		warn("DIOCSLICEINFO(%s) failed",device);
5324139Sjoerg		close(fd);
5424139Sjoerg		return 0;
5524139Sjoerg	}
5624139Sjoerg
5724139Sjoerg	d = (struct disk *)malloc(sizeof *d);
58	if(!d) err(1,"malloc failed");
59
60	memset(d,0,sizeof *d);
61
62	d->name = strdup(name);
63
64	if (!size)
65		size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
66
67	Add_Chunk(d, 0, size, name,whole,0,0);
68	if (ds.dss_slices[COMPATIBILITY_SLICE].ds_offset)
69		Add_Chunk(d, 0, 1, "-",reserved,0,0);
70
71	for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
72		char sname[20];
73		chunk_e ce;
74		u_long flags=0;
75		int subtype=0;
76		if (! ds.dss_slices[i].ds_size)
77			continue;
78		sprintf(sname,"%ss%d",name,i-1);
79		switch (ds.dss_slices[i].ds_type) {
80			case 0xa5:
81				ce = freebsd;
82				break;
83			case 0x1:
84			case 0x6:
85				ce = fat;
86				break;
87			case DOSPTYP_EXTENDED:
88				ce = extended;
89				break;
90			default:
91				ce = foo;
92				subtype = -ds.dss_slices[i].ds_type;
93				break;
94		}
95		flags |= CHUNK_ALIGN;
96		Add_Chunk(d,ds.dss_slices[i].ds_offset,
97			ds.dss_slices[i].ds_size, sname,ce,subtype,flags);
98		if (ce == extended)
99			Add_Chunk(d,ds.dss_slices[i].ds_offset,
100				1, "-",reserved, subtype, flags);
101		if (ds.dss_slices[i].ds_type == 0xa5) {
102			struct disklabel *dl;
103			int j;
104
105			dl = read_disklabel(fd,
106				ds.dss_slices[i].ds_offset + LABELSECTOR);
107			if(dl) {
108				for(j=0; j < dl->d_npartitions; j++) {
109					char pname[20];
110					sprintf(pname,"%s%c",sname,j+'a');
111					if (j == 2)
112						continue;
113					if (!dl->d_partitions[j].p_size)
114						continue;
115					Add_Chunk(d,
116						dl->d_partitions[j].p_offset,
117						dl->d_partitions[j].p_size,
118						pname,part,0,0);
119				}
120			}
121			free(dl);
122		}
123	}
124	close(fd);
125	return d;
126}
127
128void
129Debug_Disk(struct disk *d)
130{
131	printf("Debug_Disk(%s)",d->name);
132	printf("  flags=%lx",d->flags);
133	printf("  real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
134	printf("  bios_geom=%lu/%lu/%lu\n",d->bios_cyl,d->bios_hd,d->bios_sect);
135	Debug_Chunk(d->chunks);
136}
137
138void
139Free_Disk(struct disk *d)
140{
141	if(d->chunks)
142		Free_Chunk(d->chunks);
143	if(d->name)
144		free(d->name);
145	free(d);
146}
147
148struct disk *
149Clone_Disk(struct disk *d)
150{
151	struct disk *d2;
152
153	d2 = (struct disk*) malloc(sizeof *d2);
154	if(!d2) err(1,"malloc failed");
155	*d2 = *d;
156	d2->name = strdup(d2->name);
157	d2->chunks = Clone_Chunk(d2->chunks);
158	return d2;
159}
160
161void
162Collapse_Disk(struct disk *d)
163{
164
165	while(Collapse_Chunk(d,d->chunks))
166		;
167}
168