feat: CLI-only version (without GTK)

Modify the build system and the source
files to support building a CLI-only
version with only glib2 as a dependency.
Use CLI_ONLY=1 ./configure, then make clean all.
This commit is contained in:
Stéphane Lesimple
2020-08-18 18:26:24 +02:00
parent 4f480905dc
commit 99b27b982a
59 changed files with 9419 additions and 7349 deletions

View File

@@ -368,12 +368,14 @@ static void cleanup(gpointer data)
}
bail_out:
#ifndef CLI
if(Closure->guiMode)
{ if(rc->earlyTermination)
SetAdaptiveReadFootline(_("Aborted by unrecoverable error."), Closure->redText);
AllowActions(TRUE);
}
#endif
if(rc->image)
if(!LargeClose(rc->image))
@@ -399,8 +401,10 @@ bail_out:
g_free(rc);
#ifndef CLI
if(Closure->guiMode)
g_thread_exit(0);
#endif
}
/***
@@ -486,8 +490,10 @@ static void print_progress(read_closure *rc, int immediate)
int total = rc->readable+rc->correctable;
int percent = (int)((1000LL*(long long)total)/rc->expectedSectors);
#ifndef CLI
if(Closure->guiMode)
return;
#endif
if( rc->lastPercent >= percent
&& rc->lastCorrectable == rc->correctable
@@ -535,7 +541,12 @@ static void print_progress(read_closure *rc, int immediate)
static void clear_progress(read_closure *rc)
{
if(!rc->progressMsgLen || Closure->guiMode)
if(!rc->progressMsgLen ||
#ifndef CLI
Closure->guiMode)
#else
0)
#endif
return;
rc->progressSp[rc->progressMsgLen] = 0;
@@ -553,6 +564,7 @@ static void clear_progress(read_closure *rc)
* Sector markup in the spiral
*/
#ifndef CLI
static void mark_sector(read_closure *rc, gint64 sector, GdkColor *color)
{ int segment;
int changed = FALSE;
@@ -598,6 +610,7 @@ static void mark_sector(read_closure *rc, gint64 sector, GdkColor *color)
rc->expectedSectors-rc->readable-rc->correctable,
(int)((1000LL*(rc->readable+rc->correctable))/rc->expectedSectors));
}
#endif
/***
*** Basic device and image handling and sanity checks.
@@ -639,7 +652,9 @@ static void open_and_determine_mode(read_closure *rc)
rc->rs01LayerSectors = (rc->ei->sectors+rc->eh->dataBytes-1)/rc->eh->dataBytes;
#ifndef CLI
SetAdaptiveReadMinimumPercentage((1000*(rc->eh->dataBytes-rc->eh->eccBytes))/rc->eh->dataBytes);
#endif
}
else /* see if we have RS02 type ecc */
if(rc->medium->eccHeader && !strncmp((char*)rc->medium->eccHeader->method,"RS02",4))
@@ -647,7 +662,9 @@ static void open_and_determine_mode(read_closure *rc)
rc->eh = rc->medium->eccHeader;
rc->lay = RS02LayoutFromImage(rc->medium);
#ifndef CLI
SetAdaptiveReadMinimumPercentage((1000*rc->lay->ndata)/255);
#endif
if(Closure->version < rc->eh->neededVersion)
PrintCLI(_("* Warning: This image requires dvdisaster-%d.%d!\n"
@@ -718,9 +735,10 @@ static void check_size(read_closure *rc)
/* Compare size with answer from drive */
if(rc->sectors < rc->dh->sectors)
{ int answer;
{
int answer;
answer = ModalWarning(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
answer = ModalWarningOrCLI(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
_("Medium contains %lld sectors more as recorded in the .ecc file\n"
"(Medium: %lld sectors; expected from .ecc file: %lld sectors).\n"
"Only the first %lld medium sectors will be processed.\n"),
@@ -728,23 +746,30 @@ static void check_size(read_closure *rc)
rc->sectors);
if(!answer)
{ SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
{
#ifndef CLI
SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
#endif
rc->earlyTermination = FALSE;
cleanup((gpointer)rc);
}
}
if(rc->sectors > rc->dh->sectors)
{ int answer;
{
int answer;
answer = ModalWarning(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
answer = ModalWarningOrCLI(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
_("Medium contains %lld sectors less as recorded in the .ecc file\n"
"(Medium: %lld sectors; expected from .ecc file: %lld sectors).\n"),
rc->sectors-rc->dh->sectors, rc->dh->sectors, rc->sectors,
rc->sectors);
if(!answer)
{ SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
{
#ifndef CLI
SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
#endif
rc->earlyTermination = FALSE;
cleanup((gpointer)rc);
}
@@ -761,10 +786,14 @@ void GetReadingRange(gint64 sectors, gint64 *firstSector, gint64 *lastSector)
{ gint64 first, last;
if(Closure->readStart || Closure->readEnd)
{ if(!Closure->guiMode) /* more range checks are made below */
{
#ifndef CLI
if(!Closure->guiMode) /* more range checks are made below */
#endif
{ first = Closure->readStart;
last = Closure->readEnd < 0 ? sectors-1 : Closure->readEnd;
}
#ifndef CLI
else /* be more permissive in GUI mode */
{ first = 0;
last = sectors-1;
@@ -774,6 +803,7 @@ void GetReadingRange(gint64 sectors, gint64 *firstSector, gint64 *lastSector)
last = Closure->readEnd < sectors ? Closure->readEnd : sectors-1;
}
}
#endif
if(first > last || first < 0 || last >= sectors)
Stop(_("Sectors must be in range [0..%lld].\n"), sectors-1);
@@ -800,15 +830,19 @@ static void check_ecc_fingerprint(read_closure *rc)
fp_read = GetImageFingerprint(rc->medium, digest, rc->eh->fpSector);
if(!fp_read) /* Not readable. Bad luck. */
{ int answer;
{
int answer;
answer = ModalWarning(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
answer = ModalWarningOrCLI(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
_("Sector %d is missing. Can not compare medium and ecc fingerprints.\n"
"Double check that the medium and the ecc file belong together.\n"),
rc->eh->fpSector);
if(!answer)
{ SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
{
#ifndef CLI
SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
#endif
rc->earlyTermination = FALSE;
cleanup((gpointer)rc);
}
@@ -856,8 +890,11 @@ int check_image_fingerprint(read_closure *rc)
if(memcmp(image_fp, medium_fp, 16))
{
#ifndef CLI
if(!Closure->guiMode)
#endif
Stop(_("Image file does not match the optical disc."));
#ifndef CLI
else
{ int answer = ConfirmImageDeletion(Closure->imageName);
@@ -873,6 +910,7 @@ int check_image_fingerprint(read_closure *rc)
return TRUE; /* causes reopen of image in caller */
}
}
#endif
}
return 0; /* okay */
@@ -886,16 +924,20 @@ int check_image_fingerprint(read_closure *rc)
void check_image_size(read_closure *rc, gint64 image_file_sectors)
{
if(image_file_sectors > rc->expectedSectors)
{ int answer;
{
int answer;
answer = ModalWarning(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
answer = ModalWarningOrCLI(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, NULL,
_("Image file is %lld sectors longer than inserted medium\n"
"(Image file: %lld sectors; medium: %lld sectors).\n"),
image_file_sectors-rc->expectedSectors,
image_file_sectors, rc->expectedSectors);
if(!answer)
{ SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
{
#ifndef CLI
SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
#endif
rc->earlyTermination = FALSE;
cleanup((gpointer)rc);
}
@@ -913,11 +955,15 @@ static void load_crc_buf(read_closure *rc)
{
switch(rc->readMode)
{ case ECC_IN_FILE:
#ifndef CLI
SetAdaptiveReadSubtitle(_utf("Loading CRC data."));
#endif
rc->crcBuf = GetCRCFromRS01_obsolete(rc->ei);
break;
case ECC_IN_IMAGE:
#ifndef CLI
SetAdaptiveReadSubtitle(_utf("Loading CRC data."));
#endif
rc->crcBuf = GetCRCFromRS02_obsolete(rc->lay, rc->dh, rc->image);
break;
default:
@@ -948,19 +994,23 @@ static void build_interval_from_image(read_closure *rc)
Check them for "dead sector markers"
and for checksum failures if ecc data is present. */
#ifndef CLI
if(Closure->guiMode)
SetAdaptiveReadSubtitle(_("Analysing existing image file"));
#endif
for(s=0; s<=rc->highestWrittenSector; s++)
{ int n,percent;
/* Check for user interruption. */
#ifndef CLI
if(Closure->stopActions)
{ SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
rc->earlyTermination = FALSE;
cleanup((gpointer)rc);
}
#endif
/* Read the next sector */
@@ -974,7 +1024,9 @@ static void build_interval_from_image(read_closure *rc)
if(current_missing)
{ int fixme=0;
#ifndef CLI
mark_sector(rc, s, Closure->redSector);
#endif
ExplainMissingSector(rc->buf, s, current_missing, SOURCE_IMAGE, &fixme);
}
@@ -994,7 +1046,9 @@ static void build_interval_from_image(read_closure *rc)
make it missing due to the CRC failure. */
if(!current_missing)
{ current_missing = 1;
#ifndef CLI
mark_sector(rc, s, Closure->yellowSector);
#endif
}
}
@@ -1009,7 +1063,9 @@ static void build_interval_from_image(read_closure *rc)
if(rc->map)
SetBit(rc->map, s);
#ifndef CLI
mark_sector(rc, s, Closure->greenSector);
#endif
#ifdef CHECK_VISITED
rc->count[s]++;
@@ -1043,7 +1099,10 @@ static void build_interval_from_image(read_closure *rc)
percent = (100*s)/(rc->highestWrittenSector+1);
if(last_percent != percent)
{ if(!Closure->guiMode)
{
#ifndef CLI
if(!Closure->guiMode)
#endif
PrintProgress(_("Analysing existing image file: %2d%%"),percent);
last_percent = percent;
@@ -1071,8 +1130,10 @@ static void build_interval_from_image(read_closure *rc)
/*** Now that all readable sectors are known,
determine those which can already be corrected. */
#ifndef CLI
if(Closure->guiMode)
SetAdaptiveReadSubtitle(_("Determining correctable sectors"));
#endif
/* RS01 type error correction. */
@@ -1104,7 +1165,9 @@ static void build_interval_from_image(read_closure *rc)
#ifdef CHECK_VISITED
rc->count[layer_idx]++;
#endif
#ifndef CLI
mark_sector(rc, layer_idx, Closure->greenSector);
#endif
}
layer_idx += rc->rs01LayerSectors;
@@ -1137,7 +1200,9 @@ static void build_interval_from_image(read_closure *rc)
&& !GetBit(rc->map, sector))
{ SetBit(rc->map, sector);
rc->correctable++;
#ifndef CLI
mark_sector(rc, sector, Closure->greenSector);
#endif
}
}
}
@@ -1152,10 +1217,12 @@ static void build_interval_from_image(read_closure *rc)
else PrintLog(_("Analysing existing image file: %lld readable, %lld still missing.\n"),
rc->readable, rc->expectedSectors-rc->readable-rc->correctable);
#ifndef CLI
if(Closure->guiMode)
UpdateAdaptiveResults(rc->readable, rc->correctable,
rc->expectedSectors-rc->readable-rc->correctable,
(int)((1000LL*(rc->readable+rc->correctable))/rc->expectedSectors));
#endif
// print_intervals(rc);
}
@@ -1179,12 +1246,16 @@ static void mark_rs02_headers(read_closure *rc)
while(hpos < end)
{ if(!GetBit(rc->map, hpos))
{ SetBit(rc->map, hpos);
#ifndef CLI
mark_sector(rc, hpos, Closure->greenSector);
#endif
rc->correctable++;
}
if(!GetBit(rc->map, hpos+1))
{ SetBit(rc->map, hpos+1);
#ifndef CLI
mark_sector(rc, hpos+1, Closure->greenSector);
#endif
rc->correctable++;
}
@@ -1196,6 +1267,7 @@ static void mark_rs02_headers(read_closure *rc)
*** Main routine for adaptive reading
***/
#ifndef CLI
static void insert_buttons(GtkDialog *dialog)
{
gtk_dialog_add_buttons(dialog,
@@ -1203,6 +1275,7 @@ static void insert_buttons(GtkDialog *dialog)
_utf("Ignore always"), 2,
_utf("Abort"), 0, NULL);
}
#endif
/*
* Fill the gap between rc->intervalStart and rc->highestWrittenSector
@@ -1239,10 +1312,12 @@ void fill_gap(read_closure *rc)
t = g_strdup_printf(_("Filling image area [%lld..%lld]"),
firstUnwritten, rc->intervalStart-1);
clear_progress(rc);
#ifndef CLI
if(Closure->guiMode)
{ SetAdaptiveReadSubtitle(t);
ChangeSpiralCursor(Closure->readAdaptiveSpiral, -1);
}
#endif
PrintCLI(t);
g_free(t);
@@ -1268,20 +1343,25 @@ void fill_gap(read_closure *rc)
/* Check whether user hit the Stop button */
#ifndef CLI
if(Closure->stopActions)
{ if(Closure->guiMode)
{
if(Closure->guiMode)
SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
rc->earlyTermination = FALSE; /* suppress respective error message */
cleanup((gpointer)rc);
}
#endif
/* Cycle the progress animation */
if(j++ % 2000)
{ int seq = (j/2000)%10;
#ifndef CLI
if(!Closure->guiMode)
#endif
{ g_printf("%s", anim[seq]);
fflush(stdout);
}
@@ -1289,21 +1369,25 @@ void fill_gap(read_closure *rc)
/* Show progress in the spiral */
#ifndef CLI
if(Closure->guiMode)
{ int segment = i / rc->sectorsPerSegment;
if(Closure->readAdaptiveSpiral->segmentColor[segment] == Closure->background)
ChangeSegmentColor(Closure->whiteSector, segment);
}
#endif
}
PrintCLI(" \n");
rc->highestWrittenSector = rc->intervalStart-1;
#ifndef CLI
if(Closure->guiMode) /* remove temporary fill markers */
{ RemoveFillMarkers();
SetAdaptiveReadSubtitle(rc->subtitle);
}
#endif
}
@@ -1358,10 +1442,12 @@ void ReadMediumAdaptive(gpointer data)
rc->earlyTermination = TRUE;
RegisterCleanup(_("Reading aborted"), cleanup, rc);
#ifndef CLI
if(Closure->guiMode)
SetLabelText(GTK_LABEL(Closure->readAdaptiveHeadline), "<big>%s</big>\n<i>%s</i>",
_("Preparing for reading the medium image."),
_("Medium: not yet determined"));
#endif
/* Please note: Commenting the follwing Stop() out will provide
adaptive reading for RS01 and RS02, but behaviour with RS03
@@ -1418,6 +1504,7 @@ void ReadMediumAdaptive(gpointer data)
/*** Initialize segment state counters (only in GUI mode) */
#ifndef CLI
if(Closure->guiMode)
{ //rc->sectorsPerSegment = 1 + (rc->sectors / ADAPTIVE_READ_SPIRAL_SIZE);
rc->sectorsPerSegment = ((rc->expectedSectors+ADAPTIVE_READ_SPIRAL_SIZE-1) / ADAPTIVE_READ_SPIRAL_SIZE);
@@ -1425,6 +1512,7 @@ void ReadMediumAdaptive(gpointer data)
// ClipReadAdaptiveSpiral(rc->sectors/rc->sectorsPerSegment);
ClipReadAdaptiveSpiral((rc->expectedSectors+rc->sectorsPerSegment-1)/rc->sectorsPerSegment);
}
#endif
/*** Initialize the interval list */
@@ -1440,11 +1528,13 @@ reopen_image:
Stop(_("Can't open %s:\n%s"),Closure->imageName,strerror(errno));
PrintLog(_("Creating new %s image.\n"),Closure->imageName);
#ifndef CLI
if(Closure->guiMode)
SetLabelText(GTK_LABEL(Closure->readAdaptiveHeadline),
"<big>%s</big>\n<i>%s</i>",
_("Reading new medium image."),
rc->dh->mediumDescr);
#endif
/* Mark RS02 header sectors as correctable. */
@@ -1460,11 +1550,13 @@ reopen_image:
else
{ int reopen;
#ifndef CLI
if(Closure->guiMode)
SetLabelText(GTK_LABEL(Closure->readAdaptiveHeadline),
"<big>%s</big>\n<i>%s</i>",
_("Completing existing medium image."),
rc->dh->mediumDescr);
#endif
/* Open the existing image file. */
@@ -1500,8 +1592,10 @@ reopen_image:
if(rc->readMode != IMAGE_ONLY)
{ PrintLog(t);
#ifndef CLI
if(Closure->guiMode)
SetAdaptiveReadFootline(t, Closure->greenText);
#endif
}
goto finished;
}
@@ -1519,8 +1613,10 @@ reopen_image:
/*** Read the medium image. */
#ifndef CLI
if(Closure->guiMode)
SetAdaptiveReadSubtitle(rc->subtitle);
#endif
for(;;)
{ int cluster_mask = rc->dh->clusterSize-1;
@@ -1545,6 +1641,7 @@ reopen_image:
for(s=rc->intervalStart; s<=rc->intervalEnd; ) /* s is incremented elsewhere */
{ int nsectors,cnt;
#ifndef CLI
if(Closure->stopActions) /* somebody hit the Stop button */
{ if(Closure->guiMode)
SetAdaptiveReadFootline(_("Aborted by user request!"), Closure->redText);
@@ -1555,6 +1652,7 @@ reopen_image:
if(Closure->guiMode)
ChangeSpiralCursor(Closure->readAdaptiveSpiral, s / rc->sectorsPerSegment);
#endif
/* Determine number of sectors to read. Read the next dh->clusterSize sectors
unless we're at the end of the interval or at a position which is
@@ -1600,13 +1698,17 @@ reread:
if(status && !Closure->ignoreFatalSense
&& rc->dh->sense.sense_key
&& rc->dh->sense.sense_key != 3 && rc->dh->sense.sense_key != 5)
{ int answer;
{
#ifndef CLI
int answer;
if(!Closure->guiMode)
#endif
Stop(_("Sector %lld: %s\nCan not recover from above error.\n"
"Use the --ignore-fatal-sense option to override."),
s, GetLastSenseString(FALSE));
#ifndef CLI
answer = ModalDialog(GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, insert_buttons,
_("Sector %lld: %s\n\n"
"It may not be possible to recover from this error.\n"
@@ -1617,11 +1719,12 @@ reread:
Closure->ignoreFatalSense = 2;
if(!answer)
{ SetAdaptiveReadFootline(_("Aborted by unrecoverable error."), Closure->redText);
{
SetAdaptiveReadFootline(_("Aborted by unrecoverable error."), Closure->redText);
rc->earlyTermination = FALSE; /* suppress respective error message */
goto terminate;
}
#endif
}
/* When encountering an error during cluster size reads,
@@ -1675,7 +1778,9 @@ reread:
Stop(_("Failed writing to sector %lld in image [%s]: %s"),
b, "unv", strerror(errno));
#ifndef CLI
mark_sector(rc, b, Closure->yellowSector);
#endif
if(rc->highestWrittenSector < b)
rc->highestWrittenSector = b;
@@ -1692,7 +1797,9 @@ reread:
SetBit(rc->map, b);
rc->readable++;
#ifndef CLI
mark_sector(rc, b, Closure->greenSector);
#endif
if(rc->highestWrittenSector < b)
rc->highestWrittenSector = b;
@@ -1745,7 +1852,9 @@ reread:
&& !GetBit(rc->map, layer_idx))
{ SetBit(rc->map, layer_idx);
rc->correctable++;
#ifndef CLI
mark_sector(rc, layer_idx, Closure->greenSector);
#endif
#ifdef CHECK_VISITED
rc->count[layer_idx]++;
@@ -1788,7 +1897,9 @@ reread:
&& !GetBit(rc->map, sector))
{ SetBit(rc->map, sector);
rc->correctable++;
#ifndef CLI
mark_sector(rc, sector, Closure->greenSector);
#endif
fill_correctable_gap(rc, sector);
}
}
@@ -1813,8 +1924,10 @@ reread:
print_progress(rc, TRUE);
if(rc->readMode != IMAGE_ONLY)
{ PrintLog(t);
#ifndef CLI
if(Closure->guiMode && rc->ei)
SetAdaptiveReadFootline(t, Closure->foreground);
#endif
}
if(Closure->eject)
LoadMedium(rc->dh, FALSE);
@@ -1826,10 +1939,20 @@ reread:
{ unsigned char buf[2048];
PrintCLI("\n");
if(nsectors>1) PrintCLIorLabel(Closure->status,
if(nsectors>1) PrintCLIorLabel(
#ifndef CLI
Closure->status,
#else
NULL,
#endif
_("Sectors %lld-%lld: %s\n"),
s, s+nsectors-1, GetLastSenseString(FALSE));
else PrintCLIorLabel(Closure->status,
else PrintCLIorLabel(
#ifndef CLI
Closure->status,
#else
NULL,
#endif
_("Sector %lld: %s\n"),
s, GetLastSenseString(FALSE));
@@ -1849,7 +1972,9 @@ reread:
Stop(_("Failed writing to sector %lld in image [%s]: %s"),
s, "nds", strerror(errno));
#ifndef CLI
mark_sector(rc, s+i, Closure->redSector);
#endif
}
if(rc->highestWrittenSector < s+nsectors)
@@ -1944,10 +2069,12 @@ finished:
/* Force output of final results */
#ifndef CLI
if(Closure->guiMode)
{ ChangeSpiralCursor(Closure->readAdaptiveSpiral, -1);
mark_sector(rc, 0, NULL);
}
#endif
/*** Summarize results. */
@@ -1963,8 +2090,10 @@ finished:
PrintLog(_("\n%s\n"
"(%lld readable, %lld correctable, %lld still missing).\n"),
t, rc->readable, rc->correctable, rc->expectedSectors-total);
#ifndef CLI
if(Closure->guiMode)
SetAdaptiveReadFootline(t, Closure->foreground);
#endif
g_free(t);
exitCode = EXIT_FAILURE;
@@ -1976,8 +2105,10 @@ finished:
{ if(rc->readable == rc->expectedSectors)
{ char *t = _("\nGood! All sectors have been read.\n");
PrintLog(t);
#ifndef CLI
if(Closure->guiMode)
SetAdaptiveReadFootline(t, Closure->foreground);
#endif
if(Closure->eject)
LoadMedium(rc->dh, FALSE);
}
@@ -1990,8 +2121,10 @@ finished:
"%2d.%1d%% of the image have been read (%lld sectors).\n"),
t, percent/10, percent%10, rc->readable);
#ifndef CLI
if(Closure->guiMode)
SetAdaptiveReadFootline(t, Closure->foreground);
#endif
g_free(t);
exitCode = EXIT_FAILURE;
}
@@ -2009,7 +2142,9 @@ finished:
rc->earlyTermination = FALSE;
#ifndef CLI
terminate:
#endif
cleanup((gpointer)rc);
}