Added reminder to update rsync.yo manpage when adding to
[rsync/rsync.git] / util.c
CommitLineData
1960e228 1/* -*- c-file-style: "linux" -*-
0ecfbf27
MP
2 *
3 * Copyright (C) 1996-2000 by Andrew Tridgell
4 * Copyright (C) Paul Mackerras 1996
5 * Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
c627d613 21
ac13ad10 22/**
0ecfbf27 23 * @file
ac13ad10
MP
24 *
25 * Utilities used in rsync
26 **/
c627d613 27
c627d613
AT
28#include "rsync.h"
29
c7c11a0d
DD
30extern int verbose;
31
0ecfbf27
MP
32int sanitize_paths = 0;
33
34
f0359dd0 35
ac13ad10 36/**
0ecfbf27
MP
37 * Set a fd into nonblocking mode
38 **/
f0359dd0
AT
39void set_nonblocking(int fd)
40{
41 int val;
42
0ecfbf27 43 if ((val = fcntl(fd, F_GETFL, 0)) == -1)
f0359dd0
AT
44 return;
45 if (!(val & NONBLOCK_FLAG)) {
46 val |= NONBLOCK_FLAG;
47 fcntl(fd, F_SETFL, val);
48 }
49}
50
ac13ad10 51/**
0ecfbf27
MP
52 * Set a fd into blocking mode
53 **/
36349ea0
AT
54void set_blocking(int fd)
55{
56 int val;
57
0ecfbf27 58 if ((val = fcntl(fd, F_GETFL, 0)) == -1)
36349ea0
AT
59 return;
60 if (val & NONBLOCK_FLAG) {
61 val &= ~NONBLOCK_FLAG;
62 fcntl(fd, F_SETFL, val);
63 }
64}
65
f0359dd0 66
ac13ad10 67/**
0ecfbf27
MP
68 * Create a file descriptor pair - like pipe() but use socketpair if
69 * possible (because of blocking issues on pipes).
70 *
71 * Always set non-blocking.
f0359dd0 72 */
08f15335
AT
73int fd_pair(int fd[2])
74{
f0359dd0
AT
75 int ret;
76
08f15335 77#if HAVE_SOCKETPAIR
f0359dd0 78 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
08f15335 79#else
f0359dd0 80 ret = pipe(fd);
08f15335 81#endif
f0359dd0
AT
82
83 if (ret == 0) {
84 set_nonblocking(fd[0]);
85 set_nonblocking(fd[1]);
86 }
0ecfbf27 87
f0359dd0 88 return ret;
08f15335
AT
89}
90
91
0ecfbf27 92void print_child_argv(char **cmd)
5ad0e46f 93{
1bbd10fe 94 rprintf(FINFO, "opening connection using ");
5ad0e46f
MP
95 for (; *cmd; cmd++) {
96 /* Look for characters that ought to be quoted. This
97 * is not a great quoting algorithm, but it's
98 * sufficient for a log message. */
99 if (strspn(*cmd, "abcdefghijklmnopqrstuvwxyz"
100 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
101 "0123456789"
102 ",.-_=+@/") != strlen(*cmd)) {
103 rprintf(FINFO, "\"%s\" ", *cmd);
104 } else {
105 rprintf(FINFO, "%s ", *cmd);
106 }
107 }
108 rprintf(FINFO, "\n");
109}
110
111
c627d613
AT
112void out_of_memory(char *str)
113{
9486289c 114 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
65417579 115 exit_cleanup(RERR_MALLOC);
575f2fca
AT
116}
117
118void overflow(char *str)
119{
9486289c 120 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
65417579 121 exit_cleanup(RERR_MALLOC);
c627d613
AT
122}
123
124
c627d613 125
404e813c 126int set_modtime(char *fname, time_t modtime)
c627d613 127{
31e12522 128 extern int dry_run;
404e813c
MP
129 if (dry_run)
130 return 0;
131
132 if (verbose > 2) {
133 rprintf(FINFO, "set modtime of %s to (%ld) %s",
134 fname, (long) modtime,
135 asctime(localtime(&modtime)));
136 }
137
31e12522 138 {
1e9f155a 139#ifdef HAVE_UTIMBUF
31e12522
AT
140 struct utimbuf tbuf;
141 tbuf.actime = time(NULL);
142 tbuf.modtime = modtime;
143 return utime(fname,&tbuf);
c627d613 144#elif defined(HAVE_UTIME)
31e12522
AT
145 time_t t[2];
146 t[0] = time(NULL);
147 t[1] = modtime;
148 return utime(fname,t);
c627d613 149#else
31e12522
AT
150 struct timeval t[2];
151 t[0].tv_sec = time(NULL);
152 t[0].tv_usec = 0;
153 t[1].tv_sec = modtime;
154 t[1].tv_usec = 0;
155 return utimes(fname,t);
c627d613 156#endif
31e12522 157 }
c627d613 158}
94481d91 159
720b47f2 160
ac13ad10
MP
161/**
162 Create any necessary directories in fname. Unfortunately we don't know
163 what perms to give the directory when this is called so we need to rely
164 on the umask
165**/
0ecfbf27 166int create_directory_path(char *fname, int base_umask)
6574b4f7 167{
6574b4f7
AT
168 char *p;
169
170 while (*fname == '/') fname++;
171 while (strncmp(fname,"./",2)==0) fname += 2;
172
173 p = fname;
174 while ((p=strchr(p,'/'))) {
175 *p = 0;
0ecfbf27 176 do_mkdir(fname, 0777 & ~base_umask);
6574b4f7
AT
177 *p = '/';
178 p++;
179 }
180 return 0;
181}
950ab32d
AT
182
183
ac13ad10
MP
184/**
185 * Write @p len bytes at @p ptr to descriptor @p desc, retrying if
186 * interrupted.
187 *
188 * @retval len upon success
189 *
190 * @retval <0 write's (negative) error code
191 *
192 * Derived from GNU C's cccp.c.
193 */
9dd891bb 194static int full_write(int desc, char *ptr, size_t len)
950ab32d
AT
195{
196 int total_written;
197
198 total_written = 0;
199 while (len > 0) {
200 int written = write (desc, ptr, len);
201 if (written < 0) {
202#ifdef EINTR
203 if (errno == EINTR)
204 continue;
205#endif
206 return written;
207 }
208 total_written += written;
209 ptr += written;
210 len -= written;
211 }
212 return total_written;
213}
214
950ab32d 215
ac13ad10
MP
216/**
217 * Read @p len bytes at @p ptr from descriptor @p desc, retrying if
218 * interrupted.
219 *
220 * @retval >0 the actual number of bytes read
221 *
222 * @retval 0 for EOF
223 *
224 * @retval <0 for an error.
225 *
226 * Derived from GNU C's cccp.c. */
9dd891bb 227static int safe_read(int desc, char *ptr, size_t len)
950ab32d
AT
228{
229 int n_chars;
230
9dd891bb 231 if (len == 0)
950ab32d
AT
232 return len;
233
234#ifdef EINTR
235 do {
236 n_chars = read(desc, ptr, len);
237 } while (n_chars < 0 && errno == EINTR);
238#else
239 n_chars = read(desc, ptr, len);
240#endif
241
242 return n_chars;
243}
244
245
ac13ad10
MP
246/** Copy a file.
247 *
248 * This is used in conjunction with the --temp-dir option */
950ab32d
AT
249int copy_file(char *source, char *dest, mode_t mode)
250{
251 int ifd;
252 int ofd;
253 char buf[1024 * 8];
254 int len; /* Number of bytes read into `buf'. */
255
8c9fd200 256 ifd = do_open(source, O_RDONLY, 0);
950ab32d 257 if (ifd == -1) {
9486289c 258 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
259 source,strerror(errno));
260 return -1;
261 }
262
c7c11a0d 263 if (robust_unlink(dest) && errno != ENOENT) {
9486289c 264 rprintf(FERROR,"unlink %s: %s\n",
950ab32d
AT
265 dest,strerror(errno));
266 return -1;
267 }
268
31e12522 269 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
c46ded46 270 if (ofd == -1) {
9486289c 271 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
272 dest,strerror(errno));
273 close(ifd);
274 return -1;
275 }
276
277 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
278 if (full_write(ofd, buf, len) < 0) {
9486289c 279 rprintf(FERROR,"write %s: %s\n",
950ab32d
AT
280 dest,strerror(errno));
281 close(ifd);
282 close(ofd);
283 return -1;
284 }
285 }
286
287 close(ifd);
288 close(ofd);
289
290 if (len < 0) {
9486289c 291 rprintf(FERROR,"read %s: %s\n",
950ab32d
AT
292 source,strerror(errno));
293 return -1;
294 }
295
296 return 0;
297}
feaa89c4 298
c7c11a0d
DD
299/* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
300#define MAX_RENAMES_DIGITS 3
301#define MAX_RENAMES 1000
302
ac13ad10 303/**
b4235b31
MP
304 * Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
305 * rename to <path>/.rsyncNNN instead.
306 *
307 * Note that successive rsync runs will shuffle the filenames around a
308 * bit as long as the file is still busy; this is because this function
309 * does not know if the unlink call is due to a new file coming in, or
310 * --delete trying to remove old .rsyncNNN files, hence it renames it
311 * each time.
312 **/
c7c11a0d
DD
313int robust_unlink(char *fname)
314{
315#ifndef ETXTBSY
316 return do_unlink(fname);
317#else
318 static int counter = 1;
319 int rc, pos, start;
320 char path[MAXPATHLEN];
321
322 rc = do_unlink(fname);
323 if ((rc == 0) || (errno != ETXTBSY))
324 return rc;
325
326 strlcpy(path, fname, MAXPATHLEN);
327
328 pos = strlen(path);
329 while((path[--pos] != '/') && (pos >= 0))
330 ;
331 ++pos;
332 strlcpy(&path[pos], ".rsync", MAXPATHLEN-pos);
333 pos += sizeof(".rsync")-1;
334
335 if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
336 errno = ETXTBSY;
337 return -1;
338 }
339
340 /* start where the last one left off to reduce chance of clashes */
341 start = counter;
342 do {
343 sprintf(&path[pos], "%03d", counter);
344 if (++counter >= MAX_RENAMES)
345 counter = 1;
346 } while (((rc = access(path, 0)) == 0) && (counter != start));
347
4791825d 348 if (verbose > 0) {
c7c11a0d 349 rprintf(FINFO,"renaming %s to %s because of text busy\n",
4791825d
WD
350 fname, path);
351 }
c7c11a0d
DD
352
353 /* maybe we should return rename()'s exit status? Nah. */
354 if (do_rename(fname, path) != 0) {
355 errno = ETXTBSY;
356 return -1;
357 }
358 return 0;
359#endif
360}
361
362int robust_rename(char *from, char *to)
363{
364#ifndef ETXTBSY
365 return do_rename(from, to);
366#else
367 int rc = do_rename(from, to);
368 if ((rc == 0) || (errno != ETXTBSY))
369 return rc;
370 if (robust_unlink(to) != 0)
371 return -1;
372 return do_rename(from, to);
373#endif
feaa89c4 374}
3ba62a83
AT
375
376
377static pid_t all_pids[10];
378static int num_pids;
379
4cf64834 380/** Fork and record the pid of the child. **/
3ba62a83
AT
381pid_t do_fork(void)
382{
383 pid_t newpid = fork();
384
4cf64834 385 if (newpid != 0 && newpid != -1) {
3ba62a83
AT
386 all_pids[num_pids++] = newpid;
387 }
388 return newpid;
389}
390
4cf64834
MP
391/**
392 * Kill all children.
393 *
394 * @todo It would be kind of nice to make sure that they are actually
395 * all our children before we kill them, because their pids may have
396 * been recycled by some other process. Perhaps when we wait for a
397 * child, we should remove it from this array. Alternatively we could
398 * perhaps use process groups, but I think that would not work on
399 * ancient Unix versions that don't support them.
400 **/
3ba62a83
AT
401void kill_all(int sig)
402{
403 int i;
4cf64834
MP
404
405 for (i = 0; i < num_pids; i++) {
406 /* Let's just be a little careful where we
407 * point that gun, hey? See kill(2) for the
408 * magic caused by negative values. */
409 pid_t p = all_pids[i];
410
411 if (p == getpid())
412 continue;
413 if (p <= 0)
414 continue;
415
416 kill(p, sig);
3ba62a83
AT
417 }
418}
9486289c 419
4cf64834 420
ac13ad10 421/** Turn a user name into a uid */
8ef4ffd6
AT
422int name_to_uid(char *name, uid_t *uid)
423{
424 struct passwd *pass;
425 if (!name || !*name) return 0;
426 pass = getpwnam(name);
427 if (pass) {
428 *uid = pass->pw_uid;
429 return 1;
430 }
431 return 0;
432}
433
ac13ad10 434/** Turn a group name into a gid */
8ef4ffd6
AT
435int name_to_gid(char *name, gid_t *gid)
436{
437 struct group *grp;
438 if (!name || !*name) return 0;
439 grp = getgrnam(name);
440 if (grp) {
441 *gid = grp->gr_gid;
442 return 1;
443 }
444 return 0;
445}
446
ff8b29b8 447
ac13ad10 448/** Lock a byte range in a open file */
31593dd6 449int lock_range(int fd, int offset, int len)
0c515f17 450{
31593dd6 451 struct flock lock;
0c515f17 452
31593dd6
AT
453 lock.l_type = F_WRLCK;
454 lock.l_whence = SEEK_SET;
455 lock.l_start = offset;
456 lock.l_len = len;
457 lock.l_pid = 0;
458
459 return fcntl(fd,F_SETLK,&lock) == 0;
0c515f17 460}
874895d5 461
4791825d
WD
462static int exclude_server_path(char *arg)
463{
464 char *s;
465 extern struct exclude_struct **server_exclude_list;
466
467 if (server_exclude_list) {
468 for (s = arg; (s = strchr(s, '/')) != NULL; ) {
469 *s = '\0';
470 if (check_exclude(server_exclude_list, arg, 1)) {
471 /* We must leave arg truncated! */
472 return 1;
473 }
474 *s++ = '/';
475 }
476 }
477 return 0;
478}
874895d5 479
cb13abfe 480static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
874895d5 481{
932be9aa 482#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
e42c9458 483 if (!*s) s = ".";
4791825d
WD
484 s = argv[*argc] = strdup(s);
485 exclude_server_path(s);
874895d5 486 (*argc)++;
874895d5 487#else
cb13abfe 488 extern int sanitize_paths;
874895d5
AT
489 glob_t globbuf;
490 int i;
491
e42c9458
AT
492 if (!*s) s = ".";
493
4791825d 494 s = argv[*argc] = strdup(s);
cb13abfe 495 if (sanitize_paths) {
4791825d 496 sanitize_path(s, NULL);
cb13abfe 497 }
087bf010 498
874895d5 499 memset(&globbuf, 0, sizeof(globbuf));
4791825d
WD
500 if (!exclude_server_path(s))
501 glob(s, 0, NULL, &globbuf);
874895d5
AT
502 if (globbuf.gl_pathc == 0) {
503 (*argc)++;
504 globfree(&globbuf);
505 return;
506 }
a261989c 507 for (i=0; i<(maxargs - (*argc)) && i < (int) globbuf.gl_pathc;i++) {
4791825d 508 if (i == 0) free(s);
874895d5
AT
509 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
510 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
511 }
512 globfree(&globbuf);
513 (*argc) += i;
514#endif
515}
5a96ee05 516
4791825d 517/* This routine is only used in daemon mode. */
cb13abfe 518void glob_expand(char *base1, char **argv, int *argc, int maxargs)
087bf010
AT
519{
520 char *s = argv[*argc];
521 char *p, *q;
ba5e128d 522 char *base = base1;
4791825d 523 int base_len = strlen(base);
087bf010
AT
524
525 if (!s || !*s) return;
526
4791825d
WD
527 if (strncmp(s, base, base_len) == 0)
528 s += base_len;
e42c9458 529
087bf010
AT
530 s = strdup(s);
531 if (!s) out_of_memory("glob_expand");
532
8950ac03 533 if (asprintf(&base," %s/", base1) <= 0) out_of_memory("glob_expand");
4791825d 534 base_len++;
ba5e128d 535
087bf010
AT
536 q = s;
537 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
ba5e128d
AT
538 /* split it at this point */
539 *p = 0;
cb13abfe 540 glob_expand_one(q, argv, argc, maxargs);
4791825d 541 q = p + base_len;
087bf010
AT
542 }
543
cb13abfe 544 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
087bf010
AT
545
546 free(s);
ba5e128d 547 free(base);
087bf010 548}
5a96ee05 549
ac13ad10
MP
550/**
551 * Convert a string to lower case
552 **/
5a96ee05
AT
553void strlower(char *s)
554{
555 while (*s) {
32f76175
MP
556 if (isupper(* (unsigned char *) s))
557 *s = tolower(* (unsigned char *) s);
5a96ee05
AT
558 s++;
559 }
560}
e42c9458 561
fe8c0a98
AT
562void *Realloc(void *p, int size)
563{
564 if (!p) return (void *)malloc(size);
565 return (void *)realloc(p, size);
566}
5243c216
AT
567
568
569void clean_fname(char *name)
570{
571 char *p;
572 int l;
573 int modified = 1;
574
575 if (!name) return;
576
577 while (modified) {
578 modified = 0;
579
580 if ((p=strstr(name,"/./"))) {
581 modified = 1;
582 while (*p) {
583 p[0] = p[2];
584 p++;
585 }
586 }
587
588 if ((p=strstr(name,"//"))) {
589 modified = 1;
590 while (*p) {
591 p[0] = p[1];
592 p++;
593 }
594 }
595
596 if (strncmp(p=name,"./",2) == 0) {
597 modified = 1;
598 do {
599 p[0] = p[2];
600 } while (*p++);
601 }
602
603 l = strlen(p=name);
604 if (l > 1 && p[l-1] == '/') {
605 modified = 1;
606 p[l-1] = 0;
607 }
608 }
609}
610
ac13ad10 611/**
1b8e662a 612 * Make path appear as if a chroot had occurred:
ac13ad10 613 *
b4235b31
MP
614 * @li 1. remove leading "/" (or replace with "." if at end)
615 *
616 * @li 2. remove leading ".." components (except those allowed by @p reldir)
617 *
618 * @li 3. delete any other "<dir>/.." (recursively)
ac13ad10 619 *
79452d46 620 * Can only shrink paths, so sanitizes in place.
ac13ad10 621 *
b5f9e67d 622 * While we're at it, remove double slashes and "." components like
b4235b31 623 * clean_fname() does, but DON'T remove a trailing slash because that
b5f9e67d 624 * is sometimes significant on command line arguments.
ac13ad10 625 *
b4235b31 626 * If @p reldir is non-null, it is a sanitized directory that the path will be
79452d46
DD
627 * relative to, so allow as many ".." at the beginning of the path as
628 * there are components in reldir. This is used for symbolic link targets.
629 * If reldir is non-null and the path began with "/", to be completely like
630 * a chroot we should add in depth levels of ".." at the beginning of the
631 * path, but that would blow the assumption that the path doesn't grow and
632 * it is not likely to end up being a valid symlink anyway, so just do
633 * the normal removal of the leading "/" instead.
ac13ad10 634 *
1b8e662a
DD
635 * Contributed by Dave Dykstra <dwd@bell-labs.com>
636 */
cb13abfe 637void sanitize_path(char *p, char *reldir)
1b8e662a 638{
44e2e578 639 char *start, *sanp;
cb13abfe
DD
640 int depth = 0;
641 int allowdotdot = 0;
642
643 if (reldir) {
644 depth++;
645 while (*reldir) {
646 if (*reldir++ == '/') {
647 depth++;
648 }
649 }
650 }
44e2e578
DD
651 start = p;
652 sanp = p;
b5f9e67d
DD
653 while (*p == '/') {
654 /* remove leading slashes */
655 p++;
656 }
1b8e662a 657 while (*p != '\0') {
b5f9e67d 658 /* this loop iterates once per filename component in p.
44e2e578 659 * both p (and sanp if the original had a slash) should
b5f9e67d
DD
660 * always be left pointing after a slash
661 */
662 if ((*p == '.') && ((*(p+1) == '/') || (*(p+1) == '\0'))) {
663 /* skip "." component */
664 while (*++p == '/') {
665 /* skip following slashes */
666 ;
667 }
cb13abfe
DD
668 continue;
669 }
670 allowdotdot = 0;
671 if ((*p == '.') && (*(p+1) == '.') &&
4791825d 672 ((*(p+2) == '/') || (*(p+2) == '\0'))) {
cb13abfe
DD
673 /* ".." component followed by slash or end */
674 if ((depth > 0) && (sanp == start)) {
675 /* allow depth levels of .. at the beginning */
676 --depth;
677 allowdotdot = 1;
678 } else {
679 p += 2;
680 if (*p == '/')
681 p++;
682 if (sanp != start) {
683 /* back up sanp one level */
684 --sanp; /* now pointing at slash */
685 while ((sanp > start) && (*(sanp - 1) != '/')) {
686 /* skip back up to slash */
687 sanp--;
688 }
b5f9e67d 689 }
cb13abfe 690 continue;
1b8e662a 691 }
cb13abfe
DD
692 }
693 while (1) {
694 /* copy one component through next slash */
695 *sanp++ = *p++;
696 if ((*p == '\0') || (*(p-1) == '/')) {
697 while (*p == '/') {
698 /* skip multiple slashes */
699 p++;
b5f9e67d 700 }
cb13abfe 701 break;
1b8e662a
DD
702 }
703 }
cb13abfe
DD
704 if (allowdotdot) {
705 /* move the virtual beginning to leave the .. alone */
706 start = sanp;
707 }
1b8e662a 708 }
cb13abfe 709 if ((sanp == start) && !allowdotdot) {
b5f9e67d 710 /* ended up with nothing, so put in "." component */
79452d46
DD
711 /*
712 * note that the !allowdotdot doesn't prevent this from
713 * happening in all allowed ".." situations, but I didn't
714 * think it was worth putting in an extra variable to ensure
715 * it since an extra "." won't hurt in those situations.
716 */
44e2e578 717 *sanp++ = '.';
b5f9e67d 718 }
44e2e578 719 *sanp = '\0';
1b8e662a
DD
720}
721
5243c216 722
4791825d 723char curr_dir[MAXPATHLEN];
5243c216 724
4e5db0ad
MP
725/**
726 * Like chdir() but can be reversed with pop_dir() if @p save is set.
727 * It is also much faster as it remembers where we have been.
728 **/
5243c216
AT
729char *push_dir(char *dir, int save)
730{
731 char *ret = curr_dir;
732 static int initialised;
733
734 if (!initialised) {
735 initialised = 1;
736 getcwd(curr_dir, sizeof(curr_dir)-1);
737 }
738
c226b7c2
DD
739 if (!dir) return NULL; /* this call was probably just to initialize */
740
5243c216
AT
741 if (chdir(dir)) return NULL;
742
743 if (save) {
744 ret = strdup(curr_dir);
745 }
746
747 if (*dir == '/') {
37f9805d 748 strlcpy(curr_dir, dir, sizeof(curr_dir));
4791825d 749 } else if (dir[0] != '.' || dir[1] != '\0') {
37f9805d
AT
750 strlcat(curr_dir,"/", sizeof(curr_dir));
751 strlcat(curr_dir,dir, sizeof(curr_dir));
5243c216
AT
752 }
753
754 clean_fname(curr_dir);
755
756 return ret;
757}
758
4e5db0ad 759/** Reverse a push_dir() call */
5243c216
AT
760int pop_dir(char *dir)
761{
762 int ret;
763
764 ret = chdir(dir);
765 if (ret) {
766 free(dir);
767 return ret;
768 }
769
37f9805d 770 strlcpy(curr_dir, dir, sizeof(curr_dir));
5243c216
AT
771
772 free(dir);
773
774 return 0;
775}
aa9b77a5 776
eb61be19
WD
777/**
778 * Return a quoted string with the full pathname of the indicated filename.
779 * The string " (in MODNAME)" may also be appended. The returned pointer
780 * remains valid until the next time full_fname() is called.
781 **/
782char *full_fname(char *fn)
783{
784 extern int module_id;
785 static char *result = NULL;
786 char *m1, *m2, *m3;
787 char *p1, *p2;
788
789 if (result)
790 free(result);
791
792 if (*fn == '/')
793 p1 = p2 = "";
794 else {
795 p1 = curr_dir;
796 p2 = "/";
797 }
798 if (module_id >= 0) {
799 m1 = " (in ";
800 m2 = lp_name(module_id);
801 m3 = ")";
802 if (*p1) {
803 if (!lp_use_chroot(module_id)) {
804 char *p = lp_path(module_id);
805 if (*p != '/' || p[1])
806 p1 += strlen(p);
807 }
808 if (!*p1)
809 p2++;
810 else
811 p1++;
812 }
813 else
814 fn++;
815 } else
816 m1 = m2 = m3 = "";
817
818 asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
819
820 return result;
821}
822
ac13ad10 823/** We need to supply our own strcmp function for file list comparisons
aa9b77a5
AT
824 to ensure that signed/unsigned usage is consistent between machines. */
825int u_strcmp(const char *cs1, const char *cs2)
826{
5a788ade
AT
827 const uchar *s1 = (const uchar *)cs1;
828 const uchar *s2 = (const uchar *)cs2;
aa9b77a5
AT
829
830 while (*s1 && *s2 && (*s1 == *s2)) {
831 s1++; s2++;
832 }
833
834 return (int)*s1 - (int)*s2;
835}
eb86d661 836
4b957c22 837
ac13ad10
MP
838
839/**
840 * Determine if a symlink points outside the current directory tree.
036e70b0
MP
841 * This is considered "unsafe" because e.g. when mirroring somebody
842 * else's machine it might allow them to establish a symlink to
843 * /etc/passwd, and then read it through a web server.
844 *
4e5db0ad
MP
845 * Null symlinks and absolute symlinks are always unsafe.
846 *
847 * Basically here we are concerned with symlinks whose target contains
848 * "..", because this might cause us to walk back up out of the
849 * transferred directory. We are not allowed to go back up and
850 * reenter.
851 *
036e70b0
MP
852 * @param dest Target of the symlink in question.
853 *
25d34a5c 854 * @param src Top source directory currently applicable. Basically this
036e70b0 855 * is the first parameter to rsync in a simple invocation, but it's
25d34a5c 856 * modified by flist.c in slightly complex ways.
036e70b0
MP
857 *
858 * @retval True if unsafe
859 * @retval False is unsafe
4e5db0ad
MP
860 *
861 * @sa t_unsafe.c
ac13ad10 862 **/
7afa3a4a 863int unsafe_symlink(const char *dest, const char *src)
4b957c22 864{
7afa3a4a 865 const char *name, *slash;
4b957c22
AT
866 int depth = 0;
867
868 /* all absolute and null symlinks are unsafe */
7afa3a4a 869 if (!dest || !*dest || *dest == '/') return 1;
4b957c22
AT
870
871 /* find out what our safety margin is */
7afa3a4a
WD
872 for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
873 if (strncmp(name, "../", 3) == 0) {
4b957c22 874 depth=0;
7afa3a4a 875 } else if (strncmp(name, "./", 2) == 0) {
4b957c22
AT
876 /* nothing */
877 } else {
878 depth++;
879 }
880 }
7afa3a4a
WD
881 if (strcmp(name, "..") == 0)
882 depth = 0;
4b957c22 883
7afa3a4a
WD
884 for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
885 if (strncmp(name, "../", 3) == 0) {
886 /* if at any point we go outside the current directory
887 then stop - it is unsafe */
888 if (--depth < 0)
889 return 1;
890 } else if (strncmp(name, "./", 2) == 0) {
4b957c22
AT
891 /* nothing */
892 } else {
893 depth++;
894 }
4b957c22 895 }
7afa3a4a
WD
896 if (strcmp(name, "..") == 0)
897 depth--;
4b957c22 898
4b957c22
AT
899 return (depth < 0);
900}
375a4556 901
f7632fc6 902
ac13ad10 903/**
b4235b31
MP
904 * Return the date and time as a string
905 **/
f7632fc6
AT
906char *timestring(time_t t)
907{
908 static char TimeBuf[200];
909 struct tm *tm = localtime(&t);
910
911#ifdef HAVE_STRFTIME
912 strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
913#else
37f9805d 914 strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf));
f7632fc6
AT
915#endif
916
917 if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
918 TimeBuf[strlen(TimeBuf)-1] = 0;
919 }
920
921 return(TimeBuf);
922}
923
9ec16c83 924
e1bd49d6
MP
925/**
926 * Sleep for a specified number of milliseconds.
927 *
928 * Always returns TRUE. (In the future it might return FALSE if
929 * interrupted.)
930 **/
931int msleep(int t)
9ec16c83
AT
932{
933 int tdiff=0;
934 struct timeval tval,t1,t2;
935
936 gettimeofday(&t1, NULL);
937 gettimeofday(&t2, NULL);
938
939 while (tdiff < t) {
940 tval.tv_sec = (t-tdiff)/1000;
941 tval.tv_usec = 1000*((t-tdiff)%1000);
942
943 errno = 0;
944 select(0,NULL,NULL, NULL, &tval);
945
946 gettimeofday(&t2, NULL);
947 tdiff = (t2.tv_sec - t1.tv_sec)*1000 +
948 (t2.tv_usec - t1.tv_usec)/1000;
949 }
e1bd49d6
MP
950
951 return True;
9ec16c83
AT
952}
953
954
ac13ad10
MP
955/**
956 * Determine if two file modification times are equivalent (either
957 * exact or in the modification timestamp window established by
958 * --modify-window).
959 *
960 * @retval 0 if the times should be treated as the same
961 *
962 * @retval +1 if the first is later
963 *
964 * @retval -1 if the 2nd is later
965 **/
5b56cc19
AT
966int cmp_modtime(time_t file1, time_t file2)
967{
5b56cc19
AT
968 extern int modify_window;
969
970 if (file2 > file1) {
971 if (file2 - file1 <= modify_window) return 0;
972 return -1;
973 }
974 if (file1 - file2 <= modify_window) return 0;
975 return 1;
976}
977
978
979#ifdef __INSURE__XX
0f8f98c8
AT
980#include <dlfcn.h>
981
ac13ad10
MP
982/**
983 This routine is a trick to immediately catch errors when debugging
984 with insure. A xterm with a gdb is popped up when insure catches
985 a error. It is Linux specific.
986**/
0f8f98c8
AT
987int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
988{
989 static int (*fn)();
990 int ret;
8950ac03 991 char *cmd;
0f8f98c8 992
8950ac03 993 asprintf(&cmd, "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'",
0f8f98c8
AT
994 getpid(), getpid(), getpid());
995
996 if (!fn) {
997 static void *h;
998 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
999 fn = dlsym(h, "_Insure_trap_error");
1000 }
1001
1002 ret = fn(a1, a2, a3, a4, a5, a6);
1003
1004 system(cmd);
1005
8950ac03
AT
1006 free(cmd);
1007
0f8f98c8
AT
1008 return ret;
1009}
1010#endif