4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 #pragma ident "%Z%%M% %I% %E% SMI"
27 #include <sys/promif.h>
28 #include <sys/salib.h>
30 #define MAX_CMDLINE 1600 /* from GRUB source */
40 #define ENTRY_ALLOC_COUNT 10
42 extern void set_default_fs(char *fsw_name
);
43 extern int mountroot(char *str
);
50 titles
= (char **)calloc(ENTRY_ALLOC_COUNT
, sizeof (char *));
51 datasets
= (char **)calloc(ENTRY_ALLOC_COUNT
, sizeof (char *));
52 if (titles
== NULL
|| datasets
== NULL
)
53 prom_panic("out of mem");
54 menu_table_size
= ENTRY_ALLOC_COUNT
;
59 add_title_entry(char *title_str
)
62 /* skip leading white space */
63 while (isspace(*title_str
))
66 if (menu_entry_count
== menu_table_size
) {
67 printf("Reallocating at count %d\n", menu_table_size
);
68 titles
= (char **)reallocarray(titles
, ENTRY_ALLOC_COUNT
,
70 datasets
= reallocarray(datasets
, ENTRY_ALLOC_COUNT
,
72 if (titles
== NULL
|| datasets
== NULL
)
73 prom_panic("out of mem");
74 menu_table_size
+= ENTRY_ALLOC_COUNT
;
78 free(titles
[menu_entry_count
]);
79 if ((titles
[menu_entry_count
] = strdup(title_str
)) == NULL
)
80 prom_panic("out of mem");
85 add_dataset_entry(char *dataset_str
)
89 /* skip leading white space */
90 while (isspace(*dataset_str
))
93 /* if there is still any white space in the line, it's invalid */
94 for (cp
= dataset_str
; *cp
; cp
++)
98 return; /* dataset name was invalid */
101 return; /* dataset line was not preceded by a title */
103 if ((datasets
[menu_entry_count
] = strdup(dataset_str
)) == NULL
)
104 prom_panic("out of mem");
111 trim_white_space(char *cp
)
115 /* skip leading white space */
120 * if the string contained nothing but white space, return a
126 /* truncate trailing white space */
127 for (ep
= cp
+ strlen(cp
) - 1; isspace(*ep
); ep
--)
134 char *cons_gets(char *, int);
139 char linebuf
[MAX_CMDLINE
];
143 unsigned long choice
;
145 prom_init("bootlst", cif
);
146 set_default_fs("promfs");
147 if (mountroot("bootfs") != 0)
148 prom_panic("can't mount root");
150 if ((file
= fopen("/boot/menu.lst", "r")) == NULL
)
151 prom_panic("can't open menu.lst");
154 while (fgets(linebuf
, MAX_CMDLINE
, file
)) {
155 cp
= trim_white_space(linebuf
);
157 /* skip comments and blank lines */
158 if (*cp
== '#' || *cp
== '\0')
161 /* find end of first keyword on line */
162 for (ep
= cp
; !isspace(*ep
) && *ep
; ep
++)
165 /* if at the end of the line, the line had no arguments */
171 if (strcmp(cp
, "title") == 0) {
172 add_title_entry(ep
+ 1);
176 if (strcmp(cp
, "bootfs") == 0) {
177 add_dataset_entry(ep
+ 1);
182 if (menu_entry_count
== 0)
183 prom_panic("no menu entries found");
185 for (n
= 0; n
< menu_entry_count
; n
++) {
186 printf("%d %s\n", n
+ 1, titles
[n
]);
189 printf("Select environment to boot: [ 1 - %d ]: ", menu_entry_count
);
191 while (cons_gets(linebuf
, MAX_CMDLINE
)) {
192 /* cut off leading and trailing white space */
193 cp
= trim_white_space(linebuf
);
194 choice
= strtoul(cp
, NULL
, 0);
197 * If the input is totally invalid, the return value of
198 * strtoul() will be 0 or ULONG_MAX. Either way, it's
199 * of the acceptable range.
201 if (choice
== 0 || choice
> menu_entry_count
) {
202 printf("Invalid entry.\n");
205 /* XXX here is the result */
206 printf("\nTo boot the selected entry, invoke:\n");
207 printf("boot [<root-device>] -Z %s\n\n", datasets
[choice
- 1]);