1 /* grub-editenv.c - tool to edit environment block. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/types.h>
22 #include <grub/emu/misc.h>
23 #include <grub/util/misc.h>
24 #include <grub/lib/envblk.h>
25 #include <grub/i18n.h>
26 #include <grub/emu/hostfile.h>
27 #include <grub/util/install.h>
33 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
34 #pragma GCC diagnostic ignored "-Wmissing-declarations"
36 #pragma GCC diagnostic error "-Wmissing-prototypes"
37 #pragma GCC diagnostic error "-Wmissing-declarations"
42 #define DEFAULT_ENVBLK_PATH DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG
44 static struct argp_option options
[] = {
45 {0, 0, 0, OPTION_DOC
, N_("Commands:"), 1},
46 {"create", 0, 0, OPTION_DOC
|OPTION_NO_USAGE
,
47 N_("Create a blank environment block file."), 0},
48 {"list", 0, 0, OPTION_DOC
|OPTION_NO_USAGE
,
49 N_("List the current variables."), 0},
50 /* TRANSLATORS: "set" is a keyword. It's a summary of "set" subcommand. */
51 {N_("set [NAME=VALUE ...]"), 0, 0, OPTION_DOC
|OPTION_NO_USAGE
,
52 N_("Set variables."), 0},
53 /* TRANSLATORS: "unset" is a keyword. It's a summary of "unset" subcommand. */
54 {N_("unset [NAME ...]"), 0, 0, OPTION_DOC
|OPTION_NO_USAGE
,
55 N_("Delete variables."), 0},
57 {0, 0, 0, OPTION_DOC
, N_("Options:"), -1},
58 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
63 /* Print the version information. */
65 print_version (FILE *stream
, struct argp_state
*state
)
67 fprintf (stream
, "%s (%s) %s\n", program_name
, PACKAGE_NAME
, PACKAGE_VERSION
);
69 void (*argp_program_version_hook
) (FILE *, struct argp_state
*) = print_version
;
71 /* Set the bug report address */
72 const char *argp_program_bug_address
= "<"PACKAGE_BUGREPORT
">";
74 static error_t
argp_parser (int key
, char *arg
, struct argp_state
*state
)
82 case ARGP_KEY_NO_ARGS
:
83 fprintf (stderr
, "%s",
84 _("You need to specify at least one command.\n"));
89 return ARGP_ERR_UNKNOWN
;
95 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
98 help_filter (int key
, const char *text
, void *input
__attribute__ ((unused
)))
102 case ARGP_KEY_HELP_POST_DOC
:
103 return xasprintf (text
, DEFAULT_ENVBLK_PATH
, DEFAULT_ENVBLK_PATH
);
106 return (char *) text
;
110 #pragma GCC diagnostic error "-Wformat-nonliteral"
113 options
, argp_parser
, N_("FILENAME COMMAND"),
115 Tool to edit environment block.")
117 If FILENAME is `-', the default value %s is used.\n\n\
118 There is no `delete' command; if you want to delete the whole environment\n\
119 block, use `rm %s'."),
120 NULL
, help_filter
, NULL
124 open_envblk_file (const char *name
)
129 grub_envblk_t envblk
;
131 fp
= grub_util_fopen (name
, "rb");
134 /* Create the file implicitly. */
135 grub_util_create_envblk_file (name
);
136 fp
= grub_util_fopen (name
, "rb");
138 grub_util_error (_("cannot open `%s': %s"), name
,
142 if (fseek (fp
, 0, SEEK_END
) < 0)
143 grub_util_error (_("cannot seek `%s': %s"), name
,
146 size
= (size_t) ftell (fp
);
148 if (fseek (fp
, 0, SEEK_SET
) < 0)
149 grub_util_error (_("cannot seek `%s': %s"), name
,
152 buf
= xmalloc (size
);
154 if (fread (buf
, 1, size
, fp
) != size
)
155 grub_util_error (_("cannot read `%s': %s"), name
,
160 envblk
= grub_envblk_open (buf
, size
);
162 grub_util_error ("%s", _("invalid environment block"));
168 print_var (const char *varname
, const char *value
,
169 void *hook_data
__attribute__ ((unused
)))
171 printf ("%s=%s\n", varname
, value
);
176 list_variables (const char *name
)
178 grub_envblk_t envblk
;
180 envblk
= open_envblk_file (name
);
181 grub_envblk_iterate (envblk
, NULL
, print_var
);
182 grub_envblk_close (envblk
);
186 write_envblk (const char *name
, grub_envblk_t envblk
)
190 fp
= grub_util_fopen (name
, "wb");
192 grub_util_error (_("cannot open `%s': %s"), name
,
195 if (fwrite (grub_envblk_buffer (envblk
), 1, grub_envblk_size (envblk
), fp
)
196 != grub_envblk_size (envblk
))
197 grub_util_error (_("cannot write to `%s': %s"), name
,
200 grub_util_file_sync (fp
);
205 set_variables (const char *name
, int argc
, char *argv
[])
207 grub_envblk_t envblk
;
209 envblk
= open_envblk_file (name
);
214 p
= strchr (argv
[0], '=');
216 grub_util_error (_("invalid parameter %s"), argv
[0]);
220 if (! grub_envblk_set (envblk
, argv
[0], p
))
221 grub_util_error ("%s", _("environment block too small"));
227 write_envblk (name
, envblk
);
228 grub_envblk_close (envblk
);
232 unset_variables (const char *name
, int argc
, char *argv
[])
234 grub_envblk_t envblk
;
236 envblk
= open_envblk_file (name
);
239 grub_envblk_delete (envblk
, argv
[0]);
245 write_envblk (name
, envblk
);
246 grub_envblk_close (envblk
);
250 main (int argc
, char *argv
[])
252 const char *filename
;
254 int curindex
, arg_count
;
256 grub_util_host_init (&argc
, &argv
);
258 /* Parse our arguments */
259 if (argp_parse (&argp
, argc
, argv
, 0, &curindex
, 0) != 0)
261 fprintf (stderr
, "%s", _("Error in parsing command line arguments\n"));
265 arg_count
= argc
- curindex
;
269 filename
= DEFAULT_ENVBLK_PATH
;
270 command
= argv
[curindex
++];
274 filename
= argv
[curindex
++];
275 if (strcmp (filename
, "-") == 0)
276 filename
= DEFAULT_ENVBLK_PATH
;
277 command
= argv
[curindex
++];
280 if (strcmp (command
, "create") == 0)
281 grub_util_create_envblk_file (filename
);
282 else if (strcmp (command
, "list") == 0)
283 list_variables (filename
);
284 else if (strcmp (command
, "set") == 0)
285 set_variables (filename
, argc
- curindex
, argv
+ curindex
);
286 else if (strcmp (command
, "unset") == 0)
287 unset_variables (filename
, argc
- curindex
, argv
+ curindex
);
290 char *program
= xstrdup(program_name
);
291 fprintf (stderr
, _("Unknown command `%s'.\n"), command
);
292 argp_help (&argp
, stderr
, ARGP_HELP_STD_USAGE
, program
);