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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * This file contains all the functions that get/set fields
28 * in a GRUB menu entry.
35 #include <sys/types.h>
39 #include "libgrub_cmd.def"
40 #include "libgrub_impl.h"
42 typedef int (*barg_parsef_t
)(const grub_line_t
*, grub_barg_t
*);
43 static const barg_parsef_t barg_parse
[] = {
44 #define menu_cmd(cmd, num, flag, parsef) parsef,
45 #include "libgrub_cmd.def"
49 * Remove extra '/', stops at first isspace character.
50 * Return new string length.
53 clean_path(char *path
)
60 for (i
= 0; (c
= path
[i
]) != 0 && !isspace(c
); i
++) {
61 if (c
== '/' && (k
= strspn(path
+ i
, "/") - 1) != 0) {
62 /* bcopy should deal with overlapping buffers */
64 bcopy(path
+ i
+ k
, path
+ i
, n
- i
);
71 * Construct boot command line from the ge_barg field
74 barg_cmdline(const grub_barg_t
*barg
, char *cmd
, size_t size
)
77 const grub_fsdesc_t
*fsd
;
79 if (!IS_BARG_VALID(barg
) ||
80 (fsd
= grub_get_rootfsd(&barg
->gb_root
)) == NULL
)
83 /* if disk/top dataset is mounted, use mount point */
84 if (fsd
->gfs_mountp
[0] != 0) {
85 if ((n
= snprintf(cmd
, size
, "%s%s", fsd
->gfs_mountp
,
86 barg
->gb_kernel
)) >= size
)
88 return (clean_path(cmd
));
90 return (snprintf(cmd
, size
, "%s %s", fsd
->gfs_dev
,
96 * Construct ge_barg field based on the other fields of the entry.
97 * Return 0 on success, errno on failure.
100 grub_entry_construct_barg(grub_entry_t
*ent
)
104 grub_line_t
*lp
, *lend
;
109 barg
= &ent
->ge_barg
;
115 (void) memset(barg
, 0, sizeof (*barg
));
116 barg
->gb_entry
= ent
;
117 (void) bcopy(&mp
->gm_root
, &barg
->gb_root
, sizeof (barg
->gb_root
));
119 lend
= ent
->ge_end
->gl_next
;
120 for (lp
= ent
->ge_start
; lp
!= lend
; lp
= lp
->gl_next
) {
121 if (lp
->gl_cmdtp
>= GRBM_CMD_NUM
)
124 ret
= barg_parse
[lp
->gl_cmdtp
](lp
, barg
);
130 barg
->gb_errline
= lp
;
132 /* at least kernel and module should be defined */
133 if (barg
->gb_kernel
[0] != 0 && barg
->gb_module
[0] != 0)
134 barg
->gb_flags
|= GRBM_VALID_FLAG
;
141 grub_entry_get_fstyp(const grub_entry_t
*ent
)
143 if (IS_ENTRY_BARG_VALID(ent
))
144 return (ent
->ge_barg
.gb_root
.gr_fstyp
);
150 grub_entry_get_kernel(const grub_entry_t
*ent
)
152 if (IS_ENTRY_BARG_VALID(ent
))
153 return (ent
->ge_barg
.gb_kernel
);
159 grub_entry_get_module(const grub_entry_t
*ent
)
161 if (IS_ENTRY_BARG_VALID(ent
))
162 return (ent
->ge_barg
.gb_module
);
168 grub_entry_get_error_desc(const grub_entry_t
*ent
)
171 return ("Not implemented");
174 const grub_fsdesc_t
*
175 grub_entry_get_rootfs(const grub_entry_t
*ent
)
177 if (IS_ENTRY_BARG_VALID(ent
))
178 return (grub_get_rootfsd(&ent
->ge_barg
.gb_root
));
184 grub_entry_get_cmdline(grub_entry_t
*ent
, char *cmdline
, size_t size
)
186 if (IS_ENTRY_VALID(ent
) && (grub_entry_construct_barg(ent
) == 0))
187 return (barg_cmdline(&ent
->ge_barg
, cmdline
, size
));