simplify_path.c 1.1 KB

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