Files
dvdisaster/closure.c
Stéphane Lesimple 38defdf7aa Apply (most) debian patches
Apply debian patch 02-encryption
Apply debian patch 03-dvdrom
Apply a modified version of patch 05-help-dialog
Apply debian patch 08-fix-gnu-make-detection
Apply debian patch 10-use-non-size-specific-icon-and-add-keywords-to-desktop-file
Apply debian patch 12-fix-spelling-of-up-to
Apply debian patch 13-fix-missing-language-field-in-po-files
Apply a modified version of debian patch 14-make-builds-reproducible
Apply debian patch 17-fix-all-but-deprecated-api-warnings
Apply a modified version of debian patch 18-update-copyright-in-about-dialog
Apply debian patch 19-show-text-files-with-abs-path
Apply debian patch 22-fix-hurd-i386-ftbfs
Apply debian patch 23-add-bdrom-support
Apply debian patch 25-fix-man-pages
Apply debian patch 27-allow-opening-in-browser-again
Apply debian patch 28-pdftex-reproducibility
Apply debian patch 29-fix-more-typos
Apply debian patch 30-hurd-kfreebsd-ftbfs
Apply debian patch 31-improve-hurd-and-kfreebsd-support
Apply debian patch 33-honour-LDFLAGS
Apply debian patch 34-gcc8-format-security.patch
Apply debian patch 35-archived-homepage
Apply debian patch 36-fix-parallelism
2020-08-20 14:17:35 +02:00

667 lines
25 KiB
C

