File: remove.c

package info (click to toggle)
grass 6.4.4-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 104,028 kB
  • ctags: 40,409
  • sloc: ansic: 419,980; python: 63,559; tcl: 46,692; cpp: 29,791; sh: 18,564; makefile: 7,000; xml: 3,505; yacc: 561; perl: 559; lex: 480; sed: 70; objc: 7
file content (131 lines) | stat: -rw-r--r-- 3,121 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

/**
 * \file remove.c
 *
 * \brief GIS Library - File remove functions.
 *
 * (C) 2001-2008 by the GRASS Development Team
 *
 * This program is free software under the GNU General Public License
 * (>=v2). Read the file COPYING that comes with GRASS for details.
 *
 * \author GRASS GIS Development Team
 *
 * \date 1999-2008
 */

#include <grass/config.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <grass/gis.h>

static int recursive_remove(const char *path);
static int G__remove(int misc, const char *dir, const char *element,
		     const char *name);

/**
 * \brief Remove a database file.
 *
 * The file or directory <b>name</b> under the database <b>element</b> directory
 * in the current mapset is removed.<br>
 * 
 * <b>Note:</b> If <b>name</b> is a directory, everything within the
 * directory is removed as well.
 *
 * \param[in] element element name
 * \param[in] name file nane
 * \return 0 if <b>name</b> does not exist
 * \return 1 if successful
 * \return -1 on error
 */

int G_remove(const char *element, const char *name)
{
    return G__remove(0, NULL, element, name);
}

/**
 * \brief Remove a database misc file.
 *
 * The file or directory <b>name</b> under the database <b>element</b> directory
 * in the current mapset is removed.<br>
 * 
 * <b>Note:</b> If <b>name</b> is a directory, everything within the
 * directory is removed as well.
 *
 * \param[in] element element name
 * \param[in] name file name
 * \return 0 if <b>name</b> does not exist
 * \return 1 if successful
 * \return -1 on error
 */
int G_remove_misc(const char *dir, const char *element, const char *name)
{
    return G__remove(1, dir, element, name);
}

static int G__remove(int misc, const char *dir, const char *element,
		     const char *name)
{
    char path[GPATH_MAX];
    char *mapset;
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    /* name in mapset legal only if mapset is current mapset */
    mapset = G_mapset();
    if (G__name_is_fully_qualified(name, xname, xmapset)) {
	if (strcmp(mapset, xmapset) != 0)
	    return -1;
	name = xname;
    }

    if (G_legal_filename(name) < 0)
	return -1;

    if (misc)
	G__file_name_misc(path, dir, element, name, mapset);
    else
	G__file_name(path, element, name, mapset);

    /* if file does not exist, return 0 */
    if (access(path, 0) != 0)
	return 0;

    if (recursive_remove(path) == 0)
	return 1;

    return -1;
}

/* equivalent to rm -rf path */
static int recursive_remove(const char *path)
{
    DIR *dirp;
    struct dirent *dp;
    struct stat sb;
    char path2[GPATH_MAX];

    if (G_lstat(path, &sb))
	return 1;
    if (!S_ISDIR(sb.st_mode))
	return remove(path) == 0 ? 0 : 1;

    if ((dirp = opendir(path)) == NULL)
	return 1;
    while ((dp = readdir(dirp)) != NULL) {
	if (dp->d_name[0] == '.')
	    continue;
	if (strlen(path) + strlen(dp->d_name) + 2 > sizeof(path2))
	    continue;
	sprintf(path2, "%s/%s", path, dp->d_name);
	recursive_remove(path2);
    }
    closedir(dirp);

    return rmdir(path) == 0 ? 0 : 1;
}