1/* 2 * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * Copyright (c) 1993 25 * The Regents of the University of California. All rights reserved. 26 * 27 * Redistribution and use in source and binary forms, with or without 28 * modification, are permitted provided that the following conditions 29 * are met: 30 * 1. Redistributions of source code must retain the above copyright 31 * notice, this list of conditions and the following disclaimer. 32 * 2. Redistributions in binary form must reproduce the above copyright 33 * notice, this list of conditions and the following disclaimer in the 34 * documentation and/or other materials provided with the distribution. 35 * 3. All advertising materials mentioning features or use of this software 36 * must display the following acknowledgement: 37 * This product includes software developed by the University of 38 * California, Berkeley and its contributors. 39 * 4. Neither the name of the University nor the names of its contributors 40 * may be used to endorse or promote products derived from this software 41 * without specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 * SUCH DAMAGE. 54 */ 55 56 57#include <sys/param.h> 58#include <sys/sysctl.h> 59 60#include <errno.h> 61#include <paths.h> 62#include <stdlib.h> 63#include <string.h> 64#include <unistd.h> 65#include <stdio.h> /* for P_tmpdir */ 66 67#ifndef __has_include 68#include <dirhelper_priv.h> 69#else 70#if __has_include(<dirhelper_priv.h>) 71#include <dirhelper_priv.h> 72#else 73typedef enum { 74 DIRHELPER_USER_LOCAL = 0, 75 DIRHELPER_USER_LOCAL_TEMP, 76 DIRHELPER_USER_LOCAL_CACHE, 77 DIRHELPER_USER_LOCAL_LAST = DIRHELPER_USER_LOCAL_CACHE 78} dirhelper_which_t; 79#endif 80#endif 81 82#include "libc_private.h" 83 84#if __DARWIN_UNIX03 85static char *(*__dirhelper_func)(int, char *, size_t); 86 87__attribute__((__visibility__("hidden"))) 88void 89__confstr_init(const struct _libc_functions *funcs) 90{ 91 __dirhelper_func = funcs->dirhelper; 92} 93 94__attribute__((__visibility__("hidden"))) 95char * 96__dirhelper(dirhelper_which_t which, char *path, size_t pathlen) 97{ 98 if (__dirhelper_func) { 99 return __dirhelper_func(which, path, pathlen); 100 } else { 101 return NULL; 102 } 103} 104#else // !__DARWIN_UNIX03 105__attribute__((__visibility__("hidden"))) 106char *__dirhelper(dirhelper_which_t which, char *path, size_t pathlen); 107#endif // !__DARWIN_UNIX03 108 109#if __DARWIN_UNIX03 110#define CONFSTR_ERR_RET 0 111#else /* !__DARWIN_UNIX03 */ 112#define CONFSTR_ERR_RET -1 113#endif /* __DARWIN_UNIX03 */ 114 115size_t 116confstr(name, buf, len) 117 int name; 118 char *buf; 119 size_t len; 120{ 121 size_t tlen; 122 int mib[2], sverrno; 123 char *p; 124 125 switch (name) { 126 case _CS_PATH: 127 mib[0] = CTL_USER; 128 mib[1] = USER_CS_PATH; 129 if (sysctl(mib, 2, NULL, &tlen, NULL, 0) == -1) 130 return (CONFSTR_ERR_RET); 131 if (len != 0 && buf != NULL) { 132 if ((p = malloc(tlen)) == NULL) 133 return (CONFSTR_ERR_RET); 134 if (sysctl(mib, 2, p, &tlen, NULL, 0) == -1) { 135 sverrno = errno; 136 free(p); 137 errno = sverrno; 138 return (CONFSTR_ERR_RET); 139 } 140 /* 141 * POSIX 1003.2 requires partial return of 142 * the string -- that should be *real* useful. 143 */ 144 (void)strncpy(buf, p, len - 1); 145 buf[len - 1] = '\0'; 146 free(p); 147 } 148 return (tlen); 149 150 case _CS_POSIX_V6_ILP32_OFF32_CFLAGS: 151 case _CS_XBS5_ILP32_OFF32_CFLAGS: /* legacy */ 152 153 case _CS_POSIX_V6_ILP32_OFF32_LDFLAGS: 154 case _CS_XBS5_ILP32_OFF32_LDFLAGS: /* legacy */ 155 156 case _CS_POSIX_V6_ILP32_OFF32_LIBS: 157 case _CS_XBS5_ILP32_OFF32_LIBS: /* legacy */ 158 159 case _CS_XBS5_ILP32_OFF32_LINTFLAGS: /* legacy */ 160 161 case _CS_POSIX_V6_ILP32_OFFBIG_LIBS: 162 case _CS_XBS5_ILP32_OFFBIG_LIBS: /* legacy */ 163 164 case _CS_XBS5_ILP32_OFFBIG_LINTFLAGS: /* legacy */ 165 166 case _CS_POSIX_V6_LP64_OFF64_LIBS: 167 case _CS_XBS5_LP64_OFF64_LIBS: /* legacy */ 168 169 case _CS_XBS5_LP64_OFF64_LINTFLAGS: /* legacy */ 170 171 case _CS_POSIX_V6_LPBIG_OFFBIG_LIBS: 172 case _CS_XBS5_LPBIG_OFFBIG_LIBS: /* legacy */ 173 174 case _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS: /* legacy */ 175 /* No special flags... yet */ 176 p = ""; 177 goto docopy; 178 179 case _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS: 180 case _CS_XBS5_ILP32_OFFBIG_CFLAGS: /* legacy */ 181 182 case _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS: 183 case _CS_XBS5_ILP32_OFFBIG_LDFLAGS: /* legacy */ 184 p = "-W 32"; 185 goto docopy; 186 187 case _CS_POSIX_V6_LP64_OFF64_CFLAGS: 188 case _CS_XBS5_LP64_OFF64_CFLAGS: /* legacy */ 189 190 case _CS_POSIX_V6_LP64_OFF64_LDFLAGS: 191 case _CS_XBS5_LP64_OFF64_LDFLAGS: /* legacy */ 192 193 case _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS: 194 case _CS_XBS5_LPBIG_OFFBIG_CFLAGS: /* legacy */ 195 196 case _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS: 197 case _CS_XBS5_LPBIG_OFFBIG_LDFLAGS: /* legacy */ 198 p = "-W 64"; 199 goto docopy; 200 201 case _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS: 202 if (sizeof(long) >= 8) 203 p = "_POSIX_V6_LP64_OFF64"; 204 else 205 p = "_POSIX_V6_ILP32_OFFBIG"; 206 207docopy: 208 if (len != 0 && buf != NULL) 209 strlcpy(buf, p, len); 210 return (strlen(p) + 1); 211 212 case _CS_DARWIN_USER_DIR: 213 if ((p = alloca(PATH_MAX)) == NULL) { 214 errno = ENOMEM; 215 return (CONFSTR_ERR_RET); 216 } 217 if (__dirhelper(DIRHELPER_USER_LOCAL, p, PATH_MAX) == NULL) { 218 if (errno != ENOMEM) 219 errno = EIO; 220 return (CONFSTR_ERR_RET); 221 } 222 goto docopy; 223 224 case _CS_DARWIN_USER_TEMP_DIR: 225 if ((p = alloca(PATH_MAX)) == NULL) { 226 errno = ENOMEM; 227 return (CONFSTR_ERR_RET); 228 } 229 if (__dirhelper(DIRHELPER_USER_LOCAL_TEMP, p, PATH_MAX) == NULL) { 230 int dh_errno = errno; 231 /* 232 * If __dirhelper() fails, try TMPDIR and P_tmpdir, 233 * finally failing otherwise. 234 */ 235 if ((p = getenv("TMPDIR")) && access(p, W_OK) == 0) 236 goto docopy; 237 if (access(p = P_tmpdir, W_OK) == 0) 238 goto docopy; 239 if (dh_errno == ENOMEM) 240 errno = ENOMEM; 241 else 242 errno = EIO; 243 return (CONFSTR_ERR_RET); 244 } 245 goto docopy; 246 247 case _CS_DARWIN_USER_CACHE_DIR: 248 if ((p = alloca(PATH_MAX)) == NULL) { 249 errno = ENOMEM; 250 return (CONFSTR_ERR_RET); 251 } 252 if (__dirhelper(DIRHELPER_USER_LOCAL_CACHE, p, PATH_MAX) == NULL) { 253 if (errno != ENOMEM) 254 errno = EIO; 255 return (CONFSTR_ERR_RET); 256 } 257 goto docopy; 258 259 default: 260 errno = EINVAL; 261 return (0); 262 } 263 /* NOTREACHED */ 264} 265