Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

path.c

00001 /*
00002  * Copyright (c) 2005, 2006, 2007 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: path.c,v 1.3 2007/10/26 10:01:09 tat Exp $
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; /* trailing slash */
00042 
00043     dbg_err_if(path == NULL);
00044 
00045     /* convert backslashes to slashes */
00046     for(pp = path; *pp; ++pp)
00047         if(*pp == BACKSLASH)
00048             *pp = SLASH;
00049 
00050     /* must be an absolute path (i.e. must start with a slash) */
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     /* alloc a reasonable buffer immediately */
00061     dbg_err_if(u_string_reserve(s, strlen(path) + 1));
00062 
00063     /* foreach name=value pair... */
00064     for(src = path; (tok = strtok_r(src, delim, &pp)) != NULL; src = NULL)
00065     {
00066         if(!strcmp(tok, ""))
00067             continue; /* double slash */
00068         else if(!strcmp(tok, "."))
00069             continue; /* /./ */
00070         else if(!strcmp(tok, "..")) {
00071             /* eat last dir */
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             /* crop */
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     /* copy out */
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