Introduction
Introduction Statistics Contact Development Disclaimer Help
cp.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
cp.c (3791B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <dirent.h>
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <limits.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12 #include <utime.h>
13
14 #include "../fs.h"
15 #include "../util.h"
16
17 int cp_aflag = 0;
18 int cp_fflag = 0;
19 int cp_iflag = 0;
20 int cp_pflag = 0;
21 int cp_rflag = 0;
22 int cp_vflag = 0;
23 int cp_status = 0;
24 int cp_follow;
25
26 int
27 cp(const char *s1, const char *s2, int depth)
28 {
29 DIR *dp;
30 int f1, f2, flags = 0;
31 struct dirent *d;
32 struct stat st;
33 struct timespec times[2];
34 ssize_t r;
35 char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX];
36
37 if (cp_follow == 'P' || (cp_follow == 'H' && depth))
38 flags |= AT_SYMLINK_NOFOLLOW;
39
40 if (fstatat(AT_FDCWD, s1, &st, flags) < 0) {
41 weprintf("stat %s:", s1);
42 cp_status = 1;
43 return 0;
44 }
45
46 if (cp_iflag && access(s2, F_OK) == 0) {
47 if (!confirm("overwrite '%s'? ", s2))
48 return 0;
49 }
50
51 if (cp_vflag)
52 printf("%s -> %s\n", s1, s2);
53
54 if (S_ISLNK(st.st_mode)) {
55 if ((r = readlink(s1, target, sizeof(target) - 1)) >= 0)…
56 target[r] = '\0';
57 if (cp_fflag && unlink(s2) < 0 && errno != ENOEN…
58 weprintf("unlink %s:", s2);
59 cp_status = 1;
60 return 0;
61 } else if (symlink(target, s2) < 0) {
62 weprintf("symlink %s -> %s:", s2, target…
63 cp_status = 1;
64 return 0;
65 }
66 }
67 } else if (S_ISDIR(st.st_mode)) {
68 if (!cp_rflag) {
69 weprintf("%s is a directory\n", s1);
70 cp_status = 1;
71 return 0;
72 }
73 if (!(dp = opendir(s1))) {
74 weprintf("opendir %s:", s1);
75 cp_status = 1;
76 return 0;
77 }
78 if (mkdir(s2, st.st_mode) < 0 && errno != EEXIST) {
79 weprintf("mkdir %s:", s2);
80 cp_status = 1;
81 closedir(dp);
82 return 0;
83 }
84
85 while ((d = readdir(dp))) {
86 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name…
87 continue;
88
89 estrlcpy(ns1, s1, sizeof(ns1));
90 if (s1[strlen(s1) - 1] != '/')
91 estrlcat(ns1, "/", sizeof(ns1));
92 estrlcat(ns1, d->d_name, sizeof(ns1));
93
94 estrlcpy(ns2, s2, sizeof(ns2));
95 if (s2[strlen(s2) - 1] != '/')
96 estrlcat(ns2, "/", sizeof(ns2));
97 estrlcat(ns2, d->d_name, sizeof(ns2));
98
99 fnck(ns1, ns2, cp, depth + 1);
100 }
101
102 closedir(dp);
103 } else if (cp_aflag && (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mod…
104 S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode))) {
105 if (cp_fflag && unlink(s2) < 0 && errno != ENOENT) {
106 weprintf("unlink %s:", s2);
107 cp_status = 1;
108 return 0;
109 } else if (mknod(s2, st.st_mode, st.st_rdev) < 0) {
110 weprintf("mknod %s:", s2);
111 cp_status = 1;
112 return 0;
113 }
114 } else {
115 if ((f1 = open(s1, O_RDONLY)) < 0) {
116 weprintf("open %s:", s1);
117 cp_status = 1;
118 return 0;
119 }
120 if ((f2 = creat(s2, st.st_mode)) < 0 && cp_fflag) {
121 if (unlink(s2) < 0 && errno != ENOENT) {
122 weprintf("unlink %s:", s2);
123 cp_status = 1;
124 close(f1);
125 return 0;
126 }
127 f2 = creat(s2, st.st_mode);
128 }
129 if (f2 < 0) {
130 weprintf("creat %s:", s2);
131 cp_status = 1;
132 close(f1);
133 return 0;
134 }
135 if (concat(f1, s1, f2, s2) < 0) {
136 cp_status = 1;
137 close(f1);
138 close(f2);
139 return 0;
140 }
141
142 close(f1);
143 close(f2);
144 }
145
146 if (cp_aflag || cp_pflag) {
147 /* atime and mtime */
148 times[0] = st.st_atim;
149 times[1] = st.st_mtim;
150 if (utimensat(AT_FDCWD, s2, times, AT_SYMLINK_NOFOLLOW) …
151 weprintf("utimensat %s:", s2);
152 cp_status = 1;
153 }
154
155 /* owner and mode */
156 if (!S_ISLNK(st.st_mode)) {
157 if (chown(s2, st.st_uid, st.st_gid) < 0) {
158 weprintf("chown %s:", s2);
159 cp_status = 1;
160 st.st_mode &= ~(S_ISUID | S_ISGID);
161 }
162 if (chmod(s2, st.st_mode) < 0) {
163 weprintf("chmod %s:", s2);
164 cp_status = 1;
165 }
166 } else {
167 if (lchown(s2, st.st_uid, st.st_gid) < 0) {
168 weprintf("lchown %s:", s2);
169 cp_status = 1;
170 return 0;
171 }
172 }
173 }
174
175 return 0;
176 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.