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;
74 if (offset >= map->p_offset &&
75 offset+len <= map->p_offset+map->p_len) {
76 return (map->map + (offset - map->p_offset));
78 if (munmap(map->map, map->p_len) != 0) {
79 rprintf(FERROR,"munmap failed : %s\n", strerror(errno));
83 /* align the mmap region on a nice boundary back a bit from
84 where it is asked for to allow for some seeking */
85 if (offset > 2*CHUNK_SIZE) {
86 map->p_offset = offset - 2*CHUNK_SIZE;
87 map->p_offset &= ~((OFF_T)(CHUNK_SIZE-1));
92 /* map up to MAX_MAP_SIZE */
93 map->p_len = MAX(len, MAX_MAP_SIZE);
94 map->p_len = MIN(map->p_len, map->size - map->p_offset);
96 map->map = (char *)do_mmap(NULL,map->p_len,PROT_READ,
97 MAP_SHARED,map->fd,map->p_offset);
99 if (map->map == (char *)-1) {
104 return (map->map + (offset - map->p_offset));
109 if (offset >= map->p_offset &&
110 offset+len <= map->p_offset+map->p_len) {
111 return (map->p + (offset - map->p_offset));
114 len = MAX(len,CHUNK_SIZE);
115 if (len > (map->size-offset))
116 len = map->size-offset;
118 if (len > map->p_size) {
119 if (map->p) free(map->p);
120 map->p = (char *)malloc(len);
121 if (!map->p) out_of_memory("map_ptr");
125 map->p_offset = offset;
128 if (do_lseek(map->fd,offset,SEEK_SET) != offset) {
129 rprintf(FERROR,"lseek failed in map_ptr\n");
133 if ((nread=read(map->fd,map->p,len)) != len) {
134 if (nread < 0) nread = 0;
135 /* the best we can do is zero the buffer - the file
136 has changed mid transfer! */
137 memset(map->p+nread, 0, len - nread);
144 void unmap_file(struct map_struct *map)
148 munmap(map->map,map->p_len);
156 memset(map, 0, sizeof(*map));
161 /* this is taken from CVS */
162 int piped_child(char **command,int *f_in,int *f_out)
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 rprintf(FERROR,"pipe: %s\n",strerror(errno));
177 rprintf(FERROR,"fork: %s\n",strerror(errno));
183 extern int orig_umask;
184 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
185 close(to_child_pipe[1]) < 0 ||
186 close(from_child_pipe[0]) < 0 ||
187 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
188 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
191 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
192 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
194 execvp(command[0], command);
195 rprintf(FERROR,"Failed to exec %s : %s\n",
196 command[0],strerror(errno));
200 if (close(from_child_pipe[1]) < 0 ||
201 close(to_child_pipe[0]) < 0) {
202 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
206 *f_in = from_child_pipe[0];
207 *f_out = to_child_pipe[1];
212 int local_child(int argc, char **argv,int *f_in,int *f_out)
215 int to_child_pipe[2];
216 int from_child_pipe[2];
218 if (pipe(to_child_pipe) < 0 ||
219 pipe(from_child_pipe) < 0) {
220 rprintf(FERROR,"pipe: %s\n",strerror(errno));
227 rprintf(FERROR,"fork: %s\n",strerror(errno));
232 extern int am_sender;
233 extern int am_server;
235 am_sender = !am_sender;
238 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
239 close(to_child_pipe[1]) < 0 ||
240 close(from_child_pipe[0]) < 0 ||
241 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
242 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
245 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
246 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
247 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
250 if (close(from_child_pipe[1]) < 0 ||
251 close(to_child_pipe[0]) < 0) {
252 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
256 *f_in = from_child_pipe[0];
257 *f_out = to_child_pipe[1];
264 void out_of_memory(char *str)
266 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
270 void overflow(char *str)
272 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
278 int set_modtime(char *fname,time_t modtime)
281 if (dry_run) return 0;
285 tbuf.actime = time(NULL);
286 tbuf.modtime = modtime;
287 return utime(fname,&tbuf);
288 #elif defined(HAVE_UTIME)
292 return utime(fname,t);
295 t[0].tv_sec = time(NULL);
297 t[1].tv_sec = modtime;
299 return utimes(fname,t);
306 /****************************************************************************
307 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
311 ****************************************************************************/
312 int set_blocking(int fd, int set)
316 #define FLAG_TO_SET O_NONBLOCK
319 #define FLAG_TO_SET O_NDELAY
321 #define FLAG_TO_SET FNDELAY
325 if((val = fcntl(fd, F_GETFL, 0)) == -1)
327 if(set) /* Turn blocking on - ie. clear nonblock flag */
331 return fcntl( fd, F_SETFL, val);
335 /****************************************************************************
336 create any necessary directories in fname. Unfortunately we don't know
337 what perms to give the directory when this is called so we need to rely
339 ****************************************************************************/
340 int create_directory_path(char *fname)
342 extern int orig_umask;
345 while (*fname == '/') fname++;
346 while (strncmp(fname,"./",2)==0) fname += 2;
349 while ((p=strchr(p,'/'))) {
351 do_mkdir(fname,0777 & ~orig_umask);
359 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
360 Return LEN upon success, write's (negative) error code otherwise.
362 derived from GNU C's cccp.c.
364 int full_write(int desc, char *ptr, int len)
370 int written = write (desc, ptr, len);
378 total_written += written;
382 return total_written;
385 /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
386 Return the actual number of bytes read, zero for EOF, or negative
389 derived from GNU C's cccp.c. */
390 int safe_read(int desc, char *ptr, int len)
399 n_chars = read(desc, ptr, len);
400 } while (n_chars < 0 && errno == EINTR);
402 n_chars = read(desc, ptr, len);
409 /* copy a file - this is used in conjunction with the --temp-dir option */
410 int copy_file(char *source, char *dest, mode_t mode)
415 int len; /* Number of bytes read into `buf'. */
417 ifd = open(source, O_RDONLY);
419 rprintf(FERROR,"open %s: %s\n",
420 source,strerror(errno));
424 if (do_unlink(dest) && errno != ENOENT) {
425 rprintf(FERROR,"unlink %s: %s\n",
426 dest,strerror(errno));
430 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
432 rprintf(FERROR,"open %s: %s\n",
433 dest,strerror(errno));
438 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
439 if (full_write(ofd, buf, len) < 0) {
440 rprintf(FERROR,"write %s: %s\n",
441 dest,strerror(errno));
452 rprintf(FERROR,"read %s: %s\n",
453 source,strerror(errno));
460 /* sleep for a while via select */
461 void u_sleep(int usec)
467 select(0, NULL, NULL, NULL, &tv);
471 static pid_t all_pids[10];
474 /* fork and record the pid of the child */
477 pid_t newpid = fork();
480 all_pids[num_pids++] = newpid;
485 /* kill all children */
486 void kill_all(int sig)
489 for (i=0;i<num_pids;i++) {
490 if (all_pids[i] != getpid())
491 kill(all_pids[i], sig);
495 /* like strncpy but does not 0 fill the buffer and always null
496 terminates (thus it can use maxlen+1 space in d) */
497 void strlcpy(char *d, char *s, int maxlen)
500 if (len > maxlen) len = maxlen;
505 /* like strncat but does not 0 fill the buffer and always null
506 terminates (thus it can use maxlen+1 space in d) */
507 void strlcat(char *d, char *s, int maxlen)
509 int len1 = strlen(d);
510 int len2 = strlen(s);
511 if (len1+len2 > maxlen) {
515 memcpy(d+len1, s, len2);
520 /* turn a user name into a uid */
521 int name_to_uid(char *name, uid_t *uid)
524 if (!name || !*name) return 0;
525 pass = getpwnam(name);
533 /* turn a group name into a gid */
534 int name_to_gid(char *name, gid_t *gid)
537 if (!name || !*name) return 0;
538 grp = getgrnam(name);
547 /****************************************************************************
548 check if a process exists.
549 ****************************************************************************/
550 int process_exists(int pid)
552 return(kill(pid,0) == 0 || errno != ESRCH);
555 /* lock a byte range in a open file */
556 int lock_range(int fd, int offset, int len)
560 lock.l_type = F_WRLCK;
561 lock.l_whence = SEEK_SET;
562 lock.l_start = offset;
566 return fcntl(fd,F_SETLK,&lock) == 0;
570 static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
574 argv[*argc] = strdup(s);
583 argv[*argc] = strdup(s);
585 memset(&globbuf, 0, sizeof(globbuf));
586 glob(argv[*argc], 0, NULL, &globbuf);
587 if (globbuf.gl_pathc == 0) {
592 for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
593 if (i == 0) free(argv[*argc]);
594 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
595 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
602 void glob_expand(char *base1, char **argv, int *argc, int maxargs)
604 char *s = argv[*argc];
608 if (!s || !*s) return;
610 if (strncmp(s, base, strlen(base)) == 0) {
615 if (!s) out_of_memory("glob_expand");
617 base = (char *)malloc(strlen(base1)+3);
618 if (!base) out_of_memory("glob_expand");
620 sprintf(base," %s/", base1);
623 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
624 /* split it at this point */
626 glob_expand_one(q, argv, argc, maxargs);
630 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
636 /*******************************************************************
637 convert a string to lower case
638 ********************************************************************/
639 void strlower(char *s)
642 if (isupper(*s)) *s = tolower(*s);
647 /* this is like vsnprintf but the 'n' limit does not include
648 the terminating null. So if you have a 1024 byte buffer then
650 int vslprintf(char *str, int n, const char *format, va_list ap)
652 #ifdef HAVE_VSNPRINTF
653 int ret = vsnprintf(str, n, format, ap);
654 if (ret > n || ret < 0) {
662 static int len=MAXPATHLEN*8;
665 /* this code is NOT a proper vsnprintf() implementation. It
666 relies on the fact that all calls to slprintf() in rsync
667 pass strings which have already been checked to be less
668 than MAXPATHLEN in length and never more than 2 strings are
669 concatenated. This means the above buffer is absolutely
670 ample and can never be overflowed.
672 In the future we would like to replace this with a proper
673 vsnprintf() implementation but right now we need a solution
674 that is secure and portable. This is it. */
679 /* can't call debug or we would recurse */
684 vsprintf(buf, format, ap);
692 memcpy(str, buf, ret+1);
699 /* like snprintf but always null terminates */
700 int slprintf(char *str, int n, char *format, ...)
705 va_start(ap, format);
706 ret = vslprintf(str,n,format,ap);