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