diff --git a/bochs/Makefile.in b/bochs/Makefile.in index 97bc7b9bc..66d685ee3 100644 --- a/bochs/Makefile.in +++ b/bochs/Makefile.in @@ -248,6 +248,9 @@ bximage@EXE@: misc/bximage.o bxcommit@EXE@: misc/bxcommit.o @LINK_CONSOLE@ misc/bxcommit.o +bximage_new@EXE@: misc/bximage_new.o misc/hdimage.o misc/vmware3.o misc/vmware4.o misc/vpc-img.o + @LINK_CONSOLE@ misc/bximage_new.o misc/hdimage.o misc/vmware3.o misc/vmware4.o misc/vpc-img.o + niclist@EXE@: misc/niclist.o @LINK_CONSOLE@ misc/niclist.o @@ -258,6 +261,26 @@ misc/bximage.o: $(srcdir)/misc/bximage.c $(srcdir)/misc/bswap.h $(srcdir)/iodev/ misc/bxcommit.o: $(srcdir)/misc/bxcommit.c $(srcdir)/misc/bswap.h $(srcdir)/iodev/hdimage/hdimage.h $(CC) @DASH@c $(BX_INCDIRS) $(CFLAGS_CONSOLE) $(srcdir)/misc/bxcommit.c @OFP@$@ +misc/bximage_new.o: $(srcdir)/misc/bximage_new.cc $(srcdir)/misc/bswap.h \ + $(srcdir)/misc/bxcompat.h $(srcdir)/iodev/hdimage/hdimage.h + $(CXX) @DASH@c $(BX_INCDIRS) $(CXXFLAGS_CONSOLE) $(srcdir)/misc/bximage_new.cc @OFP@$@ + +misc/hdimage.o: $(srcdir)/iodev/hdimage/hdimage.cc \ + $(srcdir)/iodev/hdimage/hdimage.h $(srcdir)/misc/bxcompat.h + $(CXX) @DASH@c $(BX_INCDIRS) -DBXIMAGE $(CXXFLAGS_CONSOLE) $(srcdir)/iodev/hdimage/hdimage.cc @OFP@$@ + +misc/vmware3.o: $(srcdir)/iodev/hdimage/vmware3.cc $(srcdir)/iodev/hdimage/vmware3.h \ + $(srcdir)/iodev/hdimage/hdimage.h $(srcdir)/misc/bxcompat.h + $(CXX) @DASH@c $(BX_INCDIRS) -DBXIMAGE $(CXXFLAGS_CONSOLE) $(srcdir)/iodev/hdimage/vmware3.cc @OFP@$@ + +misc/vmware4.o: $(srcdir)/iodev/hdimage/vmware4.cc $(srcdir)/iodev/hdimage/vmware4.h \ + $(srcdir)/iodev/hdimage/hdimage.h $(srcdir)/misc/bxcompat.h + $(CXX) @DASH@c $(BX_INCDIRS) -DBXIMAGE $(CXXFLAGS_CONSOLE) $(srcdir)/iodev/hdimage/vmware4.cc @OFP@$@ + +misc/vpc-img.o: $(srcdir)/iodev/hdimage/vpc-img.cc $(srcdir)/iodev/hdimage/vpc-img.h \ + $(srcdir)/iodev/hdimage/hdimage.h $(srcdir)/misc/bxcompat.h + $(CXX) @DASH@c $(BX_INCDIRS) -DBXIMAGE $(CXXFLAGS_CONSOLE) $(srcdir)/iodev/hdimage/vpc-img.cc @OFP@$@ + misc/niclist.o: $(srcdir)/misc/niclist.c $(CC) @DASH@c $(BX_INCDIRS) $(CFLAGS_CONSOLE) $(srcdir)/misc/niclist.c @OFP@$@ diff --git a/bochs/iodev/hdimage/hdimage.cc b/bochs/iodev/hdimage/hdimage.cc index a020f92d8..3c4cde6b8 100644 --- a/bochs/iodev/hdimage/hdimage.cc +++ b/bochs/iodev/hdimage/hdimage.cc @@ -26,8 +26,8 @@ #ifdef BXIMAGE #include "config.h" -#include "osdep.h" #include "misc/bxcompat.h" +#include "osdep.h" #else #include "iodev.h" #include "cdrom.h" diff --git a/bochs/iodev/hdimage/vmware3.cc b/bochs/iodev/hdimage/vmware3.cc index d54cc16cc..7b79177c9 100644 --- a/bochs/iodev/hdimage/vmware3.cc +++ b/bochs/iodev/hdimage/vmware3.cc @@ -33,8 +33,8 @@ #ifdef BXIMAGE #include "config.h" -#include "osdep.h" #include "misc/bxcompat.h" +#include "osdep.h" #else #include "iodev.h" #endif diff --git a/bochs/iodev/hdimage/vmware4.cc b/bochs/iodev/hdimage/vmware4.cc index ef2c621e6..9a53bfd4a 100644 --- a/bochs/iodev/hdimage/vmware4.cc +++ b/bochs/iodev/hdimage/vmware4.cc @@ -33,8 +33,8 @@ #ifdef BXIMAGE #include "config.h" -#include "osdep.h" #include "misc/bxcompat.h" +#include "osdep.h" #else #include "iodev.h" #endif diff --git a/bochs/iodev/hdimage/vpc-img.cc b/bochs/iodev/hdimage/vpc-img.cc index afd7b853a..beea7a993 100644 --- a/bochs/iodev/hdimage/vpc-img.cc +++ b/bochs/iodev/hdimage/vpc-img.cc @@ -35,9 +35,9 @@ #ifdef BXIMAGE #include "config.h" +#include "misc/bxcompat.h" #include "osdep.h" #include "misc/bswap.h" -#include "misc/bxcompat.h" #else #include "iodev.h" #endif diff --git a/bochs/misc/bxcompat.h b/bochs/misc/bxcompat.h new file mode 100644 index 000000000..7dab10a5f --- /dev/null +++ b/bochs/misc/bxcompat.h @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2013 Volker Ruppert +// Copyright (C) 2001-2013 The Bochs Project +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +///////////////////////////////////////////////////////////////////////// + +#ifndef BX_COMPAT_H +#define BX_COMPAT_H + +// copied from bochs.h +#ifdef WIN32 +# include +#endif +#include +#include +#include +#ifndef _MSC_VER +# include +#else +# include +#endif +#include +#include +#include +#include +#include + +// copied from siminterface.h +enum { + BX_HDIMAGE_MODE_FLAT, + BX_HDIMAGE_MODE_CONCAT, + BX_HDIMAGE_MODE_EXTDISKSIM, + BX_HDIMAGE_MODE_DLL_HD, + BX_HDIMAGE_MODE_SPARSE, + BX_HDIMAGE_MODE_VMWARE3, + BX_HDIMAGE_MODE_VMWARE4, + BX_HDIMAGE_MODE_UNDOABLE, + BX_HDIMAGE_MODE_GROWING, + BX_HDIMAGE_MODE_VOLATILE, + BX_HDIMAGE_MODE_VVFAT, + BX_HDIMAGE_MODE_VPC +}; +#define BX_HDIMAGE_MODE_LAST BX_HDIMAGE_MODE_VPC +#define BX_HDIMAGE_MODE_UNKNOWN -1 + +// definitions for compatibility with Bochs +#ifndef UNUSED +# define UNUSED(x) ((void)x) +#endif + +#define BX_DEBUG(x) +#define BX_INFO(x) { (printf) x ; printf("\n"); } +#define BX_ERROR(x) { (printf) x ; printf("\n"); } +#define BX_PANIC(x) { (printf) x ; printf("\n"); myexit(1); } +#define BX_ASSERT(x) + +class device_image_t; + +void myexit(int code); +device_image_t* init_image(Bit8u image_mode); + +#define DEV_hdimage_init_image(a,b,c) init_image(a) + +#endif diff --git a/bochs/misc/bximage_new.cc b/bochs/misc/bximage_new.cc new file mode 100644 index 000000000..c6f526c6c --- /dev/null +++ b/bochs/misc/bximage_new.cc @@ -0,0 +1,719 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2013 Volker Ruppert +// Copyright (C) 2001-2013 The Bochs Project +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +///////////////////////////////////////////////////////////////////////// + +// TODO: Create empty hard disk or floppy disk images for bochs. +// Convert a hard disk image from one format (mode) to another. +// Commit a redolog file to a supported base image. + +#ifdef WIN32 +# include +#endif +#include + +#include "config.h" +#include "bxcompat.h" +#include "osdep.h" +#include "bswap.h" + +#define BXIMAGE +#include "iodev/hdimage/hdimage.h" +#include "iodev/hdimage/vmware3.h" +#include "iodev/hdimage/vmware4.h" +#include "iodev/hdimage/vpc-img.h" + +#define BXIMAGE_MODE_NULL 0 +#define BXIMAGE_MODE_CREATE_IMAGE 1 +#define BXIMAGE_MODE_CONVERT_IMAGE 2 +#define BXIMAGE_MODE_COMMIT_UNDOABLE 3 + +int bximage_mode; +int bx_hdimagemode; +int bx_remove; +int bx_interactive; +char bx_filename_1[512]; +char bx_filename_2[512]; + +const char *EOF_ERR = "ERROR: End of input"; +const char *svnid = "$Id$"; +const char *divider = "========================================================================"; +const char *main_menu_prompt = +"\n" +"1. Create new floppy or hard disk image\n" +"2. Convert hard disk image to other format (mode)\n" +"3. Commit 'undoable' redolog to base image\n" +"\n" +"0. Quit\n" +"\n" +"Please choose one "; + +// menu data for choosing disk mode +const char *hdmode_menu = "\nWhat kind of image should I create?\nPlease type flat, sparse or growing. "; +const char *hdmode_choices[] = {"flat", "sparse", "growing" }; +const int hdmode_choice_id[] = {BX_HDIMAGE_MODE_FLAT, BX_HDIMAGE_MODE_SPARSE, BX_HDIMAGE_MODE_GROWING}; +int hdmode_n_choices = 3; + +#if !BX_HAVE_SNPRINTF +#include +/* XXX use real snprintf */ +/* if they don't have snprintf, just use sprintf */ +int snprintf(char *s, size_t maxlen, const char *format, ...) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vsprintf(s, format, arg); + va_end(arg); + + return done; +} +#endif /* !BX_HAVE_SNPRINTF */ + +#if !BX_HAVE_MKSTEMP +int bx_mkstemp(char *tpl) +{ + mktemp(tpl); + return ::open(tpl, O_RDWR | O_CREAT | O_TRUNC +#ifdef O_BINARY + | O_BINARY +#endif + , S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP); +} +#endif // !BX_HAVE_MKSTEMP + +void myexit(int code) +{ +#ifdef WIN32 + printf("\nPress any key to continue\n"); + getch(); +#endif + exit(code); +} + +// stolen from main.cc +void bx_center_print(FILE *file, const char *line, int maxwidth) +{ + int imax; + int i; + imax = (maxwidth - strlen(line)) >> 1; + for (i=0; imax) { + fprintf(stderr, "Your choice (%s) was not an integer between %d and %d.\n\n", + clean, min, max); + } else { + // choice is okay + *out = n; + return 0; + } + } +} + +int ask_menu(const char *prompt, int n_choices, const char *choice[], int the_default, int *out) +{ + char buffer[1024]; + char *clean; + int i; + *out = -1; + while(1) { + printf("%s", prompt); + printf("[%s] ", choice[the_default]); + if (!fgets(buffer, sizeof(buffer), stdin)) + return -1; + clean = clean_string(buffer); + if (strlen(clean) < 1) { + // empty line, use the default + *out = the_default; + return 0; + } + for (i=0; i0) printf(", "); + printf("%s", choice[i]); + } + printf("\n"); + } +} + +int ask_yn(const char *prompt, int the_default, int *out) +{ + char buffer[16]; + char *clean; + *out = -1; + while (1) { + printf("%s", prompt); + printf("[%s] ", the_default?"yes":"no"); + if (!fgets(buffer, sizeof(buffer), stdin)) + return -1; + clean = clean_string(buffer); + if (strlen(clean) < 1) { + // empty line, use the default + *out = the_default; + return 0; + } + switch (tolower(clean[0])) { + case 'y': *out=1; return 0; + case 'n': *out=0; return 0; + } + fprintf(stderr, "Please type either yes or no.\n"); + } +} + +int ask_string(const char *prompt, char *the_default, char *out) +{ + char buffer[1024]; + char *clean; + printf("%s", prompt); + printf("[%s] ", the_default); + if (!fgets(buffer, sizeof(buffer), stdin)) + return -1; + clean = clean_string(buffer); + if (strlen(clean) < 1) { + // empty line, use the default + strcpy(out, the_default); + return 0; + } + strcpy(out, clean); + return 0; +} + +device_image_t* init_image(Bit8u image_mode) +{ + device_image_t *hdimage = NULL; + + // instantiate the right class + switch (image_mode) { + + case BX_HDIMAGE_MODE_FLAT: + hdimage = new default_image_t(); + break; + + case BX_HDIMAGE_MODE_SPARSE: + hdimage = new sparse_image_t(); + break; + + case BX_HDIMAGE_MODE_VMWARE3: + hdimage = new vmware3_image_t(); + break; + + case BX_HDIMAGE_MODE_VMWARE4: + hdimage = new vmware4_image_t(); + break; + + case BX_HDIMAGE_MODE_GROWING: + hdimage = new growing_image_t(); + break; + + case BX_HDIMAGE_MODE_VPC: + hdimage = new vpc_image_t(); + break; + + default: + fatal("unsupported disk image mode"); + break; + } + return hdimage; +} + +int create_image_file(const char *filename) +{ + int fd = open(filename, O_WRONLY | O_CREAT +#ifdef O_BINARY + | O_BINARY +#endif + , S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP + ); + if (fd < 0) { + fatal("ERROR: flat file is not writable"); + } + return fd; +} + +int create_flat_image(const char *filename, Bit64u size) +{ + char buffer[512]; + + int fd = create_image_file(filename); + memset(buffer, 0, 512); + if (bx_write_image(fd, size, buffer, 512) != 512) + fatal("ERROR: while writing block in flat file !"); + close(fd); + + return 0; +} + +int create_sparse_image(const char *filename, Bit64u size) +{ + Bit64u numpages; + sparse_header_t header; + size_t sizesofar; + int padtopagesize; + + memset(&header, 0, sizeof(header)); + header.magic = htod32(SPARSE_HEADER_MAGIC); + header.version = htod32(SPARSE_HEADER_VERSION); + + header.pagesize = htod32((1 << 10) * 32); // Use 32 KB Pages - could be configurable + numpages = (size / dtoh32(header.pagesize)) + 1; + + header.numpages = htod32((Bit32u)numpages); + header.disk = htod64(size); + + if (numpages != dtoh32(header.numpages)) { + fatal("ERROR: The disk image is too large for a sparse image!"); + // Could increase page size here. + // But note this only happens at 128 Terabytes! + } + + int fd = create_image_file(filename); + if (bx_write_image(fd, 0, &header, sizeof(header)) != sizeof(header)) { + close(fd); + fatal("ERROR: The disk image is not complete - could not write header!"); + } + + Bit32u *pagetable = new Bit32u[dtoh32(header.numpages)]; + if (pagetable == NULL) + fatal("ERROR: The disk image is not complete - could not create pagetable!"); + for (Bit32u i=0; icreate(filename, REDOLOG_SUBTYPE_GROWING, size) < 0) + fatal("Can't create growing mode image"); + redolog->close(); + delete redolog; + + return 0; +} + +int convert_image(int newimgmode) +{ + device_image_t *source_image, *dest_image; + Bit64u i, sc, s; + char buffer[512], null_sector[512]; + bx_bool error = 0; + + printf("\n"); + memset(null_sector, 0, 512); + int mode = hdimage_detect_image_mode(bx_filename_1); + if (mode == BX_HDIMAGE_MODE_UNKNOWN) + fatal("base disk image mode not detected"); + + source_image = init_image(mode); + if (source_image->open(bx_filename_1, O_RDONLY) < 0) + fatal("cannot open source disk image"); + + int fd = hdimage_open_file(bx_filename_2, O_RDONLY, NULL, NULL); + if (fd >= 0) { + close(fd); + int confirm; + sprintf(buffer, "\nThe disk image '%s' already exists. Are you sure you want to replace it?\nPlease type yes or no. ", bx_filename_2); + if (ask_yn(buffer, 0, &confirm) < 0) + fatal(EOF_ERR); + if (!confirm) + fatal("ERROR: Aborted"); + } + + switch (newimgmode) { + case BX_HDIMAGE_MODE_FLAT: + create_flat_image(bx_filename_2, source_image->hd_size); + break; + + case BX_HDIMAGE_MODE_GROWING: + create_growing_image(bx_filename_2, source_image->hd_size); + break; + + case BX_HDIMAGE_MODE_SPARSE: + create_sparse_image(bx_filename_2, source_image->hd_size); + break; + + default: + fatal("image mode not implemented yet"); + } + + dest_image = init_image(newimgmode); + if (dest_image->open(bx_filename_2) < 0) + fatal("cannot open destination disk image"); + + printf("\nConverting image file: [ 0%%]"); + + sc = source_image->hd_size / 512; + s = 0; + for (i = 0; i < source_image->hd_size; i+=512) { + printf("\x8\x8\x8\x8\x8%3d%%]", (int)((s+1)*100/sc)); + fflush(stdout); + if (source_image->lseek(i, SEEK_SET) < 0) { + error = 1; + break; + } + if ((source_image->read(buffer, 512) == 512) && + (memcmp(buffer, null_sector, 512) != 0)) { + if (dest_image->lseek(i, SEEK_SET) < 0) { + error = 1; + break; + } + if (dest_image->write(buffer, 512) < 0) { + error = 1; + break; + } + } + s++; + } + + source_image->close(); + dest_image->close(); + delete dest_image; + delete source_image; + + if (error) { + fatal("image conversion failed"); + } else { + printf(" Done.\n"); + } + + return 0; +} + +int commit_redolog() +{ + device_image_t *base_image; + redolog_t *redolog; + Bit64u i, sc, s; + Bit8u buffer[512]; + bx_bool error = 0; + + printf("\n"); + int mode = hdimage_detect_image_mode(bx_filename_1); + if (mode == BX_HDIMAGE_MODE_UNKNOWN) + fatal("base disk image mode not detected"); + + base_image = init_image(mode); + if (base_image->open(bx_filename_1) < 0) + fatal("cannot open base disk image"); + + redolog = new redolog_t; + if (redolog->open(bx_filename_2, REDOLOG_SUBTYPE_UNDOABLE) < 0) + fatal("Can't open redolog"); + if (!coherency_check(base_image, redolog)) + fatal("coherency check failed"); + + printf("\nCommitting changes to base image file: [ 0%%]"); + + sc = base_image->hd_size / 512; + s = 0; + for (i = 0; i < base_image->hd_size; i+=512) { + printf("\x8\x8\x8\x8\x8%3d%%]", (int)((s+1)*100/sc)); + fflush(stdout); + if (redolog->lseek(i, SEEK_SET) < 0) { + error = 1; + break; + } + if (redolog->read(buffer, 512) == 512) { + if (base_image->lseek(i, SEEK_SET) < 0) { + error = 1; + break; + } + if (base_image->write(buffer, 512) < 0) { + error = 1; + break; + } + } + s++; + } + + base_image->close(); + redolog->close(); + delete base_image; + delete redolog; + + if (error) { + fatal("redolog commit failed"); + } else { + printf(" Done.\n"); + } + + return 0; +} + +void print_usage() +{ + fprintf(stderr, + "Usage: bximage_new [options] [filename1] [filename2]\n\n" + "Supported options:\n" + " -mode=create create new floppy or hard disk image\n" + " -mode=convert convert hard disk image to other format (mode)\n" + " -mode=commit commit undoable redolog to base image\n" + " -imgmode=... create/convert: hard disk image mode\n" + " -d convert/commit: delete source file after operation\n" + " -q quiet mode (don't prompt for user input)\n" + " --help display this help and exit\n\n" + "Other arguments:\n" + " filename1 create: new image file\n" + " convert: source image file\n" + " commit: base image file\n" + " filename2 convert: destination image file\n" + " commit: redolog (journal) file\n\n"); +} + +int parse_cmdline(int argc, char *argv[]) +{ + int arg = 1; + int ret = 1; + int fnargs = 0; + + bximage_mode = BXIMAGE_MODE_NULL; + bx_hdimagemode = 0; + bx_remove = 0; + bx_interactive = 1; + bx_filename_1[0] = 0; + bx_filename_2[0] = 0; + while ((arg < argc) && (ret == 1)) { + // parse next arg + if (!strcmp("--help", argv[arg]) || !strncmp("/?", argv[arg], 2)) { + print_usage(); + ret = 0; + } + else if (!strncmp("-mode=", argv[arg], 6)) { + if (!strcmp(&argv[arg][6], "create")) { + bximage_mode = BXIMAGE_MODE_CREATE_IMAGE; + } else if (!strcmp(&argv[arg][6], "convert")) { + bximage_mode = BXIMAGE_MODE_CONVERT_IMAGE; + } else if (!strcmp(&argv[arg][6], "commit")) { + bximage_mode = BXIMAGE_MODE_COMMIT_UNDOABLE; + } else { + printf("Unknown bximage mode '%s'\n\n", &argv[arg][6]); + } + } + else if (!strncmp("-imgmode=", argv[arg], 9)) { + bx_hdimagemode = get_menu_index(&argv[arg][9], hdmode_n_choices, hdmode_choices); + if (bx_hdimagemode < 0) { + printf("Unknown image mode: %s\n\n", &argv[arg][9]); + ret = 0; + } + } + else if (!strcmp("-d", argv[arg])) { + bx_remove = 1; + } + else if (!strcmp("-q", argv[arg])) { + bx_interactive = 0; + } + else if (argv[arg][0] == '-') { + printf("Unknown option: %s\n\n", argv[arg]); + ret = 0; + } else { + if (fnargs == 0) { + strcpy(bx_filename_1, argv[arg]); + } else if (fnargs == 1) { + strcpy(bx_filename_2, argv[arg]); + } else { + printf("Ignoring extra parameter: %s\n\n", argv[arg]); + } + fnargs++; + } + arg++; + } + if (bximage_mode == BXIMAGE_MODE_NULL) { + bx_interactive = 1; + } else if ((bximage_mode != BXIMAGE_MODE_CREATE_IMAGE) && (fnargs < 2)) { + bx_interactive = 1; + } + return ret; +} + +int main(int argc, char *argv[]) +{ + char tmplogname[512]; + int imgmode = 0; + + if (!parse_cmdline(argc, argv)) + myexit(1); + + print_banner(); + + if (bx_interactive) { + if (ask_int(main_menu_prompt, 0, 3, bximage_mode, &bximage_mode) < 0) + fatal(EOF_ERR); + + switch (bximage_mode) { + case BXIMAGE_MODE_NULL: + myexit(0); + break; + + case BXIMAGE_MODE_CONVERT_IMAGE: + if (!strlen(bx_filename_1)) { + strcpy(bx_filename_1, "c.img"); + } + if (ask_string("\nWhat is the name of the source image?\n", bx_filename_1, bx_filename_1) < 0) + fatal(EOF_ERR); + if (!strlen(bx_filename_2)) { + strcpy(tmplogname, "c-new.img"); + } else { + strcpy(tmplogname, bx_filename_2); + } + if (ask_string("\nWhat should be the name of the new image?\n", tmplogname, bx_filename_2) < 0) + fatal(EOF_ERR); + if (ask_menu(hdmode_menu, hdmode_n_choices, hdmode_choices, bx_hdimagemode, &bx_hdimagemode) < 0) + fatal(EOF_ERR); + imgmode = hdmode_choice_id[bx_hdimagemode]; + if (ask_yn("\nShould the source been removed afterwards?\n", 0, &bx_remove) < 0) + fatal(EOF_ERR); + break; + + case BXIMAGE_MODE_COMMIT_UNDOABLE: + if (!strlen(bx_filename_1)) { + strcpy(bx_filename_1, "c.img"); + } + if (ask_string("\nWhat is the name of the base image?\n", bx_filename_1, bx_filename_1) < 0) + fatal(EOF_ERR); + if (!strlen(bx_filename_2)) { + snprintf(tmplogname, 256, "%s%s", bx_filename_1, UNDOABLE_REDOLOG_EXTENSION); + } else { + strcpy(tmplogname, bx_filename_2); + } + if (ask_string("\nWhat is the redolog name?\n", tmplogname, bx_filename_2) < 0) + fatal(EOF_ERR); + if (ask_yn("\nShould the redolog been removed afterwards?\n", 1, &bx_remove) < 0) + fatal(EOF_ERR); + break; + + default: + fatal("\nbximage_new: mode not implemented yet"); + } + } + if (bximage_mode == BXIMAGE_MODE_CREATE_IMAGE) { + // TODO + } else if (bximage_mode == BXIMAGE_MODE_CONVERT_IMAGE) { + convert_image(imgmode); + if (bx_remove) { + if (unlink(bx_filename_1) != 0) + fatal("ERROR: while removing the source image !\n"); + } + } else if (bximage_mode == BXIMAGE_MODE_COMMIT_UNDOABLE) { + commit_redolog(); + if (bx_remove) { + if (unlink(bx_filename_2) != 0) + fatal("ERROR: while removing the redolog !\n"); + } + } + + return 0; +}