1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /* Common functions for libxenstore, xenstored and xenstore-clients. */
3 
4 #ifndef __XEN_TOOLS_XENSTORE_COMMON__
5 #define __XEN_TOOLS_XENSTORE_COMMON__
6 
7 #include <limits.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <xenstore_lib.h>
11 
xenstore_daemon_rundir(void)12 static inline const char *xenstore_daemon_rundir(void)
13 {
14     char *s = getenv("XENSTORED_RUNDIR");
15 
16     return s ? s : XEN_RUN_STORED;
17 }
18 
xenstore_daemon_path(void)19 static inline const char *xenstore_daemon_path(void)
20 {
21     static char buf[PATH_MAX];
22     char *s = getenv("XENSTORED_PATH");
23 
24     if ( s )
25         return s;
26 
27     if ( snprintf(buf, sizeof(buf), "%s/socket", xenstore_daemon_rundir()) >=
28          PATH_MAX )
29         return NULL;
30 
31     return buf;
32 }
33 
34 /* Convert strings to permissions.  False if a problem. */
xenstore_strings_to_perms(struct xs_permissions * perms,unsigned int num,const char * strings)35 static inline bool xenstore_strings_to_perms(struct xs_permissions *perms,
36                                              unsigned int num,
37                                              const char *strings)
38 {
39     const char *p;
40     char *end;
41     unsigned int i;
42 
43     for ( p = strings, i = 0; i < num; i++ )
44     {
45         /* "r", "w", or "b" for both. */
46         switch ( *p )
47         {
48         case 'r':
49             perms[i].perms = XS_PERM_READ;
50             break;
51 
52         case 'w':
53             perms[i].perms = XS_PERM_WRITE;
54             break;
55 
56         case 'b':
57             perms[i].perms = XS_PERM_READ|XS_PERM_WRITE;
58             break;
59 
60         case 'n':
61             perms[i].perms = XS_PERM_NONE;
62             break;
63 
64         default:
65             errno = EINVAL;
66             return false;
67         }
68 
69         p++;
70         perms[i].id = strtol(p, &end, 0);
71         if ( *end || !*p )
72         {
73             errno = EINVAL;
74             return false;
75         }
76 
77         p = end + 1;
78     }
79 
80     return true;
81 }
82 
83 /* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */
xenstore_perm_to_string(const struct xs_permissions * perm,char * buffer,size_t buf_len)84 static inline bool xenstore_perm_to_string(const struct xs_permissions *perm,
85                                            char *buffer, size_t buf_len)
86 {
87     switch ( (int)perm->perms & ~XS_PERM_IGNORE )
88     {
89     case XS_PERM_WRITE:
90         *buffer = 'w';
91         break;
92 
93     case XS_PERM_READ:
94         *buffer = 'r';
95         break;
96 
97     case XS_PERM_READ|XS_PERM_WRITE:
98         *buffer = 'b';
99         break;
100 
101     case XS_PERM_NONE:
102         *buffer = 'n';
103         break;
104 
105     default:
106         errno = EINVAL;
107         return false;
108     }
109 
110     snprintf(buffer + 1, buf_len - 1, "%i", (int)perm->id);
111 
112     return true;
113 }
114 
115 /* Given a string and a length, count how many strings (nul terms). */
xenstore_count_strings(const char * strings,unsigned int len)116 static inline unsigned int xenstore_count_strings(const char *strings,
117                                                   unsigned int len)
118 {
119     unsigned int num;
120     const char *p;
121 
122     for ( p = strings, num = 0; p < strings + len; p++ )
123         if ( *p == '\0' )
124             num++;
125 
126     return num;
127 }
128 #endif /* __XEN_TOOLS_XENSTORE_COMMON__ */
129