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