1 /*
2     Xen Store Daemon interface providing simple tree-like database.
3     Copyright (C) 2005 Rusty Russell IBM Corporation
4 
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.
9 
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.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #define _GNU_SOURCE
20 
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <sys/uio.h>
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <stdbool.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <stdio.h>
33 #include <signal.h>
34 #include <stdint.h>
35 #include <errno.h>
36 #include "xenstore.h"
37 #include "list.h"
38 #include "utils.h"
39 
40 #include <xentoolcore_internal.h>
41 
42 struct xs_stored_msg {
43 	struct list_head list;
44 	struct xsd_sockmsg hdr;
45 	char *body;
46 };
47 
48 #ifdef USE_PTHREAD
49 
50 #include <pthread.h>
51 
52 #ifdef USE_DLSYM
53 #include <dlfcn.h>
54 #endif
55 
56 struct xs_handle {
57 	/* Communications channel to xenstore daemon. */
58 	int fd;
59 	Xentoolcore__Active_Handle tc_ah; /* for restrict */
60 
61 	/*
62          * A read thread which pulls messages off the comms channel and
63          * signals waiters.
64          */
65 	pthread_t read_thr;
66 	int read_thr_exists;
67 
68 	/*
69          * A list of fired watch messages, protected by a mutex. Users can
70          * wait on the conditional variable until a watch is pending.
71          */
72 	struct list_head watch_list;
73 	pthread_mutex_t watch_mutex;
74 	pthread_cond_t watch_condvar;
75 
76 	/* Clients can select() on this pipe to wait for a watch to fire. */
77 	int watch_pipe[2];
78 	/* Filtering watch event in unwatch function? */
79 	bool unwatch_filter;
80 
81 	/*
82          * A list of replies. Currently only one will ever be outstanding
83          * because we serialise requests. The requester can wait on the
84          * conditional variable for its response.
85          */
86 	struct list_head reply_list;
87 	pthread_mutex_t reply_mutex;
88 	pthread_cond_t reply_condvar;
89 
90 	/* One request at a time. */
91 	pthread_mutex_t request_mutex;
92 
93 	/* Lock discipline:
94 	 *  Only holder of the request lock may write to h->fd.
95 	 *  Only holder of the request lock may access read_thr_exists.
96 	 *  If read_thr_exists==0, only holder of request lock may read h->fd;
97 	 *  If read_thr_exists==1, only the read thread may read h->fd.
98 	 *  Only holder of the reply lock may access reply_list.
99 	 *  Only holder of the watch lock may access watch_list.
100 	 * Lock hierarchy:
101 	 *  The order in which to acquire locks is
102 	 *     request_mutex
103 	 *     reply_mutex
104 	 *     watch_mutex
105 	 */
106 };
107 
108 #define mutex_lock(m)		pthread_mutex_lock(m)
109 #define mutex_unlock(m)		pthread_mutex_unlock(m)
110 #define condvar_signal(c)	pthread_cond_signal(c)
111 #define condvar_wait(c,m)	pthread_cond_wait(c,m)
112 #define cleanup_push(f, a)	\
113     pthread_cleanup_push((void (*)(void *))(f), (void *)(a))
114 /*
115  * Some definitions of pthread_cleanup_pop() are a macro starting with an
116  * end-brace. GCC then complains if we immediately precede that with a label.
117  * Hence we insert a dummy statement to appease the compiler in this situation.
118  */
119 #define cleanup_pop(run)        ((void)0); pthread_cleanup_pop(run)
120 
121 #define read_thread_exists(h)	(h->read_thr_exists)
122 
123 /* Because pthread_cleanup_p* are not available when USE_PTHREAD is
124  * disabled, use these macros which convert appropriately. */
125 #define cleanup_push_heap(p)        cleanup_push(free, p)
126 #define cleanup_pop_heap(run, p)    cleanup_pop((run))
127 
128 static void *read_thread(void *arg);
129 
130 #else /* !defined(USE_PTHREAD) */
131 
132 struct xs_handle {
133 	int fd;
134 	Xentoolcore__Active_Handle tc_ah; /* for restrict */
135 	struct list_head reply_list;
136 	struct list_head watch_list;
137 	/* Clients can select() on this pipe to wait for a watch to fire. */
138 	int watch_pipe[2];
139 	/* Filtering watch event in unwatch function? */
140 	bool unwatch_filter;
141 };
142 
143 #define mutex_lock(m)		((void)0)
144 #define mutex_unlock(m)		((void)0)
145 #define condvar_signal(c)	((void)0)
146 #define condvar_wait(c,m)	((void)0)
147 #define cleanup_push(f, a)	((void)0)
148 #define cleanup_pop(run)	((void)0)
149 #define read_thread_exists(h)	(0)
150 
151 #define cleanup_push_heap(p)        ((void)0)
152 #define cleanup_pop_heap(run, p)    do { if ((run)) free(p); } while(0)
153 
154 #endif
155 
156 static int read_message(struct xs_handle *h, int nonblocking);
157 
setnonblock(int fd,int nonblock)158 static bool setnonblock(int fd, int nonblock) {
159 	int flags = fcntl(fd, F_GETFL);
160 	if (flags == -1)
161 		return false;
162 
163 	if (nonblock)
164 		flags |= O_NONBLOCK;
165 	else
166 		flags &= ~O_NONBLOCK;
167 
168 	if (fcntl(fd, F_SETFL, flags) == -1)
169 		return false;
170 
171 	return true;
172 }
173 
xs_fileno(struct xs_handle * h)174 int xs_fileno(struct xs_handle *h)
175 {
176 	char c = 0;
177 
178 	mutex_lock(&h->watch_mutex);
179 
180 	if ((h->watch_pipe[0] == -1) && (pipe(h->watch_pipe) != -1)) {
181 		/* Kick things off if the watch list is already non-empty. */
182 		if (!list_empty(&h->watch_list))
183 			while (write(h->watch_pipe[1], &c, 1) != 1)
184 				continue;
185 	}
186 
187 	mutex_unlock(&h->watch_mutex);
188 
189 	return h->watch_pipe[0];
190 }
191 
get_socket(const char * connect_to)192 static int get_socket(const char *connect_to)
193 {
194 	struct sockaddr_un addr;
195 	int sock, saved_errno, flags;
196 
197 	sock = socket(PF_UNIX, SOCK_STREAM, 0);
198 	if (sock < 0)
199 		return -1;
200 
201 	if ((flags = fcntl(sock, F_GETFD)) < 0)
202 		goto error;
203 	flags |= FD_CLOEXEC;
204 	if (fcntl(sock, F_SETFD, flags) < 0)
205 		goto error;
206 
207 	addr.sun_family = AF_UNIX;
208 	if(strlen(connect_to) >= sizeof(addr.sun_path)) {
209 		errno = EINVAL;
210 		goto error;
211 	}
212 	strcpy(addr.sun_path, connect_to);
213 
214 	if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
215 		goto error;
216 
217 	return sock;
218 
219 error:
220 	saved_errno = errno;
221 	close(sock);
222 	errno = saved_errno;
223 	return -1;
224 }
225 
get_dev(const char * connect_to)226 static int get_dev(const char *connect_to)
227 {
228 	/* We cannot open read-only because requests are writes */
229 	return open(connect_to, O_RDWR);
230 }
231 
all_restrict_cb(Xentoolcore__Active_Handle * ah,domid_t domid)232 static int all_restrict_cb(Xentoolcore__Active_Handle *ah, domid_t domid) {
233     struct xs_handle *h = CONTAINER_OF(ah, *h, tc_ah);
234     return xentoolcore__restrict_by_dup2_null(h->fd);
235 }
236 
get_handle(const char * connect_to)237 static struct xs_handle *get_handle(const char *connect_to)
238 {
239 	struct stat buf;
240 	struct xs_handle *h = NULL;
241 	int saved_errno;
242 
243 	h = malloc(sizeof(*h));
244 	if (h == NULL)
245 		goto err;
246 
247 	memset(h, 0, sizeof(*h));
248 	h->fd = -1;
249 
250 	h->tc_ah.restrict_callback = all_restrict_cb;
251 	xentoolcore__register_active_handle(&h->tc_ah);
252 
253 	if (stat(connect_to, &buf) != 0)
254 		goto err;
255 
256 	if (S_ISSOCK(buf.st_mode))
257 		h->fd = get_socket(connect_to);
258 	else
259 		h->fd = get_dev(connect_to);
260 
261 	if (h->fd == -1)
262 		goto err;
263 
264 	INIT_LIST_HEAD(&h->reply_list);
265 	INIT_LIST_HEAD(&h->watch_list);
266 
267 	/* Watch pipe is allocated on demand in xs_fileno(). */
268 	h->watch_pipe[0] = h->watch_pipe[1] = -1;
269 
270 	h->unwatch_filter = false;
271 
272 #ifdef USE_PTHREAD
273 	pthread_mutex_init(&h->watch_mutex, NULL);
274 	pthread_cond_init(&h->watch_condvar, NULL);
275 
276 	pthread_mutex_init(&h->reply_mutex, NULL);
277 	pthread_cond_init(&h->reply_condvar, NULL);
278 
279 	pthread_mutex_init(&h->request_mutex, NULL);
280 #endif
281 
282 	return h;
283 
284 err:
285 	saved_errno = errno;
286 
287 	if (h) {
288 		xentoolcore__deregister_active_handle(&h->tc_ah);
289 		if (h->fd >= 0)
290 			close(h->fd);
291 	}
292 	free(h);
293 
294 	errno = saved_errno;
295 	return NULL;
296 }
297 
xs_daemon_open(void)298 struct xs_handle *xs_daemon_open(void)
299 {
300 	return xs_open(0);
301 }
302 
xs_daemon_open_readonly(void)303 struct xs_handle *xs_daemon_open_readonly(void)
304 {
305 	return xs_open(XS_OPEN_READONLY);
306 }
307 
xs_domain_open(void)308 struct xs_handle *xs_domain_open(void)
309 {
310 	return xs_open(0);
311 }
312 
xs_open(unsigned long flags)313 struct xs_handle *xs_open(unsigned long flags)
314 {
315 	struct xs_handle *xsh = NULL;
316 
317 	if (flags & XS_OPEN_READONLY)
318 		xsh = get_handle(xs_daemon_socket_ro());
319 	else
320 		xsh = get_handle(xs_daemon_socket());
321 
322 	if (!xsh && !(flags & XS_OPEN_SOCKETONLY))
323 		xsh = get_handle(xs_domain_dev());
324 
325 	if (xsh && (flags & XS_UNWATCH_FILTER))
326 		xsh->unwatch_filter = true;
327 
328 	return xsh;
329 }
330 
close_free_msgs(struct xs_handle * h)331 static void close_free_msgs(struct xs_handle *h) {
332 	struct xs_stored_msg *msg, *tmsg;
333 
334 	list_for_each_entry_safe(msg, tmsg, &h->reply_list, list) {
335 		free(msg->body);
336 		free(msg);
337 	}
338 
339 	list_for_each_entry_safe(msg, tmsg, &h->watch_list, list) {
340 		free(msg->body);
341 		free(msg);
342 	}
343 }
344 
close_fds_free(struct xs_handle * h)345 static void close_fds_free(struct xs_handle *h) {
346 	if (h->watch_pipe[0] != -1) {
347 		close(h->watch_pipe[0]);
348 		close(h->watch_pipe[1]);
349 	}
350 
351 	xentoolcore__deregister_active_handle(&h->tc_ah);
352         close(h->fd);
353 
354 	free(h);
355 }
356 
xs_daemon_destroy_postfork(struct xs_handle * h)357 void xs_daemon_destroy_postfork(struct xs_handle *h)
358 {
359         close_free_msgs(h);
360         close_fds_free(h);
361 }
362 
xs_daemon_close(struct xs_handle * h)363 void xs_daemon_close(struct xs_handle *h)
364 {
365 #ifdef USE_PTHREAD
366 	if (h->read_thr_exists) {
367 		pthread_cancel(h->read_thr);
368 		pthread_join(h->read_thr, NULL);
369 	}
370 #endif
371 
372 	mutex_lock(&h->request_mutex);
373 	mutex_lock(&h->reply_mutex);
374 	mutex_lock(&h->watch_mutex);
375 
376         close_free_msgs(h);
377 
378 	mutex_unlock(&h->request_mutex);
379 	mutex_unlock(&h->reply_mutex);
380 	mutex_unlock(&h->watch_mutex);
381 
382         close_fds_free(h);
383 }
384 
xs_close(struct xs_handle * xsh)385 void xs_close(struct xs_handle* xsh)
386 {
387 	if (xsh)
388 		xs_daemon_close(xsh);
389 }
390 
read_all(int fd,void * data,unsigned int len,int nonblocking)391 static bool read_all(int fd, void *data, unsigned int len, int nonblocking)
392 	/* With nonblocking, either reads either everything requested,
393 	 * or nothing. */
394 {
395 	if (!len)
396 		return true;
397 
398 	if (nonblocking && !setnonblock(fd, 1))
399 		return false;
400 
401 	while (len) {
402 		int done;
403 
404 		done = read(fd, data, len);
405 		if (done < 0) {
406 			if (errno == EINTR)
407 				continue;
408 			goto out_false;
409 		}
410 		if (done == 0) {
411 			/* It closed fd on us?  EBADF is appropriate. */
412 			errno = EBADF;
413 			goto out_false;
414 		}
415 		data += done;
416 		len -= done;
417 
418 		if (nonblocking) {
419 			nonblocking = 0;
420 			if (!setnonblock(fd, 0))
421 				goto out_false;
422 		}
423 	}
424 
425 	return true;
426 
427 out_false:
428 	if (nonblocking)
429 		setnonblock(fd, 0);
430 	return false;
431 }
432 
433 #ifdef XSTEST
434 #define read_all read_all_choice
435 #define xs_write_all write_all_choice
436 #endif
437 
get_error(const char * errorstring)438 static int get_error(const char *errorstring)
439 {
440 	unsigned int i;
441 
442 	for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++)
443 		if (i == ARRAY_SIZE(xsd_errors) - 1)
444 			return EINVAL;
445 	return xsd_errors[i].errnum;
446 }
447 
448 /* Adds extra nul terminator, because we generally (always?) hold strings. */
read_reply(struct xs_handle * h,enum xsd_sockmsg_type * type,unsigned int * len)449 static void *read_reply(
450 	struct xs_handle *h, enum xsd_sockmsg_type *type, unsigned int *len)
451 {
452 	struct xs_stored_msg *msg;
453 	char *body;
454 	int read_from_thread;
455 
456 	read_from_thread = read_thread_exists(h);
457 
458 	/* Read from comms channel ourselves if there is no reader thread. */
459 	if (!read_from_thread && (read_message(h, 0) == -1))
460 		return NULL;
461 
462 	mutex_lock(&h->reply_mutex);
463 #ifdef USE_PTHREAD
464 	while (list_empty(&h->reply_list) && read_from_thread && h->fd != -1)
465 		condvar_wait(&h->reply_condvar, &h->reply_mutex);
466 #endif
467 	if (list_empty(&h->reply_list)) {
468 		mutex_unlock(&h->reply_mutex);
469 		errno = EINVAL;
470 		return NULL;
471 	}
472 	msg = list_top(&h->reply_list, struct xs_stored_msg, list);
473 	list_del(&msg->list);
474 	assert(list_empty(&h->reply_list));
475 	mutex_unlock(&h->reply_mutex);
476 
477 	*type = msg->hdr.type;
478 	if (len)
479 		*len = msg->hdr.len;
480 	body = msg->body;
481 
482 	free(msg);
483 
484 	return body;
485 }
486 
487 /* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
xs_talkv(struct xs_handle * h,xs_transaction_t t,enum xsd_sockmsg_type type,const struct iovec * iovec,unsigned int num_vecs,unsigned int * len)488 static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
489 		      enum xsd_sockmsg_type type,
490 		      const struct iovec *iovec,
491 		      unsigned int num_vecs,
492 		      unsigned int *len)
493 {
494 	struct xsd_sockmsg msg;
495 	void *ret = NULL;
496 	int saved_errno;
497 	unsigned int i;
498 	struct sigaction ignorepipe, oldact;
499 
500 	msg.tx_id = t;
501 	msg.req_id = 0;
502 	msg.type = type;
503 	msg.len = 0;
504 	for (i = 0; i < num_vecs; i++)
505 		msg.len += iovec[i].iov_len;
506 
507 	if (msg.len > XENSTORE_PAYLOAD_MAX) {
508 		errno = E2BIG;
509 		return 0;
510 	}
511 
512 	ignorepipe.sa_handler = SIG_IGN;
513 	sigemptyset(&ignorepipe.sa_mask);
514 	ignorepipe.sa_flags = 0;
515 	sigaction(SIGPIPE, &ignorepipe, &oldact);
516 
517 	mutex_lock(&h->request_mutex);
518 
519 	if (!xs_write_all(h->fd, &msg, sizeof(msg)))
520 		goto fail;
521 
522 	for (i = 0; i < num_vecs; i++)
523 		if (!xs_write_all(h->fd, iovec[i].iov_base, iovec[i].iov_len))
524 			goto fail;
525 
526 	ret = read_reply(h, &msg.type, len);
527 	if (!ret)
528 		goto fail;
529 
530 	mutex_unlock(&h->request_mutex);
531 
532 	sigaction(SIGPIPE, &oldact, NULL);
533 	if (msg.type == XS_ERROR) {
534 		saved_errno = get_error(ret);
535 		free(ret);
536 		errno = saved_errno;
537 		return NULL;
538 	}
539 
540 	if (msg.type != type) {
541 		free(ret);
542 		saved_errno = EBADF;
543 		goto close_fd;
544 	}
545 	return ret;
546 
547 fail:
548 	/* We're in a bad state, so close fd. */
549 	saved_errno = errno;
550 	mutex_unlock(&h->request_mutex);
551 	sigaction(SIGPIPE, &oldact, NULL);
552 close_fd:
553 	close(h->fd);
554 	h->fd = -1;
555 	errno = saved_errno;
556 	return NULL;
557 }
558 
559 /* free(), but don't change errno. */
free_no_errno(void * p)560 static void free_no_errno(void *p)
561 {
562 	int saved_errno = errno;
563 	free(p);
564 	errno = saved_errno;
565 }
566 
567 /* Simplified version of xs_talkv: single message. */
xs_single(struct xs_handle * h,xs_transaction_t t,enum xsd_sockmsg_type type,const char * string,unsigned int * len)568 static void *xs_single(struct xs_handle *h, xs_transaction_t t,
569 		       enum xsd_sockmsg_type type,
570 		       const char *string,
571 		       unsigned int *len)
572 {
573 	struct iovec iovec;
574 
575 	iovec.iov_base = (void *)string;
576 	iovec.iov_len = strlen(string) + 1;
577 	return xs_talkv(h, t, type, &iovec, 1, len);
578 }
579 
xs_bool(char * reply)580 static bool xs_bool(char *reply)
581 {
582 	if (!reply)
583 		return false;
584 	free(reply);
585 	return true;
586 }
587 
xs_directory_common(char * strings,unsigned int len,unsigned int * num)588 static char **xs_directory_common(char *strings, unsigned int len,
589 				  unsigned int *num)
590 {
591 	char *p, **ret;
592 
593 	/* Count the strings. */
594 	*num = xs_count_strings(strings, len);
595 
596 	/* Transfer to one big alloc for easy freeing. */
597 	ret = malloc(*num * sizeof(char *) + len);
598 	if (!ret) {
599 		free_no_errno(strings);
600 		return NULL;
601 	}
602 	memcpy(&ret[*num], strings, len);
603 	free_no_errno(strings);
604 
605 	strings = (char *)&ret[*num];
606 	for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
607 		ret[(*num)++] = p;
608 	return ret;
609 }
610 
xs_directory_part(struct xs_handle * h,xs_transaction_t t,const char * path,unsigned int * num)611 static char **xs_directory_part(struct xs_handle *h, xs_transaction_t t,
612 				const char *path, unsigned int *num)
613 {
614 	unsigned int off, result_len;
615 	char gen[24], offstr[8];
616 	struct iovec iovec[2];
617 	char *result = NULL, *strings = NULL;
618 
619 	memset(gen, 0, sizeof(gen));
620 	iovec[0].iov_base = (void *)path;
621 	iovec[0].iov_len = strlen(path) + 1;
622 
623 	for (off = 0;;) {
624 		snprintf(offstr, sizeof(offstr), "%u", off);
625 		iovec[1].iov_base = (void *)offstr;
626 		iovec[1].iov_len = strlen(offstr) + 1;
627 		result = xs_talkv(h, t, XS_DIRECTORY_PART, iovec, 2,
628 				  &result_len);
629 
630 		/* If XS_DIRECTORY_PART isn't supported return E2BIG. */
631 		if (!result) {
632 			if (errno == ENOSYS)
633 				errno = E2BIG;
634 			return NULL;
635 		}
636 
637 		if (off) {
638 			if (strcmp(gen, result)) {
639 				free(result);
640 				free(strings);
641 				strings = NULL;
642 				off = 0;
643 				continue;
644 			}
645 		} else
646 			strncpy(gen, result, sizeof(gen) - 1);
647 
648 		result_len -= strlen(result) + 1;
649 		strings = realloc(strings, off + result_len);
650 		memcpy(strings + off, result + strlen(result) + 1, result_len);
651 		free(result);
652 		off += result_len;
653 
654 		if (off <= 1 || strings[off - 2] == 0)
655 			break;
656 	}
657 
658 	if (off > 1)
659 		off--;
660 
661 	return xs_directory_common(strings, off, num);
662 }
663 
xs_directory(struct xs_handle * h,xs_transaction_t t,const char * path,unsigned int * num)664 char **xs_directory(struct xs_handle *h, xs_transaction_t t,
665 		    const char *path, unsigned int *num)
666 {
667 	char *strings;
668 	unsigned int len;
669 
670 	strings = xs_single(h, t, XS_DIRECTORY, path, &len);
671 	if (!strings) {
672 		if (errno != E2BIG)
673 			return NULL;
674 		return xs_directory_part(h, t, path, num);
675 	}
676 
677 	return xs_directory_common(strings, len, num);
678 }
679 
680 /* Get the value of a single file, nul terminated.
681  * Returns a malloced value: call free() on it after use.
682  * len indicates length in bytes, not including the nul.
683  * Returns NULL on failure.
684  */
xs_read(struct xs_handle * h,xs_transaction_t t,const char * path,unsigned int * len)685 void *xs_read(struct xs_handle *h, xs_transaction_t t,
686 	      const char *path, unsigned int *len)
687 {
688 	return xs_single(h, t, XS_READ, path, len);
689 }
690 
691 /* Write the value of a single file.
692  * Returns false on failure.
693  */
xs_write(struct xs_handle * h,xs_transaction_t t,const char * path,const void * data,unsigned int len)694 bool xs_write(struct xs_handle *h, xs_transaction_t t,
695 	      const char *path, const void *data, unsigned int len)
696 {
697 	struct iovec iovec[2];
698 
699 	iovec[0].iov_base = (void *)path;
700 	iovec[0].iov_len = strlen(path) + 1;
701 	iovec[1].iov_base = (void *)data;
702 	iovec[1].iov_len = len;
703 
704 	return xs_bool(xs_talkv(h, t, XS_WRITE, iovec,
705 				ARRAY_SIZE(iovec), NULL));
706 }
707 
708 /* Create a new directory.
709  * Returns false on failure, or success if it already exists.
710  */
xs_mkdir(struct xs_handle * h,xs_transaction_t t,const char * path)711 bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
712 	      const char *path)
713 {
714 	return xs_bool(xs_single(h, t, XS_MKDIR, path, NULL));
715 }
716 
717 /* Destroy a file or directory (directories must be empty).
718  * Returns false on failure, or success if it doesn't exist.
719  */
xs_rm(struct xs_handle * h,xs_transaction_t t,const char * path)720 bool xs_rm(struct xs_handle *h, xs_transaction_t t,
721 	   const char *path)
722 {
723 	return xs_bool(xs_single(h, t, XS_RM, path, NULL));
724 }
725 
726 /* Get permissions of node (first element is owner).
727  * Returns malloced array, or NULL: call free() after use.
728  */
xs_get_permissions(struct xs_handle * h,xs_transaction_t t,const char * path,unsigned int * num)729 struct xs_permissions *xs_get_permissions(struct xs_handle *h,
730 					  xs_transaction_t t,
731 					  const char *path, unsigned int *num)
732 {
733 	char *strings;
734 	unsigned int len;
735 	struct xs_permissions *ret;
736 
737 	strings = xs_single(h, t, XS_GET_PERMS, path, &len);
738 	if (!strings)
739 		return NULL;
740 
741 	/* Count the strings: each one perms then domid. */
742 	*num = xs_count_strings(strings, len);
743 
744 	/* Transfer to one big alloc for easy freeing. */
745 	ret = malloc(*num * sizeof(struct xs_permissions));
746 	if (!ret) {
747 		free_no_errno(strings);
748 		return NULL;
749 	}
750 
751 	if (!xs_strings_to_perms(ret, *num, strings)) {
752 		free_no_errno(ret);
753 		ret = NULL;
754 	}
755 
756 	free(strings);
757 	return ret;
758 }
759 
760 /* Set permissions of node (must be owner).
761  * Returns false on failure.
762  */
xs_set_permissions(struct xs_handle * h,xs_transaction_t t,const char * path,struct xs_permissions * perms,unsigned int num_perms)763 bool xs_set_permissions(struct xs_handle *h,
764 			xs_transaction_t t,
765 			const char *path,
766 			struct xs_permissions *perms,
767 			unsigned int num_perms)
768 {
769 	unsigned int i;
770 	struct iovec iov[1+num_perms];
771 
772 	iov[0].iov_base = (void *)path;
773 	iov[0].iov_len = strlen(path) + 1;
774 
775 	for (i = 0; i < num_perms; i++) {
776 		char buffer[MAX_STRLEN(unsigned int)+1];
777 
778 		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
779 			goto unwind;
780 
781 		iov[i+1].iov_base = strdup(buffer);
782 		iov[i+1].iov_len = strlen(buffer) + 1;
783 		if (!iov[i+1].iov_base)
784 			goto unwind;
785 	}
786 
787 	if (!xs_bool(xs_talkv(h, t, XS_SET_PERMS, iov, 1+num_perms, NULL)))
788 		goto unwind;
789 	for (i = 0; i < num_perms; i++)
790 		free(iov[i+1].iov_base);
791 	return true;
792 
793 unwind:
794 	num_perms = i;
795 	for (i = 0; i < num_perms; i++)
796 		free_no_errno(iov[i+1].iov_base);
797 	return false;
798 }
799 
800 /* Always return false a functionality has been removed in Xen 4.9 */
xs_restrict(struct xs_handle * h,unsigned domid)801 bool xs_restrict(struct xs_handle *h, unsigned domid)
802 {
803 	return false;
804 }
805 
806 /* Watch a node for changes (poll on fd to detect, or call read_watch()).
807  * When the node (or any child) changes, fd will become readable.
808  * Token is returned when watch is read, to allow matching.
809  * Returns false on failure.
810  */
xs_watch(struct xs_handle * h,const char * path,const char * token)811 bool xs_watch(struct xs_handle *h, const char *path, const char *token)
812 {
813 	struct iovec iov[2];
814 
815 #ifdef USE_PTHREAD
816 #define DEFAULT_THREAD_STACKSIZE (16 * 1024)
817 #define READ_THREAD_STACKSIZE 					\
818 	((DEFAULT_THREAD_STACKSIZE < PTHREAD_STACK_MIN) ? 	\
819 	PTHREAD_STACK_MIN : DEFAULT_THREAD_STACKSIZE)
820 
821 	/* We dynamically create a reader thread on demand. */
822 	mutex_lock(&h->request_mutex);
823 	if (!h->read_thr_exists) {
824 		sigset_t set, old_set;
825 		pthread_attr_t attr;
826 		static size_t stack_size;
827 #ifdef USE_DLSYM
828 		size_t (*getsz)(pthread_attr_t *attr);
829 #endif
830 
831 		if (pthread_attr_init(&attr) != 0) {
832 			mutex_unlock(&h->request_mutex);
833 			return false;
834 		}
835 		if (!stack_size) {
836 #ifdef USE_DLSYM
837 			getsz = dlsym(RTLD_DEFAULT, "__pthread_get_minstack");
838 			if (getsz)
839 				stack_size = getsz(&attr);
840 #endif
841 			if (stack_size < READ_THREAD_STACKSIZE)
842 				stack_size = READ_THREAD_STACKSIZE;
843 		}
844 		if (pthread_attr_setstacksize(&attr, stack_size) != 0) {
845 			pthread_attr_destroy(&attr);
846 			mutex_unlock(&h->request_mutex);
847 			return false;
848 		}
849 
850 		sigfillset(&set);
851 		pthread_sigmask(SIG_SETMASK, &set, &old_set);
852 
853 		if (pthread_create(&h->read_thr, &attr, read_thread, h) != 0) {
854 			pthread_sigmask(SIG_SETMASK, &old_set, NULL);
855 			pthread_attr_destroy(&attr);
856 			mutex_unlock(&h->request_mutex);
857 			return false;
858 		}
859 		h->read_thr_exists = 1;
860 		pthread_sigmask(SIG_SETMASK, &old_set, NULL);
861 		pthread_attr_destroy(&attr);
862 	}
863 	mutex_unlock(&h->request_mutex);
864 #endif
865 
866 	iov[0].iov_base = (void *)path;
867 	iov[0].iov_len = strlen(path) + 1;
868 	iov[1].iov_base = (void *)token;
869 	iov[1].iov_len = strlen(token) + 1;
870 
871 	return xs_bool(xs_talkv(h, XBT_NULL, XS_WATCH, iov,
872 				ARRAY_SIZE(iov), NULL));
873 }
874 
875 
876 /* Clear the pipe token if there are no more pending watchs.
877  * We suppose the watch_mutex is already taken.
878  */
xs_maybe_clear_watch_pipe(struct xs_handle * h)879 static void xs_maybe_clear_watch_pipe(struct xs_handle *h)
880 {
881 	char c;
882 
883 	if (list_empty(&h->watch_list) && (h->watch_pipe[0] != -1))
884 		while (read(h->watch_pipe[0], &c, 1) != 1)
885 			continue;
886 }
887 
888 /* Find out what node change was on (will block if nothing pending).
889  * Returns array of two pointers: path and token, or NULL.
890  * Call free() after use.
891  */
read_watch_internal(struct xs_handle * h,unsigned int * num,int nonblocking)892 static char **read_watch_internal(struct xs_handle *h, unsigned int *num,
893 				  int nonblocking)
894 {
895 	struct xs_stored_msg *msg;
896 	char **ret, *strings;
897 	unsigned int num_strings, i;
898 
899 	mutex_lock(&h->watch_mutex);
900 
901 #ifdef USE_PTHREAD
902 	/* Wait on the condition variable for a watch to fire.
903 	 * If the reader thread doesn't exist yet, then that's because
904 	 * we haven't called xs_watch.	Presumably the application
905 	 * will do so later; in the meantime we just block.
906 	 */
907 	while (list_empty(&h->watch_list) && h->fd != -1) {
908 		if (nonblocking) {
909 			mutex_unlock(&h->watch_mutex);
910 			errno = EAGAIN;
911 			return 0;
912 		}
913 		condvar_wait(&h->watch_condvar, &h->watch_mutex);
914 	}
915 #else /* !defined(USE_PTHREAD) */
916 	/* Read from comms channel ourselves if there are no threads
917 	 * and therefore no reader thread. */
918 
919 	assert(!read_thread_exists(h)); /* not threadsafe but worth a check */
920 	if ((read_message(h, nonblocking) == -1))
921 		return NULL;
922 
923 #endif /* !defined(USE_PTHREAD) */
924 
925 	if (list_empty(&h->watch_list)) {
926 		mutex_unlock(&h->watch_mutex);
927 		errno = EINVAL;
928 		return NULL;
929 	}
930 	msg = list_top(&h->watch_list, struct xs_stored_msg, list);
931 	list_del(&msg->list);
932 
933 	xs_maybe_clear_watch_pipe(h);
934 	mutex_unlock(&h->watch_mutex);
935 
936 	assert(msg->hdr.type == XS_WATCH_EVENT);
937 
938 	strings     = msg->body;
939 	num_strings = xs_count_strings(strings, msg->hdr.len);
940 
941 	ret = malloc(sizeof(char*) * num_strings + msg->hdr.len);
942 	if (!ret) {
943 		free_no_errno(strings);
944 		free_no_errno(msg);
945 		return NULL;
946 	}
947 
948 	ret[0] = (char *)(ret + num_strings);
949 	memcpy(ret[0], strings, msg->hdr.len);
950 
951 	free(strings);
952 	free(msg);
953 
954 	for (i = 1; i < num_strings; i++)
955 		ret[i] = ret[i - 1] + strlen(ret[i - 1]) + 1;
956 
957 	*num = num_strings;
958 
959 	return ret;
960 }
961 
xs_check_watch(struct xs_handle * h)962 char **xs_check_watch(struct xs_handle *h)
963 {
964 	unsigned int num;
965 	char **ret;
966 	ret = read_watch_internal(h, &num, 1);
967 	if (ret) assert(num >= 2);
968 	return ret;
969 }
970 
971 /* Find out what node change was on (will block if nothing pending).
972  * Returns array of two pointers: path and token, or NULL.
973  * Call free() after use.
974  */
xs_read_watch(struct xs_handle * h,unsigned int * num)975 char **xs_read_watch(struct xs_handle *h, unsigned int *num)
976 {
977 	return read_watch_internal(h, num, 0);
978 }
979 
980 /* Remove a watch on a node.
981  * Returns false on failure (no watch on that node).
982  */
xs_unwatch(struct xs_handle * h,const char * path,const char * token)983 bool xs_unwatch(struct xs_handle *h, const char *path, const char *token)
984 {
985 	struct iovec iov[2];
986 	struct xs_stored_msg *msg, *tmsg;
987 	bool res;
988 	char *s, *p;
989 	unsigned int i;
990 	char *l_token, *l_path;
991 
992 	iov[0].iov_base = (char *)path;
993 	iov[0].iov_len = strlen(path) + 1;
994 	iov[1].iov_base = (char *)token;
995 	iov[1].iov_len = strlen(token) + 1;
996 
997 	res = xs_bool(xs_talkv(h, XBT_NULL, XS_UNWATCH, iov,
998 			       ARRAY_SIZE(iov), NULL));
999 
1000 	if (!h->unwatch_filter) /* Don't filter the watch list */
1001 		return res;
1002 
1003 
1004 	/* Filter the watch list to remove potential message */
1005 	mutex_lock(&h->watch_mutex);
1006 
1007 	if (list_empty(&h->watch_list)) {
1008 		mutex_unlock(&h->watch_mutex);
1009 		return res;
1010 	}
1011 
1012 	list_for_each_entry_safe(msg, tmsg, &h->watch_list, list) {
1013 		assert(msg->hdr.type == XS_WATCH_EVENT);
1014 
1015 		s = msg->body;
1016 
1017 		l_token = NULL;
1018 		l_path = NULL;
1019 
1020 		for (p = s, i = 0; p < msg->body + msg->hdr.len; p++) {
1021 			if (*p == '\0')
1022 			{
1023 				if (i == XS_WATCH_TOKEN)
1024 					l_token = s;
1025 				else if (i == XS_WATCH_PATH)
1026 					l_path = s;
1027 				i++;
1028 				s = p + 1;
1029 			}
1030 		}
1031 
1032 		if (l_token && !strcmp(token, l_token) &&
1033 		    l_path && xs_path_is_subpath(path, l_path)) {
1034 			list_del(&msg->list);
1035 			free(msg);
1036 		}
1037 	}
1038 
1039 	xs_maybe_clear_watch_pipe(h);
1040 
1041 	mutex_unlock(&h->watch_mutex);
1042 
1043 	return res;
1044 }
1045 
1046 /* Start a transaction: changes by others will not be seen during this
1047  * transaction, and changes will not be visible to others until end.
1048  * Returns XBT_NULL on failure.
1049  */
xs_transaction_start(struct xs_handle * h)1050 xs_transaction_t xs_transaction_start(struct xs_handle *h)
1051 {
1052 	char *id_str;
1053 	xs_transaction_t id;
1054 
1055 	id_str = xs_single(h, XBT_NULL, XS_TRANSACTION_START, "", NULL);
1056 	if (id_str == NULL)
1057 		return XBT_NULL;
1058 
1059 	id = strtoul(id_str, NULL, 0);
1060 	free(id_str);
1061 
1062 	return id;
1063 }
1064 
1065 /* End a transaction.
1066  * If abandon is true, transaction is discarded instead of committed.
1067  * Returns false on failure, which indicates an error: transactions will
1068  * not fail spuriously.
1069  */
xs_transaction_end(struct xs_handle * h,xs_transaction_t t,bool abort)1070 bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
1071 			bool abort)
1072 {
1073 	char abortstr[2];
1074 
1075 	if (abort)
1076 		strcpy(abortstr, "F");
1077 	else
1078 		strcpy(abortstr, "T");
1079 
1080 	return xs_bool(xs_single(h, t, XS_TRANSACTION_END, abortstr, NULL));
1081 }
1082 
1083 /* Introduce a new domain.
1084  * This tells the store daemon about a shared memory page and event channel
1085  * associated with a domain: the domain uses these to communicate.
1086  */
xs_introduce_domain(struct xs_handle * h,unsigned int domid,unsigned long mfn,unsigned int eventchn)1087 bool xs_introduce_domain(struct xs_handle *h,
1088 			 unsigned int domid, unsigned long mfn,
1089 			 unsigned int eventchn)
1090 {
1091 	char domid_str[MAX_STRLEN(domid)];
1092 	char mfn_str[MAX_STRLEN(mfn)];
1093 	char eventchn_str[MAX_STRLEN(eventchn)];
1094 	struct iovec iov[3];
1095 
1096 	snprintf(domid_str, sizeof(domid_str), "%u", domid);
1097 	snprintf(mfn_str, sizeof(mfn_str), "%lu", mfn);
1098 	snprintf(eventchn_str, sizeof(eventchn_str), "%u", eventchn);
1099 
1100 	iov[0].iov_base = domid_str;
1101 	iov[0].iov_len = strlen(domid_str) + 1;
1102 	iov[1].iov_base = mfn_str;
1103 	iov[1].iov_len = strlen(mfn_str) + 1;
1104 	iov[2].iov_base = eventchn_str;
1105 	iov[2].iov_len = strlen(eventchn_str) + 1;
1106 
1107 	return xs_bool(xs_talkv(h, XBT_NULL, XS_INTRODUCE, iov,
1108 				ARRAY_SIZE(iov), NULL));
1109 }
1110 
xs_set_target(struct xs_handle * h,unsigned int domid,unsigned int target)1111 bool xs_set_target(struct xs_handle *h,
1112 			 unsigned int domid, unsigned int target)
1113 {
1114 	char domid_str[MAX_STRLEN(domid)];
1115 	char target_str[MAX_STRLEN(target)];
1116 	struct iovec iov[2];
1117 
1118 	snprintf(domid_str, sizeof(domid_str), "%u", domid);
1119 	snprintf(target_str, sizeof(target_str), "%u", target);
1120 
1121 	iov[0].iov_base = domid_str;
1122 	iov[0].iov_len = strlen(domid_str) + 1;
1123 	iov[1].iov_base = target_str;
1124 	iov[1].iov_len = strlen(target_str) + 1;
1125 
1126 	return xs_bool(xs_talkv(h, XBT_NULL, XS_SET_TARGET, iov,
1127 				ARRAY_SIZE(iov), NULL));
1128 }
1129 
single_with_domid(struct xs_handle * h,enum xsd_sockmsg_type type,unsigned int domid)1130 static void * single_with_domid(struct xs_handle *h,
1131 				enum xsd_sockmsg_type type,
1132 				unsigned int domid)
1133 {
1134 	char domid_str[MAX_STRLEN(domid)];
1135 
1136 	snprintf(domid_str, sizeof(domid_str), "%u", domid);
1137 
1138 	return xs_single(h, XBT_NULL, type, domid_str, NULL);
1139 }
1140 
xs_release_domain(struct xs_handle * h,unsigned int domid)1141 bool xs_release_domain(struct xs_handle *h, unsigned int domid)
1142 {
1143 	return xs_bool(single_with_domid(h, XS_RELEASE, domid));
1144 }
1145 
1146 /* clear the shutdown bit for the given domain */
xs_resume_domain(struct xs_handle * h,unsigned int domid)1147 bool xs_resume_domain(struct xs_handle *h, unsigned int domid)
1148 {
1149 	return xs_bool(single_with_domid(h, XS_RESUME, domid));
1150 }
1151 
xs_get_domain_path(struct xs_handle * h,unsigned int domid)1152 char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
1153 {
1154 	char domid_str[MAX_STRLEN(domid)];
1155 
1156 	snprintf(domid_str, sizeof(domid_str), "%u", domid);
1157 
1158 	return xs_single(h, XBT_NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
1159 }
1160 
xs_path_is_subpath(const char * parent,const char * child)1161 bool xs_path_is_subpath(const char *parent, const char *child)
1162 {
1163         size_t childlen = strlen(child);
1164         size_t parentlen = strlen(parent);
1165 
1166 	if (childlen < parentlen)
1167 		return false;
1168 
1169 	if (memcmp(child, parent, parentlen))
1170 		return false;
1171 
1172 	if (childlen > parentlen && child[parentlen] != '/')
1173 		return false;
1174 
1175 	return true;
1176 }
1177 
xs_is_domain_introduced(struct xs_handle * h,unsigned int domid)1178 bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid)
1179 {
1180 	char *domain = single_with_domid(h, XS_IS_DOMAIN_INTRODUCED, domid);
1181 	int rc = strcmp("F", domain);
1182 
1183 	free(domain);
1184 	return rc;
1185 }
1186 
xs_suspend_evtchn_port(int domid)1187 int xs_suspend_evtchn_port(int domid)
1188 {
1189     char path[128];
1190     char *portstr;
1191     int port;
1192     unsigned int plen;
1193     struct xs_handle *xs;
1194 
1195     xs = xs_daemon_open();
1196     if (!xs)
1197         return -1;
1198 
1199     sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid);
1200     portstr = xs_read(xs, XBT_NULL, path, &plen);
1201     xs_daemon_close(xs);
1202 
1203     if (!portstr || !plen) {
1204         port = -1;
1205         goto out;
1206     }
1207 
1208     port = atoi(portstr);
1209 
1210 out:
1211     free(portstr);
1212     return port;
1213 }
1214 
xs_control_command(struct xs_handle * h,const char * cmd,void * data,unsigned int len)1215 char *xs_control_command(struct xs_handle *h, const char *cmd,
1216 			 void *data, unsigned int len)
1217 {
1218 	struct iovec iov[2];
1219 
1220 	iov[0].iov_base = (void *)cmd;
1221 	iov[0].iov_len = strlen(cmd) + 1;
1222 	iov[1].iov_base = data;
1223 	iov[1].iov_len = len;
1224 
1225 	return xs_talkv(h, XBT_NULL, XS_CONTROL, iov,
1226 			ARRAY_SIZE(iov), NULL);
1227 }
1228 
xs_debug_command(struct xs_handle * h,const char * cmd,void * data,unsigned int len)1229 char *xs_debug_command(struct xs_handle *h, const char *cmd,
1230 		       void *data, unsigned int len)
1231 {
1232 	return xs_control_command(h, cmd, data, len);
1233 }
1234 
read_message(struct xs_handle * h,int nonblocking)1235 static int read_message(struct xs_handle *h, int nonblocking)
1236 {
1237 	/* IMPORTANT: It is forbidden to call this function without
1238 	 * acquiring the request lock and checking that h->read_thr_exists
1239 	 * is false.  See "Lock discipline" in struct xs_handle, above. */
1240 
1241 	/* If nonblocking==1, this function will always read either
1242 	 * nothing, returning -1 and setting errno==EAGAIN, or we read
1243 	 * whole amount requested.  Ie as soon as we have the start of
1244 	 * the message we block until we get all of it.
1245 	 */
1246 
1247 	struct xs_stored_msg *msg = NULL;
1248 	char *body = NULL;
1249 	int saved_errno = 0;
1250 	int ret = -1;
1251 
1252 	/* Allocate message structure and read the message header. */
1253 	msg = malloc(sizeof(*msg));
1254 	if (msg == NULL)
1255 		goto error;
1256 	cleanup_push_heap(msg);
1257 	if (!read_all(h->fd, &msg->hdr, sizeof(msg->hdr), nonblocking)) { /* Cancellation point */
1258 		saved_errno = errno;
1259 		goto error_freemsg;
1260 	}
1261 
1262 	/* Sanity check message body length. */
1263 	if (msg->hdr.len > XENSTORE_PAYLOAD_MAX) {
1264 		saved_errno = E2BIG;
1265 		goto error_freemsg;
1266 	}
1267 
1268 	/* Allocate and read the message body. */
1269 	body = msg->body = malloc(msg->hdr.len + 1);
1270 	if (body == NULL)
1271 		goto error_freemsg;
1272 	cleanup_push_heap(body);
1273 	if (!read_all(h->fd, body, msg->hdr.len, 0)) { /* Cancellation point */
1274 		saved_errno = errno;
1275 		goto error_freebody;
1276 	}
1277 
1278 	body[msg->hdr.len] = '\0';
1279 
1280 	if (msg->hdr.type == XS_WATCH_EVENT) {
1281 		mutex_lock(&h->watch_mutex);
1282 		cleanup_push(pthread_mutex_unlock, &h->watch_mutex);
1283 
1284 		/* Kick users out of their select() loop. */
1285 		if (list_empty(&h->watch_list) &&
1286 		    (h->watch_pipe[1] != -1))
1287 			while (write(h->watch_pipe[1], body, 1) != 1) /* Cancellation point */
1288 				continue;
1289 
1290 		list_add_tail(&msg->list, &h->watch_list);
1291 
1292 		condvar_signal(&h->watch_condvar);
1293 
1294 		cleanup_pop(1);
1295 	} else {
1296 		mutex_lock(&h->reply_mutex);
1297 
1298 		/* There should only ever be one response pending! */
1299 		if (!list_empty(&h->reply_list)) {
1300 			mutex_unlock(&h->reply_mutex);
1301 			saved_errno = EEXIST;
1302 			goto error_freebody;
1303 		}
1304 
1305 		list_add_tail(&msg->list, &h->reply_list);
1306 		condvar_signal(&h->reply_condvar);
1307 
1308 		mutex_unlock(&h->reply_mutex);
1309 	}
1310 
1311 	ret = 0;
1312 
1313 error_freebody:
1314 	cleanup_pop_heap(ret == -1, body);
1315 error_freemsg:
1316 	cleanup_pop_heap(ret == -1, msg);
1317 error:
1318 	errno = saved_errno;
1319 
1320 	return ret;
1321 }
1322 
1323 #ifdef USE_PTHREAD
read_thread(void * arg)1324 static void *read_thread(void *arg)
1325 {
1326 	struct xs_handle *h = arg;
1327 	int fd;
1328 
1329 	while (read_message(h, 0) != -1)
1330 		continue;
1331 
1332 	/* An error return from read_message leaves the socket in an undefined
1333 	 * state; we might have read only the header and not the message after
1334 	 * it, or (more commonly) the other end has closed the connection.
1335 	 * Since further communication is unsafe, close the socket.
1336 	 */
1337 	fd = h->fd;
1338 	h->fd = -1;
1339 	close(fd);
1340 
1341 	/* wake up all waiters */
1342 	pthread_mutex_lock(&h->reply_mutex);
1343 	pthread_cond_broadcast(&h->reply_condvar);
1344 	pthread_mutex_unlock(&h->reply_mutex);
1345 
1346 	pthread_mutex_lock(&h->watch_mutex);
1347 	pthread_cond_broadcast(&h->watch_condvar);
1348 	pthread_mutex_unlock(&h->watch_mutex);
1349 
1350 	return NULL;
1351 }
1352 #endif
1353 
expanding_buffer_ensure(struct expanding_buffer * ebuf,int min_avail)1354 char *expanding_buffer_ensure(struct expanding_buffer *ebuf, int min_avail)
1355 {
1356 	int want;
1357 	char *got;
1358 
1359 	if (ebuf->avail >= min_avail)
1360 		return ebuf->buf;
1361 
1362 	if (min_avail >= INT_MAX/3)
1363 		return 0;
1364 
1365 	want = ebuf->avail + min_avail + 10;
1366 	got = realloc(ebuf->buf, want);
1367 	if (!got)
1368 		return 0;
1369 
1370 	ebuf->buf = got;
1371 	ebuf->avail = want;
1372 	return ebuf->buf;
1373 }
1374 
sanitise_value(struct expanding_buffer * ebuf,const char * val,unsigned len)1375 char *sanitise_value(struct expanding_buffer *ebuf,
1376 		     const char *val, unsigned len)
1377 {
1378 	int used, remain, c;
1379 	unsigned char *ip;
1380 
1381 #define ADD(c) (ebuf->buf[used++] = (c))
1382 #define ADDF(f,c) (used += sprintf(ebuf->buf+used, (f), (c)))
1383 
1384 	assert(len < INT_MAX/5);
1385 
1386 	ip = (unsigned char *)val;
1387 	used = 0;
1388 	remain = len;
1389 
1390 	if (!expanding_buffer_ensure(ebuf, remain + 1))
1391 		return NULL;
1392 
1393 	while (remain-- > 0) {
1394 		c= *ip++;
1395 
1396 		if (c >= ' ' && c <= '~' && c != '\\') {
1397 			ADD(c);
1398 			continue;
1399 		}
1400 
1401 		if (!expanding_buffer_ensure(ebuf, used + remain + 5))
1402 			/* for "<used>\\nnn<remain>\0" */
1403 			return 0;
1404 
1405 		ADD('\\');
1406 		switch (c) {
1407 		case '\t':  ADD('t');   break;
1408 		case '\n':  ADD('n');   break;
1409 		case '\r':  ADD('r');   break;
1410 		case '\\':  ADD('\\');  break;
1411 		default:
1412 			if (c < 010) ADDF("%03o", c);
1413 			else         ADDF("x%02x", c);
1414 		}
1415 	}
1416 
1417 	ADD(0);
1418 	assert(used <= ebuf->avail);
1419 	return ebuf->buf;
1420 
1421 #undef ADD
1422 #undef ADDF
1423 }
1424 
unsanitise_value(char * out,unsigned * out_len_r,const char * in)1425 void unsanitise_value(char *out, unsigned *out_len_r, const char *in)
1426 {
1427 	const char *ip;
1428 	char *op;
1429 	unsigned c;
1430 	int n;
1431 
1432 	for (ip = in, op = out; (c = *ip++); *op++ = c) {
1433 		if (c == '\\') {
1434 			c = *ip++;
1435 
1436 #define GETF(f) do {					\
1437 			n = 0;				\
1438 			sscanf(ip, f "%n", &c, &n);	\
1439 			ip += n;			\
1440 		} while (0)
1441 
1442 			switch (c) {
1443 			case 't':              c= '\t';            break;
1444 			case 'n':              c= '\n';            break;
1445 			case 'r':              c= '\r';            break;
1446 			case '\\':             c= '\\';            break;
1447 			case 'x':                    GETF("%2x");  break;
1448 			case '0': case '4':
1449 			case '1': case '5':
1450 			case '2': case '6':
1451 			case '3': case '7':    --ip; GETF("%3o");  break;
1452 			case 0:                --ip;               break;
1453 			default:;
1454 			}
1455 #undef GETF
1456 		}
1457 	}
1458 
1459 	*op = 0;
1460 
1461 	if (out_len_r)
1462 		*out_len_r = op - out;
1463 }
1464 
1465 /*
1466  * Local variables:
1467  *  mode: C
1468  *  c-file-style: "linux"
1469  *  indent-tabs-mode: t
1470  *  c-basic-offset: 8
1471  *  tab-width: 8
1472  * End:
1473  */
1474