16d8f6ccf7925a8c69a0973916b50a667be1ba6e
[rsync.git] / util.c
1 /* 
2    Copyright (C) Andrew Tridgell 1996
3    Copyright (C) Paul Mackerras 1996
4    
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /*
21   Utilities used in rsync 
22
23   tridge, June 1996
24   */
25 #include "rsync.h"
26
27 /****************************************************************************
28 Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
29 else
30 if SYSV use O_NDELAY
31 if BSD use FNDELAY
32 ****************************************************************************/
33 int set_nonblocking(int fd)
34 {
35         int val;
36 #ifdef O_NONBLOCK
37 #define FLAG_TO_SET O_NONBLOCK
38 #else
39 #ifdef SYSV
40 #define FLAG_TO_SET O_NDELAY
41 #else /* BSD */
42 #define FLAG_TO_SET FNDELAY
43 #endif
44 #endif
45         
46         if((val = fcntl(fd, F_GETFL, 0)) == -1)
47                 return -1;
48         val |= FLAG_TO_SET;
49         return fcntl( fd, F_SETFL, val);
50 #undef FLAG_TO_SET
51 }
52
53
54 /* this is taken from CVS */
55 int piped_child(char **command,int *f_in,int *f_out)
56 {
57   int pid;
58   int to_child_pipe[2];
59   int from_child_pipe[2];
60
61   if (pipe(to_child_pipe) < 0 ||
62       pipe(from_child_pipe) < 0) {
63     rprintf(FERROR,"pipe: %s\n",strerror(errno));
64     exit_cleanup(RERR_IPC);
65   }
66
67
68   pid = do_fork();
69   if (pid < 0) {
70     rprintf(FERROR,"fork: %s\n",strerror(errno));
71     exit_cleanup(RERR_IPC);
72   }
73
74   if (pid == 0)
75     {
76       extern int orig_umask;
77       if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
78           close(to_child_pipe[1]) < 0 ||
79           close(from_child_pipe[0]) < 0 ||
80           dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
81         rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
82         exit_cleanup(RERR_IPC);
83       }
84       if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
85       if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
86       umask(orig_umask);
87       execvp(command[0], command);
88       rprintf(FERROR,"Failed to exec %s : %s\n",
89               command[0],strerror(errno));
90       exit_cleanup(RERR_IPC);
91     }
92
93   if (close(from_child_pipe[1]) < 0 ||
94       close(to_child_pipe[0]) < 0) {
95     rprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
96     exit_cleanup(RERR_IPC);
97   }
98
99   *f_in = from_child_pipe[0];
100   *f_out = to_child_pipe[1];
101
102   set_nonblocking(*f_in);
103   set_nonblocking(*f_out);
104   
105   return pid;
106 }
107
108 int local_child(int argc, char **argv,int *f_in,int *f_out)
109 {
110         int pid;
111         int to_child_pipe[2];
112         int from_child_pipe[2];
113
114         if (pipe(to_child_pipe) < 0 ||
115             pipe(from_child_pipe) < 0) {
116                 rprintf(FERROR,"pipe: %s\n",strerror(errno));
117                 exit_cleanup(RERR_IPC);
118         }
119
120
121         pid = do_fork();
122         if (pid < 0) {
123                 rprintf(FERROR,"fork: %s\n",strerror(errno));
124                 exit_cleanup(RERR_IPC);
125         }
126
127         if (pid == 0) {
128                 extern int am_sender;
129                 extern int am_server;
130
131                 am_sender = !am_sender;
132                 am_server = 1;          
133
134                 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
135                     close(to_child_pipe[1]) < 0 ||
136                     close(from_child_pipe[0]) < 0 ||
137                     dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
138                         rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
139                         exit_cleanup(RERR_IPC);
140                 }
141                 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
142                 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
143                 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
144         }
145
146         if (close(from_child_pipe[1]) < 0 ||
147             close(to_child_pipe[0]) < 0) {
148                 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
149                 exit_cleanup(RERR_IPC);
150         }
151
152         *f_in = from_child_pipe[0];
153         *f_out = to_child_pipe[1];
154   
155         return pid;
156 }
157
158
159
160 void out_of_memory(char *str)
161 {
162   rprintf(FERROR,"ERROR: out of memory in %s\n",str);
163   exit_cleanup(RERR_MALLOC);
164 }
165
166 void overflow(char *str)
167 {
168   rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
169   exit_cleanup(RERR_MALLOC);
170 }
171
172
173
174 int set_modtime(char *fname,time_t modtime)
175 {
176         extern int dry_run;
177         if (dry_run) return 0;
178         {
179 #ifdef HAVE_UTIMBUF
180                 struct utimbuf tbuf;  
181                 tbuf.actime = time(NULL);
182                 tbuf.modtime = modtime;
183                 return utime(fname,&tbuf);
184 #elif defined(HAVE_UTIME)
185                 time_t t[2];
186                 t[0] = time(NULL);
187                 t[1] = modtime;
188                 return utime(fname,t);
189 #else
190                 struct timeval t[2];
191                 t[0].tv_sec = time(NULL);
192                 t[0].tv_usec = 0;
193                 t[1].tv_sec = modtime;
194                 t[1].tv_usec = 0;
195                 return utimes(fname,t);
196 #endif
197         }
198 }
199
200
201 /****************************************************************************
202 create any necessary directories in fname. Unfortunately we don't know
203 what perms to give the directory when this is called so we need to rely
204 on the umask
205 ****************************************************************************/
206 int create_directory_path(char *fname)
207 {
208         extern int orig_umask;
209         char *p;
210
211         while (*fname == '/') fname++;
212         while (strncmp(fname,"./",2)==0) fname += 2;
213
214         p = fname;
215         while ((p=strchr(p,'/'))) {
216                 *p = 0;
217                 do_mkdir(fname,0777 & ~orig_umask); 
218                 *p = '/';
219                 p++;
220         }
221         return 0;
222 }
223
224
225 /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
226    Return LEN upon success, write's (negative) error code otherwise.  
227
228    derived from GNU C's cccp.c.
229 */
230 static int full_write(int desc, char *ptr, int len)
231 {
232         int total_written;
233         
234         total_written = 0;
235         while (len > 0) {
236                 int written = write (desc, ptr, len);
237                 if (written < 0)  {
238 #ifdef EINTR
239                         if (errno == EINTR)
240                                 continue;
241 #endif
242                         return written;
243                 }
244                 total_written += written;
245                 ptr += written;
246                 len -= written;
247         }
248         return total_written;
249 }
250
251 /* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
252    Return the actual number of bytes read, zero for EOF, or negative
253    for an error.  
254
255    derived from GNU C's cccp.c. */
256 static int safe_read(int desc, char *ptr, int len)
257 {
258         int n_chars;
259  
260         if (len <= 0)
261                 return len;
262  
263 #ifdef EINTR
264         do {
265                 n_chars = read(desc, ptr, len);
266         } while (n_chars < 0 && errno == EINTR);
267 #else
268         n_chars = read(desc, ptr, len);
269 #endif
270  
271         return n_chars;
272 }
273
274
275 /* copy a file - this is used in conjunction with the --temp-dir option */
276 int copy_file(char *source, char *dest, mode_t mode)
277 {
278         int ifd;
279         int ofd;
280         char buf[1024 * 8];
281         int len;   /* Number of bytes read into `buf'. */
282
283         ifd = open(source, O_RDONLY);
284         if (ifd == -1) {
285                 rprintf(FERROR,"open %s: %s\n",
286                         source,strerror(errno));
287                 return -1;
288         }
289
290         if (do_unlink(dest) && errno != ENOENT) {
291                 rprintf(FERROR,"unlink %s: %s\n",
292                         dest,strerror(errno));
293                 return -1;
294         }
295
296         ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
297         if (ofd == -1) {
298                 rprintf(FERROR,"open %s: %s\n",
299                         dest,strerror(errno));
300                 close(ifd);
301                 return -1;
302         }
303
304         while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
305                 if (full_write(ofd, buf, len) < 0) {
306                         rprintf(FERROR,"write %s: %s\n",
307                                 dest,strerror(errno));
308                         close(ifd);
309                         close(ofd);
310                         return -1;
311                 }
312         }
313
314         close(ifd);
315         close(ofd);
316
317         if (len < 0) {
318                 rprintf(FERROR,"read %s: %s\n",
319                         source,strerror(errno));
320                 return -1;
321         }
322
323         return 0;
324 }
325
326 /* sleep for a while via select */
327 void u_sleep(int usec)
328 {
329         struct timeval tv;
330
331         tv.tv_sec = 0;
332         tv.tv_usec = usec;
333         select(0, NULL, NULL, NULL, &tv);
334 }
335
336
337 static pid_t all_pids[10];
338 static int num_pids;
339
340 /* fork and record the pid of the child */
341 pid_t do_fork(void)
342 {
343         pid_t newpid = fork();
344         
345         if (newpid) {
346                 all_pids[num_pids++] = newpid;
347         }
348         return newpid;
349 }
350
351 /* kill all children */
352 void kill_all(int sig)
353 {
354         int i;
355         for (i=0;i<num_pids;i++) {
356                 if (all_pids[i] != getpid())
357                         kill(all_pids[i], sig);
358         }
359 }
360
361 /* turn a user name into a uid */
362 int name_to_uid(char *name, uid_t *uid)
363 {
364         struct passwd *pass;
365         if (!name || !*name) return 0;
366         pass = getpwnam(name);
367         if (pass) {
368                 *uid = pass->pw_uid;
369                 return 1;
370         }
371         return 0;
372 }
373
374 /* turn a group name into a gid */
375 int name_to_gid(char *name, gid_t *gid)
376 {
377         struct group *grp;
378         if (!name || !*name) return 0;
379         grp = getgrnam(name);
380         if (grp) {
381                 *gid = grp->gr_gid;
382                 return 1;
383         }
384         return 0;
385 }
386
387
388 /* lock a byte range in a open file */
389 int lock_range(int fd, int offset, int len)
390 {
391         struct flock lock;
392
393         lock.l_type = F_WRLCK;
394         lock.l_whence = SEEK_SET;
395         lock.l_start = offset;
396         lock.l_len = len;
397         lock.l_pid = 0;
398         
399         return fcntl(fd,F_SETLK,&lock) == 0;
400 }
401
402
403 static void glob_expand_one(char *s, char **argv, int *argc, int maxargs, int sanitize_paths)
404 {
405 #if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
406         if (!*s) s = ".";
407         argv[*argc] = strdup(s);
408         (*argc)++;
409         return;
410 #else
411         glob_t globbuf;
412         int i;
413
414         if (!*s) s = ".";
415
416         s = strdup(s);
417         sanitize_path(s);
418         argv[*argc] = s;
419
420         memset(&globbuf, 0, sizeof(globbuf));
421         glob(argv[*argc], 0, NULL, &globbuf);
422         if (globbuf.gl_pathc == 0) {
423                 (*argc)++;
424                 globfree(&globbuf);
425                 return;
426         }
427         for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
428                 if (i == 0) free(argv[*argc]);
429                 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
430                 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
431         }
432         globfree(&globbuf);
433         (*argc) += i;
434 #endif
435 }
436
437 void glob_expand(char *base1, char **argv, int *argc, int maxargs, int sanitize_paths)
438 {
439         char *s = argv[*argc];
440         char *p, *q;
441         char *base = base1;
442
443         if (!s || !*s) return;
444
445         if (strncmp(s, base, strlen(base)) == 0) {
446                 s += strlen(base);
447         }
448
449         s = strdup(s);
450         if (!s) out_of_memory("glob_expand");
451
452         base = (char *)malloc(strlen(base1)+3);
453         if (!base) out_of_memory("glob_expand");
454
455         sprintf(base," %s/", base1);
456
457         q = s;
458         while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
459                 /* split it at this point */
460                 *p = 0;
461                 glob_expand_one(q, argv, argc, maxargs, sanitize_paths);
462                 q = p+strlen(base);
463         }
464
465         if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs, sanitize_paths);
466
467         free(s);
468         free(base);
469 }
470
471 /*******************************************************************
472   convert a string to lower case
473 ********************************************************************/
474 void strlower(char *s)
475 {
476         while (*s) {
477                 if (isupper(*s)) *s = tolower(*s);
478                 s++;
479         }
480 }
481
482 /* this is like vsnprintf but it always null terminates, so you
483    can fit at most n-1 chars in */
484 int vslprintf(char *str, int n, const char *format, va_list ap)
485 {
486         int ret = vsnprintf(str, n, format, ap);
487         if (ret >= n || ret < 0) {
488                 str[n-1] = 0;
489                 return -1;
490         }
491         str[ret] = 0;
492         return ret;
493 }
494
495
496 /* like snprintf but always null terminates */
497 int slprintf(char *str, int n, char *format, ...)
498 {
499         va_list ap;  
500         int ret;
501
502         va_start(ap, format);
503         ret = vslprintf(str,n,format,ap);
504         va_end(ap);
505         return ret;
506 }
507
508
509 void *Realloc(void *p, int size)
510 {
511         if (!p) return (void *)malloc(size);
512         return (void *)realloc(p, size);
513 }
514
515
516 void clean_fname(char *name)
517 {
518         char *p;
519         int l;
520         int modified = 1;
521
522         if (!name) return;
523
524         while (modified) {
525                 modified = 0;
526
527                 if ((p=strstr(name,"/./"))) {
528                         modified = 1;
529                         while (*p) {
530                                 p[0] = p[2];
531                                 p++;
532                         }
533                 }
534
535                 if ((p=strstr(name,"//"))) {
536                         modified = 1;
537                         while (*p) {
538                                 p[0] = p[1];
539                                 p++;
540                         }
541                 }
542
543                 if (strncmp(p=name,"./",2) == 0) {      
544                         modified = 1;
545                         do {
546                                 p[0] = p[2];
547                         } while (*p++);
548                 }
549
550                 l = strlen(p=name);
551                 if (l > 1 && p[l-1] == '/') {
552                         modified = 1;
553                         p[l-1] = 0;
554                 }
555         }
556 }
557
558 /*
559  * Make path appear as if a chroot had occurred:
560  *    1. remove leading "/" (or replace with "." if at end)
561  *    2. remove leading ".." components
562  *    3. delete any other "<dir>/.." (recursively)
563  * While we're at it, remove double slashes and "." components like
564  *   clean_fname does(), but DON'T remove a trailing slash because that
565  *   is sometimes significant on command line arguments.
566  * Can only shrink paths, so sanitizes in place.
567  * Contributed by Dave Dykstra <dwd@bell-labs.com>
568  */
569
570 void sanitize_path(char *p)
571 {
572         char *start, *sanp;
573
574         start = p;
575         sanp = p;
576         while (*p == '/') {
577                 /* remove leading slashes */
578                 p++;
579         }
580         while (*p != '\0') {
581                 /* this loop iterates once per filename component in p.
582                  * both p (and sanp if the original had a slash) should
583                  * always be left pointing after a slash
584                  */
585                 if ((*p == '.') && ((*(p+1) == '/') || (*(p+1) == '\0'))) {
586                         /* skip "." component */
587                         while (*++p == '/') {
588                                 /* skip following slashes */
589                                 ;
590                         }
591                 } else if ((*p == '.') && (*(p+1) == '.') &&
592                             ((*(p+2) == '/') || (*(p+2) == '\0'))) {
593                         /* skip ".." component followed by slash or end */
594                         p += 2;
595                         if (*p == '/')
596                                 p++;
597                         if (sanp != start) {
598                                 /* back up sanp one level */
599                                 --sanp; /* now pointing at slash */
600                                 while ((sanp > start) && (*(sanp - 1) != '/')) {
601                                         /* skip back up to slash */
602                                         sanp--;
603                                 }
604                         }
605                 } else {
606                         while (1) {
607                                 /* copy one component through next slash */
608                                 *sanp++ = *p++;
609                                 if ((*p == '\0') || (*(p-1) == '/')) {
610                                         while (*p == '/') {
611                                                 /* skip multiple slashes */
612                                                 p++;
613                                         }
614                                         break;
615                                 }
616                         }
617                 }
618         }
619         if (sanp == start) {
620                 /* ended up with nothing, so put in "." component */
621                 *sanp++ = '.';
622         }
623         *sanp = '\0';
624 }
625
626
627 static char curr_dir[MAXPATHLEN];
628
629 /* like chdir() but can be reversed with pop_dir() if save is set. It
630    is also much faster as it remembers where we have been */
631 char *push_dir(char *dir, int save)
632 {
633         char *ret = curr_dir;
634         static int initialised;
635
636         if (!initialised) {
637                 initialised = 1;
638                 getcwd(curr_dir, sizeof(curr_dir)-1);
639         }
640
641         if (!dir) return NULL; /* this call was probably just to initialize */
642
643         if (chdir(dir)) return NULL;
644
645         if (save) {
646                 ret = strdup(curr_dir);
647         }
648
649         if (*dir == '/') {
650                 strlcpy(curr_dir, dir, sizeof(curr_dir));
651         } else {
652                 strlcat(curr_dir,"/", sizeof(curr_dir));
653                 strlcat(curr_dir,dir, sizeof(curr_dir));
654         }
655
656         clean_fname(curr_dir);
657
658         return ret;
659 }
660
661 /* reverse a push_dir call */
662 int pop_dir(char *dir)
663 {
664         int ret;
665
666         ret = chdir(dir);
667         if (ret) {
668                 free(dir);
669                 return ret;
670         }
671
672         strlcpy(curr_dir, dir, sizeof(curr_dir));
673
674         free(dir);
675
676         return 0;
677 }
678
679 /* we need to supply our own strcmp function for file list comparisons
680    to ensure that signed/unsigned usage is consistent between machines. */
681 int u_strcmp(const char *cs1, const char *cs2)
682 {
683         const uchar *s1 = (const uchar *)cs1;
684         const uchar *s2 = (const uchar *)cs2;
685
686         while (*s1 && *s2 && (*s1 == *s2)) {
687                 s1++; s2++;
688         }
689         
690         return (int)*s1 - (int)*s2;
691 }
692
693 static OFF_T last_ofs;
694
695 void end_progress(void)
696 {
697         extern int do_progress, am_server;
698
699         if (do_progress && !am_server) {
700                 rprintf(FINFO,"\n");
701         }
702         last_ofs = 0;
703 }
704
705 void show_progress(OFF_T ofs, OFF_T size)
706 {
707         extern int do_progress, am_server;
708
709         if (do_progress && !am_server) {
710                 if (ofs > last_ofs + 1000) {
711                         int pct = (int)((100.0*ofs)/size);
712                         rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
713                         last_ofs = ofs;
714                 }
715         }
716 }
717
718 /* determine if a symlink points outside the current directory tree */
719 int unsafe_symlink(char *dest, char *src)
720 {
721         char *tok;
722         int depth = 0;
723
724         /* all absolute and null symlinks are unsafe */
725         if (!dest || !(*dest) || (*dest == '/')) return 1;
726
727         src = strdup(src);
728         if (!src) out_of_memory("unsafe_symlink");
729
730         /* find out what our safety margin is */
731         for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
732                 if (strcmp(tok,"..") == 0) {
733                         depth=0;
734                 } else if (strcmp(tok,".") == 0) {
735                         /* nothing */
736                 } else {
737                         depth++;
738                 }
739         }
740         free(src);
741
742         /* drop by one to account for the filename portion */
743         depth--;
744
745         dest = strdup(dest);
746         if (!dest) out_of_memory("unsafe_symlink");
747
748         for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
749                 if (strcmp(tok,"..") == 0) {
750                         depth--;
751                 } else if (strcmp(tok,".") == 0) {
752                         /* nothing */
753                 } else {
754                         depth++;
755                 }
756                 /* if at any point we go outside the current directory then
757                    stop - it is unsafe */
758                 if (depth < 0) break;
759         }
760
761         free(dest);
762         return (depth < 0);
763 }
764
765
766 /****************************************************************************
767   return the date and time as a string
768 ****************************************************************************/
769 char *timestring(time_t t)
770 {
771         static char TimeBuf[200];
772         struct tm *tm = localtime(&t);
773
774 #ifdef HAVE_STRFTIME
775         strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
776 #else
777         strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf));
778 #endif
779
780         if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
781                 TimeBuf[strlen(TimeBuf)-1] = 0;
782         }
783
784         return(TimeBuf);
785 }
786