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