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