3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #define ENSC_WRAPPERS_IO 1
33 verifySource(int fd, struct stat const *exp_stat)
37 return (fstat(fd, &st)!=-1 &&
38 st.st_dev==exp_stat->st_dev &&
39 st.st_ino==exp_stat->st_ino);
43 copyLnk(char const *src, char const *dst)
49 l = readlink(src, buf, len-1);
50 if (l==-1) return false;
57 return (symlink(buf, dst)!=-1);
62 copyReg(char const *src, struct stat const *src_stat,
65 int in_fd = open(src, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_LARGEFILE);
66 int out_fd = in_fd==-1 ? -1 : open(dst, O_CREAT|O_EXCL, 0200);
69 if (in_fd==-1 || out_fd==-1 ||
70 !verifySource(in_fd, src_stat)) goto err;
74 ssize_t l = read(in_fd, buf, sizeof buf);
77 if (!WwriteAll(out_fd, buf, l, 0)) return false;
83 if (out_fd!=-1 && close(out_fd)==-1) res=false;
84 if (in_fd!=-1 && close(in_fd)==-1) res=false;
89 copyNode(char const UNUSED *src, struct stat const *src_stat,
92 return mknod(dst, src_stat->st_mode & (S_IFMT|S_IWUSR),
93 src_stat->st_rdev)!=-1;
97 copyDir(char const UNUSED *src, struct stat const UNUSED *src_stat,
100 return mkdir(dst, 0700)!=-1;
104 setModes(char const *path, struct stat const *st)
106 return (lchown(path, st->st_uid, st->st_gid)!=-1 &&
107 (S_ISLNK(st->st_mode) || chmod(path, st->st_mode)!=-1));
112 Unify_copy(char const *src, struct stat const *src_stat,
117 if (S_ISSOCK(src_stat->st_mode))
121 (((S_ISLNK (src_stat->st_mode) && copyLnk (src, dst)) ||
122 (S_ISREG (src_stat->st_mode) && copyReg (src, src_stat, dst)) ||
123 (S_ISDIR (src_stat->st_mode) && copyDir (src, src_stat, dst)) ||
124 ((S_ISBLK (src_stat->st_mode) ||
125 S_ISCHR (src_stat->st_mode) ||
126 S_ISFIFO(src_stat->st_mode)) && copyNode(src, src_stat, dst))
128 setModes(dst, src_stat) &&
129 Unify_setTime(dst, src_stat));