simplify_path.c 1023 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  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 *bb_simplify_path(const char *path)
  11. {
  12. char *s, *start, *p;
  13. if (path[0] == '/')
  14. start = xstrdup(path);
  15. else {
  16. s = xrealloc_getcwd_or_warn(NULL);
  17. start = concat_path_file(s, path);
  18. free(s);
  19. }
  20. p = s = start;
  21. do {
  22. if (*p == '/') {
  23. if (*s == '/') { /* skip duplicate (or initial) slash */
  24. continue;
  25. }
  26. if (*s == '.') {
  27. if (s[1] == '/' || !s[1]) { /* remove extra '.' */
  28. continue;
  29. }
  30. if ((s[1] == '.') && (s[2] == '/' || !s[2])) {
  31. ++s;
  32. if (p > start) {
  33. while (*--p != '/') /* omit previous dir */
  34. continue;
  35. }
  36. continue;
  37. }
  38. }
  39. }
  40. *++p = *s;
  41. } while (*++s);
  42. if ((p == start) || (*p != '/')) { /* not a trailing slash */
  43. ++p; /* so keep last character */
  44. }
  45. *p = 0;
  46. return start;
  47. }