GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
copy_dir.c
Go to the documentation of this file.
1
/*!
2
* \file lib/gis/copy_dir.c
3
*
4
* \brief GIS Library - function to recursively copy a directory
5
*
6
* Extracted from general/manage/lib/do_copy.c
7
*
8
* (C) 2008-2015 by the GRASS Development Team
9
*
10
* This program is free software under the GNU General Public License
11
* (>=v2). Read the file COPYING that comes with GRASS for details.
12
*
13
* \author Huidae Cho
14
*/
15
16
#include <stdio.h>
17
#include <errno.h>
18
#include <string.h>
19
20
#include <grass/gis.h>
21
22
#include <fcntl.h>
23
#include <unistd.h>
24
#include <dirent.h>
25
#include <sys/types.h>
26
#include <sys/stat.h>
27
28
/*!
29
* \brief Copy recursively source directory to destination directory
30
*
31
* RULE:
32
* 1. If destination does not exist, copy source to destination as expected.
33
* 2. If destination already exists and it's a file, destination will be
34
* deleted first and apply RULE 1.
35
* 3. If destination already exists which is a directory and source is a file,
36
* try to copy source to destination directory.
37
* 4. If destination already exists which is a directory and source is also a
38
* directory, try to copy all contents in source to destination directory.
39
*
40
* This rule is designed according to general/manage/lib/copy.sh.
41
*
42
* POSSIBLE CASES:
43
* \verbatim
44
* if src is a file:
45
* if dst does not exist:
46
* copy src to dst RULE 1
47
* if dst is a file:
48
* delete dst and copy src to dst RULE 2
49
* if dst is a directory:
50
* try recursive_copy(src, dst/src) RULE 3
51
* if src is a directory:
52
* if dst does not exist:
53
* copy src to dst RULE 1
54
* if dst is a file:
55
* delete dst and copy src to dst RULE 2
56
* if dst is a directory:
57
* try RULE 4
58
* for i in `ls src`
59
* do
60
* recursive_copy(src/$i, dst/$i)
61
* done
62
* \endverbatim
63
*
64
* \param src source directory
65
* \param dst destination directory
66
*
67
* \return 0 if successful, otherwise 1
68
*/
69
int
G_recursive_copy
(
const
char
*src,
const
char
*dst)
70
{
71
DIR *dirp;
72
struct
stat sb;
73
74
if
(
G_lstat
(src, &sb) < 0)
75
return
1;
76
77
/* src is a file */
78
if
(!S_ISDIR(sb.st_mode)) {
79
char
buf[4096];
80
int
fd, fd2;
81
ssize_t len, len2;
82
83
if
(
G_lstat
(dst, &sb) == 0 && S_ISDIR(sb.st_mode)) {
84
char
path
[GPATH_MAX];
85
const
char
*p = strrchr(src,
'/'
);
86
87
/* src => dst/src */
88
snprintf(
path
,
sizeof
(
path
),
"%s/%s"
, dst, (p ? p + 1 : src));
89
return
G_recursive_copy
(src,
path
);
90
}
91
92
/* src => dst */
93
if
((fd = open(src, O_RDONLY)) < 0)
94
return
1;
95
96
if
((fd2 = open(dst, O_CREAT | O_TRUNC | O_WRONLY, sb.st_mode & 0777)) <
97
0) {
98
close(fd);
99
return
1;
100
}
101
102
while
((len = read(fd, buf,
sizeof
(buf))) > 0) {
103
while
((len > 0) && (len2 = write(fd2, buf, (
size_t
)len)) >= 0)
104
len -= len2;
105
}
106
107
close(fd);
108
close(fd2);
109
110
return
0;
111
}
112
113
/* src is a directory */
114
if
(
G_lstat
(dst, &sb) < 0) {
115
if
(
G_mkdir
(dst))
116
return
1;
117
}
118
else
119
/* if dst already exists and it's a file, try to remove it */
120
if
(!S_ISDIR(sb.st_mode)) {
121
if
(remove(dst) < 0 ||
G_mkdir
(dst) < 0)
122
return
1;
123
}
124
125
dirp = opendir(src);
126
if
(!dirp)
127
return
1;
128
129
for
(;;) {
130
char
path
[GPATH_MAX], path2[GPATH_MAX];
131
struct
dirent *dp = readdir(dirp);
132
133
if
(!dp)
134
break
;
135
136
/* do not copy hidden files */
137
if
(dp->d_name[0] ==
'.'
)
138
continue
;
139
140
snprintf(
path
,
sizeof
(
path
),
"%s/%s"
, src, dp->d_name);
141
snprintf(path2,
sizeof
(path2),
"%s/%s"
, dst, dp->d_name);
142
143
if
(
G_recursive_copy
(
path
, path2) != 0) {
144
closedir(dirp);
145
return
1;
146
}
147
}
148
149
closedir(dirp);
150
151
return
0;
152
}
G_recursive_copy
int G_recursive_copy(const char *src, const char *dst)
Copy recursively source directory to destination directory.
Definition
copy_dir.c:69
G_mkdir
int G_mkdir(const char *path)
Creates a new directory.
Definition
paths.c:27
G_lstat
int G_lstat(const char *file_name, struct stat *buf)
Get file status.
Definition
paths.c:145
path
Definition
path.h:15
gis
copy_dir.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0