05094dabf3d005ab35a998ff225443fc4255611f
galt
  Mon Feb 4 23:07:42 2019 -0800
Adding ability to backup and restore the cart and its custom tracks in hgSession.

diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c
index 864a092..c15aecc 100644
--- src/hg/hgSession/hgSession.c
+++ src/hg/hgSession/hgSession.c
@@ -19,34 +19,38 @@
 #include "linefile.h"
 #include "net.h"
 #include "textOut.h"
 #include "hCommon.h"
 #include "hui.h"
 #include "cart.h"
 #include "jsHelper.h"
 #include "web.h"
 #include "hdb.h"
 #include "ra.h"
 #include "wikiLink.h"
 #include "customTrack.h"
 #include "customFactory.h"
 #include "udc.h"
 #include "hgSession.h"
-#include "hubConnect.h"
 #include "hgConfig.h"
 #include "sessionThumbnail.h"
+#include "filePath.h"
 #include "obscure.h"
+#include "trashDir.h"
+#include "hubConnect.h"
+
+#include "trackHub.h"
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "hgSession - Interface with wiki login and do session saving/loading.\n"
   "usage:\n"
   "    hgSession <various CGI settings>\n"
   );
 }
 
 /* Global variables. */
 struct cart *cart;
 char *excludeVars[] = {"Submit", "submit", NULL};
 struct slName *existingSessionNames = NULL;
@@ -295,31 +299,32 @@
         "                                       \"order\":[1,'asc'],\n"
         "                                       \"stateSave\":true,\n"
         "                                       \"stateSaveCallback\": %s,\n"
         "                                       \"stateLoadCallback\": %s\n"
         "                                 });\n"
         "} );\n"
         "}\n"
         , jsDataTableStateSave(hgSessionPrefix), jsDataTableStateLoad(hgSessionPrefix, cart));
 
 printf("<H3>My Sessions</H3>\n");
 printf("<div style=\"max-width:1024px\">");
 printf("<table id=\"sessionTable\" class=\"sessionTable stripe hover row-border compact\" borderwidth=0>\n");
 printf("<thead><tr>");
 printf("<TH><TD><B>session name (click to load)</B></TD><TD><B>created on</B></TD><td><b>assembly</b></td>"
        "<TD align=center><B>view/edit&nbsp;<BR>details&nbsp;</B></TD>"
-       "<TD align=center><B>delete this&nbsp;<BR>session&nbsp;</B></TD><TD align=center><B>share with&nbsp;<BR>others?&nbsp;</B></TD>"
+       "<TD align=center><B>delete this&nbsp;<BR>session&nbsp;</B></TD>"
+       "<TD align=center><B>share with&nbsp;<BR>others?&nbsp;</B></TD>"
        "<td align-center><b>post in&nbsp;<br><a href=\"../cgi-bin/hgPublicSessions?%s\">public listing</a>?</b></td>"
        "<TD align=center><B>send to<BR>mail</B></TD></TH>",
        cartSidUrlString(cart));
 printf("</tr></thead>");
 printf("<tbody>\n");
 
 if (gotSettings)
     sqlSafef(query, sizeof(query), "SELECT sessionName, shared, firstUse, contents, settings from %s "
         "WHERE userName = '%s' ORDER BY sessionName;",
         namedSessionTable, encUserName);
 else
     sqlSafef(query, sizeof(query), "SELECT sessionName, shared, firstUse, contents from %s "
         "WHERE userName = '%s' ORDER BY sessionName;",
         namedSessionTable, encUserName);
 sr = sqlGetResult(conn, query);
@@ -363,30 +368,31 @@
             db = cloneStringZ(dbIdx, dbEnd-dbIdx);
         else
             db = cloneString(dbIdx);
         printf("%s</td><td align=center>", db);
         }
     else
         printf("n/a</td><td align=center>");
 
     if (gotSettings)
         {
         safef(buf, sizeof(buf), "%s%s", hgsEditPrefix, encSessionName);
         cgiMakeButton(buf, "details");
         }
     else
         printf("unavailable");
