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
|
/*
* copy.c - functions for copying files and directories
*
* Copyright 2007 Red Hat, Inc.
*
* This software may be freely redistributed under the terms of the GNU
* General Public License.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "lang.h"
/* Recursive */
int copyDirectory(char * from, char * to, void (*warnFn)(char *),
void (*errorFn)(char *)) {
char *msg;
DIR * dir;
struct dirent * ent;
int fd, outfd;
char buf[4096];
int i, x;
struct stat sb;
char filespec[256];
char filespec2[256];
char link[1024];
mkdir(to, 0755);
if (!(dir = opendir(from))) {
if (errorFn) {
x = asprintf(&msg, N_("Failed to read directory %s: %s"), from,
strerror(errno));
errorFn(msg);
free(msg);
}
return 1;
}
errno = 0;
while ((ent = readdir(dir))) {
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
sprintf(filespec, "%s/%s", from, ent->d_name);
sprintf(filespec2, "%s/%s", to, ent->d_name);
lstat(filespec, &sb);
if (S_ISDIR(sb.st_mode)) {
if (copyDirectory(filespec, filespec2, warnFn, errorFn)) {
closedir(dir);
return 1;
}
} else if (S_ISLNK(sb.st_mode)) {
i = readlink(filespec, link, sizeof(link) - 1);
link[i] = '\0';
if (symlink(link, filespec2)) {
if (warnFn) {
x = asprintf(&msg, "Failed to symlink %s to %s: %s",
filespec2, link, strerror(errno));
warnFn(msg);
free(msg);
}
}
} else {
fd = open(filespec, O_RDONLY);
if (fd == -1) {
if (errorFn) {
x = asprintf(&msg, "Failed to open %s: %s", filespec,
strerror(errno));
errorFn(msg);
free(msg);
}
closedir(dir);
return 1;
}
outfd = open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644);
if (outfd == -1) {
if (warnFn) {
x = asprintf(&msg, "Failed to create %s: %s", filespec2,
strerror(errno));
warnFn(msg);
free(msg);
}
} else {
fchmod(outfd, sb.st_mode & 07777);
while ((i = read(fd, buf, sizeof(buf))) > 0)
i = write(outfd, buf, i);
close(outfd);
}
close(fd);
}
errno = 0;
}
closedir(dir);
return 0;
}
|