Blame


1 3d7e9092 2003-10-14 devnull #include <u.h>
2 3d7e9092 2003-10-14 devnull #include <libc.h>
3 3d7e9092 2003-10-14 devnull
4 3d7e9092 2003-10-14 devnull /*
5 3d7e9092 2003-10-14 devnull * In place, rewrite name to compress multiple /, eliminate ., and process ..
6 3d7e9092 2003-10-14 devnull */
7 3d7e9092 2003-10-14 devnull #define SEP(x) ((x)=='/' || (x) == 0)
8 3d7e9092 2003-10-14 devnull char*
9 3d7e9092 2003-10-14 devnull cleanname(char *name)
10 3d7e9092 2003-10-14 devnull {
11 3d7e9092 2003-10-14 devnull char *p, *q, *dotdot;
12 3d7e9092 2003-10-14 devnull int rooted;
13 3d7e9092 2003-10-14 devnull
14 3d7e9092 2003-10-14 devnull rooted = name[0] == '/';
15 3d7e9092 2003-10-14 devnull
16 3d7e9092 2003-10-14 devnull /*
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).
22 3d7e9092 2003-10-14 devnull */
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 */
26 3d7e9092 2003-10-14 devnull p++;
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])) {
30 3d7e9092 2003-10-14 devnull p += 2;
31 3d7e9092 2003-10-14 devnull if(q > dotdot) { /* can backtrack */
32 3d7e9092 2003-10-14 devnull while(--q > dotdot && *q != '/')
33 3d7e9092 2003-10-14 devnull ;
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;
40 3d7e9092 2003-10-14 devnull }
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++;
46 3d7e9092 2003-10-14 devnull }
47 3d7e9092 2003-10-14 devnull }
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;
52 3d7e9092 2003-10-14 devnull }