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