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
30 /****************************************************************************
31 Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
35 ****************************************************************************/
36 void set_nonblocking(int fd)
40 if((val = fcntl(fd, F_GETFL, 0)) == -1)
42 if (!(val & NONBLOCK_FLAG)) {
44 fcntl(fd, F_SETFL, val);
49 /* create a file descriptor pair - like pipe() but use socketpair if
50 possible (because of blocking issues on pipes)
52 always set non-blocking
54 int fd_pair(int fd[2])
59 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
65 set_nonblocking(fd[0]);
66 set_nonblocking(fd[1]);
73 /* this is taken from CVS */
74 int piped_child(char **command,int *f_in,int *f_out)
78 int from_child_pipe[2];
80 if (fd_pair(to_child_pipe) < 0 ||
81 fd_pair(from_child_pipe) < 0) {
82 rprintf(FERROR,"pipe: %s\n",strerror(errno));
83 exit_cleanup(RERR_IPC);
89 rprintf(FERROR,"fork: %s\n",strerror(errno));
90 exit_cleanup(RERR_IPC);
95 extern int orig_umask;
96 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
97 close(to_child_pipe[1]) < 0 ||
98 close(from_child_pipe[0]) < 0 ||
99 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
100 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
101 exit_cleanup(RERR_IPC);
103 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
104 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
106 execvp(command[0], command);
107 rprintf(FERROR,"Failed to exec %s : %s\n",
108 command[0],strerror(errno));
109 exit_cleanup(RERR_IPC);
112 if (close(from_child_pipe[1]) < 0 ||
113 close(to_child_pipe[0]) < 0) {
114 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
115 exit_cleanup(RERR_IPC);
118 *f_in = from_child_pipe[0];
119 *f_out = to_child_pipe[1];
124 int local_child(int argc, char **argv,int *f_in,int *f_out)
127 int to_child_pipe[2];
128 int from_child_pipe[2];
130 if (fd_pair(to_child_pipe) < 0 ||
131 fd_pair(from_child_pipe) < 0) {
132 rprintf(FERROR,"pipe: %s\n",strerror(errno));
133 exit_cleanup(RERR_IPC);
139 rprintf(FERROR,"fork: %s\n",strerror(errno));
140 exit_cleanup(RERR_IPC);
144 extern int am_sender;
145 extern int am_server;
147 am_sender = !am_sender;
150 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
151 close(to_child_pipe[1]) < 0 ||
152 close(from_child_pipe[0]) < 0 ||
153 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
154 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
155 exit_cleanup(RERR_IPC);
157 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
158 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
159 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
162 if (close(from_child_pipe[1]) < 0 ||
163 close(to_child_pipe[0]) < 0) {
164 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
165 exit_cleanup(RERR_IPC);
168 *f_in = from_child_pipe[0];
169 *f_out = to_child_pipe[1];
176 void out_of_memory(char *str)
178 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
179 exit_cleanup(RERR_MALLOC);
182 void overflow(char *str)
184 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
185 exit_cleanup(RERR_MALLOC);
190 int set_modtime(char *fname,time_t modtime)
193 if (dry_run) return 0;
197 tbuf.actime = time(NULL);
198 tbuf.modtime = modtime;
199 return utime(fname,&tbuf);
200 #elif defined(HAVE_UTIME)
204 return utime(fname,t);
207 t[0].tv_sec = time(NULL);
209 t[1].tv_sec = modtime;
211 return utimes(fname,t);
217 /****************************************************************************
218 create any necessary directories in fname. Unfortunately we don't know
219 what perms to give the directory when this is called so we need to rely
221 ****************************************************************************/
222 int create_directory_path(char *fname)
224 extern int orig_umask;
227 while (*fname == '/') fname++;
228 while (strncmp(fname,"./",2)==0) fname += 2;
231 while ((p=strchr(p,'/'))) {
233 do_mkdir(fname,0777 & ~orig_umask);
241 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
242 Return LEN upon success, write's (negative) error code otherwise.
244 derived from GNU C's cccp.c.
246 static int full_write(int desc, char *ptr, int len)
252 int written = write (desc, ptr, len);
260 total_written += written;
264 return total_written;
267 /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
268 Return the actual number of bytes read, zero for EOF, or negative
271 derived from GNU C's cccp.c. */
272 static int safe_read(int desc, char *ptr, int len)
281 n_chars = read(desc, ptr, len);
282 } while (n_chars < 0 && errno == EINTR);
284 n_chars = read(desc, ptr, len);
291 /* copy a file - this is used in conjunction with the --temp-dir option */
292 int copy_file(char *source, char *dest, mode_t mode)
297 int len; /* Number of bytes read into `buf'. */
299 ifd = do_open(source, O_RDONLY, 0);
301 rprintf(FERROR,"open %s: %s\n",
302 source,strerror(errno));
306 if (robust_unlink(dest) && errno != ENOENT) {
307 rprintf(FERROR,"unlink %s: %s\n",
308 dest,strerror(errno));
312 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
314 rprintf(FERROR,"open %s: %s\n",
315 dest,strerror(errno));
320 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
321 if (full_write(ofd, buf, len) < 0) {
322 rprintf(FERROR,"write %s: %s\n",
323 dest,strerror(errno));
334 rprintf(FERROR,"read %s: %s\n",
335 source,strerror(errno));
343 Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
344 rename to <path>/.rsyncNNN instead. Note that successive rsync runs
345 will shuffle the filenames around a bit as long as the file is still
346 busy; this is because this function does not know if the unlink call
347 is due to a new file coming in, or --delete trying to remove old
348 .rsyncNNN files, hence it renames it each time.
350 /* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
351 #define MAX_RENAMES_DIGITS 3
352 #define MAX_RENAMES 1000
354 int robust_unlink(char *fname)
357 return do_unlink(fname);
359 static int counter = 1;
361 char path[MAXPATHLEN];
363 rc = do_unlink(fname);
364 if ((rc == 0) || (errno != ETXTBSY))
367 strlcpy(path, fname, MAXPATHLEN);
370 while((path[--pos] != '/') && (pos >= 0))
373 strlcpy(&path[pos], ".rsync", MAXPATHLEN-pos);
374 pos += sizeof(".rsync")-1;
376 if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
381 /* start where the last one left off to reduce chance of clashes */
384 sprintf(&path[pos], "%03d", counter);
385 if (++counter >= MAX_RENAMES)
387 } while (((rc = access(path, 0)) == 0) && (counter != start));
390 rprintf(FINFO,"renaming %s to %s because of text busy\n",
393 /* maybe we should return rename()'s exit status? Nah. */
394 if (do_rename(fname, path) != 0) {
402 int robust_rename(char *from, char *to)
405 return do_rename(from, to);
407 int rc = do_rename(from, to);
408 if ((rc == 0) || (errno != ETXTBSY))
410 if (robust_unlink(to) != 0)
412 return do_rename(from, to);
417 static pid_t all_pids[10];
420 /* fork and record the pid of the child */
423 pid_t newpid = fork();
426 all_pids[num_pids++] = newpid;
431 /* kill all children */
432 void kill_all(int sig)
435 for (i=0;i<num_pids;i++) {
436 if (all_pids[i] != getpid())
437 kill(all_pids[i], sig);
441 /* turn a user name into a uid */
442 int name_to_uid(char *name, uid_t *uid)
445 if (!name || !*name) return 0;
446 pass = getpwnam(name);
454 /* turn a group name into a gid */
455 int name_to_gid(char *name, gid_t *gid)
458 if (!name || !*name) return 0;
459 grp = getgrnam(name);
468 /* lock a byte range in a open file */
469 int lock_range(int fd, int offset, int len)
473 lock.l_type = F_WRLCK;
474 lock.l_whence = SEEK_SET;
475 lock.l_start = offset;
479 return fcntl(fd,F_SETLK,&lock) == 0;
483 static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
485 #if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
487 argv[*argc] = strdup(s);
491 extern int sanitize_paths;
497 argv[*argc] = strdup(s);
498 if (sanitize_paths) {
499 sanitize_path(argv[*argc], NULL);
502 memset(&globbuf, 0, sizeof(globbuf));
503 glob(argv[*argc], 0, NULL, &globbuf);
504 if (globbuf.gl_pathc == 0) {
509 for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
510 if (i == 0) free(argv[*argc]);
511 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
512 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
519 void glob_expand(char *base1, char **argv, int *argc, int maxargs)
521 char *s = argv[*argc];
525 if (!s || !*s) return;
527 if (strncmp(s, base, strlen(base)) == 0) {
532 if (!s) out_of_memory("glob_expand");
534 base = (char *)malloc(strlen(base1)+3);
535 if (!base) out_of_memory("glob_expand");
537 sprintf(base," %s/", base1);
540 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
541 /* split it at this point */
543 glob_expand_one(q, argv, argc, maxargs);
547 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
553 /*******************************************************************
554 convert a string to lower case
555 ********************************************************************/
556 void strlower(char *s)
559 if (isupper(*s)) *s = tolower(*s);
564 /* this is like vsnprintf but it always null terminates, so you
565 can fit at most n-1 chars in */
566 int vslprintf(char *str, int n, const char *format, va_list ap)
568 int ret = vsnprintf(str, n, format, ap);
569 if (ret >= n || ret < 0) {
578 /* like snprintf but always null terminates */
579 int slprintf(char *str, int n, char *format, ...)
584 va_start(ap, format);
585 ret = vslprintf(str,n,format,ap);
591 void *Realloc(void *p, int size)
593 if (!p) return (void *)malloc(size);
594 return (void *)realloc(p, size);
598 void clean_fname(char *name)
609 if ((p=strstr(name,"/./"))) {
617 if ((p=strstr(name,"//"))) {
625 if (strncmp(p=name,"./",2) == 0) {
633 if (l > 1 && p[l-1] == '/') {
641 * Make path appear as if a chroot had occurred:
642 * 1. remove leading "/" (or replace with "." if at end)
643 * 2. remove leading ".." components (except those allowed by "reldir")
644 * 3. delete any other "<dir>/.." (recursively)
645 * Can only shrink paths, so sanitizes in place.
646 * While we're at it, remove double slashes and "." components like
647 * clean_fname does(), but DON'T remove a trailing slash because that
648 * is sometimes significant on command line arguments.
649 * If "reldir" is non-null, it is a sanitized directory that the path will be
650 * relative to, so allow as many ".." at the beginning of the path as
651 * there are components in reldir. This is used for symbolic link targets.
652 * If reldir is non-null and the path began with "/", to be completely like
653 * a chroot we should add in depth levels of ".." at the beginning of the
654 * path, but that would blow the assumption that the path doesn't grow and
655 * it is not likely to end up being a valid symlink anyway, so just do
656 * the normal removal of the leading "/" instead.
657 * Contributed by Dave Dykstra <dwd@bell-labs.com>
660 void sanitize_path(char *p, char *reldir)
669 if (*reldir++ == '/') {
677 /* remove leading slashes */
681 /* this loop iterates once per filename component in p.
682 * both p (and sanp if the original had a slash) should
683 * always be left pointing after a slash
685 if ((*p == '.') && ((*(p+1) == '/') || (*(p+1) == '\0'))) {
686 /* skip "." component */
687 while (*++p == '/') {
688 /* skip following slashes */
694 if ((*p == '.') && (*(p+1) == '.') &&
695 ((*(p+2) == '/') || (*(p+2) == '\0'))) {
696 /* ".." component followed by slash or end */
697 if ((depth > 0) && (sanp == start)) {
698 /* allow depth levels of .. at the beginning */
706 /* back up sanp one level */
707 --sanp; /* now pointing at slash */
708 while ((sanp > start) && (*(sanp - 1) != '/')) {
709 /* skip back up to slash */
717 /* copy one component through next slash */
719 if ((*p == '\0') || (*(p-1) == '/')) {
721 /* skip multiple slashes */
728 /* move the virtual beginning to leave the .. alone */
732 if ((sanp == start) && !allowdotdot) {
733 /* ended up with nothing, so put in "." component */
735 * note that the !allowdotdot doesn't prevent this from
736 * happening in all allowed ".." situations, but I didn't
737 * think it was worth putting in an extra variable to ensure
738 * it since an extra "." won't hurt in those situations.
746 static char curr_dir[MAXPATHLEN];
748 /* like chdir() but can be reversed with pop_dir() if save is set. It
749 is also much faster as it remembers where we have been */
750 char *push_dir(char *dir, int save)
752 char *ret = curr_dir;
753 static int initialised;
757 getcwd(curr_dir, sizeof(curr_dir)-1);
760 if (!dir) return NULL; /* this call was probably just to initialize */
762 if (chdir(dir)) return NULL;
765 ret = strdup(curr_dir);
769 strlcpy(curr_dir, dir, sizeof(curr_dir));
771 strlcat(curr_dir,"/", sizeof(curr_dir));
772 strlcat(curr_dir,dir, sizeof(curr_dir));
775 clean_fname(curr_dir);
780 /* reverse a push_dir call */
781 int pop_dir(char *dir)
791 strlcpy(curr_dir, dir, sizeof(curr_dir));
798 /* we need to supply our own strcmp function for file list comparisons
799 to ensure that signed/unsigned usage is consistent between machines. */
800 int u_strcmp(const char *cs1, const char *cs2)
802 const uchar *s1 = (const uchar *)cs1;
803 const uchar *s2 = (const uchar *)cs2;
805 while (*s1 && *s2 && (*s1 == *s2)) {
809 return (int)*s1 - (int)*s2;
812 static OFF_T last_ofs;
814 void end_progress(OFF_T size)
816 extern int do_progress, am_server;
818 if (do_progress && !am_server) {
819 rprintf(FINFO,"%.0f (100%%)\n", (double)size);
824 void show_progress(OFF_T ofs, OFF_T size)
826 extern int do_progress, am_server;
828 if (do_progress && !am_server) {
829 if (ofs > last_ofs + 1000) {
830 int pct = (int)((100.0*ofs)/size);
831 rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
837 /* determine if a symlink points outside the current directory tree */
838 int unsafe_symlink(char *dest, char *src)
843 /* all absolute and null symlinks are unsafe */
844 if (!dest || !(*dest) || (*dest == '/')) return 1;
847 if (!src) out_of_memory("unsafe_symlink");
849 /* find out what our safety margin is */
850 for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
851 if (strcmp(tok,"..") == 0) {
853 } else if (strcmp(tok,".") == 0) {
861 /* drop by one to account for the filename portion */
865 if (!dest) out_of_memory("unsafe_symlink");
867 for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
868 if (strcmp(tok,"..") == 0) {
870 } else if (strcmp(tok,".") == 0) {
875 /* if at any point we go outside the current directory then
876 stop - it is unsafe */
877 if (depth < 0) break;
885 /****************************************************************************
886 return the date and time as a string
887 ****************************************************************************/
888 char *timestring(time_t t)
890 static char TimeBuf[200];
891 struct tm *tm = localtime(&t);
894 strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
896 strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf));
899 if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
900 TimeBuf[strlen(TimeBuf)-1] = 0;
907 /****************************************************************************
908 like waitpid but does the WEXITSTATUS
909 ****************************************************************************/
911 #define WEXITSTATUS(stat) ((int)(((stat)>>8)&0xFF))
913 void wait_process(pid_t pid, int *status)
915 waitpid(pid, status, 0);
916 *status = WEXITSTATUS(*status);