/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004 by Martin C. Shepherd.
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* to whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
* OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
* INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* of the copyright holder.
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* If file-system access is to be excluded, this module has no function,
* so all of its code should be excluded.
*/
#ifndef WITHOUT_FILE_SYSTEM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <pwd.h>
#include "pathutil.h"
#include "homedir.h"
#include "errmsg.h"
/*
* Use the reentrant POSIX threads versions of the password lookup functions?
*/
/*
* Under Solaris we can use thr_main() to determine whether
* threads are actually running, and thus when it is necessary
* to avoid non-reentrant features.
*/
#include <thread.h> /* Solaris thr_main() */
#endif
#endif
/*
* Provide a password buffer size fallback in case the max size reported
* by sysconf() is said to be indeterminate.
*/
/*
* The resources needed to lookup and record a home directory are
* maintained in objects of the following type.
*/
struct HomeDir {
/* directory paths. */
#ifdef THREAD_COMPATIBLE
#endif
};
/*.......................................................................
* Create a new HomeDir object.
*
* Output:
* return HomeDir * The new object, or NULL on error.
*/
{
/*
* Allocate the container.
*/
if(!home) {
return NULL;
};
/*
* Before attempting any operation that might fail, initialize the
* container at least up to the point at which it can safely be passed
* to _del_HomeDir().
*/
/*
* Allocate a place to record error messages.
*/
return _del_HomeDir(home);
/*
* Allocate the buffer that is used by the reentrant POSIX password-entry
* lookup functions.
*/
#ifdef THREAD_COMPATIBLE
/*
* Get the length of the buffer needed by the reentrant version
* of getpwnam().
*/
#ifndef _SC_GETPW_R_SIZE_MAX
#else
errno = 0;
/*
* If the limit isn't available, substitute a suitably large fallback value.
*/
#endif
#endif
/*
* If the existing buffer length requirement is too restrictive to record
* a pathname, increase its length.
*/
pathlen = _pu_pathname_dim();
/*
* Allocate a work buffer.
*/
return _del_HomeDir(home);
};
return home;
}
/*.......................................................................
* Delete a HomeDir object.
*
* Input:
* home HomeDir * The object to be deleted.
* Output:
* return HomeDir * The deleted object (always NULL).
*/
{
if(home) {
};
return NULL;
}
/*.......................................................................
* Lookup the home directory of a given user in the password file.
*
* Input:
* home HomeDir * The resources needed to lookup the home directory.
* user const char * The name of the user to lookup, or "" to lookup
* the home directory of the person running the
* program.
* Output:
* return const char * The home directory. If the library was compiled
* with threads, this string is part of the HomeDir
* object and will change on subsequent calls. If
* the library wasn't compiled to be reentrant,
* then the string is a pointer into a static string
* in the C library and will change not only on
* subsequent calls to this function, but also if
* any calls are made to the C library password
* file lookup functions. Thus to be safe, you should
* make a copy of this string before calling any
* other function that might do a password file
* lookup.
*
* On error, NULL is returned and a description
* of the error can be acquired by calling
* _hd_last_home_dir_error().
*/
{
/*
* If no username has been specified, arrange to lookup the current
* user.
*/
/*
* Check the arguments.
*/
if(!home) {
return NULL;
};
/*
* Handle the ksh "~+". This expands to the absolute path of the
* current working directory.
*/
if(!home_dir) {
return NULL;
}
return home_dir;
};
/*
* When looking up the home directory of the current user, see if the
* HOME environment variable is set, and if so, return its value.
*/
if(login_user) {
if(home_dir)
return home_dir;
};
/*
* Look up the password entry of the user.
* First the POSIX threads version - this is painful!
*/
#ifdef THREAD_COMPATIBLE
{
/*
* Look up the password entry of the specified user.
*/
if(login_user)
&ret);
else
return NULL;
};
/*
* Get a pointer to the string that holds the home directory.
*/
};
/*
* Now the classic unix version.
*/
#else
{
if(!pwd) {
return NULL;
};
/*
* Get a pointer to the home directory.
*/
};
#endif
return home_dir;
}
/*.......................................................................
* Return a description of the last error that caused _hd_lookup_home_dir()
* to return NULL.
*
* Input:
* home HomeDir * The resources needed to record the home directory.
* Output:
* return char * The description of the last error.
*/
{
}
/*.......................................................................
* The _hd_scan_user_home_dirs() function calls a user-provided function
* for each username known by the system, passing the function both
* the name and the home directory of the user.
*
* Input:
* home HomeDir * The resource object for reading home
* directories.
* prefix const char * Only information for usernames that
* start with this prefix will be
* returned. Note that the empty
& string "", matches all usernames.
* data void * Anonymous data to be passed to the
* callback function.
* callback_fn HOME_DIR_FN(*) The function to call for each user.
* Output:
* return int 0 - Successful completion.
* 1 - An error occurred. A description
* of the error can be obtained by
* calling _hd_last_home_dir_error().
*/
{
/*
* Check the arguments.
*/
if(home) {
"_hd_scan_user_home_dirs: Missing callback function",
};
return 1;
};
/*
* Get the length of the username prefix.
*/
/*
* There are no reentrant versions of getpwent() etc for scanning
* the password file, so disable username completion when the
* library is compiled to be reentrant.
*/
if(0)
#else
if(1)
#endif
{
/* pwd_buffer are stored. */
/*
* See if the prefix that is being completed is a complete username.
*/
};
/*
* See if the username of the current user minimally matches the prefix.
*/
};
/*
* Reentrancy not required?
*/
} else
#endif
{
/*
* Open the password file.
*/
setpwent();
/*
* Read the contents of the password file, looking for usernames
* that start with the specified prefix, and adding them to the
* list of matches.
*/
#else
#endif
};
};
/*
* Close the password file.
*/
endpwent();
};
/*
* Under ksh ~+ stands for the absolute pathname of the current working
* directory.
*/
if(pwd) {
} else {
waserr = 1;
};
};
return waserr;
}
/*.......................................................................
* Return the value of getenv("PWD") if this points to the current
* directory, or the return value of getcwd() otherwise. The reason for
* prefering PWD over getcwd() is that the former preserves the history
* of symbolic links that have been traversed to reach the current
* directory. This function is designed to provide the equivalent
* expansion of the ksh ~+ directive, which normally returns its value
* of PWD.
*
* Input:
* home HomeDir * The resource object for reading home directories.
* Output:
* return const char * A pointer to either home->buffer, where the
* pathname is recorded, the string returned by
* getenv("PWD"), or NULL on error.
*/
{
/*
* Get the absolute path of the current working directory.
*/
/*
* Some shells set PWD with the path of the current working directory.
* This will differ from cwd in that it won't have had symbolic links
* expanded.
*/
/*
* If PWD was set, and it points to the same directory as cwd, return
* its value. Note that it won't be the same if the current shell or
* the current program has changed directories, after inheriting PWD
* from a parent shell.
*/
return pwd;
/*
* Also return pwd if getcwd() failed, since it represents the best
* information that we have access to.
*/
if(!cwd)
return pwd;
/*
* In the absence of a valid PWD, return cwd.
*/
return cwd;
}
#endif /* ifndef WITHOUT_FILE_SYSTEM */