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