#include <unistd.h>
#include <string.h>
#include <stdlib.h>
-#include <getopt.h>
#include "progname.h"
+#include "argp.h"
static grub_err_t
execute_command (char *name, int n, char **args)
cmd = grub_command_find (name);
if (! cmd)
- grub_util_error ("can\'t find command %s", name);
+ grub_util_error (_("can\'t find command %s"), name);
return (cmd->func) (cmd, n, args);
}
dev = grub_device_open (0);
if ((! dev) || (! dev->disk))
- grub_util_error ("can\'t open device");
+ grub_util_error (_("can\'t open device"));
grub_util_info ("total sectors : %lld",
(unsigned long long) dev->disk->total_sectors);
len = (leng > BUF_SIZE) ? BUF_SIZE : leng;
if (grub_disk_read (dev->disk, 0, skip, len, buf))
- grub_util_error ("disk read fails at offset %lld, length %d",
+ grub_util_error (_("disk read fails at offset %lld, length %d"),
skip, len);
if (hook (skip, buf, len))
file = grub_file_open (pathname);
if (!file)
{
- grub_util_error ("cannot open file %s", pathname);
+ grub_util_error (_("cannot open file %s"), pathname);
return;
}
if (skip > file->size)
{
- grub_util_error ("invalid skip value %lld", (unsigned long long) skip);
+ grub_util_error (_("invalid skip value %lld"), (unsigned long long) skip);
return;
}
sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
if (sz < 0)
{
- grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg);
+ grub_util_error (_("read error at offset %llu: %s"), ofs,
+ grub_errmsg);
break;
}
if ((int) fwrite (buf, 1, len, ff) != len)
{
- grub_util_error ("write error");
+ grub_util_error (_("write error"));
return 1;
}
ff = fopen (dest, "wb");
if (ff == NULL)
{
- grub_util_error ("open error");
+ grub_util_error (_("open error"));
return;
}
read_file (src, cp_hook);
{
if ((int) fread (buf_1, 1, len, ff) != len)
{
- grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg);
+ grub_util_error (_("read error at offset %llu: %s"), ofs, grub_errmsg);
return 1;
}
for (i = 0; i < len; i++, ofs++)
if (buf_1[i] != buf[i])
{
- grub_util_error ("compare fail at offset %llu", ofs);
+ grub_util_error (_("compare fail at offset %llu"), ofs);
return 1;
}
}
ff = fopen (dest, "rb");
if (ff == NULL)
{
- grub_util_error ("open error");
+ grub_util_error (_("open error"));
return;
}
if ((skip) && (fseeko (ff, skip, SEEK_SET)))
- grub_util_error ("seek error");
+ grub_util_error (_("seek error"));
read_file (src, cmp_hook);
fclose (ff);
grub_be_to_cpu32(*(grub_uint32_t*)GRUB_MD_CRC32->read(crc32_context)));
}
+static char *root = NULL;
+static int args_count = 0;
+static int nparm = 0;
+static int num_disks = 1;
+static char **images = NULL;
+static int cmd = 0;
+static char *debug_str = NULL;
+static char **args = NULL;
+
static void
-fstest (char **images, int num_disks, int cmd, int n, char **args)
+fstest (int n, char **args)
{
char *host_file;
char *loop_name;
argv[1] = host_file;
if (execute_command ("loopback", 2, argv))
- grub_util_error ("loopback command fails");
+ grub_util_error (_("loopback command fails"));
grub_free (loop_name);
grub_free (host_file);
}
}
-static struct option options[] = {
- {"root", required_argument, 0, 'r'},
- {"skip", required_argument, 0, 's'},
- {"length", required_argument, 0, 'n'},
- {"diskcount", required_argument, 0, 'c'},
- {"debug", required_argument, 0, 'd'},
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'V'},
- {"verbose", no_argument, 0, 'v'},
- {0, 0, 0, 0}
+static struct argp_option options[] = {
+ {0, 0, 0 , OPTION_DOC, N_("Commands:"), 1},
+ {N_("ls PATH"), 0, 0 , OPTION_DOC, N_("List files in PATH."), 1},
+ {N_("cp FILE LOCAL"), 0, 0, OPTION_DOC, N_("Copy FILE to local file LOCAL."), 1},
+ {N_("cmp FILE LOCAL"), 0, 0, OPTION_DOC, N_("Compare FILE with local file LOCAL."), 1},
+ {N_("hex FILE"), 0, 0 , OPTION_DOC, N_("Hex dump FILE."), 1},
+ {N_("crc FILE"), 0, 0 , OPTION_DOC, N_("Get crc32 checksum of FILE."), 1},
+ {N_("blocklist FILE"), 0, 0, OPTION_DOC, N_("Display blocklist of FILE."), 1},
+
+ {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2},
+ {"skip", 's', "N", 0, N_("Skip N bytes from output file."), 2},
+ {"length", 'n', "N", 0, N_("Handle N bytes in output file."), 2},
+ {"diskcount", 'c', "N", 0, N_("N input files."), 2},
+ {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2},
+ {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2},
+ {0, 0, 0, 0, 0, 0}
};
+/* Print the version information. */
static void
-usage (int status)
+print_version (FILE *stream, struct argp_state *state)
{
- if (status)
- fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
- else
- printf ("\
-Usage: %s [OPTION]... IMAGE_PATH COMMANDS\n\
-\n\
-Debug tool for filesystem driver.\n\
-\nCommands:\n\
- ls PATH list files in PATH\n\
- cp FILE LOCAL copy FILE to local file LOCAL\n\
- cmp FILE LOCAL compare FILE with local file LOCAL\n\
- hex FILE Hex dump FILE\n\
- crc FILE Get crc32 checksum of FILE\n\
- blocklist FILE display blocklist of FILE\n\
-\nOptions:\n\
- -r, --root=DEVICE_NAME set root device\n\
- -s, --skip=N skip N bytes from output file\n\
- -n, --length=N handle N bytes in output file\n\
- -c, --diskcount=N N input files\n\
- -d, --debug=S Set debug environment variable\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, PACKAGE_BUGREPORT);
-
- exit (status);
+ fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
}
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
-int
-main (int argc, char *argv[])
+error_t
+argp_parser (int key, char *arg, struct argp_state *state)
{
- char *debug_str = NULL, *root = NULL, *default_root, *alloc_root;
- int i, cmd, num_opts, image_index, num_disks = 1;
+ char *p;
- set_program_name (argv[0]);
-
- grub_util_init_nls ();
-
- /* Find the first non option entry. */
- for (num_opts = 1; num_opts < argc; num_opts++)
- if (argv[num_opts][0] == '-')
- {
- if ((argv[num_opts][2] == 0) && (num_opts < argc - 1) &&
- ((argv[num_opts][1] == 'r') ||
- (argv[num_opts][1] == 's') ||
- (argv[num_opts][1] == 'n') ||
- (argv[num_opts][1] == 'c') ||
- (argv[num_opts][1] == 'd')))
- num_opts++;
- }
- else
- break;
-
- /* Check for options. */
- while (1)
+ switch (key)
{
- int c = getopt_long (num_opts, argv, "r:s:n:c:d:hVv", options, 0);
- char *p;
-
- if (c == -1)
- break;
- else
- switch (c)
- {
- case 'r':
- root = optarg;
- break;
-
- case 's':
- skip = grub_strtoul (optarg, &p, 0);
- if (*p == 's')
- skip <<= GRUB_DISK_SECTOR_BITS;
- break;
-
- case 'n':
- leng = grub_strtoul (optarg, &p, 0);
- if (*p == 's')
- leng <<= GRUB_DISK_SECTOR_BITS;
- break;
-
- case 'c':
- num_disks = grub_strtoul (optarg, NULL, 0);
- if (num_disks < 1)
- {
- fprintf (stderr, "Invalid disk count.\n");
- usage (1);
- }
- break;
+ case 'r':
+ root = arg;
+ return 0;
+
+ case 's':
+ skip = grub_strtoul (arg, &p, 0);
+ if (*p == 's')
+ skip <<= GRUB_DISK_SECTOR_BITS;
+ return 0;
+
+ case 'n':
+ leng = grub_strtoul (arg, &p, 0);
+ if (*p == 's')
+ leng <<= GRUB_DISK_SECTOR_BITS;
+ return 0;
+
+ case 'c':
+ num_disks = grub_strtoul (arg, NULL, 0);
+ if (num_disks < 1)
+ {
+ fprintf (stderr, _("Invalid disk count.\n"));
+ argp_usage (state);
+ }
+ if (args_count != 0)
+ {
+ fprintf (stderr, _("Disk count must precede disks list.\n"));
+ argp_usage (state);
+ }
+ return 0;
- case 'd':
- debug_str = optarg;
- break;
+ case 'd':
+ debug_str = arg;
+ return 0;
- case 'h':
- usage (0);
- break;
+ case 'v':
+ verbosity++;
+ return 0;
- case 'V':
- printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
- return 0;
+ case ARGP_KEY_END:
+ if (args_count < num_disks)
+ {
+ fprintf (stderr, _("No command is specified.\n"));
+ argp_usage (state);
+ }
+ if (args_count - 1 - num_disks < nparm)
+ {
+ fprintf (stderr, _("Not enough parameters to command.\n"));
+ argp_usage (state);
+ }
+ return 0;
- case 'v':
- verbosity++;
- break;
+ case ARGP_KEY_ARG:
+ break;
- default:
- usage (1);
- break;
- }
+ default:
+ return ARGP_ERR_UNKNOWN;
}
- /* Obtain PATH. */
- if (optind + num_disks - 1 >= argc)
+ if (args_count < num_disks)
{
- fprintf (stderr, "Not enough pathname.\n");
- usage (1);
+ if (arg[0] != '/')
+ {
+ fprintf (stderr, _("Must use absolute path.\n"));
+ argp_usage (state);
+ }
+ if (args_count == 0)
+ images = xmalloc (num_disks * sizeof (images[0]));
+ images[args_count] = xstrdup (arg);
+ args_count++;
+ return 0;
}
- image_index = optind;
- for (i = 0; i < num_disks; i++, optind++)
- if (argv[optind][0] != '/')
- {
- fprintf (stderr, "Must use absolute path.\n");
- usage (1);
- }
-
- cmd = 0;
- if (optind < argc)
+ if (args_count == num_disks)
{
- int nparm = 0;
-
- if (!grub_strcmp (argv[optind], "ls"))
+ if (!grub_strcmp (arg, "ls"))
{
cmd = CMD_LS;
}
- else if (!grub_strcmp (argv[optind], "cp"))
+ else if (!grub_strcmp (arg, "cp"))
{
cmd = CMD_CP;
nparm = 2;
}
- else if (!grub_strcmp (argv[optind], "cmp"))
+ else if (!grub_strcmp (arg, "cmp"))
{
cmd = CMD_CMP;
nparm = 2;
}
- else if (!grub_strcmp (argv[optind], "hex"))
+ else if (!grub_strcmp (arg, "hex"))
{
cmd = CMD_HEX;
nparm = 1;
}
- else if (!grub_strcmp (argv[optind], "crc"))
+ else if (!grub_strcmp (arg, "crc"))
{
cmd = CMD_CRC;
nparm = 1;
}
- else if (!grub_strcmp (argv[optind], "blocklist"))
+ else if (!grub_strcmp (arg, "blocklist"))
{
cmd = CMD_BLOCKLIST;
nparm = 1;
}
else
{
- fprintf (stderr, "Invalid command %s.\n", argv[optind]);
- usage (1);
+ fprintf (stderr, _("Invalid command %s.\n"), arg);
+ argp_usage (state);
}
+ args_count++;
+ return 0;
+ }
- if (optind + 1 + nparm > argc)
- {
- fprintf (stderr, "Invalid parameter for command %s.\n",
- argv[optind]);
- usage (1);
- }
+ args[args_count - 1 - num_disks] = xstrdup (arg);
+ args_count++;
+ return 0;
+}
- optind++;
- }
- else
- {
- fprintf (stderr, "No command is specified.\n");
- usage (1);
- }
+struct argp argp = {
+ options, argp_parser, N_("IMAGE_PATH COMMANDS"),
+ N_("Debug tool for filesystem driver."),
+ NULL, NULL, NULL
+};
+
+int
+main (int argc, char *argv[])
+{
+ char *default_root, *alloc_root;
+
+ set_program_name (argv[0]);
+
+ grub_util_init_nls ();
+
+ args = xmalloc (argc * sizeof (args[0]));
+
+ argp_parse (&argp, argc, argv, 0, 0, 0);
/* Initialize all modules. */
grub_init_all ();
free (alloc_root);
/* Do it. */
- fstest (argv + image_index, num_disks, cmd, argc - optind, argv + optind);
+ fstest (args_count - 1 - num_disks, args);
/* Free resources. */
grub_fini_all ();