Added relative_paths extern.
[rsync/rsync.git] / util.c
... / ...
CommitLineData
1/* -*- c-file-style: "linux" -*-
2 *
3 * Copyright (C) 1996-2000 by Andrew Tridgell
4 * Copyright (C) Paul Mackerras 1996
5 * Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
6 *
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.
11 *
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.
16 *
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 */
21
22/**
23 * @file
24 *
25 * Utilities used in rsync
26 **/
27
28#include "rsync.h"
29
30extern int verbose;
31extern int dry_run;
32extern int module_id;
33extern int modify_window;
34extern int relative_paths;
35extern char *partial_dir;
36extern struct filter_list_struct server_filter_list;
37
38int sanitize_paths = 0;
39
40
41
42/**
43 * Set a fd into nonblocking mode
44 **/
45void set_nonblocking(int fd)
46{
47 int val;
48
49 if ((val = fcntl(fd, F_GETFL, 0)) == -1)
50 return;
51 if (!(val & NONBLOCK_FLAG)) {
52 val |= NONBLOCK_FLAG;
53 fcntl(fd, F_SETFL, val);
54 }
55}
56
57/**
58 * Set a fd into blocking mode
59 **/
60void set_blocking(int fd)
61{
62 int val;
63
64 if ((val = fcntl(fd, F_GETFL, 0)) == -1)
65 return;
66 if (val & NONBLOCK_FLAG) {
67 val &= ~NONBLOCK_FLAG;
68 fcntl(fd, F_SETFL, val);
69 }
70}
71
72
73/**
74 * Create a file descriptor pair - like pipe() but use socketpair if
75 * possible (because of blocking issues on pipes).
76 *
77 * Always set non-blocking.
78 */
79int fd_pair(int fd[2])
80{
81 int ret;
82
83#ifdef HAVE_SOCKETPAIR
84 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
85#else
86 ret = pipe(fd);
87#endif
88
89 if (ret == 0) {
90 set_nonblocking(fd[0]);
91 set_nonblocking(fd[1]);
92 }
93
94 return ret;
95}
96
97
98void print_child_argv(char **cmd)
99{
100 rprintf(FINFO, "opening connection using ");
101 for (; *cmd; cmd++) {
102 /* Look for characters that ought to be quoted. This
103 * is not a great quoting algorithm, but it's
104 * sufficient for a log message. */
105 if (strspn(*cmd, "abcdefghijklmnopqrstuvwxyz"
106 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
107 "0123456789"
108 ",.-_=+@/") != strlen(*cmd)) {
109 rprintf(FINFO, "\"%s\" ", safe_fname(*cmd));
110 } else {
111 rprintf(FINFO, "%s ", safe_fname(*cmd));
112 }
113 }
114 rprintf(FINFO, "\n");
115}
116
117
118void out_of_memory(char *str)
119{
120 rprintf(FERROR, "ERROR: out of memory in %s\n", str);
121 exit_cleanup(RERR_MALLOC);
122}
123
124void overflow_exit(char *str)
125{
126 rprintf(FERROR, "ERROR: buffer overflow in %s\n", str);
127 exit_cleanup(RERR_MALLOC);
128}
129
130
131
132int set_modtime(char *fname, time_t modtime, mode_t mode)
133{
134#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
135 if (S_ISLNK(mode))
136 return 1;
137#endif
138
139 if (verbose > 2) {
140 rprintf(FINFO, "set modtime of %s to (%ld) %s",
141 safe_fname(fname), (long)modtime,
142 asctime(localtime(&modtime)));
143 }
144
145 if (dry_run)
146 return 0;
147
148 {
149#ifdef HAVE_UTIMES
150 struct timeval t[2];
151 t[0].tv_sec = time(NULL);
152 t[0].tv_usec = 0;
153 t[1].tv_sec = modtime;
154 t[1].tv_usec = 0;
155# ifdef HAVE_LUTIMES
156 if (S_ISLNK(mode))
157 return lutimes(fname, t);
158# endif
159 return utimes(fname, t);
160#elif defined HAVE_UTIMBUF
161 struct utimbuf tbuf;
162 tbuf.actime = time(NULL);
163 tbuf.modtime = modtime;
164 return utime(fname,&tbuf);
165#elif defined HAVE_UTIME
166 time_t t[2];
167 t[0] = time(NULL);
168 t[1] = modtime;
169 return utime(fname,t);
170#else
171#error No file-time-modification routine found!
172#endif
173 }
174}
175
176
177/**
178 Create any necessary directories in fname. Unfortunately we don't know
179 what perms to give the directory when this is called so we need to rely
180 on the umask
181**/
182int create_directory_path(char *fname, int base_umask)
183{
184 char *p;
185
186 while (*fname == '/')
187 fname++;
188 while (strncmp(fname, "./", 2) == 0)
189 fname += 2;
190
191 p = fname;
192 while ((p = strchr(p,'/')) != NULL) {
193 *p = 0;
194 do_mkdir(fname, 0777 & ~base_umask);
195 *p = '/';
196 p++;
197 }
198 return 0;
199}
200
201
202/**
203 * Write @p len bytes at @p ptr to descriptor @p desc, retrying if
204 * interrupted.
205 *
206 * @retval len upon success
207 *
208 * @retval <0 write's (negative) error code
209 *
210 * Derived from GNU C's cccp.c.
211 */
212int full_write(int desc, char *ptr, size_t len)
213{
214 int total_written;
215
216 total_written = 0;
217 while (len > 0) {
218 int written = write(desc, ptr, len);
219 if (written < 0) {
220 if (errno == EINTR)
221 continue;
222 return written;
223 }
224 total_written += written;
225 ptr += written;
226 len -= written;
227 }
228 return total_written;
229}
230
231
232/**
233 * Read @p len bytes at @p ptr from descriptor @p desc, retrying if
234 * interrupted.
235 *
236 * @retval >0 the actual number of bytes read
237 *
238 * @retval 0 for EOF
239 *
240 * @retval <0 for an error.
241 *
242 * Derived from GNU C's cccp.c. */
243static int safe_read(int desc, char *ptr, size_t len)
244{
245 int n_chars;
246
247 if (len == 0)
248 return len;
249
250 do {
251 n_chars = read(desc, ptr, len);
252 } while (n_chars < 0 && errno == EINTR);
253
254 return n_chars;
255}
256
257
258/** Copy a file.
259 *
260 * This is used in conjunction with the --temp-dir, --backup, and
261 * --copy-dest options. */
262int copy_file(char *source, char *dest, mode_t mode)
263{
264 int ifd;
265 int ofd;
266 char buf[1024 * 8];
267 int len; /* Number of bytes read into `buf'. */
268
269 ifd = do_open(source, O_RDONLY, 0);
270 if (ifd == -1) {
271 rsyserr(FERROR, errno, "open %s", full_fname(source));
272 return -1;
273 }
274
275 if (robust_unlink(dest) && errno != ENOENT) {
276 rsyserr(FERROR, errno, "unlink %s", full_fname(dest));
277 return -1;
278 }
279
280 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
281 if (ofd == -1) {
282 rsyserr(FERROR, errno, "open %s", full_fname(dest));
283 close(ifd);
284 return -1;
285 }
286
287 while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
288 if (full_write(ofd, buf, len) < 0) {
289 rsyserr(FERROR, errno, "write %s", full_fname(dest));
290 close(ifd);
291 close(ofd);
292 return -1;
293 }
294 }
295
296 if (len < 0) {
297 rsyserr(FERROR, errno, "read %s", full_fname(source));
298 close(ifd);
299 close(ofd);
300 return -1;
301 }
302
303 if (close(ifd) < 0) {
304 rsyserr(FINFO, errno, "close failed on %s",
305 full_fname(source));
306 }
307
308 if (close(ofd) < 0) {
309 rsyserr(FERROR, errno, "close failed on %s",
310 full_fname(dest));
311 return -1;
312 }
313
314 return 0;
315}
316
317/* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
318#define MAX_RENAMES_DIGITS 3
319#define MAX_RENAMES 1000
320
321/**
322 * Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
323 * rename to <path>/.rsyncNNN instead.
324 *
325 * Note that successive rsync runs will shuffle the filenames around a
326 * bit as long as the file is still busy; this is because this function
327 * does not know if the unlink call is due to a new file coming in, or
328 * --delete trying to remove old .rsyncNNN files, hence it renames it
329 * each time.
330 **/
331int robust_unlink(char *fname)
332{
333#ifndef ETXTBSY
334 return do_unlink(fname);
335#else
336 static int counter = 1;
337 int rc, pos, start;
338 char path[MAXPATHLEN];
339
340 rc = do_unlink(fname);
341 if (rc == 0 || errno != ETXTBSY)
342 return rc;
343
344 if ((pos = strlcpy(path, fname, MAXPATHLEN)) >= MAXPATHLEN)
345 pos = MAXPATHLEN - 1;
346
347 while (pos > 0 && path[pos-1] != '/')
348 pos--;
349 pos += strlcpy(path+pos, ".rsync", MAXPATHLEN-pos);
350
351 if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
352 errno = ETXTBSY;
353 return -1;
354 }
355
356 /* start where the last one left off to reduce chance of clashes */
357 start = counter;
358 do {
359 sprintf(&path[pos], "%03d", counter);
360 if (++counter >= MAX_RENAMES)
361 counter = 1;
362 } while ((rc = access(path, 0)) == 0 && counter != start);
363
364 if (verbose > 0) {
365 rprintf(FINFO,"renaming %s to %s because of text busy\n",
366 safe_fname(fname), safe_fname(path));
367 }
368
369 /* maybe we should return rename()'s exit status? Nah. */
370 if (do_rename(fname, path) != 0) {
371 errno = ETXTBSY;
372 return -1;
373 }
374 return 0;
375#endif
376}
377
378/* Returns 0 on successful rename, 1 if we successfully copied the file
379 * across filesystems, -2 if copy_file() failed, and -1 on other errors. */
380int robust_rename(char *from, char *to, int mode)
381{
382 int tries = 4;
383
384 while (tries--) {
385 if (do_rename(from, to) == 0)
386 return 0;
387
388 switch (errno) {
389#ifdef ETXTBSY
390 case ETXTBSY:
391 if (robust_unlink(to) != 0)
392 return -1;
393 break;
394#endif
395 case EXDEV:
396 if (copy_file(from, to, mode) != 0)
397 return -2;
398 do_unlink(from);
399 return 1;
400 default:
401 return -1;
402 }
403 }
404 return -1;
405}
406
407
408static pid_t all_pids[10];
409static int num_pids;
410
411/** Fork and record the pid of the child. **/
412pid_t do_fork(void)
413{
414 pid_t newpid = fork();
415
416 if (newpid != 0 && newpid != -1) {
417 all_pids[num_pids++] = newpid;
418 }
419 return newpid;
420}
421
422/**
423 * Kill all children.
424 *
425 * @todo It would be kind of nice to make sure that they are actually
426 * all our children before we kill them, because their pids may have
427 * been recycled by some other process. Perhaps when we wait for a
428 * child, we should remove it from this array. Alternatively we could
429 * perhaps use process groups, but I think that would not work on
430 * ancient Unix versions that don't support them.
431 **/
432void kill_all(int sig)
433{
434 int i;
435
436 for (i = 0; i < num_pids; i++) {
437 /* Let's just be a little careful where we
438 * point that gun, hey? See kill(2) for the
439 * magic caused by negative values. */
440 pid_t p = all_pids[i];
441
442 if (p == getpid())
443 continue;
444 if (p <= 0)
445 continue;
446
447 kill(p, sig);
448 }
449}
450
451
452/** Turn a user name into a uid */
453int name_to_uid(char *name, uid_t *uid)
454{
455 struct passwd *pass;
456 if (!name || !*name)
457 return 0;
458 pass = getpwnam(name);
459 if (pass) {
460 *uid = pass->pw_uid;
461 return 1;
462 }
463 return 0;
464}
465
466/** Turn a group name into a gid */
467int name_to_gid(char *name, gid_t *gid)
468{
469 struct group *grp;
470 if (!name || !*name)
471 return 0;
472 grp = getgrnam(name);
473 if (grp) {
474 *gid = grp->gr_gid;
475 return 1;
476 }
477 return 0;
478}
479
480
481/** Lock a byte range in a open file */
482int lock_range(int fd, int offset, int len)
483{
484 struct flock lock;
485
486 lock.l_type = F_WRLCK;
487 lock.l_whence = SEEK_SET;
488 lock.l_start = offset;
489 lock.l_len = len;
490 lock.l_pid = 0;
491
492 return fcntl(fd,F_SETLK,&lock) == 0;
493}
494
495static int filter_server_path(char *arg)
496{
497 char *s;
498
499 if (server_filter_list.head) {
500 for (s = arg; (s = strchr(s, '/')) != NULL; ) {
501 *s = '\0';
502 if (check_filter(&server_filter_list, arg, 1) < 0) {
503 /* We must leave arg truncated! */
504 return 1;
505 }
506 *s++ = '/';
507 }
508 }
509 return 0;
510}
511
512static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr,
513 int *maxargs_ptr)
514{
515 char **argv = *argv_ptr;
516 int argc = *argc_ptr;
517 int maxargs = *maxargs_ptr;
518#if !defined HAVE_GLOB || !defined HAVE_GLOB_H
519 if (argc == maxargs) {
520 maxargs += MAX_ARGS;
521 if (!(argv = realloc_array(argv, char *, maxargs)))
522 out_of_memory("glob_expand_one");
523 *argv_ptr = argv;
524 *maxargs_ptr = maxargs;
525 }
526 if (!*s)
527 s = ".";
528 s = argv[argc++] = strdup(s);
529 filter_server_path(s);
530#else
531 glob_t globbuf;
532
533 if (maxargs <= argc)
534 return;
535 if (!*s)
536 s = ".";
537
538 if (sanitize_paths)
539 s = sanitize_path(NULL, s, "", 0);
540 else
541 s = strdup(s);
542
543 memset(&globbuf, 0, sizeof globbuf);
544 if (!filter_server_path(s))
545 glob(s, 0, NULL, &globbuf);
546 if (MAX((int)globbuf.gl_pathc, 1) > maxargs - argc) {
547 maxargs += globbuf.gl_pathc + MAX_ARGS;
548 if (!(argv = realloc_array(argv, char *, maxargs)))
549 out_of_memory("glob_expand_one");
550 *argv_ptr = argv;
551 *maxargs_ptr = maxargs;
552 }
553 if (globbuf.gl_pathc == 0)
554 argv[argc++] = s;
555 else {
556 int i;
557 free(s);
558 for (i = 0; i < (int)globbuf.gl_pathc; i++) {
559 if (!(argv[argc++] = strdup(globbuf.gl_pathv[i])))
560 out_of_memory("glob_expand_one");
561 }
562 }
563 globfree(&globbuf);
564#endif
565 *argc_ptr = argc;
566}
567
568/* This routine is only used in daemon mode. */
569void glob_expand(char *base1, char ***argv_ptr, int *argc_ptr, int *maxargs_ptr)
570{
571 char *s = (*argv_ptr)[*argc_ptr];
572 char *p, *q;
573 char *base = base1;
574 int base_len = strlen(base);
575
576 if (!s || !*s)
577 return;
578
579 if (strncmp(s, base, base_len) == 0)
580 s += base_len;
581
582 if (!(s = strdup(s)))
583 out_of_memory("glob_expand");
584
585 if (asprintf(&base," %s/", base1) <= 0)
586 out_of_memory("glob_expand");
587 base_len++;
588
589 for (q = s; *q; q = p + base_len) {
590 if ((p = strstr(q, base)) != NULL)
591 *p = '\0'; /* split it at this point */
592 glob_expand_one(q, argv_ptr, argc_ptr, maxargs_ptr);
593 if (!p)
594 break;
595 }
596
597 free(s);
598 free(base);
599}
600
601/**
602 * Convert a string to lower case
603 **/
604void strlower(char *s)
605{
606 while (*s) {
607 if (isupper(*(unsigned char *)s))
608 *s = tolower(*(unsigned char *)s);
609 s++;
610 }
611}
612
613/* Join strings p1 & p2 into "dest" with a guaranteed '/' between them. (If
614 * p1 ends with a '/', no extra '/' is inserted.) Returns the length of both
615 * strings + 1 (if '/' was inserted), regardless of whether the null-terminated
616 * string fits into destsize. */
617size_t pathjoin(char *dest, size_t destsize, const char *p1, const char *p2)
618{
619 size_t len = strlcpy(dest, p1, destsize);
620 if (len < destsize - 1) {
621 if (!len || dest[len-1] != '/')
622 dest[len++] = '/';
623 if (len < destsize - 1)
624 len += strlcpy(dest + len, p2, destsize - len);
625 else {
626 dest[len] = '\0';
627 len += strlen(p2);
628 }
629 }
630 else
631 len += strlen(p2) + 1; /* Assume we'd insert a '/'. */
632 return len;
633}
634
635/* Join any number of strings together, putting them in "dest". The return
636 * value is the length of all the strings, regardless of whether the null-
637 * terminated whole fits in destsize. Your list of string pointers must end
638 * with a NULL to indicate the end of the list. */
639size_t stringjoin(char *dest, size_t destsize, ...)
640{
641 va_list ap;
642 size_t len, ret = 0;
643 const char *src;
644
645 va_start(ap, destsize);
646 while (1) {
647 if (!(src = va_arg(ap, const char *)))
648 break;
649 len = strlen(src);
650 ret += len;
651 if (destsize > 1) {
652 if (len >= destsize)
653 len = destsize - 1;
654 memcpy(dest, src, len);
655 destsize -= len;
656 dest += len;
657 }
658 }
659 *dest = '\0';
660 va_end(ap);
661
662 return ret;
663}
664
665int count_dir_elements(const char *p)
666{
667 int cnt = 0, new_component = 1;
668 while (*p) {
669 if (*p++ == '/')
670 new_component = 1;
671 else if (new_component) {
672 new_component = 0;
673 cnt++;
674 }
675 }
676 return cnt;
677}
678
679/* Turns multiple adjacent slashes into a single slash, gets rid of "./"
680 * elements (but not a trailing dot dir), removes a trailing slash, and
681 * optionally collapses ".." elements (except for those at the start of the
682 * string). If the resulting name would be empty, change it into a ".". */
683unsigned int clean_fname(char *name, BOOL collapse_dot_dot)
684{
685 char *limit = name - 1, *t = name, *f = name;
686 int anchored;
687
688 if (!name)
689 return 0;
690
691 if ((anchored = *f == '/') != 0)
692 *t++ = *f++;
693 while (*f) {
694 /* discard extra slashes */
695 if (*f == '/') {
696 f++;
697 continue;
698 }
699 if (*f == '.') {
700 /* discard "." dirs (but NOT a trailing '.'!) */
701 if (f[1] == '/') {
702 f += 2;
703 continue;
704 }
705 /* collapse ".." dirs */
706 if (collapse_dot_dot
707 && f[1] == '.' && (f[2] == '/' || !f[2])) {
708 char *s = t - 1;
709 if (s == name && anchored) {
710 f += 2;
711 continue;
712 }
713 while (s > limit && *--s != '/') {}
714 if (s != t - 1 && (s < name || *s == '/')) {
715 t = s + 1;
716 f += 2;
717 continue;
718 }
719 limit = t + 2;
720 }
721 }
722 while (*f && (*t++ = *f++) != '/') {}
723 }
724
725 if (t > name+anchored && t[-1] == '/')
726 t--;
727 if (t == name)
728 *t++ = '.';
729 *t = '\0';
730
731 return t - name;
732}
733
734/* Make path appear as if a chroot had occurred. This handles a leading
735 * "/" (either removing it or expanding it) and any leading or embedded
736 * ".." components that attempt to escape past the module's top dir.
737 *
738 * If dest is NULL, a buffer is allocated to hold the result. It is legal
739 * to call with the dest and the path (p) pointing to the same buffer, but
740 * rootdir will be ignored to avoid expansion of the string.
741 *
742 * The rootdir string contains a value to use in place of a leading slash.
743 * Specify NULL to get the default of lp_path(module_id).
744 *
745 * If depth is >= 0, it is a count of how many '..'s to allow at the start
746 * of the path. Use -1 to allow unlimited depth.
747 *
748 * We also clean the path in a manner similar to clean_fname() but with a
749 * few differences:
750 *
751 * Turns multiple adjacent slashes into a single slash, gets rid of "." dir
752 * elements (INCLUDING a trailing dot dir), PRESERVES a trailing slash, and
753 * ALWAYS collapses ".." elements (except for those at the start of the
754 * string up to "depth" deep). If the resulting name would be empty,
755 * change it into a ".". */
756char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
757{
758 char *start, *sanp;
759 int rlen = 0, leave_one_dotdir = relative_paths;
760
761 if (dest != p) {
762 int plen = strlen(p);
763 if (*p == '/') {
764 if (!rootdir)
765 rootdir = lp_path(module_id);
766 rlen = strlen(rootdir);
767 depth = 0;
768 p++;
769 }
770 if (dest) {
771 if (rlen + plen + 1 >= MAXPATHLEN)
772 return NULL;
773 } else if (!(dest = new_array(char, rlen + plen + 1)))
774 out_of_memory("sanitize_path");
775 if (rlen) {
776 memcpy(dest, rootdir, rlen);
777 if (rlen > 1)
778 dest[rlen++] = '/';
779 }
780 }
781
782 start = sanp = dest + rlen;
783 while (*p != '\0') {
784 /* discard leading or extra slashes */
785 if (*p == '/') {
786 p++;
787 continue;
788 }
789 /* this loop iterates once per filename component in p.
790 * both p (and sanp if the original had a slash) should
791 * always be left pointing after a slash
792 */
793 if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
794 if (leave_one_dotdir && p[1] && sanp != dest)
795 leave_one_dotdir = 0;
796 else {
797 /* skip "." component */
798 p++;
799 continue;
800 }
801 }
802 if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
803 /* ".." component followed by slash or end */
804 if (depth <= 0 || sanp != start) {
805 p += 2;
806 if (sanp != start) {
807 /* back up sanp one level */
808 --sanp; /* now pointing at slash */
809 while (sanp > start && sanp[-1] != '/') {
810 /* skip back up to slash */
811 sanp--;
812 }
813 }
814 continue;
815 }
816 /* allow depth levels of .. at the beginning */
817 depth--;
818 /* move the virtual beginning to leave the .. alone */
819 start = sanp + 3;
820 }
821 /* copy one component through next slash */
822 while (*p && (*sanp++ = *p++) != '/') {}
823 }
824 if (sanp == dest) {
825 /* ended up with nothing, so put in "." component */
826 *sanp++ = '.';
827 }
828 *sanp = '\0';
829
830 return dest;
831}
832
833char curr_dir[MAXPATHLEN];
834unsigned int curr_dir_len;
835
836/**
837 * Like chdir(), but it keeps track of the current directory (in the
838 * global "curr_dir"), and ensures that the path size doesn't overflow.
839 * Also cleans the path using the clean_fname() function.
840 **/
841int push_dir(char *dir)
842{
843 static int initialised;
844 unsigned int len;
845
846 if (!initialised) {
847 initialised = 1;
848 getcwd(curr_dir, sizeof curr_dir - 1);
849 curr_dir_len = strlen(curr_dir);
850 }
851
852 if (!dir) /* this call was probably just to initialize */
853 return 0;
854
855 len = strlen(dir);
856 if (len == 1 && *dir == '.')
857 return 1;
858
859 if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir)
860 return 0;
861
862 if (chdir(dir))
863 return 0;
864
865 if (*dir == '/') {
866 memcpy(curr_dir, dir, len + 1);
867 curr_dir_len = len;
868 } else {
869 curr_dir[curr_dir_len++] = '/';
870 memcpy(curr_dir + curr_dir_len, dir, len + 1);
871 curr_dir_len += len;
872 }
873
874 curr_dir_len = clean_fname(curr_dir, 1);
875
876 return 1;
877}
878
879/**
880 * Reverse a push_dir() call. You must pass in an absolute path
881 * that was copied from a prior value of "curr_dir".
882 **/
883int pop_dir(char *dir)
884{
885 if (chdir(dir))
886 return 0;
887
888 curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir);
889 if (curr_dir_len >= sizeof curr_dir)
890 curr_dir_len = sizeof curr_dir - 1;
891
892 return 1;
893}
894
895/* Return the filename, turning any non-printable characters into escaped
896 * characters (e.g. \n -> \012, \ -> \\). This ensures that outputting it
897 * cannot generate an empty line nor corrupt the screen. This function can
898 * return only MAX_SAFE_NAMES values at a time! The returned value can be
899 * longer than MAXPATHLEN (because we may be trying to output an error about
900 * a too-long filename)! */
901char *safe_fname(const char *fname)
902{
903#define MAX_SAFE_NAMES 4
904 static char fbuf[MAX_SAFE_NAMES][MAXPATHLEN*2];
905 static int ndx = 0;
906 int limit = sizeof fbuf / MAX_SAFE_NAMES - 1;
907 char *t;
908
909 ndx = (ndx + 1) % MAX_SAFE_NAMES;
910 for (t = fbuf[ndx]; *fname; fname++) {
911 if (*fname == '\\') {
912 if ((limit -= 2) < 0)
913 break;
914 *t++ = '\\';
915 *t++ = '\\';
916 } else if (!isprint(*(uchar*)fname)) {
917 if ((limit -= 4) < 0)
918 break;
919 sprintf(t, "\\%03o", *(uchar*)fname);
920 t += 4;
921 } else {
922 if (--limit < 0)
923 break;
924 *t++ = *fname;
925 }
926 }
927 *t = '\0';
928
929 return fbuf[ndx];
930}
931
932/**
933 * Return a quoted string with the full pathname of the indicated filename.
934 * The string " (in MODNAME)" may also be appended. The returned pointer
935 * remains valid until the next time full_fname() is called.
936 **/
937char *full_fname(const char *fn)
938{
939 static char *result = NULL;
940 char *m1, *m2, *m3;
941 char *p1, *p2;
942
943 if (result)
944 free(result);
945
946 fn = safe_fname(fn);
947 if (*fn == '/')
948 p1 = p2 = "";
949 else {
950 p1 = curr_dir;
951 for (p2 = p1; *p2 == '/'; p2++) {}
952 if (*p2)
953 p2 = "/";
954 }
955 if (module_id >= 0) {
956 m1 = " (in ";
957 m2 = lp_name(module_id);
958 m3 = ")";
959 if (p1 == curr_dir) {
960 if (!lp_use_chroot(module_id)) {
961 char *p = lp_path(module_id);
962 if (*p != '/' || p[1])
963 p1 += strlen(p);
964 }
965 }
966 } else
967 m1 = m2 = m3 = "";
968
969 asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
970
971 return result;
972}
973
974static char partial_fname[MAXPATHLEN];
975
976char *partial_dir_fname(const char *fname)
977{
978 char *t = partial_fname;
979 int sz = sizeof partial_fname;
980 const char *fn;
981
982 if ((fn = strrchr(fname, '/')) != NULL) {
983 fn++;
984 if (*partial_dir != '/') {
985 int len = fn - fname;
986 strncpy(t, fname, len); /* safe */
987 t += len;
988 sz -= len;
989 }
990 } else
991 fn = fname;
992 if ((int)pathjoin(t, sz, partial_dir, fn) >= sz)
993 return NULL;
994 if (server_filter_list.head) {
995 static int len;
996 if (!len)
997 len = strlen(partial_dir);
998 t[len] = '\0';
999 if (check_filter(&server_filter_list, partial_fname, 1) < 0)
1000 return NULL;
1001 t[len] = '/';
1002 if (check_filter(&server_filter_list, partial_fname, 0) < 0)
1003 return NULL;
1004 }
1005
1006 return partial_fname;
1007}
1008
1009/* If no --partial-dir option was specified, we don't need to do anything
1010 * (the partial-dir is essentially '.'), so just return success. */
1011int handle_partial_dir(const char *fname, int create)
1012{
1013 char *fn, *dir;
1014
1015 if (fname != partial_fname)
1016 return 1;
1017 if (!create && *partial_dir == '/')
1018 return 1;
1019 if (!(fn = strrchr(partial_fname, '/')))
1020 return 1;
1021
1022 *fn = '\0';
1023 dir = partial_fname;
1024 if (create) {
1025 STRUCT_STAT st;
1026 int statret = do_lstat(dir, &st);
1027 if (statret == 0 && !S_ISDIR(st.st_mode)) {
1028 if (do_unlink(dir) < 0)
1029 return 0;
1030 statret = -1;
1031 }
1032 if (statret < 0 && do_mkdir(dir, 0700) < 0)
1033 return 0;
1034 } else
1035 do_rmdir(dir);
1036 *fn = '/';
1037
1038 return 1;
1039}
1040
1041/** We need to supply our own strcmp function for file list comparisons
1042 to ensure that signed/unsigned usage is consistent between machines. */
1043int u_strcmp(const char *cs1, const char *cs2)
1044{
1045 const uchar *s1 = (const uchar *)cs1;
1046 const uchar *s2 = (const uchar *)cs2;
1047
1048 while (*s1 && *s2 && (*s1 == *s2)) {
1049 s1++; s2++;
1050 }
1051
1052 return (int)*s1 - (int)*s2;
1053}
1054
1055
1056
1057/**
1058 * Determine if a symlink points outside the current directory tree.
1059 * This is considered "unsafe" because e.g. when mirroring somebody
1060 * else's machine it might allow them to establish a symlink to
1061 * /etc/passwd, and then read it through a web server.
1062 *
1063 * Null symlinks and absolute symlinks are always unsafe.
1064 *
1065 * Basically here we are concerned with symlinks whose target contains
1066 * "..", because this might cause us to walk back up out of the
1067 * transferred directory. We are not allowed to go back up and
1068 * reenter.
1069 *
1070 * @param dest Target of the symlink in question.
1071 *
1072 * @param src Top source directory currently applicable. Basically this
1073 * is the first parameter to rsync in a simple invocation, but it's
1074 * modified by flist.c in slightly complex ways.
1075 *
1076 * @retval True if unsafe
1077 * @retval False is unsafe
1078 *
1079 * @sa t_unsafe.c
1080 **/
1081int unsafe_symlink(const char *dest, const char *src)
1082{
1083 const char *name, *slash;
1084 int depth = 0;
1085
1086 /* all absolute and null symlinks are unsafe */
1087 if (!dest || !*dest || *dest == '/')
1088 return 1;
1089
1090 /* find out what our safety margin is */
1091 for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
1092 if (strncmp(name, "../", 3) == 0) {
1093 depth = 0;
1094 } else if (strncmp(name, "./", 2) == 0) {
1095 /* nothing */
1096 } else {
1097 depth++;
1098 }
1099 }
1100 if (strcmp(name, "..") == 0)
1101 depth = 0;
1102
1103 for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
1104 if (strncmp(name, "../", 3) == 0) {
1105 /* if at any point we go outside the current directory
1106 then stop - it is unsafe */
1107 if (--depth < 0)
1108 return 1;
1109 } else if (strncmp(name, "./", 2) == 0) {
1110 /* nothing */
1111 } else {
1112 depth++;
1113 }
1114 }
1115 if (strcmp(name, "..") == 0)
1116 depth--;
1117
1118 return (depth < 0);
1119}
1120
1121
1122/**
1123 * Return the date and time as a string
1124 **/
1125char *timestring(time_t t)
1126{
1127 static char TimeBuf[200];
1128 struct tm *tm = localtime(&t);
1129
1130#ifdef HAVE_STRFTIME
1131 strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
1132#else
1133 strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
1134#endif
1135
1136 if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
1137 TimeBuf[strlen(TimeBuf)-1] = 0;
1138 }
1139
1140 return(TimeBuf);
1141}
1142
1143
1144/**
1145 * Sleep for a specified number of milliseconds.
1146 *
1147 * Always returns TRUE. (In the future it might return FALSE if
1148 * interrupted.)
1149 **/
1150int msleep(int t)
1151{
1152 int tdiff = 0;
1153 struct timeval tval, t1, t2;
1154
1155 gettimeofday(&t1, NULL);
1156
1157 while (tdiff < t) {
1158 tval.tv_sec = (t-tdiff)/1000;
1159 tval.tv_usec = 1000*((t-tdiff)%1000);
1160
1161 errno = 0;
1162 select(0,NULL,NULL, NULL, &tval);
1163
1164 gettimeofday(&t2, NULL);
1165 tdiff = (t2.tv_sec - t1.tv_sec)*1000 +
1166 (t2.tv_usec - t1.tv_usec)/1000;
1167 }
1168
1169 return True;
1170}
1171
1172
1173/**
1174 * Determine if two file modification times are equivalent (either
1175 * exact or in the modification timestamp window established by
1176 * --modify-window).
1177 *
1178 * @retval 0 if the times should be treated as the same
1179 *
1180 * @retval +1 if the first is later
1181 *
1182 * @retval -1 if the 2nd is later
1183 **/
1184int cmp_modtime(time_t file1, time_t file2)
1185{
1186 if (file2 > file1) {
1187 if (file2 - file1 <= modify_window)
1188 return 0;
1189 return -1;
1190 }
1191 if (file1 - file2 <= modify_window)
1192 return 0;
1193 return 1;
1194}
1195
1196
1197#ifdef __INSURE__XX
1198#include <dlfcn.h>
1199
1200/**
1201 This routine is a trick to immediately catch errors when debugging
1202 with insure. A xterm with a gdb is popped up when insure catches
1203 a error. It is Linux specific.
1204**/
1205int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
1206{
1207 static int (*fn)();
1208 int ret;
1209 char *cmd;
1210
1211 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'",
1212 getpid(), getpid(), getpid());
1213
1214 if (!fn) {
1215 static void *h;
1216 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
1217 fn = dlsym(h, "_Insure_trap_error");
1218 }
1219
1220 ret = fn(a1, a2, a3, a4, a5, a6);
1221
1222 system(cmd);
1223
1224 free(cmd);
1225
1226 return ret;
1227}
1228#endif
1229
1230
1231#define MALLOC_MAX 0x40000000
1232
1233void *_new_array(unsigned int size, unsigned long num)
1234{
1235 if (num >= MALLOC_MAX/size)
1236 return NULL;
1237 return malloc(size * num);
1238}
1239
1240void *_realloc_array(void *ptr, unsigned int size, unsigned long num)
1241{
1242 if (num >= MALLOC_MAX/size)
1243 return NULL;
1244 /* No realloc should need this, but just in case... */
1245 if (!ptr)
1246 return malloc(size * num);
1247 return realloc(ptr, size * num);
1248}
1249
1250/* Take a filename and filename length and return the most significant
1251 * filename suffix we can find. This ignores suffixes such as "~",
1252 * ".bak", ".orig", ".~1~", etc. */
1253const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr)
1254{
1255 const char *suf, *s;
1256 BOOL had_tilde;
1257 int s_len;
1258
1259 /* One or more dots at the start aren't a suffix. */
1260 while (fn_len && *fn == '.') fn++, fn_len--;
1261
1262 /* Ignore the ~ in a "foo~" filename. */
1263 if (fn_len > 1 && fn[fn_len-1] == '~')
1264 fn_len--, had_tilde = True;
1265 else
1266 had_tilde = False;
1267
1268 /* Assume we don't find an suffix. */
1269 suf = "";
1270 *len_ptr = 0;
1271
1272 /* Find the last significant suffix. */
1273 for (s = fn + fn_len; fn_len > 1; ) {
1274 while (*--s != '.' && s != fn) {}
1275 if (s == fn)
1276 break;
1277 s_len = fn_len - (s - fn);
1278 fn_len = s - fn;
1279 if (s_len == 4) {
1280 if (strcmp(s+1, "bak") == 0
1281 || strcmp(s+1, "old") == 0)
1282 continue;
1283 } else if (s_len == 5) {
1284 if (strcmp(s+1, "orig") == 0)
1285 continue;
1286 } else if (s_len > 2 && had_tilde
1287 && s[1] == '~' && isdigit(*(uchar*)(s+2)))
1288 continue;
1289 *len_ptr = s_len;
1290 suf = s;
1291 if (s_len == 1)
1292 break;
1293 /* Determine if the suffix is all digits. */
1294 for (s++, s_len--; s_len > 0; s++, s_len--) {
1295 if (!isdigit(*(uchar*)s))
1296 return suf;
1297 }
1298 /* An all-digit suffix may not be that signficant. */
1299 s = suf;
1300 }
1301
1302 return suf;
1303}
1304
1305/* This is an implementation of the Levenshtein distance algorithm. It
1306 * was implemented to avoid needing a two-dimensional matrix (to save
1307 * memory). It was also tweaked to try to factor in the ASCII distance
1308 * between changed characters as a minor distance quantity. The normal
1309 * Levenshtein units of distance (each signifying a single change between
1310 * the two strings) are defined as a "UNIT". */
1311
1312#define UNIT (1 << 16)
1313
1314uint32 fuzzy_distance(const char *s1, int len1, const char *s2, int len2)
1315{
1316 uint32 a[MAXPATHLEN], diag, above, left, diag_inc, above_inc, left_inc;
1317 int32 cost;
1318 int i1, i2;
1319
1320 if (!len1 || !len2) {
1321 if (!len1) {
1322 s1 = s2;
1323 len1 = len2;
1324 }
1325 for (i1 = 0, cost = 0; i1 < len1; i1++)
1326 cost += s1[i1];
1327 return (int32)len1 * UNIT + cost;
1328 }
1329
1330 for (i2 = 0; i2 < len2; i2++)
1331 a[i2] = (i2+1) * UNIT;
1332
1333 for (i1 = 0; i1 < len1; i1++) {
1334 diag = i1 * UNIT;
1335 above = (i1+1) * UNIT;
1336 for (i2 = 0; i2 < len2; i2++) {
1337 left = a[i2];
1338 if ((cost = *((uchar*)s1+i1) - *((uchar*)s2+i2)) != 0) {
1339 if (cost < 0)
1340 cost = UNIT - cost;
1341 else
1342 cost = UNIT + cost;
1343 }
1344 diag_inc = diag + cost;
1345 left_inc = left + UNIT + *((uchar*)s1+i1);
1346 above_inc = above + UNIT + *((uchar*)s2+i2);
1347 a[i2] = above = left < above
1348 ? (left_inc < diag_inc ? left_inc : diag_inc)
1349 : (above_inc < diag_inc ? above_inc : diag_inc);
1350 diag = left;
1351 }
1352 }
1353
1354 return a[len2-1];
1355}