From fa15e701fdcc4784ec37cd0a83e0458792189867 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 18 Jul 1994 20:44:12 +0000 Subject: Formerly file-inv-trans.c.~3~ --- libdiskfs/file-inv-trans.c | 59 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'libdiskfs/file-inv-trans.c') diff --git a/libdiskfs/file-inv-trans.c b/libdiskfs/file-inv-trans.c index 6838a4a6..17fc0da0 100644 --- a/libdiskfs/file-inv-trans.c +++ b/libdiskfs/file-inv-trans.c @@ -17,6 +17,7 @@ #include "priv.h" #include "fs_S.h" +#include /* Implement fs.defs:file_invoke_translator as described in . */ kern_return_t @@ -66,9 +67,9 @@ diskfs_S_file_invoke_translator (struct protid *cred, mach_port_mod_refs (mach_task_self (), control, MACH_PORT_RIGHT_SEND, 1); mutex_unlock (&np->lock); - error = fsys_getroot (childcontrol, cred->uids, cred->nuids, + error = fsys_getroot (control, cred->uids, cred->nuids, cred->gids, cred->ngids, flags, retry, - retryname, retrypt); + retry_name, retrypt); if (error == MACH_SEND_INVALID_DEST) { mutex_lock (&np->lock); @@ -89,5 +90,57 @@ diskfs_S_file_invoke_translator (struct protid *cred, /* Ignore O_NOTRANS here. */ if (type == S_IFLNK && !(flags & O_NOLINK)) - + { + /* Handle symlink interpretation */ + char pathbuf[np->dn_stat.st_size + 1]; + int amt; + + if (diskfs_read_symlink_hook) + error = (*diskfs_read_symlink_hook) (np, pathbuf); + if (!diskfs_read_symlink_hook || error == EINVAL) + error = diskfs_node_rdwr (np, pathbuf, 0, np->dn_stat.st_size, 0, + 0, &amt); + pathbuf[amt] = '\0'; + + mutex_unlock (&np->lock); + if (error) + return error; + + if (pathbuf[0] == '/') + { + *retry = FS_RETRY_MAGICAL; + *retrypt = MACH_PORT_NULL; + *retrypttype = MACH_MSG_TYPE_COPY_SEND; + strcpy (retry_name, pathbuf); + return 0; + } + else + { + *retry = FS_RETRY_REAUTH; + *retrypt = _diskfs_dotdot_file; + *retrypttype = MACH_MSG_TYPE_COPY_SEND; + strcpy (retry_name, pathbuf); + return 0; + } + } + if ((type == S_IFSOCK || type == S_IFBLK + || type == S_IFCHR || type == S_IFIFO) + && (flags & (O_READ|O_WRITE|O_EXEC))) + error = EOPNOTSUPP; + + + flags &= ~OPENONLY_STATE_MODES; + + *retry = FS_RETRY_NONE; + retry_name[0] = '\0'; + *retrypt = (ports_get_right + (diskfs_make_protid + (diskfs_make_peropen (np, flags, _diskfs_dotdot_file), + cred->uids, cred->nuids, cred->gids, cred->ngids))); + *retrypttype = MACH_MSG_TYPE_MAKE_SEND; + + mutex_unlock (&np->lock); + + return 0; +} -- cgit v1.2.3