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