Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | ||||
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 3 | * bb_simplify_path implementation for busybox |
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 4 | * |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 5 | * Copyright (C) 2001 Manuel Novoa III <mjn3@codepoet.org> |
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 6 | * |
"Robert P. J. Day" | 5d8843e | 2006-07-10 11:41:19 +0000 | [diff] [blame] | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 8 | */ |
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 9 | #include "libbb.h" |
10 | |||||
Denis Vlasenko | 1cf4a0e | 2009-04-22 13:49:16 +0000 | [diff] [blame] | 11 | char* FAST_FUNC bb_simplify_abs_path_inplace(char *start) |
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 12 | { |
Denis Vlasenko | 1cf4a0e | 2009-04-22 13:49:16 +0000 | [diff] [blame] | 13 | char *s, *p; |
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 14 | |
Matt Kraai | 0a68590 | 2001-08-14 17:10:08 +0000 | [diff] [blame] | 15 | p = s = start; |
Matt Kraai | 0a68590 | 2001-08-14 17:10:08 +0000 | [diff] [blame] | 16 | do { |
17 | if (*p == '/') { | ||||
18 | if (*s == '/') { /* skip duplicate (or initial) slash */ | ||||
19 | continue; | ||||
Denis Vlasenko | 16abcd9 | 2007-04-13 23:59:52 +0000 | [diff] [blame] | 20 | } |
21 | if (*s == '.') { | ||||
22 | if (s[1] == '/' || !s[1]) { /* remove extra '.' */ | ||||
Matt Kraai | 0a68590 | 2001-08-14 17:10:08 +0000 | [diff] [blame] | 23 | continue; |
Denis Vlasenko | 16abcd9 | 2007-04-13 23:59:52 +0000 | [diff] [blame] | 24 | } |
25 | if ((s[1] == '.') && (s[2] == '/' || !s[2])) { | ||||
Matt Kraai | 0a68590 | 2001-08-14 17:10:08 +0000 | [diff] [blame] | 26 | ++s; |
27 | if (p > start) { | ||||
Denis Vlasenko | 16abcd9 | 2007-04-13 23:59:52 +0000 | [diff] [blame] | 28 | while (*--p != '/') /* omit previous dir */ |
29 | continue; | ||||
Matt Kraai | 0a68590 | 2001-08-14 17:10:08 +0000 | [diff] [blame] | 30 | } |
31 | continue; | ||||
32 | } | ||||
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 33 | } |
34 | } | ||||
Matt Kraai | 0a68590 | 2001-08-14 17:10:08 +0000 | [diff] [blame] | 35 | *++p = *s; |
36 | } while (*++s); | ||||
37 | |||||
38 | if ((p == start) || (*p != '/')) { /* not a trailing slash */ | ||||
39 | ++p; /* so keep last character */ | ||||
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 40 | } |
Denis Vlasenko | 1cf4a0e | 2009-04-22 13:49:16 +0000 | [diff] [blame] | 41 | *p = '\0'; |
42 | return p; | ||||
43 | } | ||||
Matt Kraai | 0a68590 | 2001-08-14 17:10:08 +0000 | [diff] [blame] | 44 | |
Denis Vlasenko | 1cf4a0e | 2009-04-22 13:49:16 +0000 | [diff] [blame] | 45 | char* FAST_FUNC bb_simplify_path(const char *path) |
46 | { | ||||
47 | char *s, *p; | ||||
48 | |||||
49 | if (path[0] == '/') | ||||
50 | s = xstrdup(path); | ||||
51 | else { | ||||
52 | p = xrealloc_getcwd_or_warn(NULL); | ||||
53 | s = concat_path_file(p, path); | ||||
54 | free(p); | ||||
55 | } | ||||
56 | |||||
57 | bb_simplify_abs_path_inplace(s); | ||||
58 | return s; | ||||
Matt Kraai | a7cecbc | 2001-08-10 15:05:27 +0000 | [diff] [blame] | 59 | } |