eb2780907d717a7cf8e2a34cd79276512c3880dc
chmalee
  Fri May 2 11:59:49 2025 -0700
Oops when a user was uploading a hub.txt file to hubspace that was not named 'hub.txt', we were doing dumb stuff. Also fix more issues with the hubspace data dir being a symlink, refs #35384

diff --git src/hg/lib/userdata.c src/hg/lib/userdata.c
index fa31df42c1e..3823add7dac 100644
--- src/hg/lib/userdata.c
+++ src/hg/lib/userdata.c
@@ -42,42 +42,49 @@
 char *getDataDir(char *userName)
 /* Return the full path to the user specific data directory, can be configured via hg.conf
  * on hgwdev, this is /data/tusd */
 {
 char *tusdDataBaseDir = cfgOption("tusdDataDir");
 if (!tusdDataBaseDir  || isEmpty(tusdDataBaseDir))
     errAbort("trying to save user file but no tusdDataDir defined in hg.conf");
 if (tusdDataBaseDir[0] != '/')
     errAbort("config setting tusdDataDir must be an absolute path (starting with '/')");
 
 char *encUserName = cgiEncode(userName);
 char *userPrefix = md5HexForString(encUserName);
 userPrefix[2] = '\0';
 
 struct dyString *newDataDir = dyStringNew(0);
-dyStringPrintf(newDataDir, "%s/%s/%s/", 
+dyStringPrintf(newDataDir, "%s/%s/%s",
     tusdDataBaseDir, userPrefix, encUserName);
 
+char *canonicalPath = needMem(PATH_MAX);
+realpath(dyStringContents(newDataDir), canonicalPath);
+// now that we have canonicalized the path we need to add a '/' back on
+// so the rest of the routines can append to this result
+
+dyStringClear(newDataDir);
+dyStringPrintf(newDataDir, "%s/", canonicalPath);
 return dyStringCannibalize(&newDataDir);
 }
 
 char *stripDataDir(char *fname, char *userName)
 /* Strips the getDataDir(userName) off of fname. The dataDir may be a symbolic
  * link, we will resolve it here. NOTE that this relies on
  * calling realpath(3) on the fname argument prior to calling stripDataDir() */
 {
-char *dataDir = realpath(getDataDir(userName), NULL);
+char *dataDir = getDataDir(userName);
 if (!dataDir)
     {
     // catch a realpath error
     return NULL;
     }
 int prefixSize = strlen(dataDir);
 if (startsWith(dataDir, fname))
     {
     char *ret = fname + prefixSize;
     return ret;
     }
 return NULL;
 }
 
 char *getHubDataDir(char *userName, char *hub)