+ } else if (sp[0] == '.' && sp[1] == '.' && sp[2] == 0) {
+ char link[MAXPATHLEN];
+ int cc;
+ char *newcp;
+
+ /*
+ * We have something like "yyy/xxx/..", where "yyy"
+ * can be null or a path starting at /, and "xxx"
+ * is a single component.
+ * Before compressing "xxx/..", we want to expand
+ * "yyy/xxx", if it is a symbolic link.
+ */
+ *--sp = 0; /* form the pathname for readlink */
+ if (sp != cp &&
+ (cc = readlink(cp, link, sizeof link)) >= 0) {
+ link[cc] = '\0';
+ if (slash)
+ *p = '/';
+ /*
+ * Point p to the '/' in "/..", and restore
+ * the '/'.
+ */
+ *(p = sp) = '/';
+ /*
+ * find length of p
+ */
+ for (p1 = p; *p1++;)
+ ;
+ if (*link != '/') {
+ /*
+ * Relative path, expand it between
+ * the "yyy/" and the "/..".
+ * First, back sp up to the character
+ * past "yyy/".
+ */
+ while (*--sp != '/')
+ ;
+ sp++;
+ *sp = 0;
+ /*
+ * New length is
+ * "yyy/" + link + "/.." and rest
+ */
+ p1 = newcp = xalloc((unsigned)
+ ((sp - cp) + cc + (p1 - p)));
+ /*
+ * Copy new path into newcp
+ */
+ for (p2 = cp; *p1++ = *p2++;)
+ ;
+ for (p1--, p2 = link; *p1++ = *p2++;)
+ ;
+ for (p1--, p2 = p; *p1++ = *p2++;)
+ ;
+ /*
+ * Restart canonicalization at
+ * expanded "/xxx".
+ */
+ p = sp - cp - 1 + newcp;
+ } else {
+ /*
+ * New length is link + "/.." and rest
+ */
+ p1 = newcp = xalloc((unsigned)
+ (cc + (p1 - p)));
+ /*
+ * Copy new path into newcp
+ */
+ for (p2 = link; *p1++ = *p2++;)
+ ;
+ for (p1--, p2 = p; *p1++ = *p2++;)
+ ;
+ /*
+ * Restart canonicalization at beginning
+ */
+ p = newcp;
+ }
+ xfree(cp);
+ cp = newcp;
+ continue; /* canonicalize the link */
+ }
+ *sp = '/';
+ if (sp != cp)