150276Speter/****************************************************************************
2174993Srafan * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
30166124Srafan *  Author: Thomas E. Dickey                                                *
3150276Speter ****************************************************************************/
3250276Speter
3350276Speter#include <curses.priv.h>
34166124Srafan
35174993Srafan#include <ctype.h>
36166124Srafan#include <sys/stat.h>
37166124Srafan
3866963Speter#include <tic.h>
3997049Speter#include <nc_alloc.h>
4050276Speter
41174993SrafanMODULE_ID("$Id: access.c,v 1.14 2007/11/18 00:57:53 tom Exp $")
4250276Speter
4397049Speter#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
4497049Speter
4576726SpeterNCURSES_EXPORT(char *)
4697049Speter_nc_rootname(char *path)
4797049Speter{
4897049Speter    char *result = _nc_basename(path);
49174993Srafan#if !MIXEDCASE_FILENAMES || defined(PROG_EXT)
5097049Speter    static char *temp;
5197049Speter    char *s;
5297049Speter
5397049Speter    temp = strdup(result);
5497049Speter    result = temp;
55174993Srafan#if !MIXEDCASE_FILENAMES
5697049Speter    for (s = result; *s != '\0'; ++s) {
5797049Speter	*s = LOWERCASE(*s);
5897049Speter    }
5997049Speter#endif
6097049Speter#if defined(PROG_EXT)
6197049Speter    if ((s = strrchr(result, '.')) != 0) {
6297049Speter	if (!strcmp(s, PROG_EXT))
6397049Speter	    *s = '\0';
6497049Speter    }
6597049Speter#endif
6697049Speter#endif
6797049Speter    return result;
6897049Speter}
6997049Speter
70166124Srafan/*
71166124Srafan * Check if a string appears to be an absolute pathname.
72166124Srafan */
73166124SrafanNCURSES_EXPORT(bool)
74166124Srafan_nc_is_abs_path(const char *path)
7550276Speter{
76166124Srafan#if defined(__EMX__) || defined(__DJGPP__)
77166124Srafan#define is_pathname(s) ((((s) != 0) && ((s)[0] == '/')) \
78166124Srafan		  || (((s)[0] != 0) && ((s)[1] == ':')))
79166124Srafan#else
80166124Srafan#define is_pathname(s) ((s) != 0 && (s)[0] == '/')
81166124Srafan#endif
82166124Srafan    return is_pathname(path);
83166124Srafan}
84166124Srafan
85166124Srafan/*
86166124Srafan * Return index of the basename
87166124Srafan */
88166124SrafanNCURSES_EXPORT(unsigned)
89166124Srafan_nc_pathlast(const char *path)
90166124Srafan{
91166124Srafan    const char *test = strrchr(path, '/');
9266963Speter#ifdef __EMX__
93166124Srafan    if (test == 0)
94166124Srafan	test = strrchr(path, '\\');
9566963Speter#endif
96166124Srafan    if (test == 0)
97166124Srafan	test = path;
9866963Speter    else
99166124Srafan	test++;
100166124Srafan    return (test - path);
10166963Speter}
10266963Speter
103166124SrafanNCURSES_EXPORT(char *)
104166124Srafan_nc_basename(char *path)
105166124Srafan{
106166124Srafan    return path + _nc_pathlast(path);
107166124Srafan}
108166124Srafan
10976726SpeterNCURSES_EXPORT(int)
11066963Speter_nc_access(const char *path, int mode)
11166963Speter{
11266963Speter    if (access(path, mode) < 0) {
11366963Speter	if ((mode & W_OK) != 0
11466963Speter	    && errno == ENOENT
11566963Speter	    && strlen(path) < PATH_MAX) {
11666963Speter	    char head[PATH_MAX];
11766963Speter	    char *leaf = _nc_basename(strcpy(head, path));
11866963Speter
11966963Speter	    if (leaf == 0)
12066963Speter		leaf = head;
12166963Speter	    *leaf = '\0';
12266963Speter	    if (head == leaf)
12366963Speter		(void) strcpy(head, ".");
12466963Speter
12566963Speter	    return access(head, R_OK | W_OK | X_OK);
12650276Speter	}
12766963Speter	return -1;
12866963Speter    }
12966963Speter    return 0;
13050276Speter}
13166963Speter
132166124SrafanNCURSES_EXPORT(bool)
133166124Srafan_nc_is_dir_path(const char *path)
134166124Srafan{
135166124Srafan    bool result = FALSE;
136166124Srafan    struct stat sb;
137166124Srafan
138166124Srafan    if (stat(path, &sb) == 0
139166124Srafan	&& (sb.st_mode & S_IFMT) == S_IFDIR) {
140166124Srafan	result = TRUE;
141166124Srafan    }
142166124Srafan    return result;
143166124Srafan}
144166124Srafan
145166124SrafanNCURSES_EXPORT(bool)
146166124Srafan_nc_is_file_path(const char *path)
147166124Srafan{
148166124Srafan    bool result = FALSE;
149166124Srafan    struct stat sb;
150166124Srafan
151166124Srafan    if (stat(path, &sb) == 0
152166124Srafan	&& (sb.st_mode & S_IFMT) == S_IFREG) {
153166124Srafan	result = TRUE;
154166124Srafan    }
155166124Srafan    return result;
156166124Srafan}
157166124Srafan
15866963Speter#ifndef USE_ROOT_ENVIRON
15966963Speter/*
16066963Speter * Returns true if we allow application to use environment variables that are
16166963Speter * used for searching lists of directories, etc.
16266963Speter */
16376726SpeterNCURSES_EXPORT(int)
16466963Speter_nc_env_access(void)
16566963Speter{
16666963Speter#if HAVE_ISSETUGID
16766963Speter    if (issetugid())
16866963Speter	return FALSE;
16966963Speter#elif HAVE_GETEUID && HAVE_GETEGID
17066963Speter    if (getuid() != geteuid()
17176726Speter	|| getgid() != getegid())
17266963Speter	return FALSE;
17366963Speter#endif
17476726Speter    return getuid() != 0 && geteuid() != 0;	/* ...finally, disallow root */
17566963Speter}
17666963Speter#endif
177