GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
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 SPDX-FileCopyrightText: 1999-2014 GRASS Development Team
7 SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include <grass/config.h>
11#include <string.h>
12#include <unistd.h>
13#include <stdbool.h>
14#include <stdlib.h>
15#include <errno.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <grass/gis.h>
19#include <grass/glocale.h>
20
21static int make_mapset_element(const char *, const char *);
22static int make_mapset_element_no_fail_on_race(const char *, const char *);
23static int make_mapset_element_impl(const char *, const char *, bool);
24
25/*!
26 \brief Create element in the current mapset.
27
28 Make the specified element in the current mapset will check for the
29 existence of the element and do nothing if it is found so this
30 routine can be called even if the element already exists.
31
32 Calls G_fatal_error() on failure.
33
34 \deprecated
35 This function is deprecated due to confusion in element terminology.
36 Use G_make_mapset_object_group() or G_make_mapset_dir_object() instead.
37
38 \param p_element element to be created in mapset
39
40 \return 0 no element defined
41 \return 1 on success
42 */
44{
45 char path[GPATH_MAX];
46
48 return make_mapset_element(path, p_element);
49}
50
51/*!
52 \brief Create directory for group of elements of a given type.
53
54 Creates the specified element directory in the current mapset.
55 It will check for the existence of the element and do nothing
56 if it is found so this routine can be called even if the element
57 already exists to ensure that it exists.
58
59 If creation fails, but the directory exists after the failure,
60 the function reports success. Therefore, two processes creating
61 a directory in this way can work in parallel.
62
63 Calls G_fatal_error() on failure.
64
65 \param type object type (e.g., `cell`)
66
67 \return 0 no element defined
68 \return 1 on success
69
70 \sa G_make_mapset_dir_object()
71 \sa G_make_mapset_object_group_tmp()
72 */
73int G_make_mapset_object_group(const char *type)
74{
75 char path[GPATH_MAX];
76
78 return make_mapset_element_no_fail_on_race(path, type);
79}
80
81/*!
82 \brief Create directory for an object of a given type.
83
84 Creates the specified element directory in the current mapset.
85 It will check for the existence of the element and do nothing
86 if it is found so this routine can be called even if the element
87 already exists to ensure that it exists.
88
89 Any failure to create it, including the case when it exists
90 (i.e., was created by another process after the existence test)
91 is considered a failure because two processes should not attempt
92 to create two objects of the same name (and type).
93
94 This function is for objects which are directories
95 (the function does not create files).
96
97 Calls G_fatal_error() on failure.
98
99 \param type object type (e.g., `vector`)
100 \param name object name (e.g., `bridges`)
101
102 \return 0 no element defined
103 \return 1 on success
104
105 \sa G_make_mapset_object_group()
106 */
107int G_make_mapset_dir_object(const char *type, const char *name)
108{
109 char path[GPATH_MAX];
110
112 G_file_name(path, type, NULL, G_mapset());
113 return make_mapset_element(path, name);
114}
115
116/*!
117 \brief Create element in the temporary directory.
118
119 See G_file_name_tmp() for details.
120
121 \param p_element element to be created in mapset (e.g., `elevation`)
122
123 \note
124 Use G_make_mapset_object_group_tmp() for creating common, shared
125 directories which are for multiple concrete elements (objects).
126
127 \return 0 no element defined
128 \return 1 on success
129 */
131{
132 char path[GPATH_MAX];
133
135 return make_mapset_element(path, p_element);
136}
137
138/*!
139 \brief Create directory for type of objects in the temporary directory.
140
141 See G_file_name_tmp() for details.
142
143 \param type object type (e.g., `cell`)
144
145 \note
146 Use G_make_mapset_object_group_tmp() for creating common, shared
147 directories which are for multiple concrete elements (objects).
148
149 \return 0 no element defined
150 \return 1 on success
151 */
153{
154 char path[GPATH_MAX];
155
157 return make_mapset_element_no_fail_on_race(path, type);
158}
159
160/*!
161 \brief Create directory for type of objects in the temporary directory.
162
163 See G_file_name_basedir() for details.
164
165 \param type object type (e.g., `cell`)
166
167 \note
168 Use G_make_mapset_object_group_basedir() for creating common, shared
169 directories for temporary data.
170
171 \return 0 no element defined
172 \return 1 on success
173 */
174int G_make_mapset_object_group_basedir(const char *type, const char *basedir)
175{
176 char path[GPATH_MAX];
177
179 return make_mapset_element_no_fail_on_race(path, type);
180}
181
182int make_mapset_element_impl(const char *p_path, const char *p_element,
183 bool race_ok)
184{
185 char path[GPATH_MAX] = {'\0'};
186 char *p;
187 const char *element;
188
190 if (*element == 0)
191 return 0;
192
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) {
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"),
224 }
225 else {
226 /* Access error is not related to mkdir. */
228 _("Unable to access mapset element %s (%s): %s"),
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(_WIN32) || 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 snprintf(path, sizeof(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
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition file_name.c:59
char * G_file_name_basedir(char *, const char *, const char *, const char *, const char *)
Builds full path names to GIS data files in temporary directory (for internal use only)
Definition file_name.c:153
int G_stat(const char *, struct stat *)
Get file status.
Definition paths.c:128
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:85
char * G_file_name_tmp(char *, const char *, const char *, const char *)
Builds full path names to GIS data files in temporary directory (for internal use only)
Definition file_name.c:123
int G_mkdir(const char *)
Creates a new directory.
Definition paths.c:27
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:31
#define GPATH_MAX
Definition gis.h:196
#define _(str)
Definition glocale.h:10
int G_make_mapset_object_group_tmp(const char *type)
Create directory for type of objects in the temporary directory.
Definition mapset_msc.c:152
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:73
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:107
int G_make_mapset_element(const char *p_element)
Create element in the current mapset.
Definition mapset_msc.c:43
int G_make_mapset_element_tmp(const char *p_element)
Create element in the temporary directory.
Definition mapset_msc.c:130
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:174
const char * name
Definition named_colr.c:6
#define S_ISDIR(mode)
Definition stat.h:6
Definition path.h:15
#define access
Definition unistd.h:7