GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
remove.c
Go to the documentation of this file.
1 /*!
2  * \file lib/gis/remove.c
3  *
4  * \brief GIS Library - File remove functions.
5  *
6  * (C) 2001-2009 by 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  * \author Original author CERL
12  */
13 
14 #include <grass/config.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <dirent.h>
22 #include <grass/gis.h>
23 
24 static int G__remove(int misc, const char *dir, const char *element,
25  const char *name);
26 
27 /*!
28  * \brief Remove a database file.
29  *
30  * The file or directory <i>name</i> under the database <i>element</i>
31  * directory in the current mapset is removed.
32  *
33  * If <i>name</i> is a directory, everything within the directory is
34  * removed as well.
35  *
36  * \param element element name
37  * \param name file name
38  *
39  * \return 0 if <i>name</i> does not exist
40  * \return 1 if successful
41  * \return -1 on error
42  */
43 int G_remove(const char *element, const char *name)
44 {
45  return G__remove(0, NULL, element, name);
46 }
47 
48 /*!
49  * \brief Remove a database misc file.
50  *
51  * The file or directory <i>name</i> under the database <i>element</i>
52  * directory in the current mapset is removed.
53  *
54  * If <i>name</i> is a directory, everything within the directory is
55  * removed as well.
56  *
57  * \param element element name
58  * \param name file name
59  *
60  * \return 0 if <i>name</i> does not exist
61  * \return 1 if successful
62  * \return -1 on error
63  */
64 int G_remove_misc(const char *dir, const char *element, const char *name)
65 {
66  return G__remove(1, dir, element, name);
67 }
68 
69 static int G__remove(int misc, const char *dir, const char *element,
70  const char *name)
71 {
72  char path[GPATH_MAX];
73  const char *mapset;
74  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
75 
76  /* name in mapset legal only if mapset is current mapset */
77  mapset = G_mapset();
78  if (G_name_is_fully_qualified(name, xname, xmapset)) {
79  if (strcmp(mapset, xmapset) != 0)
80  return -1;
81  name = xname;
82  }
83 
84  if (G_legal_filename(name) < 0)
85  return -1;
86 
87  if (misc)
88  G_file_name_misc(path, dir, element, name, mapset);
89  else
90  G_file_name(path, element, name, mapset);
91 
92  /* if file does not exist, return 0 */
93  if (access(path, 0) != 0)
94  return 0;
95 
96  if (G_recursive_remove(path) == 0)
97  return 1;
98 
99  return -1;
100 }
101 
102 /*!
103  \brief Recursively remove all files in given directory
104 
105  Equivalent to rm -rf path.
106 
107  \param path path to the directory which should be removed
108 
109  \return 0 on success
110  \return -1 on error
111  */
112 int G_recursive_remove(const char *path)
113 {
114  DIR *dirp;
115  struct dirent *dp;
116  struct stat sb;
117  char path2[GPATH_MAX];
118 
119  if (G_lstat(path, &sb))
120  return -1;
121  if (!S_ISDIR(sb.st_mode))
122  return remove(path) == 0 ? 0 : -1;
123 
124  if ((dirp = opendir(path)) == NULL)
125  return -1;
126  while ((dp = readdir(dirp)) != NULL) {
127  if (dp->d_name[0] == '.')
128  continue;
129  if (strlen(path) + strlen(dp->d_name) + 2 > sizeof(path2))
130  continue;
131  snprintf(path2, sizeof(path2), "%s/%s", path, dp->d_name);
132  G_recursive_remove(path2);
133  }
134  closedir(dirp);
135 
136  return rmdir(path) == 0 ? 0 : -1;
137 }
#define NULL
Definition: ccmath.h:32
char * G_file_name_misc(char *, const char *, const char *, const char *, const char *)
Builds full path names to GIS misc data files.
Definition: file_name.c:101
int G_name_is_fully_qualified(const char *, char *, char *)
Check if map name is fully qualified (map @ mapset)
Definition: nme_in_mps.c:36
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition: file_name.c:61
int G_legal_filename(const char *)
Check for legal database file name.
Definition: legal_name.c:34
int G_lstat(const char *, struct stat *)
Get file status.
Definition: paths.c:145
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
struct DIR DIR
Definition: dirent.h:18
#define GMAPSET_MAX
Definition: gis.h:197
#define GPATH_MAX
Definition: gis.h:199
#define GNAME_MAX
Definition: gis.h:196
DIR * opendir(const char *name)
Definition: msvc/dirent.c:15
int closedir(DIR *dir)
Definition: msvc/dirent.c:54
struct dirent * readdir(DIR *dir)
Definition: msvc/dirent.c:75
const char * name
Definition: named_colr.c:6
int G_remove(const char *element, const char *name)
Remove a database file.
Definition: remove.c:43
int G_recursive_remove(const char *path)
Recursively remove all files in given directory.
Definition: remove.c:112
int G_remove_misc(const char *dir, const char *element, const char *name)
Remove a database misc file.
Definition: remove.c:64
#define S_ISDIR(mode)
Definition: stat.h:6
Definition: dirent.h:20
char * d_name
Definition: dirent.h:21
Definition: lidar.h:85
Definition: path.h:15
#define access
Definition: unistd.h:7
#define rmdir
Definition: unistd.h:15