00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #include <u/libu.h>
00015 #include <klone/utils.h>
00016 #ifdef HAVE_STRINGS
00017 #include <strings.h>
00018 #endif
00019
00034 int u_uri_normalize(char *path)
00035 {
00036 enum { SLASH = '/', BACKSLASH = '\\' };
00037 u_string_t *s = NULL;
00038 size_t len;
00039 char delim[2];
00040 char *pp, *tok, *src, *cs;
00041 int trsl = 0;
00042
00043 dbg_err_if(path == NULL);
00044
00045
00046 for(pp = path; *pp; ++pp)
00047 if(*pp == BACKSLASH)
00048 *pp = SLASH;
00049
00050
00051 dbg_err_if(path[0] != SLASH);
00052
00053 if(path[strlen(path)-1] == SLASH)
00054 trsl = 1;
00055
00056 dbg_err_if(u_snprintf(delim, sizeof(delim), "%c", SLASH));
00057
00058 dbg_err_if(u_string_create(NULL, 0, &s));
00059
00060
00061 dbg_err_if(u_string_reserve(s, strlen(path) + 1));
00062
00063
00064 for(src = path; (tok = strtok_r(src, delim, &pp)) != NULL; src = NULL)
00065 {
00066 if(!strcmp(tok, ""))
00067 continue;
00068 else if(!strcmp(tok, "."))
00069 continue;
00070 else if(!strcmp(tok, "..")) {
00071
00072 len = u_string_len(s);
00073 cs = u_string_c(s) + u_string_len(s) - 1;
00074 for(; len && *cs != SLASH; --len, --cs)
00075 continue;
00076
00077 dbg_err_if(u_string_set_length(s, (len ? --len : 0) ));
00078 } else {
00079 dbg_err_if(u_string_aprintf(s, "%c%s", SLASH, tok));
00080 }
00081 }
00082
00083 if(!u_string_len(s) || trsl)
00084 dbg_err_if(u_string_aprintf(s, "%c", SLASH));
00085
00086
00087 strcpy(path, u_string_c(s));
00088
00089 u_string_free(s);
00090
00091 return 0;
00092 err:
00093 if(s)
00094 u_string_free(s);
00095 return ~0;
00096 }
00097