simplify_path.c 1002 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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 = xgetcwd(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. } else if (*s == '.') {
  26. if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */
  27. continue;
  28. } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) {
  29. ++s;
  30. if (p > start) {
  31. while (*--p != '/'); /* omit previous dir */
  32. }
  33. continue;
  34. }
  35. }
  36. }
  37. *++p = *s;
  38. } while (*++s);
  39. if ((p == start) || (*p != '/')) { /* not a trailing slash */
  40. ++p; /* so keep last character */
  41. }
  42. *p = 0;
  43. return start;
  44. }