Changed rprintf() calls that included strerror() to use rsyserr().
[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) {
d62bcc17 255 rsyserr(FERROR, errno, "open %s", full_fname(source));
950ab32d
AT
256 return -1;
257 }
258
c7c11a0d 259 if (robust_unlink(dest) && errno != ENOENT) {
d62bcc17 260 rsyserr(FERROR, errno, "unlink %s", full_fname(dest));
950ab32d
AT
261 return -1;
262 }
263
31e12522 264 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
c46ded46 265 if (ofd == -1) {
d62bcc17 266 rsyserr(FERROR, errno, "open %s", full_fname(dest));
950ab32d
AT
267 close(ifd);
268 return -1;
269 }
270
5cb37436 271 while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
950ab32d 272 if (full_write(ofd, buf, len) < 0) {
d62bcc17 273 rsyserr(FERROR, errno, "write %s", full_fname(dest));
950ab32d
AT
274 close(ifd);
275 close(ofd);
276 return -1;
277 }
278 }
279
8b602edd 280 if (len < 0) {
d62bcc17 281 rsyserr(FERROR, errno, "read %s", full_fname(source));
8b602edd
WD
282 close(ifd);
283 close(ofd);
284 return -1;
285 }
286
9f27cd8c 287 if (close(ifd) < 0) {
d62bcc17
WD
288 rsyserr(FINFO, errno, "close failed on %s",
289 full_fname(source));
9f27cd8c
WD
290 }
291
292 if (close(ofd) < 0) {
d62bcc17
WD
293 rsyserr(FERROR, errno, "close failed on %s",
294 full_fname(dest));
9f27cd8c
WD
295 return -1;
296 }
950ab32d 297
950ab32d
AT
298 return 0;
299}
feaa89c4 300
c7c11a0d
DD
301/* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
302#define MAX_RENAMES_DIGITS 3
303#define MAX_RENAMES 1000
304
ac13ad10 305/**
b4235b31
MP
306 * Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
307 * rename to <path>/.rsyncNNN instead.
308 *
309 * Note that successive rsync runs will shuffle the filenames around a
310 * bit as long as the file is still busy; this is because this function
311 * does not know if the unlink call is due to a new file coming in, or
312 * --delete trying to remove old .rsyncNNN files, hence it renames it
313 * each time.
314 **/
c7c11a0d
DD
315int robust_unlink(char *fname)
316{
317#ifndef ETXTBSY
318 return do_unlink(fname);
319#else
320 static int counter = 1;
321 int rc, pos, start;
322 char path[MAXPATHLEN];
323
324 rc = do_unlink(fname);
c284f34a 325 if (rc == 0 || errno != ETXTBSY)
c7c11a0d
DD
326 return rc;
327
c284f34a
WD
328 if ((pos = strlcpy(path, fname, MAXPATHLEN)) >= MAXPATHLEN)
329 pos = MAXPATHLEN - 1;
c7c11a0d 330
c284f34a
WD
331 while (pos > 0 && path[pos-1] != '/')
332 pos--;
5cb37436 333 pos += strlcpy(path+pos, ".rsync", MAXPATHLEN-pos);
c7c11a0d
DD
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;
c284f34a 346 } while ((rc = access(path, 0)) == 0 && counter != start);
c7c11a0d 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
62c9e6b3
WD
362/* Returns 0 on success, -1 on most errors, and -2 if we got an error
363 * trying to copy the file across file systems. */
364int robust_rename(char *from, char *to, int mode)
c7c11a0d 365{
62c9e6b3
WD
366 int tries = 4;
367
368 while (tries--) {
369 if (do_rename(from, to) == 0)
370 return 0;
371
372 switch (errno) {
373#ifdef ETXTBSY
374 case ETXTBSY:
375 if (robust_unlink(to) != 0)
376 return -1;
377 break;
c7c11a0d 378#endif
62c9e6b3
WD
379 case EXDEV:
380 if (copy_file(from, to, mode) != 0)
381 return -2;
382 do_unlink(from);
383 return 0;
384 default:
385 return -1;
386 }
387 }
388 return -1;
feaa89c4 389}
3ba62a83
AT
390
391
392static pid_t all_pids[10];
393static int num_pids;
394
4cf64834 395/** Fork and record the pid of the child. **/
3ba62a83
AT
396pid_t do_fork(void)
397{
398 pid_t newpid = fork();
5cb37436 399
4cf64834 400 if (newpid != 0 && newpid != -1) {
3ba62a83
AT
401 all_pids[num_pids++] = newpid;
402 }
403 return newpid;
404}
405
4cf64834
MP
406/**
407 * Kill all children.
408 *
409 * @todo It would be kind of nice to make sure that they are actually
410 * all our children before we kill them, because their pids may have
411 * been recycled by some other process. Perhaps when we wait for a
412 * child, we should remove it from this array. Alternatively we could
413 * perhaps use process groups, but I think that would not work on
414 * ancient Unix versions that don't support them.
415 **/
3ba62a83
AT
416void kill_all(int sig)
417{
418 int i;
4cf64834
MP
419
420 for (i = 0; i < num_pids; i++) {
421 /* Let's just be a little careful where we
422 * point that gun, hey? See kill(2) for the
423 * magic caused by negative values. */
424 pid_t p = all_pids[i];
425
426 if (p == getpid())
427 continue;
428 if (p <= 0)
429 continue;
430
431 kill(p, sig);
3ba62a83
AT
432 }
433}
9486289c 434
4cf64834 435
ac13ad10 436/** Turn a user name into a uid */
8ef4ffd6
AT
437int name_to_uid(char *name, uid_t *uid)
438{
439 struct passwd *pass;
440 if (!name || !*name) return 0;
441 pass = getpwnam(name);
442 if (pass) {
443 *uid = pass->pw_uid;
444 return 1;
445 }
446 return 0;
447}
448
ac13ad10 449/** Turn a group name into a gid */
8ef4ffd6
AT
450int name_to_gid(char *name, gid_t *gid)
451{
452 struct group *grp;
453 if (!name || !*name) return 0;
454 grp = getgrnam(name);
455 if (grp) {
456 *gid = grp->gr_gid;
457 return 1;
458 }
459 return 0;
460}
461
ff8b29b8 462
ac13ad10 463/** Lock a byte range in a open file */
31593dd6 464int lock_range(int fd, int offset, int len)
0c515f17 465{
31593dd6 466 struct flock lock;
0c515f17 467
31593dd6
AT
468 lock.l_type = F_WRLCK;
469 lock.l_whence = SEEK_SET;
470 lock.l_start = offset;
471 lock.l_len = len;
472 lock.l_pid = 0;
5cb37436 473
31593dd6 474 return fcntl(fd,F_SETLK,&lock) == 0;
0c515f17 475}
874895d5 476
4791825d
WD
477static int exclude_server_path(char *arg)
478{
479 char *s;
4791825d 480
bf6dcd17 481 if (server_exclude_list.head) {
4791825d
WD
482 for (s = arg; (s = strchr(s, '/')) != NULL; ) {
483 *s = '\0';
9fdb334e 484 if (check_exclude(&server_exclude_list, arg, 1) < 0) {
4791825d
WD
485 /* We must leave arg truncated! */
486 return 1;
487 }
488 *s++ = '/';
489 }
490 }
491 return 0;
492}
874895d5 493
cb13abfe 494static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
874895d5 495{
932be9aa 496#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
4135d091
WD
497 if (maxargs <= *argc)
498 return;
499 if (!*s)
500 s = ".";
4791825d
WD
501 s = argv[*argc] = strdup(s);
502 exclude_server_path(s);
874895d5 503 (*argc)++;
874895d5 504#else
cb13abfe 505 extern int sanitize_paths;
874895d5
AT
506 glob_t globbuf;
507 int i;
508
4135d091
WD
509 if (!*s)
510 s = ".";
e42c9458 511
4791825d 512 s = argv[*argc] = strdup(s);
4135d091 513 if (sanitize_paths)
4791825d 514 sanitize_path(s, NULL);
087bf010 515
5cb37436 516 memset(&globbuf, 0, sizeof globbuf);
4791825d
WD
517 if (!exclude_server_path(s))
518 glob(s, 0, NULL, &globbuf);
874895d5
AT
519 if (globbuf.gl_pathc == 0) {
520 (*argc)++;
521 globfree(&globbuf);
522 return;
523 }
c284f34a
WD
524 for (i = 0; i < maxargs - *argc && i < (int)globbuf.gl_pathc; i++) {
525 if (i == 0)
526 free(s);
527 argv[*argc + i] = strdup(globbuf.gl_pathv[i]);
528 if (!argv[*argc + i])
529 out_of_memory("glob_expand");
874895d5
AT
530 }
531 globfree(&globbuf);
c284f34a 532 *argc += i;
874895d5
AT
533#endif
534}
5a96ee05 535
4791825d 536/* This routine is only used in daemon mode. */
cb13abfe 537void glob_expand(char *base1, char **argv, int *argc, int maxargs)
087bf010
AT
538{
539 char *s = argv[*argc];
540 char *p, *q;
ba5e128d 541 char *base = base1;
4791825d 542 int base_len = strlen(base);
087bf010
AT
543
544 if (!s || !*s) return;
545
4791825d
WD
546 if (strncmp(s, base, base_len) == 0)
547 s += base_len;
e42c9458 548
087bf010
AT
549 s = strdup(s);
550 if (!s) out_of_memory("glob_expand");
551
8950ac03 552 if (asprintf(&base," %s/", base1) <= 0) out_of_memory("glob_expand");
4791825d 553 base_len++;
ba5e128d 554
087bf010 555 q = s;
c284f34a 556 while ((p = strstr(q,base)) != NULL && *argc < maxargs) {
ba5e128d
AT
557 /* split it at this point */
558 *p = 0;
cb13abfe 559 glob_expand_one(q, argv, argc, maxargs);
4791825d 560 q = p + base_len;
087bf010
AT
561 }
562
c284f34a
WD
563 if (*q && *argc < maxargs)
564 glob_expand_one(q, argv, argc, maxargs);
087bf010
AT
565
566 free(s);
ba5e128d 567 free(base);
087bf010 568}
5a96ee05 569
ac13ad10
MP
570/**
571 * Convert a string to lower case
572 **/
5a96ee05
AT
573void strlower(char *s)
574{
575 while (*s) {
32f76175
MP
576 if (isupper(* (unsigned char *) s))
577 *s = tolower(* (unsigned char *) s);
5a96ee05
AT
578 s++;
579 }
580}
e42c9458 581
368ad70e
WD
582/* Join strings p1 & p2 into "dest" with a guaranteed '/' between them. (If
583 * p1 ends with a '/', no extra '/' is inserted.) Returns the length of both
a8f7e4b8
WD
584 * strings + 1 (if '/' was inserted), regardless of whether the null-terminated
585 * string fits into destsize. */
368ad70e
WD
586size_t pathjoin(char *dest, size_t destsize, const char *p1, const char *p2)
587{
588 size_t len = strlcpy(dest, p1, destsize);
589 if (len < destsize - 1) {
590 if (!len || dest[len-1] != '/')
591 dest[len++] = '/';
592 if (len < destsize - 1)
593 len += strlcpy(dest + len, p2, destsize - len);
594 else {
595 dest[len] = '\0';
596 len += strlen(p2);
597 }
598 }
599 else
600 len += strlen(p2) + 1; /* Assume we'd insert a '/'. */
601 return len;
602}
603
604/* Join any number of strings together, putting them in "dest". The return
a8f7e4b8
WD
605 * value is the length of all the strings, regardless of whether the null-
606 * terminated whole fits in destsize. Your list of string pointers must end
607 * with a NULL to indicate the end of the list. */
368ad70e
WD
608size_t stringjoin(char *dest, size_t destsize, ...)
609{
5cb37436 610 va_list ap;
368ad70e
WD
611 size_t len, ret = 0;
612 const char *src;
613
614 va_start(ap, destsize);
615 while (1) {
616 if (!(src = va_arg(ap, const char *)))
617 break;
618 len = strlen(src);
619 ret += len;
620 if (destsize > 1) {
621 if (len >= destsize)
622 len = destsize - 1;
623 memcpy(dest, src, len);
624 destsize -= len;
625 dest += len;
626 }
627 }
628 *dest = '\0';
629 va_end(ap);
630
631 return ret;
632}
633
5243c216
AT
634void clean_fname(char *name)
635{
636 char *p;
637 int l;
638 int modified = 1;
639
640 if (!name) return;
641
642 while (modified) {
643 modified = 0;
644
c284f34a 645 if ((p = strstr(name,"/./")) != NULL) {
5243c216
AT
646 modified = 1;
647 while (*p) {
648 p[0] = p[2];
649 p++;
650 }
651 }
652
c284f34a 653 if ((p = strstr(name,"//")) != NULL) {
5243c216
AT
654 modified = 1;
655 while (*p) {
656 p[0] = p[1];
657 p++;
658 }
659 }
660
c284f34a 661 if (strncmp(p = name, "./", 2) == 0) {
5243c216
AT
662 modified = 1;
663 do {
664 p[0] = p[2];
665 } while (*p++);
666 }
667
c284f34a 668 l = strlen(p = name);
5243c216
AT
669 if (l > 1 && p[l-1] == '/') {
670 modified = 1;
671 p[l-1] = 0;
672 }
673 }
674}
675
ac13ad10 676/**
1b8e662a 677 * Make path appear as if a chroot had occurred:
ac13ad10 678 *
b4235b31
MP
679 * @li 1. remove leading "/" (or replace with "." if at end)
680 *
681 * @li 2. remove leading ".." components (except those allowed by @p reldir)
682 *
683 * @li 3. delete any other "<dir>/.." (recursively)
ac13ad10 684 *
79452d46 685 * Can only shrink paths, so sanitizes in place.
ac13ad10 686 *
b5f9e67d 687 * While we're at it, remove double slashes and "." components like
b4235b31 688 * clean_fname() does, but DON'T remove a trailing slash because that
b5f9e67d 689 * is sometimes significant on command line arguments.
ac13ad10 690 *
b4235b31 691 * If @p reldir is non-null, it is a sanitized directory that the path will be
79452d46
DD
692 * relative to, so allow as many ".." at the beginning of the path as
693 * there are components in reldir. This is used for symbolic link targets.
694 * If reldir is non-null and the path began with "/", to be completely like
695 * a chroot we should add in depth levels of ".." at the beginning of the
696 * path, but that would blow the assumption that the path doesn't grow and
697 * it is not likely to end up being a valid symlink anyway, so just do
698 * the normal removal of the leading "/" instead.
ac13ad10 699 *
1b8e662a
DD
700 * Contributed by Dave Dykstra <dwd@bell-labs.com>
701 */
cb13abfe 702void sanitize_path(char *p, char *reldir)
1b8e662a 703{
44e2e578 704 char *start, *sanp;
cb13abfe
DD
705 int depth = 0;
706 int allowdotdot = 0;
707
708 if (reldir) {
709 depth++;
710 while (*reldir) {
711 if (*reldir++ == '/') {
712 depth++;
713 }
714 }
715 }
44e2e578
DD
716 start = p;
717 sanp = p;
b5f9e67d
DD
718 while (*p == '/') {
719 /* remove leading slashes */
720 p++;
721 }
1b8e662a 722 while (*p != '\0') {
b5f9e67d 723 /* this loop iterates once per filename component in p.
44e2e578 724 * both p (and sanp if the original had a slash) should
b5f9e67d
DD
725 * always be left pointing after a slash
726 */
c284f34a 727 if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
b5f9e67d
DD
728 /* skip "." component */
729 while (*++p == '/') {
730 /* skip following slashes */
731 ;
732 }
cb13abfe
DD
733 continue;
734 }
735 allowdotdot = 0;
c284f34a 736 if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
cb13abfe 737 /* ".." component followed by slash or end */
c284f34a 738 if (depth > 0 && sanp == start) {
cb13abfe
DD
739 /* allow depth levels of .. at the beginning */
740 --depth;
741 allowdotdot = 1;
742 } else {
743 p += 2;
744 if (*p == '/')
745 p++;
746 if (sanp != start) {
747 /* back up sanp one level */
748 --sanp; /* now pointing at slash */
c284f34a 749 while (sanp > start && sanp[-1] != '/') {
cb13abfe
DD
750 /* skip back up to slash */
751 sanp--;
752 }
b5f9e67d 753 }
cb13abfe 754 continue;
1b8e662a 755 }
cb13abfe
DD
756 }
757 while (1) {
758 /* copy one component through next slash */
759 *sanp++ = *p++;
42509417 760 if (*p == '\0' || p[-1] == '/') {
cb13abfe
DD
761 while (*p == '/') {
762 /* skip multiple slashes */
763 p++;
b5f9e67d 764 }
cb13abfe 765 break;
1b8e662a
DD
766 }
767 }
cb13abfe
DD
768 if (allowdotdot) {
769 /* move the virtual beginning to leave the .. alone */
770 start = sanp;
771 }
1b8e662a 772 }
c284f34a 773 if (sanp == start && !allowdotdot) {
b5f9e67d 774 /* ended up with nothing, so put in "." component */
79452d46
DD
775 /*
776 * note that the !allowdotdot doesn't prevent this from
777 * happening in all allowed ".." situations, but I didn't
778 * think it was worth putting in an extra variable to ensure
779 * it since an extra "." won't hurt in those situations.
780 */
44e2e578 781 *sanp++ = '.';
b5f9e67d 782 }
44e2e578 783 *sanp = '\0';
1b8e662a
DD
784}
785
14b61c63
WD
786/* Works much like sanitize_path(), with these differences: (1) a new buffer
787 * is allocated for the sanitized path rather than modifying it in-place; (2)
788 * a leading slash gets transformed into the rootdir value (which can be empty
789 * or NULL if you just want the slash to get dropped); (3) no "reldir" can be
790 * specified. */
791char *alloc_sanitize_path(const char *path, const char *rootdir)
792{
793 char *buf;
794 int rlen, plen = strlen(path);
795
b05b3c9b 796 if (*path == '/' && rootdir) {
14b61c63 797 rlen = strlen(rootdir);
b05b3c9b
WD
798 if (rlen == 1)
799 path++;
800 } else
14b61c63
WD
801 rlen = 0;
802 if (!(buf = new_array(char, rlen + plen + 1)))
803 out_of_memory("alloc_sanitize_path");
804 if (rlen)
805 memcpy(buf, rootdir, rlen);
806 memcpy(buf + rlen, path, plen + 1);
807
b05b3c9b 808 if (rlen > 1)
14b61c63
WD
809 rlen++;
810 sanitize_path(buf + rlen, NULL);
b05b3c9b
WD
811 if (rlen && buf[rlen] == '.' && buf[rlen+1] == '\0') {
812 if (rlen > 1)
813 rlen--;
814 buf[rlen] = '\0';
815 }
14b61c63
WD
816
817 return buf;
818}
5243c216 819
4791825d 820char curr_dir[MAXPATHLEN];
4af8fe4e 821unsigned int curr_dir_len;
5243c216 822
4e5db0ad 823/**
a16d8f2b
WD
824 * Like chdir(), but it keeps track of the current directory (in the
825 * global "curr_dir"), and ensures that the path size doesn't overflow.
826 * Also cleans the path using the clean_fname() function.
4e5db0ad 827 **/
4af8fe4e 828int push_dir(char *dir)
5243c216 829{
5243c216 830 static int initialised;
4af8fe4e 831 unsigned int len;
5243c216
AT
832
833 if (!initialised) {
834 initialised = 1;
5cb37436 835 getcwd(curr_dir, sizeof curr_dir - 1);
4af8fe4e 836 curr_dir_len = strlen(curr_dir);
5243c216
AT
837 }
838
4af8fe4e
WD
839 if (!dir) /* this call was probably just to initialize */
840 return 0;
c226b7c2 841
4af8fe4e
WD
842 len = strlen(dir);
843 if (len == 1 && *dir == '.')
844 return 1;
5243c216 845
4af8fe4e
WD
846 if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir)
847 return 0;
848
849 if (chdir(dir))
850 return 0;
5243c216
AT
851
852 if (*dir == '/') {
4af8fe4e
WD
853 memcpy(curr_dir, dir, len + 1);
854 curr_dir_len = len;
855 } else {
856 curr_dir[curr_dir_len++] = '/';
857 memcpy(curr_dir + curr_dir_len, dir, len + 1);
858 curr_dir_len += len;
5243c216
AT
859 }
860
861 clean_fname(curr_dir);
862
4af8fe4e 863 return 1;
5243c216
AT
864}
865
a16d8f2b
WD
866/**
867 * Reverse a push_dir() call. You must pass in an absolute path
868 * that was copied from a prior value of "curr_dir".
869 **/
5243c216
AT
870int pop_dir(char *dir)
871{
4af8fe4e
WD
872 if (chdir(dir))
873 return 0;
5243c216 874
4af8fe4e
WD
875 curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir);
876 if (curr_dir_len >= sizeof curr_dir)
877 curr_dir_len = sizeof curr_dir - 1;
5243c216 878
4af8fe4e 879 return 1;
5243c216 880}
aa9b77a5 881
eb61be19
WD
882/**
883 * Return a quoted string with the full pathname of the indicated filename.
884 * The string " (in MODNAME)" may also be appended. The returned pointer
885 * remains valid until the next time full_fname() is called.
886 **/
887char *full_fname(char *fn)
888{
889 extern int module_id;
890 static char *result = NULL;
891 char *m1, *m2, *m3;
892 char *p1, *p2;
893
894 if (result)
895 free(result);
896
897 if (*fn == '/')
898 p1 = p2 = "";
899 else {
900 p1 = curr_dir;
901 p2 = "/";
902 }
903 if (module_id >= 0) {
904 m1 = " (in ";
905 m2 = lp_name(module_id);
906 m3 = ")";
907 if (*p1) {
908 if (!lp_use_chroot(module_id)) {
909 char *p = lp_path(module_id);
910 if (*p != '/' || p[1])
911 p1 += strlen(p);
912 }
913 if (!*p1)
914 p2++;
915 else
916 p1++;
917 }
918 else
919 fn++;
920 } else
921 m1 = m2 = m3 = "";
922
923 asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
924
925 return result;
926}
927
ac13ad10 928/** We need to supply our own strcmp function for file list comparisons
aa9b77a5
AT
929 to ensure that signed/unsigned usage is consistent between machines. */
930int u_strcmp(const char *cs1, const char *cs2)
931{
5a788ade
AT
932 const uchar *s1 = (const uchar *)cs1;
933 const uchar *s2 = (const uchar *)cs2;
aa9b77a5
AT
934
935 while (*s1 && *s2 && (*s1 == *s2)) {
936 s1++; s2++;
937 }
5cb37436 938
aa9b77a5
AT
939 return (int)*s1 - (int)*s2;
940}
eb86d661 941
4b957c22 942
ac13ad10
MP
943
944/**
945 * Determine if a symlink points outside the current directory tree.
036e70b0
MP
946 * This is considered "unsafe" because e.g. when mirroring somebody
947 * else's machine it might allow them to establish a symlink to
948 * /etc/passwd, and then read it through a web server.
949 *
4e5db0ad
MP
950 * Null symlinks and absolute symlinks are always unsafe.
951 *
952 * Basically here we are concerned with symlinks whose target contains
953 * "..", because this might cause us to walk back up out of the
954 * transferred directory. We are not allowed to go back up and
955 * reenter.
956 *
036e70b0
MP
957 * @param dest Target of the symlink in question.
958 *
25d34a5c 959 * @param src Top source directory currently applicable. Basically this
036e70b0 960 * is the first parameter to rsync in a simple invocation, but it's
25d34a5c 961 * modified by flist.c in slightly complex ways.
036e70b0
MP
962 *
963 * @retval True if unsafe
964 * @retval False is unsafe
4e5db0ad
MP
965 *
966 * @sa t_unsafe.c
ac13ad10 967 **/
7afa3a4a 968int unsafe_symlink(const char *dest, const char *src)
4b957c22 969{
7afa3a4a 970 const char *name, *slash;
4b957c22
AT
971 int depth = 0;
972
973 /* all absolute and null symlinks are unsafe */
7afa3a4a 974 if (!dest || !*dest || *dest == '/') return 1;
4b957c22
AT
975
976 /* find out what our safety margin is */
7afa3a4a
WD
977 for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
978 if (strncmp(name, "../", 3) == 0) {
c284f34a 979 depth = 0;
7afa3a4a 980 } else if (strncmp(name, "./", 2) == 0) {
4b957c22
AT
981 /* nothing */
982 } else {
983 depth++;
984 }
985 }
7afa3a4a
WD
986 if (strcmp(name, "..") == 0)
987 depth = 0;
4b957c22 988
7afa3a4a
WD
989 for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
990 if (strncmp(name, "../", 3) == 0) {
991 /* if at any point we go outside the current directory
992 then stop - it is unsafe */
993 if (--depth < 0)
994 return 1;
995 } else if (strncmp(name, "./", 2) == 0) {
4b957c22
AT
996 /* nothing */
997 } else {
998 depth++;
999 }
4b957c22 1000 }
7afa3a4a
WD
1001 if (strcmp(name, "..") == 0)
1002 depth--;
4b957c22 1003
4b957c22
AT
1004 return (depth < 0);
1005}
375a4556 1006
f7632fc6 1007
ac13ad10 1008/**
b4235b31
MP
1009 * Return the date and time as a string
1010 **/
f7632fc6
AT
1011char *timestring(time_t t)
1012{
1013 static char TimeBuf[200];
1014 struct tm *tm = localtime(&t);
1015
1016#ifdef HAVE_STRFTIME
5cb37436 1017 strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
f7632fc6 1018#else
5cb37436 1019 strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
f7632fc6
AT
1020#endif
1021
1022 if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
1023 TimeBuf[strlen(TimeBuf)-1] = 0;
1024 }
1025
1026 return(TimeBuf);
1027}
1028
9ec16c83 1029
e1bd49d6
MP
1030/**
1031 * Sleep for a specified number of milliseconds.
1032 *
1033 * Always returns TRUE. (In the future it might return FALSE if
1034 * interrupted.)
1035 **/
1036int msleep(int t)
9ec16c83 1037{
c284f34a
WD
1038 int tdiff = 0;
1039 struct timeval tval, t1, t2;
9ec16c83
AT
1040
1041 gettimeofday(&t1, NULL);
1042 gettimeofday(&t2, NULL);
5cb37436 1043
9ec16c83
AT
1044 while (tdiff < t) {
1045 tval.tv_sec = (t-tdiff)/1000;
1046 tval.tv_usec = 1000*((t-tdiff)%1000);
5cb37436 1047
9ec16c83
AT
1048 errno = 0;
1049 select(0,NULL,NULL, NULL, &tval);
1050
1051 gettimeofday(&t2, NULL);
5cb37436 1052 tdiff = (t2.tv_sec - t1.tv_sec)*1000 +
9ec16c83
AT
1053 (t2.tv_usec - t1.tv_usec)/1000;
1054 }
e1bd49d6
MP
1055
1056 return True;
9ec16c83
AT
1057}
1058
1059
ac13ad10
MP
1060/**
1061 * Determine if two file modification times are equivalent (either
1062 * exact or in the modification timestamp window established by
1063 * --modify-window).
1064 *
1065 * @retval 0 if the times should be treated as the same
1066 *
1067 * @retval +1 if the first is later
1068 *
1069 * @retval -1 if the 2nd is later
1070 **/
5b56cc19
AT
1071int cmp_modtime(time_t file1, time_t file2)
1072{
5b56cc19
AT
1073 extern int modify_window;
1074
1075 if (file2 > file1) {
1076 if (file2 - file1 <= modify_window) return 0;
1077 return -1;
1078 }
1079 if (file1 - file2 <= modify_window) return 0;
1080 return 1;
1081}
1082
1083
1084#ifdef __INSURE__XX
0f8f98c8
AT
1085#include <dlfcn.h>
1086
ac13ad10
MP
1087/**
1088 This routine is a trick to immediately catch errors when debugging
1089 with insure. A xterm with a gdb is popped up when insure catches
1090 a error. It is Linux specific.
1091**/
0f8f98c8
AT
1092int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
1093{
1094 static int (*fn)();
1095 int ret;
8950ac03 1096 char *cmd;
0f8f98c8 1097
5cb37436 1098 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
1099 getpid(), getpid(), getpid());
1100
1101 if (!fn) {
1102 static void *h;
1103 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
1104 fn = dlsym(h, "_Insure_trap_error");
1105 }
1106
1107 ret = fn(a1, a2, a3, a4, a5, a6);
1108
1109 system(cmd);
1110
8950ac03
AT
1111 free(cmd);
1112
0f8f98c8
AT
1113 return ret;
1114}
1115#endif
58cadc86
WD
1116
1117
1118#define MALLOC_MAX 0x40000000
1119
1120void *_new_array(unsigned int size, unsigned long num)
1121{
1122 if (num >= MALLOC_MAX/size)
1123 return NULL;
1124 return malloc(size * num);
1125}
1126
1127void *_realloc_array(void *ptr, unsigned int size, unsigned long num)
1128{
1129 if (num >= MALLOC_MAX/size)
1130 return NULL;
1131 /* No realloc should need this, but just in case... */
1132 if (!ptr)
1133 return malloc(size * num);
1134 return realloc(ptr, size * num);
1135}