Support the new MacOS X 10.4 ioctl interface that is a device
node. Patched from Tomas Olson <tol@it.su.se>. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@16111 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995 - 2000, 2002, 2004 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1995 - 2000, 2002, 2004, 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -42,11 +42,24 @@ struct procdata {
|
||||
unsigned long param1;
|
||||
unsigned long syscall;
|
||||
};
|
||||
#define VIOC_SYSCALL _IOW('C', 1, void *)
|
||||
#define VIOC_SYSCALL_PROC _IOW('C', 1, void *)
|
||||
|
||||
struct devdata {
|
||||
unsigned long syscall;
|
||||
unsigned long param1;
|
||||
unsigned long param2;
|
||||
unsigned long param3;
|
||||
unsigned long param4;
|
||||
unsigned long param5;
|
||||
unsigned long param6;
|
||||
unsigned long retval;
|
||||
};
|
||||
#define VIOC_SYSCALL_DEV _IOWR('C', 2, struct devdata)
|
||||
|
||||
|
||||
int _kafs_debug; /* this should be done in a better way */
|
||||
|
||||
#define UNKNOWN_ENTRY_POINT (-1)
|
||||
#define NO_ENTRY_POINT 0
|
||||
#define SINGLE_ENTRY_POINT 1
|
||||
#define MULTIPLE_ENTRY_POINT 2
|
||||
@@ -54,10 +67,11 @@ int _kafs_debug; /* this should be done in a better way */
|
||||
#define SINGLE_ENTRY_POINT3 4
|
||||
#define LINUX_PROC_POINT 5
|
||||
#define AIX_ENTRY_POINTS 6
|
||||
#define UNKNOWN_ENTRY_POINT 7
|
||||
#define MACOS_DEV_POINT 7
|
||||
|
||||
static int afs_entry_point = UNKNOWN_ENTRY_POINT;
|
||||
static int afs_syscalls[2];
|
||||
static char *afs_procpath;
|
||||
static char *afs_ioctlpath;
|
||||
|
||||
/* Magic to get AIX syscalls to work */
|
||||
#ifdef _AIX
|
||||
@@ -148,30 +162,30 @@ map_syscall_name_to_number (const char *str, int *res)
|
||||
#endif
|
||||
|
||||
static int
|
||||
try_proc(const char *path)
|
||||
try_ioctlpath(const char *path, int entrypoint)
|
||||
{
|
||||
int fd;
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd < 0)
|
||||
return 1;
|
||||
close(fd);
|
||||
afs_procpath = strdup(path);
|
||||
if (afs_procpath == NULL)
|
||||
afs_ioctlpath = strdup(path);
|
||||
if (afs_ioctlpath == NULL)
|
||||
return 1;
|
||||
afs_entry_point = LINUX_PROC_POINT;
|
||||
afs_entry_point = entrypoint;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_proc(struct procdata *data)
|
||||
do_ioctl(void *data, unsigned long cmd)
|
||||
{
|
||||
int fd, ret, saved_errno;
|
||||
fd = open(afs_procpath, O_RDWR);
|
||||
fd = open(afs_ioctlpath, O_RDWR);
|
||||
if (fd < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
ret = ioctl(fd, VIOC_SYSCALL, data);
|
||||
ret = ioctl(fd, cmd, data);
|
||||
saved_errno = errno;
|
||||
close(fd);
|
||||
errno = saved_errno;
|
||||
@@ -204,7 +218,22 @@ k_pioctl(char *a_path,
|
||||
data.param2 = (unsigned long)o_opcode;
|
||||
data.param3 = (unsigned long)a_paramsP;
|
||||
data.param4 = (unsigned long)a_followSymlinks;
|
||||
return do_proc(&data);
|
||||
return do_ioctl(&data, VIOC_SYSCALL_PROC);
|
||||
}
|
||||
case MACOS_DEV_POINT: {
|
||||
struct devdata data = { AFSCALL_PIOCTL, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int ret;
|
||||
|
||||
data.param1 = (unsigned long)a_path;
|
||||
data.param2 = (unsigned long)o_opcode;
|
||||
data.param3 = (unsigned long)a_paramsP;
|
||||
data.param4 = (unsigned long)a_followSymlinks;
|
||||
|
||||
ret = do_ioctl(&data, VIOC_SYSCALL_DEV);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return data.retval;
|
||||
}
|
||||
#ifdef _AIX
|
||||
case AIX_ENTRY_POINTS:
|
||||
@@ -255,8 +284,15 @@ k_setpag(void)
|
||||
#endif
|
||||
case LINUX_PROC_POINT: {
|
||||
struct procdata data = { 0, 0, 0, 0, AFSCALL_SETPAG };
|
||||
return do_proc(&data);
|
||||
return do_ioctl(&data, VIOC_SYSCALL_PROC);
|
||||
}
|
||||
case MACOS_DEV_POINT: {
|
||||
struct devdata data = { AFSCALL_SETPAG, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int ret = do_ioctl(&data, VIOC_SYSCALL_DEV);
|
||||
if (ret)
|
||||
return ret;
|
||||
return data.retval;
|
||||
}
|
||||
#ifdef _AIX
|
||||
case AIX_ENTRY_POINTS:
|
||||
return Setpag();
|
||||
@@ -343,7 +379,10 @@ k_hasafs(void)
|
||||
RETSIGTYPE (*saved_func)(int);
|
||||
#endif
|
||||
int saved_errno;
|
||||
char *env = getenv ("AFS_SYSCALL");
|
||||
char *env = NULL;
|
||||
|
||||
if (!issuid())
|
||||
env = getenv ("AFS_SYSCALL");
|
||||
|
||||
/*
|
||||
* Already checked presence of AFS syscalls?
|
||||
@@ -364,6 +403,13 @@ k_hasafs(void)
|
||||
saved_func = signal(SIGSYS, SIGSYS_handler);
|
||||
#endif
|
||||
|
||||
if (env && (strncmp("/dev/", env, 5) == 0 || strncmp("/proc/", env, 6) == 0)) {
|
||||
if (try_ioctlpath(env, LINUX_PROC_POINT) == 0)
|
||||
goto done;
|
||||
if (try_ioctlpath(env, MACOS_DEV_POINT) == 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
|
||||
{
|
||||
int tmp;
|
||||
@@ -445,11 +491,14 @@ k_hasafs(void)
|
||||
goto done;
|
||||
#endif
|
||||
|
||||
if (try_proc("/proc/fs/openafs/afs_ioctl") == 0)
|
||||
if (try_ioctlpath("/proc/fs/openafs/afs_ioctl", LINUX_PROC_POINT) == 0)
|
||||
goto done;
|
||||
if (try_proc("/proc/fs/nnpfs/afs_ioctl") == 0)
|
||||
if (try_ioctlpath("/proc/fs/nnpfs/afs_ioctl", LINUX_PROC_POINT) == 0)
|
||||
goto done;
|
||||
if (env && try_proc(env) == 0)
|
||||
|
||||
if (try_ioctlpath("/dev/openafs_ioctl", MACOS_DEV_POINT) == 0)
|
||||
goto done;
|
||||
if (try_ioctlpath("/dev/nnpfs_ioctl", MACOS_DEV_POINT) == 0)
|
||||
goto done;
|
||||
|
||||
done:
|
||||
|
Reference in New Issue
Block a user