[go: up one dir, main page]

File: abspath.c

package info (click to toggle)
rdup 1.1.11-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,324 kB
  • sloc: ansic: 3,840; sh: 3,361; exp: 271; makefile: 78; ruby: 36; perl: 4
file content (76 lines) | stat: -rw-r--r-- 1,597 bytes parent folder | download | duplicates (2)
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;
}