GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
mapset_msc.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/mapset_msc.c
3
4 \brief GIS library - Mapset user permission routines.
5
6 (C) 1999-2014 The GRASS development team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10 */
11
12#include <grass/config.h>
13#include <string.h>
14#include <unistd.h>
15#include <stdlib.h>
16#include <errno.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <grass/gis.h>
20#include <grass/glocale.h>
21
22static int make_mapset_element(const char *, const char *);
23static int make_mapset_element_no_fail_on_race(const char *, const char *);
24static int make_mapset_element_impl(const char *, const char *, bool);
25
26/*!
27 \brief Create element in the current mapset.
28
29 Make the specified element in the current mapset will check for the
30 existence of the element and do nothing if it is found so this
31 routine can be called even if the element already exists.
32
33 Calls G_fatal_error() on failure.
34
35 \deprecated
36 This function is deprecated due to confusion in element terminology.
37 Use G_make_mapset_object_group() or G_make_mapset_dir_object() instead.
38
39 \param p_element element to be created in mapset
40
41 \return 0 no element defined
42 \return 1 on success
43 */
44int G_make_mapset_element(const char *p_element)
45{
46 char path[GPATH_MAX];
47
49 return make_mapset_element(path, p_element);
50}
51
52/*!
53 \brief Create directory for group of elements of a given type.
54
55 Creates the specified element directory in the current mapset.
56 It will check for the existence of the element and do nothing
57 if it is found so this routine can be called even if the element
58 already exists to ensure that it exists.
59
60 If creation fails, but the directory exists after the failure,
61 the function reports success. Therefore, two processes creating
62 a directory in this way can work in parallel.
63
64 Calls G_fatal_error() on failure.
65
66 \param type object type (e.g., `cell`)
67
68 \return 0 no element defined
69 \return 1 on success
70
71 \sa G_make_mapset_dir_object()
72 \sa G_make_mapset_object_group_tmp()
73 */
74int G_make_mapset_object_group(const char *type)
75{
76 char path[GPATH_MAX];
77
79 return make_mapset_element_no_fail_on_race(path, type);
80}
81
82/*!
83 \brief Create directory for an object of a given type.
84
85 Creates the specified element directory in the current mapset.
86 It will check for the existence of the element and do nothing
87 if it is found so this routine can be called even if the element
88 already exists to ensure that it exists.
89
90 Any failure to create it, including the case when it exists
91 (i.e., was created by another process after the existence test)
92 is considered a failure because two processes should not attempt
93 to create two objects of the same name (and type).
94
95 This function is for objects which are directories
96 (the function does not create files).
97
98 Calls G_fatal_error() on failure.
99
100 \param type object type (e.g., `vector`)
101 \param name object name (e.g., `bridges`)
102
103 \return 0 no element defined
104 \return 1 on success
105
106 \sa G_make_mapset_object_group()
107 */
108int G_make_mapset_dir_object(const char *type, const char *name)
109{
110 char path[GPATH_MAX];
111
113 G_file_name(path, type, NULL, G_mapset());
114 return make_mapset_element(path, name);
115}
116
117/*!
118 \brief Create element in the temporary directory.
119
120 See G_file_name_tmp() for details.
121
122 \param p_element element to be created in mapset (e.g., `elevation`)
123
124 \note
125 Use G_make_mapset_object_group_tmp() for creating common, shared
126 directories which are for multiple concrete elements (objects).
127
128 \return 0 no element defined
129 \return 1 on success
130 */
131int G_make_mapset_element_tmp(const char *p_element)
132{
133 char path[GPATH_MAX];
134
136 return make_mapset_element(path, p_element);
137}
138
139/*!
140 \brief Create directory for type of objects in the temporary directory.
141
142 See G_file_name_tmp() for details.
143
144 \param type object type (e.g., `cell`)
145
146 \note
147 Use G_make_mapset_object_group_tmp() for creating common, shared
148 directories which are for multiple concrete elements (objects).
149
150 \return 0 no element defined
151 \return 1 on success
152 */
154{
155 char path[GPATH_MAX];
156
158 return make_mapset_element_no_fail_on_race(path, type);
159}
160
161/*!
162 \brief Create directory for type of objects in the temporary directory.
163
164 See G_file_name_basedir() for details.
165
166 \param type object type (e.g., `cell`)
167
168 \note
169 Use G_make_mapset_object_group_basedir() for creating common, shared
170 directories for temporary data.
171
172 \return 0 no element defined
173 \return 1 on success
174 */
175int G_make_mapset_object_group_basedir(const char *type, const char *basedir)
176{
177 char path[GPATH_MAX];
178
180 return make_mapset_element_no_fail_on_race(path, type);
181}
182
183int make_mapset_element_impl(const char *p_path, const char *p_element,
184 bool race_ok)
185{
186 char path[GPATH_MAX], *p;
187 const char *element;
188
189 element = p_element;
190 if (*element == 0)
191 return 0;
192
193 strncpy(path, p_path, GPATH_MAX);
194 p = path;
195 while (*p)
196 p++;
197 /* add trailing slash if missing */
198 --p;
199 if (*p++ != '/') {
200 *p++ = '/';
201 *p = 0;
202 }
203
204 /* now append element, one directory at a time, to path */
205 while (1) {
206 if (*element == '/' || *element == 0) {
207 *p = 0;
208 char *msg = NULL;
209
210 if (access(path, 0) != 0) {
211 /* Assuming that directory does not exist. */
212 if (G_mkdir(path) != 0) {
213 msg = G_store(strerror(errno));
214 }
215 }
216 if (access(path, 0) != 0 || (msg && !race_ok)) {
217 /* Directory is not accessible even after attempt to create it.
218 */
219 if (msg) {
220 /* Error already happened when mkdir. */
222 _("Unable to make mapset element %s (%s): %s"),
223 p_element, path, strerror(errno));
224 }
225 else {
226 /* Access error is not related to mkdir. */
228 _("Unable to access mapset element %s (%s): %s"),
229 p_element, path, strerror(errno));
230 }
231 }
232 if (*element == 0)
233 return 1;
234 }
235 *p++ = *element++;
236 }
237}
238
239int make_mapset_element(const char *p_path, const char *p_element)
240{
241 return make_mapset_element_impl(p_path, p_element, false);
242}
243
244int make_mapset_element_no_fail_on_race(const char *p_path,
245 const char *p_element)
246{
247 return make_mapset_element_impl(p_path, p_element, true);
248}
249
250/*!
251 \brief Create misc element in the current mapset.
252
253 \param dir directory path (e.g., `cell_misc`)
254 \param name element to be created in mapset (e.g., `elevation`)
255
256 \return 0 no element defined
257 \return 1 on success
258 */
259int G__make_mapset_element_misc(const char *dir, const char *name)
260{
261 return G_make_mapset_dir_object(dir, name);
262}
263
264static int check_owner(const struct stat *info)
265{
266#if defined(__MINGW32__) || defined(SKIP_MAPSET_OWN_CHK)
267 return 1;
268#else
269 const char *check = getenv("GRASS_SKIP_MAPSET_OWNER_CHECK");
270
271 if (check && *check)
272 return 1;
273 if (info->st_uid != getuid())
274 return 0;
275 if (info->st_uid != geteuid())
276 return 0;
277 return 1;
278#endif
279}
280
281/*!
282 \brief Check for user mapset permission
283
284 \param mapset mapset name
285
286 \return 1 mapset exists, and user has permission
287 \return 0 mapset exists, BUT user denied permission
288 \return -1 mapset does not exist
289 */
290int G_mapset_permissions(const char *mapset)
291{
292 char path[GPATH_MAX];
293 struct stat info;
294
295 G_file_name(path, "", "", mapset);
296
297 if (G_stat(path, &info) != 0)
298 return -1;
299 if (!S_ISDIR(info.st_mode))
300 return -1;
301
302 if (!check_owner(&info))
303 return 0;
304
305 return 1;
306}
307
308/*!
309 \brief Check for user mapset permission
310
311 \param gisdbase full path to GISDBASE
312 \param location location name
313 \param mapset mapset name
314
315 \return 1 mapset exists, and user has permission
316 \return 0 mapset exists, BUT user denied permission
317 \return -1 mapset does not exist
318 */
319int G_mapset_permissions2(const char *gisdbase, const char *location,
320 const char *mapset)
321{
322 char path[GPATH_MAX];
323 struct stat info;
324
325 sprintf(path, "%s/%s/%s", gisdbase, location, mapset);
326
327 if (G_stat(path, &info) != 0)
328 return -1;
329 if (!S_ISDIR(info.st_mode))
330 return -1;
331
332 if (!check_owner(&info))
333 return 0;
334
335 return 1;
336}
#define NULL
Definition ccmath.h:32
char * G_file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
Definition file_name.c:61
char * G_file_name_basedir(char *path, const char *element, const char *name, const char *mapset, const char *basedir)
Builds full path names to GIS data files in temporary directory (for internal use only)
Definition file_name.c:154
char * G_file_name_tmp(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files in temporary directory (for internal use only)
Definition file_name.c:125
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition gis/error.c:159
const char * G_mapset(void)
Get current mapset name.
Definition mapset.c:33
int G_make_mapset_object_group_tmp(const char *type)
Create directory for type of objects in the temporary directory.
Definition mapset_msc.c:153
int G__make_mapset_element_misc(const char *dir, const char *name)
Create misc element in the current mapset.
Definition mapset_msc.c:259
int G_mapset_permissions2(const char *gisdbase, const char *location, const char *mapset)
Check for user mapset permission.
Definition mapset_msc.c:319
int G_make_mapset_object_group(const char *type)
Create directory for group of elements of a given type.
Definition mapset_msc.c:74
int G_mapset_permissions(const char *mapset)
Check for user mapset permission.
Definition mapset_msc.c:290
int G_make_mapset_dir_object(const char *type, const char *name)
Create directory for an object of a given type.
Definition mapset_msc.c:108
int G_make_mapset_element(const char *p_element)
Create element in the current mapset.
Definition mapset_msc.c:44
int G_make_mapset_element_tmp(const char *p_element)
Create element in the temporary directory.
Definition mapset_msc.c:131
int G_make_mapset_object_group_basedir(const char *type, const char *basedir)
Create directory for type of objects in the temporary directory.
Definition mapset_msc.c:175
const char * name
Definition named_colr.c:6
int G_mkdir(const char *path)
Creates a new directory.
Definition paths.c:27
int G_stat(const char *file_name, struct stat *buf)
Get file status.
Definition paths.c:128
char * G_store(const char *s)
Copy string to allocated memory.
Definition strings.c:87
Definition path.h:15