+
     printf("</TD><TD align=center>");
     safef(buf, sizeof(buf), "%s%s", hgsDeletePrefix, encSessionName);
     char command[512];
     safef(command, sizeof(command), confirmDeleteFormat, encSessionName);
     cgiMakeOnClickSubmitButton(command, buf, "delete");
 
     printf("</TD><TD align=center>");
     safef(buf, sizeof(buf), "%s%s", hgsSharePrefix, encSessionName);
     cgiMakeCheckBoxWithId(buf, shared>0, buf);
     jsOnEventById("change",buf,"console.log('new status' + this.checked); document.mainForm.submit();");
 
     printf("</TD><TD align=center>");
     safef(buf, sizeof(buf), "%s%s", hgsGalleryPrefix, encSessionName);
     cgiMakeCheckBoxFourWay(buf, inGallery, shared>0, buf, NULL, NULL);
     jsOnEventById("change", buf, "document.mainForm.submit();");
@@ -446,30 +452,55 @@
 jsOnEventById("keypress", hgsLoadLocalFileName,"return noSubmitOnEnter(event);");
 printf("&nbsp;&nbsp;");
 cgiMakeButton(hgsDoLoadLocal, "submit");
 printf("</TD></TR>\n");
 printf("<TR><TD colspan=2></TD></TR>\n");
 
 printf("<TR><TD colspan=2>Use settings from a URL (http://..., ftp://...):"
        "</TD>\n");
 printf("<TD>\n");
 cgiMakeOnKeypressTextVar(hgsLoadUrlName,
 			 cartUsualString(cart, hgsLoadUrlName, ""),
 			 20, jsPressOnEnter(hgsDoLoadUrl));
 printf("&nbsp;&nbsp;");
 cgiMakeButton(hgsDoLoadUrl, "submit");
 printf("</TD></TR>\n");
