preparing for release of 1.7.3
[rsync.git] / util.c
blobf61e91dad8571703d78864756431a83f1aa0bee6
1 /*
2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
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.
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.
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.
21 Utilities used in rsync
23 tridge, June 1996
25 #include "rsync.h"
27 int num_waiting(int fd)
29 int len=0;
30 ioctl(fd,FIONREAD,&len);
31 return(len);
35 struct map_struct *map_file(int fd,off_t len)
37 struct map_struct *ret;
38 ret = (struct map_struct *)malloc(sizeof(*ret));
39 if (!ret) out_of_memory("map_file");
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;
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;
57 char *map_ptr(struct map_struct *map,off_t offset,int len)
59 int nread = -2;
61 if (map->map)
62 return map->map+offset;
64 if (len == 0)
65 return NULL;
67 if (len > (map->size-offset))
68 len = map->size-offset;
70 if (offset >= map->p_offset &&
71 offset+len <= map->p_offset+map->p_len) {
72 return (map->p + (offset - map->p_offset));
75 len = MAX(len,CHUNK_SIZE);
76 if (len > (map->size-offset))
77 len = map->size-offset;
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;
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);
93 map->p_offset = offset;
94 map->p_len = len;
96 return map->p;
100 void unmap_file(struct map_struct *map)
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);
111 /* this is taken from CVS */
112 int piped_child(char **command,int *f_in,int *f_out)
114 int pid;
115 int to_child_pipe[2];
116 int from_child_pipe[2];
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);
125 pid = do_fork();
126 if (pid < 0) {
127 fprintf(FERROR,"fork: %s\n",strerror(errno));
128 exit_cleanup(1);
131 if (pid == 0)
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);
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);
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);
156 *f_in = from_child_pipe[0];
157 *f_out = to_child_pipe[1];
159 return pid;
162 int local_child(int argc, char **argv,int *f_in,int *f_out)
164 int pid;
165 int to_child_pipe[2];
166 int from_child_pipe[2];
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);
175 pid = do_fork();
176 if (pid < 0) {
177 fprintf(FERROR,"fork: %s\n",strerror(errno));
178 exit_cleanup(1);
181 if (pid == 0) {
182 extern int am_sender;
183 extern int am_server;
185 am_sender = !am_sender;
186 am_server = 1;
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);
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);
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);
206 *f_in = from_child_pipe[0];
207 *f_out = to_child_pipe[1];
209 return pid;
214 void out_of_memory(char *str)
216 fprintf(FERROR,"ERROR: out of memory in %s\n",str);
217 exit_cleanup(1);
220 void overflow(char *str)
222 fprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
223 exit_cleanup(1);
228 int set_modtime(char *fname,time_t modtime)
230 extern int dry_run;
231 if (dry_run) return 0;
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
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)
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
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
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)
292 extern int orig_umask;
293 char *p;
295 while (*fname == '/') fname++;
296 while (strncmp(fname,"./",2)==0) fname += 2;
298 p = fname;
299 while ((p=strchr(p,'/'))) {
300 *p = 0;
301 do_mkdir(fname,0777 & ~orig_umask);
302 *p = '/';
303 p++;
305 return 0;
309 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
310 Return LEN upon success, write's (negative) error code otherwise.
312 derived from GNU C's cccp.c.
314 int full_write(int desc, char *ptr, int len)
316 int total_written;
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;
328 total_written += written;
329 ptr += written;
330 len -= written;
332 return total_written;
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.
339 derived from GNU C's cccp.c. */
340 int safe_read(int desc, char *ptr, int len)
342 int n_chars;
344 if (len <= 0)
345 return len;
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
355 return n_chars;
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)
362 int ifd;
363 int ofd;
364 char buf[1024 * 8];
365 int len; /* Number of bytes read into `buf'. */
367 ifd = open(source, O_RDONLY);
368 if (ifd == -1) {
369 fprintf(FERROR,"open %s: %s\n",
370 source,strerror(errno));
371 return -1;
374 if (do_unlink(dest) && errno != ENOENT) {
375 fprintf(FERROR,"unlink %s: %s\n",
376 dest,strerror(errno));
377 return -1;
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;
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;
398 close(ifd);
399 close(ofd);
401 if (len < 0) {
402 fprintf(FERROR,"read %s: %s\n",
403 source,strerror(errno));
404 return -1;
407 return 0;
410 /* sleep for a while via select */
411 void u_sleep(int usec)
413 struct timeval tv;
415 tv.tv_sec = 0;
416 tv.tv_usec = usec;
417 select(0, NULL, NULL, NULL, &tv);
421 static pid_t all_pids[10];
422 static int num_pids;
424 /* fork and record the pid of the child */
425 pid_t do_fork(void)
427 pid_t newpid = fork();
429 if (newpid) {
430 all_pids[num_pids++] = newpid;
432 return newpid;
435 /* kill all children */
436 void kill_all(int sig)
438 int i;
439 for (i=0;i<num_pids;i++) {
440 if (all_pids[i] != getpid())
441 kill(all_pids[i], sig);