preparing for release of 2.1.1
[rsync/rsync.git] / util.c
... / ...
CommitLineData
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/****************************************************************************
28Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
29else
30if SYSV use O_NDELAY
31if BSD use FNDELAY
32****************************************************************************/
33int 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 */
55int 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(1);
65 }
66
67
68 pid = do_fork();
69 if (pid < 0) {
70 rprintf(FERROR,"fork: %s\n",strerror(errno));
71 exit_cleanup(1);
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(1);
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(1);
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(1);
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
108int 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(1);
118 }
119
120
121 pid = do_fork();
122 if (pid < 0) {
123 rprintf(FERROR,"fork: %s\n",strerror(errno));
124 exit_cleanup(1);
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(1);
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(1);
150 }
151
152 *f_in = from_child_pipe[0];
153 *f_out = to_child_pipe[1];
154
155 return pid;
156}
157
158
159
160void out_of_memory(char *str)
161{
162 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
163 exit_cleanup(1);
164}
165
166void overflow(char *str)
167{
168 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
169 exit_cleanup(1);
170}
171
172
173
174int 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/****************************************************************************
202create any necessary directories in fname. Unfortunately we don't know
203what perms to give the directory when this is called so we need to rely
204on the umask
205****************************************************************************/
206int 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*/
230static 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. */
256static 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 */
276int 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 */
327void 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
337static pid_t all_pids[10];
338static int num_pids;
339
340/* fork and record the pid of the child */
341pid_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 */
352void 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/* like strncpy but does not 0 fill the buffer and always null
362 terminates (thus it can use maxlen+1 space in d) */
363void strlcpy(char *d, char *s, int maxlen)
364{
365 int len = strlen(s);
366 if (len > maxlen) len = maxlen;
367 memcpy(d, s, len);
368 d[len] = 0;
369}
370
371/* like strncat but does not 0 fill the buffer and always null
372 terminates (thus it can use maxlen+1 space in d) */
373void strlcat(char *d, char *s, int maxlen)
374{
375 int len1 = strlen(d);
376 int len2 = strlen(s);
377 if (len1+len2 > maxlen) {
378 len2 = maxlen-len1;
379 }
380 if (len2 > 0) {
381 memcpy(d+len1, s, len2);
382 d[len1+len2] = 0;
383 }
384}
385
386/* turn a user name into a uid */
387int name_to_uid(char *name, uid_t *uid)
388{
389 struct passwd *pass;
390 if (!name || !*name) return 0;
391 pass = getpwnam(name);
392 if (pass) {
393 *uid = pass->pw_uid;
394 return 1;
395 }
396 return 0;
397}
398
399/* turn a group name into a gid */
400int name_to_gid(char *name, gid_t *gid)
401{
402 struct group *grp;
403 if (!name || !*name) return 0;
404 grp = getgrnam(name);
405 if (grp) {
406 *gid = grp->gr_gid;
407 return 1;
408 }
409 return 0;
410}
411
412
413/* lock a byte range in a open file */
414int lock_range(int fd, int offset, int len)
415{
416 struct flock lock;
417
418 lock.l_type = F_WRLCK;
419 lock.l_whence = SEEK_SET;
420 lock.l_start = offset;
421 lock.l_len = len;
422 lock.l_pid = 0;
423
424 return fcntl(fd,F_SETLK,&lock) == 0;
425}
426
427
428static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
429{
430#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
431 if (!*s) s = ".";
432 argv[*argc] = strdup(s);
433 (*argc)++;
434 return;
435#else
436 glob_t globbuf;
437 int i;
438
439 if (!*s) s = ".";
440
441 argv[*argc] = strdup(s);
442
443 memset(&globbuf, 0, sizeof(globbuf));
444 glob(argv[*argc], 0, NULL, &globbuf);
445 if (globbuf.gl_pathc == 0) {
446 (*argc)++;
447 globfree(&globbuf);
448 return;
449 }
450 for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
451 if (i == 0) free(argv[*argc]);
452 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
453 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
454 }
455 globfree(&globbuf);
456 (*argc) += i;
457#endif
458}
459
460void glob_expand(char *base1, char **argv, int *argc, int maxargs)
461{
462 char *s = argv[*argc];
463 char *p, *q;
464 char *base = base1;
465
466 if (!s || !*s) return;
467
468 if (strncmp(s, base, strlen(base)) == 0) {
469 s += strlen(base);
470 }
471
472 s = strdup(s);
473 if (!s) out_of_memory("glob_expand");
474
475 base = (char *)malloc(strlen(base1)+3);
476 if (!base) out_of_memory("glob_expand");
477
478 sprintf(base," %s/", base1);
479
480 q = s;
481 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
482 /* split it at this point */
483 *p = 0;
484 glob_expand_one(q, argv, argc, maxargs);
485 q = p+strlen(base);
486 }
487
488 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
489
490 free(s);
491 free(base);
492}
493
494/*******************************************************************
495 convert a string to lower case
496********************************************************************/
497void strlower(char *s)
498{
499 while (*s) {
500 if (isupper(*s)) *s = tolower(*s);
501 s++;
502 }
503}
504
505/* this is like vsnprintf but the 'n' limit does not include
506 the terminating null. So if you have a 1024 byte buffer then
507 pass 1023 for n */
508int vslprintf(char *str, int n, const char *format, va_list ap)
509{
510#ifdef HAVE_VSNPRINTF
511 int ret = vsnprintf(str, n, format, ap);
512 if (ret > n || ret < 0) {
513 str[n] = 0;
514 return -1;
515 }
516 str[ret] = 0;
517 return ret;
518#else
519 static char *buf;
520 static int len=MAXPATHLEN*8;
521 int ret;
522
523 /* this code is NOT a proper vsnprintf() implementation. It
524 relies on the fact that all calls to slprintf() in rsync
525 pass strings which have already been checked to be less
526 than MAXPATHLEN in length and never more than 2 strings are
527 concatenated. This means the above buffer is absolutely
528 ample and can never be overflowed.
529
530 In the future we would like to replace this with a proper
531 vsnprintf() implementation but right now we need a solution
532 that is secure and portable. This is it. */
533
534 if (!buf) {
535 buf = malloc(len);
536 if (!buf) {
537 /* can't call debug or we would recurse */
538 exit_cleanup(1);
539 }
540 }
541
542 vsprintf(buf, format, ap);
543 ret = strlen(buf);
544 if (ret > n) {
545 /* yikes! */
546 exit_cleanup(1);
547 }
548 buf[ret] = 0;
549
550 memcpy(str, buf, ret+1);
551
552 return ret;
553#endif
554}
555
556
557/* like snprintf but always null terminates */
558int slprintf(char *str, int n, char *format, ...)
559{
560 va_list ap;
561 int ret;
562
563 va_start(ap, format);
564 ret = vslprintf(str,n,format,ap);
565 va_end(ap);
566 return ret;
567}
568
569
570void *Realloc(void *p, int size)
571{
572 if (!p) return (void *)malloc(size);
573 return (void *)realloc(p, size);
574}
575
576
577void clean_fname(char *name)
578{
579 char *p;
580 int l;
581 int modified = 1;
582
583 if (!name) return;
584
585 while (modified) {
586 modified = 0;
587
588 if ((p=strstr(name,"/./"))) {
589 modified = 1;
590 while (*p) {
591 p[0] = p[2];
592 p++;
593 }
594 }
595
596 if ((p=strstr(name,"//"))) {
597 modified = 1;
598 while (*p) {
599 p[0] = p[1];
600 p++;
601 }
602 }
603
604 if (strncmp(p=name,"./",2) == 0) {
605 modified = 1;
606 do {
607 p[0] = p[2];
608 } while (*p++);
609 }
610
611 l = strlen(p=name);
612 if (l > 1 && p[l-1] == '/') {
613 modified = 1;
614 p[l-1] = 0;
615 }
616 }
617}
618
619
620static char curr_dir[MAXPATHLEN];
621
622/* like chdir() but can be reversed with pop_dir() if save is set. It
623 is also much faster as it remembers where we have been */
624char *push_dir(char *dir, int save)
625{
626 char *ret = curr_dir;
627 static int initialised;
628
629 if (!initialised) {
630 initialised = 1;
631 getcwd(curr_dir, sizeof(curr_dir)-1);
632 }
633
634 if (chdir(dir)) return NULL;
635
636 if (save) {
637 ret = strdup(curr_dir);
638 }
639
640 if (*dir == '/') {
641 strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
642 } else {
643 strlcat(curr_dir,"/", sizeof(curr_dir)-1);
644 strlcat(curr_dir,dir, sizeof(curr_dir)-1);
645 }
646
647 clean_fname(curr_dir);
648
649 return ret;
650}
651
652/* reverse a push_dir call */
653int pop_dir(char *dir)
654{
655 int ret;
656
657 ret = chdir(dir);
658 if (ret) {
659 free(dir);
660 return ret;
661 }
662
663 strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
664
665 free(dir);
666
667 return 0;
668}
669
670/* we need to supply our own strcmp function for file list comparisons
671 to ensure that signed/unsigned usage is consistent between machines. */
672int u_strcmp(const char *cs1, const char *cs2)
673{
674 const uchar *s1 = (uchar *)cs1;
675 const uchar *s2 = (uchar *)cs2;
676
677 while (*s1 && *s2 && (*s1 == *s2)) {
678 s1++; s2++;
679 }
680
681 return (int)*s1 - (int)*s2;
682}
683
684static OFF_T last_ofs;
685
686void end_progress(void)
687{
688 extern int do_progress, am_server;
689
690 if (do_progress && !am_server) {
691 rprintf(FINFO,"\n");
692 }
693 last_ofs = 0;
694}
695
696void show_progress(OFF_T ofs, OFF_T size)
697{
698 extern int do_progress, am_server;
699
700 if (do_progress && !am_server) {
701 if (ofs > last_ofs + 1000) {
702 int pct = (int)((100.0*ofs)/size);
703 rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
704 last_ofs = ofs;
705 }
706 }
707}
708
709/* determine if a symlink points outside the current directory tree */
710int unsafe_symlink(char *dest, char *src)
711{
712 char *tok;
713 int depth = 0;
714
715 /* all absolute and null symlinks are unsafe */
716 if (!dest || !(*dest) || (*dest == '/')) return 1;
717
718 src = strdup(src);
719 if (!src) out_of_memory("unsafe_symlink");
720
721 /* find out what our safety margin is */
722 for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
723 if (strcmp(tok,"..") == 0) {
724 depth=0;
725 } else if (strcmp(tok,".") == 0) {
726 /* nothing */
727 } else {
728 depth++;
729 }
730 }
731 free(src);
732
733 /* drop by one to account for the filename portion */
734 depth--;
735
736 dest = strdup(dest);
737 if (!dest) out_of_memory("unsafe_symlink");
738
739 for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
740 if (strcmp(tok,"..") == 0) {
741 depth--;
742 } else if (strcmp(tok,".") == 0) {
743 /* nothing */
744 } else {
745 depth++;
746 }
747 /* if at any point we go outside the current directory then
748 stop - it is unsafe */
749 if (depth < 0) break;
750 }
751
752 free(dest);
753 return (depth < 0);
754}