relative_path.c (1109B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include "./relative_path.h"
- #include <string.h>
- int
- relative_path(const char *base, const char *abs_file, char result[static PATH_MAX])
- {
- if(!base[0] || !abs_file[0]) return -1;
- int comm = 0;
- for(int i = 0; base[i] && abs_file[i]; i++)
- {
- if(base[i] != abs_file[i]) break;
- if(base[i] == '/') comm = i;
- }
- comm++;
- // both paths pointing to the same directory
- if(base[comm] == '\0' && abs_file[comm] == '\0')
- {
- result[0] = '.';
- result[1] = '\0';
- return 0;
- }
- size_t abs_rem = strlen(abs_file + comm);
- int off = 0;
- for(int i = comm; base[i]; i++)
- if(base[i] == '/') off++;
- // Make sure everything fits before copying into result
- if(((off * 3) + abs_rem + 1) > PATH_MAX) return -1;
- int res_pos = 0;
- for(int i = 0; i < off; i++)
- {
- memcpy(result + res_pos, "../", 3);
- res_pos += 3;
- }
- memcpy(result + res_pos, abs_file + comm, abs_rem + 1);
- return 0;
- }