forked from miekg/rdup
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathabspath.c
76 lines (69 loc) · 1.56 KB
/
abspath.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "rdup.h"
/*
* Remove /./ and /../ and // from a pathname
* An absolute pathname argument is required.
* Returns NULL on error, otherwise NULL terminated
* sanitized pathname.
*
* Also see realpath(3)
*/
char * abspath(char *path)
{
char *p, *c;
char *slash, *abspath2;
char *abspath;
int i;
if (!path)
return NULL;
if (!g_path_is_absolute(path))
return NULL;
/* abspath can be NULL or abspath[0] == '\0'. The NULL
* is initial. the [0] == '\0' is when we got back to
* the root
*/
abspath = NULL;
abspath2 = g_strdup(path);
i = strlen(abspath2);
if (i > BUFSIZE)
return NULL;
/* add closing / (guard) */
if (abspath2[i - 1] != '/') {
abspath2 = g_realloc(abspath2, i + 2);
abspath2[i] = '/';
abspath2[i + 1] = '\0';
}
/* jump from slash to slash */
for (p = abspath2; (c = strchr(p, '/')); p++) {
*c = '\0';
if (*p == '\0' || (strcmp(p, ".") == 0)) {
/* do nothing */
p = c;
} else if (strcmp(p, "..") == 0) {
/* go back a slash */
if (abspath == NULL || abspath[0] == '\0') {
abspath = g_strdup("/");
} else {
slash = strrchr(abspath, '/');
*slash = '\0';
*c = '/';
}
} else {
if (abspath == NULL || abspath[0] == '\0' ||
(strcmp(abspath, "/") == 0) ) {
g_free(abspath);
abspath = g_strconcat("/", p, NULL);
} else {
gchar* tmp = g_strdup(abspath);
g_free(abspath);
abspath = g_strjoin("/", tmp, p, NULL);
g_free(tmp);
}
*c = '/';
}
p = c;
}
if (abspath == NULL || abspath[0] == '\0')
abspath = g_strdup("/");
g_free(abspath2);
return abspath;
}