1 /*
2 Common routines between Xen store user library and daemon.
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 #include <unistd.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include "xenstore_lib.h"
25
26 /* Common routines for the Xen store daemon and client library. */
27
xs_daemon_rootdir(void)28 const char *xs_daemon_rootdir(void)
29 {
30 char *s = getenv("XENSTORED_ROOTDIR");
31 return (s ? s : XEN_LIB_STORED);
32 }
33
xs_daemon_rundir(void)34 const char *xs_daemon_rundir(void)
35 {
36 char *s = getenv("XENSTORED_RUNDIR");
37 return (s ? s : XEN_RUN_STORED);
38 }
39
xs_daemon_path(void)40 static const char *xs_daemon_path(void)
41 {
42 static char buf[PATH_MAX];
43 char *s = getenv("XENSTORED_PATH");
44 if (s)
45 return s;
46 if (snprintf(buf, sizeof(buf), "%s/socket",
47 xs_daemon_rundir()) >= PATH_MAX)
48 return NULL;
49 return buf;
50 }
51
xs_daemon_tdb(void)52 const char *xs_daemon_tdb(void)
53 {
54 static char buf[PATH_MAX];
55 snprintf(buf, sizeof(buf), "%s/tdb", xs_daemon_rootdir());
56 return buf;
57 }
58
xs_daemon_socket(void)59 const char *xs_daemon_socket(void)
60 {
61 return xs_daemon_path();
62 }
63
xs_daemon_socket_ro(void)64 const char *xs_daemon_socket_ro(void)
65 {
66 static char buf[PATH_MAX];
67 const char *s = xs_daemon_path();
68 if (s == NULL)
69 return NULL;
70 if (snprintf(buf, sizeof(buf), "%s_ro", s) >= PATH_MAX)
71 return NULL;
72 return buf;
73 }
74
xs_domain_dev(void)75 const char *xs_domain_dev(void)
76 {
77 char *s = getenv("XENSTORED_PATH");
78 if (s)
79 return s;
80 #if defined(__RUMPUSER_XEN__) || defined(__RUMPRUN__)
81 return "/dev/xen/xenbus";
82 #elif defined(__linux__)
83 if (access("/dev/xen/xenbus", F_OK) == 0)
84 return "/dev/xen/xenbus";
85 return "/proc/xen/xenbus";
86 #elif defined(__NetBSD__)
87 return "/kern/xen/xenbus";
88 #elif defined(__FreeBSD__)
89 return "/dev/xen/xenstore";
90 #else
91 return "/dev/xen/xenbus";
92 #endif
93 }
94
95 /* Simple routines for writing to sockets, etc. */
xs_write_all(int fd,const void * data,unsigned int len)96 bool xs_write_all(int fd, const void *data, unsigned int len)
97 {
98 while (len) {
99 int done;
100
101 done = write(fd, data, len);
102 if (done < 0 && errno == EINTR)
103 continue;
104 if (done <= 0)
105 return false;
106 data += done;
107 len -= done;
108 }
109
110 return true;
111 }
112
113 /* Convert strings to permissions. False if a problem. */
xs_strings_to_perms(struct xs_permissions * perms,unsigned int num,const char * strings)114 bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
115 const char *strings)
116 {
117 const char *p;
118 char *end;
119 unsigned int i;
120
121 for (p = strings, i = 0; i < num; i++) {
122 /* "r", "w", or "b" for both. */
123 switch (*p) {
124 case 'r':
125 perms[i].perms = XS_PERM_READ;
126 break;
127 case 'w':
128 perms[i].perms = XS_PERM_WRITE;
129 break;
130 case 'b':
131 perms[i].perms = XS_PERM_READ|XS_PERM_WRITE;
132 break;
133 case 'n':
134 perms[i].perms = XS_PERM_NONE;
135 break;
136 default:
137 errno = EINVAL;
138 return false;
139 }
140 p++;
141 perms[i].id = strtol(p, &end, 0);
142 if (*end || !*p) {
143 errno = EINVAL;
144 return false;
145 }
146 p = end + 1;
147 }
148 return true;
149 }
150
151 /* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */
xs_perm_to_string(const struct xs_permissions * perm,char * buffer,size_t buf_len)152 bool xs_perm_to_string(const struct xs_permissions *perm,
153 char *buffer, size_t buf_len)
154 {
155 switch ((int)perm->perms) {
156 case XS_PERM_WRITE:
157 *buffer = 'w';
158 break;
159 case XS_PERM_READ:
160 *buffer = 'r';
161 break;
162 case XS_PERM_READ|XS_PERM_WRITE:
163 *buffer = 'b';
164 break;
165 case XS_PERM_NONE:
166 *buffer = 'n';
167 break;
168 default:
169 errno = EINVAL;
170 return false;
171 }
172 snprintf(buffer+1, buf_len-1, "%i", (int)perm->id);
173 return true;
174 }
175
176 /* Given a string and a length, count how many strings (nul terms). */
xs_count_strings(const char * strings,unsigned int len)177 unsigned int xs_count_strings(const char *strings, unsigned int len)
178 {
179 unsigned int num;
180 const char *p;
181
182 for (p = strings, num = 0; p < strings + len; p++)
183 if (*p == '\0')
184 num++;
185
186 return num;
187 }
188