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 /****************************************************************************
28 Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
32 ****************************************************************************/
33 int set_nonblocking(int fd)
37 #define FLAG_TO_SET O_NONBLOCK
40 #define FLAG_TO_SET O_NDELAY
42 #define FLAG_TO_SET FNDELAY
46 if((val = fcntl(fd, F_GETFL, 0)) == -1)
49 return fcntl( fd, F_SETFL, val);
54 /* this is taken from CVS */
55 int piped_child(char **command,int *f_in,int *f_out)
59 int from_child_pipe[2];
61 if (pipe(to_child_pipe) < 0 ||
62 pipe(from_child_pipe) < 0) {
63 rprintf(FERROR,"pipe: %s\n",strerror(errno));
64 exit_cleanup(RERR_IPC);
70 rprintf(FERROR,"fork: %s\n",strerror(errno));
71 exit_cleanup(RERR_IPC);
76 extern int orig_umask;
77 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
78 close(to_child_pipe[1]) < 0 ||
79 close(from_child_pipe[0]) < 0 ||
80 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
81 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
82 exit_cleanup(RERR_IPC);
84 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
85 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
87 execvp(command[0], command);
88 rprintf(FERROR,"Failed to exec %s : %s\n",
89 command[0],strerror(errno));
90 exit_cleanup(RERR_IPC);
93 if (close(from_child_pipe[1]) < 0 ||
94 close(to_child_pipe[0]) < 0) {
95 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
96 exit_cleanup(RERR_IPC);
99 *f_in = from_child_pipe[0];
100 *f_out = to_child_pipe[1];
102 set_nonblocking(*f_in);
103 set_nonblocking(*f_out);
108 int local_child(int argc, char **argv,int *f_in,int *f_out)
111 int to_child_pipe[2];
112 int from_child_pipe[2];
114 if (pipe(to_child_pipe) < 0 ||
115 pipe(from_child_pipe) < 0) {
116 rprintf(FERROR,"pipe: %s\n",strerror(errno));
117 exit_cleanup(RERR_IPC);
123 rprintf(FERROR,"fork: %s\n",strerror(errno));
124 exit_cleanup(RERR_IPC);
128 extern int am_sender;
129 extern int am_server;
131 am_sender = !am_sender;
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 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
139 exit_cleanup(RERR_IPC);
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 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
146 if (close(from_child_pipe[1]) < 0 ||
147 close(to_child_pipe[0]) < 0) {
148 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
149 exit_cleanup(RERR_IPC);
152 *f_in = from_child_pipe[0];
153 *f_out = to_child_pipe[1];
160 void out_of_memory(char *str)
162 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
163 exit_cleanup(RERR_MALLOC);
166 void overflow(char *str)
168 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
169 exit_cleanup(RERR_MALLOC);
174 int set_modtime(char *fname,time_t modtime)
177 if (dry_run) return 0;
181 tbuf.actime = time(NULL);
182 tbuf.modtime = modtime;
183 return utime(fname,&tbuf);
184 #elif defined(HAVE_UTIME)
188 return utime(fname,t);
191 t[0].tv_sec = time(NULL);
193 t[1].tv_sec = modtime;
195 return utimes(fname,t);
201 /****************************************************************************
202 create any necessary directories in fname. Unfortunately we don't know
203 what perms to give the directory when this is called so we need to rely
205 ****************************************************************************/
206 int create_directory_path(char *fname)
208 extern int orig_umask;
211 while (*fname == '/') fname++;
212 while (strncmp(fname,"./",2)==0) fname += 2;
215 while ((p=strchr(p,'/'))) {
217 do_mkdir(fname,0777 & ~orig_umask);
225 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
226 Return LEN upon success, write's (negative) error code otherwise.
228 derived from GNU C's cccp.c.
230 static int full_write(int desc, char *ptr, int len)
236 int written = write (desc, ptr, len);
244 total_written += written;
248 return total_written;
251 /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
252 Return the actual number of bytes read, zero for EOF, or negative
255 derived from GNU C's cccp.c. */
256 static int safe_read(int desc, char *ptr, int len)
265 n_chars = read(desc, ptr, len);
266 } while (n_chars < 0 && errno == EINTR);
268 n_chars = read(desc, ptr, len);
275 /* copy a file - this is used in conjunction with the --temp-dir option */
276 int copy_file(char *source, char *dest, mode_t mode)
281 int len; /* Number of bytes read into `buf'. */
283 ifd = open(source, O_RDONLY);
285 rprintf(FERROR,"open %s: %s\n",
286 source,strerror(errno));
290 if (do_unlink(dest) && errno != ENOENT) {
291 rprintf(FERROR,"unlink %s: %s\n",
292 dest,strerror(errno));
296 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
298 rprintf(FERROR,"open %s: %s\n",
299 dest,strerror(errno));
304 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
305 if (full_write(ofd, buf, len) < 0) {
306 rprintf(FERROR,"write %s: %s\n",
307 dest,strerror(errno));
318 rprintf(FERROR,"read %s: %s\n",
319 source,strerror(errno));
326 /* sleep for a while via select */
327 void u_sleep(int usec)
333 select(0, NULL, NULL, NULL, &tv);
337 static pid_t all_pids[10];
340 /* fork and record the pid of the child */
343 pid_t newpid = fork();
346 all_pids[num_pids++] = newpid;
351 /* kill all children */
352 void kill_all(int sig)
355 for (i=0;i<num_pids;i++) {
356 if (all_pids[i] != getpid())
357 kill(all_pids[i], sig);
361 /* like strncpy but does not 0 fill the buffer and always null
362 terminates. bufsize is the size of the destination buffer */
363 size_t strlcpy(char *d, const char *s, size_t bufsize)
365 size_t len = strlen(s);
367 if (len >= bufsize) len = bufsize-1;
373 /* like strncat but does not 0 fill the buffer and always null
374 terminates. bufsize is the length of the buffer, which should
375 be one more than the maximum resulting string length */
376 size_t strlcat(char *d, const char *s, size_t bufsize)
378 size_t len1 = strlen(d);
379 size_t len2 = strlen(s);
380 size_t ret = len1 + len2;
382 if (len1+len2 >= bufsize) {
383 len2 = bufsize - (len1+1);
386 memcpy(d+len1, s, len2);
392 /* turn a user name into a uid */
393 int name_to_uid(char *name, uid_t *uid)
396 if (!name || !*name) return 0;
397 pass = getpwnam(name);
405 /* turn a group name into a gid */
406 int name_to_gid(char *name, gid_t *gid)
409 if (!name || !*name) return 0;
410 grp = getgrnam(name);
419 /* lock a byte range in a open file */
420 int lock_range(int fd, int offset, int len)
424 lock.l_type = F_WRLCK;
425 lock.l_whence = SEEK_SET;
426 lock.l_start = offset;
430 return fcntl(fd,F_SETLK,&lock) == 0;
434 static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
436 #if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
438 argv[*argc] = strdup(s);
447 argv[*argc] = strdup(s);
449 memset(&globbuf, 0, sizeof(globbuf));
450 glob(argv[*argc], 0, NULL, &globbuf);
451 if (globbuf.gl_pathc == 0) {
456 for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
457 if (i == 0) free(argv[*argc]);
458 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
459 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
466 void glob_expand(char *base1, char **argv, int *argc, int maxargs)
468 char *s = argv[*argc];
472 if (!s || !*s) return;
474 if (strncmp(s, base, strlen(base)) == 0) {
479 if (!s) out_of_memory("glob_expand");
481 base = (char *)malloc(strlen(base1)+3);
482 if (!base) out_of_memory("glob_expand");
484 sprintf(base," %s/", base1);
487 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
488 /* split it at this point */
490 glob_expand_one(q, argv, argc, maxargs);
494 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
500 /*******************************************************************
501 convert a string to lower case
502 ********************************************************************/
503 void strlower(char *s)
506 if (isupper(*s)) *s = tolower(*s);
511 /* this is like vsnprintf but it always null terminates, so you
512 can fit at most n-1 chars in */
513 int vslprintf(char *str, int n, const char *format, va_list ap)
515 int ret = vsnprintf(str, n, format, ap);
516 if (ret >= n || ret < 0) {
525 /* like snprintf but always null terminates */
526 int slprintf(char *str, int n, char *format, ...)
531 va_start(ap, format);
532 ret = vslprintf(str,n,format,ap);
538 void *Realloc(void *p, int size)
540 if (!p) return (void *)malloc(size);
541 return (void *)realloc(p, size);
545 void clean_fname(char *name)
556 if ((p=strstr(name,"/./"))) {
564 if ((p=strstr(name,"//"))) {
572 if (strncmp(p=name,"./",2) == 0) {
580 if (l > 1 && p[l-1] == '/') {
588 * Make path appear as if a chroot had occurred:
589 * 1. remove leading "/" (or replace with "." if at end)
590 * 2. remove leading ".." components
591 * 3. delete any other "<dir>/.." (recursively)
592 * While we're at it, remove double slashes and "." components like
593 * clean_fname does(), but DON'T remove a trailing slash because that
594 * is sometimes significant on command line arguments.
595 * Return a malloc'ed copy.
596 * Contributed by Dave Dykstra <dwd@bell-labs.com>
599 char *sanitize_path(char *p)
603 copy = (char *) malloc(strlen(p)+1);
606 /* remove leading slashes */
610 /* this loop iterates once per filename component in p.
611 * both p (and copyp if the original had a slash) should
612 * always be left pointing after a slash
614 if ((*p == '.') && ((*(p+1) == '/') || (*(p+1) == '\0'))) {
615 /* skip "." component */
616 while (*++p == '/') {
617 /* skip following slashes */
620 } else if ((*p == '.') && (*(p+1) == '.') &&
621 ((*(p+2) == '/') || (*(p+2) == '\0'))) {
622 /* skip ".." component followed by slash or end */
627 /* back up the copy one level */
628 --copyp; /* now pointing at slash */
629 while ((copyp > copy) && (*(copyp - 1) != '/')) {
630 /* skip back up to slash */
636 /* copy one component through next slash */
638 if ((*p == '\0') || (*(p-1) == '/')) {
640 /* skip multiple slashes */
649 /* ended up with nothing, so put in "." component */
657 static char curr_dir[MAXPATHLEN];
659 /* like chdir() but can be reversed with pop_dir() if save is set. It
660 is also much faster as it remembers where we have been */
661 char *push_dir(char *dir, int save)
663 char *ret = curr_dir;
664 static int initialised;
668 getcwd(curr_dir, sizeof(curr_dir)-1);
671 if (chdir(dir)) return NULL;
674 ret = strdup(curr_dir);
678 strlcpy(curr_dir, dir, sizeof(curr_dir));
680 strlcat(curr_dir,"/", sizeof(curr_dir));
681 strlcat(curr_dir,dir, sizeof(curr_dir));
684 clean_fname(curr_dir);
689 /* reverse a push_dir call */
690 int pop_dir(char *dir)
700 strlcpy(curr_dir, dir, sizeof(curr_dir));
707 /* we need to supply our own strcmp function for file list comparisons
708 to ensure that signed/unsigned usage is consistent between machines. */
709 int u_strcmp(const char *cs1, const char *cs2)
711 const uchar *s1 = (uchar *)cs1;
712 const uchar *s2 = (uchar *)cs2;
714 while (*s1 && *s2 && (*s1 == *s2)) {
718 return (int)*s1 - (int)*s2;
721 static OFF_T last_ofs;
723 void end_progress(void)
725 extern int do_progress, am_server;
727 if (do_progress && !am_server) {
733 void show_progress(OFF_T ofs, OFF_T size)
735 extern int do_progress, am_server;
737 if (do_progress && !am_server) {
738 if (ofs > last_ofs + 1000) {
739 int pct = (int)((100.0*ofs)/size);
740 rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
746 /* determine if a symlink points outside the current directory tree */
747 int unsafe_symlink(char *dest, char *src)
752 /* all absolute and null symlinks are unsafe */
753 if (!dest || !(*dest) || (*dest == '/')) return 1;
756 if (!src) out_of_memory("unsafe_symlink");
758 /* find out what our safety margin is */
759 for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
760 if (strcmp(tok,"..") == 0) {
762 } else if (strcmp(tok,".") == 0) {
770 /* drop by one to account for the filename portion */
774 if (!dest) out_of_memory("unsafe_symlink");
776 for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
777 if (strcmp(tok,"..") == 0) {
779 } else if (strcmp(tok,".") == 0) {
784 /* if at any point we go outside the current directory then
785 stop - it is unsafe */
786 if (depth < 0) break;
794 /****************************************************************************
795 return the date and time as a string
796 ****************************************************************************/
797 char *timestring(time_t t)
799 static char TimeBuf[200];
800 struct tm *tm = localtime(&t);
803 strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
805 strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf));
808 if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
809 TimeBuf[strlen(TimeBuf)-1] = 0;