44ccfacbe3a3d4b300f80d48651c77837a4b571e galt Tue Apr 26 11:12:02 2022 -0700 SQL INJECTION Prevention Version 2 - this improves our methods by making subclauses of SQL that get passed around be both easy and correct to use. The way that was achieved was by getting rid of the obscure and not well used functions sqlSafefFrag and sqlDyStringPrintfFrag and replacing them with the plain versions of those functions, since these are not needed anymore. The new version checks for NOSQLINJ in unquoted %-s which is used to include SQL clauses, and will give an error the NOSQLINJ clause is not present, and this will automatically require the correct behavior by developers. sqlDyStringPrint is a very useful function, however because it was not enforced, users could use various other dyString functions and they operated without any awareness or checking for SQL correct use. Now those dyString functions are prohibited and it will produce an error if you try to use a dyString function on a SQL string, which is simply detected by the presence of the NOSQLINJ prefix. diff --git src/hg/hgText/hgWigText.c src/hg/hgText/hgWigText.c index 36883ba..bc6eff4 100644 --- src/hg/hgText/hgWigText.c +++ src/hg/hgText/hgWigText.c @@ -1,885 +1,885 @@ /* hgWigText.c - functions for wiggle tracks in hgText */ /* Copyright (C) 2013 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "wiggle.h" #include "hgColors.h" #include "web.h" #include "cheapcgi.h" #include "hCommon.h" #include "hgText.h" #include "hui.h" #include "customTrack.h" #include "portable.h" /* possible two sets of data could be existing */ static struct wiggleData *wigData[2] = { (struct wiggleData *)NULL, (struct wiggleData *)NULL, }; /* Droplist menu for custom track visibility: */ static char *ctWigVisMenu[] = { "hide", "dense", "full", }; static int ctWigVisMenuSize = sizeof(ctWigVisMenu)/sizeof(char *); /* Droplist menu for custom track data count: */ static char *ctWigCountMenu[] = { "10000", "100000", "1000000", }; static int ctWigCountMenuSize = sizeof(ctWigCountMenu)/sizeof(char *); struct wiggleStats *wigStatsList[2] = { (struct wiggleStats *) NULL, (struct wiggleStats *) NULL, }; struct hash *chromsDone[2]; static void printBedEl(struct bed *bedEl) { printf("%s\t%u\t%u\t%s\n", bedEl->chrom, bedEl->chromStart, bedEl->chromEnd, bedEl->name); } /********* wiggle compare functions ***********************************/ static boolean wigInRange(int tableId, double value, boolean summaryOnly, struct wiggle *wiggle) { boolean ret = FALSE; if (summaryOnly) ret = ((wiggle->lowerLimit <= wigDataConstraint[tableId][1]) && (wiggle->lowerLimit+wiggle->dataRange >= wigDataConstraint[tableId][0])); else ret = (value >= wigDataConstraint[tableId][0] && value <= wigDataConstraint[tableId][1]); return ret; } static boolean wigLessThan(int tableId, double value, boolean summaryOnly, struct wiggle *wiggle) { boolean ret = FALSE; if (summaryOnly) ret = (wiggle->lowerLimit < wigDataConstraint[tableId][0]); else ret = (value < wigDataConstraint[tableId][0]); return ret; } static boolean wigLessEqual(int tableId, double value, boolean summaryOnly, struct wiggle *wiggle) { boolean ret = FALSE; if (summaryOnly) ret = (wiggle->lowerLimit <= wigDataConstraint[tableId][0]); else ret = (value <= wigDataConstraint[tableId][0]); return ret; } static boolean wigEqual(int tableId, double value, boolean summaryOnly, struct wiggle *wiggle) { boolean ret = FALSE; if (summaryOnly) ret = ((wiggle->lowerLimit < wigDataConstraint[tableId][0]) && (wiggle->lowerLimit+wiggle->dataRange > wigDataConstraint[tableId][0])); else ret = (value == wigDataConstraint[tableId][0]); return ret; } static boolean wigNotEqual(int tableId, double value, boolean summaryOnly, struct wiggle *wiggle) { boolean ret = FALSE; if (summaryOnly) ret = ((wiggle->lowerLimit > wigDataConstraint[tableId][0]) || (wiggle->lowerLimit+wiggle->dataRange < wigDataConstraint[tableId][0])); else ret = (value != wigDataConstraint[tableId][0]); return ret; } static boolean wigGreaterEqual(int tableId, double value, boolean summaryOnly, struct wiggle *wiggle) { boolean ret = FALSE; if (summaryOnly) ret=(wiggle->lowerLimit+wiggle->dataRange >= wigDataConstraint[tableId][0]); else ret = (value >= wigDataConstraint[tableId][0]); return ret; } static boolean wigGreaterThan(int tableId, double value, boolean summaryOnly, struct wiggle *wiggle) { boolean ret = FALSE; if (summaryOnly) ret = (wiggle->lowerLimit+wiggle->dataRange > wigDataConstraint[tableId][0]); else ret = (value > wigDataConstraint[tableId][0]); return ret; } static void showConstraints(char *constraints, int tableId, boolean htmlOutput) { boolean foundSome = FALSE; if (htmlOutput) printf("<P>Constraints in effect: "); if ((constraints != NULL) && (constraints[0] != 0)) { foundSome = TRUE; if (htmlOutput) printf("%s\n", constraints); else printf("#\tSQL query constraint: %s\n", constraints); } if (wigConstraint[tableId]) { if (htmlOutput) if (foundSome) printf(" AND "); foundSome = TRUE; if (sameWord(wigConstraint[tableId],"in range")) { if (htmlOutput) printf("(data value %s [%g , %g])", wigConstraint[tableId], wigDataConstraint[tableId][0], wigDataConstraint[tableId][1]); else printf("#\tdata value constraint range: %s [%g , %g]\n", wigConstraint[tableId], wigDataConstraint[tableId][0], wigDataConstraint[tableId][1]); } else { if (htmlOutput) printf("(data value %s %g)", wigConstraint[tableId], wigDataConstraint[tableId][0]); else printf("#\tdata value constraint: %s %g\n", wigConstraint[tableId], wigDataConstraint[tableId][0]); } } if (htmlOutput) { if (foundSome) printf("</P>\n"); else printf("NONE</P>\n"); } } void wiggleConstraints(char *cmp, char *pat, int tableIndex) { wigConstraint[tableIndex] = cmp; wiggleCompare[tableIndex] = NULL; if (strlen(pat)>0) { if (sameWord(cmp,"in range")) { char *rangeValues[2]; char *clone = cloneString(pat); int records = 0; char *comma = strchr(pat,','); if (comma == (char *)NULL) records = chopByWhite(clone,rangeValues,2); else records = chopByChar(clone,',',rangeValues,2); if (records == 2) { trimSpaces(rangeValues[0]); trimSpaces(rangeValues[1]); wigDataConstraint[tableIndex][0] = sqlDouble(rangeValues[0]); wigDataConstraint[tableIndex][1] = sqlDouble(rangeValues[1]); if (wigDataConstraint[tableIndex][0] > wigDataConstraint[tableIndex][1]) { double d = wigDataConstraint[tableIndex][1]; wigDataConstraint[tableIndex][1] = wigDataConstraint[tableIndex][0]; wigDataConstraint[tableIndex][0] = d; } wiggleCompare[tableIndex] = wigInRange; } freeMem(clone); if (wigDataConstraint[tableIndex][1] == wigDataConstraint[tableIndex][0]) errAbort("For \"in range\" constraint, you must give two numbers separated by whitespace or comma."); } else { wigDataConstraint[tableIndex][0] = sqlDouble(pat); if (sameWord(cmp,"<")) wiggleCompare[tableIndex] = wigLessThan; else if (sameWord(cmp,"<=")) wiggleCompare[tableIndex] = wigLessEqual; else if (sameWord(cmp,"=")) wiggleCompare[tableIndex] = wigEqual; else if (sameWord(cmp,"!=")) wiggleCompare[tableIndex] = wigNotEqual; else if (sameWord(cmp,">=")) wiggleCompare[tableIndex]=wigGreaterEqual; else if (sameWord(cmp,">")) wiggleCompare[tableIndex] = wigGreaterThan; } } } static void wigPrintRow(struct wiggleStats *wigStats) { printf("<TR><TH ALIGN=LEFT> %s </TH>\n", wigStats->chrom); printf("\t<TD ALIGN=RIGHT> %u </TD>\n", wigStats->chromStart+1); /* display closed coords */ printf("\t<TD ALIGN=RIGHT> %u </TD>\n", wigStats->chromEnd); printf("\t<TD ALIGN=RIGHT> %u </TD>\n", wigStats->count); printf("\t<TD ALIGN=RIGHT> %d </TD>\n", wigStats->span); printf("\t<TD ALIGN=RIGHT> %u </TD>\n", wigStats->count*wigStats->span); printf("\t<TD ALIGN=RIGHT> %g </TD>\n", wigStats->lowerLimit); printf("\t<TD ALIGN=RIGHT> %g </TD>\n", wigStats->lowerLimit+wigStats->dataRange); printf("\t<TD ALIGN=RIGHT> %g </TD>\n", wigStats->dataRange); printf("\t<TD ALIGN=RIGHT> %g </TD>\n", wigStats->mean); printf("\t<TD ALIGN=RIGHT> %g </TD>\n", wigStats->variance); printf("\t<TD ALIGN=RIGHT> %g </TD>\n", wigStats->stddev); printf("<TR>\n"); } static void wigPrintStats(struct wiggleStats **wsList, char *chrom) { struct wiggleStats *wigStats = (struct wiggleStats *)NULL; for (wigStats = *wsList; wigStats; wigStats = wigStats->next) { if (sameWord(wigStats->chrom,chrom)) wigPrintRow(wigStats); } } /* Check to see if this stats are done for this chrom */ static boolean wigStatsDone(int tableId, char *chrom) { if (chromsDone[tableId] == (struct hash *)NULL) return FALSE; else if (hashLookup(chromsDone[tableId],chrom)) return TRUE; else return FALSE; } static void wigMarkDone(int tableId, char *chrom) { if ((struct hash *)NULL == chromsDone[tableId]) chromsDone[tableId] = newHash(0); if ( (struct hashEl *)NULL == hashLookup(chromsDone[tableId],chrom)) hashAdd(chromsDone[tableId],chrom,NULL); } void wigMakeBedList(char *database, char *table, char *chrom, char *constraints, int tableId) { char *setting = cartCgiUsualString(cart, "tbWigCount", ctWigCountMenu[1]); unsigned maxLinesOut = MAX_LINES_OUT; if (setting != (char *) NULL) maxLinesOut = sqlUnsigned(setting); if ( ! wigStatsDone(tableId, chrom)) { wigData[tableId] = wigFetchData(database, table, chrom, winStart, winEnd, WIG_ALL_DATA, WIG_DATA_NOT_RETURNED, tableId, wiggleCompare[tableId], constraints, &bedListWig[tableId], maxLinesOut, &wigStatsList[tableId]); wigMarkDone(tableId, chrom); } } void wigDoStats(char *database, char *table, struct slName *chromList, int tableId, char *constraints) { struct slName *chromPtr; char *db = getTableDb(); struct sqlConnection *conn = hAllocOrConnect(db); struct sqlResult *sr = (struct sqlResult *)NULL; char query[256]; char **row = (char **)NULL; char wigFullTableName[256]; char *setting = cartCgiUsualString(cart, "tbWigCount", ctWigCountMenu[1]); unsigned maxLinesOut = MAX_LINES_OUT; int numChroms = 0; int tableRowsDisplayed = 0; if (setting != (char *) NULL) maxLinesOut = sqlUnsigned(setting); if (tableIsSplit) { getFullTableName(wigFullTableName, hDefaultChromDb(db), table); sqlSafef(query, sizeof(query), "show table status like '%s'", wigFullTableName); } else sqlSafef(query, sizeof(query), "show table status like '%s'", table); sr = sqlMustGetResult(conn,query); row = sqlNextRow(sr); // For some reason BORDER=1 does not work in our web.c nested table scheme. // So use web.c's trick of using an enclosing table to provide a border. puts("<P><!--outer table is for border purposes-->" "\n" "<TABLE BGCOLOR='#" HG_COL_BORDER "' BORDER=0 CELLSPACING=0 CELLPADDING=1><TR><TD>"); puts("<TABLE BGCOLOR='#" HG_COL_INSIDE "' BORDER=1 CELLSPACING=0>"); if (row != NULL) { printf("<TR><TD COLSPAN=12>\n"); printf("<TABLE COLS=12 ALIGN=CENTER HSPACE=0>" "<TR><TH COLSPAN=1 ALIGN=LEFT> Database: %s </TH><TH COLSPAN=1 ALIGN=CENTER> Table: %s </TH><TH COLSPAN=10 ALIGN=RIGHT> Last update: %s </TH></TR></TABLE></TD></TR>\n", database, table, row[11]); } else { printf("<TR><TH COLSPAN=6 ALIGN=LEFT> Database: %s </TH><TH COLSPAN=6 ALIGN=RIGHT> Table: %s </TH></TR>\n", database, table); } sqlFreeResult(&sr); hFreeOrDisconnect(&conn); printf("<TR><TH> Chrom </TH><TH> Data <BR> start </TH>"); printf("<TH> Data <BR> end </TH>"); printf("<TH> # of Data <BR> values </TH><TH> Data <BR> span </TH>"); printf("<TH> Bases <BR> covered </TH><TH> Minimum </TH>"); printf("<TH> Maximum </TH><TH> Range </TH><TH> Mean </TH>"); printf("<TH> Variance </TH><TH> Standard <BR> deviation </TH></TR>\n"); numChroms = slCount(chromList); for (chromPtr=chromList; chromPtr != NULL; chromPtr=chromPtr->next) { char *chrom = chromPtr->name; char wigFullTableName[256]; getFullTableName(wigFullTableName, chrom, table); if ( ! wigStatsDone(tableId, chrom)) { boolean dataFetchType = WIG_SUMMARY_ONLY; if (numChroms == 1) dataFetchType = WIG_ALL_DATA; if (wiggleCompare[tableId]) dataFetchType = WIG_ALL_DATA; if (numChroms > 1) wigData[tableId] = wigFetchData(database, wigFullTableName, chrom, winStart, winEnd, dataFetchType, WIG_DATA_NOT_RETURNED, tableId, wiggleCompare[tableId], constraints, (struct bed **)NULL, maxLinesOut, &wigStatsList[tableId]); else wigData[tableId] = wigFetchData(database, wigFullTableName, chrom, winStart, winEnd, dataFetchType, WIG_DATA_NOT_RETURNED, tableId, wiggleCompare[tableId], constraints, (struct bed **)NULL, 0, &wigStatsList[tableId]); wigMarkDone(tableId, chrom); } if (wigStatsDone(tableId, chrom)) { wigPrintStats(&wigStatsList[tableId], chrom); if (wigStatsList[tableId] != (struct wiggleStats *) NULL) ++tableRowsDisplayed; } else { printf("<TR><TH ALIGN=LEFT> %s </TH>", chrom); printf("<TH COLSPAN=11> No data </TH></TR>\n"); ++tableRowsDisplayed; } } /* No rows in table, indicate this no result */ if (!tableRowsDisplayed) puts("<TR><TH ALIGN=CENTER COLSPAN=12> No data found matching this request </TH></TR>"); printf("</TABLE>\n"); puts("</TD></TR></TABLE></P>"); } /* void wigDoStats() */ void doWiggleCtOptions(boolean doCt) { struct hTableInfo *hti = getOutputHti(); char *table = getTableName(); char *table2 = getTable2Name(); char *op = cgiOptionalString("tbIntersectOp"); char *db = getTableDb(); char *outputType = cgiUsualString("outputType", cgiString("phase")); char *phase = (existsAndEqual("phase", getOutputPhase) ? cgiString("outputType") : cgiString("phase")); char *setting = NULL; char buf[256]; char *constraints = constrainFields(NULL); saveOutputOptionsState(); saveIntersectOptionsState(); webStart(cart, "Table Browser: %s %s: %s", hOrganism(database), freezeName, phase); checkTableExists(fullTableName); printf("<FORM ACTION=\"%s\" NAME=\"mainForm\" METHOD=\"%s\">\n", hgTextName(), httpFormMethod); cartSaveSession(cart); cgiMakeHiddenVar("db", db); cgiMakeHiddenVar("table", getTableVar()); displayPosition(); cgiMakeHiddenVar("outputType", outputType); preserveConstraints(fullTableName, db, NULL); preserveTable2(); printf("<H3> Select %s Options for %s: </H3>\n", (doCt ? "Custom Track" : "DATA"), hti->rootName); puts("<A HREF=\"/goldenPath/help/hgTextHelp.html#BEDOptions\">" "<B>Help</B></A><P>"); puts("<TABLE><TR><TD>"); if (doCt) { puts("</TD><TD>" "<A HREF=\"/goldenPath/help/customTrack.html\" TARGET=_blank>" "Custom track</A> header: </B>"); } else { cgiMakeCheckBox("tbDoCustomTrack", cartCgiUsualBoolean(cart, "tbDoCustomTrack", FALSE)); puts("</TD><TD> <B> Include " "<A HREF=\"/goldenPath/help/customTrack.html\" TARGET=_blank>" "custom track</A> header: </B>"); } puts("</TD></TR><TR><TD></TD><TD>name="); if (op == NULL) table2 = NULL; snprintf(buf, sizeof(buf), "tb_%s", hti->rootName); setting = cgiUsualString("tbCtName", buf); cgiMakeTextVar("tbCtName", setting, 16); puts("</TD></TR><TR><TD></TD><TD>description="); snprintf(buf, sizeof(buf), "table browser query on %s%s%s", table, (table2 ? ", " : ""), (table2 ? table2 : "")); setting = cgiUsualString("tbCtDesc", buf); cgiMakeTextVar("tbCtDesc", setting, 50); puts("</TD></TR><TR><TD></TD><TD>visibility="); setting = cartCgiUsualString(cart, "tbCtVis", ctWigVisMenu[2]); cgiMakeDropList("tbCtVis", ctWigVisMenu, ctWigVisMenuSize, setting); puts("</TD></TR><TR><TD></TD></TR></TABLE>"); showConstraints(constraints, WIG_TABLE_1, TRUE); printf("<P> <B> Select type of data output: </B> <BR>\n"); if (doCt) setting = cartCgiUsualString(cart, "tbWigDataType", "bedData"); else setting = cartCgiUsualString(cart, "tbWigDataType", "wigData"); cgiMakeRadioButton("tbWigDataType", "bedData", sameString(setting, "bedData")); printf("BED format (no data value information, only position)<BR>\n"); cgiMakeRadioButton("tbWigDataType", "wigData", sameString(setting, "wigData")); printf("DATA VALUE format (position and real valued data)</P>\n"); puts("<P> <B> Limit output to: </B>"); setting = cartCgiUsualString(cart, "tbWigCount", ctWigCountMenu[1]); cgiMakeDropList("tbWigCount", ctWigCountMenu, ctWigCountMenuSize, setting); puts("<B> lines of data </B> (to avoid browser overload)</P>\n"); if (doCt) { cartSetBoolean(cart, "tbDoCustomTrack", TRUE); cgiMakeButton("phase", getCtWiggleTrackPhase); cgiMakeButton("phase", getCtWiggleFilePhase); } else { cgiMakeButton("phase", getWigglePhase); } puts("</FORM>"); webEnd(); } /* void doWiggleCtOptions(boolean doCt) */ static void fileConstraints(char *constraints, int tableId, FILE *f) { if (constraints) fprintf(f, "#\tSQL query constraint: %s\n", constraints); if (wigConstraint[tableId]) { if (sameWord(wigConstraint[tableId],"in range")) fprintf(f,"#\tdata value constraint range: %s [%g , %g]\n", wigConstraint[tableId], wigDataConstraint[tableId][0], wigDataConstraint[tableId][1]); else fprintf(f,"#\tdata value constraint: %s %g\n", wigConstraint[tableId], wigDataConstraint[tableId][0]); } } void doGetWiggleData(boolean doCt) /* Find wiggle data and display it */ { struct slName *chromList, *chromPtr; char *db = getTableDb(); char *table = getTableName(); struct wiggleData *wigData = (struct wiggleData *) NULL; struct wiggleData *wdPtr = (struct wiggleData *) NULL; struct trackDb *tdb = (struct trackDb *)NULL; char *track = getTrackName(); unsigned linesOutput = 0; boolean doCtHdr = (cartCgiUsualBoolean(cart, "tbDoCustomTrack", FALSE) || doCt); char *constraints; char *setting = cartCgiUsualString(cart, "tbWigCount", ctWigCountMenu[1]); unsigned maxLinesOut = MAX_LINES_OUT; char *longLabel = cloneString("User Supplied Track"); char *ctDesc = cgiUsualString("tbCtDesc", table); char *ctName = cgiUsualString("tbCtName", table); char *ctVis = cgiUsualString("tbCtVis", "hide"); char *ctUrl = cgiUsualString("tbCtUrl", ""); struct customTrack *ctNew = NULL; char tableName[128]; char *visibility; int visNum = 0; boolean wigBED = FALSE; struct bed *bedList = NULL; FILE *wigAsciiFH = (FILE *) NULL; if (! sameString(customTrackPseudoDb, db)) { struct sqlConnection *conn = hAllocOrConnect(db); tdb = hMaybeTrackInfo(conn, track); hFreeOrDisconnect(&conn); } if (setting != (char *) NULL) maxLinesOut = sqlUnsigned(setting); setting = cartCgiUsualString(cart, "tbWigDataType", "wigData"); if ( sameString(setting, "bedData") ) wigBED = TRUE; saveOutputOptionsState(); saveIntersectOptionsState(); constraints = constrainFields(NULL); if ((constraints != NULL) && (constraints[0] == 0)) constraints = NULL; if (!doCt) { printf("Content-Type: text/plain\n\n"); webStartText(); } if (differentWord(ctName,table) ) snprintf(tableName, sizeof(tableName), "%s", ctName); else snprintf(tableName, sizeof(tableName), "tb_%s", table); if (ctDesc != (char *)NULL) { freeMem(longLabel); longLabel = cloneString(ctDesc); } if (ctVis != (char *)NULL) visibility = cloneString(ctVis); else visibility = cloneString("hide"); visNum = (int) hTvFromStringNoAbort(visibility); if (visNum < 0) visNum = 0; if (allGenome) chromList = getOrderedChromList(); else chromList = newSlName(chrom); if (doCtHdr && wigBED && !doCt) { printf("track name=\"%s\" description=\"%s\" " "visibility=%s\n", tableName, longLabel, visibility); showConstraints(constraints, WIG_TABLE_1, FALSE); } if (doCt) { int fields=0; if (wigBED) fields=4; ctNew = newCT(tableName, longLabel, visNum, ctUrl, fields); if (wigBED) ctNew->wiggle = FALSE; else { struct tempName tn; makeTempName(&tn, "hgtct", ".wig"); ctNew->wigFile = cloneString(tn.forCgi); makeTempName(&tn, "hgtct", ".wib"); ctNew->wibFile = cloneString(tn.forCgi); makeTempName(&tn, "hgtct", ".wia"); ctNew->wigAscii = cloneString(tn.forCgi); wigAsciiFH = mustOpen(ctNew->wigAscii, "w"); #if defined(DEBUG) /* dbg */ /* allow file readability for debug */ chmod(ctNew->wigAscii, 0666); #endif ctNew->wiggle = TRUE; } } for (chromPtr=chromList; chromPtr != NULL && (linesOutput < maxLinesOut); chromPtr=chromPtr->next) { char *chrom = chromPtr->name; char wigFullTableName[256]; int bedLength = 0; getFullTableName(wigFullTableName, chrom, table); if (wigBED) { wigData = wigFetchData(database, table, chrom, winStart, winEnd, WIG_ALL_DATA, WIG_DATA_NOT_RETURNED, WIG_TABLE_1, wiggleCompare[WIG_TABLE_1], constraints, &bedListWig[WIG_TABLE_1], maxLinesOut, (struct wiggleStats **)NULL); wigMarkDone(WIG_TABLE_1, chrom); bedLength = slCount(bedListWig[WIG_TABLE_1]); } else { wigData = wigFetchData(database, table, chrom, winStart, winEnd, WIG_ALL_DATA, WIG_RETURN_DATA, WIG_TABLE_1, wiggleCompare[WIG_TABLE_1], constraints, (struct bed **)NULL, maxLinesOut, (struct wiggleStats **)NULL); wigMarkDone(WIG_TABLE_1, chrom); } if (wigData) { unsigned span = 0; char *chrom = (char *) NULL; unsigned char colorR, colorG, colorB; unsigned char altColorR, altColorG, altColorB; float priority; int wordCount; char *words[128]; char *trackType = (char *) NULL; boolean nextSpan = FALSE; if (tdb && tdb->type) { char *typeLine = cloneString(tdb->type); if (ctDesc == (char *)NULL) { freeMem(longLabel); longLabel = cloneString(tdb->longLabel); } priority = tdb->priority; wordCount = chopLine(typeLine,words); if (wordCount > 0) trackType = words[0]; colorR = tdb->colorR; colorG = tdb->colorG; colorB = tdb->colorB; altColorR = tdb->altColorR; altColorG = tdb->altColorG; altColorB = tdb->altColorB; colorR = colorG = colorB = 0; altColorR = altColorG = altColorB = 128; } else { priority = 42; if (ctDesc == (char *)NULL) { freeMem(longLabel); longLabel = cloneString("User Supplied Track"); } colorR = colorG = colorB = 255; altColorR = altColorG = altColorB = 128; } if (doCt) { ctNew->tdb->longLabel = longLabel; } if (doCtHdr && (!wigBED)) { if (doCt) { - struct dyString *wigSettings = newDyString(0); + struct dyString *wigSettings = dyStringNew(0); ctNew->tdb->priority = priority; ctNew->tdb->colorR = colorR; ctNew->tdb->colorG = colorB; ctNew->tdb->colorB = colorB; ctNew->tdb->altColorR = altColorR; ctNew->tdb->altColorG = altColorB; ctNew->tdb->altColorB = altColorB; /* more settings to be done */ dyStringPrintf(wigSettings, "type='wiggle_0'\twigFile='%s'\twibFile='%s'", ctNew->wigFile, ctNew->wibFile); ctNew->tdb->settings = dyStringCannibalize(&wigSettings); fileConstraints(constraints, WIG_TABLE_1, wigAsciiFH); } else { printf("track type=wiggle_0 name=%s description=\"%s\" " "visibility=%s color=%d,%d,%d altColor=%d,%d,%d " "priority=%g\n", tableName, longLabel, visibility, colorR, colorG, colorB, altColorR, altColorG, altColorB, priority); showConstraints(constraints, WIG_TABLE_1, FALSE); } } for (wdPtr = wigData; (linesOutput < maxLinesOut) && (wdPtr != (struct wiggleData *) NULL); wdPtr= wdPtr->next) { if ((chrom == (char *) NULL) || differentWord(chrom,wdPtr->chrom)) { if (!(doCtHdr | wigBED)) { if (!doCt) printf("#\t"); } if (!wigBED) { if (doCt) fprintf(wigAsciiFH, "variableStep chrom=%s span=%u\n", wdPtr->chrom, wdPtr->span); else printf("variableStep chrom=%s span=%u\n", wdPtr->chrom, wdPtr->span); } chrom = wdPtr->chrom; span = wdPtr->span; } if (span != wdPtr->span) { if (!(doCtHdr | wigBED)) printf("#\t"); if (!wigBED) { if (doCt) fprintf(wigAsciiFH, "variableStep chrom=%s span=%u\n", wdPtr->chrom, wdPtr->span); else printf("variableStep chrom=%s span=%u\n", wdPtr->chrom, wdPtr->span); } span = wdPtr->span; } if (wdPtr->data) { struct wiggleDatum *wd = wdPtr->data; int i; for (i = 0; (!nextSpan) && (linesOutput < maxLinesOut) && (i < wdPtr->count); ++i, ++wd) { if (doCt) fprintf(wigAsciiFH, "%u\t%g\n", wd->chromStart+1, wd->value); else printf("%u\t%g\n", wd->chromStart+1, wd->value); ++linesOutput; } } else if (bedLength > 0) { struct bed *bedEl = bedListWig[WIG_TABLE_1]; for ( ; linesOutput < maxLinesOut && bedEl; bedEl = bedEl->next) { if (doCt) { struct bed *newBed = cloneBed(bedEl); slAddHead(&bedList, newBed); } else printBedEl(bedEl); ++linesOutput; } if (doCt) bedFreeList(&bedListWig[WIG_TABLE_1]); bedLength = 0; } } wigFreeData(&wigData); } } if ((ctNew != NULL) && (bedList != NULL)) { slReverse(&bedList); ctNew->bedList = bedList; } if ((ctNew != NULL) && ((ctNew->bedList != NULL) || (ctNew->wigAscii != NULL))) { /* Load existing custom tracks and add this new one: */ struct customTrack *ctList = getCustomTracks(); slAddHead(&ctList, ctNew); carefulClose(&wigAsciiFH); /* Save the custom tracks out to file (overwrite the old file): */ customTracksSaveCart(cart, ctList); } if (doCt) { char browserUrl[128]; char headerText[256]; int redirDelay = 5; if (linesOutput < 1) { printf("Content-Type: text/plain\n\n"); webStartText(); printf("#\tno results returned from query\n"); webEnd(); } else { safef(browserUrl, sizeof(browserUrl), "%s?db=%s&position=%s:%d-%d", hgTracksName(), database, chrom, winStart, winEnd); safef(headerText, sizeof(headerText), "<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"%d;URL=%s\">", redirDelay, browserUrl); webStartHeader(cart, headerText, "Table Browser: %s %s: %s", hOrganism(database), freezeName, getCtPhase); printf("You will be automatically redirected to the genome browser in\n" "%d seconds, or you can <BR>\n" "<A HREF=\"%s\">click here to continue</A>.\n", redirDelay, browserUrl); webEnd(); } } else { if (linesOutput < 1) { printf("#\tno results returned from query\n"); } else if (linesOutput >= maxLinesOut) printf("#\tmaximum data output of %u lines reached\n", maxLinesOut); webEnd(); } } /* void doGetWiggleData(boolean doCt) */