- Changed set_modtime() to take the file's mode as an arg.
[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         int i;
532
533         if (maxargs <= argc)
534                 return;
535         if (!*s)
536                 s = ".";
537
538         if (sanitize_paths)
539                 s = sanitize_path(NULL, s, "", 0);
540         else
541                 s = strdup(s);
542
543         memset(&globbuf, 0, sizeof globbuf);
544         if (!filter_server_path(s))
545                 glob(s, 0, NULL, &globbuf);
546         if (MAX((int)globbuf.gl_pathc, 1) > maxargs - argc) {
547                 maxargs += globbuf.gl_pathc + MAX_ARGS;
548                 if (!(argv = realloc_array(argv, char *, maxargs)))
549                         out_of_memory("glob_expand_one");
550                 *argv_ptr = argv;
551                 *maxargs_ptr = maxargs;
552         }
553         if (globbuf.gl_pathc == 0)
554                 argv[argc++] = s;
555         else {
556                 int j = globbuf.gl_pathc;
557                 free(s);
558                 for (i = 0; i < j; i++) {
559                         if (!(argv[argc++] = strdup(globbuf.gl_pathv[i])))
560                                 out_of_memory("glob_expand_one");
561                 }
562         }
563         globfree(&globbuf);
564 #endif
565         *argc_ptr = argc;
566 }
567
568 /* This routine is only used in daemon mode. */
569 void glob_expand(char *base1, char ***argv_ptr, int *argc_ptr, int *maxargs_ptr)
570 {
571         char *s = (*argv_ptr)[*argc_ptr];
572         char *p, *q;
573         char *base = base1;
574         int base_len = strlen(base);
575
576         if (!s || !*s)
577                 return;
578
579         if (strncmp(s, base, base_len) == 0)
580                 s += base_len;
581
582         if (!(s = strdup(s)))
583                 out_of_memory("glob_expand");
584
585         if (asprintf(&base," %s/", base1) <= 0)
586                 out_of_memory("glob_expand");
587         base_len++;
588
589         for (q = s; *q; q = p + base_len) {
590                 if ((p = strstr(q, base)) != NULL)
591                         *p = '\0'; /* split it at this point */
592                 glob_expand_one(q, argv_ptr, argc_ptr, maxargs_ptr);
593                 if (!p)
594                         break;
595         }
596
597         free(s);
598         free(base);
599 }
600
601 /**
602  * Convert a string to lower case
603  **/
604 void strlower(char *s)
605 {
606         while (*s) {
607                 if (isupper(*(unsigned char *)s))
608                         *s = tolower(*(unsigned char *)s);
609                 s++;
610         }
611 }
612
613 /* Join strings p1 & p2 into "dest" with a guaranteed '/' between them.  (If
614  * p1 ends with a '/', no extra '/' is inserted.)  Returns the length of both
615  * strings + 1 (if '/' was inserted), regardless of whether the null-terminated
616  * string fits into destsize. */
617 size_t pathjoin(char *dest, size_t destsize, const char *p1, const char *p2)
618 {
619         size_t len = strlcpy(dest, p1, destsize);
620         if (len < destsize - 1) {
621                 if (!len || dest[len-1] != '/')
622                         dest[len++] = '/';
623                 if (len < destsize - 1)
624                         len += strlcpy(dest + len, p2, destsize - len);
625                 else {
626                         dest[len] = '\0';
627                         len += strlen(p2);
628                 }
629         }
630         else
631                 len += strlen(p2) + 1; /* Assume we'd insert a '/'. */
632         return len;
633 }
634
635 /* Join any number of strings together, putting them in "dest".  The return
636  * value is the length of all the strings, regardless of whether the null-
637  * terminated whole fits in destsize.  Your list of string pointers must end
638  * with a NULL to indicate the end of the list. */
639 size_t stringjoin(char *dest, size_t destsize, ...)
640 {
641         va_list ap;
642         size_t len, ret = 0;
643         const char *src;
644
645         va_start(ap, destsize);
646         while (1) {
647                 if (!(src = va_arg(ap, const char *)))
648                         break;
649                 len = strlen(src);
650                 ret += len;
651                 if (destsize > 1) {
652                         if (len >= destsize)
653                                 len = destsize - 1;
654                         memcpy(dest, src, len);
655                         destsize -= len;
656                         dest += len;
657                 }
658         }
659         *dest = '\0';
660         va_end(ap);
661
662         return ret;
663 }
664
665 int count_dir_elements(const char *p)
666 {
667         int cnt = 0, new_component = 1;
668         while (*p) {
669                 if (*p++ == '/')
670                         new_component = 1;
671                 else if (new_component) {
672                         new_component = 0;
673                         cnt++;
674                 }
675         }
676         return cnt;
677 }
678
679 /* Turns multiple adjacent slashes into a single slash, gets rid of "./"
680  * elements (but not a trailing dot dir), removes a trailing slash, and
681  * optionally collapses ".." elements (except for those at the start of the
682  * string).  If the resulting name would be empty, change it into a ".". */
683 unsigned int clean_fname(char *name, BOOL collapse_dot_dot)
684 {
685         char *limit = name - 1, *t = name, *f = name;
686         int anchored;
687
688         if (!name)
689                 return 0;
690
691         if ((anchored = *f == '/') != 0)
692                 *t++ = *f++;
693         while (*f) {
694                 /* discard extra slashes */
695                 if (*f == '/') {
696                         f++;
697                         continue;
698                 }
699                 if (*f == '.') {
700                         /* discard "." dirs (but NOT a trailing '.'!) */
701                         if (f[1] == '/') {
702                                 f += 2;
703                                 continue;
704                         }
705                         /* collapse ".." dirs */
706                         if (collapse_dot_dot
707                             && f[1] == '.' && (f[2] == '/' || !f[2])) {
708                                 char *s = t - 1;
709                                 if (s == name && anchored) {
710                                         f += 2;
711                                         continue;
712                                 }
713                                 while (s > limit && *--s != '/') {}
714                                 if (s != t - 1 && (s < name || *s == '/')) {
715                                         t = s + 1;
716                                         f += 2;
717                                         continue;
718                                 }
719                                 limit = t + 2;
720                         }
721                 }
722                 while (*f && (*t++ = *f++) != '/') {}
723         }
724
725         if (t > name+anchored && t[-1] == '/')
726                 t--;
727         if (t == name)
728                 *t++ = '.';
729         *t = '\0';
730
731         return t - name;
732 }
733
734 /* Make path appear as if a chroot had occurred.  This handles a leading
735  * "/" (either removing it or expanding it) and any leading or embedded
736  * ".." components that attempt to escape past the module's top dir.
737  *
738  * If dest is NULL, a buffer is allocated to hold the result.  It is legal
739  * to call with the dest and the path (p) pointing to the same buffer, but
740  * rootdir will be ignored to avoid expansion of the string.
741  *
742  * The rootdir string contains a value to use in place of a leading slash.
743  * Specify NULL to get the default of lp_path(module_id).
744  *
745  * If depth is >= 0, it is a count of how many '..'s to allow at the start
746  * of the path.  Use -1 to allow unlimited depth.
747  *
748  * We also clean the path in a manner similar to clean_fname() but with a
749  * few differences: 
750  *
751  * Turns multiple adjacent slashes into a single slash, gets rid of "." dir
752  * elements (INCLUDING a trailing dot dir), PRESERVES a trailing slash, and
753  * ALWAYS collapses ".." elements (except for those at the start of the
754  * string up to "depth" deep).  If the resulting name would be empty,
755  * change it into a ".". */
756 char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
757 {
758         char *start, *sanp;
759         int rlen = 0;
760
761         if (dest != p) {
762                 int plen = strlen(p);
763                 if (*p == '/') {
764                         if (!rootdir)
765                                 rootdir = lp_path(module_id);
766                         rlen = strlen(rootdir);
767                         depth = 0;
768                         p++;
769                 }
770                 if (dest) {
771                         if (rlen + plen + 1 >= MAXPATHLEN)
772                                 return NULL;
773                 } else if (!(dest = new_array(char, rlen + plen + 1)))
774                         out_of_memory("sanitize_path");
775                 if (rlen) {
776                         memcpy(dest, rootdir, rlen);
777                         if (rlen > 1)
778                                 dest[rlen++] = '/';
779                 }
780         }
781
782         start = sanp = dest + rlen;
783         while (*p != '\0') {
784                 /* discard leading or extra slashes */
785                 if (*p == '/') {
786                         p++;
787                         continue;
788                 }
789                 /* this loop iterates once per filename component in p.
790                  * both p (and sanp if the original had a slash) should
791                  * always be left pointing after a slash
792                  */
793                 if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
794                         /* skip "." component */
795                         p++;
796                         continue;
797                 }
798                 if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
799                         /* ".." component followed by slash or end */
800                         if (depth <= 0 || sanp != start) {
801                                 p += 2;
802                                 if (sanp != start) {
803                                         /* back up sanp one level */
804                                         --sanp; /* now pointing at slash */
805                                         while (sanp > start && sanp[-1] != '/') {
806                                                 /* skip back up to slash */
807                                                 sanp--;
808                                         }
809                                 }
810                                 continue;
811                         }
812                         /* allow depth levels of .. at the beginning */
813                         depth--;
814                         /* move the virtual beginning to leave the .. alone */
815                         start = sanp + 3;
816                 }
817                 /* copy one component through next slash */
818                 while (*p && (*sanp++ = *p++) != '/') {}
819         }
820         if (sanp == dest) {
821                 /* ended up with nothing, so put in "." component */
822                 *sanp++ = '.';
823         }
824         *sanp = '\0';
825
826         return dest;
827 }
828
829 char curr_dir[MAXPATHLEN];
830 unsigned int curr_dir_len;
831
832 /**
833  * Like chdir(), but it keeps track of the current directory (in the
834  * global "curr_dir"), and ensures that the path size doesn't overflow.
835  * Also cleans the path using the clean_fname() function.
836  **/
837 int push_dir(char *dir)
838 {
839         static int initialised;
840         unsigned int len;
841
842         if (!initialised) {
843                 initialised = 1;
844                 getcwd(curr_dir, sizeof curr_dir - 1);
845                 curr_dir_len = strlen(curr_dir);
846         }
847
848         if (!dir)       /* this call was probably just to initialize */
849                 return 0;
850
851         len = strlen(dir);
852         if (len == 1 && *dir == '.')
853                 return 1;
854
855         if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir)
856                 return 0;
857
858         if (chdir(dir))
859                 return 0;
860
861         if (*dir == '/') {
862                 memcpy(curr_dir, dir, len + 1);
863                 curr_dir_len = len;
864         } else {
865                 curr_dir[curr_dir_len++] = '/';
866                 memcpy(curr_dir + curr_dir_len, dir, len + 1);
867                 curr_dir_len += len;
868         }
869
870         curr_dir_len = clean_fname(curr_dir, 1);
871
872         return 1;
873 }
874
875 /**
876  * Reverse a push_dir() call.  You must pass in an absolute path
877  * that was copied from a prior value of "curr_dir".
878  **/
879 int pop_dir(char *dir)
880 {
881         if (chdir(dir))
882                 return 0;
883
884         curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir);
885         if (curr_dir_len >= sizeof curr_dir)
886                 curr_dir_len = sizeof curr_dir - 1;
887
888         return 1;
889 }
890
891 /* Return the filename, turning any non-printable characters into escaped
892  * characters (e.g. \n -> \012, \ -> \\).  This ensures that outputting it
893  * cannot generate an empty line nor corrupt the screen.  This function can
894  * return only MAX_SAFE_NAMES values at a time!  The returned value can be
895  * longer than MAXPATHLEN (because we may be trying to output an error about
896  * a too-long filename)! */
897 char *safe_fname(const char *fname)
898 {
899 #define MAX_SAFE_NAMES 4
900         static char fbuf[MAX_SAFE_NAMES][MAXPATHLEN*2];
901         static int ndx = 0;
902         int limit = sizeof fbuf / MAX_SAFE_NAMES - 1;
903         char *t;
904
905         ndx = (ndx + 1) % MAX_SAFE_NAMES;
906         for (t = fbuf[ndx]; *fname; fname++) {
907                 if (*fname == '\\') {
908                         if ((limit -= 2) < 0)
909                                 break;
910                         *t++ = '\\';
911                         *t++ = '\\';
912                 } else if (!isprint(*(uchar*)fname)) {
913                         if ((limit -= 4) < 0)
914                                 break;
915                         sprintf(t, "\\%03o", *(uchar*)fname);
916                         t += 4;
917                 } else {
918                         if (--limit < 0)
919                                 break;
920                         *t++ = *fname;
921                 }
922         }
923         *t = '\0';
924
925         return fbuf[ndx];
926 }
927
928 /**
929  * Return a quoted string with the full pathname of the indicated filename.
930  * The string " (in MODNAME)" may also be appended.  The returned pointer
931  * remains valid until the next time full_fname() is called.
932  **/
933 char *full_fname(const char *fn)
934 {
935         static char *result = NULL;
936         char *m1, *m2, *m3;
937         char *p1, *p2;
938
939         if (result)
940                 free(result);
941
942         fn = safe_fname(fn);
943         if (*fn == '/')
944                 p1 = p2 = "";
945         else {
946                 p1 = curr_dir;
947                 for (p2 = p1; *p2 == '/'; p2++) {}
948                 if (*p2)
949                         p2 = "/";
950         }
951         if (module_id >= 0) {
952                 m1 = " (in ";
953                 m2 = lp_name(module_id);
954                 m3 = ")";
955                 if (p1 == curr_dir) {
956                         if (!lp_use_chroot(module_id)) {
957                                 char *p = lp_path(module_id);
958                                 if (*p != '/' || p[1])
959                                         p1 += strlen(p);
960                         }
961                 }
962         } else
963                 m1 = m2 = m3 = "";
964
965         asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
966
967         return result;
968 }
969
970 static char partial_fname[MAXPATHLEN];
971
972 char *partial_dir_fname(const char *fname)
973 {
974         char *t = partial_fname;
975         int sz = sizeof partial_fname;
976         const char *fn;
977
978         if ((fn = strrchr(fname, '/')) != NULL) {
979                 fn++;
980                 if (*partial_dir != '/') {
981                         int len = fn - fname;
982                         strncpy(t, fname, len); /* safe */
983                         t += len;
984                         sz -= len;
985                 }
986         } else
987                 fn = fname;
988         if ((int)pathjoin(t, sz, partial_dir, fn) >= sz)
989                 return NULL;
990         if (server_filter_list.head) {
991                 static int len;
992                 if (!len)
993                         len = strlen(partial_dir);
994                 t[len] = '\0';
995                 if (check_filter(&server_filter_list, partial_fname, 1) < 0)
996                         return NULL;
997                 t[len] = '/';
998                 if (check_filter(&server_filter_list, partial_fname, 0) < 0)
999                         return NULL;
1000         }
1001
1002         return partial_fname;
1003 }
1004
1005 /* If no --partial-dir option was specified, we don't need to do anything
1006  * (the partial-dir is essentially '.'), so just return success. */
1007 int handle_partial_dir(const char *fname, int create)
1008 {
1009         char *fn, *dir;
1010
1011         if (fname != partial_fname)
1012                 return 1;
1013         if (!create && *partial_dir == '/')
1014                 return 1;
1015         if (!(fn = strrchr(partial_fname, '/')))
1016                 return 1;
1017
1018         *fn = '\0';
1019         dir = partial_fname;
1020         if (create) {
1021                 STRUCT_STAT st;
1022                 int statret = do_lstat(dir, &st);
1023                 if (statret == 0 && !S_ISDIR(st.st_mode)) {
1024                         if (do_unlink(dir) < 0)
1025                                 return 0;
1026                         statret = -1;
1027                 }
1028                 if (statret < 0 && do_mkdir(dir, 0700) < 0)
1029                         return 0;
1030         } else
1031                 do_rmdir(dir);
1032         *fn = '/';
1033
1034         return 1;
1035 }
1036
1037 /** We need to supply our own strcmp function for file list comparisons
1038    to ensure that signed/unsigned usage is consistent between machines. */
1039 int u_strcmp(const char *cs1, const char *cs2)
1040 {
1041         const uchar *s1 = (const uchar *)cs1;
1042         const uchar *s2 = (const uchar *)cs2;
1043
1044         while (*s1 && *s2 && (*s1 == *s2)) {
1045                 s1++; s2++;
1046         }
1047
1048         return (int)*s1 - (int)*s2;
1049 }
1050
1051
1052
1053 /**
1054  * Determine if a symlink points outside the current directory tree.
1055  * This is considered "unsafe" because e.g. when mirroring somebody
1056  * else's machine it might allow them to establish a symlink to
1057  * /etc/passwd, and then read it through a web server.
1058  *
1059  * Null symlinks and absolute symlinks are always unsafe.
1060  *
1061  * Basically here we are concerned with symlinks whose target contains
1062  * "..", because this might cause us to walk back up out of the
1063  * transferred directory.  We are not allowed to go back up and
1064  * reenter.
1065  *
1066  * @param dest Target of the symlink in question.
1067  *
1068  * @param src Top source directory currently applicable.  Basically this
1069  * is the first parameter to rsync in a simple invocation, but it's
1070  * modified by flist.c in slightly complex ways.
1071  *
1072  * @retval True if unsafe
1073  * @retval False is unsafe
1074  *
1075  * @sa t_unsafe.c
1076  **/
1077 int unsafe_symlink(const char *dest, const char *src)
1078 {
1079         const char *name, *slash;
1080         int depth = 0;
1081
1082         /* all absolute and null symlinks are unsafe */
1083         if (!dest || !*dest || *dest == '/')
1084                 return 1;
1085
1086         /* find out what our safety margin is */
1087         for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
1088                 if (strncmp(name, "../", 3) == 0) {
1089                         depth = 0;
1090                 } else if (strncmp(name, "./", 2) == 0) {
1091                         /* nothing */
1092                 } else {
1093                         depth++;
1094                 }
1095         }
1096         if (strcmp(name, "..") == 0)
1097                 depth = 0;
1098
1099         for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
1100                 if (strncmp(name, "../", 3) == 0) {
1101                         /* if at any point we go outside the current directory
1102                            then stop - it is unsafe */
1103                         if (--depth < 0)
1104                                 return 1;
1105                 } else if (strncmp(name, "./", 2) == 0) {
1106                         /* nothing */
1107                 } else {
1108                         depth++;
1109                 }
1110         }
1111         if (strcmp(name, "..") == 0)
1112                 depth--;
1113
1114         return (depth < 0);
1115 }
1116
1117
1118 /**
1119  * Return the date and time as a string
1120  **/
1121 char *timestring(time_t t)
1122 {
1123         static char TimeBuf[200];
1124         struct tm *tm = localtime(&t);
1125
1126 #ifdef HAVE_STRFTIME
1127         strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
1128 #else
1129         strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
1130 #endif
1131
1132         if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
1133                 TimeBuf[strlen(TimeBuf)-1] = 0;
1134         }
1135
1136         return(TimeBuf);
1137 }
1138
1139
1140 /**
1141  * Sleep for a specified number of milliseconds.
1142  *
1143  * Always returns TRUE.  (In the future it might return FALSE if
1144  * interrupted.)
1145  **/
1146 int msleep(int t)
1147 {
1148         int tdiff = 0;
1149         struct timeval tval, t1, t2;
1150
1151         gettimeofday(&t1, NULL);
1152
1153         while (tdiff < t) {
1154                 tval.tv_sec = (t-tdiff)/1000;
1155                 tval.tv_usec = 1000*((t-tdiff)%1000);
1156
1157                 errno = 0;
1158                 select(0,NULL,NULL, NULL, &tval);
1159
1160                 gettimeofday(&t2, NULL);
1161                 tdiff = (t2.tv_sec - t1.tv_sec)*1000 +
1162                         (t2.tv_usec - t1.tv_usec)/1000;
1163         }
1164
1165         return True;
1166 }
1167
1168
1169 /**
1170  * Determine if two file modification times are equivalent (either
1171  * exact or in the modification timestamp window established by
1172  * --modify-window).
1173  *
1174  * @retval 0 if the times should be treated as the same
1175  *
1176  * @retval +1 if the first is later
1177  *
1178  * @retval -1 if the 2nd is later
1179  **/
1180 int cmp_modtime(time_t file1, time_t file2)
1181 {
1182         if (file2 > file1) {
1183                 if (file2 - file1 <= modify_window)
1184                         return 0;
1185                 return -1;
1186         }
1187         if (file1 - file2 <= modify_window)
1188                 return 0;
1189         return 1;
1190 }
1191
1192
1193 #ifdef __INSURE__XX
1194 #include <dlfcn.h>
1195
1196 /**
1197    This routine is a trick to immediately catch errors when debugging
1198    with insure. A xterm with a gdb is popped up when insure catches
1199    a error. It is Linux specific.
1200 **/
1201 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
1202 {
1203         static int (*fn)();
1204         int ret;
1205         char *cmd;
1206
1207         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'",
1208                 getpid(), getpid(), getpid());
1209
1210         if (!fn) {
1211                 static void *h;
1212                 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
1213                 fn = dlsym(h, "_Insure_trap_error");
1214         }
1215
1216         ret = fn(a1, a2, a3, a4, a5, a6);
1217
1218         system(cmd);
1219
1220         free(cmd);
1221
1222         return ret;
1223 }
1224 #endif
1225
1226
1227 #define MALLOC_MAX 0x40000000
1228
1229 void *_new_array(unsigned int size, unsigned long num)
1230 {
1231         if (num >= MALLOC_MAX/size)
1232                 return NULL;
1233         return malloc(size * num);
1234 }
1235
1236 void *_realloc_array(void *ptr, unsigned int size, unsigned long num)
1237 {
1238         if (num >= MALLOC_MAX/size)
1239                 return NULL;
1240         /* No realloc should need this, but just in case... */
1241         if (!ptr)
1242                 return malloc(size * num);
1243         return realloc(ptr, size * num);
1244 }
1245
1246 /* Take a filename and filename length and return the most significant
1247  * filename suffix we can find.  This ignores suffixes such as "~",
1248  * ".bak", ".orig", ".~1~", etc. */
1249 const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr)
1250 {
1251         const char *suf, *s;
1252         BOOL had_tilde;
1253         int s_len;
1254
1255         /* One or more dots at the start aren't a suffix. */
1256         while (fn_len && *fn == '.') fn++, fn_len--;
1257
1258         /* Ignore the ~ in a "foo~" filename. */
1259         if (fn_len > 1 && fn[fn_len-1] == '~')
1260                 fn_len--, had_tilde = True;
1261         else
1262                 had_tilde = False;
1263
1264         /* Assume we don't find an suffix. */
1265         suf = "";
1266         *len_ptr = 0;
1267
1268         /* Find the last significant suffix. */
1269         for (s = fn + fn_len; fn_len > 1; ) {
1270                 while (*--s != '.' && s != fn) {}
1271                 if (s == fn)
1272                         break;
1273                 s_len = fn_len - (s - fn);
1274                 fn_len = s - fn;
1275                 if (s_len == 4) {
1276                         if (strcmp(s+1, "bak") == 0
1277                          || strcmp(s+1, "old") == 0)
1278                                 continue;
1279                 } else if (s_len == 5) {
1280                         if (strcmp(s+1, "orig") == 0)
1281                                 continue;
1282                 } else if (s_len > 2 && had_tilde
1283                     && s[1] == '~' && isdigit(*(uchar*)(s+2)))
1284                         continue;
1285                 *len_ptr = s_len;
1286                 suf = s;
1287                 if (s_len == 1)
1288                         break;
1289                 /* Determine if the suffix is all digits. */
1290                 for (s++, s_len--; s_len > 0; s++, s_len--) {
1291                         if (!isdigit(*(uchar*)s))
1292                                 return suf;
1293                 }
1294                 /* An all-digit suffix may not be that signficant. */
1295                 s = suf;
1296         }
1297
1298         return suf;
1299 }
1300
1301 /* This is an implementation of the Levenshtein distance algorithm.  It
1302  * was implemented to avoid needing a two-dimensional matrix (to save
1303  * memory).  It was also tweaked to try to factor in the ASCII distance
1304  * between changed characters as a minor distance quantity.  The normal
1305  * Levenshtein units of distance (each signifying a single change between
1306  * the two strings) are defined as a "UNIT". */
1307
1308 #define UNIT (1 << 16)
1309
1310 uint32 fuzzy_distance(const char *s1, int len1, const char *s2, int len2)
1311 {
1312         uint32 a[MAXPATHLEN], diag, above, left, diag_inc, above_inc, left_inc;
1313         int32 cost;
1314         int i1, i2;
1315
1316         if (!len1 || !len2) {
1317                 if (!len1) {
1318                         s1 = s2;
1319                         len1 = len2;
1320                 }
1321                 for (i1 = 0, cost = 0; i1 < len1; i1++)
1322                         cost += s1[i1];
1323                 return (int32)len1 * UNIT + cost;
1324         }
1325
1326         for (i2 = 0; i2 < len2; i2++)
1327                 a[i2] = (i2+1) * UNIT;
1328
1329         for (i1 = 0; i1 < len1; i1++) {
1330                 diag = i1 * UNIT;
1331                 above = (i1+1) * UNIT;
1332                 for (i2 = 0; i2 < len2; i2++) {
1333                         left = a[i2];
1334                         if ((cost = *((uchar*)s1+i1) - *((uchar*)s2+i2)) != 0) {
1335                                 if (cost < 0)
1336                                         cost = UNIT - cost;
1337                                 else
1338                                         cost = UNIT + cost;
1339                         }
1340                         diag_inc = diag + cost;
1341                         left_inc = left + UNIT + *((uchar*)s1+i1);
1342                         above_inc = above + UNIT + *((uchar*)s2+i2);
1343                         a[i2] = above = left < above
1344                               ? (left_inc < diag_inc ? left_inc : diag_inc)
1345                               : (above_inc < diag_inc ? above_inc : diag_inc);
1346                         diag = left;
1347                 }
1348         }
1349
1350         return a[len2-1];
1351 }