xref: /freebsd/contrib/ncurses/ncurses/tinfo/access.c (revision 5ca44d1c)
10e3d5408SPeter Wemm /****************************************************************************
25ca44d1cSRong-En Fan  * Copyright 2019,2020 Thomas E. Dickey                                     *
30e3d5408SPeter Wemm  * Copyright 1998-2011,2012 Free Software Foundation, Inc.                  *
40e3d5408SPeter Wemm  *                                                                          *
50e3d5408SPeter Wemm  * Permission is hereby granted, free of charge, to any person obtaining a  *
60e3d5408SPeter Wemm  * copy of this software and associated documentation files (the            *
70e3d5408SPeter Wemm  * "Software"), to deal in the Software without restriction, including      *
80e3d5408SPeter Wemm  * without limitation the rights to use, copy, modify, merge, publish,      *
90e3d5408SPeter Wemm  * distribute, distribute with modifications, sublicense, and/or sell       *
100e3d5408SPeter Wemm  * copies of the Software, and to permit persons to whom the Software is    *
110e3d5408SPeter Wemm  * furnished to do so, subject to the following conditions:                 *
120e3d5408SPeter Wemm  *                                                                          *
130e3d5408SPeter Wemm  * The above copyright notice and this permission notice shall be included  *
140e3d5408SPeter Wemm  * in all copies or substantial portions of the Software.                   *
150e3d5408SPeter Wemm  *                                                                          *
160e3d5408SPeter Wemm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
170e3d5408SPeter Wemm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
180e3d5408SPeter Wemm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
190e3d5408SPeter Wemm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
200e3d5408SPeter Wemm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
210e3d5408SPeter Wemm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
220e3d5408SPeter Wemm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
230e3d5408SPeter Wemm  *                                                                          *
240e3d5408SPeter Wemm  * Except as contained in this notice, the name(s) of the above copyright   *
250e3d5408SPeter Wemm  * holders shall not be used in advertising or otherwise to promote the     *
260e3d5408SPeter Wemm  * sale, use or other dealings in this Software without prior written       *
270e3d5408SPeter Wemm  * authorization.                                                           *
280e3d5408SPeter Wemm  ****************************************************************************/
290e3d5408SPeter Wemm 
304a1a9510SRong-En Fan /****************************************************************************
310e3d5408SPeter Wemm  *  Author: Thomas E. Dickey                                                *
320e3d5408SPeter Wemm  ****************************************************************************/
330e3d5408SPeter Wemm 
344a1a9510SRong-En Fan #include <curses.priv.h>
355ca44d1cSRong-En Fan 
364a1a9510SRong-En Fan #include <ctype.h>
374a1a9510SRong-En Fan 
3818259542SPeter Wemm #include <tic.h>
3939f2269fSPeter Wemm 
400e3d5408SPeter Wemm MODULE_ID("$Id: access.c,v 1.27 2020/08/29 16:22:03 juergen Exp $")
415ca44d1cSRong-En Fan 
4239f2269fSPeter Wemm #define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
4339f2269fSPeter Wemm 
4439f2269fSPeter Wemm #ifdef _NC_MSC
4539f2269fSPeter Wemm # define ACCESS(FN, MODE) access((FN), (MODE)&(R_OK|W_OK))
4639f2269fSPeter Wemm #else
4739f2269fSPeter Wemm # define ACCESS access
4839f2269fSPeter Wemm #endif
495ca44d1cSRong-En Fan 
NCURSES_EXPORT(char *)5039f2269fSPeter Wemm NCURSES_EXPORT(char *)
5139f2269fSPeter Wemm _nc_rootname(char *path)
5239f2269fSPeter Wemm {
5339f2269fSPeter Wemm     char *result = _nc_basename(path);
5439f2269fSPeter Wemm #if !MIXEDCASE_FILENAMES || defined(PROG_EXT)
555ca44d1cSRong-En Fan     static char *temp;
5639f2269fSPeter Wemm     char *s;
5739f2269fSPeter Wemm 
5839f2269fSPeter Wemm     temp = strdup(result);
5939f2269fSPeter Wemm     result = temp;
6039f2269fSPeter Wemm #if !MIXEDCASE_FILENAMES
6139f2269fSPeter Wemm     for (s = result; *s != '\0'; ++s) {
6239f2269fSPeter Wemm 	*s = (char) LOWERCASE(*s);
6339f2269fSPeter Wemm     }
6439f2269fSPeter Wemm #endif
6539f2269fSPeter Wemm #if defined(PROG_EXT)
6639f2269fSPeter Wemm     if ((s = strrchr(result, '.')) != 0) {
6739f2269fSPeter Wemm 	if (!strcmp(s, PROG_EXT))
6839f2269fSPeter Wemm 	    *s = '\0';
690e3d5408SPeter Wemm     }
704a1a9510SRong-En Fan #endif
714a1a9510SRong-En Fan #endif
724a1a9510SRong-En Fan     return result;
734a1a9510SRong-En Fan }
744a1a9510SRong-En Fan 
754a1a9510SRong-En Fan /*
764a1a9510SRong-En Fan  * Check if a string appears to be an absolute pathname.
774a1a9510SRong-En Fan  */
784a1a9510SRong-En Fan NCURSES_EXPORT(bool)
_nc_is_abs_path(const char * path)794a1a9510SRong-En Fan _nc_is_abs_path(const char *path)
804a1a9510SRong-En Fan {
814a1a9510SRong-En Fan #if defined(__EMX__) || defined(__DJGPP__)
824a1a9510SRong-En Fan #define is_pathname(s) ((((s) != 0) && ((s)[0] == '/')) \
834a1a9510SRong-En Fan 		  || (((s)[0] != 0) && ((s)[1] == ':')))
844a1a9510SRong-En Fan #else
854a1a9510SRong-En Fan #define is_pathname(s) ((s) != 0 && (s)[0] == '/')
864a1a9510SRong-En Fan #endif
874a1a9510SRong-En Fan     return is_pathname(path);
884a1a9510SRong-En Fan }
894a1a9510SRong-En Fan 
904a1a9510SRong-En Fan /*
914a1a9510SRong-En Fan  * Return index of the basename
924a1a9510SRong-En Fan  */
934a1a9510SRong-En Fan NCURSES_EXPORT(unsigned)
_nc_pathlast(const char * path)944a1a9510SRong-En Fan _nc_pathlast(const char *path)
954a1a9510SRong-En Fan {
964a1a9510SRong-En Fan     const char *test = strrchr(path, '/');
974a1a9510SRong-En Fan #ifdef __EMX__
984a1a9510SRong-En Fan     if (test == 0)
994a1a9510SRong-En Fan 	test = strrchr(path, '\\');
1004a1a9510SRong-En Fan #endif
1014a1a9510SRong-En Fan     if (test == 0)
1024a1a9510SRong-En Fan 	test = path;
1037a69bbfbSPeter Wemm     else
10418259542SPeter Wemm 	test++;
10518259542SPeter Wemm     return (unsigned) (test - path);
1064a1a9510SRong-En Fan }
10718259542SPeter Wemm 
10818259542SPeter Wemm NCURSES_EXPORT(char *)
_nc_basename(char * path)1097a69bbfbSPeter Wemm _nc_basename(char *path)
11018259542SPeter Wemm {
1110e3d5408SPeter Wemm     return path + _nc_pathlast(path);
1120e3d5408SPeter Wemm }
1130e3d5408SPeter Wemm 
11418259542SPeter Wemm NCURSES_EXPORT(int)
_nc_access(const char * path,int mode)11518259542SPeter Wemm _nc_access(const char *path, int mode)
1160e3d5408SPeter Wemm {
11718259542SPeter Wemm     int result;
11818259542SPeter Wemm 
1190e3d5408SPeter Wemm     if (path == 0) {
1200e3d5408SPeter Wemm 	result = -1;
1210e3d5408SPeter Wemm     } else if (ACCESS(path, mode) < 0) {
1220e3d5408SPeter Wemm 	if ((mode & W_OK) != 0
1230e3d5408SPeter Wemm 	    && errno == ENOENT
12418259542SPeter Wemm 	    && strlen(path) < PATH_MAX) {
1250e3d5408SPeter Wemm 	    char head[PATH_MAX];
1260e3d5408SPeter Wemm 	    char *leaf;
1270e3d5408SPeter Wemm 
1280e3d5408SPeter Wemm 	    _nc_STRCPY(head, path, sizeof(head));
1290e3d5408SPeter Wemm 	    leaf = _nc_basename(head);
1300e3d5408SPeter Wemm 	    if (leaf == 0)
13118259542SPeter Wemm 		leaf = head;
1324a1a9510SRong-En Fan 	    *leaf = '\0';
1334a1a9510SRong-En Fan 	    if (head == leaf)
1344a1a9510SRong-En Fan 		_nc_STRCPY(head, ".", sizeof(head));
1354a1a9510SRong-En Fan 
1364a1a9510SRong-En Fan 	    result = ACCESS(head, R_OK | W_OK | X_OK);
1374a1a9510SRong-En Fan 	} else {
1384a1a9510SRong-En Fan 	    result = -1;
1394a1a9510SRong-En Fan 	}
1404a1a9510SRong-En Fan     } else {
1414a1a9510SRong-En Fan 	result = 0;
1424a1a9510SRong-En Fan     }
1434a1a9510SRong-En Fan     return result;
1444a1a9510SRong-En Fan }
1454a1a9510SRong-En Fan 
1464a1a9510SRong-En Fan NCURSES_EXPORT(bool)
_nc_is_dir_path(const char * path)1474a1a9510SRong-En Fan _nc_is_dir_path(const char *path)
1484a1a9510SRong-En Fan {
1494a1a9510SRong-En Fan     bool result = FALSE;
1504a1a9510SRong-En Fan     struct stat sb;
1514a1a9510SRong-En Fan 
1524a1a9510SRong-En Fan     if (stat(path, &sb) == 0
1534a1a9510SRong-En Fan 	&& S_ISDIR(sb.st_mode)) {
1544a1a9510SRong-En Fan 	result = TRUE;
1554a1a9510SRong-En Fan     }
1564a1a9510SRong-En Fan     return result;
1574a1a9510SRong-En Fan }
15818259542SPeter Wemm 
15918259542SPeter Wemm NCURSES_EXPORT(bool)
_nc_is_file_path(const char * path)16018259542SPeter Wemm _nc_is_file_path(const char *path)
16118259542SPeter Wemm {
16218259542SPeter Wemm     bool result = FALSE;
1637a69bbfbSPeter Wemm     struct stat sb;
16418259542SPeter Wemm 
16518259542SPeter Wemm     if (stat(path, &sb) == 0
16618259542SPeter Wemm 	&& S_ISREG(sb.st_mode)) {
16718259542SPeter Wemm 	result = TRUE;
16818259542SPeter Wemm     }
16918259542SPeter Wemm     return result;
17018259542SPeter Wemm }
17118259542SPeter Wemm 
17218259542SPeter Wemm #ifndef USE_ROOT_ENVIRON
17318259542SPeter Wemm /*
1747a69bbfbSPeter Wemm  * Returns true if we allow application to use environment variables that are
17518259542SPeter Wemm  * used for searching lists of directories, etc.
17618259542SPeter Wemm  */
177 NCURSES_EXPORT(int)
_nc_env_access(void)178 _nc_env_access(void)
179 {
180 #if HAVE_ISSETUGID
181     if (issetugid())
182 	return FALSE;
183 #elif HAVE_GETEUID && HAVE_GETEGID
184     if (getuid() != geteuid()
185 	|| getgid() != getegid())
186 	return FALSE;
187 #endif
188     /* ...finally, disallow root */
189     return (getuid() != ROOT_UID) && (geteuid() != ROOT_UID);
190 }
191 #endif
192