Imported Upstream version 0.6.3
[platform/upstream/multipath-tools.git] / kpartx / unixware.c
1 #include "kpartx.h"
2 #include <stdio.h>
3
4 #define UNIXWARE_FS_UNUSED     0
5 #define UNIXWARE_NUMSLICE      16
6 #define UNIXWARE_DISKMAGIC     (0xCA5E600D)
7 #define UNIXWARE_DISKMAGIC2    (0x600DDEEE)
8
9 struct unixware_slice {
10         unsigned short s_label;         /* label */
11         unsigned short s_flags;         /* permission flags */
12         unsigned int   start_sect;      /* starting sector */
13         unsigned int   nr_sects;        /* number of sectors in slice */
14 };
15
16 struct unixware_disklabel {
17         unsigned int   d_type;          /* drive type */
18         unsigned char  d_magic[4];      /* the magic number */
19         unsigned int   d_version;       /* version number */
20         char    d_serial[12];           /* serial number of the device */
21         unsigned int   d_ncylinders;    /* # of data cylinders per device */
22         unsigned int   d_ntracks;       /* # of tracks per cylinder */
23         unsigned int   d_nsectors;      /* # of data sectors per track */
24         unsigned int   d_secsize;       /* # of bytes per sector */
25         unsigned int   d_part_start;    /* # of first sector of this partition */
26         unsigned int   d_unknown1[12];  /* ? */
27         unsigned int   d_alt_tbl;       /* byte offset of alternate table */
28         unsigned int   d_alt_len;       /* byte length of alternate table */
29         unsigned int   d_phys_cyl;      /* # of physical cylinders per device */
30         unsigned int   d_phys_trk;      /* # of physical tracks per cylinder */
31         unsigned int   d_phys_sec;      /* # of physical sectors per track */
32         unsigned int   d_phys_bytes;    /* # of physical bytes per sector */
33         unsigned int   d_unknown2;      /* ? */
34         unsigned int   d_unknown3;      /* ? */
35         unsigned int   d_pad[8];        /* pad */
36
37         struct unixware_vtoc {
38                 unsigned char   v_magic[4];     /* the magic number */
39                 unsigned int    v_version;      /* version number */
40                 char    v_name[8];              /* volume name */
41                 unsigned short  v_nslices;      /* # of slices */
42                 unsigned short  v_unknown1;     /* ? */
43                 unsigned int    v_reserved[10]; /* reserved */
44                 struct unixware_slice
45                     v_slice[UNIXWARE_NUMSLICE]; /* slice headers */
46         } vtoc;
47
48 };  /* 408 */
49
50 int
51 read_unixware_pt(int fd, struct slice all, struct slice *sp, int ns) {
52         struct unixware_disklabel *l;
53         struct unixware_slice *p;
54         unsigned int offset = all.start;
55         char *bp;
56         int n = 0;
57
58         bp = getblock(fd, offset+29);   /* 1 sector suffices */
59         if (bp == NULL)
60                 return -1;
61
62         l = (struct unixware_disklabel *) bp;
63         if (four2int(l->d_magic) != UNIXWARE_DISKMAGIC ||
64             four2int(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2)
65                 return -1;
66
67         p = &l->vtoc.v_slice[1];        /* slice 0 is the whole disk. */
68         while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
69                 if (p->s_label == UNIXWARE_FS_UNUSED)
70                         /* nothing */;
71                 else if (n < ns) {
72                         sp[n].start = p->start_sect;
73                         sp[n].size = p->nr_sects;
74                         n++;
75                 } else {
76                         fprintf(stderr,
77                                 "unixware_partition: too many slices\n");
78                         break;
79                 }
80                 p++;
81         }
82         return n;
83 }