155682Smarkm/*
2233294Sstas * Copyright (c) 1995 - 2000, 2002, 2004, 2005 Kungliga Tekniska H��gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
5233294Sstas *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
9233294Sstas *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
12233294Sstas *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
16233294Sstas *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
20233294Sstas *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "kafs_locl.h"
3555682Smarkm
36142403Snectarstruct procdata {
37142403Snectar    unsigned long param4;
38142403Snectar    unsigned long param3;
39142403Snectar    unsigned long param2;
40142403Snectar    unsigned long param1;
41142403Snectar    unsigned long syscall;
42142403Snectar};
43178825Sdfr#define VIOC_SYSCALL_PROC _IOW('C', 1, void *)
44142403Snectar
45178825Sdfrstruct devdata {
46178825Sdfr    unsigned long syscall;
47178825Sdfr    unsigned long param1;
48178825Sdfr    unsigned long param2;
49178825Sdfr    unsigned long param3;
50178825Sdfr    unsigned long param4;
51178825Sdfr    unsigned long param5;
52178825Sdfr    unsigned long param6;
53178825Sdfr    unsigned long retval;
54178825Sdfr};
55233294Sstas#ifdef _IOWR
56178825Sdfr#define VIOC_SYSCALL_DEV _IOWR('C', 2, struct devdata)
57178825Sdfr#define VIOC_SYSCALL_DEV_OPENAFS _IOWR('C', 1, struct devdata)
58233294Sstas#endif
59142403Snectar
60178825Sdfr
6155682Smarkmint _kafs_debug; /* this should be done in a better way */
6255682Smarkm
63178825Sdfr#define UNKNOWN_ENTRY_POINT	(-1)
6455682Smarkm#define NO_ENTRY_POINT		0
6555682Smarkm#define SINGLE_ENTRY_POINT	1
6655682Smarkm#define MULTIPLE_ENTRY_POINT	2
6755682Smarkm#define SINGLE_ENTRY_POINT2	3
6855682Smarkm#define SINGLE_ENTRY_POINT3	4
69142403Snectar#define LINUX_PROC_POINT	5
70142403Snectar#define AIX_ENTRY_POINTS	6
71178825Sdfr#define MACOS_DEV_POINT		7
72178825Sdfr
7355682Smarkmstatic int afs_entry_point = UNKNOWN_ENTRY_POINT;
7455682Smarkmstatic int afs_syscalls[2];
75178825Sdfrstatic char *afs_ioctlpath;
76178825Sdfrstatic unsigned long afs_ioctlnum;
7755682Smarkm
7855682Smarkm/* Magic to get AIX syscalls to work */
7955682Smarkm#ifdef _AIX
8055682Smarkm
8155682Smarkmstatic int (*Pioctl)(char*, int, struct ViceIoctl*, int);
8255682Smarkmstatic int (*Setpag)(void);
8355682Smarkm
8455682Smarkm#include "dlfcn.h"
8555682Smarkm
8655682Smarkm/*
8755682Smarkm *
8855682Smarkm */
8955682Smarkm
9055682Smarkmstatic int
9155682Smarkmtry_aix(void)
9255682Smarkm{
9355682Smarkm#ifdef STATIC_AFS_SYSCALLS
9455682Smarkm    Pioctl = aix_pioctl;
9555682Smarkm    Setpag = aix_setpag;
9655682Smarkm#else
9755682Smarkm    void *ptr;
9855682Smarkm    char path[MaxPathLen], *p;
9955682Smarkm    /*
10055682Smarkm     * If we are root or running setuid don't trust AFSLIBPATH!
10155682Smarkm     */
10255682Smarkm    if (getuid() != 0 && !issuid() && (p = getenv("AFSLIBPATH")) != NULL)
10355682Smarkm	strlcpy(path, p, sizeof(path));
10455682Smarkm    else
10555682Smarkm	snprintf(path, sizeof(path), "%s/afslib.so", LIBDIR);
106233294Sstas
10755682Smarkm    ptr = dlopen(path, RTLD_NOW);
10855682Smarkm    if(ptr == NULL) {
10955682Smarkm	if(_kafs_debug) {
11055682Smarkm	    if(errno == ENOEXEC && (p = dlerror()) != NULL)
11155682Smarkm		fprintf(stderr, "dlopen(%s): %s\n", path, p);
11255682Smarkm	    else if (errno != ENOENT)
11355682Smarkm		fprintf(stderr, "dlopen(%s): %s\n", path, strerror(errno));
11455682Smarkm	}
11555682Smarkm	return 1;
11655682Smarkm    }
11755682Smarkm    Setpag = (int (*)(void))dlsym(ptr, "aix_setpag");
118233294Sstas    Pioctl = (int (*)(char*, int,
11955682Smarkm		      struct ViceIoctl*, int))dlsym(ptr, "aix_pioctl");
12055682Smarkm#endif
12155682Smarkm    afs_entry_point = AIX_ENTRY_POINTS;
12255682Smarkm    return 0;
12355682Smarkm}
12455682Smarkm#endif /* _AIX */
12555682Smarkm
126233294Sstas/*
12755682Smarkm * This probably only works under Solaris and could get confused if
128233294Sstas * there's a /etc/name_to_sysnum file.
12955682Smarkm */
13055682Smarkm
131178825Sdfr#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
132178825Sdfr
13355682Smarkm#define _PATH_ETC_NAME_TO_SYSNUM "/etc/name_to_sysnum"
13455682Smarkm
13555682Smarkmstatic int
13655682Smarkmmap_syscall_name_to_number (const char *str, int *res)
13755682Smarkm{
13855682Smarkm    FILE *f;
13955682Smarkm    char buf[256];
14055682Smarkm    size_t str_len = strlen (str);
14155682Smarkm
14255682Smarkm    f = fopen (_PATH_ETC_NAME_TO_SYSNUM, "r");
14355682Smarkm    if (f == NULL)
14455682Smarkm	return -1;
14555682Smarkm    while (fgets (buf, sizeof(buf), f) != NULL) {
14672445Sassar	if (buf[0] == '#')
14772445Sassar	    continue;
14872445Sassar
14955682Smarkm	if (strncmp (str, buf, str_len) == 0) {
15055682Smarkm	    char *begptr = buf + str_len;
15155682Smarkm	    char *endptr;
15255682Smarkm	    long val = strtol (begptr, &endptr, 0);
15355682Smarkm
15455682Smarkm	    if (val != 0 && endptr != begptr) {
15555682Smarkm		fclose (f);
15655682Smarkm		*res = val;
15755682Smarkm		return 0;
15855682Smarkm	    }
15955682Smarkm	}
16055682Smarkm    }
16155682Smarkm    fclose (f);
16255682Smarkm    return -1;
16355682Smarkm}
164178825Sdfr#endif
16555682Smarkm
166233294Sstasstatic int
167178825Sdfrtry_ioctlpath(const char *path, unsigned long ioctlnum, int entrypoint)
168142403Snectar{
169178825Sdfr    int fd, ret, saved_errno;
170178825Sdfr
171142403Snectar    fd = open(path, O_RDWR);
172142403Snectar    if (fd < 0)
173142403Snectar	return 1;
174178825Sdfr    switch (entrypoint) {
175178825Sdfr    case LINUX_PROC_POINT: {
176178825Sdfr	struct procdata data = { 0, 0, 0, 0, AFSCALL_PIOCTL };
177178825Sdfr	data.param2 = (unsigned long)VIOCGETTOK;
178178825Sdfr	ret = ioctl(fd, ioctlnum, &data);
179178825Sdfr	break;
180178825Sdfr    }
181178825Sdfr    case MACOS_DEV_POINT: {
182178825Sdfr	struct devdata data = { AFSCALL_PIOCTL, 0, 0, 0, 0, 0, 0, 0 };
183178825Sdfr	data.param2 = (unsigned long)VIOCGETTOK;
184178825Sdfr	ret = ioctl(fd, ioctlnum, &data);
185178825Sdfr	break;
186178825Sdfr    }
187178825Sdfr    default:
188178825Sdfr	abort();
189178825Sdfr    }
190178825Sdfr    saved_errno = errno;
191142403Snectar    close(fd);
192233294Sstas    /*
193178825Sdfr     * Be quite liberal in what error are ok, the first is the one
194178825Sdfr     * that should trigger given that params is NULL.
195178825Sdfr     */
196233294Sstas    if (ret &&
197178825Sdfr	(saved_errno != EFAULT &&
198233294Sstas	 saved_errno != EDOM &&
199178825Sdfr	 saved_errno != ENOTCONN))
200142403Snectar	return 1;
201178825Sdfr    afs_ioctlnum = ioctlnum;
202178825Sdfr    afs_ioctlpath = strdup(path);
203178825Sdfr    if (afs_ioctlpath == NULL)
204178825Sdfr	return 1;
205178825Sdfr    afs_entry_point = entrypoint;
206142403Snectar    return 0;
207142403Snectar}
208142403Snectar
209142403Snectarstatic int
210178825Sdfrdo_ioctl(void *data)
211142403Snectar{
212142403Snectar    int fd, ret, saved_errno;
213178825Sdfr    fd = open(afs_ioctlpath, O_RDWR);
214142403Snectar    if (fd < 0) {
215142403Snectar	errno = EINVAL;
216142403Snectar	return -1;
217142403Snectar    }
218178825Sdfr    ret = ioctl(fd, afs_ioctlnum, data);
219142403Snectar    saved_errno = errno;
220142403Snectar    close(fd);
221142403Snectar    errno = saved_errno;
222142403Snectar    return ret;
223142403Snectar}
224142403Snectar
22555682Smarkmint
22655682Smarkmk_pioctl(char *a_path,
22755682Smarkm	 int o_opcode,
22855682Smarkm	 struct ViceIoctl *a_paramsP,
22955682Smarkm	 int a_followSymlinks)
23055682Smarkm{
23155682Smarkm#ifndef NO_AFS
23255682Smarkm    switch(afs_entry_point){
23355682Smarkm#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
23455682Smarkm    case SINGLE_ENTRY_POINT:
23555682Smarkm    case SINGLE_ENTRY_POINT2:
23655682Smarkm    case SINGLE_ENTRY_POINT3:
23755682Smarkm	return syscall(afs_syscalls[0], AFSCALL_PIOCTL,
23855682Smarkm		       a_path, o_opcode, a_paramsP, a_followSymlinks);
23955682Smarkm#endif
24055682Smarkm#if defined(AFS_PIOCTL)
24155682Smarkm    case MULTIPLE_ENTRY_POINT:
24255682Smarkm	return syscall(afs_syscalls[0],
24355682Smarkm		       a_path, o_opcode, a_paramsP, a_followSymlinks);
24455682Smarkm#endif
245142403Snectar    case LINUX_PROC_POINT: {
246142403Snectar	struct procdata data = { 0, 0, 0, 0, AFSCALL_PIOCTL };
247142403Snectar	data.param1 = (unsigned long)a_path;
248142403Snectar	data.param2 = (unsigned long)o_opcode;
249142403Snectar	data.param3 = (unsigned long)a_paramsP;
250142403Snectar	data.param4 = (unsigned long)a_followSymlinks;
251178825Sdfr	return do_ioctl(&data);
252142403Snectar    }
253178825Sdfr    case MACOS_DEV_POINT: {
254178825Sdfr	struct devdata data = { AFSCALL_PIOCTL, 0, 0, 0, 0, 0, 0, 0 };
255178825Sdfr	int ret;
256233294Sstas
257178825Sdfr	data.param1 = (unsigned long)a_path;
258178825Sdfr	data.param2 = (unsigned long)o_opcode;
259178825Sdfr	data.param3 = (unsigned long)a_paramsP;
260178825Sdfr	data.param4 = (unsigned long)a_followSymlinks;
261233294Sstas
262178825Sdfr	ret = do_ioctl(&data);
263178825Sdfr	if (ret)
264178825Sdfr	    return ret;
265233294Sstas
266178825Sdfr	return data.retval;
267178825Sdfr    }
26855682Smarkm#ifdef _AIX
26955682Smarkm    case AIX_ENTRY_POINTS:
27055682Smarkm	return Pioctl(a_path, o_opcode, a_paramsP, a_followSymlinks);
27155682Smarkm#endif
272233294Sstas    }
27355682Smarkm    errno = ENOSYS;
27455682Smarkm#ifdef SIGSYS
275120945Snectar    kill(getpid(), SIGSYS);	/* You lose! */
27655682Smarkm#endif
27755682Smarkm#endif /* NO_AFS */
27855682Smarkm    return -1;
27955682Smarkm}
28055682Smarkm
28155682Smarkmint
28255682Smarkmk_afs_cell_of_file(const char *path, char *cell, int len)
28355682Smarkm{
28455682Smarkm    struct ViceIoctl parms;
28555682Smarkm    parms.in = NULL;
28655682Smarkm    parms.in_size = 0;
28755682Smarkm    parms.out = cell;
28855682Smarkm    parms.out_size = len;
289178825Sdfr    return k_pioctl(rk_UNCONST(path), VIOC_FILE_CELL_NAME, &parms, 1);
29055682Smarkm}
29155682Smarkm
29255682Smarkmint
29355682Smarkmk_unlog(void)
29455682Smarkm{
29555682Smarkm    struct ViceIoctl parms;
29655682Smarkm    memset(&parms, 0, sizeof(parms));
29755682Smarkm    return k_pioctl(0, VIOCUNLOG, &parms, 0);
29855682Smarkm}
29955682Smarkm
30055682Smarkmint
30155682Smarkmk_setpag(void)
30255682Smarkm{
30355682Smarkm#ifndef NO_AFS
30455682Smarkm    switch(afs_entry_point){
30555682Smarkm#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
30655682Smarkm    case SINGLE_ENTRY_POINT:
30755682Smarkm    case SINGLE_ENTRY_POINT2:
30855682Smarkm    case SINGLE_ENTRY_POINT3:
30955682Smarkm	return syscall(afs_syscalls[0], AFSCALL_SETPAG);
31055682Smarkm#endif
31155682Smarkm#if defined(AFS_PIOCTL)
31255682Smarkm    case MULTIPLE_ENTRY_POINT:
31355682Smarkm	return syscall(afs_syscalls[1]);
31455682Smarkm#endif
315142403Snectar    case LINUX_PROC_POINT: {
316142403Snectar	struct procdata data = { 0, 0, 0, 0, AFSCALL_SETPAG };
317178825Sdfr	return do_ioctl(&data);
318142403Snectar    }
319178825Sdfr    case MACOS_DEV_POINT: {
320178825Sdfr	struct devdata data = { AFSCALL_SETPAG, 0, 0, 0, 0, 0, 0, 0 };
321178825Sdfr	int ret = do_ioctl(&data);
322178825Sdfr	if (ret)
323178825Sdfr	    return ret;
324178825Sdfr	return data.retval;
325178825Sdfr     }
32655682Smarkm#ifdef _AIX
32755682Smarkm    case AIX_ENTRY_POINTS:
32855682Smarkm	return Setpag();
32955682Smarkm#endif
33055682Smarkm    }
331233294Sstas
33255682Smarkm    errno = ENOSYS;
33355682Smarkm#ifdef SIGSYS
334120945Snectar    kill(getpid(), SIGSYS);	/* You lose! */
33555682Smarkm#endif
33655682Smarkm#endif /* NO_AFS */
33755682Smarkm    return -1;
33855682Smarkm}
33955682Smarkm
34055682Smarkmstatic jmp_buf catch_SIGSYS;
34155682Smarkm
34255682Smarkm#ifdef SIGSYS
34355682Smarkm
34455682Smarkmstatic RETSIGTYPE
34555682SmarkmSIGSYS_handler(int sig)
34655682Smarkm{
34755682Smarkm    errno = 0;
34855682Smarkm    signal(SIGSYS, SIGSYS_handler); /* Need to reinstall handler on SYSV */
34955682Smarkm    longjmp(catch_SIGSYS, 1);
35055682Smarkm}
35155682Smarkm
35255682Smarkm#endif
35355682Smarkm
35455682Smarkm/*
35555682Smarkm * Try to see if `syscall' is a pioctl.  Return 0 iff succesful.
35655682Smarkm */
35755682Smarkm
35855682Smarkm#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
35955682Smarkmstatic int
36055682Smarkmtry_one (int syscall_num)
36155682Smarkm{
36255682Smarkm    struct ViceIoctl parms;
36355682Smarkm    memset(&parms, 0, sizeof(parms));
36455682Smarkm
36555682Smarkm    if (setjmp(catch_SIGSYS) == 0) {
36655682Smarkm	syscall(syscall_num, AFSCALL_PIOCTL,
36755682Smarkm		0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
36855682Smarkm	if (errno == EINVAL) {
36955682Smarkm	    afs_entry_point = SINGLE_ENTRY_POINT;
37055682Smarkm	    afs_syscalls[0] = syscall_num;
37155682Smarkm	    return 0;
37255682Smarkm	}
37355682Smarkm    }
37455682Smarkm    return 1;
37555682Smarkm}
37655682Smarkm#endif
37755682Smarkm
37855682Smarkm/*
37955682Smarkm * Try to see if `syscall_pioctl' is a pioctl syscall.  Return 0 iff
38055682Smarkm * succesful.
38155682Smarkm *
38255682Smarkm */
38355682Smarkm
38455682Smarkm#ifdef AFS_PIOCTL
38555682Smarkmstatic int
38655682Smarkmtry_two (int syscall_pioctl, int syscall_setpag)
38755682Smarkm{
38855682Smarkm    struct ViceIoctl parms;
38955682Smarkm    memset(&parms, 0, sizeof(parms));
39055682Smarkm
39155682Smarkm    if (setjmp(catch_SIGSYS) == 0) {
39255682Smarkm	syscall(syscall_pioctl,
39355682Smarkm		0, VIOCSETTOK, &parms, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
39455682Smarkm	if (errno == EINVAL) {
39555682Smarkm	    afs_entry_point = MULTIPLE_ENTRY_POINT;
39655682Smarkm	    afs_syscalls[0] = syscall_pioctl;
39755682Smarkm	    afs_syscalls[1] = syscall_setpag;
39855682Smarkm	    return 0;
39955682Smarkm	}
40055682Smarkm    }
40155682Smarkm    return 1;
40255682Smarkm}
40355682Smarkm#endif
40455682Smarkm
40555682Smarkmint
40655682Smarkmk_hasafs(void)
40755682Smarkm{
40855682Smarkm#if !defined(NO_AFS) && defined(SIGSYS)
40972445Sassar    RETSIGTYPE (*saved_func)(int);
41055682Smarkm#endif
411178825Sdfr    int saved_errno, ret;
412178825Sdfr    char *env = NULL;
413178825Sdfr
414178825Sdfr    if (!issuid())
415178825Sdfr	env = getenv ("AFS_SYSCALL");
416233294Sstas
41755682Smarkm    /*
41855682Smarkm     * Already checked presence of AFS syscalls?
41955682Smarkm     */
42055682Smarkm    if (afs_entry_point != UNKNOWN_ENTRY_POINT)
42155682Smarkm	return afs_entry_point != NO_ENTRY_POINT;
42255682Smarkm
42355682Smarkm    /*
42455682Smarkm     * Probe kernel for AFS specific syscalls,
42555682Smarkm     * they (currently) come in two flavors.
42655682Smarkm     * If the syscall is absent we recive a SIGSYS.
42755682Smarkm     */
42855682Smarkm    afs_entry_point = NO_ENTRY_POINT;
429233294Sstas
43055682Smarkm    saved_errno = errno;
43155682Smarkm#ifndef NO_AFS
43255682Smarkm#ifdef SIGSYS
43355682Smarkm    saved_func = signal(SIGSYS, SIGSYS_handler);
43455682Smarkm#endif
435178825Sdfr    if (env && strstr(env, "..") == NULL) {
43655682Smarkm
437178825Sdfr	if (strncmp("/proc/", env, 6) == 0) {
438178825Sdfr	    if (try_ioctlpath(env, VIOC_SYSCALL_PROC, LINUX_PROC_POINT) == 0)
439178825Sdfr		goto done;
440178825Sdfr	}
441178825Sdfr	if (strncmp("/dev/", env, 5) == 0) {
442233294Sstas#ifdef VIOC_SYSCALL_DEV
443178825Sdfr	    if (try_ioctlpath(env, VIOC_SYSCALL_DEV, MACOS_DEV_POINT) == 0)
444178825Sdfr		goto done;
445233294Sstas#endif
446233294Sstas#ifdef VIOC_SYSCALL_DEV_OPENAFS
447178825Sdfr	    if (try_ioctlpath(env,VIOC_SYSCALL_DEV_OPENAFS,MACOS_DEV_POINT) ==0)
448178825Sdfr		goto done;
449233294Sstas#endif
450178825Sdfr	}
451178825Sdfr    }
452178825Sdfr
453178825Sdfr    ret = try_ioctlpath("/proc/fs/openafs/afs_ioctl",
454178825Sdfr			VIOC_SYSCALL_PROC, LINUX_PROC_POINT);
455178825Sdfr    if (ret == 0)
456178825Sdfr	goto done;
457233294Sstas    ret = try_ioctlpath("/proc/fs/nnpfs/afs_ioctl",
458178825Sdfr			VIOC_SYSCALL_PROC, LINUX_PROC_POINT);
459178825Sdfr    if (ret == 0)
460178825Sdfr	goto done;
461178825Sdfr
462233294Sstas#ifdef VIOC_SYSCALL_DEV_OPENAFS
463233294Sstas    ret = try_ioctlpath("/dev/openafs_ioctl",
464178825Sdfr			VIOC_SYSCALL_DEV_OPENAFS, MACOS_DEV_POINT);
465178825Sdfr    if (ret == 0)
466178825Sdfr	goto done;
467233294Sstas#endif
468233294Sstas#ifdef VIOC_SYSCALL_DEV
469178825Sdfr    ret = try_ioctlpath("/dev/nnpfs_ioctl", VIOC_SYSCALL_DEV, MACOS_DEV_POINT);
470178825Sdfr    if (ret == 0)
471178825Sdfr	goto done;
472233294Sstas#endif
473178825Sdfr
47455682Smarkm#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
47555682Smarkm    {
47655682Smarkm	int tmp;
47755682Smarkm
47855682Smarkm	if (env != NULL) {
47955682Smarkm	    if (sscanf (env, "%d", &tmp) == 1) {
48055682Smarkm		if (try_one (tmp) == 0)
48155682Smarkm		    goto done;
48255682Smarkm	    } else {
48355682Smarkm		char *end = NULL;
48455682Smarkm		char *p;
48555682Smarkm		char *s = strdup (env);
48655682Smarkm
48755682Smarkm		if (s != NULL) {
48855682Smarkm		    for (p = strtok_r (s, ",", &end);
48955682Smarkm			 p != NULL;
49055682Smarkm			 p = strtok_r (NULL, ",", &end)) {
49155682Smarkm			if (map_syscall_name_to_number (p, &tmp) == 0)
49255682Smarkm			    if (try_one (tmp) == 0) {
49355682Smarkm				free (s);
49455682Smarkm				goto done;
49555682Smarkm			    }
49655682Smarkm		    }
49755682Smarkm		    free (s);
49855682Smarkm		}
49955682Smarkm	    }
50055682Smarkm	}
50155682Smarkm    }
50255682Smarkm#endif /* AFS_SYSCALL || AFS_SYSCALL2 || AFS_SYSCALL3 */
50355682Smarkm
50455682Smarkm#ifdef AFS_SYSCALL
50555682Smarkm    if (try_one (AFS_SYSCALL) == 0)
50655682Smarkm	goto done;
50755682Smarkm#endif /* AFS_SYSCALL */
50855682Smarkm
50955682Smarkm#ifdef AFS_PIOCTL
51055682Smarkm    {
51155682Smarkm	int tmp[2];
51255682Smarkm
51355682Smarkm	if (env != NULL && sscanf (env, "%d%d", &tmp[0], &tmp[1]) == 2)
51455682Smarkm	    if (try_two (tmp[0], tmp[1]) == 2)
51555682Smarkm		goto done;
51655682Smarkm    }
51755682Smarkm#endif /* AFS_PIOCTL */
51855682Smarkm
51955682Smarkm#ifdef AFS_PIOCTL
52055682Smarkm    if (try_two (AFS_PIOCTL, AFS_SETPAG) == 0)
52155682Smarkm	goto done;
52255682Smarkm#endif /* AFS_PIOCTL */
52355682Smarkm
52455682Smarkm#ifdef AFS_SYSCALL2
52555682Smarkm    if (try_one (AFS_SYSCALL2) == 0)
52655682Smarkm	goto done;
52755682Smarkm#endif /* AFS_SYSCALL2 */
52855682Smarkm
52955682Smarkm#ifdef AFS_SYSCALL3
53055682Smarkm    if (try_one (AFS_SYSCALL3) == 0)
53155682Smarkm	goto done;
53255682Smarkm#endif /* AFS_SYSCALL3 */
53355682Smarkm
53455682Smarkm#ifdef _AIX
53555682Smarkm#if 0
53655682Smarkm    if (env != NULL) {
53755682Smarkm	char *pos = NULL;
53855682Smarkm	char *pioctl_name;
53955682Smarkm	char *setpag_name;
54055682Smarkm
54155682Smarkm	pioctl_name = strtok_r (env, ", \t", &pos);
54255682Smarkm	if (pioctl_name != NULL) {
54355682Smarkm	    setpag_name = strtok_r (NULL, ", \t", &pos);
54455682Smarkm	    if (setpag_name != NULL)
54555682Smarkm		if (try_aix (pioctl_name, setpag_name) == 0)
54655682Smarkm		    goto done;
54755682Smarkm	}
54855682Smarkm    }
54955682Smarkm#endif
55055682Smarkm
55155682Smarkm    if(try_aix() == 0)
55255682Smarkm	goto done;
55355682Smarkm#endif
55455682Smarkm
555142403Snectar
55655682Smarkmdone:
55755682Smarkm#ifdef SIGSYS
55855682Smarkm    signal(SIGSYS, saved_func);
55955682Smarkm#endif
56055682Smarkm#endif /* NO_AFS */
56155682Smarkm    errno = saved_errno;
56255682Smarkm    return afs_entry_point != NO_ENTRY_POINT;
56355682Smarkm}
564178825Sdfr
565178825Sdfrint
566178825Sdfrk_hasafs_recheck(void)
567178825Sdfr{
568178825Sdfr    afs_entry_point = UNKNOWN_ENTRY_POINT;
569178825Sdfr    return k_hasafs();
570178825Sdfr}
571