/*-------------------------------------------------------------*/
/***************************************************************
* Under Windows, '/' and '\' are recognized as directory *
* separator. However, under Unix, only '/' is valid. *
* So, if you want your code to be portable, use '/'. *
***************************************************************/
/*-------------------------------------------------------------*/
/* Name : netwib_path_canon
Description :
Clean a filename ("//"->"/", "/./"->"/", "/aa/../"->"/", etc.).
Input parameter(s) :
pathname : filename (ex : "/tmp/dir/..//./file")
Input/output parameter(s) :
Output parameter(s) :
*pcanonizedpathname : cleaned filename (ex : "/tmp/file")
Normal return values :
NETWIB_ERR_OK : ok
Examples of canonical paths :
file dir dir/file dir/dir
/file /dir /dir/file /dir/dir
../file ../dir ../dir/file ../dir/dir
/ . ..
Windows using a drive letter :
c:file c:dir c:dir/file c:dir/dir
c:/file c:/dir c:/dir/file c:/dir/dir
c:../file c:../dir c:../dir/file c:../dir/dir
c:/ c: c:..
Windows using a smb or cifs share :
//server/share/
//s/sh/file //s/sh/dir //s/sh/dir/file //s/sh/dir/dir
Note : a Window share is very similar to an absolute path
with two leading '/'. To ensure they are not mixed,
you have to ensure an absolute path does not start
with '//'.
*/
netwib_err netwib_path_canon(netwib_constbuf *ppathname,
netwib_buf *pcanonizedpathname);
/*-------------------------------------------------------------*/
/***************************************************************
* netwib functions : *
* - always work with : *
* + canonized path *
* - generally work with : *
* + relative path with leading "./" *
* + "c:." instead of "c:" (only under Windows) *
* + path with "\" instead of "/" (only under Windows) *
* - might work with : *
* + directory name ending with "/" (not under Windows) *
* + path such as "/dir/../dir2/file" *
* *
* So, user should canonize paths before using them. *
***************************************************************/
/*-------------------------------------------------------------*/
/* Name : netwib_pathtype_init
Description :
Obtain type of a path.
Input parameter(s) :
*ppathname : pathname to obtain.
Input/output parameter(s) :
Output parameter(s) :
*ppathtype : type as a bitfield
Normal return values :
NETWIB_ERR_OK : ok
Examples :
pathname absolute root unix windrive winshare
file 0=no 0 1 0 0
/file 1=yes 0 1 0 0
../file 0 0 1 0 0
/ 1 1 1 0 0
. 0 0 1 0 0
.. 0 0 1 0 0
c:file 0 0 0 1 0
c:/file 1 0 0 1 0
c:../file 0 0 0 1 0
c:/ 1 1 0 1 0
c: 0 0 0 1 0
c:.. 0 0 0 1 0
//s/sh/file 1 0 0 0 1
//s/sh/ 1 1 0 0 1
*/
#define NETWIB_PATHTYPE_ABSOLUTE 0x01 /* absolute: path is fully specified */
#define NETWIB_PATHTYPE_ROOT 0x02 /* root: can't go up */
#define NETWIB_PATHTYPE_UNIX 0x04 /* unix (or windows simple path) */
#define NETWIB_PATHTYPE_WINDRIVE 0x08 /* windows drive: c:, d: */
#define NETWIB_PATHTYPE_WINSHARE 0x10 /* windows smb share: //server/share/ */
typedef netwib_uint32 netwib_pathtype;
netwib_err netwib_pathtype_init(netwib_constbuf *ppathname,
netwib_pathtype *ppathtype);
/*-------------------------------------------------------------*/
/* Name : netwib_path_decode_xyz
Description :
Separate a path.
Input parameter(s) :
ppathname : filename (ex : "/tmp/file")
Input/output parameter(s) :
type : type of information to extract
Output parameter(s) :
*pout : output buffer (canonized, even if ppathname is not)
Normal return values :
NETWIB_ERR_OK : ok
Examples :
pathname begin core parent child
file . file . file
d/f . d/f d f
/file / /file / file
/d/f / /d/f /d f
../file . ../file .. file
../d/f . ../d/f ../d f
/ / / Error1 /
. . . .. .
.. . .. ../.. ..
c:file c: file c: file
c:d/f c: d/f c:d f
c:/file c:/ /file c:/ file
c:/d/f c:/ /d/f c:/d f
c:../file c: ../file c:.. file
c:../d/f c: ../d/f c:../d f
c:/ c:/ / Error1 /
c: c: . c:.. .
c:.. c: .. c:../.. ..
//s/t/file //s/t/ /file //s/t/ file
//s/t/d/f //s/t/ /d/f //s/t/d f
//s/t/ //s/t/ / Error1 /
Errors are :
Error1 : NETWIB_ERR_PAPATHROOTDOTDOT
*/
typedef enum {
NETWIB_PATH_DECODETYPE_BEGIN = 1, /* root directory or . */
NETWIB_PATH_DECODETYPE_CORE, /* path starting at begin */
NETWIB_PATH_DECODETYPE_PARENT, /* parent directory */
NETWIB_PATH_DECODETYPE_CHILD, /* last item */
NETWIB_PATH_DECODETYPE_EXTENSION /* file extension without the dot
(empty if no extension) ; pout is
a netwib_bufext */
/* note : pathname == begin+core or parent+child */
} netwib_path_decodetype;
netwib_err netwib_path_decode(netwib_constbuf *ppathname,
netwib_path_decodetype type,
netwib_buf *pout);
#define netwib_path_decode_begin(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_BEGIN,pout)
#define netwib_path_decode_core(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_CORE,pout)
#define netwib_path_decode_parent(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_PARENT,pout)
#define netwib_path_decode_child(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_CHILD,pout)
#define netwib_path_decode_extension(pathname,pout) netwib_path_decode(pathname,NETWIB_PATH_DECODETYPE_EXTENSION,pout)
/*-------------------------------------------------------------*/
/* Name : netwib_path_init_xyz
Description :
Initialize a path.
Input parameter(s) :
See below
Input/output parameter(s) :
pout : path initialized (canonized, even if input is not)
Output parameter(s) :
Normal return values :
NETWIB_ERR_OK : ok
*/
typedef enum {
NETWIB_PATH_INITTYPE_CONCAT = 1,
NETWIB_PATH_INITTYPE_JAIL,
NETWIB_PATH_INITTYPE_ABS,
NETWIB_PATH_INITTYPE_RELA,
NETWIB_PATH_INITTYPE_RELB,
} netwib_path_inittype;
/*
Definitions :
concat : path from the beginning of dirname1 to pathname2
[dirname1]-[pathname2]
X-------------------->
If pathname2 is absolute, an error occurs (except if
dirname1 is a root).
jail : same as concat except pathname2 is considered as an
absolute path inside dirname1. It's a kind of chroot
or jail with a rootdir of dirname1. Resulting filename
cannot escape from dirname1.
abs : absolute path to pathname2 (pathname2 is in a
file located in dirname1 directory)
root
[dirname1]-[pathname2]
X---------------------->
If pathname2 is absolute, result is pathname2.
If dirname1 is not absolute, an error occurs.
rela : relative path to go to pathname2 from a file
in dirname1 directory (pathname2 is in a
file located in dirname1 directory)
[dirname1]-[pathname2]
X----------->
If pathname2 is relative, result is pathname2.
If pathname2 is absolute, dirname1 must be absolute.
relb : relative path to go to pathname2 from a file
in dirname1 directory (pathname1 and pathname2
are located in the same directory)
[dirname1]
[ pathname2 ]
X----->
If pathname2 is absolute, dirname1 must be absolute.
If pathname2 is relative, dirname1 must be relative.
Examples of concat, jail and abs :
dirname1 pathname2 concat jail abs
d1 d2/f2 d1/d2/f2 d1/d2/f2 Error
d1 ../d2/f2 d2/f2 Error Error
d1 /d2/f2 Error d1/d2/f2 /d2/f2
../d1 d2/f2 ../d1/d2/f2 ../d1/d2/f2 Error
../d1 ../d2/f2 ../d2/f2 Error Error
../d1 /d2/f2 Error ../d1/d2/f2 /d2/f2
/d1 d2/f2 /d1/d2/f2 /d1/d2/f2 /d1/d2/f2
/d1 ../d2/f2 /d2/f2 Error /d2/f2
/d1 /d2/f2 Error /d1/d2/f2 /d2/f2
isroot /d2/f2 x/d2/f2 x/d2/f2 /d2/f2
Examples of rela and relb :
dirname1 pathname2 rela relb
d1 d2/f2 d2/f2 ../d2/f2
d1 ../d2/f2 ../d2/f2 ../../d2/f2
d1 /d2/f2 Error Error
../d1 d2/f2 d2/f2 Error
../d1 ../d2/f2 ../d2/f2 ../d2/f2
../d1 /d2/f2 Error Error
/d1 d2/f2 d2/f2 Error
/d1 ../d2/f2 ../d2/f2 Error
/d1 /d2/f2 ../d2/f2 ../d2/f2
d1 d1 d1 . (because pathname2 is like ...)
/d1 /d1 . . (dirname1, so it's a directory)
The errors have the code : NETWIB_ERR_PAPATHCANTINIT.
*/
netwib_err netwib_path_init(netwib_constbuf *pdirname1,
netwib_constbuf *ppathname2,
netwib_path_inittype type,
netwib_buf *pout);
#define netwib_path_init_concat(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_CONCAT,pout)
#define netwib_path_init_jail(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_JAIL,pout)
#define netwib_path_init_abs(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_ABS,pout)
#define netwib_path_init_rela(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_RELA,pout)
#define netwib_path_init_relb(dirname1,pathname2,pout) netwib_path_init(dirname1,pathname2,NETWIB_PATH_INITTYPE_RELB,pout)