static char * resolve_symlinks (const vfs_path_t * vpath) { char *p, *p2; char *buf, *buf2, *q, *r, c; struct stat mybuf; if (vpath->relative) return NULL; p = p2 = g_strdup (vfs_path_as_str (vpath)); r = buf = g_malloc (MC_MAXPATHLEN); buf2 = g_malloc (MC_MAXPATHLEN); *r++ = PATH_SEP; *r = 0; do { q = strchr (p + 1, PATH_SEP); if (!q) { q = strchr (p + 1, 0); if (q == p + 1) break; } c = *q; *q = 0; if (mc_lstat (vpath, &mybuf) < 0) { MC_PTR_FREE (buf); goto ret; } if (!S_ISLNK (mybuf.st_mode)) strcpy (r, p + 1); else { int len; len = mc_readlink (vpath, buf2, MC_MAXPATHLEN - 1); if (len < 0) { MC_PTR_FREE (buf); goto ret; } buf2[len] = 0; if (IS_PATH_SEP (*buf2)) strcpy (buf, buf2); else strcpy (r, buf2); } canonicalize_pathname (buf); r = strchr (buf, 0); if (*r == '\0' || !IS_PATH_SEP (r[-1])) /* FIXME: this condition is always true because r points to the EOL */ { *r++ = PATH_SEP; *r = '\0'; } *q = c; p = q; } while (c != '\0'); if (*buf == '\0') strcpy (buf, PATH_SEP_STR); else if (IS_PATH_SEP (r[-1]) && r != buf + 1) r[-1] = '\0'; ret: g_free (buf2); g_free (p2); return buf; }
static char * resolve_symlinks (const char *path) { char *buf, *buf2, *q, *r, c; int len; struct stat mybuf; const char *p; if (*path != PATH_SEP) return NULL; r = buf = g_malloc (MC_MAXPATHLEN); buf2 = g_malloc (MC_MAXPATHLEN); *r++ = PATH_SEP; *r = 0; p = path; for (;;) { q = strchr (p + 1, PATH_SEP); if (!q) { q = strchr (p + 1, 0); if (q == p + 1) break; } c = *q; *q = 0; if (mc_lstat (path, &mybuf) < 0) { g_free (buf); g_free (buf2); *q = c; return NULL; } if (!S_ISLNK (mybuf.st_mode)) strcpy (r, p + 1); else { len = mc_readlink (path, buf2, MC_MAXPATHLEN - 1); if (len < 0) { g_free (buf); g_free (buf2); *q = c; return NULL; } buf2[len] = 0; if (*buf2 == PATH_SEP) strcpy (buf, buf2); else strcpy (r, buf2); } canonicalize_pathname (buf); r = strchr (buf, 0); if (!*r || *(r - 1) != PATH_SEP) { *r++ = PATH_SEP; *r = 0; } *q = c; p = q; if (!c) break; } if (!*buf) strcpy (buf, PATH_SEP_STR); else if (*(r - 1) == PATH_SEP && r != buf + 1) *(r - 1) = 0; g_free (buf2); return buf; }