1 3d7e9092 2003-10-14 devnull #include <u.h>
2 3d7e9092 2003-10-14 devnull #include <libc.h>
5 3d7e9092 2003-10-14 devnull * In place, rewrite name to compress multiple /, eliminate ., and process ..
7 3d7e9092 2003-10-14 devnull #define SEP(x) ((x)=='/' || (x) == 0)
9 3d7e9092 2003-10-14 devnull cleanname(char *name)
11 3d7e9092 2003-10-14 devnull char *p, *q, *dotdot;
12 3d7e9092 2003-10-14 devnull int rooted;
14 3d7e9092 2003-10-14 devnull rooted = name[0] == '/';
17 3d7e9092 2003-10-14 devnull * invariants:
18 3d7e9092 2003-10-14 devnull * p points at beginning of path element we're considering.
19 3d7e9092 2003-10-14 devnull * q points just past the last path element we wrote (no slash).
20 3d7e9092 2003-10-14 devnull * dotdot points just past the point where .. cannot backtrack
21 3d7e9092 2003-10-14 devnull * any further (no slash).
23 3d7e9092 2003-10-14 devnull p = q = dotdot = name+rooted;
24 3d7e9092 2003-10-14 devnull while(*p) {
25 3d7e9092 2003-10-14 devnull if(p[0] == '/') /* null element */
27 3d7e9092 2003-10-14 devnull else if(p[0] == '.' && SEP(p[1]))
28 3d7e9092 2003-10-14 devnull p += 1; /* don't count the separator in case it is nul */
29 3d7e9092 2003-10-14 devnull else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
31 3d7e9092 2003-10-14 devnull if(q > dotdot) { /* can backtrack */
32 3d7e9092 2003-10-14 devnull while(--q > dotdot && *q != '/')
34 3d7e9092 2003-10-14 devnull } else if(!rooted) { /* /.. is / but ./../ is .. */
35 3d7e9092 2003-10-14 devnull if(q != name)
36 3d7e9092 2003-10-14 devnull *q++ = '/';
37 3d7e9092 2003-10-14 devnull *q++ = '.';
38 3d7e9092 2003-10-14 devnull *q++ = '.';
39 3d7e9092 2003-10-14 devnull dotdot = q;
41 3d7e9092 2003-10-14 devnull } else { /* real path element */
42 3d7e9092 2003-10-14 devnull if(q != name+rooted)
43 3d7e9092 2003-10-14 devnull *q++ = '/';
44 3d7e9092 2003-10-14 devnull while((*q = *p) != '/' && *q != 0)
45 3d7e9092 2003-10-14 devnull p++, q++;
48 3d7e9092 2003-10-14 devnull if(q == name) /* empty string is really ``.'' */
49 3d7e9092 2003-10-14 devnull *q++ = '.';
50 3d7e9092 2003-10-14 devnull *q = '\0';
51 3d7e9092 2003-10-14 devnull return name;