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