From 60cdd02b02578b427ca3926d566811c6bb7a9970 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Wed, 8 Sep 2010 09:05:18 +0100 Subject: [PATCH] fish: Generate list of prepared disk image types. This commit shouldn't change the semantics of the code. --- .gitignore | 2 + fish/Makefile.am | 7 ++- fish/fish.h | 6 +++ fish/prep.c | 142 ++----------------------------------------------------- fish/prep_disk.c | 41 ++++++++++++++++ fish/prep_fs.c | 55 +++++++++++++++++++++ fish/prep_part.c | 43 +++++++++++++++++ po/POTFILES.in | 4 ++ src/generator.ml | 114 ++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 276 insertions(+), 138 deletions(-) create mode 100644 fish/prep_disk.c create mode 100644 fish/prep_fs.c create mode 100644 fish/prep_part.c diff --git a/.gitignore b/.gitignore index cfea549..55bd91b 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,8 @@ fish/cmds.c fish/completion.c fish/guestfish fish/guestfish.static +fish/prepopts.c +fish/prepopts.h fish/rc_protocol.c fish/rc_protocol.h fuse/guestmount diff --git a/fish/Makefile.am b/fish/Makefile.am index f75e4e0..fa8068a 100644 --- a/fish/Makefile.am +++ b/fish/Makefile.am @@ -22,7 +22,9 @@ bin_PROGRAMS = guestfish generator_built = \ cmds.c \ completion.c \ - guestfish-actions.pod + guestfish-actions.pod \ + prepopts.h \ + prepopts.c BUILT_SOURCES = \ $(generator_built) \ @@ -49,6 +51,9 @@ guestfish_SOURCES = \ man.c \ more.c \ prep.c \ + prep_disk.c \ + prep_part.c \ + prep_fs.c \ progress.c \ rc.c \ reopen.c \ diff --git a/fish/fish.h b/fish/fish.h index be357f5..7c9c955 100644 --- a/fish/fish.h +++ b/fish/fish.h @@ -116,12 +116,18 @@ extern int do_man (const char *cmd, int argc, char *argv[]); extern int do_more (const char *cmd, int argc, char *argv[]); /* in prep.c */ +struct prep_data { + const struct prep *prep; + const char *orig_type_string; + const char **params; +}; typedef struct prep_data prep_data; extern void list_prepared_drives (void); extern prep_data *create_prepared_file (const char *type_string, const char *filename); extern void prepare_drive (const char *filename, prep_data *data, const char *device); +extern void prep_error (prep_data *data, const char *filename, const char *fs, ...) __attribute__((noreturn, format (printf,3,4))); /* in progress.c */ extern void reset_progress_bar (void); diff --git a/fish/prep.c b/fish/prep.c index 7186622..369dd6d 100644 --- a/fish/prep.c +++ b/fish/prep.c @@ -25,86 +25,9 @@ #include #include "fish.h" +#include "prepopts.h" static prep_data *parse_type_string (const char *type_string); -static void prep_error (prep_data *data, const char *filename, const char *fs, ...) __attribute__((noreturn, format (printf,3,4))); - -struct prep { - const char *name; /* eg. "fs" */ - - size_t nr_params; /* optional parameters */ - struct param *params; - - const char *shortdesc; /* short description */ - const char *longdesc; /* long description */ - - /* functions to implement it */ - void (*prelaunch) (const char *filename, prep_data *); - void (*postlaunch) (const char *filename, prep_data *, const char *device); -}; - -struct param { - const char *pname; /* parameter name */ - const char *pdefault; /* parameter default */ - const char *pdesc; /* parameter description */ -}; - -static void prelaunch_disk (const char *filename, prep_data *data); -static struct param disk_params[] = { - { "size", "100M", "the size of the disk image" }, -}; - -static void prelaunch_part (const char *filename, prep_data *data); -static void postlaunch_part (const char *filename, prep_data *data, const char *device); -static struct param part_params[] = { - { "size", "100M", "the size of the disk image" }, - { "partition", "mbr", "partition table type" }, -}; - -static void prelaunch_fs (const char *filename, prep_data *data); -static void postlaunch_fs (const char *filename, prep_data *data, const char *device); -static struct param fs_params[] = { - { "filesystem", "ext2", "the type of filesystem to use" }, - { "size", "100M", "the size of the disk image" }, - { "partition", "mbr", "partition table type" }, -}; - -static const struct prep preps[] = { - { "disk", - 1, disk_params, - "create a blank disk", - "\ - Create a blank disk, size 100MB (by default).\n\ -\n\ - The default size can be changed by supplying an optional parameter.", - prelaunch_disk, NULL - }, - { "part", - 2, part_params, - "create a partitioned disk", - "\ - Create a disk with a single partition. By default the size of the disk\n\ - is 100MB (the available space in the partition will be a tiny bit smaller)\n\ - and the partition table will be MBR (old DOS-style).\n\ -\n\ - These defaults can be changed by supplying optional parameters.", - prelaunch_part, postlaunch_part - }, - { "fs", - 3, fs_params, - "create a filesystem", - "\ - Create a disk with a single partition, with the partition containing\n\ - an empty filesystem. This defaults to creating a 100MB disk (the available\n\ - space in the filesystem will be a tiny bit smaller) with an MBR (old\n\ - DOS-style) partition table and an ext2 filesystem.\n\ -\n\ - These defaults can be changed by supplying optional parameters.", - prelaunch_fs, postlaunch_fs - }, -}; - -#define nr_preps (sizeof preps / sizeof preps[0]) void list_prepared_drives (void) @@ -113,7 +36,7 @@ list_prepared_drives (void) printf (_("List of available prepared disk images:\n\n")); - for (i = 0; i < nr_preps; ++i) { + for (i = 0; i < NR_PREPS; ++i) { printf (_("\ guestfish -N %-16s %s\n\ \n\ @@ -145,12 +68,6 @@ directory. (\"test2.img\" etc if -N option is given multiple times).\n\ For more information see the guestfish(1) manual.\n")); } -struct prep_data { - const struct prep *prep; - const char *orig_type_string; - const char **params; -}; - /* Parse the type string (from the command line) and create the output * file 'filename'. This is called before launch. Return the opaque * prep_data which will be passed back to us in prepare_drive below. @@ -171,11 +88,11 @@ parse_type_string (const char *type_string) /* Match on the type part (without parameters). */ size_t len = strcspn (type_string, ":"); - for (i = 0; i < nr_preps; ++i) + for (i = 0; i < NR_PREPS; ++i) if (STRCASEEQLEN (type_string, preps[i].name, len)) break; - if (i == nr_preps) { + if (i == NR_PREPS) { fprintf (stderr, _("\ guestfish: -N parameter '%s': no such prepared disk image known.\n\ Use 'guestfish -N list' to list possible values for the -N parameter.\n"), @@ -234,7 +151,7 @@ prepare_drive (const char *filename, prep_data *data, data->prep->postlaunch (filename, data, device); } -static void +void prep_error (prep_data *data, const char *filename, const char *fs, ...) { fprintf (stderr, @@ -250,52 +167,3 @@ prep_error (prep_data *data, const char *filename, const char *fs, ...) exit (EXIT_FAILURE); } - -static void -prelaunch_disk (const char *filename, prep_data *data) -{ - if (alloc_disk (filename, data->params[0], 0, 1) == -1) - prep_error (data, filename, _("failed to allocate disk")); -} - -static void -prelaunch_part (const char *filename, prep_data *data) -{ - if (alloc_disk (filename, data->params[0], 0, 1) == -1) - prep_error (data, filename, _("failed to allocate disk")); -} - -static void -postlaunch_part (const char *filename, prep_data *data, const char *device) -{ - if (guestfs_part_disk (g, device, data->params[1]) == -1) - prep_error (data, filename, _("failed to partition disk: %s"), - guestfs_last_error (g)); -} - -static void -prelaunch_fs (const char *filename, prep_data *data) -{ - if (alloc_disk (filename, data->params[1], 0, 1) == -1) - prep_error (data, filename, _("failed to allocate disk")); -} - -static void -postlaunch_fs (const char *filename, prep_data *data, const char *device) -{ - if (guestfs_part_disk (g, device, data->params[2]) == -1) - prep_error (data, filename, _("failed to partition disk: %s"), - guestfs_last_error (g)); - - char *part; - if (asprintf (&part, "%s1", device) == -1) { - perror ("asprintf"); - exit (EXIT_FAILURE); - } - - if (guestfs_mkfs (g, data->params[0], part) == -1) - prep_error (data, filename, _("failed to create filesystem (%s): %s"), - data->params[0], guestfs_last_error (g)); - - free (part); -} diff --git a/fish/prep_disk.c b/fish/prep_disk.c new file mode 100644 index 0000000..d393d8d --- /dev/null +++ b/fish/prep_disk.c @@ -0,0 +1,41 @@ +/* guestfish - the filesystem interactive shell + * Copyright (C) 2010 Red Hat Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include +#include +#include +#include +#include + +#include "fish.h" +#include "prepopts.h" + +void +prep_prelaunch_disk (const char *filename, prep_data *data) +{ + if (alloc_disk (filename, data->params[0], 0, 1) == -1) + prep_error (data, filename, _("failed to allocate disk")); +} + +void +prep_postlaunch_disk (const char *filename, prep_data *data, const char *device) +{ + /* nothing */ +} diff --git a/fish/prep_fs.c b/fish/prep_fs.c new file mode 100644 index 0000000..d8fa609 --- /dev/null +++ b/fish/prep_fs.c @@ -0,0 +1,55 @@ +/* guestfish - the filesystem interactive shell + * Copyright (C) 2010 Red Hat Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include +#include +#include +#include +#include + +#include "fish.h" +#include "prepopts.h" + +void +prep_prelaunch_fs (const char *filename, prep_data *data) +{ + if (alloc_disk (filename, data->params[1], 0, 1) == -1) + prep_error (data, filename, _("failed to allocate disk")); +} + +void +prep_postlaunch_fs (const char *filename, prep_data *data, const char *device) +{ + if (guestfs_part_disk (g, device, data->params[2]) == -1) + prep_error (data, filename, _("failed to partition disk: %s"), + guestfs_last_error (g)); + + char *part; + if (asprintf (&part, "%s1", device) == -1) { + perror ("asprintf"); + exit (EXIT_FAILURE); + } + + if (guestfs_mkfs (g, data->params[0], part) == -1) + prep_error (data, filename, _("failed to create filesystem (%s): %s"), + data->params[0], guestfs_last_error (g)); + + free (part); +} diff --git a/fish/prep_part.c b/fish/prep_part.c new file mode 100644 index 0000000..ac46f37 --- /dev/null +++ b/fish/prep_part.c @@ -0,0 +1,43 @@ +/* guestfish - the filesystem interactive shell + * Copyright (C) 2010 Red Hat Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include +#include +#include +#include +#include + +#include "fish.h" +#include "prepopts.h" + +void +prep_prelaunch_part (const char *filename, prep_data *data) +{ + if (alloc_disk (filename, data->params[0], 0, 1) == -1) + prep_error (data, filename, _("failed to allocate disk")); +} + +void +prep_postlaunch_part (const char *filename, prep_data *data, const char *device) +{ + if (guestfs_part_disk (g, device, data->params[1]) == -1) + prep_error (data, filename, _("failed to partition disk: %s"), + guestfs_last_error (g)); +} diff --git a/po/POTFILES.in b/po/POTFILES.in index a06249a..d65ccfd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -81,6 +81,10 @@ fish/lcd.c fish/man.c fish/more.c fish/prep.c +fish/prep_disk.c +fish/prep_fs.c +fish/prep_part.c +fish/prepopts.c fish/progress.c fish/rc.c fish/reopen.c diff --git a/src/generator.ml b/src/generator.ml index 2a5ecfb..2f2e391 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -5619,6 +5619,40 @@ type callt = | CallBool of bool | CallBuffer of string +(* Used for the guestfish -N (prepared disk images) option. + * Note that the longdescs are indented by 2 spaces. + *) +let prepopts = [ + ("disk", + "create a blank disk", + [ "size", "100M", "the size of the disk image" ], + " Create a blank disk, size 100MB (by default). + + The default size can be changed by supplying an optional parameter."); + + ("part", + "create a partitioned disk", + [ "size", "100M", "the size of the disk image"; + "partition", "mbr", "partition table type" ], + " Create a disk with a single partition. By default the size of the disk + is 100MB (the available space in the partition will be a tiny bit smaller) + and the partition table will be MBR (old DOS-style). + + These defaults can be changed by supplying optional parameters."); + + ("fs", + "create a filesystem", + [ "filesystem", "ext2", "the type of filesystem to use"; + "size", "100M", "the size of the disk image"; + "partition", "mbr", "partition table type" ], + " Create a disk with a single partition, with the partition containing + an empty filesystem. This defaults to creating a 100MB disk (the available + space in the filesystem will be a tiny bit smaller) with an MBR (old + DOS-style) partition table and an ext2 filesystem. + + These defaults can be changed by supplying optional parameters."); +] + (* Used to memoize the result of pod2text. *) let pod2text_memo_filename = "src/.pod2text.data" let pod2text_memo : ((int * string * string), string list) Hashtbl.t = @@ -8810,6 +8844,84 @@ Guestfish will prompt for these separately.\n\n"; | Some txt -> pr "%s\n\n" txt ) all_functions_sorted +and generate_fish_prep_options_h () = + generate_header CStyle GPLv2plus; + + pr "#ifndef PREPOPTS_H\n"; + pr "\n"; + + pr "\ +struct prep { + const char *name; /* eg. \"fs\" */ + + size_t nr_params; /* optional parameters */ + struct prep_param *params; + + const char *shortdesc; /* short description */ + const char *longdesc; /* long description */ + + /* functions to implement it */ + void (*prelaunch) (const char *filename, prep_data *); + void (*postlaunch) (const char *filename, prep_data *, const char *device); +}; + +struct prep_param { + const char *pname; /* parameter name */ + const char *pdefault; /* parameter default */ + const char *pdesc; /* parameter description */ +}; + +extern const struct prep preps[]; +#define NR_PREPS %d + +" (List.length prepopts); + + List.iter ( + fun (name, shortdesc, args, longdesc) -> + pr "\ +extern void prep_prelaunch_%s (const char *filename, prep_data *data); +extern void prep_postlaunch_%s (const char *filename, prep_data *data, const char *device); + +" name name; + ) prepopts; + + pr "\n"; + pr "#endif /* PREPOPTS_H */\n" + +and generate_fish_prep_options_c () = + generate_header CStyle GPLv2plus; + + pr "\ +#include \"fish.h\" +#include \"prepopts.h\" + +"; + + List.iter ( + fun (name, shortdesc, args, longdesc) -> + pr "static struct prep_param %s_args[] = {\n" name; + List.iter ( + fun (n, default, desc) -> + pr " { \"%s\", \"%s\", \"%s\" },\n" n default desc + ) args; + pr "};\n"; + pr "\n"; + ) prepopts; + + pr "const struct prep preps[] = {\n"; + List.iter ( + fun (name, shortdesc, args, longdesc) -> + pr " { \"%s\", %d, %s_args, + \"%s\", + \"%s\", + prep_prelaunch_%s, prep_postlaunch_%s }, +" + name (List.length args) name + (c_quote shortdesc) (c_quote longdesc) + name name; + ) prepopts; + pr "};\n" + (* Generate a C function prototype. *) and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true) ?(single_line = false) ?(newline = false) ?(in_daemon = false) @@ -12915,6 +13027,8 @@ Run it from the top source directory using the command output_to "fish/cmds.c" generate_fish_cmds; output_to "fish/completion.c" generate_fish_completion; output_to "fish/guestfish-actions.pod" generate_fish_actions_pod; + output_to "fish/prepopts.c" generate_fish_prep_options_c; + output_to "fish/prepopts.h" generate_fish_prep_options_h; output_to "ocaml/guestfs.mli" generate_ocaml_mli; output_to "ocaml/guestfs.ml" generate_ocaml_ml; output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c; -- 1.8.3.1