mapset_msc.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*!
  2. \file lib/gis/mapset_msc.c
  3. \brief GIS library - Mapset user permission routines.
  4. (C) 1999-2014 The GRASS development team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. */
  8. #include <grass/config.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <errno.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <grass/gis.h>
  16. #include <grass/glocale.h>
  17. static int make_mapset_element(const char *, const char *);
  18. static int make_mapset_element_no_fail_on_race(const char *, const char *);
  19. static int make_mapset_element_impl(const char *, const char *, bool);
  20. /*!
  21. \brief Create element in the current mapset.
  22. Make the specified element in the current mapset will check for the
  23. existence of the element and do nothing if it is found so this
  24. routine can be called even if the element already exists.
  25. Calls G_fatal_error() on failure.
  26. \deprecated
  27. This function is deprecated due to confusion in element terminology.
  28. Use G_make_mapset_object_group() or G_make_mapset_dir_object() instead.
  29. \param p_element element to be created in mapset
  30. \return 0 no element defined
  31. \return 1 on success
  32. */
  33. int G_make_mapset_element(const char *p_element)
  34. {
  35. char path[GPATH_MAX];
  36. G_file_name(path, NULL, NULL, G_mapset());
  37. return make_mapset_element(path, p_element);
  38. }
  39. /*!
  40. \brief Create directory for group of elements of a given type.
  41. Creates the specified element directory in the current mapset.
  42. It will check for the existence of the element and do nothing
  43. if it is found so this routine can be called even if the element
  44. already exists to ensure that it exists.
  45. If creation fails, but the directory exists after the failure,
  46. the function reports success. Therefore, two processes creating
  47. a directory in this way can work in parallel.
  48. Calls G_fatal_error() on failure.
  49. \param type object type (e.g., `cell`)
  50. \return 0 no element defined
  51. \return 1 on success
  52. \sa G_make_mapset_dir_object()
  53. \sa G_make_mapset_object_group_tmp()
  54. */
  55. int G_make_mapset_object_group(const char *type)
  56. {
  57. char path[GPATH_MAX];
  58. G_file_name(path, NULL, NULL, G_mapset());
  59. return make_mapset_element_no_fail_on_race(path, type);
  60. }
  61. /*!
  62. \brief Create directory for an object of a given type.
  63. Creates the specified element directory in the current mapset.
  64. It will check for the existence of the element and do nothing
  65. if it is found so this routine can be called even if the element
  66. already exists to ensure that it exists.
  67. Any failure to create it, including the case when it exists
  68. (i.e., was created by another process after the existence test)
  69. is considered a failure because two processes should not attempt
  70. to create two objects of the same name (and type).
  71. This function is for objects which are directories
  72. (the function does not create files).
  73. Calls G_fatal_error() on failure.
  74. \param type object type (e.g., `vector`)
  75. \param name object name (e.g., `bridges`)
  76. \return 0 no element defined
  77. \return 1 on success
  78. \sa G_make_mapset_object_group()
  79. */
  80. int G_make_mapset_dir_object(const char *type, const char *name)
  81. {
  82. char path[GPATH_MAX];
  83. G_make_mapset_object_group(type);
  84. G_file_name(path, type, NULL, G_mapset());
  85. return make_mapset_element(path, name);
  86. }
  87. /*!
  88. \brief Create element in the temporary directory.
  89. See G_file_name_tmp() for details.
  90. \param p_element element to be created in mapset (e.g., `elevation`)
  91. \note
  92. Use G_make_mapset_object_group_tmp() for creating common, shared
  93. directories which are for multiple concrete elements (objects).
  94. \return 0 no element defined
  95. \return 1 on success
  96. */
  97. int G_make_mapset_element_tmp(const char *p_element)
  98. {
  99. char path[GPATH_MAX];
  100. G_file_name_tmp(path, NULL, NULL, G_mapset());
  101. return make_mapset_element(path, p_element);
  102. }
  103. /*!
  104. \brief Create directory for type of objects in the temporary directory.
  105. See G_file_name_tmp() for details.
  106. \param type object type (e.g., `cell`)
  107. \note
  108. Use G_make_mapset_object_group_tmp() for creating common, shared
  109. directories which are for multiple concrete elements (objects).
  110. \return 0 no element defined
  111. \return 1 on success
  112. */
  113. int G_make_mapset_object_group_tmp(const char *type)
  114. {
  115. char path[GPATH_MAX];
  116. G_file_name_tmp(path, NULL, NULL, G_mapset());
  117. return make_mapset_element_no_fail_on_race(path, type);
  118. }
  119. int make_mapset_element_impl(const char *p_path, const char *p_element, bool race_ok)
  120. {
  121. char path[GPATH_MAX], *p;
  122. const char *element;
  123. element = p_element;
  124. if (*element == 0)
  125. return 0;
  126. strncpy(path, p_path, GPATH_MAX);
  127. p = path;
  128. while (*p)
  129. p++;
  130. /* add trailing slash if missing */
  131. --p;
  132. if (*p++ != '/') {
  133. *p++ = '/';
  134. *p = 0;
  135. }
  136. /* now append element, one directory at a time, to path */
  137. while (1) {
  138. if (*element == '/' || *element == 0) {
  139. *p = 0;
  140. char *msg = NULL;
  141. if (access(path, 0) != 0) {
  142. /* Assuming that directory does not exist. */
  143. if (G_mkdir(path) != 0) {
  144. msg = G_store(strerror(errno));
  145. }
  146. }
  147. if (access(path, 0) != 0 || (msg && !race_ok)) {
  148. /* Directory is not accessible even after attempt to create it. */
  149. if (msg) {
  150. /* Error already happened when mkdir. */
  151. G_fatal_error(_("Unable to make mapset element %s (%s): %s"),
  152. p_element, path, strerror(errno));
  153. }
  154. else {
  155. /* Access error is not related to mkdir. */
  156. G_fatal_error(_("Unable to access mapset element %s (%s): %s"),
  157. p_element, path, strerror(errno));
  158. }
  159. }
  160. if (*element == 0)
  161. return 1;
  162. }
  163. *p++ = *element++;
  164. }
  165. }
  166. int make_mapset_element(const char *p_path, const char *p_element)
  167. {
  168. return make_mapset_element_impl(p_path, p_element, false);
  169. }
  170. int make_mapset_element_no_fail_on_race(const char *p_path, const char *p_element)
  171. {
  172. return make_mapset_element_impl(p_path, p_element, true);
  173. }
  174. /*!
  175. \brief Create misc element in the current mapset.
  176. \param dir directory path (e.g., `cell_misc`)
  177. \param name element to be created in mapset (e.g., `elevation`)
  178. \return 0 no element defined
  179. \return 1 on success
  180. */
  181. int G__make_mapset_element_misc(const char *dir, const char *name)
  182. {
  183. return G_make_mapset_dir_object(dir, name);
  184. }
  185. static int check_owner(const struct stat *info)
  186. {
  187. #if defined(__MINGW32__) || defined(SKIP_MAPSET_OWN_CHK)
  188. return 1;
  189. #else
  190. const char *check = getenv("GRASS_SKIP_MAPSET_OWNER_CHECK");
  191. if (check && *check)
  192. return 1;
  193. if (info->st_uid != getuid())
  194. return 0;
  195. if (info->st_uid != geteuid())
  196. return 0;
  197. return 1;
  198. #endif
  199. }
  200. /*!
  201. \brief Check for user mapset permission
  202. \param mapset mapset name
  203. \return 1 mapset exists, and user has permission
  204. \return 0 mapset exists, BUT user denied permission
  205. \return -1 mapset does not exist
  206. */
  207. int G_mapset_permissions(const char *mapset)
  208. {
  209. char path[GPATH_MAX];
  210. struct stat info;
  211. G_file_name(path, "", "", mapset);
  212. if (G_stat(path, &info) != 0)
  213. return -1;
  214. if (!S_ISDIR(info.st_mode))
  215. return -1;
  216. if (!check_owner(&info))
  217. return 0;
  218. return 1;
  219. }
  220. /*!
  221. \brief Check for user mapset permission
  222. \param gisdbase full path to GISDBASE
  223. \param location location name
  224. \param mapset mapset name
  225. \return 1 mapset exists, and user has permission
  226. \return 0 mapset exists, BUT user denied permission
  227. \return -1 mapset does not exist
  228. */
  229. int G_mapset_permissions2(const char *gisdbase, const char *location,
  230. const char *mapset)
  231. {
  232. char path[GPATH_MAX];
  233. struct stat info;
  234. sprintf(path, "%s/%s/%s", gisdbase, location, mapset);
  235. if (G_stat(path, &info) != 0)
  236. return -1;
  237. if (!S_ISDIR(info.st_mode))
  238. return -1;
  239. if (!check_owner(&info))
  240. return 0;
  241. return 1;
  242. }