00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00031 #include <assert.h>
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <global.h>
00035
00036 #include "define.h"
00037 #include "path.h"
00038
00039 #if 0
00040
00043 #define DEBUG_PATH
00044 #endif
00045
00063 char *path_combine(const char *src, const char *dst, char *path, size_t size) {
00064 char *p;
00065
00066 if (*dst == '/') {
00067
00068 snprintf(path, size, "%s", dst);
00069 } else {
00070
00071 snprintf(path, size, "%s", src);
00072 p = strrchr(path, '/');
00073 if (p != NULL) {
00074 p++;
00075 } else {
00076 p = path;
00077 if (*src == '/')
00078 *p++ = '/';
00079 }
00080 snprintf(p, size-(p-path), "%s", dst);
00081 }
00082
00083 #if defined(DEBUG_PATH)
00084 LOG(llevDebug, "path_combine(%s, %s) = %s\n", src, dst, path);
00085 #endif
00086 return(path);
00087 }
00088
00097 void path_normalize(char *path) {
00098 char *p;
00099
00100 char *q;
00101 char *w;
00102
00103 size_t len;
00104
00105 #if defined(DEBUG_PATH)
00106 LOG(llevDebug, "path_normalize: input '%s'\n", path);
00107 #endif
00108
00109 p = path;
00110 w = p;
00111 while (*p != '\0') {
00112 if (*p == '/') {
00113 if ((w == path && *path == '/') || (w > path && w[-1] != '/'))
00114 *w++ = '/';
00115 p++;
00116 continue;
00117 }
00118
00119 q = strchr(p, '/');
00120 if (q == NULL)
00121 q = p+strlen(p);
00122 len = q-p;
00123 assert(len > 0);
00124
00125 #if defined(DEBUG_PATH)
00126 LOG(llevDebug, "path_normalize: checking '%.*s'\n", (int)len, p);
00127 #endif
00128
00129 if (len == 1 && *p == '.') {
00130
00131 } else if (len == 2 && memcmp(p, "..", 2) == 0) {
00132 if (w == path || (w == path+3 && memcmp(path, "../", 3) == 0)) {
00133
00134 memmove(w, p, len);
00135 w += len;
00136 } else if (w == path+1 && *path == '/') {
00137
00138 } else {
00139
00140 if (w > path && w[-1] == '/')
00141 w--;
00142 while (w > path && w[-1] != '/')
00143 w--;
00144 }
00145 } else {
00146
00147 memmove(w, p, len);
00148 w += len;
00149 }
00150
00151 p = q;
00152
00153 #if defined(DEBUG_PATH)
00154 LOG(llevDebug, "path_normalize: so far '%.*s'\n", (int)(w-path), path);
00155 #endif
00156 }
00157
00158
00159 while (w > path+1 && w[-1] == '/') {
00160 w--;
00161 }
00162
00163 *w = '\0';
00164
00165 #if defined(DEBUG_PATH)
00166 LOG(llevDebug, "path_normalize: result '%s'\n", path);
00167 #endif
00168 }
00169
00184 char *path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size) {
00185 path_combine(src, dst, path, size);
00186 path_normalize(path);
00187 return(path);
00188 }