#line 4 "relative.c-nw" #include #include #include "uri.e" EXPORT void URL_expand(URI *uri, const URI base) { char *s, *p, *t, *h; int n, a, b, c, d; uri->tp = base.tp; if (uri->scheme) return; /* Not relative at all! */ uri->scheme = base.scheme; if (uri->host) return; /* Rest is not relative */ uri->user = base.user; uri->passw = base.passw; uri->host = base.host; uri->port = base.port; h = strip2str(uri->path); if (uri->path == NULL) { /* No relative path */ uri->path = base.path; } else if (h[0] != '/') { /* Doesn't start at root */ s = strip2str(base.path); p = strrchr(s, '/'); /* Last `/' in base */ if (p) { n = p - s; /* Length of directory part */ newarray(t, n + strlen(h) + 2); /* Room for new path */ strncpy(t, s, n); /* Copy directory */ t[n] = '/'; /* Add a slash */ strcpy(t + n + 1, h); /* Append the rel. path */ n = strlen(t); b = 0; assert(t[0] == '/'); while (t[b]) { /* Remove `.' directories */ for (c = b + 1; t[c] && t[c] != '/'; c++) ; if (c == b + 2 && t[b+1] == '.') { memmove(t + b, t + c, n - c + 1); n -= 2; } else b = c; } b = d = 0; while (t[b] == '/') { /* Remove `..' directories */ for (c = b + 1; t[c] && t[c] != '/'; c++) ; if (c == b + 3 && t[b+1] == '.' && t[b + 2] == '.') { for (a = b - 1; a >= d && t[a] != '/'; a--) ; if (a >= d) { memmove(t + a, t + c, n - c + 1); n -= c - a; b = a; } else { b = c; d = c; } } else b = c; } #if 0 /* Remove `.' directories */ for (i = n - 3; i > 0; i--) { if (n_eq(t + i, "/./", 3)) { memmove(t + i + 1, t + i + 3, n - i - 2); n -= 2; } } /* Remove `/.' at end */ if (n > 2 && n_eq(t + n - 2, "/.", 2)) { n -= 2; t[n] = '\0'; } /* Remove `..' directories */ for (i = n - 4; i > 0; i--) { if (n_eq(t + i, "/../", 4)) { for (j = i - 1; j != 0 && t[j] != '/'; j--) ; if (t[j] == '/') { memmove(t + j + 1, t + i + 4, n - i - 3); i = j + 1; n -= i - j + 3; } } } /* Remove `/..' at end */ if (n > 3 && n_eq(t + n - 3, "/..", 3)) { for (j = n - 4; j != 0 && t[j] != '/'; j--) ; if (t[j] == '/') { t[j] = '\0'; n = j; } } #endif uri->path = str2strip(t); dispose(t); } } }