/* * misc/bximage.c * $Id: bxcommit.c,v 1.14 2009-04-14 09:45:22 sshwarts Exp $ * * Commits a redolog file in a flat file for bochs images. * */ #include #include #include #ifndef _MSC_VER #include #else #include #endif #include #include #include #include #include #ifdef WIN32 # include #endif #include "config.h" #include #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 */ #include "../osdep.h" #define HDIMAGE_HEADERS_ONLY 1 #include "../iodev/hdimage.h" char *EOF_ERR = "ERROR: End of input"; char *rcsid = "$Id: bxcommit.c,v 1.14 2009-04-14 09:45:22 sshwarts Exp $"; char *divider = "========================================================================"; 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, char *line, int maxwidth) { int imax; int i; imax = (maxwidth - strlen(line)) >> 1; for (i=0; imax) { printf ("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, 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; } printf("Please type either yes or no.\n"); } } int ask_string(const char *prompt, char *the_default, char *out) { char buffer[1024]; char *clean; out[0] = 0; 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; } /* produce the image file */ int commit_redolog(const char *flatname, const char *redologname) { int flatfd, redologfd; redolog_header_t header; Bit32u *catalog, catalog_size; Bit8u *bitmap; Bit32u i, bitmap_blocs, extent_blocs; Bit8u buffer[512]; // check if flat file exists flatfd = open (flatname, O_WRONLY #ifdef O_BINARY | O_BINARY #endif ); if (flatfd<0) { fatal("ERROR: flat file not found or not writable"); } // Check if redolog exists printf("%s\n",redologname); redologfd = open(redologname, O_RDONLY #ifdef O_BINARY | O_BINARY #endif ); if (redologfd<0) { fatal("ERROR: redolog file not found"); } printf ("\nReading redolog header: ["); if (read(redologfd, &header, STANDARD_HEADER_SIZE) != STANDARD_HEADER_SIZE) fatal("\nERROR: while reading redolog header!"); // Print infos on redlog printf("Type='%s', Subtype='%s', Version=%d.%d] Done.", header.standard.type, header.standard.subtype, dtoh32(header.standard.version)/0x10000, dtoh32(header.standard.version)%0x10000); printf("\nChecking redolog header: ["); if (strcmp((char *)header.standard.magic, STANDARD_HEADER_MAGIC) != 0) fatal("\nERROR: bad magic in redolog header!"); if (strcmp((char *)header.standard.type, REDOLOG_TYPE) != 0) fatal("\nERROR: bad type in redolog header!"); if (strcmp((char *)header.standard.subtype, REDOLOG_SUBTYPE_UNDOABLE) != 0) fatal("\nERROR: bad subtype in redolog header!"); if (header.standard.version != htod32(STANDARD_HEADER_VERSION)) fatal("\nERROR: bad version in redolog header!"); printf("#entries=%d, bitmap size=%d, exent size = %d] Done.", dtoh32(header.specific.catalog), dtoh32(header.specific.bitmap), dtoh32(header.specific.extent)); catalog = (Bit32u*)malloc(dtoh32(header.specific.catalog) * sizeof(Bit32u)); bitmap = (Bit8u*)malloc(dtoh32(header.specific.bitmap)); printf("\nReading Catalog: ["); lseek(redologfd, dtoh32(header.standard.header), SEEK_SET); catalog_size = dtoh32(header.specific.catalog) * sizeof(Bit32u); if ((Bit32u) read(redologfd, catalog, catalog_size) != catalog_size) fatal("\nERROR: while reading redolog catalog!"); printf("] Done."); printf("\nCommitting changes to flat file: [ 0%%]"); bitmap_blocs = 1 + (dtoh32(header.specific.bitmap) - 1) / 512; extent_blocs = 1 + (dtoh32(header.specific.extent) - 1) / 512; for(i=0; i