123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- /*!
- \file lib/gis/mapset_msc.c
- \brief GIS library - Mapset user permission routines.
- (C) 1999-2014 The GRASS development team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- */
- #include <grass/config.h>
- #include <string.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- static int make_mapset_element(const char *, const char *);
- static int make_mapset_element_no_fail_on_race(const char *, const char *);
- static int make_mapset_element_impl(const char *, const char *, bool);
- /*!
- \brief Create element in the current mapset.
- Make the specified element in the current mapset will check for the
- existence of the element and do nothing if it is found so this
- routine can be called even if the element already exists.
-
- Calls G_fatal_error() on failure.
- \deprecated
- This function is deprecated due to confusion in element terminology.
- Use G_make_mapset_object_group() or G_make_mapset_dir_object() instead.
- \param p_element element to be created in mapset
- \return 0 no element defined
- \return 1 on success
- */
- int G_make_mapset_element(const char *p_element)
- {
- char path[GPATH_MAX];
-
- G_file_name(path, NULL, NULL, G_mapset());
- return make_mapset_element(path, p_element);
- }
- /*!
- \brief Create directory for group of elements of a given type.
- Creates the specified element directory in the current mapset.
- It will check for the existence of the element and do nothing
- if it is found so this routine can be called even if the element
- already exists to ensure that it exists.
- If creation fails, but the directory exists after the failure,
- the function reports success. Therefore, two processes creating
- a directory in this way can work in parallel.
- Calls G_fatal_error() on failure.
- \param type object type (e.g., `cell`)
- \return 0 no element defined
- \return 1 on success
- \sa G_make_mapset_dir_object()
- \sa G_make_mapset_object_group_tmp()
- */
- int G_make_mapset_object_group(const char *type)
- {
- char path[GPATH_MAX];
- G_file_name(path, NULL, NULL, G_mapset());
- return make_mapset_element_no_fail_on_race(path, type);
- }
- /*!
- \brief Create directory for an object of a given type.
- Creates the specified element directory in the current mapset.
- It will check for the existence of the element and do nothing
- if it is found so this routine can be called even if the element
- already exists to ensure that it exists.
- Any failure to create it, including the case when it exists
- (i.e., was created by another process after the existence test)
- is considered a failure because two processes should not attempt
- to create two objects of the same name (and type).
- This function is for objects which are directories
- (the function does not create files).
- Calls G_fatal_error() on failure.
- \param type object type (e.g., `vector`)
- \param name object name (e.g., `bridges`)
- \return 0 no element defined
- \return 1 on success
- \sa G_make_mapset_object_group()
- */
- int G_make_mapset_dir_object(const char *type, const char *name)
- {
- char path[GPATH_MAX];
- G_make_mapset_object_group(type);
- G_file_name(path, type, NULL, G_mapset());
- return make_mapset_element(path, name);
- }
- /*!
- \brief Create element in the temporary directory.
- See G_file_name_tmp() for details.
- \param p_element element to be created in mapset (e.g., `elevation`)
- \note
- Use G_make_mapset_object_group_tmp() for creating common, shared
- directories which are for multiple concrete elements (objects).
- \return 0 no element defined
- \return 1 on success
- */
- int G_make_mapset_element_tmp(const char *p_element)
- {
- char path[GPATH_MAX];
-
- G_file_name_tmp(path, NULL, NULL, G_mapset());
- return make_mapset_element(path, p_element);
- }
- /*!
- \brief Create directory for type of objects in the temporary directory.
- See G_file_name_tmp() for details.
- \param type object type (e.g., `cell`)
- \note
- Use G_make_mapset_object_group_tmp() for creating common, shared
- directories which are for multiple concrete elements (objects).
- \return 0 no element defined
- \return 1 on success
- */
- int G_make_mapset_object_group_tmp(const char *type)
- {
- char path[GPATH_MAX];
- G_file_name_tmp(path, NULL, NULL, G_mapset());
- return make_mapset_element_no_fail_on_race(path, type);
- }
- int make_mapset_element_impl(const char *p_path, const char *p_element, bool race_ok)
- {
- char path[GPATH_MAX], *p;
- const char *element;
- element = p_element;
- if (*element == 0)
- return 0;
- strncpy(path, p_path, GPATH_MAX);
- p = path;
- while (*p)
- p++;
- /* add trailing slash if missing */
- --p;
- if (*p++ != '/') {
- *p++ = '/';
- *p = 0;
- }
- /* now append element, one directory at a time, to path */
- while (1) {
- if (*element == '/' || *element == 0) {
- *p = 0;
- char *msg = NULL;
- if (access(path, 0) != 0) {
- /* Assuming that directory does not exist. */
- if (G_mkdir(path) != 0) {
- msg = G_store(strerror(errno));
- }
- }
- if (access(path, 0) != 0 || (msg && !race_ok)) {
- /* Directory is not accessible even after attempt to create it. */
- if (msg) {
- /* Error already happened when mkdir. */
- G_fatal_error(_("Unable to make mapset element %s (%s): %s"),
- p_element, path, strerror(errno));
- }
- else {
- /* Access error is not related to mkdir. */
- G_fatal_error(_("Unable to access mapset element %s (%s): %s"),
- p_element, path, strerror(errno));
- }
- }
- if (*element == 0)
- return 1;
- }
- *p++ = *element++;
- }
- }
- int make_mapset_element(const char *p_path, const char *p_element)
- {
- return make_mapset_element_impl(p_path, p_element, false);
- }
- int make_mapset_element_no_fail_on_race(const char *p_path, const char *p_element)
- {
- return make_mapset_element_impl(p_path, p_element, true);
- }
- /*!
- \brief Create misc element in the current mapset.
- \param dir directory path (e.g., `cell_misc`)
- \param name element to be created in mapset (e.g., `elevation`)
- \return 0 no element defined
- \return 1 on success
- */
- int G__make_mapset_element_misc(const char *dir, const char *name)
- {
- return G_make_mapset_dir_object(dir, name);
- }
- static int check_owner(const struct stat *info)
- {
- #if defined(__MINGW32__) || defined(SKIP_MAPSET_OWN_CHK)
- return 1;
- #else
- const char *check = getenv("GRASS_SKIP_MAPSET_OWNER_CHECK");
- if (check && *check)
- return 1;
- if (info->st_uid != getuid())
- return 0;
- if (info->st_uid != geteuid())
- return 0;
- return 1;
- #endif
- }
- /*!
- \brief Check for user mapset permission
- \param mapset mapset name
- \return 1 mapset exists, and user has permission
- \return 0 mapset exists, BUT user denied permission
- \return -1 mapset does not exist
- */
- int G_mapset_permissions(const char *mapset)
- {
- char path[GPATH_MAX];
- struct stat info;
- G_file_name(path, "", "", mapset);
- if (G_stat(path, &info) != 0)
- return -1;
- if (!S_ISDIR(info.st_mode))
- return -1;
- if (!check_owner(&info))
- return 0;
- return 1;
- }
- /*!
- \brief Check for user mapset permission
- \param gisdbase full path to GISDBASE
- \param location location name
- \param mapset mapset name
- \return 1 mapset exists, and user has permission
- \return 0 mapset exists, BUT user denied permission
- \return -1 mapset does not exist
- */
- int G_mapset_permissions2(const char *gisdbase, const char *location,
- const char *mapset)
- {
- char path[GPATH_MAX];
- struct stat info;
- sprintf(path, "%s/%s/%s", gisdbase, location, mapset);
- if (G_stat(path, &info) != 0)
- return -1;
- if (!S_ISDIR(info.st_mode))
- return -1;
- if (!check_owner(&info))
- return 0;
- return 1;
- }
|