/*
 *  realpathWrapper.c
 *  
 *
 *  Created by Steven J Abner on Fri Apr 30 2004.
 *  Copyright (c) 2004. Any and All may use.
 *  No implied warranties.
 *
 *  Special notes:
 *	DO NOT USE other than in TclpObjNormalizePath
 *	this does not check if resolvedname exists
 *	this does not check if resolvedname correct size
 *
 *  #define Realpath realpathWrapper
 */

char *
realpathWrapper(const char *pathname, char *resolvedname) {
    int idx = 0;
    char *retVal = NULL;
    findPath(pathname, &retVal, &idx);
    if (errno) {
    /*
     * code to adjust offending separator to end
     * of path word
     */
        int rdex = idx;
        int rvallen = strlen(retVal);
        // move to next separator and terniated
        do { rdex++; }
        while (retVal[rdex] != '/' && rdex < rvallen);
        if (rdex == rvallen)
            retVal[idx] = 0;
        else
            retVal[rdex] = 0;
        goto finishup;
    }
    /*
     * code to check last word of path for links
     */
    idx = strlen(retVal);
    while (idx > 0 && retVal[idx] != '/') idx--;
    /* needed for root links */
    if (idx != 0)
        idx = strlen(retVal);
    else
        idx++;
    {
        struct stat curStatBuf;
        lstat(retVal, &curStatBuf);
        if (S_ISLNK(curStatBuf.st_mode)) {
            int normPathLen, pBdex;
            
            normPathLen = readlink(retVal, (&retVal[idx]), (2*MAXPATHLEN - idx));
            retVal[idx + normPathLen] = 0;
            if (retVal[idx] == '/') {
                pBdex = 0;
                do { retVal[pBdex] = retVal[idx]; pBdex++; idx++; }
                while (--normPathLen > 0);
            } else {
                pBdex = idx + normPathLen;
            }
            retVal[pBdex] = 0;
            idx = strlen(retVal);
        }
        if (errno == ENOENT)
            errno = 0;
    }
finishup:
    idx = strlen(retVal);
    if (idx >= MAXPATHLEN) {
        errno = ENAMETOOLONG;
        free(retVal);
        resolvedname = "";
        return NULL;
    }
    memcpy(resolvedname, retVal, (unsigned)(idx + 1));
    free(retVal);
    if (errno) 
        return NULL;
    return resolvedname;
}
