void showSymlinkType(char *submitFileName, char *submitDir)
/* Show symlink type */
{
struct stat sb;
char *lastPath = NULL;
char *path = cloneString(submitFileName);

// apply path to submitDir, giving an absolute path
char *newPath = expandRelativePath(submitDir, path);
verbose(3, "submitDir=[%s]\npath=[%s]\nnewPath=[%s]\n", submitDir, path, newPath);
if (!newPath)
    errAbort("Too many .. in path %s to make relative to submitDir %s\n", path, submitDir);
freeMem(path);
path = newPath;
struct dyString *dy = dyStringNew(256);
int symlinkLevels = 0;
boolean broken = FALSE;
while (TRUE)
    {
    dyStringPrintf(dy,"path=%s", path);
    if (lstat(path, &sb) == -1)
	{
	if (errno == ENOENT)
	    {
	    dyStringPrintf(dy," NOT FOUND");
	    broken = TRUE;
	    break;
	    }
	errnoAbort("lstat failure on %s", path);
	}
    if ((sb.st_mode & S_IFMT) == S_IFLNK)
	dyStringPrintf(dy," SYMLINK ");
    else if ((sb.st_mode & S_IFMT) == S_IFREG)
	dyStringPrintf(dy," FILE");
    else if ((sb.st_mode & S_IFMT) == S_IFDIR)
	dyStringPrintf(dy," DIR");
    else
	dyStringPrintf(dy," SPECIAL");
    if ((sb.st_mode & S_IFMT) != S_IFLNK)
	break;

    // follow the symlink
    ++symlinkLevels;
    if (symlinkLevels > 10)
	errAbort("Too many symlinks followed: %d symlinks. Probably a symlink loop.", symlinkLevels);

    // read the symlink
    ssize_t nbytes, bufsiz;
    // determine whether the buffer returned was truncated.
    bufsiz = sb.st_size + 1;
    char *symPath = needMem(bufsiz);
    nbytes = readlink(path, symPath, bufsiz);
    if (nbytes == -1) 
	errnoAbort("readlink failure on symlink %s", path);
    if (nbytes == bufsiz)
        errAbort("readlink returned buffer truncated\n");


    // apply symPath to path
    newPath = pathRelativeToFile(path, symPath);
    verbose(3, "path=%s\nsymPath=%s\nnewPath=%s\n", path, symPath, newPath);
    if (!newPath)
        errAbort("Too many .. in symlink path %s to make relative to %s\n", symPath, path);
    if (lastPath)
	freeMem(lastPath);
    lastPath = path;
    freeMem(symPath);
    path = newPath;
    }
if (symlinkLevels < 1)
    {
    errAbort("Too few symlinks followed: %d symlinks. dy=[%s]", symlinkLevels, dy->string);
    }
freeMem(path);

if (!(brokenOnly && !broken))
    printf("%s\n", dy->string);

dyStringFree(&dy);
}
예제 #2
0
char *htmlExpandUrl(char *base, char *url)
/* Expand URL that is relative to base to stand on its own. 
 * Return NULL if it's not http or https. */
{
struct dyString *dy = NULL;
char *hostName, *pastHostName;

/* some mailto: have SGML char encoding, e.g &#97; to hide from spambots */
url = cloneString(url);	/* Clone because asciiEntityDecode may modify it. */
asciiEntityDecode(url, url, strlen(url));

/* In easiest case URL is actually absolute and begins with
 * protocol.  Just return clone of url. */
if (startsWith("http:", url) || startsWith("https:", url))
    return url;

/* If it's got a colon, but no http or https, then it's some
 * protocol we don't understand, like a mailto.  Just return NULL. */
if (strchr(url, ':') != NULL)
    {
    freez(&url);
    return NULL;
    }

/* Figure out first character past host name. Load up
 * return string with protocol (if any) and host name. */
dy = dyStringNew(256);
if (startsWith("http:", base) || startsWith("https:", base))
    hostName = (strchr(base, ':') + 3);
else
    hostName = base;
pastHostName = strchr(hostName, '/');
if (pastHostName == NULL)
    pastHostName = hostName + strlen(hostName);
dyStringAppendN(dy, base, pastHostName - base);

/* Add url to return string after host name. */
if (startsWith("/", url))	/* New URL is absolute, just append to hostName */
    {
    dyStringAppend(dy, url);
    }
else
    {
    char *curDir = pastHostName;
    char *endDir;
    if (curDir[0] == '/')
        curDir += 1;
    dyStringAppendC(dy, '/');
    endDir = strrchr(curDir, '/');
    if (endDir == NULL)
	endDir = curDir;
    if (startsWith("../", url))
	{
	char *dir = cloneStringZ(curDir, endDir-curDir);
	char *path = expandRelativePath(dir, url);
	if (path != NULL)
	     {
	     dyStringAppend(dy, path);
	     }
	freez(&dir);
	freez(&path);
	}
    else
	{
	dyStringAppendN(dy, curDir, endDir-curDir);
	if (lastChar(dy->string) != '/')
	    dyStringAppendC(dy, '/');
	dyStringAppend(dy, url);
	}
    }
freez(&url);
return dyStringCannibalize(&dy);
}