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