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
27 int num_waiting(int fd)
30 ioctl(fd,FIONREAD,&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");
50 if (len < MAX_MAP_SIZE)
51 ret->map = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
57 char *map_ptr(struct map_struct *map,off_t offset,int len)
62 return map->map+offset;
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");
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);
93 map->p_offset = offset;
100 void unmap_file(struct map_struct *map)
104 munmap(map->map,map->size);
106 if (map->p) free(map->p);
111 /* this is taken from CVS */
112 int piped_child(char **command,int *f_in,int *f_out)
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));
127 fprintf(FERROR,"fork: %s\n",strerror(errno));
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));
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]);
144 execvp(command[0], command);
145 fprintf(FERROR,"Failed to exec %s : %s\n",
146 command[0],strerror(errno));
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));
156 *f_in = from_child_pipe[0];
157 *f_out = to_child_pipe[1];
163 void out_of_memory(char *str)
165 fprintf(FERROR,"ERROR: out of memory in %s\n",str);
169 void overflow(char *str)
171 fprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
177 int set_modtime(char *fname,time_t modtime)
180 if (dry_run) return 0;
184 tbuf.actime = time(NULL);
185 tbuf.modtime = modtime;
186 return utime(fname,&tbuf);
187 #elif defined(HAVE_UTIME)
191 return utime(fname,t);
194 t[0].tv_sec = time(NULL);
196 t[1].tv_sec = modtime;
198 return utimes(fname,t);
205 /****************************************************************************
206 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
210 ****************************************************************************/
211 int set_blocking(int fd, int set)
215 #define FLAG_TO_SET O_NONBLOCK
218 #define FLAG_TO_SET O_NDELAY
220 #define FLAG_TO_SET FNDELAY
224 if((val = fcntl(fd, F_GETFL, 0)) == -1)
226 if(set) /* Turn blocking on - ie. clear nonblock flag */
230 return fcntl( fd, F_SETFL, val);
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
238 ****************************************************************************/
239 int create_directory_path(char *fname)
241 extern int orig_umask;
244 while (*fname == '/') fname++;
245 while (strncmp(fname,"./",2)==0) fname += 2;
248 while ((p=strchr(p,'/'))) {
250 mkdir(fname,0777 & ~orig_umask);
258 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
259 Return LEN upon success, write's (negative) error code otherwise.
261 derived from GNU C's cccp.c.
263 int full_write(int desc, char *ptr, int len)
269 int written = write (desc, ptr, len);
277 total_written += written;
281 return total_written;
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
288 derived from GNU C's cccp.c. */
289 int safe_read(int desc, char *ptr, int len)
298 n_chars = read(desc, ptr, len);
299 } while (n_chars < 0 && errno == EINTR);
301 n_chars = read(desc, ptr, len);
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)
314 int len; /* Number of bytes read into `buf'. */
316 ifd = open(source, O_RDONLY);
318 fprintf(FERROR,"open %s: %s\n",
319 source,strerror(errno));
323 if (do_unlink(dest) && errno != ENOENT) {
324 fprintf(FERROR,"unlink %s: %s\n",
325 dest,strerror(errno));
329 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
331 fprintf(FERROR,"open %s: %s\n",
332 dest,strerror(errno));
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));
351 fprintf(FERROR,"read %s: %s\n",
352 source,strerror(errno));
359 /* sleep for a while via select */
360 void u_sleep(int usec)
366 select(0, NULL, NULL, NULL, &tv);
370 static pid_t all_pids[10];
373 /* fork and record the pid of the child */
376 pid_t newpid = fork();
379 all_pids[num_pids++] = newpid;
384 /* kill all children */
385 void kill_all(int sig)
388 for (i=0;i<num_pids;i++) {
389 if (all_pids[i] != getpid())
390 kill(all_pids[i], sig);