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