Last of the cleanup before the patching starts.
[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
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).
5cb37436 70 *
0ecfbf27 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{
c284f34a
WD
114 rprintf(FERROR, "ERROR: out of memory in %s\n", str);
115 exit_cleanup(RERR_MALLOC);
575f2fca
AT
116}
117
118void overflow(char *str)
119{
c284f34a
WD
120 rprintf(FERROR, "ERROR: buffer overflow in %s\n", str);
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 }
5cb37436 137
31e12522 138 {
1e9f155a 139#ifdef HAVE_UTIMBUF
5cb37436 140 struct utimbuf tbuf;
31e12522
AT
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
c284f34a
WD
170 while (*fname == '/')
171 fname++;
172 while (strncmp(fname, "./", 2) == 0)
173 fname += 2;
6574b4f7
AT
174
175 p = fname;
c284f34a 176 while ((p = strchr(p,'/')) != NULL) {
6574b4f7 177 *p = 0;
5cb37436 178 do_mkdir(fname, 0777 & ~base_umask);
6574b4f7
AT
179 *p = '/';
180 p++;
181 }
182 return 0;
183}
950ab32d
AT
184
185
ac13ad10
MP
186/**
187 * Write @p len bytes at @p ptr to descriptor @p desc, retrying if
188 * interrupted.
189 *
190 * @retval len upon success
191 *
192 * @retval <0 write's (negative) error code
193 *
194 * Derived from GNU C's cccp.c.
195 */
9dd891bb 196static int full_write(int desc, char *ptr, size_t len)
950ab32d
AT
197{
198 int total_written;
5cb37436 199
950ab32d
AT
200 total_written = 0;
201 while (len > 0) {
5c1b7bfd 202 int written = write(desc, ptr, len);
950ab32d 203 if (written < 0) {
950ab32d
AT
204 if (errno == EINTR)
205 continue;
950ab32d
AT
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;
5cb37436 230
9dd891bb 231 if (len == 0)
950ab32d 232 return len;
5cb37436 233
950ab32d
AT
234 do {
235 n_chars = read(desc, ptr, len);
236 } while (n_chars < 0 && errno == EINTR);
5cb37436 237
950ab32d
AT
238 return n_chars;
239}
240
241
ac13ad10
MP
242/** Copy a file.
243 *
244 * This is used in conjunction with the --temp-dir option */
950ab32d
AT
245int copy_file(char *source, char *dest, mode_t mode)
246{
247 int ifd;
248 int ofd;
249 char buf[1024 * 8];
250 int len; /* Number of bytes read into `buf'. */
251
8c9fd200 252 ifd = do_open(source, O_RDONLY, 0);
950ab32d 253 if (ifd == -1) {
9486289c 254 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
255 source,strerror(errno));
256 return -1;
257 }
258
c7c11a0d 259 if (robust_unlink(dest) && errno != ENOENT) {
9486289c 260 rprintf(FERROR,"unlink %s: %s\n",
950ab32d
AT
261 dest,strerror(errno));
262 return -1;
263 }
264
31e12522 265 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
c46ded46 266 if (ofd == -1) {
9486289c 267 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
268 dest,strerror(errno));
269 close(ifd);
270 return -1;
271 }
272
5cb37436 273 while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
950ab32d 274 if (full_write(ofd, buf, len) < 0) {
9486289c 275 rprintf(FERROR,"write %s: %s\n",
950ab32d
AT
276 dest,strerror(errno));
277 close(ifd);
278 close(ofd);
279 return -1;
280 }
281 }
282
283 close(ifd);
284 close(ofd);
285
286 if (len < 0) {
9486289c 287 rprintf(FERROR,"read %s: %s\n",
950ab32d
AT
288 source,strerror(errno));
289 return -1;
290 }
291
292 return 0;
293}
feaa89c4 294
c7c11a0d
DD
295/* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
296#define MAX_RENAMES_DIGITS 3
297#define MAX_RENAMES 1000
298
ac13ad10 299/**
b4235b31
MP
300 * Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
301 * rename to <path>/.rsyncNNN instead.
302 *
303 * Note that successive rsync runs will shuffle the filenames around a
304 * bit as long as the file is still busy; this is because this function
305 * does not know if the unlink call is due to a new file coming in, or
306 * --delete trying to remove old .rsyncNNN files, hence it renames it
307 * each time.
308 **/
c7c11a0d
DD
309int robust_unlink(char *fname)
310{
311#ifndef ETXTBSY
312 return do_unlink(fname);
313#else
314 static int counter = 1;
315 int rc, pos, start;
316 char path[MAXPATHLEN];
317
318 rc = do_unlink(fname);
c284f34a 319 if (rc == 0 || errno != ETXTBSY)
c7c11a0d
DD
320 return rc;
321
c284f34a
WD
322 if ((pos = strlcpy(path, fname, MAXPATHLEN)) >= MAXPATHLEN)
323 pos = MAXPATHLEN - 1;
c7c11a0d 324
c284f34a
WD
325 while (pos > 0 && path[pos-1] != '/')
326 pos--;
5cb37436 327 pos += strlcpy(path+pos, ".rsync", MAXPATHLEN-pos);
c7c11a0d
DD
328
329 if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
330 errno = ETXTBSY;
331 return -1;
332 }
333
334 /* start where the last one left off to reduce chance of clashes */
335 start = counter;
336 do {
337 sprintf(&path[pos], "%03d", counter);
338 if (++counter >= MAX_RENAMES)
339 counter = 1;
c284f34a 340 } while ((rc = access(path, 0)) == 0 && counter != start);
c7c11a0d 341
4791825d 342 if (verbose > 0) {
c7c11a0d 343 rprintf(FINFO,"renaming %s to %s because of text busy\n",
4791825d
WD
344 fname, path);
345 }
c7c11a0d
DD
346
347 /* maybe we should return rename()'s exit status? Nah. */
348 if (do_rename(fname, path) != 0) {
349 errno = ETXTBSY;
350 return -1;
351 }
352 return 0;
353#endif
354}
355
62c9e6b3
WD
356/* Returns 0 on success, -1 on most errors, and -2 if we got an error
357 * trying to copy the file across file systems. */
358int robust_rename(char *from, char *to, int mode)
c7c11a0d 359{
62c9e6b3
WD
360 int tries = 4;
361
362 while (tries--) {
363 if (do_rename(from, to) == 0)
364 return 0;
365
366 switch (errno) {
367#ifdef ETXTBSY
368 case ETXTBSY:
369 if (robust_unlink(to) != 0)
370 return -1;
371 break;
c7c11a0d 372#endif
62c9e6b3
WD
373 case EXDEV:
374 if (copy_file(from, to, mode) != 0)
375 return -2;
376 do_unlink(from);
377 return 0;
378 default:
379 return -1;
380 }
381 }
382 return -1;
feaa89c4 383}
3ba62a83
AT
384
385
386static pid_t all_pids[10];
387static int num_pids;
388
4cf64834 389/** Fork and record the pid of the child. **/
3ba62a83
AT
390pid_t do_fork(void)
391{
392 pid_t newpid = fork();
5cb37436 393
4cf64834 394 if (newpid != 0 && newpid != -1) {
3ba62a83
AT
395 all_pids[num_pids++] = newpid;
396 }
397 return newpid;
398}
399
4cf64834
MP
400/**
401 * Kill all children.
402 *
403 * @todo It would be kind of nice to make sure that they are actually
404 * all our children before we kill them, because their pids may have
405 * been recycled by some other process. Perhaps when we wait for a
406 * child, we should remove it from this array. Alternatively we could
407 * perhaps use process groups, but I think that would not work on
408 * ancient Unix versions that don't support them.
409 **/
3ba62a83
AT
410void kill_all(int sig)
411{
412 int i;
4cf64834
MP
413
414 for (i = 0; i < num_pids; i++) {
415 /* Let's just be a little careful where we
416 * point that gun, hey? See kill(2) for the
417 * magic caused by negative values. */
418 pid_t p = all_pids[i];
419
420 if (p == getpid())
421 continue;
422 if (p <= 0)
423 continue;
424
425 kill(p, sig);
3ba62a83
AT
426 }
427}
9486289c 428
4cf64834 429
ac13ad10 430/** Turn a user name into a uid */
8ef4ffd6
AT
431int name_to_uid(char *name, uid_t *uid)
432{
433 struct passwd *pass;
434 if (!name || !*name) return 0;
435 pass = getpwnam(name);
436 if (pass) {
437 *uid = pass->pw_uid;
438 return 1;
439 }
440 return 0;
441}
442
ac13ad10 443/** Turn a group name into a gid */
8ef4ffd6
AT
444int name_to_gid(char *name, gid_t *gid)
445{
446 struct group *grp;
447 if (!name || !*name) return 0;
448 grp = getgrnam(name);
449 if (grp) {
450 *gid = grp->gr_gid;
451 return 1;
452 }
453 return 0;
454}
455
ff8b29b8 456
ac13ad10 457/** Lock a byte range in a open file */
31593dd6 458int lock_range(int fd, int offset, int len)
0c515f17 459{
31593dd6 460 struct flock lock;
0c515f17 461
31593dd6
AT
462 lock.l_type = F_WRLCK;
463 lock.l_whence = SEEK_SET;
464 lock.l_start = offset;
465 lock.l_len = len;
466 lock.l_pid = 0;
5cb37436 467
31593dd6 468 return fcntl(fd,F_SETLK,&lock) == 0;
0c515f17 469}
874895d5 470
4791825d
WD
471static int exclude_server_path(char *arg)
472{
473 char *s;
474 extern struct exclude_struct **server_exclude_list;
475
476 if (server_exclude_list) {
477 for (s = arg; (s = strchr(s, '/')) != NULL; ) {
478 *s = '\0';
479 if (check_exclude(server_exclude_list, arg, 1)) {
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
788 if (*path == '/' && rootdir)
789 rlen = strlen(rootdir);
790 else
791 rlen = 0;
792 if (!(buf = new_array(char, rlen + plen + 1)))
793 out_of_memory("alloc_sanitize_path");
794 if (rlen)
795 memcpy(buf, rootdir, rlen);
796 memcpy(buf + rlen, path, plen + 1);
797
798 if (rlen)
799 rlen++;
800 sanitize_path(buf + rlen, NULL);
801 if (rlen && buf[rlen] == '.' && buf[rlen+1] == '\0')
802 buf[rlen-1] = '\0';
803
804 return buf;
805}
5243c216 806
4791825d 807char curr_dir[MAXPATHLEN];
4af8fe4e 808unsigned int curr_dir_len;
5243c216 809
4e5db0ad 810/**
a16d8f2b
WD
811 * Like chdir(), but it keeps track of the current directory (in the
812 * global "curr_dir"), and ensures that the path size doesn't overflow.
813 * Also cleans the path using the clean_fname() function.
4e5db0ad 814 **/
4af8fe4e 815int push_dir(char *dir)
5243c216 816{
5243c216 817 static int initialised;
4af8fe4e 818 unsigned int len;
5243c216
AT
819
820 if (!initialised) {
821 initialised = 1;
5cb37436 822 getcwd(curr_dir, sizeof curr_dir - 1);
4af8fe4e 823 curr_dir_len = strlen(curr_dir);
5243c216
AT
824 }
825
4af8fe4e
WD
826 if (!dir) /* this call was probably just to initialize */
827 return 0;
c226b7c2 828
4af8fe4e
WD
829 len = strlen(dir);
830 if (len == 1 && *dir == '.')
831 return 1;
5243c216 832
4af8fe4e
WD
833 if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir)
834 return 0;
835
836 if (chdir(dir))
837 return 0;
5243c216
AT
838
839 if (*dir == '/') {
4af8fe4e
WD
840 memcpy(curr_dir, dir, len + 1);
841 curr_dir_len = len;
842 } else {
843 curr_dir[curr_dir_len++] = '/';
844 memcpy(curr_dir + curr_dir_len, dir, len + 1);
845 curr_dir_len += len;
5243c216
AT
846 }
847
848 clean_fname(curr_dir);
849
4af8fe4e 850 return 1;
5243c216
AT
851}
852
a16d8f2b
WD
853/**
854 * Reverse a push_dir() call. You must pass in an absolute path
855 * that was copied from a prior value of "curr_dir".
856 **/
5243c216
AT
857int pop_dir(char *dir)
858{
4af8fe4e
WD
859 if (chdir(dir))
860 return 0;
5243c216 861
4af8fe4e
WD
862 curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir);
863 if (curr_dir_len >= sizeof curr_dir)
864 curr_dir_len = sizeof curr_dir - 1;
5243c216 865
4af8fe4e 866 return 1;
5243c216 867}
aa9b77a5 868
eb61be19
WD
869/**
870 * Return a quoted string with the full pathname of the indicated filename.
871 * The string " (in MODNAME)" may also be appended. The returned pointer
872 * remains valid until the next time full_fname() is called.
873 **/
874char *full_fname(char *fn)
875{
876 extern int module_id;
877 static char *result = NULL;
878 char *m1, *m2, *m3;
879 char *p1, *p2;
880
881 if (result)
882 free(result);
883
884 if (*fn == '/')
885 p1 = p2 = "";
886 else {
887 p1 = curr_dir;
888 p2 = "/";
889 }
890 if (module_id >= 0) {
891 m1 = " (in ";
892 m2 = lp_name(module_id);
893 m3 = ")";
894 if (*p1) {
895 if (!lp_use_chroot(module_id)) {
896 char *p = lp_path(module_id);
897 if (*p != '/' || p[1])
898 p1 += strlen(p);
899 }
900 if (!*p1)
901 p2++;
902 else
903 p1++;
904 }
905 else
906 fn++;
907 } else
908 m1 = m2 = m3 = "";
909
910 asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
911
912 return result;
913}
914
ac13ad10 915/** We need to supply our own strcmp function for file list comparisons
aa9b77a5
AT
916 to ensure that signed/unsigned usage is consistent between machines. */
917int u_strcmp(const char *cs1, const char *cs2)
918{
5a788ade
AT
919 const uchar *s1 = (const uchar *)cs1;
920 const uchar *s2 = (const uchar *)cs2;
aa9b77a5
AT
921
922 while (*s1 && *s2 && (*s1 == *s2)) {
923 s1++; s2++;
924 }
5cb37436 925
aa9b77a5
AT
926 return (int)*s1 - (int)*s2;
927}
eb86d661 928
4b957c22 929
ac13ad10
MP
930
931/**
932 * Determine if a symlink points outside the current directory tree.
036e70b0
MP
933 * This is considered "unsafe" because e.g. when mirroring somebody
934 * else's machine it might allow them to establish a symlink to
935 * /etc/passwd, and then read it through a web server.
936 *
4e5db0ad
MP
937 * Null symlinks and absolute symlinks are always unsafe.
938 *
939 * Basically here we are concerned with symlinks whose target contains
940 * "..", because this might cause us to walk back up out of the
941 * transferred directory. We are not allowed to go back up and
942 * reenter.
943 *
036e70b0
MP
944 * @param dest Target of the symlink in question.
945 *
25d34a5c 946 * @param src Top source directory currently applicable. Basically this
036e70b0 947 * is the first parameter to rsync in a simple invocation, but it's
25d34a5c 948 * modified by flist.c in slightly complex ways.
036e70b0
MP
949 *
950 * @retval True if unsafe
951 * @retval False is unsafe
4e5db0ad
MP
952 *
953 * @sa t_unsafe.c
ac13ad10 954 **/
7afa3a4a 955int unsafe_symlink(const char *dest, const char *src)
4b957c22 956{
7afa3a4a 957 const char *name, *slash;
4b957c22
AT
958 int depth = 0;
959
960 /* all absolute and null symlinks are unsafe */
7afa3a4a 961 if (!dest || !*dest || *dest == '/') return 1;
4b957c22
AT
962
963 /* find out what our safety margin is */
7afa3a4a
WD
964 for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
965 if (strncmp(name, "../", 3) == 0) {
c284f34a 966 depth = 0;
7afa3a4a 967 } else if (strncmp(name, "./", 2) == 0) {
4b957c22
AT
968 /* nothing */
969 } else {
970 depth++;
971 }
972 }
7afa3a4a
WD
973 if (strcmp(name, "..") == 0)
974 depth = 0;
4b957c22 975
7afa3a4a
WD
976 for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
977 if (strncmp(name, "../", 3) == 0) {
978 /* if at any point we go outside the current directory
979 then stop - it is unsafe */
980 if (--depth < 0)
981 return 1;
982 } else if (strncmp(name, "./", 2) == 0) {
4b957c22
AT
983 /* nothing */
984 } else {
985 depth++;
986 }
4b957c22 987 }
7afa3a4a
WD
988 if (strcmp(name, "..") == 0)
989 depth--;
4b957c22 990
4b957c22
AT
991 return (depth < 0);
992}
375a4556 993
f7632fc6 994
ac13ad10 995/**
b4235b31
MP
996 * Return the date and time as a string
997 **/
f7632fc6
AT
998char *timestring(time_t t)
999{
1000 static char TimeBuf[200];
1001 struct tm *tm = localtime(&t);
1002
1003#ifdef HAVE_STRFTIME
5cb37436 1004 strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
f7632fc6 1005#else
5cb37436 1006 strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
f7632fc6
AT
1007#endif
1008
1009 if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
1010 TimeBuf[strlen(TimeBuf)-1] = 0;
1011 }
1012
1013 return(TimeBuf);
1014}
1015
9ec16c83 1016
e1bd49d6
MP
1017/**
1018 * Sleep for a specified number of milliseconds.
1019 *
1020 * Always returns TRUE. (In the future it might return FALSE if
1021 * interrupted.)
1022 **/
1023int msleep(int t)
9ec16c83 1024{
c284f34a
WD
1025 int tdiff = 0;
1026 struct timeval tval, t1, t2;
9ec16c83
AT
1027
1028 gettimeofday(&t1, NULL);
1029 gettimeofday(&t2, NULL);
5cb37436 1030
9ec16c83
AT
1031 while (tdiff < t) {
1032 tval.tv_sec = (t-tdiff)/1000;
1033 tval.tv_usec = 1000*((t-tdiff)%1000);
5cb37436 1034
9ec16c83
AT
1035 errno = 0;
1036 select(0,NULL,NULL, NULL, &tval);
1037
1038 gettimeofday(&t2, NULL);
5cb37436 1039 tdiff = (t2.tv_sec - t1.tv_sec)*1000 +
9ec16c83
AT
1040 (t2.tv_usec - t1.tv_usec)/1000;
1041 }
e1bd49d6
MP
1042
1043 return True;
9ec16c83
AT
1044}
1045
1046
ac13ad10
MP
1047/**
1048 * Determine if two file modification times are equivalent (either
1049 * exact or in the modification timestamp window established by
1050 * --modify-window).
1051 *
1052 * @retval 0 if the times should be treated as the same
1053 *
1054 * @retval +1 if the first is later
1055 *
1056 * @retval -1 if the 2nd is later
1057 **/
5b56cc19
AT
1058int cmp_modtime(time_t file1, time_t file2)
1059{
5b56cc19
AT
1060 extern int modify_window;
1061
1062 if (file2 > file1) {
1063 if (file2 - file1 <= modify_window) return 0;
1064 return -1;
1065 }
1066 if (file1 - file2 <= modify_window) return 0;
1067 return 1;
1068}
1069
1070
1071#ifdef __INSURE__XX
0f8f98c8
AT
1072#include <dlfcn.h>
1073
ac13ad10
MP
1074/**
1075 This routine is a trick to immediately catch errors when debugging
1076 with insure. A xterm with a gdb is popped up when insure catches
1077 a error. It is Linux specific.
1078**/
0f8f98c8
AT
1079int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
1080{
1081 static int (*fn)();
1082 int ret;
8950ac03 1083 char *cmd;
0f8f98c8 1084
5cb37436 1085 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
1086 getpid(), getpid(), getpid());
1087
1088 if (!fn) {
1089 static void *h;
1090 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
1091 fn = dlsym(h, "_Insure_trap_error");
1092 }
1093
1094 ret = fn(a1, a2, a3, a4, a5, a6);
1095
1096 system(cmd);
1097
8950ac03
AT
1098 free(cmd);
1099
0f8f98c8
AT
1100 return ret;
1101}
1102#endif
58cadc86
WD
1103
1104
1105#define MALLOC_MAX 0x40000000
1106
1107void *_new_array(unsigned int size, unsigned long num)
1108{
1109 if (num >= MALLOC_MAX/size)
1110 return NULL;
1111 return malloc(size * num);
1112}
1113
1114void *_realloc_array(void *ptr, unsigned int size, unsigned long num)
1115{
1116 if (num >= MALLOC_MAX/size)
1117 return NULL;
1118 /* No realloc should need this, but just in case... */
1119 if (!ptr)
1120 return malloc(size * num);
1121 return realloc(ptr, size * num);
1122}