コード例 #1
0
ファイル: web.c プロジェクト: ucsc-mus-strain-cactus/kent
void checkForGeoMirrorRedirect(struct cart *cart)
// Implement Geo/IP based redirection.
{
char *thisNodeStr = geoMirrorNode();
if (thisNodeStr)   // if geo-mirroring is enabled
    {
    char *redirectCookie = findCookieData("redirect");
    char *redirect = cgiOptionalString("redirect");

    // if we're not already redirected
    if (redirect == NULL && redirectCookie == NULL) 
        {
        int thisNode = sqlUnsigned(thisNodeStr);
        struct sqlConnection *centralConn = hConnectCentral();
        char *ipStr = cgiRemoteAddr();
        int node = defaultNode(centralConn, ipStr);

        // if our node is not the node that's closest.
        if (thisNode != node)
            {
	    char *geoSuffix = cfgOptionDefault("browser.geoSuffix","");
            char query[1056];
            sqlSafef(query, sizeof query, "select domain from gbNode%s where node = %d", geoSuffix, node);
            char *newDomain = sqlQuickString(centralConn, query);
            char *oldDomain = cgiServerName();
            char *port = cgiServerPort();
            char *uri = cgiRequestUri();
            char *sep = strchr(uri, '?') ? "&" : "?";
            int newUriSize = strlen(uri) + 1024;
            char *newUri = needMem(newUriSize);
            char *oldUri = needMem(newUriSize);
            safef(oldUri, newUriSize, "http%s://%s:%s%s%sredirect=manual&source=%s", 
		cgiServerHttpsIsOn() ? "s" : "", oldDomain, port, uri, sep, oldDomain);
            safef(newUri, newUriSize, "http%s://%s:%s%s%sredirect=manual&source=%s", 
		cgiServerHttpsIsOn() ? "s" : "", newDomain, port, uri, sep, oldDomain);

	    printf("<TR><TD COLSPAN=3 id='redirectTd' onclick=\"javascript:document.getElementById('redirectTd').innerHTML='';\">"
	    "<div style=\"margin: 10px 25%%; border-style:solid; border-width:thin; border-color:#97D897;\">"
	    "<h3 style=\"background-color: #97D897; text-align: left; margin-top:0px; margin-bottom:0px;\">"
	    "&nbsp;You might want to navigate to your nearest mirror - %s"
	    "</h3> "
	    "<ul style=\"margin:5px;\">",
	    newDomain);
	    
	    printf("<li>User settings (sessions and custom tracks) <B>will differ</B> between sites."
		"<idiv style=\"float:right;\"><a href=\"../goldenPath/help/genomeEuro.html#sessions\">Read more.</a></idiv>");
	    printf("<li>Take me to  <a href=\"%s\">%s</a> </li>",
		newUri, newDomain);
	    printf("<li>Let me stay here   <a href=\"%s\">%s</a>",
		oldUri, oldDomain );
	    printf("</div></TD></TR>\n");
            exit(0);
            }
        hDisconnectCentral(&centralConn);
        }
    }
}
コード例 #2
0
ファイル: search.c プロジェクト: davidhoover/kent
void getSearchTrixFile(char *database, char *buf, int len)
// Fill-in the name of the track search trix file
{
char *trixPath = cfgOptionDefault("browser.trixPath", "/gbdb/$db/trackDb.ix");
struct subText *subList = subTextNew("$db", database);
subTextStatic(subList, trixPath, buf, len);
char *subBuf = hReplaceGbdb(buf);
safecpy(buf, len, subBuf);
freez(&subBuf);
}
コード例 #3
0
ファイル: hubConnect.c プロジェクト: davidhoover/kent
static boolean
hubTimeToCheck(struct hubConnectStatus *hub, char *notOkStatus)
/* check to see if enough time has passed to re-check a hub that
 * has an error status.  Default time to wait is 30 minutes, but this
 * is configurable with the hub.timeToCheck conf variable */
{
char *checkTimeString = cfgOptionDefault(hgHubConnectTimeToCheck, "1800");
time_t checkTime = sqlUnsigned(checkTimeString);
return dateIsOlderBy(notOkStatus, "%F %T", checkTime);
}
コード例 #4
0
ファイル: hgGateway.c プロジェクト: davidhoover/kent
static void doMainPage()
/* Send HTML with javascript to bootstrap the user interface. */
{
// Start web page with new banner
char *db = NULL, *genome = NULL, *clade = NULL;
getDbGenomeClade(cart, &db, &genome, &clade, oldVars);
// If CGI has &lastDbPos=..., handle that here and save position to cart so it's in place for
// future cartJson calls.
char *position = cartGetPosition(cart, db, NULL);
cartSetString(cart, "position", position);
webStartJWest(cart, db, "Genome Browser Gateway");

if (cgiIsOnWeb())
    checkForGeoMirrorRedirect(cart);

#define WARNING_BOX_START "<div id=\"previewWarningRow\" class=\"jwRow\">" \
         "<div id=\"previewWarningBox\" class=\"jwWarningBox\">"

#define UNDER_DEV "Data and tools on this site are under development, have not been reviewed " \
         "for quality, and are subject to change at any time. "

#define MAIN_SITE "The high-quality, reviewed public site of the UCSC Genome Browser is " \
         "available for use at <a href=\"http://genome.ucsc.edu/\">http://genome.ucsc.edu/</a>."

#define WARNING_BOX_END "</div></div>"

if (hIsPreviewHost())
    {
    puts(WARNING_BOX_START
         "WARNING: This is the UCSC Genome Browser preview site. "
         "This website is a weekly mirror of our internal development server for public access. "
         UNDER_DEV
         "We provide this site for early access, with the warning that it is less available "
         "and stable than our public site. "
         MAIN_SITE
         WARNING_BOX_END);
    }

if (hIsPrivateHost() && !hHostHasPrefix("hgwdev-demo6"))
    {
    puts(WARNING_BOX_START
         "WARNING: This is the UCSC Genome Browser development site. "
         "This website is used for testing purposes only and is not intended for general public "
         "use. "
         UNDER_DEV
         MAIN_SITE
         WARNING_BOX_END);
    }

// The visible page elements are all in ./hgGateway.html, which is transformed into a quoted .h
// file containing a string constant that we #include and print here (see makefile).
puts(
#include "hgGateway.html.h"
);

// Set global JS variables hgsid, activeGenomes, and survey* at page load time
// We can't just use "var hgsid = " or the other scripts won't see it -- it has to be
// "window.hgsid = ".
puts("<script>");
printf("window.%s = '%s';\n", cartSessionVarName(), cartSessionId(cart));
puts("window.activeGenomes =");
printActiveGenomes();
puts(";");
char *surveyLink = cfgOption("survey");
if (isNotEmpty(surveyLink) && !sameWord(surveyLink, "off"))
    {
    printf("window.surveyLink=\"%s\";\n", jsonStringEscape(surveyLink));
    char *surveyLabel = cfgOptionDefault("surveyLabel", "Please take our survey");
    printf("window.surveyLabel=\"%s\";\n", jsonStringEscape(surveyLabel));
    char *surveyLabelImage = cfgOption("surveyLabelImage");
    if (isNotEmpty(surveyLabelImage))
        printf("window.surveyLabelImage=\"%s\";\n", jsonStringEscape(surveyLabelImage));
    else
        puts("window.surveyLabelImage=null;");
    }
else
    {
    puts("window.surveyLink=null;");
    puts("window.surveyLabel=null;");
    puts("window.surveyLabelImage=null;");
    }
puts("</script>");

puts("<script src=\"../js/es5-shim.4.0.3.min.js\"></script>");
puts("<script src=\"../js/es5-sham.4.0.3.min.js\"></script>");
puts("<script src=\"../js/lodash.3.10.0.compat.min.js\"></script>");
puts("<script src=\"../js/cart.js\"></script>");

webIncludeResourceFile("jquery-ui.css");
jsIncludeFile("jquery-ui.js", NULL);
jsIncludeFile("jquery.watermarkinput.js", NULL);
jsIncludeFile("utils.js",NULL);

// Phylogenetic tree .js file, produced by dbDbTaxonomy.pl:
char *dbDbTree = cfgOptionDefault("hgGateway.dbDbTaxonomy", "../js/dbDbTaxonomy.js");
if (isNotEmpty(dbDbTree))
    printf("<script src=\"%s\"></script>\n", dbDbTree);

// Main JS for hgGateway:
puts("<script src=\"../js/hgGateway.js\"></script>");

webIncludeFile("inc/jWestFooter.html");

cartFlushHubWarnings();

webEndJWest();
}
コード例 #5
0
ファイル: web.c プロジェクト: elmargb/kentUtils
static void phoneHome()
{
static boolean beenHere = FALSE;
if (beenHere)  /* one at a time please */
    return;
beenHere = TRUE;

char *expireTime = cfgOptionDefault("browser.cgiExpireMinutes", "20");
unsigned expireMinutes = sqlUnsigned(expireTime);
expireSeconds = expireMinutes * 60;

char trashFile[PATH_LEN];
safef(trashFile, sizeof(trashFile), "%s/registration.txt", trashDir());

/* trashFile does not exist during command line execution */
if(fileExists(trashFile))	/* update access time for trashFile */
    {
    struct utimbuf ut;
    struct stat mystat;
    ZeroVar(&mystat);
    if (stat(trashFile,&mystat)==0)
	{
	ut.actime = clock1();
	ut.modtime = mystat.st_mtime;
	}
    else
	{
	ut.actime = ut.modtime = clock1();
	}
    (void) utime(trashFile, &ut);
    if (expireSeconds > 0)
	{
	(void) signal(SIGALRM, cgiApoptosis);
	(void) alarm(expireSeconds);	/* CGI timeout */
	}
    return;
    }

char *scriptName = cgiScriptName();
char *ip = getenv("SERVER_ADDR");
if (scriptName && ip)  /* will not be true from command line execution */
    {
    FILE *f = fopen(trashFile, "w");
    if (f)		/* rigamarole only if we can get a trash file */
	{
	time_t now = time(NULL);
	char *localTime;
	extern char *tzname[2];
	struct tm *tm = localtime(&now);
	localTime = sqlUnixTimeToDate(&now,FALSE); /* FALSE == localtime */
	fprintf(f, "%s, %s, %s %s, %s\n", scriptName, ip, localTime,
	    tm->tm_isdst ? tzname[1] : tzname[0], trashFile);
	fclose(f);
	chmod(trashFile, 0666);
	pid_t pid0 = fork();
	if (0 == pid0)	/* in child */
	    {
	    close(STDOUT_FILENO); /* do not hang up Apache finish for parent */
	    expireSeconds = 0;	/* no error message from this exit */
	    (void) signal(SIGALRM, cgiApoptosis);
	    (void) alarm(6);	/* timeout here in 6 seconds */
#include "versionInfo.h"
	    char url[1024];
	    safef(url, sizeof(url), "%s%s%s%s%s%s", "http://",
	"genomewiki.", "ucsc.edu/", "cgi-bin/useCount?", "version=browser.v",
		CGI_VERSION);

	    /* 6 second alarm will exit this page fetch if it does not work */
	    (void) htmlPageGetWithCookies(url, NULL); /* ignore return */

	    exit(0);
	    }	/* child of fork has done exit(0) normally or via alarm */
	}		/* trash file open OK */
    if (expireSeconds > 0)
	{
	(void) signal(SIGALRM, cgiApoptosis);
	(void) alarm(expireSeconds);	/* CGI timeout */
	}
    }			/* an actual CGI binary */
}			/* phoneHome()	*/
コード例 #6
0
ファイル: web.c プロジェクト: elmargb/kentUtils
char *webTimeStampedLinkToResource(char *fileName, boolean wrapInHtml)
// If wrapInHtml
//   returns versioned link embedded in style or script html (free after use).
// else
//   returns full path of a versioned path to the requested resource file (js, or css).
// NOTE: png, jpg and gif should also be supported but are untested.
//
// In production sites we use a versioned softlink that includes the CGI version. This has the following benefits:
// a) flushes user's web browser cache when the user visits a GB site whose version has changed since their last visit;
// b) enforces the requirement that static files are the same version as the CGIs (something that often fails to happen in mirrors).
// (see notes in redmine #3170).
//
// In dev trees we use mtime to create a pseudo-version; this forces web browsers to reload css/js file when it changes,
// so we don't get odd behavior that can be caused by caching of mis-matched javascript and style files in dev trees.
//
// In either case, the actual file has to have been previously created by running make in the appropriate directory (kent/src/hg/js
// or kent/src/hg/htdocs/style).
{
char baseName[PATH_LEN];
char extension[FILEEXT_LEN];
splitPath(fileName, NULL, baseName, extension);
boolean js = sameString(".js",extension);
boolean style = !js && sameString(".css",extension);
boolean image = !js
             && !style
             && (  sameString(".png",extension)
                || sameString(".jpg",extension)
                || sameString(".gif",extension));
if (!js && !style) // && !image) NOTE: This code has not been tested on images but should work.
    errAbort("webTimeStampedLinkToResource: unknown resource type for %s.\n", fileName);

// Build and verify directory
char *dirName = "";
if (js)
    dirName = cfgOptionDefault("browser.javaScriptDir", "js");
else if (style)
    dirName = cfgOptionDefault("browser.styleDir","style");
else if (image)
    dirName = cfgOptionDefault("browser.styleImagesDir","style/images");
struct dyString *fullDirName = NULL;
char *docRoot = hDocumentRoot();
if (docRoot != NULL)
    fullDirName = dyStringCreate("%s/%s", docRoot, dirName);
else
    // tolerate missing docRoot (i.e. when running from command line)
    fullDirName = dyStringCreate("%s", dirName);
if (!fileExists(dyStringContents(fullDirName)))
    errAbort("webTimeStampedLinkToResource: dir: %s doesn't exist.\n",
             dyStringContents(fullDirName));

// build and verify real path to file
struct dyString *realFileName = dyStringCreate("%s/%s", dyStringContents(fullDirName), fileName);
if (!fileExists(dyStringContents(realFileName)))
    errAbort("webTimeStampedLinkToResource: file: %s doesn't exist.\n",
             dyStringContents(realFileName));

// build and verify link path including timestamp in the form of dir/baseName + timeStamp or CGI Version + ext
long mtime = fileModTime(dyStringContents(realFileName));
struct dyString *linkWithTimestamp;

char *scriptName = cgiScriptName();
if (scriptName == NULL)
    scriptName = cloneString("");
boolean nonVersionedLinks = FALSE;
if (endsWith(scriptName, "qaPushQ"))
    nonVersionedLinks = TRUE;
if (nonVersionedLinks)
    linkWithTimestamp = dyStringCreate("%s/%s%s", dyStringContents(fullDirName), baseName, extension);
else if ((cfgOption("versionStamped") == NULL) &&  (hIsPreviewHost() || hIsPrivateHost()))
    linkWithTimestamp = dyStringCreate("%s/%s-%ld%s", dyStringContents(fullDirName), baseName, mtime, extension);
else
    linkWithTimestamp = dyStringCreate("%s/%s-v%s%s", dyStringContents(fullDirName), baseName, CGI_VERSION, extension);

if (!fileExists(dyStringContents(linkWithTimestamp)))
    errAbort("Cannot find correct version of file '%s'; this is due to an installation error\n\nError details: %s does not exist",
             fileName, dyStringContents(linkWithTimestamp));

// Free up all that extra memory
dyStringFree(&realFileName);
dyStringFree(&fullDirName);
char *linkFull = dyStringCannibalize(&linkWithTimestamp);
char *link = linkFull;
if (docRoot != NULL)
    {
    link = cloneString(linkFull + strlen(docRoot) + 1);
    freeMem(linkFull);
    }

if (wrapInHtml) // wrapped for christmas
    {
    struct dyString *wrapped = dyStringNew(0);
    if (js)
        dyStringPrintf(wrapped,"<script type='text/javascript' SRC='/%s'></script>\n", link);
    else if (style)
        dyStringPrintf(wrapped,"<LINK rel='STYLESHEET' href='/%s' TYPE='text/css' />\n", link);
    else // Will be image, since these are the only three choices allowed
        dyStringPrintf(wrapped,"<IMG src='/%s' />\n", link);
    freeMem(link);
    link = dyStringCannibalize(&wrapped);
    }

return link;
}
コード例 #7
0
int documentLink(struct hash *ra, char *term, char *docTerm,char *dir,
                 char *title,boolean genericDoc)
