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 & ~XS_PERM_IGNORE) { 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