logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/

relative_path.c (1109B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "./relative_path.h"
  6. #include <string.h>
  7. int
  8. relative_path(const char *base, const char *abs_file, char result[static PATH_MAX])
  9. {
  10. if(!base[0] || !abs_file[0]) return -1;
  11. int comm = 0;
  12. for(int i = 0; base[i] && abs_file[i]; i++)
  13. {
  14. if(base[i] != abs_file[i]) break;
  15. if(base[i] == '/') comm = i;
  16. }
  17. comm++;
  18. // both paths pointing to the same directory
  19. if(base[comm] == '\0' && abs_file[comm] == '\0')
  20. {
  21. result[0] = '.';
  22. result[1] = '\0';
  23. return 0;
  24. }
  25. size_t abs_rem = strlen(abs_file + comm);
  26. int off = 0;
  27. for(int i = comm; base[i]; i++)
  28. if(base[i] == '/') off++;
  29. // Make sure everything fits before copying into result
  30. if(((off * 3) + abs_rem + 1) > PATH_MAX) return -1;
  31. int res_pos = 0;
  32. for(int i = 0; i < off; i++)
  33. {
  34. memcpy(result + res_pos, "../", 3);
  35. res_pos += 3;
  36. }
  37. memcpy(result + res_pos, abs_file + comm, abs_rem + 1);
  38. return 0;
  39. }