1 /*
2 * Copyright (c) 2003,2004 Daniel Bryan
3 * All rights reserved.
4 *
5 * For more information see COPYRIGHT.
6 */
7
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <sys/uio.h>
11 #include <sys/types.h>
12 #include <sys/time.h>
13 #include <time.h>
14 #include <errno.h>
15 #include <string.h>
16
17 #include "common.h"
18 #include "screen.h"
19 #include "misc.h"
20 #include "copy.h"
21 #include "path.h"
22
copylink(char * src,char * dest)23 int copylink(char *src, char *dest) {
24
25 char buf[MAXPATHLEN];
26 int exists = 0;
27 int i;
28 struct stat st2;
29
30 if(stat(dest,&st2) != -1)
31 exists=1;
32
33 i = readlink(src,buf,sizeof(buf)-1);
34 if(i < 0) {
35 logadds(LOG_ERR,"%s: Bad link",src,NULL);
36 return 1;
37 }
38 buf[i] = '\0';
39
40 if(use_curses) {
41 scrn_upd_file(src,dest);
42 } else if(vflag) {
43 fprintf(stderr,"\r%lu/%lu - %s -> %s\n",curfile,totalfiles,src,dest);
44 }
45
46 if(exists) {
47 if(unlink(dest) == -1){
48 logadds(LOG_ERR,"%s: Can not overwrite link",dest,NULL);
49 return 1;
50 }
51 }
52 if(symlink(buf,dest) == -1){
53 logadds(LOG_ERR,"%s: Can not create link",dest,NULL);
54 return 1;
55 }
56
57 if(use_curses)
58 logadds(LOG_VRB,"%s: Created",dest,NULL);
59 goodcp++;
60
61 return 0;
62 }
63
copyfifo(char * destfile,struct stat * st)64 int copyfifo(char *destfile, struct stat *st) {
65 struct stat tmp;
66
67 if(use_curses) {
68 scrn_upd_file(destfile,NULL);
69 } else if(vflag) {
70 fprintf(stderr,"\r%lu/%lu - %s\n",curfile,totalfiles,destfile);
71 }
72 if(stat(destfile,&tmp) != -1) {
73 if(unlink(destfile))
74 return 1;
75 }
76 if(mkfifo(destfile,st->st_mode) == -1) {
77 logadds(LOG_ERR,"%s: Can not create fifo file",destfile,NULL);
78 return 1;
79 }
80 setperm(destfile,st);
81 if(use_curses)
82 logadds(LOG_VRB,"%s: Created",destfile,NULL);
83 goodcp++;
84 return 0;
85 }
86
copyspecial(char * destfile,struct stat * st)87 int copyspecial(char *destfile, struct stat *st) {
88 struct stat tmp;
89
90 if(use_curses) {
91 scrn_upd_file(destfile,NULL);
92 } else if(vflag) {
93 fprintf(stderr,"\r%lu/%lu - %s\n",curfile,totalfiles,destfile);
94 }
95 if(stat(destfile,&tmp) != -1) {
96 if(unlink(destfile))
97 return 1;
98 }
99 if(mknod(destfile,st->st_mode,st->st_rdev)) {
100 logadds(LOG_ERR,"%s: Can not create file",destfile,NULL);
101 return 1;
102 }
103 setperm(destfile,st);
104 if(use_curses)
105 logadds(LOG_VRB,"%s: Created",destfile,NULL);
106 goodcp++;
107 return 0;
108 }
109
110 #define MAX_BUF 204800 /* default buffer size */
111
copyfile(char * srcfile,char * destfile,struct stat * st)112 int copyfile(char *srcfile, char *destfile, struct stat *st) {
113
114 int f, f2;
115 struct stat st2;
116 int rcnt = 0;
117 int rest = 0;
118 int wcnt = 0;
119 char *p = NULL;
120 unsigned long sizecpd, size;
121 struct timeval timea;
122
123 /* 0.1 seconds
124 ts.tv_nsec = 100000000;
125 ts.tv_sec = 0;*/
126 timea.tv_sec = 0;
127 timea.tv_usec = 100;
128
129 if(use_curses) {
130 scrn_upd_file(srcfile,destfile);
131 } else if(vflag) {
132 fprintf(stderr,"\r%lu/%lu - %s\n",curfile,totalfiles,srcfile);
133 }
134 if((f = open(srcfile, O_RDONLY)) == -1) {
135 print_error(srcfile,errno);
136 return 1;
137 }
138 if(stat(destfile,&st2) != -1) {
139 if(iflag || Iflag) {
140 if(logget(destfile))
141 return 1;
142 }
143 if(nflag) {
144 logadds(LOG_VRB,"%s: file has not been overwritten",destfile,NULL);
145 return 0;
146 }
147 if(fflag) {
148 unlink(destfile);
149 f2 = open(destfile, O_WRONLY | O_CREAT | O_TRUNC,\
150 st->st_mode & ~(S_ISUID | S_ISGID));
151 } else
152 f2 = open(destfile, O_WRONLY | O_TRUNC,0);
153 } else {
154 f2 = open(destfile, O_WRONLY | O_CREAT | O_TRUNC,\
155 st->st_mode & ~(S_ISUID | S_ISGID));
156 }
157 if(f2 == -1) {
158 print_error(destfile,errno);
159 return 1;
160 }
161 size = st->st_size;
162 sizecpd = 0;
163
164 if(size < 1) {
165 logadds(LOG_VRB,"%s: file size is 0",srcfile,NULL);
166 } else {
167 if(buf_size < 1)
168 buf_size = MAX_BUF;
169 if(databuf == NULL) {
170 if((databuf = (char *)malloc(buf_size)) == NULL) {
171 exit_pre();
172 fprintf(stderr,"Can not allocate %d bytes of memory\n",buf_size);
173 exit(1);
174 }
175 }
176 while ((rcnt = read(f,databuf,buf_size)) > 0) {
177 rest = rcnt;
178 p = databuf;
179 wcnt = 0;
180 for(;;) {
181 p += wcnt;
182 rest -= wcnt;
183 wcnt = write(f2,p,rest);
184 if(rest <= wcnt || wcnt <= 0)
185 break;
186
187 }
188 if(rest != wcnt) {
189 logadds(LOG_ERR,"%s: Error writing file",destfile,NULL);
190 return 1;
191 }
192
193 sizecpd += rcnt;
194 if(use_curses)
195 scrn_upd_part(sizecpd,size);
196 else
197 scrn_updtxt(sizecpd,size,0);
198 if(dflag)
199 select(0,NULL,NULL,NULL,&timea);
200 }
201 if(use_curses) {
202 scrn_upd_part(sizecpd,size);
203 } else {
204 scrn_updtxt(sizecpd,size,1);
205 }
206 }
207
208 close(f);
209 close(f2);
210
211 if(rcnt < 0) {
212 logadds(LOG_ERR,"%s: Error reading file",srcfile,NULL);
213 return 1;
214 }
215 setperm(destfile,st);
216
217 goodcp++;
218 if(use_curses)
219 logadds(LOG_VRB,"%s: File copied",pathname(srcfile),NULL);
220 return 0;
221 }
222