+
+printf("<TR><TD colspan=2></TD></TR>\n");
+
+char name[256];
+safef(name, sizeof name, "%s", hgsExtractUploadPrefix);
+
+printf("<TR>");
+printf("<TD colspan=2>Use settings including custom tracks in local backup archive file (.tar.gz):</TD>");
+printf("<TD><INPUT TYPE=FILE NAME='%s' id='%s'>", name, name);
+printf("&nbsp;&nbsp;<input type='submit' id='archiveUpload' value='submit'></TD></TR>");
+printf("<TR><TD colspan=2></TD></TR>");
+
+// check the file name, e.g. does it have the right name or extension?
+char js[1024];
+safef(js, sizeof js, 
+"var control = document.getElementById('%s');"
+"var files = control.files;"
+"if ((files.length == 1) && (files[0].name.endsWith('.tar.gz')))"
+"    return true;"
+"alert('Please choose the correct backup archive ending in .tar.gz');"
+"return false;"
+, name);
+
+jsOnEventById("click", "archiveUpload", js);
+
 printf("</TABLE>\n");
 printf("<P></P>\n");
 }
 
 void showSavingOptions(char *userName)
 /* Show options for saving a new named session in our db or to a file. */
 {
 printf("<H3>Save Settings</H3>\n");
 printf("<TABLE BORDERWIDTH=0>\n");
 
 if (isNotEmpty(userName))
     {
     printf("<TR><TD colspan=4>Save current settings as named session:"
 	   "</TD></TR>\n"
 	   "<TR><TD>&nbsp;&nbsp;&nbsp;</TD><TD>name:</TD><TD>\n");
@@ -519,30 +550,40 @@
 printf("file type returned: ");
 char *compressType = cartUsualString(cart, hgsSaveLocalFileCompress, textOutCompressNone);
 cgiMakeRadioButton(hgsSaveLocalFileCompress, textOutCompressNone,
 		   differentWord(textOutCompressGzip, compressType));
 printf("&nbsp;plain text&nbsp&nbsp");
 cgiMakeRadioButton(hgsSaveLocalFileCompress, textOutCompressGzip,
 		   sameWord(textOutCompressGzip, compressType));
 printf("&nbsp;gzip compressed (ignored if output file is blank)");
 printf("</TD><TD>");
 printf("&nbsp;");
 cgiMakeButton(hgsDoSaveLocal, "submit");
 printf("</TD></TR>\n");
 printf("<TR><TD></TD><TD colspan=3>(leave file blank to get output in "
        "browser window)</TD></TR>\n");
 printf("<TR><TD colspan=4></TD></TR>\n");
+
+printf("<TR><TD colspan=4>Save Full Session:</TD></TR>\n");
+printf("<TR><TD>&nbsp;&nbsp;&nbsp;</TD><TD colspan=2>");
+printf("backup settings including custom tracks to archive .tar.gz</TD>");
+printf("<TD>");
+printf("&nbsp;");
+cgiMakeButton(hgsShowDownloadPrefix, "submit");
+printf("</TD></TR>\n");
+
+printf("<TR><TD colspan=4></TD></TR>\n");
 printf("</TABLE>\n");
 }
 
 void showSessionControls(char *userName, boolean savedSessionsSupported,
 			 boolean webStarted)
 /* If userName is non-null, show sessions that belong to user and allow
  * saving of named sessions.
  * If savedSessionsSupported, allow import of named sessions.
  * Allow export/import of settings from file/URL. */
 {
 char *formMethod = cartUsualString(cart, "formMethod", "POST");
 
 if (webStarted)
     webNewSection("Session Management");
 else
@@ -675,30 +716,35 @@
 
 void cleanHgSessionFromCart(struct cart *cart)
 /* Remove hgSession action variables that should not stay in the cart. */
 {
 char varName[256];
 safef(varName, sizeof(varName), "%s%s", cgiBooleanShadowPrefix(), hgsSharePrefix);
 cartRemovePrefix(cart, varName);
 cartRemovePrefix(cart, hgsSharePrefix);
 safef(varName, sizeof(varName), "%s%s", cgiBooleanShadowPrefix(), hgsGalleryPrefix);
 cartRemovePrefix(cart, varName);
 cartRemovePrefix(cart, hgsGalleryPrefix);
 cartRemovePrefix(cart, hgsLoadPrefix);
 cartRemovePrefix(cart, hgsEditPrefix);
 cartRemovePrefix(cart, hgsLoadLocalFileName);
 cartRemovePrefix(cart, hgsDeletePrefix);
+cartRemovePrefix(cart, hgsShowDownloadPrefix);
+cartRemovePrefix(cart, hgsMakeDownloadPrefix);
+cartRemovePrefix(cart, hgsDoDownloadPrefix);
+cartRemovePrefix(cart, hgsExtractUploadPrefix);
+cartRemovePrefix(cart, hgsDoUploadPrefix);
 cartRemovePrefix(cart, hgsDo);
 cartRemove(cart, hgsOldSessionName);
 cartRemove(cart, hgsCancel);
 }
 
 static void outIfNotPresent(struct cart *cart, struct dyString *dy, char *track, int tdbVis)
 /* Output default trackDb visibility if it's not mentioned in the cart. */
 {
 char *cartVis = cartOptionalString(cart, track);
 if (cartVis == NULL)
     {
     if (dy)
         dyStringPrintf(dy,"&%s=%s", track, hStringFromTv(tdbVis));
     else
         printf("%s %s\n", track, hStringFromTv(tdbVis));
@@ -965,31 +1011,33 @@
 		   "<INPUT TYPE=TEXT NAME=\"%s\" id='%s' SIZE=%d VALUE=\"%s\" >\n",
 		   sessionName, hgSessionName(),
 		   cartSessionVarName(cart), cartSessionId(cart), hgsOldSessionName, sessionName,
 		   hgsNewSessionName, hgsNewSessionName, 32, sessionName);
     jsOnEventById("change"  , hgsNewSessionName, highlightAccChanges);
     jsOnEventById("keypress", hgsNewSessionName, highlightAccChanges);
 
     dyStringPrintf(dyMessage,
 		   "&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME=\"%s%s\" VALUE=\"use\">"
 		   "&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME=\"%s%s\" id='%s%s' VALUE=\"delete\">"
 		   "&nbsp;&nbsp;<INPUT TYPE=SUBMIT ID=\"%s\" NAME=\"%s\" VALUE=\"accept changes\">"
 		   "&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME=\"%s\" VALUE=\"cancel\"> "
 		   "<BR>\n",
 		   hgsLoadPrefix, encSessionName, 
 		   hgsDeletePrefix, encSessionName, hgsDeletePrefix, encSessionName,
-		   hgsDoSessionChange, hgsDoSessionChange, hgsCancel);
+		   hgsDoSessionChange, hgsDoSessionChange, 
+		   hgsCancel);
+
     char id[256];
     safef(id, sizeof id, "%s%s", hgsDeletePrefix, encSessionName);
     jsOnEventByIdF("click", id, confirmDeleteFormat, encSessionName);
 
     dyStringPrintf(dyMessage,
 		   "Share with others? <INPUT TYPE=CHECKBOX NAME=\"%s%s\"%s VALUE=on "
 		   "id=\"detailsSharedCheckbox\">\n"
 		   "<INPUT TYPE=HIDDEN NAME=\"%s%s%s\" VALUE=0><BR>\n",
 		   hgsSharePrefix, encSessionName, (shared>0 ? " CHECKED" : ""),
 		   cgiBooleanShadowPrefix(), hgsSharePrefix, encSessionName);
     jsOnEventByIdF("change", "detailsSharedCheckbox", "{%s %s}", highlightAccChanges, toggleGalleryDisable);
     jsOnEventByIdF("click" , "detailsSharedCheckbox", "{%s %s}", highlightAccChanges, toggleGalleryDisable);
 
     dyStringPrintf(dyMessage,
 		   "List in Public Sessions? <INPUT TYPE=CHECKBOX NAME=\"%s%s\"%s VALUE=on "
@@ -1412,30 +1460,35 @@
 char *newName = cartOptionalString(cart, hgsNewSessionName);
 if (isNotEmpty(newName) && !sameString(sessionName, newName))
     {
     char *encNewName = cgiEncodeFull(newName);
     sqlSafef(query, sizeof(query),
 	  "UPDATE %s set sessionName = '%s' WHERE userName = '%s' AND sessionName = '%s';",
 	  namedSessionTable, encNewName, encUserName, encSessionName);
 	sqlUpdate(conn, query);
     dyStringPrintf(dyMessage, "Changed session name from %s to <B>%s</B>.\n",
 		   sessionName, newName);
     sessionName = newName;
     encSessionName = encNewName;
     renamePrefixedCartVar(hgsEditPrefix         , encOldSessionName, encNewName);
     renamePrefixedCartVar(hgsLoadPrefix         , encOldSessionName, encNewName);
     renamePrefixedCartVar(hgsDeletePrefix       , encOldSessionName, encNewName);
+    renamePrefixedCartVar(hgsShowDownloadPrefix , encOldSessionName, encNewName);
+    renamePrefixedCartVar(hgsMakeDownloadPrefix , encOldSessionName, encNewName);
+    renamePrefixedCartVar(hgsDoDownloadPrefix   , encOldSessionName, encNewName);
+    renamePrefixedCartVar(hgsExtractUploadPrefix, encOldSessionName, encNewName);
+    renamePrefixedCartVar(hgsDoUploadPrefix     , encOldSessionName, encNewName);
     if (shared >= 2)
         {
         thumbnailRemove(encUserName, encSessionName, conn);
         thumbnailAdd(encUserName, encNewName, conn, dyMessage);
         }
     }
 
 char sharedVarName[256];
 char galleryVarName[256];
 safef(sharedVarName, sizeof(sharedVarName), hgsSharePrefix "%s", encOldSessionName);
 safef(galleryVarName, sizeof(galleryVarName), hgsGalleryPrefix "%s", encOldSessionName);
 if (cgiBooleanDefined(sharedVarName) || cgiBooleanDefined(galleryVarName))
     {
     int newShared = shared;
     if (cgiBooleanDefined(sharedVarName))
@@ -1499,45 +1552,262 @@
 			namedSessionTable, dyRa->string, encUserName, encSessionName);
 	sqlUpdate(conn, dyQuery->string);
 	dyStringPrintf(dyMessage, "Updated description of <B>%s</B>.\n", sessionName);
 	}
     }
 if (isEmpty(dyMessage->string))
     dyStringPrintf(dyMessage, "No changes to session <B>%s</B>.\n", sessionName);
 dyStringPrintf(dyMessage, "%s %s",
 	       getSessionLink(encUserName, encSessionName),
 	       getSessionEmailLink(encUserName, encSessionName));
 if (shared)
     printShareMessage(dyMessage, encUserName, encSessionName, FALSE);
 return dyStringCannibalize(&dyMessage);
 }
 
