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