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