/* dvdisaster: Additional error correction for optical media.
* Copyright (C) 2004-2017 Carsten Gnoerlich.
*
* Email: carsten@dvdisaster.org -or- cgnoerlich@fsfe.org
* Project homepage: http://www.dvdisaster.org
*
* This file is part of dvdisaster.
*
* dvdisaster 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 3 of the License, or
* (at your option) any later version.
*
* dvdisaster 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 dvdisaster. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dvdisaster.h"
#if 0
#define Verbose g_printf
#else
#define Verbose(format, ...)
#endif
/***
*** Locate the binary and documentation directory
***/
static void get_base_dirs()
{
/*** Unless completely disabled through a configure option, the
source directory is supposed to hold the most recent files,
so try this first. */
#ifdef WITH_EMBEDDED_SRC_PATH_YES
if(DirStat(SRCDIR))
{ Closure->binDir = g_strdup(SRCDIR);
Closure->docDir = g_strdup_printf("%s/documentation",SRCDIR);
Verbose("Using paths from SRCDIR = %s\n", SRCDIR);
goto find_dotfile;
}
#endif /* WITH_EMBEDDED_SRC_PATH_YES */
/*** Otherwise try the installation directory.
On Unices this is a hardcoded directory. */
#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_KFREEBSD) || \
defined(SYS_NETBSD) || defined(SYS_HURD) || defined(SYS_UNKNOWN)
if(DirStat(BINDIR))
Closure->binDir = g_strdup(BINDIR);
if(DirStat(DOCDIR))
Closure->docDir = g_strdup(DOCDIR);
Verbose("Using hardcoded BINDIR = %s, DOCDIR = %s\n", BINDIR, DOCDIR);
#endif
/*** The location of the dotfile depends on the operating system.
Under Unix the users home directory is used. */
#ifdef WITH_EMBEDDED_SRC_PATH_YES
find_dotfile:
#endif /* WITH_EMBEDDED_SRC_PATH_YES */
Closure->homeDir = g_strdup(g_getenv("HOME"));
if(!Closure->dotFile) /* may have been set by the --resource-file option */
Closure->dotFile = g_strdup_printf("%s/.dvdisaster", Closure->homeDir);
Verbose("\nUsing file locations:\n"
"- Homedir: %s\n"
"- Bin dir: %s\n"
"- Doc dir: %s\n"
"- dotfile: %s\n\n",
Closure->homeDir,
Closure->binDir,
Closure->docDir,
Closure->dotFile);
}
/***
*** Set/get color values
***/
/*
* Update color string for the <span color="#f00baa">...</span> string
*/
#ifndef CLI
void UpdateMarkup(char **string, GdkColor *color)
{ int hexval;
hexval = (color->red << 8) & 0xff0000;
hexval |= color->green & 0xff00;
hexval |= (color->blue >> 8) & 0xff;
if(*string) g_free(*string);
*string = g_strdup_printf("color=\"#%06x\"", hexval);
}
/*
* Default color values
*/
void DefaultColors()
{
Closure->redText->red = 0xffff;
Closure->redText->green = 0;
Closure->redText->blue = 0;
Closure->greenText->red = 0;
Closure->greenText->green = 0x8000;
Closure->greenText->blue = 0;
Closure->barColor->red = 0xffff;
Closure->barColor->green = 0;
Closure->barColor->blue = 0;
Closure->logColor->red = 0xffff;
Closure->logColor->green = 0;
Closure->logColor->blue = 0xffff;
Closure->curveColor->red = 0;
Closure->curveColor->green = 0;
Closure->curveColor->blue = 0xffff;
Closure->redSector->red = 0xffff;
Closure->redSector->green = 0;
Closure->redSector->blue = 0;
Closure->yellowSector->red = 0xffff;
Closure->yellowSector->green = 0xc000;
Closure->yellowSector->blue = 0;
Closure->greenSector->red = 0;
Closure->greenSector->green = 0xdb00;
Closure->greenSector->blue = 0;
Closure->darkSector->red = 0;
Closure->darkSector->green = 0x8000;
Closure->darkSector->blue = 0;
Closure->blueSector->red = 0;
Closure->blueSector->green = 0;
Closure->blueSector->blue = 0xffff;
Closure->whiteSector->red = 0xffff;
Closure->whiteSector->green = 0xffff;
Closure->whiteSector->blue = 0xffff;
UpdateMarkup(&Closure->redMarkup, Closure->redText);
UpdateMarkup(&Closure->greenMarkup, Closure->greenText);
}
static void save_colors(FILE *dotfile, char *symbol, GdkColor *color)
{ char *blanks=" ";
char *pad;
int len=strlen(symbol);
if(len>19) pad=blanks+19;
else pad=blanks+len;
fprintf(dotfile, "%s:%s%02x%02x%02x\n", symbol, pad,
color->red>>8, color->green>>8, color->blue>>8);
}
static void get_color(GdkColor *color, char *value)
{ unsigned int hex = strtol(value, NULL, 16);
color->red = (hex>>8)&0xff00;
color->green = hex&0xff00;
color->blue = (hex<<8)&0xff00;
}
#endif
/***
*** Save and restore user settings to/from the .dvdisaster file
***/
#define MAX_LINE_LEN 512
void ReadDotfile()
{ FILE *dotfile;
char line[MAX_LINE_LEN];
dotfile = portable_fopen(Closure->dotFile, "rb");
if(!dotfile)
return;
while(TRUE)
{ int n;
char symbol[41];
char *value;
/* Get first MAX_LINE_LEN bytes of line, discard the rest */
line[MAX_LINE_LEN-1] = 1;
if (!fgets(line, MAX_LINE_LEN, dotfile)) break;
if(!line[MAX_LINE_LEN-1]) /* line longer than buffer */
while(!feof(dotfile) && fgetc(dotfile) != '\n')
;
/* Trivially reject the line */
if(feof(dotfile)) break;
if(*line == '#') continue;
if(!sscanf(line, "%40[0-9a-zA-Z-]%n", symbol, &n)) continue;
if(line[n] != ':') continue;
/* Separate line contents into symbol: value pair */
value = line+n+1;
while(*value && *value == ' ')
value++;
if(!*value) continue;
n = strlen(value);
if(value[n-1] == '\n')
value[n-1] = 0;
/* Parse the symbols which are recognized in this version */
if(!strcmp(symbol, "last-device")) { if(Closure->device) g_free(Closure->device);
Closure->device = g_strdup(value); continue; }
if(!strcmp(symbol, "last-image")) { g_free(Closure->imageName);
if(!strcmp(value, "none"))
Closure->imageName = g_strdup("");
else Closure->imageName = g_strdup(value);
continue;
}
if(!strcmp(symbol, "last-ecc")) { g_free(Closure->eccName);
if(!strcmp(value, "none"))
Closure->eccName = g_strdup("");
else Closure->eccName = g_strdup(value);
continue;
}
if(!strcmp(symbol, "adaptive-read")) { Closure->adaptiveRead = atoi(value); continue; }
if(!strcmp(symbol, "auto-suffix")) { Closure->autoSuffix = atoi(value); continue; }
if(!strcmp(symbol, "bd-size1")) { Closure->bdSize1 = Closure->savedBDSize1 = atoll(value); continue; }
if(!strcmp(symbol, "bd-size2")) { Closure->bdSize2 = Closure->savedBDSize2 = atoll(value); continue; }
if(!strcmp(symbol, "bd-size3")) { Closure->bdSize3 = Closure->savedBDSize3 = atoll(value); continue; }
if(!strcmp(symbol, "cache-size")) { Closure->cacheMiB = atoi(value); continue; }
if(!strcmp(symbol, "cd-size")) { Closure->cdSize = Closure->savedCDSize = atoll(value); continue; }
if(!strcmp(symbol, "codec-threads")) { Closure->codecThreads = atoi(value); continue; }
if(!strcmp(symbol, "confirm-deletion")){ Closure->confirmDeletion = atoi(value); continue; }
if(!strcmp(symbol, "dao")) { Closure->noTruncate = atoi(value); continue; }
if(!strcmp(symbol, "defective-dump")) { Closure->defectiveDump = atoi(value); continue; }
if(!strcmp(symbol, "defective-dir")) { if(Closure->dDumpDir) g_free(Closure->dDumpDir);
Closure->dDumpDir = g_strdup(value); continue; }
if(!strcmp(symbol, "defective-prefix")){ if(Closure->dDumpPrefix) g_free(Closure->dDumpPrefix);
Closure->dDumpPrefix = g_strdup(value); continue; }
if(!strcmp(symbol, "dotfile-version")) { Closure->dotFileVersion = atoi(value); continue; }
if(!strcmp(symbol, "dvd-size1")) { Closure->dvdSize1 = Closure->savedDVDSize1 = atoll(value); continue; }
if(!strcmp(symbol, "dvd-size2")) { Closure->dvdSize2 = Closure->savedDVDSize2 = atoll(value); continue; }
if(!strcmp(symbol, "ecc-target")) { Closure->eccTarget = atoi(value); continue; }
if(!strcmp(symbol, "eject")) { Closure->eject = atoi(value); continue; }
if(!strcmp(symbol, "encoding-algorithm")) { Closure->encodingAlgorithm = atoi(value); continue; }
if(!strcmp(symbol, "encoding-io-strategy")) { Closure->encodingIOStrategy = atoi(value); continue; }
if(!strcmp(symbol, "examine-rs02")) { Closure->examineRS02 = atoi(value); continue; }
if(!strcmp(symbol, "examine-rs03")) { Closure->examineRS03 = atoi(value); continue; }
if(!strcmp(symbol, "fill-unreadable")) { Closure->fillUnreadable = atoi(value); continue; }
if(!strcmp(symbol, "ignore-fatal-sense")) { Closure->ignoreFatalSense = atoi(value); continue; }
if(!strcmp(symbol, "ignore-iso-size")) { Closure->ignoreIsoSize = atoi(value); continue; }
if(!strcmp(symbol, "internal-attempts")) { Closure->internalAttempts = atoi(value); continue; }
if(!strcmp(symbol, "jump")) { Closure->sectorSkip = atoi(value); continue; }
if(!strcmp(symbol, "log-file-enabled")){ Closure->logFileEnabled = atoi(value); continue; }
if(!strcmp(symbol, "log-file")) { if(Closure->logFile) g_free(Closure->logFile);
Closure->logFile = g_strdup(value); continue; }
if(!strcmp(symbol, "medium-size")) { Closure->mediumSize = atoll(value); continue; }
if(!strcmp(symbol, "method-name")) { if(Closure->methodName) g_free(Closure->methodName);
Closure->methodName = g_strdup(value); continue; }
if(!strcmp(symbol, "max-read-attempts")) { Closure->maxReadAttempts = atoi(value); continue; }
if(!strcmp(symbol, "min-read-attempts")) { Closure->minReadAttempts = atoi(value); continue; }
if(!strcmp(symbol, "old-missing-sector-marker")) { Closure->dsmVersion = !atoi(value); continue; }
if(!strcmp(symbol, "pdf-viewer")) { g_free(Closure->viewer);
Closure->viewer = g_strdup(value); continue; }
if(!strcmp(symbol, "prefetch-sectors")){ Closure->prefetchSectors = atoi(value); continue; }
if(!strcmp(symbol, "raw-mode")) { Closure->rawMode = atoi(value); continue; }
if(!strcmp(symbol, "read-and-create")) { Closure->readAndCreate = atoi(value); continue; }
if(!strcmp(symbol, "read-medium")) { Closure->readingPasses = atoi(value); continue; }
if(!strcmp(symbol, "read-raw")) { Closure->readRaw = atoi(value); continue; }
if(!strcmp(symbol, "redundancy")) { if(Closure->redundancy) g_free(Closure->redundancy);
Closure->redundancy = g_strdup(value); continue; }
if(!strcmp(symbol, "reverse-cancel-ok")) { Closure->reverseCancelOK = atoi(value); continue; }
if(!strcmp(symbol, "spinup-delay")) { Closure->spinupDelay = atoi(value); continue; }
if(!strcmp(symbol, "unlink")) { Closure->unlinkImage = atoi(value); continue; }
if(!strcmp(symbol, "verbose")) { Closure->verbose = atoi(value); continue; }
if(!strcmp(symbol, "welcome-msg")) { Closure->welcomeMessage = atoi(value); continue; }
#ifndef CLI
if(!strcmp(symbol, "positive-text")) { get_color(Closure->greenText, value);
UpdateMarkup(&Closure->greenMarkup, Closure->greenText);
continue;
}
if(!strcmp(symbol, "negative-text")) { get_color(Closure->redText, value);
UpdateMarkup(&Closure->redMarkup, Closure->redText);
continue;
}
if(!strcmp(symbol, "bar-color")) { get_color(Closure->barColor, value); continue; }
if(!strcmp(symbol, "log-color")) { get_color(Closure->logColor, value); continue; }
if(!strcmp(symbol, "curve-color")) { get_color(Closure->curveColor, value); continue; }
if(!strcmp(symbol, "defective-sector")){ get_color(Closure->redSector, value); continue; }
if(!strcmp(symbol, "bad-checksum-sector")){ get_color(Closure->yellowSector, value); continue; }
if(!strcmp(symbol, "good-sector")) { get_color(Closure->greenSector, value); continue; }
if(!strcmp(symbol, "ignored-sector")) { get_color(Closure->blueSector, value); continue; }
if(!strcmp(symbol, "highlit-sector")) { get_color(Closure->whiteSector, value); continue; }
if(!strcmp(symbol, "present-sector")) { get_color(Closure->darkSector, value); continue; }
#endif
}
if(fclose(dotfile))
g_printf("Error closing configuration file %s: %s\n",
Closure->dotFile, strerror(errno));
}
static void update_dotfile()
{ const char *no_dot_files;
FILE *dotfile;
/*** If the environment $NO_DOT_FILES is set,
do not alter the dotfile. */
no_dot_files = g_getenv("NO_DOT_FILES");
if(no_dot_files && atoi(no_dot_files))
return;
/*** Otherwise, save our session */
dotfile = portable_fopen(Closure->dotFile, "wb");
if(!dotfile)
{ g_printf("Could not open configuration file %s: %s\n",
Closure->dotFile, strerror(errno));
return;
}
g_fprintf(dotfile,
_("# dvdisaster-%s configuration file\n"
"# This is an automatically generated file\n"
"# which will be overwritten each time dvdisaster is run.\n\n"),
VERSION);
g_fprintf(dotfile, "last-device: %s\n", Closure->device);
g_fprintf(dotfile, "last-image: %s\n", Closure->imageName);
g_fprintf(dotfile, "last-ecc: %s\n\n", Closure->eccName);
g_fprintf(dotfile, "adaptive-read: %d\n", Closure->adaptiveRead);
g_fprintf(dotfile, "auto-suffix: %d\n", Closure->autoSuffix);
g_fprintf(dotfile, "bd-size1: %lld\n", (long long int)Closure->bdSize1);
g_fprintf(dotfile, "bd-size2: %lld\n", (long long int)Closure->bdSize2);
g_fprintf(dotfile, "bd-size3: %lld\n", (long long int)Closure->bdSize3);
g_fprintf(dotfile, "cache-size: %d\n", Closure->cacheMiB);
g_fprintf(dotfile, "cd-size: %lld\n", (long long int)Closure->cdSize);
g_fprintf(dotfile, "codec-threads: %d\n", Closure->codecThreads);
g_fprintf(dotfile, "confirm-deletion: %d\n", Closure->confirmDeletion);
g_fprintf(dotfile, "dao: %d\n", Closure->noTruncate);
g_fprintf(dotfile, "defective-dump: %d\n", Closure->defectiveDump);
g_fprintf(dotfile, "defective-dir: %s\n", Closure->dDumpDir);
g_fprintf(dotfile, "defective-prefix: %s\n", Closure->dDumpPrefix);
g_fprintf(dotfile, "dotfile-version: %d\n", Closure->dotFileVersion);
g_fprintf(dotfile, "dvd-size1: %lld\n", (long long int)Closure->dvdSize1);
g_fprintf(dotfile, "dvd-size2: %lld\n", (long long int)Closure->dvdSize2);
g_fprintf(dotfile, "ecc-target: %d\n", Closure->eccTarget);
g_fprintf(dotfile, "eject: %d\n", Closure->eject);
g_fprintf(dotfile, "encoding-algorithm:%d\n", Closure->encodingAlgorithm);
g_fprintf(dotfile, "encoding-io-strategy:%d\n", Closure->encodingIOStrategy);
g_fprintf(dotfile, "examine-rs02: %d\n", Closure->examineRS02);
g_fprintf(dotfile, "examine-rs03: %d\n", Closure->examineRS03);
g_fprintf(dotfile, "fill-unreadable: %d\n", Closure->fillUnreadable);
g_fprintf(dotfile, "ignore-fatal-sense: %d\n", Closure->ignoreFatalSense);
g_fprintf(dotfile, "ignore-iso-size: %d\n", Closure->ignoreIsoSize);
g_fprintf(dotfile, "internal-attempts: %d\n", Closure->internalAttempts);
g_fprintf(dotfile, "jump: %d\n", Closure->sectorSkip);
g_fprintf(dotfile, "log-file-enabled: %d\n", Closure->logFileEnabled);
g_fprintf(dotfile, "log-file: %s\n", Closure->logFile);
g_fprintf(dotfile, "medium-size: %lld\n", (long long int)Closure->mediumSize);
g_fprintf(dotfile, "method-name: %s\n", Closure->methodName);
g_fprintf(dotfile, "max-read-attempts: %d\n", Closure->maxReadAttempts);
g_fprintf(dotfile, "min-read-attempts: %d\n", Closure->minReadAttempts);
g_fprintf(dotfile, "old-missing-sector-marker: %d\n", !Closure->dsmVersion);
g_fprintf(dotfile, "pdf-viewer: %s\n", Closure->viewer);
g_fprintf(dotfile, "prefetch-sectors: %d\n", Closure->prefetchSectors);
g_fprintf(dotfile, "raw-mode: %d\n", Closure->rawMode);
g_fprintf(dotfile, "read-and-create: %d\n", Closure->readAndCreate);
g_fprintf(dotfile, "read-medium: %d\n", Closure->readingPasses);
g_fprintf(dotfile, "read-raw: %d\n", Closure->readRaw);
if(Closure->redundancy)
g_fprintf(dotfile, "redundancy: %s\n", Closure->redundancy);
g_fprintf(dotfile, "reverse-cancel-ok: %d\n", Closure->reverseCancelOK);
g_fprintf(dotfile, "spinup-delay: %d\n", Closure->spinupDelay);
g_fprintf(dotfile, "unlink: %d\n", Closure->unlinkImage);
g_fprintf(dotfile, "verbose: %d\n", Closure->verbose);
g_fprintf(dotfile, "welcome-msg: %d\n\n", Closure->welcomeMessage);
#ifndef CLI
save_colors(dotfile, "positive-text", Closure->greenText);
save_colors(dotfile, "negative-text", Closure->redText);
save_colors(dotfile, "bar-color", Closure->barColor);
save_colors(dotfile, "log-color", Closure->logColor);
save_colors(dotfile, "curve-color", Closure->curveColor);
save_colors(dotfile, "defective-sector", Closure->redSector);
save_colors(dotfile, "bad-checksum-sector",Closure->yellowSector);
save_colors(dotfile, "good-sector", Closure->greenSector);
save_colors(dotfile, "ignored-sector", Closure->blueSector);
save_colors(dotfile, "highlit-sector", Closure->whiteSector);
save_colors(dotfile, "present-sector", Closure->darkSector);
#endif
if(fclose(dotfile))
g_printf("Error closing configuration file %s: %s\n",
Closure->dotFile, strerror(errno));
}
/***
*** Allocate and initialize our global variables
***/
GlobalClosure *Closure;
int exitCode = EXIT_SUCCESS;
void InitClosure()
{ int v1,v2,v3,dots=0;
char *v,version[strlen(VERSION)+1];
Closure = g_malloc0(sizeof(GlobalClosure));
/* Extract the version string */
#ifdef HAVE_UNSTABLE_RELEASE
Closure->cookedVersion = g_strdup_printf("%s (unstable)", VERSION);
Closure->releaseFlags = MFLAG_DEVEL;
#else
Closure->cookedVersion = g_strdup(VERSION);
#endif
/* Generate a more comprehensive version string */
#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_KFREEBSD) || \
defined(SYS_NETBSD) || defined(SYS_HURD)
#ifdef HAVE_64BIT
#define BITNESS_STRING " 64bit"
#else
#define BITNESS_STRING " 32bit"
#endif
#else
#define BITNESS_STRING ""
#endif
Closure->versionString = g_strdup_printf("dvdisaster %s build %s, %s%s",
Closure->cookedVersion, buildCount, SYS_NAME, BITNESS_STRING);
/* Replace the dot with a locale-resistant separator */
strcpy(version,VERSION);
for(v=version; *v; v++)
if(*v=='.')
{ *v='x';
dots++;
}
if(dots == 2)
{ v1 = v2 = v3 = 0;
sscanf(version,"%dx%dx%d",&v1,&v2,&v3);
}
else
{ g_printf("Error: malformed version number %s\n",VERSION);
exit(EXIT_FAILURE);
}
Closure->version = 10000*v1 + 100*v2 + v3;
/* Get home and system directories */
get_base_dirs();
/* Fill in other closure defaults */
Closure->deviceNames = g_ptr_array_new();
Closure->deviceNodes = g_ptr_array_new();
Closure->viewer = g_strdup("xdg-open");
Closure->browser = g_strdup("xdg-open");
Closure->methodList = g_ptr_array_new();
Closure->methodName = g_strdup("RS01");
Closure->dDumpDir = g_strdup(Closure->homeDir);
Closure->cacheMiB = 32;
Closure->prefetchSectors = 128;
Closure->codecThreads = 1;
Closure->eccTarget = 1;
Closure->encodingAlgorithm = ENCODING_ALG_DEFAULT;
Closure->minReadAttempts = 1;
Closure->maxReadAttempts = 1;
Closure->rawMode = 0x20;
Closure->internalAttempts = -1;
Closure->sectorSkip = 16;
Closure->spinupDelay = 5;
Closure->fillUnreadable = -1;
Closure->welcomeMessage = 1;
Closure->useSCSIDriver = DRIVER_SG;
Closure->dsmVersion = 1;
/* default sizes for typical CD and DVD media */
Closure->cdSize = Closure->savedCDSize = CDR_SIZE;
Closure->dvdSize1 = Closure->savedDVDSize1 = DVD_SL_SIZE;
Closure->dvdSize2 = Closure->savedDVDSize2 = DVD_DL_SIZE;
Closure->bdSize1 = Closure->savedBDSize1 = BD_SL_SIZE;
Closure->bdSize2 = Closure->savedBDSize2 = BD_DL_SIZE;
Closure->bdSize3 = Closure->savedBDSize3 = BDXL_TL_SIZE;
#ifndef CLI
Closure->logString = g_string_sized_new(1024);
Closure->logLock = g_malloc0(sizeof(GMutex));
g_mutex_init(Closure->logLock);
Closure->background = g_malloc0(sizeof(GdkColor));
Closure->foreground = g_malloc0(sizeof(GdkColor));
Closure->grid = g_malloc0(sizeof(GdkColor));
Closure->redText = g_malloc0(sizeof(GdkColor));
Closure->greenText = g_malloc0(sizeof(GdkColor));
Closure->barColor = g_malloc0(sizeof(GdkColor));
Closure->logColor = g_malloc0(sizeof(GdkColor));
Closure->curveColor = g_malloc0(sizeof(GdkColor));
Closure->redSector = g_malloc0(sizeof(GdkColor));
Closure->yellowSector= g_malloc0(sizeof(GdkColor));
Closure->greenSector = g_malloc0(sizeof(GdkColor));
Closure->blueSector = g_malloc0(sizeof(GdkColor));
Closure->whiteSector = g_malloc0(sizeof(GdkColor));
Closure->darkSector = g_malloc0(sizeof(GdkColor));
DefaultColors();
#endif
memset(Closure->bs, '\b', 255);
memset(Closure->sp, ' ', 255);
DefaultLogFile();
}
/*
* Add some localized file name defaults.
* Can't do this in InitClosure() as the locale has not been
* initialized when it is being called.
*/
void LocalizedFileDefaults()
{
/* Storing the files in the cwd appears to be a sane default. */
Closure->imageName = g_strdup(_("medium.iso"));
Closure->eccName = g_strdup(_("medium.ecc"));
Closure->dDumpPrefix = g_strdup(_("sector-"));
}
/*
* Clean up properly
*/
#define cond_free(x) if(x) g_free(x)
/* Doing a simple g_ptr_array_free(a, TRUE)
would confuse our memory leak checker */
void cond_free_ptr_array(GPtrArray *a)
{ unsigned int i;
if(!a) return;
for(i=0; i<a->len; i++)
g_free(g_ptr_array_index(a,i));
g_ptr_array_free(a, FALSE);
}
void FreeClosure()
{
#ifndef CLI
if(Closure->guiMode)
#endif
/* in CLI-only mode, always update dotfile */
update_dotfile();
cond_free(Closure->cookedVersion);
cond_free(Closure->versionString);
cond_free(Closure->device);
cond_free_ptr_array(Closure->deviceNames);
cond_free_ptr_array(Closure->deviceNodes);
cond_free(Closure->imageName);
cond_free(Closure->eccName);
cond_free(Closure->redundancy);
CallMethodDestructors();
cond_free_ptr_array(Closure->methodList);
cond_free(Closure->methodName);
cond_free(Closure->homeDir);
cond_free(Closure->dotFile);
cond_free(Closure->logFile);
cond_free(Closure->binDir);
cond_free(Closure->docDir);
cond_free(Closure->viewer);
cond_free(Closure->browser);
cond_free(Closure->errorTitle);
cond_free(Closure->simulateCD);
cond_free(Closure->dDumpDir);
cond_free(Closure->dDumpPrefix);
#ifndef CLI
if(Closure->prefsContext)
FreePreferences(Closure->prefsContext);
if(Closure->rawEditorContext)
FreeRawEditorContext(Closure->rawEditorContext);
if(Closure->logString)
g_string_free(Closure->logString, TRUE);
if(Closure->logLock)
{ g_mutex_clear(Closure->logLock);
g_free(Closure->logLock);
}
if(Closure->drawGC)
g_object_unref(Closure->drawGC);
cond_free(Closure->background);
cond_free(Closure->foreground);
cond_free(Closure->grid);
cond_free(Closure->redText);
cond_free(Closure->greenText);
cond_free(Closure->barColor);
cond_free(Closure->logColor);
cond_free(Closure->curveColor);
cond_free(Closure->redSector);
cond_free(Closure->yellowSector);
cond_free(Closure->greenSector);
cond_free(Closure->blueSector);
cond_free(Closure->whiteSector);
cond_free(Closure->darkSector);
cond_free(Closure->redMarkup);
cond_free(Closure->greenMarkup);
cond_free(Closure->invisibleDash);
if(Closure->readLinearCurve)
FreeCurve(Closure->readLinearCurve);
if(Closure->readLinearSpiral)
FreeSpiral(Closure->readLinearSpiral);
if(Closure->readAdaptiveSpiral)
FreeSpiral(Closure->readAdaptiveSpiral);
if(Closure->readAdaptiveSubtitle)
g_free(Closure->readAdaptiveSubtitle);
if(Closure->readAdaptiveErrorMsg)
g_free(Closure->readAdaptiveErrorMsg);
#endif
g_free(Closure);
}