Migrate grub-mkimage.c to argp.

* Makefile.util.def (grub-mkimage): Add util/argp_common.c.
	(grub-setup): Likewise.
	* util/grub-setup.c (print_version): Move to ...
	* util/argp_common.c (print_version): ... here.
	* util/grub-setup.c (argp_program_version_hook): Move to ...
	* util/argp_common.c (argp_program_version_hook): ... here.
	* util/grub-setup.c (argp_parser): Add exit (1) on fatal error for
	safety.
	* util/grub-mkimage.c (main): Migrate to argp.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-02-03 21:18:37 +01:00
parent 57db0757f4
commit c76899a0ea
5 changed files with 257 additions and 201 deletions

View file

@ -1,3 +1,17 @@
2012-02-03 Vladimir Serbinenko <phcoder@gmail.com>
Migrate grub-mkimage.c to argp.
* Makefile.util.def (grub-mkimage): Add util/argp_common.c.
(grub-setup): Likewise.
* util/grub-setup.c (print_version): Move to ...
* util/argp_common.c (print_version): ... here.
* util/grub-setup.c (argp_program_version_hook): Move to ...
* util/argp_common.c (argp_program_version_hook): ... here.
* util/grub-setup.c (argp_parser): Add exit (1) on fatal error for
safety.
* util/grub-mkimage.c (main): Migrate to argp.
2012-02-03 Vladimir Serbinenko <phcoder@gmail.com> 2012-02-03 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkrescue.in: Use same message as * util/grub-mkrescue.in: Use same message as

View file

