/* Declarations of file name translation functions for the GNU Hurd.
   Copyright (C) 1995, 1996, 1997, 2006 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef _HURD_LOOKUP_H
#define _HURD_LOOKUP_H	1

/* These functions all take two callback functions as the first two arguments.
   The first callback function USE_INIT_PORT is called as follows:

   error_t use_init_port (int which, error_t (*operate) (mach_port_t));

   WHICH is nonnegative value less than INIT_PORT_MAX, indicating which
   init port is required.  The callback function should call *OPERATE
   with a send right to the appropriate init port.  No user reference
   is consumed; the right will only be used after *OPERATE returns if
   *OPERATE has added its own user reference.

   LOOKUP is a function to do the actual filesystem lookup.  It is passed the
   same arguments that the dir_lookup rpc accepts, and if 0, __dir_lookup is
   used.

   The second callback function GET_DTABLE_PORT should behave like `getdport'.

   All these functions return zero on success or an error code on failure.  */


/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>).  If
   successful, returns zero and store the port to FILE in *PORT; otherwise
   returns an error code. */

error_t __hurd_file_name_lookup (error_t (*use_init_port)
				   (int which,
				    error_t (*operate) (mach_port_t)),
				 file_t (*get_dtable_port) (int fd),
				 error_t (*lookup)
				   (file_t dir, char *name, int flags, mode_t mode,
				    retry_type *do_retry, string_t retry_name,
				    mach_port_t *result),
				 const char *file_name,
				 int flags, mode_t mode,
				 file_t *result);
error_t hurd_file_name_lookup (error_t (*use_init_port)
			         (int which,
				  error_t (*operate) (mach_port_t)),
			       file_t (*get_dtable_port) (int fd),
			       error_t (*lookup)
				 (file_t dir, char *name, int flags, mode_t mode,
				  retry_type *do_retry, string_t retry_name,
				  mach_port_t *result),
			       const char *file_name,
			       int flags, mode_t mode,
			       file_t *result);


/* Split FILE into a directory and a name within the directory.  Look up a
   port for the directory and store it in *DIR; store in *NAME a pointer
   into FILE where the name within directory begins.  */

error_t __hurd_file_name_split (error_t (*use_init_port)
				  (int which,
				   error_t (*operate) (mach_port_t)),
				file_t (*get_dtable_port) (int fd),
				error_t (*lookup) (file_t dir, char *name,
						   int flags, mode_t mode,
				   retry_type *do_retry, string_t retry_name,
				   mach_port_t *result),
				const char *file_name,
				file_t *dir, char **name);
error_t hurd_file_name_split (error_t (*use_init_port)
			        (int which,
				 error_t (*operate) (mach_port_t)),
			      file_t (*get_dtable_port) (int fd),
			      error_t (*lookup) (file_t dir, char *name,
						 int flags, mode_t mode,
				 retry_type *do_retry, string_t retry_name,
				 mach_port_t *result),
			      const char *file_name,
			      file_t *dir, char **name);

/* Split DIRECTORY into a parent directory and a name within the directory.
   This is the same as hurd_file_name_split, but ignores trailing slashes.  */

error_t __hurd_directory_name_split (error_t (*use_init_port)
				  (int which,
				   error_t (*operate) (mach_port_t)),
				file_t (*get_dtable_port) (int fd),
				error_t (*lookup) (file_t dir, char *name,
						   int flags, mode_t mode,
				   retry_type *do_retry, string_t retry_name,
				   mach_port_t *result),
				const char *directory_name,
				file_t *dir, char **name);
error_t hurd_directory_name_split (error_t (*use_init_port)
				   (int which,
				    error_t (*operate) (mach_port_t)),
				   file_t (*get_dtable_port) (int fd),
				   error_t (*lookup) (file_t dir, char *name,
						      int flags, mode_t mode,
				    retry_type *do_retry, string_t retry_name,
				    mach_port_t *result),
				   const char *directory_name,
				   file_t *dir, char **name);


/* Process the values returned by `dir_lookup' et al, and loop doing
   `dir_lookup' calls until one returns FS_RETRY_NONE.  The arguments
   should be those just passed to and/or returned from `dir_lookup',
   `fsys_getroot', or `file_invoke_translator'.  This function consumes the
   reference in *RESULT even if it returns an error.  */

error_t __hurd_file_name_lookup_retry (error_t (*use_init_port)
				         (int which,
					  error_t (*operate) (mach_port_t)),
				       file_t (*get_dtable_port) (int fd),
				       error_t (*lookup)
				         (file_t dir, char *name,
					  int flags, mode_t mode,
					  retry_type *do_retry,
					  string_t retry_name,
					  mach_port_t *result),
				       enum retry_type doretry,
				       char retryname[1024],
				       int flags, mode_t mode,
				       file_t *result);
error_t hurd_file_name_lookup_retry (error_t (*use_init_port)
				       (int which,
					error_t (*operate) (mach_port_t)),
				     file_t (*get_dtable_port) (int fd),
				     error_t (*lookup)
				       (file_t dir, char *name,
					int flags, mode_t mode,
					retry_type *do_retry,
					string_t retry_name,
					mach_port_t *result),
				     enum retry_type doretry,
				     char retryname[1024],
				     int flags, mode_t mode,
				     file_t *result);


/* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and
   return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to
   NULL).  Otherwise, call FUN repeatedly with FILE_NAME prefixed with each
   successive `:' separated element of PATH, returning whenever FUN returns
   0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting
   prefixed path).  If FUN never returns 0, return the first non-ENOENT
   return value, or ENOENT if there is none.  */
error_t file_name_path_scan (const char *file_name, const char *path,
			     error_t (*fun)(const char *name),
			     char **prefixed_name);

/* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result
   (see hurd_file_name_lookup for details), but a simple filename (without
   any directory prefixes) will be consecutively prefixed with the pathnames
   in the `:' separated list PATH until one succeeds in a successful lookup.
   If none succeed, then the first error that wasn't ENOENT is returned, or
   ENOENT if no other errors were returned.  If PREFIXED_NAME is non-NULL,
   then if RESULT is looked up directly, *PREFIXED_NAME is set to NULL, and
   if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
   malloced storage containing the prefixed name.  */
error_t hurd_file_name_path_lookup (error_t (*use_init_port)
				    (int which,
				     error_t (*operate) (mach_port_t)),
				    file_t (*get_dtable_port) (int fd),
				    error_t (*lookup)
				      (file_t dir, char *name,
				       int flags, mode_t mode,
				       retry_type *do_retry,
				       string_t retry_name,
				       mach_port_t *result),
				    const char *file_name, const char *path,
				    int flags, mode_t mode,
				    file_t *result, char **prefixed_name);

#endif	/* hurd/lookup.h */
