/* * 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; }