summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fileops.c6
-rw-r--r--src/fileops.h2
-rw-r--r--src/repository.c75
3 files changed, 80 insertions, 3 deletions
diff --git a/src/fileops.c b/src/fileops.c
index c407515f1..56bf2927f 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -334,7 +334,7 @@ int gitfo_dirent(
return GIT_SUCCESS;
}
-static void posixify_path(char *path)
+void gitfo_posixify_path(char *path)
{
#if GIT_PLATFORM_PATH_SEP != '/'
while (*path) {
@@ -456,7 +456,7 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path, con
return git__throw(GIT_EOVERFLOW, "Failed to prettify dir path: the base path is too long for the buffer.");
strcpy(buffer_out, base_path);
- posixify_path(buffer_out);
+ gitfo_posixify_path(buffer_out);
git__joinpath(buffer_out, buffer_out, "");
}
@@ -587,7 +587,7 @@ int gitfo_getcwd(char *buffer_out, size_t size)
if (cwd_buffer == NULL)
return git__throw(GIT_EOSERR, "Failed to retrieve current working directory");
- posixify_path(buffer_out);
+ gitfo_posixify_path(buffer_out);
git__joinpath(buffer_out, buffer_out, ""); //Ensure the path ends with a trailing slash
diff --git a/src/fileops.h b/src/fileops.h
index 23f16542b..4a86e1c63 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -198,6 +198,8 @@ int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path, con
*/
int gitfo_prettify_file_path(char *buffer_out, size_t size, const char *path, const char *base_path);
+void gitfo_posixify_path(char *path);
+
int gitfo_retrieve_path_root_offset(const char *path);
#endif /* INCLUDE_fileops_h__ */
diff --git a/src/repository.c b/src/repository.c
index 76042c214..59d1b80c6 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -299,6 +299,81 @@ cleanup:
return git__rethrow(error, "Failed to open repository");
}
+static int abspath(char *buffer_out, size_t size, const char *path)
+{
+ assert(buffer_out && size >= GIT_PATH_MAX);
+
+ #ifdef GIT_WIN32
+ if (_fullpath(buffer_out, path, size) == NULL)
+ return git__throw(GIT_EOSERR, "Failed to retrieve real path: %s causing errors", buffer_out);
+ #else
+ if (realpath(path, buffer_out) == NULL)
+ return git__throw(GIT_EOSERR, "Failed to retrieve real path: %s causing errors", buffer_out);
+ #endif
+
+ gitfo_posixify_path(buffer_out);
+
+ return GIT_SUCCESS;
+}
+
+static dev_t retrieve_device(dev_t *device_out, const char *path)
+{
+ struct stat path_info;
+
+ assert(device_out);
+
+ if (gitfo_stat(path, &path_info))
+ return git__throw(GIT_EOSERR, "Failed to get file informations: %s", path);
+
+ *device_out = path_info.st_dev;
+
+ return GIT_SUCCESS;
+}
+
+static int retrieve_ceiling_directories_offset(const char *path, const char *ceiling_directories)
+{
+ char buf[GIT_PATH_MAX + 1];
+ char buf2[GIT_PATH_MAX + 1];
+ const char *ceil, *sep;
+ int len, max_len = -1;
+ int min_len;
+
+ assert(path);
+
+ min_len = gitfo_retrieve_path_root_offset(path) + 1;
+
+ if (ceiling_directories == NULL || min_len == 0)
+ return min_len;
+
+ for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
+ for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
+ len = sep - ceil;
+
+ if (len == 0 || len > GIT_PATH_MAX || gitfo_retrieve_path_root_offset(ceil) == -1)
+ continue;
+
+ strncpy(buf, ceil, len);
+ buf[len] = '\0';
+
+ gitfo_posixify_path(buf);
+ if (gitfo_prettify_dir_path(buf2, sizeof(buf2), buf, NULL) < GIT_SUCCESS)
+ continue;
+
+ len = strlen(buf2);
+ if (len > 0 && buf2[len-1] == '/')
+ buf[--len] = '\0';
+
+ if (!strncmp(path, buf2, len) &&
+ path[len] == '/' &&
+ len > max_len)
+ {
+ max_len = len;
+ }
+ }
+
+ return max_len <= min_len ? min_len : max_len;
+}
+
void git_repository_free(git_repository *repo)
{
if (repo == NULL)