GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
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] = {'\0'};
187 char *p;
188 const char *element;
189
190 element = p_element;
191 if (*element == 0)
192 return 0;
193
194 strncpy(path, p_path, GPATH_MAX - 1);
195 p = path;
196 while (*p)
197 p++;
198 /* add trailing slash if missing */
199 --p;
200 if (*p++ != '/') {
201 *p++ = '/';
202 *p = 0;
203 }
204
205 /* now append element, one directory at a time, to path */
206 while (1) {
207 if (*element == '/' || *element == 0) {
208 *p = 0;
209 char *msg = NULL;
210
211 if (access(path, 0) != 0) {
212 /* Assuming that directory does not exist. */
213 if (G_mkdir(path) != 0) {
214 msg = G_store(strerror(errno));
215 }
216 }
217 if (access(path, 0) != 0 || (msg && !race_ok)) {
218 /* Directory is not accessible even after attempt to create it.
219 */
220 if (msg) {
221 /* Error already happened when mkdir. */
223 _("Unable to make mapset element %s (%s): %s"),
224 p_element, path, strerror(errno));
225 }
226 else {
227 /* Access error is not related to mkdir. */
229 _("Unable to access mapset element %s (%s): %s"),
230 p_element, path, strerror(errno));
231 }
232 }
233 if (*element == 0)
234 return 1;
235 }
236 *p++ = *element++;
237 }
238}
239
240int make_mapset_element(const char *p_path, const char *p_element)
241{
242 return make_mapset_element_impl(p_path, p_element, false);
243}
244
245int make_mapset_element_no_fail_on_race(const char *p_path,
246 const char *p_element)
247{
248 return make_mapset_element_impl(p_path, p_element, true);
249}
250
251/*!
252 \brief Create misc element in the current mapset.
253
254 \param dir directory path (e.g., `cell_misc`)
255 \param name element to be created in mapset (e.g., `elevation`)
256
257 \return 0 no element defined
258 \return 1 on success
259 */
260int G__make_mapset_element_misc(const char *dir, const char *name)
261{
262 return G_make_mapset_dir_object(dir, name);
263}
264
265static int check_owner(const struct stat *info)
266{
267#if defined(__MINGW32__) || defined(SKIP_MAPSET_OWN_CHK)
268 return 1;
269#else
270 const char *check = getenv("GRASS_SKIP_MAPSET_OWNER_CHECK");
271
272 if (check && *check)
273 return 1;
274 if (info->st_uid != getuid())
275 return 0;
276 if (info->st_uid != geteuid())
277 return 0;
278 return 1;
279#endif
280}
281
282/*!
283 \brief Check for user mapset permission
284
285 \param mapset mapset name
286
287 \return 1 mapset exists, and user has permission
288 \return 0 mapset exists, BUT user denied permission
289 \return -1 mapset does not exist
290 */
291int G_mapset_permissions(const char *mapset)
292{
293 char path[GPATH_MAX];
294 struct stat info;
295
296 G_file_name(path, "", "", mapset);
297
298 if (G_stat(path, &info) != 0)
299 return -1;
300 if (!S_ISDIR(info.st_mode))
301 return -1;
302
303 if (!check_owner(&info))
304 return 0;
305
306 return 1;
307}
308
309/*!
310 \brief Check for user mapset permission
311
312 \param gisdbase full path to GISDBASE
313 \param location location name
314 \param mapset mapset name
315
316 \return 1 mapset exists, and user has permission
317 \return 0 mapset exists, BUT user denied permission
318 \return -1 mapset does not exist
319 */
320int G_mapset_permissions2(const char *gisdbase, const char *location,
321 const char *mapset)
322{
323 char path[GPATH_MAX];
324 struct stat info;
325
326 sprintf(path, "%s/%s/%s", gisdbase, location, mapset);
327
328 if (G_stat(path, &info) != 0)
329 return -1;
330 if (!S_ISDIR(info.st_mode))
331 return -1;
332
333 if (!check_owner(&info))
334 return 0;
335
336 return 1;
337}
#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:260
int G_mapset_permissions2(const char *gisdbase, const char *location, const char *mapset)
Check for user mapset permission.
Definition mapset_msc.c:320
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:291
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