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 len = MIN(len, MAX_MAP_SIZE);
51 ret->map = (char *)do_mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
52 if (ret->map == (char *)-1) {
62 char *map_ptr(struct map_struct *map,OFF_T offset,int len)
69 if (len > (map->size-offset))
70 len = map->size-offset;
73 if (offset >= map->p_offset &&
74 offset+len <= map->p_offset+map->p_len) {
75 return (map->map + (offset - map->p_offset));
77 if (munmap(map->map, map->p_len) != 0) {
78 rprintf(FERROR,"munmap failed : %s\n", strerror(errno));
82 /* align the mmap region on a nice boundary back a bit from
83 where it is asked for to allow for some seeking */
84 if (offset > 2*CHUNK_SIZE) {
85 map->p_offset = offset - 2*CHUNK_SIZE;
86 map->p_offset &= ~((OFF_T)(CHUNK_SIZE-1));
91 /* map up to MAX_MAP_SIZE */
92 map->p_len = MAX(len, MAX_MAP_SIZE);
93 map->p_len = MIN(map->p_len, map->size - map->p_offset);
95 map->map = (char *)do_mmap(NULL,map->p_len,PROT_READ,
96 MAP_SHARED,map->fd,map->p_offset);
98 if (map->map == (char *)-1) {
103 return (map->map + (offset - map->p_offset));
107 if (offset >= map->p_offset &&
108 offset+len <= map->p_offset+map->p_len) {
109 return (map->p + (offset - map->p_offset));
112 len = MAX(len,CHUNK_SIZE);
113 if (len > (map->size-offset))
114 len = map->size-offset;
116 if (len > map->p_size) {
117 if (map->p) free(map->p);
118 map->p = (char *)malloc(len);
119 if (!map->p) out_of_memory("map_ptr");
123 map->p_offset = offset;
126 if (do_lseek(map->fd,offset,SEEK_SET) != offset) {
127 rprintf(FERROR,"lseek failed in map_ptr\n");
131 if ((nread=read(map->fd,map->p,len)) != len) {
132 if (nread < 0) nread = 0;
133 /* the best we can do is zero the buffer - the file
134 has changed mid transfer! */
135 memset(map->p+nread, 0, len - nread);
142 void unmap_file(struct map_struct *map)
146 munmap(map->map,map->p_len);
154 memset(map, 0, sizeof(*map));
159 /* this is taken from CVS */
160 int piped_child(char **command,int *f_in,int *f_out)
163 int to_child_pipe[2];
164 int from_child_pipe[2];
166 if (pipe(to_child_pipe) < 0 ||
167 pipe(from_child_pipe) < 0) {
168 rprintf(FERROR,"pipe: %s\n",strerror(errno));
175 rprintf(FERROR,"fork: %s\n",strerror(errno));
181 extern int orig_umask;
182 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
183 close(to_child_pipe[1]) < 0 ||
184 close(from_child_pipe[0]) < 0 ||
185 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
186 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
189 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
190 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
192 execvp(command[0], command);
193 rprintf(FERROR,"Failed to exec %s : %s\n",
194 command[0],strerror(errno));
198 if (close(from_child_pipe[1]) < 0 ||
199 close(to_child_pipe[0]) < 0) {
200 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
204 *f_in = from_child_pipe[0];
205 *f_out = to_child_pipe[1];
210 int local_child(int argc, char **argv,int *f_in,int *f_out)
213 int to_child_pipe[2];
214 int from_child_pipe[2];
216 if (pipe(to_child_pipe) < 0 ||
217 pipe(from_child_pipe) < 0) {
218 rprintf(FERROR,"pipe: %s\n",strerror(errno));
225 rprintf(FERROR,"fork: %s\n",strerror(errno));
230 extern int am_sender;
231 extern int am_server;
233 am_sender = !am_sender;
236 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
237 close(to_child_pipe[1]) < 0 ||
238 close(from_child_pipe[0]) < 0 ||
239 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
240 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
243 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
244 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
245 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
248 if (close(from_child_pipe[1]) < 0 ||
249 close(to_child_pipe[0]) < 0) {
250 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
254 *f_in = from_child_pipe[0];
255 *f_out = to_child_pipe[1];
262 void out_of_memory(char *str)
264 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
268 void overflow(char *str)
270 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
276 int set_modtime(char *fname,time_t modtime)
279 if (dry_run) return 0;
283 tbuf.actime = time(NULL);
284 tbuf.modtime = modtime;
285 return utime(fname,&tbuf);
286 #elif defined(HAVE_UTIME)
290 return utime(fname,t);
293 t[0].tv_sec = time(NULL);
295 t[1].tv_sec = modtime;
297 return utimes(fname,t);
304 /****************************************************************************
305 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
309 ****************************************************************************/
310 int set_blocking(int fd, int set)
314 #define FLAG_TO_SET O_NONBLOCK
317 #define FLAG_TO_SET O_NDELAY
319 #define FLAG_TO_SET FNDELAY
323 if((val = fcntl(fd, F_GETFL, 0)) == -1)
325 if(set) /* Turn blocking on - ie. clear nonblock flag */
329 return fcntl( fd, F_SETFL, val);
333 /****************************************************************************
334 create any necessary directories in fname. Unfortunately we don't know
335 what perms to give the directory when this is called so we need to rely
337 ****************************************************************************/
338 int create_directory_path(char *fname)
340 extern int orig_umask;
343 while (*fname == '/') fname++;
344 while (strncmp(fname,"./",2)==0) fname += 2;
347 while ((p=strchr(p,'/'))) {
349 do_mkdir(fname,0777 & ~orig_umask);
357 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
358 Return LEN upon success, write's (negative) error code otherwise.
360 derived from GNU C's cccp.c.
362 int full_write(int desc, char *ptr, int len)
368 int written = write (desc, ptr, len);
376 total_written += written;
380 return total_written;
383 /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
384 Return the actual number of bytes read, zero for EOF, or negative
387 derived from GNU C's cccp.c. */
388 int safe_read(int desc, char *ptr, int len)
397 n_chars = read(desc, ptr, len);
398 } while (n_chars < 0 && errno == EINTR);
400 n_chars = read(desc, ptr, len);
407 /* copy a file - this is used in conjunction with the --temp-dir option */
408 int copy_file(char *source, char *dest, mode_t mode)
413 int len; /* Number of bytes read into `buf'. */
415 ifd = open(source, O_RDONLY);
417 rprintf(FERROR,"open %s: %s\n",
418 source,strerror(errno));
422 if (do_unlink(dest) && errno != ENOENT) {
423 rprintf(FERROR,"unlink %s: %s\n",
424 dest,strerror(errno));
428 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
430 rprintf(FERROR,"open %s: %s\n",
431 dest,strerror(errno));
436 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
437 if (full_write(ofd, buf, len) < 0) {
438 rprintf(FERROR,"write %s: %s\n",
439 dest,strerror(errno));
450 rprintf(FERROR,"read %s: %s\n",
451 source,strerror(errno));
458 /* sleep for a while via select */
459 void u_sleep(int usec)
465 select(0, NULL, NULL, NULL, &tv);
469 static pid_t all_pids[10];
472 /* fork and record the pid of the child */
475 pid_t newpid = fork();
478 all_pids[num_pids++] = newpid;
483 /* kill all children */
484 void kill_all(int sig)
487 for (i=0;i<num_pids;i++) {
488 if (all_pids[i] != getpid())
489 kill(all_pids[i], sig);
493 /* like strncpy but does not 0 fill the buffer and always null
494 terminates (thus it can use maxlen+1 space in d) */
495 void strlcpy(char *d, char *s, int maxlen)
498 if (len > maxlen) len = maxlen;
503 /* like strncat but does not 0 fill the buffer and always null
504 terminates (thus it can use maxlen+1 space in d) */
505 void strlcat(char *d, char *s, int maxlen)
507 int len1 = strlen(d);
508 int len2 = strlen(s);
509 if (len1+len2 > maxlen) {
513 memcpy(d+len1, s, len2);
518 /* turn a user name into a uid */
519 int name_to_uid(char *name, uid_t *uid)
522 if (!name || !*name) return 0;
523 pass = getpwnam(name);
531 /* turn a group name into a gid */
532 int name_to_gid(char *name, gid_t *gid)
535 if (!name || !*name) return 0;
536 grp = getgrnam(name);
545 /****************************************************************************
546 check if a process exists.
547 ****************************************************************************/
548 int process_exists(int pid)
550 return(kill(pid,0) == 0 || errno != ESRCH);
553 /* lock a byte range in a open file */
554 int lock_range(int fd, int offset, int len)
558 lock.l_type = F_WRLCK;
559 lock.l_whence = SEEK_SET;
560 lock.l_start = offset;
564 return fcntl(fd,F_SETLK,&lock) == 0;
568 static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
572 argv[*argc] = strdup(s);
581 argv[*argc] = strdup(s);
583 memset(&globbuf, 0, sizeof(globbuf));
584 glob(argv[*argc], 0, NULL, &globbuf);
585 if (globbuf.gl_pathc == 0) {
590 for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
591 if (i == 0) free(argv[*argc]);
592 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
593 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
600 void glob_expand(char *base1, char **argv, int *argc, int maxargs)
602 char *s = argv[*argc];
606 if (!s || !*s) return;
608 if (strncmp(s, base, strlen(base)) == 0) {
613 if (!s) out_of_memory("glob_expand");
615 base = (char *)malloc(strlen(base1)+3);
616 if (!base) out_of_memory("glob_expand");
618 sprintf(base," %s/", base1);
621 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
622 /* split it at this point */
624 glob_expand_one(q, argv, argc, maxargs);
628 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
634 /*******************************************************************
635 convert a string to lower case
636 ********************************************************************/
637 void strlower(char *s)
640 if (isupper(*s)) *s = tolower(*s);
645 /* this is like vsnprintf but the 'n' limit does not include
646 the terminating null. So if you have a 1024 byte buffer then
648 int vslprintf(char *str, int n, const char *format, va_list ap)
650 #ifdef HAVE_VSNPRINTF
651 int ret = vsnprintf(str, n, format, ap);
652 if (ret > n || ret < 0) {
660 static int len=MAXPATHLEN*8;
663 /* this code is NOT a proper vsnprintf() implementation. It
664 relies on the fact that all calls to slprintf() in rsync
665 pass strings which have already been checked to be less
666 than MAXPATHLEN in length and never more than 2 strings are
667 concatenated. This means the above buffer is absolutely
668 ample and can never be overflowed.
670 In the future we would like to replace this with a proper
671 vsnprintf() implementation but right now we need a solution
672 that is secure and portable. This is it. */
677 /* can't call debug or we would recurse */
682 vsprintf(buf, format, ap);
690 memcpy(str, buf, ret+1);
697 /* like snprintf but always null terminates */
698 int slprintf(char *str, int n, char *format, ...)
703 va_start(ap, format);
704 ret = vslprintf(str,n,format,ap);