xref: /minix3/minix/lib/libhgfs/path.c (revision 94e65446c4f963450ea94b8becc02cec062675cd)
1433d6423SLionel Sambuc /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2433d6423SLionel Sambuc 
3433d6423SLionel Sambuc #include "inc.h"
4433d6423SLionel Sambuc 
5433d6423SLionel Sambuc #include <limits.h>
6433d6423SLionel Sambuc 
7433d6423SLionel Sambuc /*===========================================================================*
8433d6423SLionel Sambuc  *				path_put				     *
9433d6423SLionel Sambuc  *===========================================================================*/
path_put(const char * path)10*94e65446SDavid van Moolenbroek void path_put(const char *path)
11433d6423SLionel Sambuc {
12433d6423SLionel Sambuc /* Append the given path name in HGFS format to the RPC buffer. Truncate it
13433d6423SLionel Sambuc  * if it is longer than PATH_MAX bytes.
14433d6423SLionel Sambuc  */
15*94e65446SDavid van Moolenbroek   const char *p;
16*94e65446SDavid van Moolenbroek   char buf[PATH_MAX];
17*94e65446SDavid van Moolenbroek   unsigned int len;
18433d6423SLionel Sambuc 
19433d6423SLionel Sambuc   /* No leading slashes are allowed. */
20433d6423SLionel Sambuc   for (p = path; *p == '/'; p++);
21433d6423SLionel Sambuc 
22433d6423SLionel Sambuc   /* No double or tailing slashes, either. */
23433d6423SLionel Sambuc   for (len = 0; *p && len < sizeof(buf) - 1; len++) {
24433d6423SLionel Sambuc     if (*p == '/') {
25433d6423SLionel Sambuc       for (p++; *p == '/'; p++);
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc       if (!*p) break;
28433d6423SLionel Sambuc 
29433d6423SLionel Sambuc       buf[len] = 0;
30433d6423SLionel Sambuc     }
31433d6423SLionel Sambuc     else buf[len] = *p++;
32433d6423SLionel Sambuc   }
33433d6423SLionel Sambuc 
34433d6423SLionel Sambuc   RPC_NEXT32 = len;
35433d6423SLionel Sambuc 
36433d6423SLionel Sambuc   memcpy(RPC_PTR, buf, len);
37433d6423SLionel Sambuc   RPC_ADVANCE(len);
38433d6423SLionel Sambuc 
39433d6423SLionel Sambuc   RPC_NEXT8 = 0;
40433d6423SLionel Sambuc }
41433d6423SLionel Sambuc 
42433d6423SLionel Sambuc /*===========================================================================*
43433d6423SLionel Sambuc  *				path_get				     *
44433d6423SLionel Sambuc  *===========================================================================*/
path_get(char * path,int max)45433d6423SLionel Sambuc int path_get(char *path, int max)
46433d6423SLionel Sambuc {
47433d6423SLionel Sambuc /* Retrieve a HGFS formatted path name from the RPC buffer. Returns EINVAL if
48433d6423SLionel Sambuc  * the path name is invalid. Returns ENAMETOOLONG if the path name is too
49433d6423SLionel Sambuc  * long. Returns OK on success.
50433d6423SLionel Sambuc  */
51433d6423SLionel Sambuc   char *p, *q;
52433d6423SLionel Sambuc   int n, len;
53433d6423SLionel Sambuc 
54433d6423SLionel Sambuc   n = len = RPC_NEXT32;
55433d6423SLionel Sambuc 
56433d6423SLionel Sambuc   if (len >= max) return ENAMETOOLONG;
57433d6423SLionel Sambuc 
58433d6423SLionel Sambuc   for (p = path, q = RPC_PTR; n--; p++, q++) {
59433d6423SLionel Sambuc     /* We can not deal with a slash in a path component. */
60433d6423SLionel Sambuc     if (*q == '/') return EINVAL;
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc     if (*q == 0) *p = '/';
63433d6423SLionel Sambuc     else *p = *q;
64433d6423SLionel Sambuc   }
65433d6423SLionel Sambuc 
66433d6423SLionel Sambuc   RPC_ADVANCE(len);
67433d6423SLionel Sambuc 
68433d6423SLionel Sambuc   *p = 0;
69433d6423SLionel Sambuc 
70433d6423SLionel Sambuc   return (RPC_NEXT8 != 0) ? EINVAL : OK;
71433d6423SLionel Sambuc }
72