1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * Auto partitioning code.
26 */
27
28#include <stdio.h>
29#include <ctype.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <string.h>
33#include <err.h>
34#include "disk.h"
35#include "mbr.h"
36#include "auto.h"
37
38int AUTO_boothfs __P((disk_t *, mbr_t *));
39int AUTO_hfs __P((disk_t *, mbr_t *));
40int AUTO_dos __P((disk_t *, mbr_t *));
41int AUTO_raid __P((disk_t *, mbr_t *));
42
43/* The default style is the first one in the list */
44struct _auto_style {
45  char *style_name;
46  int (*style_fn)(disk_t *, mbr_t *);
47  char *description;
48} style_fns[] = {
49  {"boothfs", AUTO_boothfs, "8Mb boot plus HFS+ root partition"},
50  {"hfs",     AUTO_hfs,     "Entire disk as one HFS+ partition"},
51  {"dos",     AUTO_dos,     "Entire disk as one DOS partition"},
52  {"raid",    AUTO_raid,    "Entire disk as one 0xAC partition"},
53  {0,0}
54};
55
56void
57AUTO_print_styles(FILE *f)
58{
59  struct _auto_style *fp;
60  int i;
61
62  for (i=0, fp = &style_fns[0]; fp->style_name != NULL; i++, fp++) {
63    fprintf(f, "  %-10s  %s%s\n", fp->style_name, fp->description, (i==0) ? " (default)" : "");
64  }
65}
66
67
68int
69AUTO_init(disk_t *disk, char *style, mbr_t *mbr)
70{
71  struct _auto_style *fp;
72
73  for (fp = &style_fns[0]; fp->style_name != NULL; fp++) {
74    /* If style is NULL, use the first (default) style */
75    if (style == NULL || strcasecmp(style, fp->style_name) == 0) {
76      return (*fp->style_fn)(disk, mbr);
77    }
78  }
79  warnx("No such auto-partition style %s", style);
80  return AUTO_ERR;
81}
82
83
84static int
85use_whole_disk(disk_t *disk, unsigned char id, mbr_t *mbr)
86{
87  MBR_clear(mbr);
88  mbr->part[0].id = id;
89  mbr->part[0].bs = 63;
90  mbr->part[0].ns = disk->real->size - 63;
91  PRT_fix_CHS(disk, &mbr->part[0], 0);
92  return AUTO_OK;
93}
94
95/* DOS style: one partition for the whole disk */
96int
97AUTO_dos(disk_t *disk, mbr_t *mbr)
98{
99  int cc;
100  cc = use_whole_disk(disk, 0x0C, mbr);
101  if (cc == AUTO_OK) {
102    mbr->part[0].flag = DOSACTIVE;
103  }
104  return cc;
105}
106
107/* HFS style: one partition for the whole disk */
108int
109AUTO_hfs(disk_t *disk, mbr_t *mbr)
110{
111  int cc;
112  cc = use_whole_disk(disk, 0xAF, mbr);
113  if (cc == AUTO_OK) {
114    mbr->part[0].flag = DOSACTIVE;
115  }
116  return cc;
117}
118
119/* One boot partition, one HFS+ root partition */
120int
121AUTO_boothfs (disk_t *disk, mbr_t *mbr)
122{
123  /* Check disk size. */
124  if (disk->real->size < 16 * 2048) {
125    errx(1, "Disk size must be greater than 16Mb");
126    return AUTO_ERR;
127  }
128
129  MBR_clear(mbr);
130
131  /* 8MB boot partition */
132  mbr->part[0].id = 0xAB;
133  mbr->part[0].bs = 63;
134  mbr->part[0].ns = 8 * 1024 * 2;
135  mbr->part[0].flag = DOSACTIVE;
136  PRT_fix_CHS(disk, &mbr->part[0], 0);
137
138  /* Rest of the disk for rooting */
139  mbr->part[1].id = 0xAF;
140  mbr->part[1].bs = (mbr->part[0].bs + mbr->part[0].ns);
141  mbr->part[1].ns = disk->real->size - mbr->part[0].ns - 63;
142  PRT_fix_CHS(disk, &mbr->part[1], 1);
143
144  return AUTO_OK;
145}
146
147
148
149/* RAID style: one 0xAC partition for the whole disk */
150int
151AUTO_raid(disk_t *disk, mbr_t *mbr)
152{
153  return use_whole_disk(disk, 0xAC, mbr);
154}
155
156