libidav/utils.c

changeset 611
a7c48e0dca88
parent 609
dc3d70848c7c
child 624
27985062cd2c
--- a/libidav/utils.c	Fri Aug 02 21:40:05 2019 +0200
+++ b/libidav/utils.c	Fri Aug 02 22:04:00 2019 +0200
@@ -41,9 +41,13 @@
 #ifdef _WIN32
 #include <conio.h>
 #define getpasswordchar() getch()
+#define IS_PATH_SEPARATOR(c) (c == '/' || c == '\\')
+#define PATH_SEPARATOR '\\'
 #else
 #include <termios.h>
 #define getpasswordchar() getchar()
+#define IS_PATH_SEPARATOR(c) (c == '/')
+#define PATH_SEPARATOR '/'
 #endif
 
 #include "webdav.h"
@@ -377,10 +381,10 @@
     scstr_t p1 = scstr(path1);
     scstr_t p2 = scstr(path2);
     
-    if(p1.ptr[p1.length-1] == '/') {
+    if(IS_PATH_SEPARATOR(p1.ptr[p1.length-1])) {
         p1.length--;
     }
-    if(p2.ptr[p2.length-1] == '/') {
+    if(IS_PATH_SEPARATOR(p2.ptr[p2.length-1])) {
         p2.length--;
     }
     
@@ -393,7 +397,7 @@
     }
     
     if(sstrprefix(p2, p1)) {
-        if(p2.ptr[p1.length] == '/') {
+        if(IS_PATH_SEPARATOR(p2.ptr[p1.length])) {
             return 1;
         }
     }
@@ -401,6 +405,29 @@
     return 0;
 }
 
+#ifdef _WIN32
+int util_path_isabsolut(const char *path) {
+    if(strlen(path) < 3) {
+        return 0;
+    }
+    
+    // check if first char is A-Z or a-z
+    char c = path[0];
+    if(!((c >= 65 && c <= 90) || (c >= 97 && c <= 122))) {
+        return 0;
+    }
+    
+    if(path[1] == ':' && path[2] == '\\') {
+        return 1;
+    }
+    return 0;
+}
+#else
+int util_path_isabsolut(const char *path) {
+    return path[0] == '/';
+}
+#endif
+
 char* util_path_normalize(const char *path) {
     size_t len = strlen(path);
     UcxBuffer *buf = ucx_buffer_new(NULL, len+1, UCX_BUFFER_AUTOEXTEND);
@@ -413,10 +440,10 @@
     int seg_start = 0;
     for(int i=0;i<=len;i++) {
         char c = path[i];
-        if(c == '/' || c == '\0') {
+        if(IS_PATH_SEPARATOR(c) || c == '\0') {
             const char *seg_ptr = path+seg_start;
             int seg_len = i - seg_start;
-            if(seg_ptr[0] == '/') {
+            if(IS_PATH_SEPARATOR(seg_ptr[0])) {
                 seg_ptr++;
                 seg_len--;
             }
@@ -426,11 +453,11 @@
                 if(!sstrcmp(seg, SC(".."))) {
                     for(int j=buf->pos;j>=0;j--) {
                         char t = buf->space[j];
-                        if(t == '/' || j == 0) {
+                        if(IS_PATH_SEPARATOR(t) || j == 0) {
                             buf->pos = j;
                             buf->size = j;
                             buf->space[j] = 0;
-                            add_separator = t == '/' ? 1 : 0;
+                            add_separator = IS_PATH_SEPARATOR(t) ? 1 : 0;
                             break;
                         }
                     }
@@ -438,7 +465,7 @@
                     // ignore
                 } else {
                     if(add_separator) {
-                        ucx_buffer_putc(buf, '/');
+                        ucx_buffer_putc(buf, PATH_SEPARATOR);
                     }
                     ucx_buffer_write(seg_ptr, 1, seg_len, buf);
                     add_separator = 1;
@@ -458,19 +485,19 @@
     return space;
 }
 
-char* util_create_relative_path(const char *abspath, const char *base) {
+static char* create_relative_path(const char *abspath, const char *base) {
     size_t path_len = strlen(abspath);
     size_t base_len = strlen(base);
     
-    if(abspath[path_len-1] == '/') {
+    if(IS_PATH_SEPARATOR(abspath[path_len-1])) {
         path_len--;
     }
-    if(base[base_len-1] == '/') {
+    if(IS_PATH_SEPARATOR(base[base_len-1])) {
         base_len--;
     }
     // get base parent
     for(int i=base_len-1;i>=0;i--) {
-        if(base[i] == '/') {
+        if(IS_PATH_SEPARATOR(base[i])) {
             base_len = i+1;
             break;
         }
@@ -486,7 +513,7 @@
         char c = abspath[i];
         if(c != base[i]) {
             break;
-        } else if(c == '/') {
+        } else if(IS_PATH_SEPARATOR(c)) {
             last_dir = i;
         }
     }
@@ -497,7 +524,7 @@
         // base is deeper than the link root, we have to go backwards
         int dircount = 0;
         for(int i=last_dir+1;i<base_len;i++) {
-            if(base[i] == '/') {
+            if(IS_PATH_SEPARATOR(base[i])) {
                 dircount++;
             }
         }
@@ -520,6 +547,35 @@
     return ret;
 }
 
+#ifdef _WIN32
+char* util_create_relative_path(const char *abspath, const char *base) {
+    char *abspath_converted = strdup(abspath);
+    char *base_converted = strdup(base);
+    size_t abs_len = strlen(abspath_converted);
+    size_t base_len = strlen(base_converted);
+    
+    for(int i=0;i<abs_len;i++) {
+        if(abspath_converted[i] == '\\') {
+            abspath_converted[i] = '/';
+        }
+    }
+    for(int i=0;i<base_len;i++) {
+        if(base_converted[i] == '\\') {
+            base_converted[i] = '/';
+        }
+    }
+    
+    char *ret = create_relative_path(abspath_converted, base_converted);
+    free(abspath_converted);
+    free(base_converted);
+    return ret;
+}
+#else
+char* util_create_relative_path(const char *abspath, const char *base) {
+    return create_relative_path(abspath, base);
+}
+#endif
+
 
 void util_capture_header(CURL *handle, UcxMap* map) {
     if(map) {

mercurial