debuggers.hg

view tools/xenstore/xs_lib.c @ 21067:b4a1832a916f

Update Xen version to 4.0.0-rc6
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 09 18:18:05 2010 +0000 (2010-03-09)
parents 8dada4c897c9
children
line source
1 /*
2 Common routines between Xen store user library and daemon.
3 Copyright (C) 2005 Rusty Russell IBM Corporation
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <assert.h>
26 #include "xs_lib.h"
28 /* Common routines for the Xen store daemon and client library. */
30 const char *xs_daemon_rootdir(void)
31 {
32 char *s = getenv("XENSTORED_ROOTDIR");
33 return (s ? s : "/var/lib/xenstored");
34 }
36 const char *xs_daemon_rundir(void)
37 {
38 char *s = getenv("XENSTORED_RUNDIR");
39 return (s ? s : "/var/run/xenstored");
40 }
42 static const char *xs_daemon_path(void)
43 {
44 static char buf[PATH_MAX];
45 char *s = getenv("XENSTORED_PATH");
46 if (s)
47 return s;
48 if (snprintf(buf, sizeof(buf), "%s/socket",
49 xs_daemon_rundir()) >= PATH_MAX)
50 return NULL;
51 return buf;
52 }
54 const char *xs_daemon_tdb(void)
55 {
56 static char buf[PATH_MAX];
57 snprintf(buf, sizeof(buf), "%s/tdb", xs_daemon_rootdir());
58 return buf;
59 }
61 const char *xs_daemon_socket(void)
62 {
63 return xs_daemon_path();
64 }
66 const char *xs_daemon_socket_ro(void)
67 {
68 static char buf[PATH_MAX];
69 const char *s = xs_daemon_path();
70 if (s == NULL)
71 return NULL;
72 if (snprintf(buf, sizeof(buf), "%s_ro", s) >= PATH_MAX)
73 return NULL;
74 return buf;
75 }
77 const char *xs_domain_dev(void)
78 {
79 char *s = getenv("XENSTORED_PATH");
80 if (s)
81 return s;
83 #if defined(__linux__)
84 return "/proc/xen/xenbus";
85 #elif defined(__NetBSD__)
86 return "/kern/xen/xenbus";
87 #else
88 return "/dev/xen/xenbus";
89 #endif
90 }
92 /* Simple routines for writing to sockets, etc. */
93 bool xs_write_all(int fd, const void *data, unsigned int len)
94 {
95 while (len) {
96 int done;
98 done = write(fd, data, len);
99 if (done < 0 && errno == EINTR)
100 continue;
101 if (done <= 0)
102 return false;
103 data += done;
104 len -= done;
105 }
107 return true;
108 }
110 /* Convert strings to permissions. False if a problem. */
111 bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
112 const char *strings)
113 {
114 const char *p;
115 char *end;
116 unsigned int i;
118 for (p = strings, i = 0; i < num; i++) {
119 /* "r", "w", or "b" for both. */
120 switch (*p) {
121 case 'r':
122 perms[i].perms = XS_PERM_READ;
123 break;
124 case 'w':
125 perms[i].perms = XS_PERM_WRITE;
126 break;
127 case 'b':
128 perms[i].perms = XS_PERM_READ|XS_PERM_WRITE;
129 break;
130 case 'n':
131 perms[i].perms = XS_PERM_NONE;
132 break;
133 default:
134 errno = EINVAL;
135 return false;
136 }
137 p++;
138 perms[i].id = strtol(p, &end, 0);
139 if (*end || !*p) {
140 errno = EINVAL;
141 return false;
142 }
143 p = end + 1;
144 }
145 return true;
146 }
148 /* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */
149 bool xs_perm_to_string(const struct xs_permissions *perm,
150 char *buffer, size_t buf_len)
151 {
152 switch ((int)perm->perms) {
153 case XS_PERM_WRITE:
154 *buffer = 'w';
155 break;
156 case XS_PERM_READ:
157 *buffer = 'r';
158 break;
159 case XS_PERM_READ|XS_PERM_WRITE:
160 *buffer = 'b';
161 break;
162 case XS_PERM_NONE:
163 *buffer = 'n';
164 break;
165 default:
166 errno = EINVAL;
167 return false;
168 }
169 snprintf(buffer+1, buf_len-1, "%i", (int)perm->id);
170 return true;
171 }
173 /* Given a string and a length, count how many strings (nul terms). */
174 unsigned int xs_count_strings(const char *strings, unsigned int len)
175 {
176 unsigned int num;
177 const char *p;
179 for (p = strings, num = 0; p < strings + len; p++)
180 if (*p == '\0')
181 num++;
183 return num;
184 }
186 char *expanding_buffer_ensure(struct expanding_buffer *ebuf, int min_avail)
187 {
188 int want;
189 char *got;
191 if (ebuf->avail >= min_avail)
192 return ebuf->buf;
194 if (min_avail >= INT_MAX/3)
195 return 0;
197 want = ebuf->avail + min_avail + 10;
198 got = realloc(ebuf->buf, want);
199 if (!got)
200 return 0;
202 ebuf->buf = got;
203 ebuf->avail = want;
204 return ebuf->buf;
205 }
207 char *sanitise_value(struct expanding_buffer *ebuf,
208 const char *val, unsigned len)
209 {
210 int used, remain, c;
211 unsigned char *ip;
213 #define ADD(c) (ebuf->buf[used++] = (c))
214 #define ADDF(f,c) (used += sprintf(ebuf->buf+used, (f), (c)))
216 assert(len < INT_MAX/5);
218 ip = (unsigned char *)val;
219 used = 0;
220 remain = len;
222 if (!expanding_buffer_ensure(ebuf, remain + 1))
223 return NULL;
225 while (remain-- > 0) {
226 c= *ip++;
228 if (c >= ' ' && c <= '~' && c != '\\') {
229 ADD(c);
230 continue;
231 }
233 if (!expanding_buffer_ensure(ebuf, used + remain + 5))
234 /* for "<used>\\nnn<remain>\0" */
235 return 0;
237 ADD('\\');
238 switch (c) {
239 case '\t': ADD('t'); break;
240 case '\n': ADD('n'); break;
241 case '\r': ADD('r'); break;
242 case '\\': ADD('\\'); break;
243 default:
244 if (c < 010) ADDF("%03o", c);
245 else ADDF("x%02x", c);
246 }
247 }
249 ADD(0);
250 assert(used <= ebuf->avail);
251 return ebuf->buf;
253 #undef ADD
254 #undef ADDF
255 }
257 void unsanitise_value(char *out, unsigned *out_len_r, const char *in)
258 {
259 const char *ip;
260 char *op;
261 unsigned c;
262 int n;
264 for (ip = in, op = out; (c = *ip++); *op++ = c) {
265 if (c == '\\') {
266 c = *ip++;
268 #define GETF(f) do { \
269 n = 0; \
270 sscanf(ip, f "%n", &c, &n); \
271 ip += n; \
272 } while (0)
274 switch (c) {
275 case 't': c= '\t'; break;
276 case 'n': c= '\n'; break;
277 case 'r': c= '\r'; break;
278 case '\\': c= '\\'; break;
279 case 'x': GETF("%2x"); break;
280 case '0': case '4':
281 case '1': case '5':
282 case '2': case '6':
283 case '3': case '7': --ip; GETF("%3o"); break;
284 case 0: --ip; break;
285 default:;
286 }
287 #undef GETF
288 }
289 }
291 *op = 0;
293 if (out_len_r)
294 *out_len_r = op - out;
295 }