home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc., 675 Mass Ave,
- Cambridge, MA 02139, USA. */
-
- #include <hurd.h>
- #include <string.h>
- #include <limits.h>
-
- error_t
- __hurd_path_lookup (file_t crdir, file_t cwdir,
- const char *path, int flags, mode_t mode,
- file_t *result)
- {
- error_t err;
- file_t startdir, result;
-
- enum retry_type doretry;
- char retryname[PATH_MAX];
- file_t newpt;
- int dealloc_dir;
- int nloops;
-
- if (*path == '/')
- {
- startdir = crdir;
- while (*path == '/')
- ++path;
- }
- else
- startdir = cwdir;
-
- dealloc_dir = 0;
- nloops = 0;
-
- for (;;)
- {
- err = __dir_pathtrans (startdir, path, flags, mode,
- &doretry, retryname, &result);
-
- if (dealloc_dir)
- __mach_port_deallocate (__mach_task_self (), startdir);
- if (err)
- return err;
-
- switch (doretry)
- {
- case FS_RETRY_NONE:
- return POSIX_SUCCESS;
-
- case FS_RETRY_REAUTH:
- __io_reauthenticate (*result);
- _HURD_PORT_USE (&_hurd_auth,
- __auth_user_authenticate (port, result, &newpt));
- __mach_port_deallocate (__mach_task_self (), *result);
- *result = newpt;
- /* Fall through. */
-
- case FS_RETRY_NORMAL:
- if (nloops++ >= MAXSYMLINKS)
- return ELOOP;
-
- if (retryname[0] == '/')
- {
- startdir = crdir;
- dealloc_dir = 0;
- path = retryname;
- do
- ++path;
- while (*path == '/');
- }
- else
- {
- startdir = *result;
- dealloc_dir = 1;
- path = retryname;
- }
- }
- }
- }
-
- error_t
- __hurd_path_split (file_t crdir, file_t cwdir,
- const char *path,
- file_t *dir, char **name)
- {
- const char *lastslash;
-
- /* Skip leading slashes in the pathname. */
- if (*path == '/')
- {
- while (*path == '/')
- ++path;
- --path; /* Leave on one slash. */
- }
-
- lastslash = strrchr (path, '/');
-
- if (lastslash != NULL)
- {
- if (lastslash == path)
- {
- /* "/foobar" => crdir + "foobar". */
- *name = path + 1;
- __mach_port_mod_refs (__mach_task_self (), MACH_PORT_RIGHT_SEND,
- crdir, +1);
- *dir = crdir;
- return 0;
- }
- else
- {
- /* "/dir1/dir2/.../file". */
- char dirname[lastslash - path + 1];
- memcpy (dirname, path, lastslash - path);
- dirname[lastslath - path] = '\0';
- *name = lastslash + 1;
- return __hurd_path_lookup (crdir, cwdir, dirname, 0, 0, dir);
- }
- }
- else
- {
- /* "foobar" => cwdir + "foobar". */
- *name = path;
- __mach_port_mod_refs (__mach_task_self (), MACH_PORT_RIGHT_SEND,
- cwdir, 1);
- *dir = cwdir;
- return 0;
- }
- }
-
- file_t
- __path_lookup (const char *path, int flags, mode_t mode)
- {
- error_t err;
- file_t result, crdir, cwdir;
- int dealloc_crdir, dealloc_cwdir;
-
- crdir = _hurd_port_get (&_hurd_crdir, &dealloc_crdir);
- cwdir = _hurd_port_get (&_hurd_cwdir, &dealloc_cwdir);
-
- err = __hurd_path_lookup (crdir, cwdir, path, flags, mode, &result);
-
- _hurd_port_free (crdir, &dealloc_crdir);
- _hurd_port_free (cwdir, &dealloc_cwdir);
-
- if (err)
- {
- errno = err;
- return MACH_PORT_NULL;
- }
- else
- return result;
- }
-
- file_t
- __path_split (const char *path, char **name)
- {
- error_t err;
- file_t dir, crdir, cwdir;
- int dealloc_crdir, dealloc_cwdir;
-
- crdir = _hurd_port_get (&_hurd_crdir, &dealloc_crdir);
- cwdir = _hurd_port_get (&_hurd_cwdir, &dealloc_cwdir);
-
- err = __hurd_path_split (crdir, cwdir, path, &dir, name);
-
- _hurd_port_free (crdir, &dealloc_crdir);
- _hurd_port_free (cwdir, &dealloc_cwdir);
-
- if (err)
- {
- errno = err;
- return MACH_PORT_NULL;
- }
- else
- return dir;
- }
-