don't need to test for SETPGRP any more as it is no longer used
[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
163 void out_of_memory(char *str)
164 {
165   fprintf(FERROR,"out of memory in %s\n",str);
166   exit_cleanup(1);
167 }
168
169
170
171 int set_modtime(char *fname,time_t modtime)
172 {
173         extern int dry_run;
174         if (dry_run) return 0;
175         {
176 #ifdef HAVE_UTIMBUF
177                 struct utimbuf tbuf;  
178                 tbuf.actime = time(NULL);
179                 tbuf.modtime = modtime;
180                 return utime(fname,&tbuf);
181 #elif defined(HAVE_UTIME)
182                 time_t t[2];
183                 t[0] = time(NULL);
184                 t[1] = modtime;
185                 return utime(fname,t);
186 #else
187                 struct timeval t[2];
188                 t[0].tv_sec = time(NULL);
189                 t[0].tv_usec = 0;
190                 t[1].tv_sec = modtime;
191                 t[1].tv_usec = 0;
192                 return utimes(fname,t);
193 #endif
194         }
195 }
196
197
198
199 /****************************************************************************
200 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
201 else
202 if SYSV use O_NDELAY
203 if BSD use FNDELAY
204 ****************************************************************************/
205 int set_blocking(int fd, int set)
206 {
207   int val;
208 #ifdef O_NONBLOCK
209 #define FLAG_TO_SET O_NONBLOCK
210 #else
211 #ifdef SYSV
212 #define FLAG_TO_SET O_NDELAY
213 #else /* BSD */
214 #define FLAG_TO_SET FNDELAY
215 #endif
216 #endif
217
218   if((val = fcntl(fd, F_GETFL, 0)) == -1)
219         return -1;
220   if(set) /* Turn blocking on - ie. clear nonblock flag */
221         val &= ~FLAG_TO_SET;
222   else
223     val |= FLAG_TO_SET;
224   return fcntl( fd, F_SETFL, val);
225 #undef FLAG_TO_SET
226 }
227
228 /****************************************************************************
229 create any necessary directories in fname. Unfortunately we don't know
230 what perms to give the directory when this is called so we need to rely
231 on the umask
232 ****************************************************************************/
233 int create_directory_path(char *fname)
234 {
235         extern int orig_umask;
236         char *p;
237
238         while (*fname == '/') fname++;
239         while (strncmp(fname,"./",2)==0) fname += 2;
240
241         p = fname;
242         while ((p=strchr(p,'/'))) {
243                 *p = 0;
244                 mkdir(fname,0777 & ~orig_umask); 
245                 *p = '/';
246                 p++;
247         }
248         return 0;
249 }
250
251
252 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
253    Return LEN upon success, write's (negative) error code otherwise.  
254
255    derived from GNU C's cccp.c.
256 */
257 int full_write(int desc, char *ptr, int len)
258 {
259         int total_written;
260         
261         total_written = 0;
262         while (len > 0) {
263                 int written = write (desc, ptr, len);
264                 if (written < 0)  {
265 #ifdef EINTR
266                         if (errno == EINTR)
267                                 continue;
268 #endif
269                         return written;
270                 }
271                 total_written += written;
272                 ptr += written;
273                 len -= written;
274         }
275         return total_written;
276 }
277
278 /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
279    Return the actual number of bytes read, zero for EOF, or negative
280    for an error.  
281
282    derived from GNU C's cccp.c. */
283 int safe_read(int desc, char *ptr, int len)
284 {
285         int n_chars;
286  
287         if (len <= 0)
288                 return len;
289  
290 #ifdef EINTR
291         do {
292                 n_chars = read(desc, ptr, len);
293         } while (n_chars < 0 && errno == EINTR);
294 #else
295         n_chars = read(desc, ptr, len);
296 #endif
297  
298         return n_chars;
299 }
300
301
302 /* copy a file - this is used in conjunction with the --temp-dir option */
303 int copy_file(char *source, char *dest, mode_t mode)
304 {
305         int ifd;
306         int ofd;
307         char buf[1024 * 8];
308         int len;   /* Number of bytes read into `buf'. */
309
310         ifd = open(source, O_RDONLY);
311         if (ifd == -1) {
312                 fprintf(FERROR,"open %s: %s\n",
313                         source,strerror(errno));
314                 return -1;
315         }
316
317         if (do_unlink(dest) && errno != ENOENT) {
318                 fprintf(FERROR,"unlink %s: %s\n",
319                         dest,strerror(errno));
320                 return -1;
321         }
322
323         ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
324         if (ofd < 0) {
325                 fprintf(FERROR,"open %s: %s\n",
326                         dest,strerror(errno));
327                 close(ifd);
328                 return -1;
329         }
330
331         while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
332                 if (full_write(ofd, buf, len) < 0) {
333                         fprintf(FERROR,"write %s: %s\n",
334                                 dest,strerror(errno));
335                         close(ifd);
336                         close(ofd);
337                         return -1;
338                 }
339         }
340
341         close(ifd);
342         close(ofd);
343
344         if (len < 0) {
345                 fprintf(FERROR,"read %s: %s\n",
346                         source,strerror(errno));
347                 return -1;
348         }
349
350         return 0;
351 }
352
353 /* sleep for a while via select */
354 void u_sleep(int usec)
355 {
356         struct timeval tv;
357
358         tv.tv_sec = 0;
359         tv.tv_usec = usec;
360         select(0, NULL, NULL, NULL, &tv);
361 }
362
363
364 static pid_t all_pids[10];
365 static int num_pids;
366
367 /* fork and record the pid of the child */
368 pid_t do_fork(void)
369 {
370         pid_t newpid = fork();
371         
372         if (newpid) {
373                 all_pids[num_pids++] = newpid;
374         }
375         return newpid;
376 }
377
378 /* kill all children */
379 void kill_all(int sig)
380 {
381         int i;
382         for (i=0;i<num_pids;i++) {
383                 if (all_pids[i] != getpid())
384                         kill(all_pids[i], sig);
385         }
386 }