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