Main Page | Modules | File List | 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.5 2008/03/18 22:48:51 tho Exp $
00009  */
00010 
00011 #include "klone_conf.h"
00012 #include <sys/stat.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <u/libu.h>
00016 #include <klone/emb.h>
00017 #include <klone/utils.h>
00018 #ifdef HAVE_STRINGS
00019 #include <strings.h>
00020 #endif
00021 
00036 int u_uri_normalize(char *path)
00037 {
00038     enum { SLASH = '/', BACKSLASH = '\\' };
00039     u_string_t *s = NULL;
00040     size_t len;
00041     char delim[2];
00042     char *pp, *tok, *src, *cs;
00043     int trsl = 0; /* trailing slash */
00044 
00045     dbg_err_if(path == NULL);
00046 
00047     /* convert backslashes to slashes */
00048     for(pp = path; *pp; ++pp)
00049         if(*pp == BACKSLASH)
00050             *pp = SLASH;
00051 
00052     /* must be an absolute path (i.e. must start with a slash) */
00053     dbg_err_if(path[0] != SLASH); 
00054 
00055     if(path[strlen(path)-1] == SLASH)
00056         trsl = 1;
00057 
00058     dbg_err_if(u_snprintf(delim, sizeof(delim), "%c", SLASH));
00059 
00060     dbg_err_if(u_string_create(NULL, 0, &s));
00061 
00062     /* alloc a reasonable buffer immediately */
00063     dbg_err_if(u_string_reserve(s, strlen(path) + 1));
00064 
00065     /* foreach name=value pair... */
00066     for(src = path; (tok = strtok_r(src, delim, &pp)) != NULL; src = NULL)
00067     {
00068         if(!strcmp(tok, ""))
00069             continue; /* double slash */
00070         else if(!strcmp(tok, "."))
00071             continue; /* /./ */
00072         else if(!strcmp(tok, "..")) {
00073             /* eat last dir */
00074             len = u_string_len(s);
00075             cs = u_string_c(s) + u_string_len(s) - 1;
00076             for(; len && *cs != SLASH; --len, --cs)
00077                 continue;
00078             /* crop */
00079             dbg_err_if(u_string_set_length(s, (len ? --len : 0) ));
00080         } else {
00081             dbg_err_if(u_string_aprintf(s, "%c%s", SLASH, tok));
00082         }
00083     }
00084 
00085     if(!u_string_len(s) || trsl)
00086         dbg_err_if(u_string_aprintf(s, "%c", SLASH));
00087 
00088     /* copy out */
00089     strcpy(path, u_string_c(s));
00090 
00091     u_string_free(s);
00092 
00093     return 0;
00094 err:
00095     if(s)
00096         u_string_free(s);
00097     return ~0;
00098 }
00099 
00109 int u_path_where_art_thou (const char *fqn, int *where)
00110 {
00111     struct stat sb;
00112     embres_t *dummy;
00113 
00114     dbg_return_if (fqn == NULL, ~0);
00115     dbg_return_if (where == NULL, ~0);
00116 
00117     /* check embfs first */
00118     if (emb_lookup(fqn, &dummy) == 0)
00119     {
00120         *where = U_PATH_IN_EMBFS;
00121         return 0;
00122     }
00123 
00124     /* then the file system */
00125     if (stat(fqn, &sb) == 0)
00126     {
00127         *where = U_PATH_IN_FS;
00128         return 0;
00129     }
00130 
00131     /* then give up */
00132     *where = U_PATH_NOT_FOUND;
00133 
00134     return 0;
00135 }