1/* |
2 * Copyright (c) 1995 - 2000, 2002, 2004 Kungliga Tekniska H�gskolan |
3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include "kafs_locl.h" 35 |
36RCSID("$Id: afssys.c,v 1.69.2.2 2004/06/22 14:29:48 lha Exp $"); |
37 |
38struct procdata { 39 unsigned long param4; 40 unsigned long param3; 41 unsigned long param2; 42 unsigned long param1; 43 unsigned long syscall; 44}; 45#define VIOC_SYSCALL _IOW('C', 1, void *) 46 47 |
48int _kafs_debug; /* this should be done in a better way */ 49 50#define NO_ENTRY_POINT 0 51#define SINGLE_ENTRY_POINT 1 52#define MULTIPLE_ENTRY_POINT 2 53#define SINGLE_ENTRY_POINT2 3 54#define SINGLE_ENTRY_POINT3 4 |
55#define LINUX_PROC_POINT 5 56#define AIX_ENTRY_POINTS 6 57#define UNKNOWN_ENTRY_POINT 7 |
58static int afs_entry_point = UNKNOWN_ENTRY_POINT; 59static int afs_syscalls[2]; |
60static char *afs_procpath; |
61 62/* Magic to get AIX syscalls to work */ 63#ifdef _AIX 64 65static int (*Pioctl)(char*, int, struct ViceIoctl*, int); 66static int (*Setpag)(void); 67 68#include "dlfcn.h" --- 70 unchanged lines hidden (view full) --- 139 return 0; 140 } 141 } 142 } 143 fclose (f); 144 return -1; 145} 146 |
147static int 148try_proc(const char *path) 149{ 150 int fd; 151 fd = open(path, O_RDWR); 152 if (fd < 0) 153 return 1; 154 close(fd); 155 afs_procpath = strdup(path); 156 if (afs_procpath == NULL) 157 return 1; 158 afs_entry_point = LINUX_PROC_POINT; 159 return 0; 160} 161 162static int 163do_proc(struct procdata *data) 164{ 165 int fd, ret, saved_errno; 166 fd = open(afs_procpath, O_RDWR); 167 if (fd < 0) { 168 errno = EINVAL; 169 return -1; 170 } 171 ret = ioctl(fd, VIOC_SYSCALL, data); 172 saved_errno = errno; 173 close(fd); 174 errno = saved_errno; 175 return ret; 176} 177 |
178int 179k_pioctl(char *a_path, 180 int o_opcode, 181 struct ViceIoctl *a_paramsP, 182 int a_followSymlinks) 183{ 184#ifndef NO_AFS 185 switch(afs_entry_point){ --- 4 unchanged lines hidden (view full) --- 190 return syscall(afs_syscalls[0], AFSCALL_PIOCTL, 191 a_path, o_opcode, a_paramsP, a_followSymlinks); 192#endif 193#if defined(AFS_PIOCTL) 194 case MULTIPLE_ENTRY_POINT: 195 return syscall(afs_syscalls[0], 196 a_path, o_opcode, a_paramsP, a_followSymlinks); 197#endif |
198 case LINUX_PROC_POINT: { 199 struct procdata data = { 0, 0, 0, 0, AFSCALL_PIOCTL }; 200 data.param1 = (unsigned long)a_path; 201 data.param2 = (unsigned long)o_opcode; 202 data.param3 = (unsigned long)a_paramsP; 203 data.param4 = (unsigned long)a_followSymlinks; 204 return do_proc(&data); 205 } |
206#ifdef _AIX 207 case AIX_ENTRY_POINTS: 208 return Pioctl(a_path, o_opcode, a_paramsP, a_followSymlinks); 209#endif |
210 } |
211 errno = ENOSYS; 212#ifdef SIGSYS 213 kill(getpid(), SIGSYS); /* You lose! */ 214#endif 215#endif /* NO_AFS */ 216 return -1; 217} 218 --- 26 unchanged lines hidden (view full) --- 245 case SINGLE_ENTRY_POINT2: 246 case SINGLE_ENTRY_POINT3: 247 return syscall(afs_syscalls[0], AFSCALL_SETPAG); 248#endif 249#if defined(AFS_PIOCTL) 250 case MULTIPLE_ENTRY_POINT: 251 return syscall(afs_syscalls[1]); 252#endif |
253 case LINUX_PROC_POINT: { 254 struct procdata data = { 0, 0, 0, 0, AFSCALL_SETPAG }; 255 return do_proc(&data); 256 } |
257#ifdef _AIX 258 case AIX_ENTRY_POINTS: 259 return Setpag(); 260#endif 261 } 262 263 errno = ENOSYS; 264#ifdef SIGSYS --- 172 unchanged lines hidden (view full) --- 437 } 438 } 439#endif 440 441 if(try_aix() == 0) 442 goto done; 443#endif 444 |
445 if (try_proc("/proc/fs/openafs/afs_ioctl") == 0) 446 goto done; 447 if (try_proc("/proc/fs/nnpfs/afs_ioctl") == 0) 448 goto done; 449 if (env && try_proc(env) == 0) 450 goto done; 451 |
452done: 453#ifdef SIGSYS 454 signal(SIGSYS, saved_func); 455#endif 456#endif /* NO_AFS */ 457 errno = saved_errno; 458 return afs_entry_point != NO_ENTRY_POINT; 459} |