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