@ -142,6 +142,8 @@ program = {
common = util/grub-mkimage.c; common = util/grub-mkimage.c;
common = util/resolve.c; common = util/resolve.c;
common = util/argp_common.c;
extra_dist = util/grub-mkimagexx.c; extra_dist = util/grub-mkimagexx.c;
ldadd = libgrubmods.a; ldadd = libgrubmods.a;
@ -314,6 +316,7 @@ program = {
mansection = 8; mansection = 8;
common = util/grub-setup.c; common = util/grub-setup.c;
common = util/lvm.c; common = util/lvm.c;
common = util/argp_common.c;
common = grub-core/lib/reed_solomon.c; common = grub-core/lib/reed_solomon.c;
sparc64_ieee1275 = util/ieee1275/ofpath.c; sparc64_ieee1275 = util/ieee1275/ofpath.c;
@ -349,6 +352,7 @@ program = {
mansection = 1; mansection = 1;
common = util/grub-mklayout.c; common = util/grub-mklayout.c;
common = util/argp_common.c;
ldadd = libgrubmods.a; ldadd = libgrubmods.a;
ldadd = libgrubgcry.a; ldadd = libgrubgcry.a;
@ -502,6 +506,7 @@ script = {
script = { script = {
name = grub-kbdcomp; name = grub-kbdcomp;
common = util/grub-kbdcomp.in; common = util/grub-kbdcomp.in;
mansection = 1;
}; };
script = { script = {

35
util/argp_common.c Normal file
View file

@ -0,0 +1,35 @@
/* grub-setup.c - make GRUB usable */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#define _GNU_SOURCE 1
#include "progname.h"
#include <argp.h>
/* Print the version information. */
static void
print_version (FILE *stream, struct argp_state *state)
{
fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
}
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
/* Set the bug report address */
const char *argp_program_bug_address = "<"PACKAGE_BUGREPORT">";

View file

@ -42,7 +42,7 @@
#include <grub/efi/pe32.h> #include <grub/efi/pe32.h>
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#include <getopt.h> #include <argp.h>
#include "progname.h" #include "progname.h"
@ -1631,227 +1631,240 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
static struct option options[] = static struct argp_option options[] = {
{ {"directory", 'd', N_("DIR"), 0, N_("use images and modules under DIR [default=%s/@platform@]"), 0},
{"directory", required_argument, 0, 'd'}, {"prefix", 'p', N_("DIR"), 0, N_("set grub_prefix directory [default=%s]"), 0},
{"prefix", required_argument, 0, 'p'}, {"memdisk", 'm', N_("FILE"), 0, N_("embed FILE as a memdisk image"), 0},
{"memdisk", required_argument, 0, 'm'}, {"config", 'c', N_("FILE"), 0, N_("embed FILE as boot config"), 0},
{"font", required_argument, 0, 'f'}, {"note", 'n', 0, 0, N_("add NOTE segment for CHRP Open Firmware"), 0},
{"config", required_argument, 0, 'c'}, {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
{"output", required_argument, 0, 'o'}, {"format", 'O', N_("FORMAT"), 0, N_("generate an image in format.\navailable formats: %s"), 0},
{"note", no_argument, 0, 'n'}, {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use"), 0},
{"format", required_argument, 0, 'O'}, {"verbose", 'v', 0, 0, N_("Print verbose messages."), 0},
{"compression", required_argument, 0, 'C'}, { 0, 0, 0, 0, 0, 0 }
{"help", no_argument, 0, 'h'}, };
{"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
static void static char *
usage (int status) help_filter (int key, const char *text, void *input __attribute__ ((unused)))
{ {
if (status) switch (key)
fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name);
else
{ {
int format_len = 0; case 'd':
char *formats; return xasprintf (text, GRUB_PKGLIBROOTDIR);
char *ptr; case 'p':
unsigned i; return xasprintf (text, DEFAULT_DIRECTORY);
for (i = 0; i < ARRAY_SIZE (image_targets); i++) case 'O':
format_len += strlen (image_targets[i].names[0]) + 2; {
ptr = formats = xmalloc (format_len); int format_len = 0;
for (i = 0; i < ARRAY_SIZE (image_targets); i++) char *formats;
{ char *ptr;
strcpy (ptr, image_targets[i].names[0]); char *ret;
ptr += strlen (image_targets[i].names[0]); unsigned i;
*ptr++ = ','; for (i = 0; i < ARRAY_SIZE (image_targets); i++)
*ptr++ = ' '; format_len += strlen (image_targets[i].names[0]) + 2;
} ptr = formats = xmalloc (format_len);
ptr[-2] = 0; for (i = 0; i < ARRAY_SIZE (image_targets); i++)
{
printf (_("\ strcpy (ptr, image_targets[i].names[0]);
Usage: %s [OPTION]... [MODULES]\n\ ptr += strlen (image_targets[i].names[0]);
\n\ *ptr++ = ',';
Make a bootable image of GRUB.\n\ *ptr++ = ' ';
\n\ }
-d, --directory=DIR use images and modules under DIR [default=%s/@platform@]\n\ ptr[-2] = 0;
-p, --prefix=DIR set grub_prefix directory [default=%s]\n\ ret = xasprintf (text, formats);
-m, --memdisk=FILE embed FILE as a memdisk image\n\ free (formats);
-c, --config=FILE embed FILE as boot config\n\ return ret;
-n, --note add NOTE segment for CHRP Open Firmware\n\ }
-o, --output=FILE output a generated image to FILE [default=stdout]\n\ default:
-O, --format=FORMAT generate an image in format\n\ return (char *) text;
available formats: %s\n\
-C, --compression=(xz|none|auto) choose the compression to use\n\
-h, --help display this message and exit\n\
-V, --version print version information and exit\n\
-v, --verbose print verbose messages\n\
\n\
Report bugs to <%s>.\n\
"),
program_name, GRUB_PKGLIBROOTDIR, DEFAULT_DIRECTORY,
formats,
PACKAGE_BUGREPORT);
free (formats);
} }
exit (status);
} }
struct arguments
{
size_t nmodules;
size_t modules_max;
char **modules;
char *output;
char *dir;
char *prefix;
char *memdisk;
char *font;
char *config;
int note;
struct image_target_desc *image_target;
grub_compression_t comp;
};
static error_t
argp_parser (int key, char *arg, struct argp_state *state)
{
/* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */
struct arguments *arguments = state->input;
char *p;
switch (key)
{
case 'o':
if (arguments->output)
free (arguments->output);
arguments->output = xstrdup (arg);
break;
case 'O':
{
unsigned i, j;
for (i = 0; i < ARRAY_SIZE (image_targets); i++)
for (j = 0; image_targets[i].names[j]
&& j < ARRAY_SIZE (image_targets[i].names); j++)
if (strcmp (arg, image_targets[i].names[j]) == 0)
arguments->image_target = &image_targets[i];
if (!arguments->image_target)
{
printf (_("unknown target format %s\n"), arg);
argp_usage (state);
exit (1);
}
break;
}
case 'd':
if (arguments->dir)
free (arguments->dir);
arguments->dir = xstrdup (arg);
break;
case 'n':
arguments->note = 1;
break;
case 'm':
if (arguments->memdisk)
free (arguments->memdisk);
arguments->memdisk = xstrdup (arg);
if (arguments->prefix)
free (arguments->prefix);
arguments->prefix = xstrdup ("(memdisk)/boot/grub");
break;
case 'c':
if (arguments->config)
free (arguments->config);
arguments->config = xstrdup (arg);
break;
case 'C':
if (grub_strcmp (arg, "xz") == 0)
{
#ifdef HAVE_LIBLZMA
arguments->comp = COMPRESSION_XZ;
#else
grub_util_error (_("grub-mkimage is compiled without XZ support"));
#endif
}
else if (grub_strcmp (arg, "none") == 0)
arguments->comp = COMPRESSION_NONE;
else
grub_util_error (_("Unknown compression format %s"), arg);
break;
case 'p':
if (arguments->prefix)
free (arguments->prefix);
arguments->prefix = xstrdup (arg);
break;
case 'v':
verbosity++;
break;
case ARGP_KEY_ARG:
assert (arguments->nmodules < arguments->modules_max);
arguments->modules[arguments->nmodules++] = xstrdup(arg);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = {
options, argp_parser, N_("[OPTION]... [MODULES]"),
N_("Make a bootable image of GRUB."),
NULL, help_filter, NULL
};
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
char *output = NULL;
char *dir = NULL;
char *prefix = NULL;
char *memdisk = NULL;
char *font = NULL;
char *config = NULL;
FILE *fp = stdout; FILE *fp = stdout;
int note = 0; struct arguments arguments;
struct image_target_desc *image_target = NULL;
grub_compression_t comp = COMPRESSION_AUTO;
set_program_name (argv[0]); set_program_name (argv[0]);
grub_util_init_nls (); grub_util_init_nls ();
while (1) memset (&arguments, 0, sizeof (struct arguments));
arguments.comp = COMPRESSION_AUTO;
arguments.modules_max = argc + 1;
arguments.modules = xmalloc ((arguments.modules_max + 1)
* sizeof (arguments.modules[0]));
memset (arguments.modules, 0, (arguments.modules_max + 1)
* sizeof (arguments.modules[0]));
if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
{ {
int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:C:hVvn", options, 0); fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
exit(1);
if (c == -1)
break;
else
switch (c)
{
case 'o':
if (output)
free (output);
output = xstrdup (optarg);
break;
case 'O':
{
unsigned i, j;
for (i = 0; i < ARRAY_SIZE (image_targets); i++)
for (j = 0; image_targets[i].names[j]
&& j < ARRAY_SIZE (image_targets[i].names); j++)
if (strcmp (optarg, image_targets[i].names[j]) == 0)
image_target = &image_targets[i];
if (!image_target)
{
printf (_("unknown target format %s\n"), optarg);
usage (1);
}
break;
}
case 'd':
if (dir)
free (dir);
dir = xstrdup (optarg);
break;
case 'n':
note = 1;
break;
case 'm':
if (memdisk)
free (memdisk);
memdisk = xstrdup (optarg);
if (prefix)
free (prefix);
prefix = xstrdup ("(memdisk)/boot/grub");
break;
case 'c':
if (config)
free (config);
config = xstrdup (optarg);
break;
case 'C':
if (grub_strcmp (optarg, "xz") == 0)
{
#ifdef HAVE_LIBLZMA
comp = COMPRESSION_XZ;
#else
grub_util_error (_("grub-mkimage is compiled without XZ support"),
optarg);
#endif
}
else if (grub_strcmp (optarg, "none") == 0)
comp = COMPRESSION_NONE;
else
grub_util_error (_("Unknown compression format %s"), optarg);
break;
case 'h':
usage (0);
break;
case 'p':
if (prefix)
free (prefix);
prefix = xstrdup (optarg);
break;
case 'V':
printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
return 0;
case 'v':
verbosity++;
break;
default:
usage (1);
break;
}
} }
if (!image_target) if (!arguments.image_target)
{ {
char *program = xstrdup(program_name);
printf ("%s", _("Target format not specified (use the -O option).\n")); printf ("%s", _("Target format not specified (use the -O option).\n"));
usage (1); argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
free (program);
exit(1);
} }
if (output) if (arguments.output)
{ {
fp = fopen (output, "wb"); fp = fopen (arguments.output, "wb");
if (! fp) if (! fp)
grub_util_error (_("cannot open %s"), output); grub_util_error (_("cannot open %s"), arguments.output);
free (output); free (arguments.output);
} }
if (!dir) if (!arguments.dir)
{ {
dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) arguments.dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR)
+ grub_strlen (image_target->dirname) + 1); + grub_strlen (arguments.image_target->dirname)
memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1); + 1);
*(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/'; memcpy (arguments.dir, GRUB_PKGLIBROOTDIR,
strcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->dirname); sizeof (GRUB_PKGLIBROOTDIR) - 1);
*(arguments.dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/';
strcpy (arguments.dir + sizeof (GRUB_PKGLIBROOTDIR),
arguments.image_target->dirname);
} }
generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, generate_image (arguments.dir, arguments.prefix ? : DEFAULT_DIRECTORY, fp,
argv + optind, memdisk, config, arguments.modules, arguments.memdisk, arguments.config,
image_target, note, comp); arguments.image_target, arguments.note, arguments.comp);
fflush (fp); fflush (fp);
fsync (fileno (fp)); fsync (fileno (fp));
fclose (fp); fclose (fp);
if (dir) if (arguments.dir)
free (dir); free (arguments.dir);
return 0; return 0;
} }

View file

@ -746,8 +746,7 @@ static struct argp_option options[] = {
N_("Install even if problems are detected"), 0}, N_("Install even if problems are detected"), 0},
{"skip-fs-probe",'s',0, 0, {"skip-fs-probe",'s',0, 0,
N_("Do not probe for filesystems in DEVICE"), 0}, N_("Do not probe for filesystems in DEVICE"), 0},
{"verbose", 'v', 0, 0, {"verbose", 'v', 0, 0, N_("Print verbose messages."), 0},
N_("Print verbose messages."), 0},
{"allow-floppy", 'a', 0, 0, {"allow-floppy", 'a', 0, 0,
N_("Make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 0}, N_("Make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 0},
@ -788,17 +787,6 @@ struct arguments
char *device; char *device;
}; };
/* Print the version information. */
static void
print_version (FILE *stream, struct argp_state *state)
{
fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
}
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
/* Set the bug report address */
const char *argp_program_bug_address = "<"PACKAGE_BUGREPORT">";
static error_t static error_t
argp_parser (int key, char *arg, struct argp_state *state) argp_parser (int key, char *arg, struct argp_state *state)
{ {
@ -868,6 +856,7 @@ argp_parser (int key, char *arg, struct argp_state *state)
case ARGP_KEY_NO_ARGS: case ARGP_KEY_NO_ARGS:
fprintf (stderr, "%s", _("No device is specified.\n")); fprintf (stderr, "%s", _("No device is specified.\n"));
argp_usage (state); argp_usage (state);
exit (1);
break; break;
default: default: