1 1.1 elric /* $NetBSD: afssys.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (c) 1995 - 2000, 2002, 2004, 2005 Kungliga Tekniska Hgskolan 5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden). 6 1.1 elric * All rights reserved. 7 1.1 elric * 8 1.1 elric * Redistribution and use in source and binary forms, with or without 9 1.1 elric * modification, are permitted provided that the following conditions 10 1.1 elric * are met: 11 1.1 elric * 12 1.1 elric * 1. Redistributions of source code must retain the above copyright 13 1.1 elric * notice, this list of conditions and the following disclaimer. 14 1.1 elric * 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors 20 1.1 elric * may be used to endorse or promote products derived from this software 21 1.1 elric * without specific prior written permission. 22 1.1 elric * 23 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 elric * SUCH DAMAGE. 34 1.1 elric */ 35 1.1 elric 36 1.1 elric #include "kafs_locl.h" 37 1.1 elric 38 1.1 elric struct procdata { 39 1.1 elric unsigned long param4; 40 1.1 elric unsigned long param3; 41 1.1 elric unsigned long param2; 42 1.1 elric unsigned long param1; 43 1.1 elric unsigned long syscall; 44 1.1 elric }; 45 1.2 christos #ifdef __GNU__ 46 1.2 christos #define _IOT_procdata _IOT(_IOTS(long), 5, 0, 0, 0, 0) 47 1.2 christos #define VIOC_SYSCALL_PROC _IOW('C', 1, struct procdata) 48 1.2 christos #else 49 1.1 elric #define VIOC_SYSCALL_PROC _IOW('C', 1, void *) 50 1.2 christos #endif 51 1.1 elric 52 1.1 elric struct devdata { 53 1.1 elric unsigned long syscall; 54 1.1 elric unsigned long param1; 55 1.1 elric unsigned long param2; 56 1.1 elric unsigned long param3; 57 1.1 elric unsigned long param4; 58 1.1 elric unsigned long param5; 59 1.1 elric unsigned long param6; 60 1.1 elric unsigned long retval; 61 1.1 elric }; 62 1.2 christos #ifdef __GNU__ 63 1.2 christos #define _IOT_devdata _IOT(_IOTS(long), 8, 0, 0, 0, 0) 64 1.2 christos #endif 65 1.1 elric #ifdef _IOWR 66 1.1 elric #define VIOC_SYSCALL_DEV _IOWR('C', 2, struct devdata) 67 1.1 elric #define VIOC_SYSCALL_DEV_OPENAFS _IOWR('C', 1, struct devdata) 68 1.1 elric #endif 69 1.1 elric 70 1.2 christos #ifdef _IOW 71 1.2 christos #ifdef _ILP32 72 1.2 christos struct sundevdata { 73 1.2 christos uint32_t param6; 74 1.2 christos uint32_t param5; 75 1.2 christos uint32_t param4; 76 1.2 christos uint32_t param3; 77 1.2 christos uint32_t param2; 78 1.2 christos uint32_t param1; 79 1.2 christos uint32_t syscall; 80 1.2 christos }; 81 1.2 christos #define VIOC_SUN_SYSCALL_DEV _IOW('C', 2, struct sundevdata) 82 1.2 christos #else 83 1.2 christos struct sundevdata { 84 1.2 christos uint64_t param6; 85 1.2 christos uint64_t param5; 86 1.2 christos uint64_t param4; 87 1.2 christos uint64_t param3; 88 1.2 christos uint64_t param2; 89 1.2 christos uint64_t param1; 90 1.2 christos uint64_t syscall; 91 1.2 christos }; 92 1.2 christos #define VIOC_SUN_SYSCALL_DEV _IOW('C', 1, struct sundevdata) 93 1.2 christos #endif 94 1.2 christos #endif /* _IOW */ 95 1.2 christos 96 1.1 elric 97 1.1 elric int _kafs_debug; /* this should be done in a better way */ 98 1.1 elric 99 1.1 elric #define UNKNOWN_ENTRY_POINT (-1) 100 1.1 elric #define NO_ENTRY_POINT 0 101 1.1 elric #define SINGLE_ENTRY_POINT 1 102 1.1 elric #define MULTIPLE_ENTRY_POINT 2 103 1.1 elric #define SINGLE_ENTRY_POINT2 3 104 1.1 elric #define SINGLE_ENTRY_POINT3 4 105 1.1 elric #define LINUX_PROC_POINT 5 106 1.1 elric #define AIX_ENTRY_POINTS 6 107 1.1 elric #define MACOS_DEV_POINT 7 108 1.2 christos #define SUN_PROC_POINT 8 109 1.1 elric 110 1.1 elric static int afs_entry_point = UNKNOWN_ENTRY_POINT; 111 1.1 elric static int afs_syscalls[2]; 112 1.1 elric static char *afs_ioctlpath; 113 1.1 elric static unsigned long afs_ioctlnum; 114 1.1 elric 115 1.1 elric /* Magic to get AIX syscalls to work */ 116 1.1 elric #ifdef _AIX 117 1.1 elric 118 1.1 elric static int (*Pioctl)(char*, int, struct ViceIoctl*, int); 119 1.1 elric static int (*Setpag)(void); 120 1.1 elric 121 1.1 elric #include "dlfcn.h" 122 1.1 elric 123 1.1 elric /* 124 1.1 elric * 125 1.1 elric */ 126 1.1 elric 127 1.1 elric static int 128 1.1 elric try_aix(void) 129 1.1 elric { 130 1.1 elric #ifdef STATIC_AFS_SYSCALLS 131 1.1 elric Pioctl = aix_pioctl; 132 1.1 elric Setpag = aix_setpag; 133 1.1 elric #else 134 1.1 elric void *ptr; 135 1.1 elric char path[MaxPathLen], *p; 136 1.1 elric /* 137 1.1 elric * If we are root or running setuid don't trust AFSLIBPATH! 138 1.1 elric */ 139 1.1 elric if (getuid() != 0 && !issuid() && (p = getenv("AFSLIBPATH")) != NULL) 140 1.1 elric strlcpy(path, p, sizeof(path)); 141 1.1 elric else 142 1.1 elric snprintf(path, sizeof(path), "%s/afslib.so", LIBDIR); 143 1.2 christos 144 1.1 elric ptr = dlopen(path, RTLD_NOW); 145 1.1 elric if(ptr == NULL) { 146 1.1 elric if(_kafs_debug) { 147 1.1 elric if(errno == ENOEXEC && (p = dlerror()) != NULL) 148 1.1 elric fprintf(stderr, "dlopen(%s): %s\n", path, p); 149 1.1 elric else if (errno != ENOENT) 150 1.1 elric fprintf(stderr, "dlopen(%s): %s\n", path, strerror(errno)); 151 1.1 elric } 152 1.1 elric return 1; 153 1.1 elric } 154 1.1 elric Setpag = (int (*)(void))dlsym(ptr, "aix_setpag"); 155 1.1 elric Pioctl = (int (*)(char*, int, 156 1.1 elric struct ViceIoctl*, int))dlsym(ptr, "aix_pioctl"); 157 1.1 elric #endif 158 1.1 elric afs_entry_point = AIX_ENTRY_POINTS; 159 1.1 elric return 0; 160 1.1 elric } 161 1.1 elric #endif /* _AIX */ 162 1.1 elric 163 1.1 elric /* 164 1.1 elric * This probably only works under Solaris and could get confused if 165 1.1 elric * there's a /etc/name_to_sysnum file. 166 1.1 elric */ 167 1.1 elric 168 1.1 elric #if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3) 169 1.1 elric 170 1.1 elric #define _PATH_ETC_NAME_TO_SYSNUM "/etc/name_to_sysnum" 171 1.1 elric 172 1.1 elric static int 173 1.1 elric map_syscall_name_to_number (const char *str, int *res) 174 1.1 elric { 175 1.1 elric FILE *f; 176 1.1 elric char buf[256]; 177 1.1 elric size_t str_len = strlen (str); 178 1.1 elric 179 1.1 elric f = fopen (_PATH_ETC_NAME_TO_SYSNUM, "r"); 180 1.1 elric if (f == NULL) 181 1.1 elric return -1; 182 1.1 elric while (fgets (buf, sizeof(buf), f) != NULL) { 183 1.1 elric if (buf[0] == '#') 184 1.1 elric continue; 185 1.1 elric 186 1.1 elric if (strncmp (str, buf, str_len) == 0) { 187 1.1 elric char *begptr = buf + str_len; 188 1.1 elric char *endptr; 189 1.1 elric long val = strtol (begptr, &endptr, 0); 190 1.1 elric 191 1.1 elric if (val != 0 && endptr != begptr) { 192 1.1 elric fclose (f); 193 1.1 elric *res = val; 194 1.1 elric return 0; 195 1.1 elric } 196 1.1 elric } 197 1.1 elric } 198 1.1 elric fclose (f); 199 1.1 elric return -1; 200 1.1 elric } 201 1.1 elric #endif 202 1.1 elric 203 1.1 elric static int 204 1.1 elric try_ioctlpath(const char *path, unsigned long ioctlnum, int entrypoint) 205 1.1 elric { 206 1.1 elric int fd, ret, saved_errno; 207 1.1 elric 208 1.1 elric fd = open(path, O_RDWR); 209 1.1 elric if (fd < 0) 210 1.1 elric return 1; 211 1.1 elric switch (entrypoint) { 212 1.1 elric case LINUX_PROC_POINT: { 213 1.1 elric struct procdata data = { 0, 0, 0, 0, AFSCALL_PIOCTL }; 214 1.1 elric data.param2 = (unsigned long)VIOCGETTOK; 215 1.1 elric ret = ioctl(fd, ioctlnum, &data); 216 1.1 elric break; 217 1.1 elric } 218 1.1 elric case MACOS_DEV_POINT: { 219 1.1 elric struct devdata data = { AFSCALL_PIOCTL, 0, 0, 0, 0, 0, 0, 0 }; 220 1.1 elric data.param2 = (unsigned long)VIOCGETTOK; 221 1.1 elric ret = ioctl(fd, ioctlnum, &data); 222 1.1 elric break; 223 1.1 elric } 224 1.2 christos case SUN_PROC_POINT: { 225 1.2 christos struct sundevdata data = { 0, 0, 0, 0, 0, 0, AFSCALL_PIOCTL }; 226 1.2 christos data.param2 = (unsigned long)VIOCGETTOK; 227 1.2 christos ret = ioctl(fd, ioctlnum, &data); 228 1.2 christos break; 229 1.2 christos } 230 1.1 elric default: 231 1.1 elric abort(); 232 1.1 elric } 233 1.1 elric saved_errno = errno; 234 1.1 elric close(fd); 235 1.1 elric /* 236 1.1 elric * Be quite liberal in what error are ok, the first is the one 237 1.1 elric * that should trigger given that params is NULL. 238 1.1 elric */ 239 1.1 elric if (ret && 240 1.1 elric (saved_errno != EFAULT && 241 1.1 elric saved_errno != EDOM && 242 1.1 elric saved_errno != ENOTCONN)) 243 1.1 elric return 1; 244 1.1 elric afs_ioctlnum = ioctlnum; 245 1.1 elric afs_ioctlpath = strdup(path); 246 1.1 elric if (afs_ioctlpath == NULL) 247 1.1 elric return 1; 248 1.1 elric afs_entry_point = entrypoint; 249 1.1 elric return 0; 250 1.1 elric } 251 1.1 elric 252 1.1 elric static int 253 1.1 elric do_ioctl(void *data) 254 1.1 elric { 255 1.1 elric int fd, ret, saved_errno; 256 1.1 elric fd = open(afs_ioctlpath, O_RDWR); 257 1.1 elric if (fd < 0) { 258 1.1 elric errno = EINVAL; 259 1.1 elric return -1; 260 1.1 elric } 261 1.1 elric ret = ioctl(fd, afs_ioctlnum, data); 262 1.1 elric saved_errno = errno; 263 1.1 elric close(fd); 264 1.1 elric errno = saved_errno; 265 1.1 elric return ret; 266 1.1 elric } 267 1.1 elric 268 1.1 elric int 269 1.1 elric k_pioctl(char *a_path, 270 1.1 elric int o_opcode, 271 1.1 elric struct ViceIoctl *a_paramsP, 272 1.1 elric int a_followSymlinks) 273 1.1 elric { 274 1.1 elric #ifndef NO_AFS 275 1.1 elric switch(afs_entry_point){ 276 1.1 elric #if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3) 277 1.1 elric case SINGLE_ENTRY_POINT: 278 1.1 elric case SINGLE_ENTRY_POINT2: 279 1.1 elric case SINGLE_ENTRY_POINT3: 280 1.1 elric return syscall(afs_syscalls[0], AFSCALL_PIOCTL, 281 1.1 elric a_path, o_opcode, a_paramsP, a_followSymlinks); 282 1.1 elric #endif 283 1.1 elric #if defined(AFS_PIOCTL) 284 1.1 elric case MULTIPLE_ENTRY_POINT: 285 1.1 elric return syscall(afs_syscalls[0], 286 1.1 elric a_path, o_opcode, a_paramsP, a_followSymlinks); 287 1.1 elric #endif 288 1.1 elric case LINUX_PROC_POINT: { 289 1.1 elric struct procdata data = { 0, 0, 0, 0, AFSCALL_PIOCTL }; 290 1.1 elric data.param1 = (unsigned long)a_path; 291 1.1 elric data.param2 = (unsigned long)o_opcode; 292 1.1 elric data.param3 = (unsigned long)a_paramsP; 293 1.1 elric data.param4 = (unsigned long)a_followSymlinks; 294 1.1 elric return do_ioctl(&data); 295 1.1 elric } 296 1.1 elric case MACOS_DEV_POINT: { 297 1.1 elric struct devdata data = { AFSCALL_PIOCTL, 0, 0, 0, 0, 0, 0, 0 }; 298 1.1 elric int ret; 299 1.2 christos 300 1.1 elric data.param1 = (unsigned long)a_path; 301 1.1 elric data.param2 = (unsigned long)o_opcode; 302 1.1 elric data.param3 = (unsigned long)a_paramsP; 303 1.1 elric data.param4 = (unsigned long)a_followSymlinks; 304 1.2 christos 305 1.1 elric ret = do_ioctl(&data); 306 1.1 elric if (ret) 307 1.1 elric return ret; 308 1.2 christos 309 1.1 elric return data.retval; 310 1.1 elric } 311 1.2 christos case SUN_PROC_POINT: { 312 1.2 christos struct sundevdata data = { 0, 0, 0, 0, 0, 0, AFSCALL_PIOCTL }; 313 1.2 christos data.param1 = (unsigned long)a_path; 314 1.2 christos data.param2 = (unsigned long)o_opcode; 315 1.2 christos data.param3 = (unsigned long)a_paramsP; 316 1.2 christos data.param4 = (unsigned long)a_followSymlinks; 317 1.2 christos return do_ioctl(&data); 318 1.2 christos } 319 1.1 elric #ifdef _AIX 320 1.1 elric case AIX_ENTRY_POINTS: 321 1.1 elric return Pioctl(a_path, o_opcode, a_paramsP, a_followSymlinks); 322 1.1 elric #endif 323 1.1 elric } 324 1.1 elric errno = ENOSYS; 325 1.1 elric #ifdef SIGSYS 326 1.1 elric kill(getpid(), SIGSYS); /* You lose! */ 327 1.1 elric #endif 328 1.1 elric #endif /* NO_AFS */ 329 1.1 elric return -1; 330 1.1 elric } 331 1.1 elric 332 1.1 elric int 333 1.1 elric k_afs_cell_of_file(const char *path, char *cell, int len) 334 1.1 elric { 335 1.1 elric struct ViceIoctl parms; 336 1.1 elric parms.in = NULL; 337 1.1 elric parms.in_size = 0; 338 1.1 elric parms.out = cell; 339 1.1 elric parms.out_size = len; 340 1.1 elric return k_pioctl(rk_UNCONST(path), VIOC_FILE_CELL_NAME, &parms, 1); 341 1.1 elric } 342 1.1 elric 343 1.1 elric int 344 1.1 elric k_unlog(void) 345 1.1 elric { 346 1.1 elric struct ViceIoctl parms; 347 1.1 elric memset(&parms, 0, sizeof(parms)); 348 1.1 elric return k_pioctl(0, VIOCUNLOG, &parms, 0); 349 1.1 elric } 350 1.1 elric 351 1.1 elric int 352 1.1 elric k_setpag(void) 353 1.1 elric { 354 1.1 elric #ifndef NO_AFS 355 1.1 elric switch(afs_entry_point){ 356 1.1 elric #if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3) 357 1.1 elric case SINGLE_ENTRY_POINT: 358 1.1 elric case SINGLE_ENTRY_POINT2: 359 1.1 elric case SINGLE_ENTRY_POINT3: 360 1.1 elric return syscall(afs_syscalls[0], AFSCALL_SETPAG); 361 1.1 elric #endif 362 1.1 elric #if defined(AFS_PIOCTL) 363 1.1 elric case MULTIPLE_ENTRY_POINT: 364 1.1 elric return syscall(afs_syscalls[1]); 365 1.1 elric #endif 366 1.1 elric case LINUX_PROC_POINT: { 367 1.1 elric struct procdata data = { 0, 0, 0, 0, AFSCALL_SETPAG }; 368 1.1 elric return do_ioctl(&data); 369 1.1 elric } 370 1.1 elric case MACOS_DEV_POINT: { 371 1.1 elric struct devdata data = { AFSCALL_SETPAG, 0, 0, 0, 0, 0, 0, 0 }; 372 1.1 elric int ret = do_ioctl(&data); 373 1.1 elric if (ret) 374 1.1 elric return ret; 375 1.1 elric return data.retval; 376 1.1 elric } 377 1.2 christos case SUN_PROC_POINT: { 378 1.2 christos struct sundevdata data = { 0, 0, 0, 0, 0, 0, AFSCALL_SETPAG }; 379 1.2 christos return do_ioctl(&data); 380 1.2 christos } 381 1.1 elric #ifdef _AIX 382 1.1 elric case AIX_ENTRY_POINTS: 383 1.1 elric return Setpag(); 384 1.1 elric #endif 385 1.1 elric } 386 1.1 elric 387 1.1 elric errno = ENOSYS; 388 1.1 elric #ifdef SIGSYS 389 1.1 elric kill(getpid(), SIGSYS); /* You lose! */ 390 1.1 elric #endif 391 1.1 elric #endif /* NO_AFS */ 392 1.1 elric return -1; 393 1.1 elric } 394 1.1 elric 395 1.1 elric static jmp_buf catch_SIGSYS; 396 1.1 elric 397 1.1 elric #ifdef SIGSYS 398 1.1 elric 399 1.1 elric static RETSIGTYPE 400 1.1 elric SIGSYS_handler(int sig) 401 1.1 elric { 402 1.1 elric errno = 0; 403 1.1 elric signal(SIGSYS, SIGSYS_handler); /* Need to reinstall handler on SYSV */ 404 1.1 elric longjmp(catch_SIGSYS, 1); 405 1.1 elric } 406 1.1 elric 407 1.1 elric #endif 408 1.1 elric 409 1.1 elric /* 410 1.1 elric * Try to see if `syscall' is a pioctl. Return 0 iff succesful. 411 1.1 elric */ 412 1.1 elric 413 1.1 elric #if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3) 414 1.1 elric static int 415 1.1 elric try_one (int syscall_num) 416 1.1 elric { 417 1.1 elric struct ViceIoctl parms; 418 1.1 elric memset(&parms, 0, sizeof(parms)); 419 1.1 elric 420 1.1 elric if (setjmp(catch_SIGSYS) == 0) { 421 1.1 elric syscall(syscall_num, AFSCALL_PIOCTL, 422 1.1 elric 0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 423 1.1 elric if (errno == EINVAL) { 424 1.1 elric afs_entry_point = SINGLE_ENTRY_POINT; 425 1.1 elric afs_syscalls[0] = syscall_num; 426 1.1 elric return 0; 427 1.1 elric } 428 1.1 elric } 429 1.1 elric return 1; 430 1.1 elric } 431 1.1 elric #endif 432 1.1 elric 433 1.1 elric /* 434 1.1 elric * Try to see if `syscall_pioctl' is a pioctl syscall. Return 0 iff 435 1.1 elric * succesful. 436 1.1 elric * 437 1.1 elric */ 438 1.1 elric 439 1.1 elric #ifdef AFS_PIOCTL 440 1.1 elric static int 441 1.1 elric try_two (int syscall_pioctl, int syscall_setpag) 442 1.1 elric { 443 1.1 elric struct ViceIoctl parms; 444 1.1 elric memset(&parms, 0, sizeof(parms)); 445 1.1 elric 446 1.1 elric if (setjmp(catch_SIGSYS) == 0) { 447 1.1 elric syscall(syscall_pioctl, 448 1.1 elric 0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 449 1.1 elric if (errno == EINVAL) { 450 1.1 elric afs_entry_point = MULTIPLE_ENTRY_POINT; 451 1.1 elric afs_syscalls[0] = syscall_pioctl; 452 1.1 elric afs_syscalls[1] = syscall_setpag; 453 1.1 elric return 0; 454 1.1 elric } 455 1.1 elric } 456 1.1 elric return 1; 457 1.1 elric } 458 1.1 elric #endif 459 1.1 elric 460 1.1 elric int 461 1.1 elric k_hasafs(void) 462 1.1 elric { 463 1.1 elric #if !defined(NO_AFS) && defined(SIGSYS) 464 1.1 elric RETSIGTYPE (*saved_func)(int); 465 1.1 elric #endif 466 1.1 elric int saved_errno, ret; 467 1.1 elric char *env = NULL; 468 1.1 elric 469 1.1 elric if (!issuid()) 470 1.1 elric env = getenv ("AFS_SYSCALL"); 471 1.1 elric 472 1.1 elric /* 473 1.1 elric * Already checked presence of AFS syscalls? 474 1.1 elric */ 475 1.1 elric if (afs_entry_point != UNKNOWN_ENTRY_POINT) 476 1.1 elric return afs_entry_point != NO_ENTRY_POINT; 477 1.1 elric 478 1.1 elric /* 479 1.1 elric * Probe kernel for AFS specific syscalls, 480 1.1 elric * they (currently) come in two flavors. 481 1.1 elric * If the syscall is absent we recive a SIGSYS. 482 1.1 elric */ 483 1.1 elric afs_entry_point = NO_ENTRY_POINT; 484 1.1 elric 485 1.1 elric saved_errno = errno; 486 1.1 elric #ifndef NO_AFS 487 1.1 elric #ifdef SIGSYS 488 1.1 elric saved_func = signal(SIGSYS, SIGSYS_handler); 489 1.1 elric #endif 490 1.1 elric if (env && strstr(env, "..") == NULL) { 491 1.1 elric 492 1.1 elric if (strncmp("/proc/", env, 6) == 0) { 493 1.1 elric if (try_ioctlpath(env, VIOC_SYSCALL_PROC, LINUX_PROC_POINT) == 0) 494 1.1 elric goto done; 495 1.1 elric } 496 1.1 elric if (strncmp("/dev/", env, 5) == 0) { 497 1.1 elric #ifdef VIOC_SYSCALL_DEV 498 1.1 elric if (try_ioctlpath(env, VIOC_SYSCALL_DEV, MACOS_DEV_POINT) == 0) 499 1.1 elric goto done; 500 1.1 elric #endif 501 1.1 elric #ifdef VIOC_SYSCALL_DEV_OPENAFS 502 1.1 elric if (try_ioctlpath(env,VIOC_SYSCALL_DEV_OPENAFS,MACOS_DEV_POINT) ==0) 503 1.1 elric goto done; 504 1.1 elric #endif 505 1.1 elric } 506 1.1 elric } 507 1.1 elric 508 1.1 elric ret = try_ioctlpath("/proc/fs/openafs/afs_ioctl", 509 1.1 elric VIOC_SYSCALL_PROC, LINUX_PROC_POINT); 510 1.1 elric if (ret == 0) 511 1.1 elric goto done; 512 1.1 elric ret = try_ioctlpath("/proc/fs/nnpfs/afs_ioctl", 513 1.1 elric VIOC_SYSCALL_PROC, LINUX_PROC_POINT); 514 1.1 elric if (ret == 0) 515 1.1 elric goto done; 516 1.1 elric 517 1.1 elric #ifdef VIOC_SYSCALL_DEV_OPENAFS 518 1.1 elric ret = try_ioctlpath("/dev/openafs_ioctl", 519 1.1 elric VIOC_SYSCALL_DEV_OPENAFS, MACOS_DEV_POINT); 520 1.1 elric if (ret == 0) 521 1.1 elric goto done; 522 1.1 elric #endif 523 1.1 elric #ifdef VIOC_SYSCALL_DEV 524 1.1 elric ret = try_ioctlpath("/dev/nnpfs_ioctl", VIOC_SYSCALL_DEV, MACOS_DEV_POINT); 525 1.1 elric if (ret == 0) 526 1.1 elric goto done; 527 1.1 elric #endif 528 1.2 christos #ifdef VIOC_SUN_SYSCALL_DEV 529 1.2 christos ret = try_ioctlpath("/dev/afs", VIOC_SUN_SYSCALL_DEV, SUN_PROC_POINT); 530 1.2 christos if (ret == 0) 531 1.2 christos goto done; 532 1.2 christos #endif 533 1.2 christos 534 1.1 elric 535 1.1 elric #if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3) 536 1.1 elric { 537 1.1 elric int tmp; 538 1.1 elric 539 1.1 elric if (env != NULL) { 540 1.1 elric if (sscanf (env, "%d", &tmp) == 1) { 541 1.1 elric if (try_one (tmp) == 0) 542 1.1 elric goto done; 543 1.1 elric } else { 544 1.1 elric char *end = NULL; 545 1.1 elric char *p; 546 1.1 elric char *s = strdup (env); 547 1.1 elric 548 1.1 elric if (s != NULL) { 549 1.1 elric for (p = strtok_r (s, ",", &end); 550 1.1 elric p != NULL; 551 1.1 elric p = strtok_r (NULL, ",", &end)) { 552 1.1 elric if (map_syscall_name_to_number (p, &tmp) == 0) 553 1.1 elric if (try_one (tmp) == 0) { 554 1.1 elric free (s); 555 1.1 elric goto done; 556 1.1 elric } 557 1.1 elric } 558 1.1 elric free (s); 559 1.1 elric } 560 1.1 elric } 561 1.1 elric } 562 1.1 elric } 563 1.1 elric #endif /* AFS_SYSCALL || AFS_SYSCALL2 || AFS_SYSCALL3 */ 564 1.1 elric 565 1.1 elric #ifdef AFS_SYSCALL 566 1.1 elric if (try_one (AFS_SYSCALL) == 0) 567 1.1 elric goto done; 568 1.1 elric #endif /* AFS_SYSCALL */ 569 1.1 elric 570 1.1 elric #ifdef AFS_PIOCTL 571 1.1 elric { 572 1.1 elric int tmp[2]; 573 1.1 elric 574 1.1 elric if (env != NULL && sscanf (env, "%d%d", &tmp[0], &tmp[1]) == 2) 575 1.1 elric if (try_two (tmp[0], tmp[1]) == 2) 576 1.1 elric goto done; 577 1.1 elric } 578 1.1 elric #endif /* AFS_PIOCTL */ 579 1.1 elric 580 1.1 elric #ifdef AFS_PIOCTL 581 1.1 elric if (try_two (AFS_PIOCTL, AFS_SETPAG) == 0) 582 1.1 elric goto done; 583 1.1 elric #endif /* AFS_PIOCTL */ 584 1.1 elric 585 1.1 elric #ifdef AFS_SYSCALL2 586 1.1 elric if (try_one (AFS_SYSCALL2) == 0) 587 1.1 elric goto done; 588 1.1 elric #endif /* AFS_SYSCALL2 */ 589 1.1 elric 590 1.1 elric #ifdef AFS_SYSCALL3 591 1.1 elric if (try_one (AFS_SYSCALL3) == 0) 592 1.1 elric goto done; 593 1.1 elric #endif /* AFS_SYSCALL3 */ 594 1.1 elric 595 1.1 elric #ifdef _AIX 596 1.1 elric #if 0 597 1.1 elric if (env != NULL) { 598 1.1 elric char *pos = NULL; 599 1.1 elric char *pioctl_name; 600 1.1 elric char *setpag_name; 601 1.1 elric 602 1.1 elric pioctl_name = strtok_r (env, ", \t", &pos); 603 1.1 elric if (pioctl_name != NULL) { 604 1.1 elric setpag_name = strtok_r (NULL, ", \t", &pos); 605 1.1 elric if (setpag_name != NULL) 606 1.1 elric if (try_aix (pioctl_name, setpag_name) == 0) 607 1.1 elric goto done; 608 1.1 elric } 609 1.1 elric } 610 1.1 elric #endif 611 1.1 elric 612 1.1 elric if(try_aix() == 0) 613 1.1 elric goto done; 614 1.1 elric #endif 615 1.1 elric 616 1.1 elric 617 1.1 elric done: 618 1.1 elric #ifdef SIGSYS 619 1.1 elric signal(SIGSYS, saved_func); 620 1.1 elric #endif 621 1.1 elric #endif /* NO_AFS */ 622 1.1 elric errno = saved_errno; 623 1.1 elric return afs_entry_point != NO_ENTRY_POINT; 624 1.1 elric } 625 1.1 elric 626 1.1 elric int 627 1.1 elric k_hasafs_recheck(void) 628 1.1 elric { 629 1.1 elric afs_entry_point = UNKNOWN_ENTRY_POINT; 630 1.1 elric return k_hasafs(); 631 1.1 elric } 632