Merge branch 'mainline' into zfs
[grub2/phcoder.git] / util / grub-editenv.c
blob6d123405028020b3dfe5876a618b3fd5ab059072
1 /* grub-editenv.c - tool to edit environment block. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008,2009 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/>.
20 #include <config.h>
21 #include <grub/types.h>
22 #include <grub/util/misc.h>
23 #include <grub/lib/envblk.h>
24 #include <grub/handler.h>
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <getopt.h>
32 #define DEFAULT_ENVBLK_SIZE 1024
34 void
35 grub_putchar (int c)
37 putchar (c);
40 void
41 grub_refresh (void)
43 fflush (stdout);
46 struct grub_handler_class grub_term_input_class;
47 struct grub_handler_class grub_term_output_class;
49 int
50 grub_getkey (void)
52 return 0;
55 char *
56 grub_env_get (const char *name __attribute__ ((unused)))
58 return NULL;
61 static struct option options[] = {
62 {"help", no_argument, 0, 'h'},
63 {"version", no_argument, 0, 'V'},
64 {"verbose", no_argument, 0, 'v'},
65 {0, 0, 0, 0}
68 static void
69 usage (int status)
71 if (status)
72 fprintf (stderr, "Try ``grub-editenv --help'' for more information.\n");
73 else
74 printf ("\
75 Usage: grub-editenv [OPTIONS] FILENAME COMMAND\n\
76 \n\
77 Tool to edit environment block.\n\
78 \nCommands:\n\
79 create create a blank environment block file\n\
80 list list the current variables\n\
81 set [name=value ...] set variables\n\
82 unset [name ....] delete variables\n\
83 \nOptions:\n\
84 -h, --help display this message and exit\n\
85 -V, --version print version information and exit\n\
86 -v, --verbose print verbose messages\n\
87 \n\
88 Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
90 exit (status);
93 static void
94 create_envblk_file (const char *name)
96 FILE *fp;
97 char *buf;
99 buf = malloc (DEFAULT_ENVBLK_SIZE);
100 if (! buf)
101 grub_util_error ("out of memory");
103 fp = fopen (name, "wb");
104 if (! fp)
105 grub_util_error ("cannot open the file %s", name);
107 memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
108 memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#',
109 DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
111 if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE)
112 grub_util_error ("cannot write to the file %s", name);
114 fsync (fileno (fp));
115 free (buf);
116 fclose (fp);
119 static grub_envblk_t
120 open_envblk_file (const char *name)
122 FILE *fp;
123 char *buf;
124 size_t size;
125 grub_envblk_t envblk;
127 fp = fopen (name, "rb");
128 if (! fp)
130 /* Create the file implicitly. */
131 create_envblk_file (name);
132 fp = fopen (name, "rb");
133 if (! fp)
134 grub_util_error ("cannot open the file %s", name);
137 if (fseek (fp, 0, SEEK_END) < 0)
138 grub_util_error ("cannot seek the file %s", name);
140 size = (size_t) ftell (fp);
142 if (fseek (fp, 0, SEEK_SET) < 0)
143 grub_util_error ("cannot seek the file %s", name);
145 buf = malloc (size);
146 if (! buf)
147 grub_util_error ("out of memory");
149 if (fread (buf, 1, size, fp) != size)
150 grub_util_error ("cannot read the file %s", name);
152 fclose (fp);
154 envblk = grub_envblk_open (buf, size);
155 if (! envblk)
156 grub_util_error ("invalid environment block");
158 return envblk;
161 static void
162 list_variables (const char *name)
164 grub_envblk_t envblk;
166 auto int print_var (const char *name, const char *value);
167 int print_var (const char *name, const char *value)
169 printf ("%s=%s\n", name, value);
170 return 0;
173 envblk = open_envblk_file (name);
174 grub_envblk_iterate (envblk, print_var);
175 grub_envblk_close (envblk);
178 static void
179 write_envblk (const char *name, grub_envblk_t envblk)
181 FILE *fp;
183 fp = fopen (name, "wb");
184 if (! fp)
185 grub_util_error ("cannot open the file %s", name);
187 if (fwrite (grub_envblk_buffer (envblk), 1, grub_envblk_size (envblk), fp)
188 != grub_envblk_size (envblk))
189 grub_util_error ("cannot write to the file %s", name);
191 fsync (fileno (fp));
192 fclose (fp);
195 static void
196 set_variables (const char *name, int argc, char *argv[])
198 grub_envblk_t envblk;
200 envblk = open_envblk_file (name);
201 while (argc)
203 char *p;
205 p = strchr (argv[0], '=');
206 if (! p)
207 grub_util_error ("invalid parameter %s", argv[0]);
209 *(p++) = 0;
211 if (! grub_envblk_set (envblk, argv[0], p))
212 grub_util_error ("environment block too small");
214 argc--;
215 argv++;
218 write_envblk (name, envblk);
219 grub_envblk_close (envblk);
222 static void
223 unset_variables (const char *name, int argc, char *argv[])
225 grub_envblk_t envblk;
227 envblk = open_envblk_file (name);
228 while (argc)
230 grub_envblk_delete (envblk, argv[0]);
232 argc--;
233 argv++;
236 write_envblk (name, envblk);
237 grub_envblk_close (envblk);
241 main (int argc, char *argv[])
243 char *filename;
244 char *command;
246 progname = "grub-editenv";
248 /* Check for options. */
249 while (1)
251 int c = getopt_long (argc, argv, "hVv", options, 0);
253 if (c == -1)
254 break;
255 else
256 switch (c)
258 case 'h':
259 usage (0);
260 break;
262 case 'V':
263 printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
264 return 0;
266 case 'v':
267 verbosity++;
268 break;
270 default:
271 usage (1);
272 break;
276 /* Obtain the filename. */
277 if (optind >= argc)
279 fprintf (stderr, "no filename specified\n");
280 usage (1);
283 if (optind + 1 >= argc)
285 fprintf (stderr, "no command specified\n");
286 usage (1);
289 filename = argv[optind];
290 command = argv[optind + 1];
292 if (strcmp (command, "create") == 0)
293 create_envblk_file (filename);
294 else if (strcmp (command, "list") == 0)
295 list_variables (filename);
296 else if (strcmp (command, "set") == 0)
297 set_variables (filename, argc - optind - 2, argv + optind + 2);
298 else if (strcmp (command, "unset") == 0)
299 unset_variables (filename, argc - optind - 2, argv + optind + 2);
300 else
302 fprintf (stderr, "unknown command %s\n", command);
303 usage (1);
306 return 0;