+// ======================================
+
+void prepBackGroundCall(char **pBackgroundProgress, char *cleanPrefix)
+/* fix cart and save state */
+{
+*pBackgroundProgress = cloneString(cgiUsualString("backgroundProgress", NULL)); 
+cartRemove(cart, "backgroundExec");
+cartRemove(cart, "backgroundProgress");
+cartRemovePrefix(cart, cleanPrefix);
+cartSaveState(cart);  // in case it crashes
+}
+
+void launchForeAndBackGround(char *operation)
+/* update cart, launch background and foreground */
+{
+char cmd[1024]; 
+safef(cmd, sizeof cmd, "./hgSession backgroundExec=%s", operation);
+
+// allow child to see variables loaded from CGI.
+// because CGI settings have not been saved back to the cart yet
+cartSaveState(cart);   
+
+char *workUrl = NULL;
+// automatically adds hgsid
+// automatically adds backGroundProgress=%s url.progress for separate channel
+// Have to pass the userName manually since background exec will not get cookie,
+// but we are no longer using userName which was needed with saved-sessions.
+startBackgroundWork(cmd, &workUrl);
+
+htmlOpen("Background Status");
+
+jsInlineF(
+    "setTimeout(function(){location = 'hgSession?backgroundStatus=%s&hgsid=%s';},2000);\n", 
+    cgiEncode(workUrl), cartSessionId(cart));
+htmlClose();
+fflush(stdout);
+}
+
+void passSubmittedBinaryAsTrashFile(struct hashEl *list)
+/* fetch the binary file submitted in memory,
+ * and save it to temp trash location,
+ * saving the name in the cart. 
+ * This is necessary to pass the file to the background process.*/
+{
+// List should have these two
+// hgS_extractUpload_hub_9614_Anc11__binary
+// hgS_extractUpload_hub_9614_Anc11__filename
+// can have a third __filepath if crashes leaving in the cart.
+
+char *binaryParam = NULL;
+struct hashEl *hel = NULL;
+for (hel = list; hel; hel = hel->next)
+    {
+    if (endsWith(hel->name, "__binary"))
+	binaryParam = cloneString(hel->name);
+    }
+
+if (!binaryParam)
+    {
+    htmlOpen("No file selected");
+    printf("Please choose a saved session custom tracks local backup archive file (.tar.gz) to upload");
+    htmlClose();
+    exit(0);
+    } 
+
+char *binaryValue = cartOptionalString(cart, binaryParam);
+
+char *binInfo = cloneString(binaryValue);
+char *words[2];
+char *mem;
+unsigned long size;
+chopByWhite(binInfo, words, ArraySize(words));
+mem = (char *)sqlUnsignedLong(words[0]);
+size = sqlUnsignedLong(words[1]);
+
+struct tempName tn;
+trashDirFile(&tn, "backGround", cartSessionId(cart), ".bin");
+
+writeGulp(tn.forCgi, mem, size); 
+
+// add new cart var with trash path
+// hgS_extractUpload_hub_9614_Anc11__filepath
+char *varName = replaceChars(binaryParam, "__binary", "__filepath");
+cartRemove(cart, varName);  // just in case
+cartSetString(cart, varName, tn.forCgi);  // update the cart
+}
 
 void hgSession()
 /* hgSession - Interface with wiki login and do session saving/loading.
  * Here we set up cart and some global variables, dispatch the command,
  * and put away the cart when it is done. */
 {
 struct hash *oldVars = hashNew(10);
 
 /* Sometimes we output HTML and sometimes plain text; let each outputter
  * take care of headers instead of using a fixed cart*Shell(). */
 cart = cartAndCookieNoContent(hUserCookie(), excludeVars, oldVars);
 
 char *userName = (loginSystemEnabled() || wikiLinkEnabled()) ? wikiLinkUserName() : NULL;
 
-if (cartVarExists(cart, hgsDoMainPage) || cartVarExists(cart, hgsCancel))
+char *backgroundStatus = cloneString(cartUsualString(cart, "backgroundStatus", NULL));
+
+if (backgroundStatus)
+    {
+    // clear backgroundStatus from the cart
+    cartRemove(cart, "backgroundStatus");
+    /* Save cart variables. */
+    cartSaveState(cart);
+    getBackgroundStatus(backgroundStatus);
+    exit(0);
+    }
+
+char *backgroundExec = cloneString(cgiUsualString("backgroundExec", NULL));
+
+
+struct hashEl *showDownloadList = cartFindPrefix(cart, hgsShowDownloadPrefix);
+struct hashEl *makeDownloadList = cartFindPrefix(cart, hgsMakeDownloadPrefix);
+struct hashEl *doDownloadList = cartFindPrefix(cart, hgsDoDownloadPrefix);
+struct hashEl *extractUploadList = cartFindPrefix(cart, hgsExtractUploadPrefix);
+struct hashEl *doUploadList = cartFindPrefix(cart, hgsDoUploadPrefix);
+
+// The form gets submitted but no filename for upload was chosen and submitted.
+if (extractUploadList && sameString(hgsExtractUploadPrefix, extractUploadList->name))
+    extractUploadList = NULL; // no filename was submitted. ignore.
+
+if (showDownloadList)
+    showDownloadSessionCtData(showDownloadList);
+else if (makeDownloadList)
+    {
+    if (sameOk(backgroundExec,"makeDownloadSessionCtData"))
+	{
+	// only one, not a list.
+	struct hashEl *hel = makeDownloadList;
+	char *param1 = cloneString(hel->name);
+
+	char *backgroundProgress = NULL; 
+	prepBackGroundCall(&backgroundProgress, hgsMakeDownloadPrefix);
+
+	makeDownloadSessionCtData(param1, backgroundProgress);
+
+	exit(0);  // cannot return
+	}
+    else
+	{
+
+	launchForeAndBackGround("makeDownloadSessionCtData");
+
+	exit(0);
+	}
+
+    }
+else if (doDownloadList)
+    doDownloadSessionCtData(doDownloadList);
+else if (extractUploadList)
+    {
+    if (sameOk(backgroundExec,"extractUploadSessionCtData"))
+	{
+	// only one, but becomes a list
+        // since there are multiple cart names with suffixes for handling binary submitted file.
+	//hgS_extractUpload___filepath 
+	//hgS_extractUpload___binary 
+	//hgS_extractUpload___filename 
+	char *param1 = NULL;
+	char *param2 = NULL;
+	char *param3 = NULL;
+	struct hashEl *hel = NULL;
+	for (hel = extractUploadList; hel; hel = hel->next)
+	    {
+	    if (endsWith(hel->name, "__binary"))
+		param1 = cloneString(hel->name);
+	    if (endsWith(hel->name, "__filename"))
+		param2 = cloneString(hel->name);
+	    if (endsWith(hel->name, "__filepath"))
+		param3 = cloneString(hel->name);
+	    }
+	if (!param1)
+	    errAbort("missing __binary param");
+	if (!param2)
+	    errAbort("missing __filename param");
+	if (!param3)
+	    errAbort("missing __filepath param");
+
+	char *param1Value = cloneString(cartOptionalString(cart, param1));
+	char *param2Value = cloneString(cartOptionalString(cart, param2));
+	char *param3Value = cloneString(cartOptionalString(cart, param3));
+
+	char *backgroundProgress = NULL; 
+	prepBackGroundCall(&backgroundProgress, hgsExtractUploadPrefix);
+
+	extractUploadSessionCtData(
+	    param1, param1Value, 
+	    param2, param2Value, 
+	    param3, param3Value, 
+	    backgroundProgress);
+
+	exit(0);  // cannot return
+	}
+    else
+	{
+	passSubmittedBinaryAsTrashFile(extractUploadList);
+
+	launchForeAndBackGround("extractUploadSessionCtData");
+
+	exit(0);
+	}
+
+    }
+else if (doUploadList)
+    {
+    if (sameOk(backgroundExec,"doUploadSessionCtData"))
+	{
+	// only one, not a list.
+	struct hashEl *hel = doUploadList;
+	char *param1 = cloneString(hel->name);
+
+	char *backgroundProgress = NULL; 
+	prepBackGroundCall(&backgroundProgress, hgsDoUploadPrefix);
+
+	doUploadSessionCtData(param1, backgroundProgress);
+
+	exit(0);  // cannot return
+	}
+    else
+	{
+
+	launchForeAndBackGround("doUploadSessionCtData");
+
+	exit(0);
+	}
+
+    }
+else if (cartVarExists(cart, hgsDoMainPage) || cartVarExists(cart, hgsCancel))
     doMainPage(userName, NULL);
 else if (cartVarExists(cart, hgsDoNewSession))
     {
     char *message = doNewSession(userName);
     doMainPage(userName, message);
     }
 else if (cartVarExists(cart, hgsDoOtherUser))
     {
     char *message = doOtherUser(hgsDoOtherUser);
     doMainPage(userName, message);
     }
 else if (cartVarExists(cart, hgsDoSaveLocal))
     {
     doSaveLocal();
     }