1 2 /*-------------------------------------------------------------*/ 3 /*************************************************************** 4 * Under Windows, '/' and '\' are recognized as directory * 5 * separator. However, under Unix, only '/' is valid. * 6 * So, if you want your code to be portable, use '/'. * 7 ***************************************************************/ 8 9 /*-------------------------------------------------------------*/ 10 /* Name : netwib_path_canon 11 Description : 12 Clean a filename ("//"->"/", "/./"->"/", "/aa/../"->"/", etc.). 13 Input parameter(s) : 14 pathname : filename (ex : "/tmp/dir/..//./file") 15 Input/output parameter(s) : 16 Output parameter(s) : 17 *pcanonizedpathname : cleaned filename (ex : "/tmp/file") 18 Normal return values : 19 NETWIB_ERR_OK : ok 20 Examples of canonical paths : 21 file dir dir/file dir/dir 22 /file /dir /dir/file /dir/dir 23 ../file ../dir ../dir/file ../dir/dir 24 / . .. 25 Windows using a drive letter : 26 c:file c:dir c:dir/file c:dir/dir 27 c:/file c:/dir c:/dir/file c:/dir/dir 28 c:../file c:../dir c:../dir/file c:../dir/dir 29 c:/ c: c:.. 30 Windows using a smb or cifs share : 31 //server/share/ 32 //s/sh/file //s/sh/dir //s/sh/dir/file //s/sh/dir/dir 33 Note : a Window share is very similar to an absolute path 34 with two leading '/'. To ensure they are not mixed, 35 you have to ensure an absolute path does not start 36 with '//'. 37 */ 38 netwib_err netwib_path_canon(netwib_constbuf *ppathname, 39 netwib_buf *pcanonizedpathname); 40 41 /*-------------------------------------------------------------*/ 42 /*************************************************************** 43 * netwib functions : * 44 * - always work with : * 45 * + canonized path * 46 * - generally work with : * 47 * + relative path with leading "./" * 48 * + "c:." instead of "c:" (only under Windows) * 49 * + path with "\" instead of "/" (only under Windows) * 50 * - might work with : * 51 * + directory name ending with "/" (not under Windows) * 52 * + path such as "/dir/../dir2/file" * 53 * * 54 * So, user should canonize paths before using netwib * 55 * functions. However, functions in this module accept * 56 * un-canonized paths and produce canonized paths. So, * 57 * functions in this module are safe for use. * 58 ***************************************************************/ 59 60 /*-------------------------------------------------------------*/ 61 /*************************************************************** 62 * Empty string ("") is not a valid path. If functions of this * 63 * module have an empty parameter, error * 64 * NETWIB_ERR_PAPATHNOTCANON occurs. * 65 ***************************************************************/ 66 67 /*-------------------------------------------------------------*/ 68 /* Name : netwib_pathtype_init 69 Description : 70 Obtain type of a path. 71 Input parameter(s) : 72 *ppathname : pathname to obtain info for (do not need to be canonized). 73 Input/output parameter(s) : 74 Output parameter(s) : 75 *ppathtype : type as a bitfield 76 Normal return values : 77 NETWIB_ERR_OK : ok 78 Examples : 79 pathname absolute root unix windrive winshare 80 file 0=no 0 1 0 0 81 /file 1=yes 0 1 0 0 82 ../file 0 0 1 0 0 83 / 1 1 1 0 0 84 . 0 0 1 0 0 85 .. 0 0 1 0 0 86 c:file 0 0 0 1 0 87 c:/file 1 0 0 1 0 88 c:../file 0 0 0 1 0 89 c:/ 1 1 0 1 0 90 c: 0 0 0 1 0 91 c:.. 0 0 0 1 0 92 //s/sh/file 1 0 0 0 1 93 //s/sh/ 1 1 0 0 1 94 */ 95 #define NETWIB_PATHTYPE_ABSOLUTE 0x01 /* absolute: path is fully specified */ 96 #define NETWIB_PATHTYPE_ROOT 0x02 /* root: can't go up */ 97 #define NETWIB_PATHTYPE_UNIX 0x04 /* unix (or windows simple path) */ 98 #define NETWIB_PATHTYPE_WINDRIVE 0x08 /* windows drive: c:, d: */ 99 #define NETWIB_PATHTYPE_WINSHARE 0x10 /* windows smb share: //server/share/ */ 100 typedef netwib_uint32 netwib_pathtype; 101 netwib_err netwib_pathtype_init(netwib_constbuf *ppathname, 102 netwib_pathtype *ppathtype); 103 104 /*-------------------------------------------------------------*/ 105 /* Name : netwib_path_decode_xyz 106 Description : 107 Separate a path. 108 Input parameter(s) : 109 ppathname : filename (ex : "/tmp/file") (do not need to be canonized) 110 Input/output parameter(s) : 111 type : type of information to extract 112 Output parameter(s) : 113 *pout : output buffer (canonized, even if ppathname is not) 114 Normal return values : 115 NETWIB_ERR_OK : ok 116 Examples : 117 pathname begin core parent child 118 file . file . file 119 d/f . d/f d f 120 /file / /file / file 121 /d/f / /d/f /d f 122 ../file . ../file .. file 123 ../d/f . ../d/f ../d f 124 / / / Error1 / 125 . . . .. . 126 .. . .. ../.. .. 127 c:file c: file c: file 128 c:d/f c: d/f c:d f 129 c:/file c:/ /file c:/ file 130 c:/d/f c:/ /d/f c:/d f 131 c:../file c: ../file c:.. file 132 c:../d/f c: ../d/f c:../d f 133 c:/ c:/ / Error1 / 134 c: c: . c:.. . 135 c:.. c: .. c:../.. .. 136 //s/t/file //s/t/ /file //s/t/ file 137 //s/t/d/f //s/t/ /d/f //s/t/d f 138 //s/t/ //s/t/ / Error1 / 139 Errors are : 140 Error1 : NETWIB_ERR_PAPATHROOTDOTDOT 141 */ 142 typedef enum { 143 NETWIB_PATH_DECODETYPE_BEGIN = 1, /* root directory or . */ 144 NETWIB_PATH_DECODETYPE_CORE, /* path starting at begin */ 145 NETWIB_PATH_DECODETYPE_PARENT, /* parent directory */ 146 NETWIB_PATH_DECODETYPE_CHILD, /* last item */ 147 NETWIB_PATH_DECODETYPE_EXTENSION /* file extension without the dot 148 (empty if no extension) ; pout is 149 a netwib_bufext */ 150 /* note : pathname == begin+core or parent+child */ 151 } netwib_path_decodetype; 152 netwib_err netwib_path_decode(netwib_constbuf *ppathname, 153 netwib_path_decodetype type, 154 netwib_buf *pout); 155 #define netwib_path_decode_begin(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_BEGIN,pout) 156 #define netwib_path_decode_core(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_CORE,pout) 157 #define netwib_path_decode_parent(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_PARENT,pout) 158 #define netwib_path_decode_child(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_CHILD,pout) 159 #define netwib_path_decode_extension(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_EXTENSION,pout) 160 161 /*-------------------------------------------------------------*/ 162 /* Name : netwib_path_init_xyz 163 Description : 164 Initialize a path. 165 Input parameter(s) : 166 See below (do not need to be canonized) 167 Input/output parameter(s) : 168 pout : path initialized (canonized, even if input is not) 169 Output parameter(s) : 170 Normal return values : 171 NETWIB_ERR_OK : ok 172 */ 173 typedef enum { 174 NETWIB_PATH_INITTYPE_CONCAT = 1, 175 NETWIB_PATH_INITTYPE_JAIL, 176 NETWIB_PATH_INITTYPE_ABS, 177 NETWIB_PATH_INITTYPE_RELA, 178 NETWIB_PATH_INITTYPE_RELB, 179 } netwib_path_inittype; 180 /* 181 Definitions : 182 concat : path from the beginning of dirname1 to pathname2 183 [dirname1]-[pathname2] 184 X--------------------> 185 If pathname2 is absolute, an error occurs (except if 186 dirname1 is a root). 187 jail : same as concat except pathname2 is considered as an 188 absolute path inside dirname1. It's a kind of chroot 189 or jail with a rootdir of dirname1. Resulting filename 190 cannot escape from dirname1. 191 abs : absolute path to pathname2 (pathname2 is in a 192 file located in dirname1 directory) 193 root 194 [dirname1]-[pathname2] 195 X----------------------> 196 If pathname2 is absolute, result is pathname2. 197 If dirname1 is not absolute, an error occurs. 198 rela : relative path to go to pathname2 from a file 199 in dirname1 directory (pathname2 is in a 200 file located in dirname1 directory) 201 [dirname1]-[pathname2] 202 X-----------> 203 If pathname2 is relative, result is pathname2. 204 If pathname2 is absolute, dirname1 must be absolute. 205 relb : relative path to go to pathname2 from a file 206 in dirname1 directory (pathname1 and pathname2 207 are located in the same directory) 208 [dirname1] 209 [ pathname2 ] 210 X-----> 211 If pathname2 is absolute, dirname1 must be absolute. 212 If pathname2 is relative, dirname1 must be relative. 213 Examples of concat, jail and abs : 214 dirname1 pathname2 concat jail abs 215 d1 d2/f2 d1/d2/f2 d1/d2/f2 Error 216 d1 ../d2/f2 d2/f2 Error Error 217 d1 /d2/f2 Error d1/d2/f2 /d2/f2 218 ../d1 d2/f2 ../d1/d2/f2 ../d1/d2/f2 Error 219 ../d1 ../d2/f2 ../d2/f2 Error Error 220 ../d1 /d2/f2 Error ../d1/d2/f2 /d2/f2 221 /d1 d2/f2 /d1/d2/f2 /d1/d2/f2 /d1/d2/f2 222 /d1 ../d2/f2 /d2/f2 Error /d2/f2 223 /d1 /d2/f2 Error /d1/d2/f2 /d2/f2 224 isroot /d2/f2 x/d2/f2 x/d2/f2 /d2/f2 225 Examples of rela and relb : 226 dirname1 pathname2 rela relb 227 d1 d2/f2 d2/f2 ../d2/f2 228 d1 ../d2/f2 ../d2/f2 ../../d2/f2 229 d1 /d2/f2 Error Error 230 ../d1 d2/f2 d2/f2 Error 231 ../d1 ../d2/f2 ../d2/f2 ../d2/f2 232 ../d1 /d2/f2 Error Error 233 /d1 d2/f2 d2/f2 Error 234 /d1 ../d2/f2 ../d2/f2 Error 235 /d1 /d2/f2 ../d2/f2 ../d2/f2 236 d1 d1 d1 . (because pathname2 is like ...) 237 /d1 /d1 . . (dirname1, so it's a directory) 238 The errors have the code : NETWIB_ERR_PAPATHCANTINIT. 239 */ 240 netwib_err netwib_path_init(netwib_constbuf *pdirname1, 241 netwib_constbuf *ppathname2, 242 netwib_path_inittype type, 243 netwib_buf *pout); 244 #define netwib_path_init_concat(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_CONCAT,pout) 245 #define netwib_path_init_jail(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_JAIL,pout) 246 #define netwib_path_init_abs(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_ABS,pout) 247 #define netwib_path_init_rela(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_RELA,pout) 248 #define netwib_path_init_relb(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_RELB,pout) 249