// Compare controlled vocab based on term value
{
boolean docsPrinted = 0;
char *s;
if (title == NULL)
    title = docTerm;

//can use hg.conf to direct links back to main UCSC server if a mirror doesn't
//want all the PDFs
char *baseUrl = cfgOptionDefault("hgEncodeVocabDocBaseUrl", "");
// add links to protocol doc if it exists
char docUrl[PATH_LEN];
char docFile[PATH_LEN];
// parse setting
s = hashFindVal(ra,docTerm);
if (s != NULL)
    {
    if (sameWord(s,"missing"))
        printf("&nbsp;<em>missing</em>\n");
    else
        {
        char *docSetting = cloneString(s);
        char *settings=docSetting;
        int count=0;
        while ((s = nextWord(&settings)) != NULL)
            {
            char *docTitle = NULL;
            char *fileName = NULL;
            if (strchr(s,':')) // lab Specific setting
                {
                docTitle = strSwapChar(s,':',0);
                fileName = docTitle + strlen(docTitle) + 1;
                }
            else
                {
                docTitle = title;
                fileName = s;
                }
            if (count>0)
                printf("<BR>");
            count++;
            docTitle = htmlEncode(strSwapChar(docTitle,'_',' '));
            if (sameWord(fileName,"missing"))
                printf("%s<em>missing</em>\n",docTitle);
            else
                {
                safef(docUrl,  sizeof(docUrl),  "%s%s%s", baseUrl, dir, fileName);
                safef(docFile, sizeof(docFile), "%s%s", hDocumentRoot(), docUrl);
                printf(" <A TARGET=_BLANK HREF=%s>%s</A>\n", docUrl,docTitle);
                docsPrinted++;
                }
            freeMem(docTitle);
            }
        freeMem(docSetting);
        }
    }
else if (genericDoc)
    { // generate a standard name
    safef(docUrl,  sizeof(docUrl),  "%s%s%s_protocol.pdf", baseUrl, dir, term);
    safef(docFile, sizeof(docFile), "%s%s", hDocumentRoot(), docUrl);
    if (fileExists(docFile))
        {
        printf(" <A TARGET=_BLANK HREF=%s>%s</A>\n", docUrl,title);
        docsPrinted++;
        }
    }
return docsPrinted;
}
コード例 #8
0
ファイル: hgHubConnect.c プロジェクト: bowhan/kent
void doMiddle(struct cart *theCart)
/* Write header and body of html page. */
{
boolean gotDisconnect = FALSE;

cart = theCart;

if (cartVarExists(cart, hgHubDoClear))
    {
    doClearHub(cart);
    cartWebEnd();
    return;
    }

if (cartVarExists(cart, hgHubDoDisconnect))
    {
    gotDisconnect = TRUE;
    doDisconnectHub(cart);

    // now rebuild the cart variable ("trackHubs") that has which lists which
    // hubs are on.
    hubConnectHubsInCart(cart);
    }

if (cartVarExists(cart, hgHubDoReset))
    {
    doResetHub(cart);
    }

cartWebStart(cart, NULL, "%s", pageTitle);
jsIncludeFile("jquery.js", NULL);
jsIncludeFile("utils.js", NULL);
jsIncludeFile("jquery-ui.js", NULL);

webIncludeResourceFile("jquery-ui.css");

jsIncludeFile("ajax.js", NULL);
jsIncludeFile("hgHubConnect.js", NULL);
jsIncludeFile("jquery.cookie.js", NULL);

printf("<div id=\"hgHubConnectUI\"> <div id=\"description\"> \n");
printf(
   "<P>Track data hubs are collections of tracks from outside of UCSC that "
   "can be imported into the Genome Browser.  To import a public hub check "
   "the box in the list below. "
   "After import the hub will show up as a group of tracks with its own blue "
   "bar and label underneath the main browser graphic, and in the "
   "configure page. For more information, see the "
   "<A HREF=\"../goldenPath/help/hgTrackHubHelp.html\" TARGET=_blank>"
   "User's Guide</A>.</P>\n"
   "<P><B>NOTE: Because Track Hubs are created and maintained by external sources,"
   " UCSC is not responsible for their content.</B></P>"
   );
printf("</div>\n");

getDbAndGenome(cart, &database, &organism, oldVars);

char *survey = cfgOptionEnv("HGDB_HUB_SURVEY", "hubSurvey");
char *surveyLabel = cfgOptionEnv("HGDB_HUB_SURVEY_LABEL", "hubSurveyLabel");

if (survey && differentWord(survey, "off"))
    hPrintf("<span style='background-color:yellow;'><A HREF='%s' TARGET=_BLANK><EM><B>%s</EM></B></A></span>\n", survey, surveyLabel ? surveyLabel : "Take survey");
hPutc('\n');

// check to see if we have any new hubs
hubCheckForNew(cart);

// grab all the hubs that are listed in the cart
struct hubConnectStatus *hubList =  hubConnectStatusListFromCartAll(cart);

checkTrackDbs(hubList);

// here's a little form for the add new hub button
printf("<FORM ACTION=\"%s\" NAME=\"addHubForm\">\n",  "../cgi-bin/hgHubConnect");
cgiMakeHiddenVar("hubUrl", "");
cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on");
puts("</FORM>");

// this the form for the disconnect hub button
printf("<FORM ACTION=\"%s\" NAME=\"disconnectHubForm\">\n",  "../cgi-bin/hgHubConnect");
cgiMakeHiddenVar("hubId", "");
cgiMakeHiddenVar(hgHubDoDisconnect, "on");
cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on");
puts("</FORM>");

// this the form for the reset hub button
printf("<FORM ACTION=\"%s\" NAME=\"resetHubForm\">\n",  "../cgi-bin/hgHubConnect");
cgiMakeHiddenVar("hubUrl", "");
cgiMakeHiddenVar(hgHubDoReset, "on");
cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on");
puts("</FORM>");


// ... and now the main form
if (cartVarExists(cart, hgHubConnectCgiDestUrl))
    destUrl = cartOptionalString(cart, hgHubConnectCgiDestUrl);
printf("<FORM ACTION=\"%s\" METHOD=\"POST\" NAME=\"mainForm\">\n", destUrl);
cartSaveSession(cart);

// we have two tabs for the public and unlisted hubs
printf("<div id=\"tabs\">"
       "<ul> <li><a href=\"#publicHubs\">Public Hubs</a></li>"
       "<li><a href=\"#unlistedHubs\">My Hubs</a></li> "
       "</ul> ");

struct hash *publicHash = hgHubConnectPublic();
hgHubConnectUnlisted(hubList, publicHash);
printf("</div>");

printf("<div class=\"tabFooter\">");
cgiMakeButton("Submit", "Use Selected Hubs");

char *emailAddress = cfgOptionDefault("hub.emailAddress","*****@*****.**");
printf("<span class=\"small\">"
    "Contact <A HREF=\"mailto:%s\">%s</A> to add a public hub."
    "</span>\n", emailAddress,emailAddress);
printf("</div>");

cgiMakeHiddenVar(hgHubConnectRemakeTrackHub, "on");

printf("</div>\n");
puts("</FORM>");
cartWebEnd();
}
コード例 #9
0
ファイル: configTest.c プロジェクト: cmwshang/pgbackrest
/***********************************************************************************************************************************
Test run
***********************************************************************************************************************************/
void
testRun(void)
{
    FUNCTION_HARNESS_VOID();

    // Static tests against known values -- these may break as options change so will need to be kept up to date.  The tests have
    // generally been selected to favor values that are not expected to change but adjustments are welcome as long as the type of
    // test is not drastically changed.
    // *****************************************************************************************************************************
    if (testBegin("check known values"))
    {
        TEST_ERROR(cfgCommandId(BOGUS_STR), AssertError, "invalid command 'BOGUS'");
        TEST_RESULT_INT(cfgCommandId("archive-push"), cfgCmdArchivePush, "command id from name");

        TEST_ERROR(
            cfgCommandDefIdFromId(CFG_COMMAND_TOTAL), AssertError, "assertion 'commandId < cfgCmdNone' failed");
        TEST_RESULT_INT(cfgCommandDefIdFromId(cfgCmdBackup), cfgDefCmdBackup, "command id to def id");

        TEST_RESULT_STR(cfgCommandName(cfgCmdBackup), "backup", "command name from id");

        TEST_RESULT_INT(cfgOptionDefIdFromId(cfgOptPgHost + 6), cfgDefOptPgHost, "option id to def id");

        TEST_RESULT_INT(cfgOptionId("target"), cfgOptTarget, "option id from name");
        TEST_RESULT_INT(cfgOptionId(BOGUS_STR), -1, "option id from invalid option name");

        TEST_ERROR(
            cfgOptionIdFromDefId(cfgDefOptionTotal(), 6), AssertError,
            "assertion 'optionDefId < cfgDefOptionTotal()' failed");
        TEST_ERROR(
            cfgOptionIdFromDefId(0, 999999), AssertError,
            "assertion 'index < cfgDefOptionIndexTotal(optionDefId)' failed");
        TEST_RESULT_INT(cfgOptionIdFromDefId(cfgDefOptPgHost, 6), cfgOptPgHost + 6, "option def id to id");

        TEST_ERROR(cfgOptionIndex(CFG_OPTION_TOTAL), AssertError, "assertion 'optionId < CFG_OPTION_TOTAL' failed");
        TEST_RESULT_INT(cfgOptionIndex(cfgOptPgHostCmd + 6), 6, "option index");
        TEST_RESULT_INT(cfgOptionIndex(cfgOptCompressLevel), 0, "option index");

        TEST_RESULT_INT(cfgOptionIndexTotal(cfgOptPgPath), 8, "option index total");
        TEST_RESULT_INT(cfgOptionIndexTotal(cfgOptLogLevelConsole), 1, "option index total");

        TEST_RESULT_STR(cfgOptionName(cfgOptBackupStandby), "backup-standby", "option id from name");
    }

    // *****************************************************************************************************************************
    if (testBegin("configuration"))
    {
        TEST_RESULT_VOID(cfgInit(), "config init");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_INT(cfgCommand(), cfgCmdNone, "command begins as none");
        TEST_RESULT_VOID(cfgCommandSet(cfgCmdBackup), "command set to backup");
        TEST_RESULT_INT(cfgCommand(), cfgCmdBackup, "command is backup");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_VOID(cfgCommandSet(cfgCmdBackup), "command set to backup");
        TEST_RESULT_INT(cfgLogLevelDefault(), logLevelInfo, "default log level is info");
        TEST_RESULT_BOOL(cfgLogFile(), true, "log file is on");
        TEST_RESULT_BOOL(cfgLockRequired(), true, "lock is required");
        TEST_RESULT_BOOL(cfgLockRemoteRequired(cfgCmdBackup), true, "remote lock is required");
        TEST_RESULT_INT(cfgLockType(), lockTypeBackup, "lock is type backup");
        TEST_RESULT_INT(cfgLockRemoteType(cfgCmdBackup), lockTypeBackup, "remote lock is type backup");
        TEST_RESULT_BOOL(cfgParameterAllowed(), false, "parameters not allowed");

        TEST_RESULT_VOID(cfgCommandSet(cfgCmdInfo), "command set to info");
        TEST_RESULT_INT(cfgLogLevelDefault(), logLevelDebug, "default log level is debug");
        TEST_RESULT_INT(cfgLogLevelStdErrMax(), logLevelTrace, "max stderr log level is trace");
        TEST_RESULT_BOOL(cfgLogFile(), false, "log file is off");
        TEST_RESULT_BOOL(cfgLockRequired(), false, "lock is not required");
        TEST_RESULT_BOOL(cfgLockRemoteRequired(cfgCmdInfo), false, "remote lock is not required");
        TEST_RESULT_INT(cfgLockType(), lockTypeNone, "lock is type none");
        TEST_RESULT_INT(cfgLockRemoteType(cfgCmdInfo), lockTypeNone, "remote lock is type none");

        TEST_RESULT_VOID(cfgCommandSet(cfgCmdStanzaCreate), "command set to stanza-create");
        TEST_RESULT_BOOL(cfgLockRequired(), true, "lock is required");
        TEST_RESULT_INT(cfgLockType(), lockTypeAll, "lock is type all");

        TEST_RESULT_VOID(cfgCommandSet(cfgCmdLocal), "command set to local");
        TEST_RESULT_INT(cfgLogLevelStdErrMax(), logLevelError, "max stderr log level is error");
        TEST_RESULT_BOOL(cfgLogFile(), true, "log file is on");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_BOOL(cfgCommandHelp(), false, "command help defaults to false");
        TEST_RESULT_VOID(cfgCommandHelpSet(true), "set command help");
        TEST_RESULT_BOOL(cfgCommandHelp(), true, "command help is set");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_INT(strLstSize(cfgCommandParam()), 0, "command param list defaults to empty");
        TEST_RESULT_VOID(cfgCommandParamSet(strLstAddZ(strLstNew(), "param")), "set command param list");
        TEST_RESULT_INT(strLstSize(cfgCommandParam()), 1, "command param list is set");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_PTR(cfgExe(), NULL, "exe defaults to null");
        TEST_RESULT_VOID(cfgExeSet(strNew("/path/to/exe")), "set exe");
        TEST_RESULT_STR(strPtr(cfgExe()), "/path/to/exe", "exe is set");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_BOOL(cfgOptionNegate(cfgOptConfig), false, "negate defaults to false");
        TEST_RESULT_VOID(cfgOptionNegateSet(cfgOptConfig, true), "set negate");
        TEST_RESULT_BOOL(cfgOptionNegate(cfgOptConfig), true, "negate is set");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_BOOL(cfgOptionReset(cfgOptConfig), false, "reset defaults to false");
        TEST_RESULT_VOID(cfgOptionResetSet(cfgOptConfig, true), "set reset");
        TEST_RESULT_BOOL(cfgOptionReset(cfgOptConfig), true, "reset is set");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_BOOL(cfgOptionValid(cfgOptConfig), false, "valid defaults to false");
        TEST_RESULT_BOOL(cfgOptionTest(cfgOptConfig), false, "option not valid for the command");
        TEST_RESULT_VOID(cfgOptionValidSet(cfgOptConfig, true), "set valid");
        TEST_RESULT_BOOL(cfgOptionValid(cfgOptConfig), true, "valid is set");
        TEST_RESULT_BOOL(cfgOptionTest(cfgOptConfig), false, "option valid but value is null");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptConfig, cfgSourceParam, varNewStrZ("cfg")), "set option config");
        TEST_RESULT_BOOL(cfgOptionTest(cfgOptConfig), true, "option valid and value not null");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_PTR(cfgOption(cfgOptOnline), NULL, "online is null");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptOnline, cfgSourceParam, varNewBool(false)), "set online");
        TEST_RESULT_BOOL(cfgOptionBool(cfgOptOnline), false, "online is set");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptOnline, cfgSourceParam, varNewStrZ("1")), "set online");
        TEST_RESULT_BOOL(cfgOptionBool(cfgOptOnline), true, "online is set");
        TEST_RESULT_INT(cfgOptionSource(cfgOptOnline), cfgSourceParam, "online source is set");
        TEST_ERROR(
            cfgOptionDbl(cfgOptOnline), AssertError,
            "assertion 'varType(configOptionValue[optionId].value) == varTypeDouble' failed");
        TEST_ERROR(
            cfgOptionInt64(cfgOptOnline), AssertError,
            "assertion 'varType(configOptionValue[optionId].value) == varTypeInt64' failed");

        TEST_RESULT_VOID(cfgOptionSet(cfgOptCompressLevel, cfgSourceParam, varNewInt64(1)), "set compress-level");
        TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 1, "compress-level is set");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptCompressLevel, cfgSourceDefault, varNewStrZ("3")), "set compress-level");
        TEST_RESULT_INT(cfgOptionUInt(cfgOptCompressLevel), 3, "compress-level is set");
        TEST_RESULT_INT(cfgOptionSource(cfgOptCompressLevel), cfgSourceDefault, "compress source is set");
        TEST_ERROR(
            cfgOptionBool(cfgOptCompressLevel), AssertError,
            "assertion 'varType(configOptionValue[optionId].value) == varTypeBool' failed");

        TEST_RESULT_VOID(
            cfgOptionSet(cfgOptArchivePushQueueMax, cfgSourceParam, varNewInt64(999999999999)), "set archive-push-queue-max");
        TEST_RESULT_INT(cfgOptionInt64(cfgOptArchivePushQueueMax), 999999999999, "archive-push-queue-max is set");
        TEST_RESULT_INT(cfgOptionUInt64(cfgOptArchivePushQueueMax), 999999999999, "archive-push-queue-max is set");

        TEST_RESULT_VOID(cfgOptionSet(cfgOptProtocolTimeout, cfgSourceParam, varNewDbl(1.1)), "set protocol-timeout");
        TEST_RESULT_DOUBLE(cfgOptionDbl(cfgOptProtocolTimeout), 1.1, "protocol-timeout is set");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptProtocolTimeout, cfgSourceConfig, varNewStrZ("3.3")), "set protocol-timeout");
        TEST_RESULT_DOUBLE(cfgOptionDbl(cfgOptProtocolTimeout), 3.3, "protocol-timeout is set");
        TEST_RESULT_INT(cfgOptionSource(cfgOptProtocolTimeout), cfgSourceConfig, "protocol-timeout source is set");
        TEST_ERROR(
            cfgOptionKv(cfgOptProtocolTimeout), AssertError,
            "assertion 'varType(configOptionValue[optionId].value) == varTypeKeyValue' failed");

        TEST_RESULT_VOID(cfgOptionSet(cfgOptProtocolTimeout, cfgSourceConfig, NULL), "set protocol-timeout to NULL");
        TEST_RESULT_PTR(cfgOption(cfgOptProtocolTimeout), NULL, "protocol-timeout is not set");

        TEST_ERROR(
            cfgOptionSet(cfgOptRecoveryOption, cfgSourceParam, varNewDbl(1.1)), AssertError,
            "option 'recovery-option' must be set with KeyValue variant");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptRecoveryOption, cfgSourceConfig, varNewKv(kvNew())), "set recovery-option");
        TEST_RESULT_INT(varLstSize(kvKeyList(cfgOptionKv(cfgOptRecoveryOption))), 0, "recovery-option is set");
        TEST_ERROR(
            cfgOptionLst(cfgOptRecoveryOption), AssertError,
            "assertion 'configOptionValue[optionId].value == NULL"
                " || varType(configOptionValue[optionId].value) == varTypeVariantList' failed");

        TEST_RESULT_INT(varLstSize(cfgOptionLst(cfgOptDbInclude)), 0, "db-include defaults to empty");
        TEST_ERROR(
            cfgOptionSet(cfgOptDbInclude, cfgSourceParam, varNewDbl(1.1)), AssertError,
            "option 'db-include' must be set with VariantList variant");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptDbInclude, cfgSourceConfig, varNewVarLst(varLstNew())), "set db-include");
        TEST_RESULT_INT(varLstSize(cfgOptionLst(cfgOptDbInclude)), 0, "db-include is set");
        TEST_ERROR(
            cfgOptionStr(cfgOptDbInclude), AssertError,
            "assertion 'configOptionValue[optionId].value == NULL"
                " || varType(configOptionValue[optionId].value) == varTypeString' failed");

        TEST_RESULT_PTR(cfgOptionStr(cfgOptStanza), NULL, "stanza defaults to null");
        TEST_ERROR(
            cfgOptionSet(cfgOptStanza, cfgSourceParam, varNewDbl(1.1)), AssertError,
            "option 'stanza' must be set with String variant");
        TEST_RESULT_VOID(cfgOptionSet(cfgOptStanza, cfgSourceConfig, varNewStrZ("db")), "set stanza");
        TEST_RESULT_STR(strPtr(cfgOptionStr(cfgOptStanza)), "db", "stanza is set");
        TEST_ERROR(
            cfgOptionInt(cfgOptStanza), AssertError,
            "assertion 'varType(configOptionValue[optionId].value) == varTypeInt64' failed");

        // -------------------------------------------------------------------------------------------------------------------------
        TEST_RESULT_VOID(cfgInit(), "config init resets value");
        TEST_RESULT_INT(cfgCommand(), cfgCmdNone, "command begins as none");
    }

    // *****************************************************************************************************************************
    if (testBegin("cfgOptionHostPort()"))
    {
        unsigned int port = 55555;

        cfgInit();
        cfgCommandSet(cfgCmdBackup);

        cfgOptionValidSet(cfgOptRepoS3Host, true);
        cfgOptionSet(cfgOptRepoS3Host, cfgSourceConfig, varNewStrZ("host.com")) ;
        TEST_RESULT_STR(strPtr(cfgOptionHostPort(cfgOptRepoS3Host, &port)), "host.com", "check plain host");
        TEST_RESULT_UINT(port, 55555, "check that port was not updated");

        cfgOptionSet(cfgOptRepoS3Host, cfgSourceConfig, varNewStrZ("myhost.com:777")) ;
        TEST_RESULT_STR(strPtr(cfgOptionHostPort(cfgOptRepoS3Host, &port)), "myhost.com", "check host with port");
        TEST_RESULT_UINT(port, 777, "check that port was updated");

        TEST_RESULT_STR(strPtr(cfgOptionHostPort(cfgOptRepoS3Endpoint, &port)), NULL, "check null host");
        TEST_RESULT_UINT(port, 777, "check that port was not updated");

        cfgOptionSet(cfgOptRepoS3Host, cfgSourceConfig, varNewStrZ("myhost.com:777:888")) ;
        TEST_ERROR(
            cfgOptionHostPort(cfgOptRepoS3Host, &port), OptionInvalidError,
            "'myhost.com:777:888' is not valid for option 'repo1-s3-host'"
                "\nHINT: is more than one port specified?");
        TEST_RESULT_UINT(port, 777, "check that port was not updated");

        cfgOptionValidSet(cfgOptRepoS3Endpoint, true);
        cfgOptionSet(cfgOptRepoS3Endpoint, cfgSourceConfig, varNewStrZ("myendpoint.com:ZZZ")) ;
        TEST_ERROR(
            cfgOptionHostPort(cfgOptRepoS3Endpoint, &port), OptionInvalidError,
            "'myendpoint.com:ZZZ' is not valid for option 'repo1-s3-endpoint'"
                "\nHINT: port is not a positive integer.");
        TEST_RESULT_UINT(port, 777, "check that port was not updated");
    }

    // *****************************************************************************************************************************
    if (testBegin("cfgOptionDefault() and cfgOptionDefaultSet()"))
    {
        TEST_RESULT_VOID(cfgInit(), "config init");
        TEST_RESULT_VOID(cfgCommandSet(cfgCmdBackup), "backup command");

        TEST_RESULT_STR(strPtr(varStr(cfgOptionDefault(cfgOptType))), "incr", "backup type default");
        TEST_RESULT_BOOL(varBool(cfgOptionDefault(cfgOptCompress)), "true", "backup compress default");
        TEST_RESULT_DOUBLE(varDbl(cfgOptionDefault(cfgOptProtocolTimeout)), 1830, "backup protocol-timeout default");
        TEST_RESULT_INT(varIntForce(cfgOptionDefault(cfgOptCompressLevel)), 6, "backup compress-level default");
        TEST_RESULT_PTR(cfgOptionDefault(cfgOptDbInclude), NULL, "backup db-include default is null");

        TEST_RESULT_VOID(cfgOptionSet(cfgOptPgHost, cfgSourceParam, varNewStrZ("backup")), "backup host set");
        TEST_RESULT_VOID(cfgOptionDefaultSet(cfgOptPgHost, varNewStrZ("backup-default")), "backup host default");
        TEST_RESULT_VOID(cfgOptionDefaultSet(cfgOptPgHost, varNewStrZ("backup-default2")), "reset backup host default");
        TEST_RESULT_STR(strPtr(varStr(cfgOption(cfgOptPgHost))), "backup", "backup host value");
        TEST_RESULT_STR(strPtr(varStr(cfgOptionDefault(cfgOptPgHost))), "backup-default2", "backup host default");

        TEST_RESULT_VOID(cfgOptionSet(cfgOptPgSocketPath, cfgSourceDefault, NULL), "backup pg-socket-path set");
        TEST_RESULT_VOID(cfgOptionDefaultSet(cfgOptPgSocketPath, varNewStrZ("/to/socket")), "backup pg-socket-path default");
        TEST_RESULT_VOID(cfgOptionDefaultSet(cfgOptPgSocketPath, varNewStrZ("/to/socket2")), "reset backup pg-socket-path default");
        TEST_RESULT_STR(strPtr(varStr(cfgOption(cfgOptPgSocketPath))), "/to/socket2", "backup pg-socket-path value");
        TEST_RESULT_STR(strPtr(varStr(cfgOptionDefault(cfgOptPgSocketPath))), "/to/socket2", "backup pg-socket-path value default");
    }

    FUNCTION_HARNESS_RESULT_VOID();
}