added "created dir" message
[rsync/rsync.git] / util.c
1 /* 
2    Copyright (C) Andrew Tridgell 1996
3    Copyright (C) Paul Mackerras 1996
4    
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; either version 2 of the License, or
8    (at your option) any later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /*
21   Utilities used in rsync 
22
23   tridge, June 1996
24   */
25 #include "rsync.h"
26
27 static int total_written = 0;
28 static int total_read = 0;
29
30 extern int verbose;
31
32 int write_total(void)
33 {
34   return total_written;
35 }
36
37 int read_total(void)
38 {
39   return total_read;
40 }
41
42 void write_int(int f,int x)
43 {
44   char b[4];
45   SIVAL(b,0,x);
46   if (write(f,b,4) != 4) {
47     fprintf(stderr,"write_int failed : %s\n",strerror(errno));
48     exit(1);
49   }
50   total_written += 4;
51 }
52
53 void write_buf(int f,char *buf,int len)
54 {
55   if (write(f,buf,len) != len) {
56     fprintf(stderr,"write_buf failed : %s\n",strerror(errno));
57     exit(1);
58   }
59   total_written += len;
60 }
61
62 static int num_waiting(int fd)
63 {
64   int len=0;
65 #ifdef FIONREAD
66   ioctl(fd,FIONREAD,&len);
67 #endif
68   return(len);
69 }
70
71 static char *read_buffer = NULL;
72 static char *read_buffer_p = NULL;
73 static int read_buffer_len = 0;
74 static int read_buffer_size = 0;
75
76
77 void write_flush(int f)
78 {
79 }
80
81 void read_check(int f)
82 {
83   int n;
84
85   if (read_buffer_len == 0) {
86     read_buffer_p = read_buffer;
87   }
88
89   if ((n=num_waiting(f)) <= 0)
90     return;
91
92   if (read_buffer_p != read_buffer) {
93     memmove(read_buffer,read_buffer_p,read_buffer_len);
94     read_buffer_p = read_buffer;
95   }
96
97   if (n > (read_buffer_size - read_buffer_len)) {
98     read_buffer_size += n;
99     if (!read_buffer)
100       read_buffer = (char *)malloc(read_buffer_size);
101     else
102       read_buffer = (char *)realloc(read_buffer,read_buffer_size);
103     if (!read_buffer) out_of_memory("read check");      
104     read_buffer_p = read_buffer;      
105   }
106
107   n = read(f,read_buffer+read_buffer_len,n);
108   if (n > 0) {
109     read_buffer_len += n;
110   }
111 }
112
113
114 static int readfd(int fd,char *buffer,int N)
115 {
116   int  ret;
117   int total=0;  
118  
119   while (total < N)
120     {
121       if (read_buffer_len > 0) {
122         ret = MIN(read_buffer_len,N-total);
123         memcpy(buffer+total,read_buffer_p,ret);
124         read_buffer_p += ret;
125         read_buffer_len -= ret;
126       } else {
127         ret = read(fd,buffer + total,N - total);
128       }
129
130       if (ret <= 0)
131         return total;
132       total += ret;
133     }
134   return total;
135 }
136
137
138 int read_int(int f)
139 {
140   char b[4];
141   if (readfd(f,b,4) != 4) {
142     if (verbose > 1) 
143       fprintf(stderr,"Error reading %d bytes : %s\n",4,strerror(errno));
144     exit(1);
145   }
146   total_read += 4;
147   return IVAL(b,0);
148 }
149
150 void read_buf(int f,char *buf,int len)
151 {
152   if (readfd(f,buf,len) != len) {
153     if (verbose > 1) 
154       fprintf(stderr,"Error reading %d bytes : %s\n",len,strerror(errno));
155     exit(1);
156   }
157   total_read += len;
158 }
159
160
161 char *map_file(int fd,off_t len)
162 {
163   char *ret = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
164   return ret;
165 }
166
167 void unmap_file(char *buf,off_t len)
168 {
169   if (len > 0 && buf)
170     munmap(buf,len);
171 }
172
173
174 int read_write(int fd_in,int fd_out,int size)
175 {
176   static char *buf=NULL;
177   static int bufsize = WRITE_BLOCK_SIZE;
178   int total=0;
179   
180   if (!buf) {
181     buf = (char *)malloc(bufsize);
182     if (!buf) out_of_memory("read_write");
183   }
184
185   while (total < size) {
186     int n = MIN(size-total,bufsize);
187     read_buf(fd_in,buf,n);
188     if (write(fd_out,buf,n) != n)
189       return total;
190     total += n;
191   }
192   return total;
193 }
194
195
196 /* this is taken from CVS */
197 int piped_child(char **command,int *f_in,int *f_out)
198 {
199   int pid;
200   int to_child_pipe[2];
201   int from_child_pipe[2];
202
203   if (pipe(to_child_pipe) < 0 ||
204       pipe(from_child_pipe) < 0) {
205     fprintf(stderr,"pipe: %s\n",strerror(errno));
206     exit(1);
207   }
208
209
210   pid = fork();
211   if (pid < 0) {
212     fprintf(stderr,"fork: %s\n",strerror(errno));
213     exit(1);
214   }
215
216   if (pid == 0)
217     {
218       if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
219           close(to_child_pipe[1]) < 0 ||
220           close(from_child_pipe[0]) < 0 ||
221           dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
222         fprintf(stderr,"Failed to dup/close : %s\n",strerror(errno));
223         exit(1);
224       }
225       execvp(command[0], command);
226       fprintf(stderr,"Failed to exec %s : %s\n",
227               command[0],strerror(errno));
228       exit(1);
229     }
230
231   if (close(from_child_pipe[1]) < 0 ||
232       close(to_child_pipe[0]) < 0) {
233     fprintf(stderr,"Failed to close : %s\n",strerror(errno));   
234     exit(1);
235   }
236
237   *f_in = from_child_pipe[0];
238   *f_out = to_child_pipe[1];
239   
240   return pid;
241 }
242
243
244 void out_of_memory(char *str)
245 {
246   fprintf(stderr,"out of memory in %s\n",str);
247   exit(1);
248 }
249
250
251 #ifndef HAVE_STRDUP
252  char *strdup(char *s)
253 {
254   int l = strlen(s) + 1;
255   char *ret = (char *)malloc(l);
256   if (ret)
257     strcpy(ret,s);
258   return ret;
259 }
260 #endif
261
262
263 int set_modtime(char *fname,time_t modtime)
264 {
265 #ifdef HAVE_UTIME_H
266   struct utimbuf tbuf;  
267   tbuf.actime = time(NULL);
268   tbuf.modtime = modtime;
269   return utime(fname,&tbuf);
270 #elif defined(HAVE_UTIME)
271   time_t t[2];
272   t[0] = time(NULL);
273   t[1] = modtime;
274   return utime(fname,t);
275 #else
276   struct timeval t[2];
277   t[0].tv_sec = time(NULL);
278   t[0].tv_usec = 0;
279   t[1].tv_sec = modtime;
280   t[1].tv_usec = 0;
281   return utimes(fname,t);
282 #endif
283 }
284