in local->local mode don't use exec to start the "remote" 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 int num_waiting(int fd)
28 {
29   int len=0;
30   ioctl(fd,FIONREAD,&len);
31   return(len);
32 }
33
34
35 struct map_struct *map_file(int fd,off_t len)
36 {
37   struct map_struct *ret;
38   ret = (struct map_struct *)malloc(sizeof(*ret));
39   if (!ret) out_of_memory("map_file");
40
41   ret->map = NULL;
42   ret->fd = fd;
43   ret->size = len;
44   ret->p = NULL;
45   ret->p_size = 0;
46   ret->p_offset = 0;
47   ret->p_len = 0;
48
49 #ifdef HAVE_MMAP
50   if (len < MAX_MAP_SIZE)
51     ret->map = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
52 #endif
53   return ret;
54 }
55
56
57 char *map_ptr(struct map_struct *map,off_t offset,int len)
58 {
59   int nread = -2;
60
61   if (map->map)
62     return map->map+offset;
63
64   if (len == 0) 
65     return NULL;
66
67   if (len > (map->size-offset))
68       len = map->size-offset;
69
70   if (offset >= map->p_offset && 
71       offset+len <= map->p_offset+map->p_len) {
72     return (map->p + (offset - map->p_offset));
73   }
74
75   len = MAX(len,CHUNK_SIZE);
76   if (len > (map->size-offset))
77       len = map->size-offset;
78
79   if (len > map->p_size) {
80     if (map->p) free(map->p);
81     map->p = (char *)malloc(len);
82     if (!map->p) out_of_memory("map_ptr");
83     map->p_size = len;
84   }
85
86   if (lseek(map->fd,offset,SEEK_SET) != offset ||
87       (nread=read(map->fd,map->p,len)) != len) {
88           fprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n",
89                   (int)offset, len, nread, errno);
90           exit_cleanup(1);
91   }
92
93   map->p_offset = offset;
94   map->p_len = len;
95
96   return map->p; 
97 }
98
99
100 void unmap_file(struct map_struct *map)
101 {
102 #ifdef HAVE_MMAP
103   if (map->map)
104     munmap(map->map,map->size);
105 #endif
106   if (map->p) free(map->p);
107   free(map);
108 }
109
110
111 /* this is taken from CVS */
112 int piped_child(char **command,int *f_in,int *f_out)
113 {
114   int pid;
115   int to_child_pipe[2];
116   int from_child_pipe[2];
117
118   if (pipe(to_child_pipe) < 0 ||
119       pipe(from_child_pipe) < 0) {
120     fprintf(FERROR,"pipe: %s\n",strerror(errno));
121     exit_cleanup(1);
122   }
123
124
125   pid = do_fork();
126   if (pid < 0) {
127     fprintf(FERROR,"fork: %s\n",strerror(errno));
128     exit_cleanup(1);
129   }
130
131   if (pid == 0)
132     {
133       extern int orig_umask;
134       if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
135           close(to_child_pipe[1]) < 0 ||
136           close(from_child_pipe[0]) < 0 ||
137           dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
138         fprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
139         exit_cleanup(1);
140       }
141       if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
142       if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
143       umask(orig_umask);
144       execvp(command[0], command);
145       fprintf(FERROR,"Failed to exec %s : %s\n",
146               command[0],strerror(errno));
147       exit_cleanup(1);
148     }
149
150   if (close(from_child_pipe[1]) < 0 ||
151       close(to_child_pipe[0]) < 0) {
152     fprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
153     exit_cleanup(1);
154   }
155
156   *f_in = from_child_pipe[0];
157   *f_out = to_child_pipe[1];
158   
159   return pid;
160 }
161
162 int local_child(int argc, char **argv,int *f_in,int *f_out)
163 {
164         int pid;
165         int to_child_pipe[2];
166         int from_child_pipe[2];
167
168         if (pipe(to_child_pipe) < 0 ||
169             pipe(from_child_pipe) < 0) {
170                 fprintf(FERROR,"pipe: %s\n",strerror(errno));
171                 exit_cleanup(1);
172         }
173
174
175         pid = do_fork();
176         if (pid < 0) {
177                 fprintf(FERROR,"fork: %s\n",strerror(errno));
178                 exit_cleanup(1);
179         }
180
181         if (pid == 0) {
182                 extern int am_sender;
183                 extern int am_server;
184
185                 am_sender = !am_sender;
186                 am_server = 1;          
187
188                 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
189                     close(to_child_pipe[1]) < 0 ||
190                     close(from_child_pipe[0]) < 0 ||
191                     dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
192                         fprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
193                         exit_cleanup(1);
194                 }
195                 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
196                 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
197                 start_server(argc, argv);
198         }
199
200         if (close(from_child_pipe[1]) < 0 ||
201             close(to_child_pipe[0]) < 0) {
202                 fprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
203                 exit_cleanup(1);
204         }
205
206         *f_in = from_child_pipe[0];
207         *f_out = to_child_pipe[1];
208   
209         return pid;
210 }
211
212
213
214 void out_of_memory(char *str)
215 {
216   fprintf(FERROR,"ERROR: out of memory in %s\n",str);
217   exit_cleanup(1);
218 }
219
220 void overflow(char *str)
221 {
222   fprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
223   exit_cleanup(1);
224 }
225
226
227
228 int set_modtime(char *fname,time_t modtime)
229 {
230         extern int dry_run;
231         if (dry_run) return 0;
232         {
233 #ifdef HAVE_UTIMBUF
234                 struct utimbuf tbuf;  
235                 tbuf.actime = time(NULL);
236                 tbuf.modtime = modtime;
237                 return utime(fname,&tbuf);
238 #elif defined(HAVE_UTIME)
239                 time_t t[2];
240                 t[0] = time(NULL);
241                 t[1] = modtime;
242                 return utime(fname,t);
243 #else
244                 struct timeval t[2];
245                 t[0].tv_sec = time(NULL);
246                 t[0].tv_usec = 0;
247                 t[1].tv_sec = modtime;
248                 t[1].tv_usec = 0;
249                 return utimes(fname,t);
250 #endif
251         }
252 }
253
254
255
256 /****************************************************************************
257 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
258 else
259 if SYSV use O_NDELAY
260 if BSD use FNDELAY
261 ****************************************************************************/
262 int set_blocking(int fd, int set)
263 {
264   int val;
265 #ifdef O_NONBLOCK
266 #define FLAG_TO_SET O_NONBLOCK
267 #else
268 #ifdef SYSV
269 #define FLAG_TO_SET O_NDELAY
270 #else /* BSD */
271 #define FLAG_TO_SET FNDELAY
272 #endif
273 #endif
274
275   if((val = fcntl(fd, F_GETFL, 0)) == -1)
276         return -1;
277   if(set) /* Turn blocking on - ie. clear nonblock flag */
278         val &= ~FLAG_TO_SET;
279   else
280     val |= FLAG_TO_SET;
281   return fcntl( fd, F_SETFL, val);
282 #undef FLAG_TO_SET
283 }
284
285 /****************************************************************************
286 create any necessary directories in fname. Unfortunately we don't know
287 what perms to give the directory when this is called so we need to rely
288 on the umask
289 ****************************************************************************/
290 int create_directory_path(char *fname)
291 {
292         extern int orig_umask;
293         char *p;
294
295         while (*fname == '/') fname++;
296         while (strncmp(fname,"./",2)==0) fname += 2;
297
298         p = fname;
299         while ((p=strchr(p,'/'))) {
300                 *p = 0;
301                 mkdir(fname,0777 & ~orig_umask); 
302                 *p = '/';
303                 p++;
304         }
305         return 0;
306 }
307
308
309 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
310    Return LEN upon success, write's (negative) error code otherwise.  
311
312    derived from GNU C's cccp.c.
313 */
314 int full_write(int desc, char *ptr, int len)
315 {
316         int total_written;
317         
318         total_written = 0;
319         while (len > 0) {
320                 int written = write (desc, ptr, len);
321                 if (written < 0)  {
322 #ifdef EINTR
323                         if (errno == EINTR)
324                                 continue;
325 #endif
326                         return written;
327                 }
328                 total_written += written;
329                 ptr += written;
330                 len -= written;
331         }
332         return total_written;
333 }
334
335 /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
336    Return the actual number of bytes read, zero for EOF, or negative
337    for an error.  
338
339    derived from GNU C's cccp.c. */
340 int safe_read(int desc, char *ptr, int len)
341 {
342         int n_chars;
343  
344         if (len <= 0)
345                 return len;
346  
347 #ifdef EINTR
348         do {
349                 n_chars = read(desc, ptr, len);
350         } while (n_chars < 0 && errno == EINTR);
351 #else
352         n_chars = read(desc, ptr, len);
353 #endif
354  
355         return n_chars;
356 }
357
358
359 /* copy a file - this is used in conjunction with the --temp-dir option */
360 int copy_file(char *source, char *dest, mode_t mode)
361 {
362         int ifd;
363         int ofd;
364         char buf[1024 * 8];
365         int len;   /* Number of bytes read into `buf'. */
366
367         ifd = open(source, O_RDONLY);
368         if (ifd == -1) {
369                 fprintf(FERROR,"open %s: %s\n",
370                         source,strerror(errno));
371                 return -1;
372         }
373
374         if (do_unlink(dest) && errno != ENOENT) {
375                 fprintf(FERROR,"unlink %s: %s\n",
376                         dest,strerror(errno));
377                 return -1;
378         }
379
380         ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
381         if (ofd < 0) {
382                 fprintf(FERROR,"open %s: %s\n",
383                         dest,strerror(errno));
384                 close(ifd);
385                 return -1;
386         }
387
388         while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
389                 if (full_write(ofd, buf, len) < 0) {
390                         fprintf(FERROR,"write %s: %s\n",
391                                 dest,strerror(errno));
392                         close(ifd);
393                         close(ofd);
394                         return -1;
395                 }
396         }
397
398         close(ifd);
399         close(ofd);
400
401         if (len < 0) {
402                 fprintf(FERROR,"read %s: %s\n",
403                         source,strerror(errno));
404                 return -1;
405         }
406
407         return 0;
408 }
409
410 /* sleep for a while via select */
411 void u_sleep(int usec)
412 {
413         struct timeval tv;
414
415         tv.tv_sec = 0;
416         tv.tv_usec = usec;
417         select(0, NULL, NULL, NULL, &tv);
418 }
419
420
421 static pid_t all_pids[10];
422 static int num_pids;
423
424 /* fork and record the pid of the child */
425 pid_t do_fork(void)
426 {
427         pid_t newpid = fork();
428         
429         if (newpid) {
430                 all_pids[num_pids++] = newpid;
431         }
432         return newpid;
433 }
434
435 /* kill all children */
436 void kill_all(int sig)
437 {
438         int i;
439         for (i=0;i<num_pids;i++) {
440                 if (all_pids[i] != getpid())
441                         kill(all_pids[i], sig);
442         }
443 }