- if ((cp = expath(name, type)) &&
- (ep = cp+strlen(cp)-1) > cp &&
- *ep == '/') {
- *ep = '\0';
+ for (cp=f; *cp; ) {
+ if (*cp != '/') {
+ /* Skip. Interesting places are only after slashes. */
+ /* We don't care about "./" beginnings */
+ cp++;
+ continue;
+ }
+
+ /* Let's see what follows the slash ... */
+ switch (*++cp) {
+ case '\0':
+ *--cp = '\0';
+ continue; /* ... and thus exit the loop */
+
+ case '/':
+ /* reduce subsequent slashes to one */
+ for (dp = cp; *dp == '/'; dp++) {
+ continue;
+ }
+ strcpy(cp, dp);
+ cp--;
+ continue; /* ... at the slash */
+
+ case '.':
+ if (cp[1] == '/' || cp[1] == '\0') {
+ /* one-dot element */
+ strcpy(cp-1, cp+1);
+ cp--;
+ continue;
+ } else if ((strncmp(cp, "../", 3) == 0) ||
+ (strcmp(cp, "..") == 0)) {
+ /* dot-dot element */
+ /* crop out previous path element */
+ for (dp=cp-2; dp>f && *dp!='/'; dp--) {
+ continue;
+ }
+ if (dp < f) {
+ /* path starts with "/.." */
+ dp = f;
+ }
+ strcpy(dp, cp+2);
+ cp = dp;
+ continue;
+ } else {
+ /* a normal hidden file */
+ cp++;
+ continue;
+ }
+
+ default:
+ /* nothing special */
+ cp++;
+ continue;
+ }