use mmap() for files of any size. This should be much more buffer
[rsync/rsync.git] / util.c
CommitLineData
c627d613
AT
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
720b47f2 27int num_waiting(int fd)
94481d91
AT
28{
29 int len=0;
94481d91 30 ioctl(fd,FIONREAD,&len);
94481d91
AT
31 return(len);
32}
33
d9bea2dd 34
bcacc18b 35struct map_struct *map_file(int fd,OFF_T len)
c627d613 36{
754d120c
AT
37 struct map_struct *ret;
38 ret = (struct map_struct *)malloc(sizeof(*ret));
39 if (!ret) out_of_memory("map_file");
40
41 ret->map = NULL;
42 ret->fd = fd;
43 ret->size = len;
44 ret->p = NULL;
45 ret->p_size = 0;
46 ret->p_offset = 0;
47 ret->p_len = 0;
c6e7fcb4 48
d9bea2dd 49#ifdef HAVE_MMAP
754d120c
AT
50 len = MIN(len, MAX_MAP_SIZE);
51 ret->map = (char *)do_mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
52 if (ret->map == (char *)-1) {
53 ret->map = NULL;
54 } else {
55 ret->p_len = len;
56 }
d9bea2dd 57#endif
754d120c 58 return ret;
c627d613
AT
59}
60
0b910560 61
bcacc18b 62char *map_ptr(struct map_struct *map,OFF_T offset,int len)
d9bea2dd 63{
3e607d23
AT
64 int nread;
65
3e607d23
AT
66 if (len == 0)
67 return NULL;
68
69 if (len > (map->size-offset))
70 len = map->size-offset;
71
754d120c
AT
72 if (map->map) {
73 if (offset >= map->p_offset &&
74 offset+len <= map->p_offset+map->p_len) {
75 return (map->map + (offset - map->p_offset));
76 }
77 if (munmap(map->map, map->p_len) != 0) {
78 rprintf(FERROR,"munmap failed : %s\n", strerror(errno));
79 exit_cleanup(1);
80 }
81
82 /* align the mmap region on a nice boundary back a bit from
83 where it is asked for to allow for some seeking */
84 if (offset > 2*CHUNK_SIZE) {
85 map->p_offset = offset - 2*CHUNK_SIZE;
86 map->p_offset &= ~((OFF_T)(CHUNK_SIZE-1));
87 } else {
88 map->p_offset = 0;
89 }
90
91 /* map up to MAX_MAP_SIZE */
92 map->p_len = MAX(len, MAX_MAP_SIZE);
93 map->p_len = MIN(map->p_len, map->size - map->p_offset);
94
95 map->map = (char *)do_mmap(NULL,map->p_len,PROT_READ,
96 MAP_SHARED,map->fd,map->p_offset);
97
98 if (map->map == (char *)-1) {
99 map->map = NULL;
100 map->p_len = 0;
101 map->p_offset = 0;
102 } else {
103 return (map->map + (offset - map->p_offset));
104 }
105 }
106
3e607d23
AT
107 if (offset >= map->p_offset &&
108 offset+len <= map->p_offset+map->p_len) {
109 return (map->p + (offset - map->p_offset));
110 }
111
112 len = MAX(len,CHUNK_SIZE);
113 if (len > (map->size-offset))
114 len = map->size-offset;
115
116 if (len > map->p_size) {
117 if (map->p) free(map->p);
118 map->p = (char *)malloc(len);
119 if (!map->p) out_of_memory("map_ptr");
120 map->p_size = len;
121 }
122
123 map->p_offset = offset;
124 map->p_len = len;
125
126 if (do_lseek(map->fd,offset,SEEK_SET) != offset) {
127 rprintf(FERROR,"lseek failed in map_ptr\n");
128 exit_cleanup(1);
129 }
130
131 if ((nread=read(map->fd,map->p,len)) != len) {
132 if (nread < 0) nread = 0;
133 /* the best we can do is zero the buffer - the file
134 has changed mid transfer! */
135 memset(map->p+nread, 0, len - nread);
136 }
137
138 return map->p;
d9bea2dd
AT
139}
140
141
c6e7fcb4 142void unmap_file(struct map_struct *map)
c627d613 143{
7bec6a5c 144#ifdef HAVE_MMAP
754d120c
AT
145 if (map->map) {
146 munmap(map->map,map->p_len);
147 map->map = NULL;
148 }
7bec6a5c 149#endif
754d120c
AT
150 if (map->p) {
151 free(map->p);
152 map->p = NULL;
153 }
154 memset(map, 0, sizeof(*map));
155 free(map);
c627d613
AT
156}
157
158
c627d613
AT
159/* this is taken from CVS */
160int piped_child(char **command,int *f_in,int *f_out)
161{
162 int pid;
163 int to_child_pipe[2];
164 int from_child_pipe[2];
165
166 if (pipe(to_child_pipe) < 0 ||
167 pipe(from_child_pipe) < 0) {
9486289c 168 rprintf(FERROR,"pipe: %s\n",strerror(errno));
34ccb63e 169 exit_cleanup(1);
c627d613
AT
170 }
171
172
3ba62a83 173 pid = do_fork();
c627d613 174 if (pid < 0) {
9486289c 175 rprintf(FERROR,"fork: %s\n",strerror(errno));
34ccb63e 176 exit_cleanup(1);
c627d613
AT
177 }
178
179 if (pid == 0)
180 {
6574b4f7 181 extern int orig_umask;
c627d613
AT
182 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
183 close(to_child_pipe[1]) < 0 ||
184 close(from_child_pipe[0]) < 0 ||
185 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
9486289c 186 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
34ccb63e 187 exit_cleanup(1);
c627d613 188 }
773f2bd4
AT
189 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
190 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
6574b4f7 191 umask(orig_umask);
c627d613 192 execvp(command[0], command);
9486289c 193 rprintf(FERROR,"Failed to exec %s : %s\n",
c627d613 194 command[0],strerror(errno));
34ccb63e 195 exit_cleanup(1);
c627d613
AT
196 }
197
198 if (close(from_child_pipe[1]) < 0 ||
199 close(to_child_pipe[0]) < 0) {
9486289c 200 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
34ccb63e 201 exit_cleanup(1);
c627d613
AT
202 }
203
204 *f_in = from_child_pipe[0];
205 *f_out = to_child_pipe[1];
206
207 return pid;
208}
209
366345fe
AT
210int local_child(int argc, char **argv,int *f_in,int *f_out)
211{
212 int pid;
213 int to_child_pipe[2];
214 int from_child_pipe[2];
215
216 if (pipe(to_child_pipe) < 0 ||
217 pipe(from_child_pipe) < 0) {
9486289c 218 rprintf(FERROR,"pipe: %s\n",strerror(errno));
366345fe
AT
219 exit_cleanup(1);
220 }
221
222
223 pid = do_fork();
224 if (pid < 0) {
9486289c 225 rprintf(FERROR,"fork: %s\n",strerror(errno));
366345fe
AT
226 exit_cleanup(1);
227 }
228
229 if (pid == 0) {
230 extern int am_sender;
231 extern int am_server;
232
233 am_sender = !am_sender;
234 am_server = 1;
235
236 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
237 close(to_child_pipe[1]) < 0 ||
238 close(from_child_pipe[0]) < 0 ||
239 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
9486289c 240 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
366345fe
AT
241 exit_cleanup(1);
242 }
243 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
244 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
9486289c 245 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
366345fe
AT
246 }
247
248 if (close(from_child_pipe[1]) < 0 ||
249 close(to_child_pipe[0]) < 0) {
9486289c 250 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
366345fe
AT
251 exit_cleanup(1);
252 }
253
254 *f_in = from_child_pipe[0];
255 *f_out = to_child_pipe[1];
256
257 return pid;
258}
259
260
c627d613
AT
261
262void out_of_memory(char *str)
263{
9486289c 264 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
575f2fca
AT
265 exit_cleanup(1);
266}
267
268void overflow(char *str)
269{
9486289c 270 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
34ccb63e 271 exit_cleanup(1);
c627d613
AT
272}
273
274
c627d613
AT
275
276int set_modtime(char *fname,time_t modtime)
277{
31e12522
AT
278 extern int dry_run;
279 if (dry_run) return 0;
280 {
1e9f155a 281#ifdef HAVE_UTIMBUF
31e12522
AT
282 struct utimbuf tbuf;
283 tbuf.actime = time(NULL);
284 tbuf.modtime = modtime;
285 return utime(fname,&tbuf);
c627d613 286#elif defined(HAVE_UTIME)
31e12522
AT
287 time_t t[2];
288 t[0] = time(NULL);
289 t[1] = modtime;
290 return utime(fname,t);
c627d613 291#else
31e12522
AT
292 struct timeval t[2];
293 t[0].tv_sec = time(NULL);
294 t[0].tv_usec = 0;
295 t[1].tv_sec = modtime;
296 t[1].tv_usec = 0;
297 return utimes(fname,t);
c627d613 298#endif
31e12522 299 }
c627d613 300}
94481d91 301
720b47f2
AT
302
303
304/****************************************************************************
305Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
306else
307if SYSV use O_NDELAY
308if BSD use FNDELAY
309****************************************************************************/
310int set_blocking(int fd, int set)
311{
312 int val;
313#ifdef O_NONBLOCK
314#define FLAG_TO_SET O_NONBLOCK
315#else
316#ifdef SYSV
317#define FLAG_TO_SET O_NDELAY
318#else /* BSD */
319#define FLAG_TO_SET FNDELAY
320#endif
321#endif
322
323 if((val = fcntl(fd, F_GETFL, 0)) == -1)
324 return -1;
325 if(set) /* Turn blocking on - ie. clear nonblock flag */
326 val &= ~FLAG_TO_SET;
327 else
328 val |= FLAG_TO_SET;
329 return fcntl( fd, F_SETFL, val);
330#undef FLAG_TO_SET
331}
6574b4f7
AT
332
333/****************************************************************************
334create any necessary directories in fname. Unfortunately we don't know
335what perms to give the directory when this is called so we need to rely
336on the umask
337****************************************************************************/
338int create_directory_path(char *fname)
339{
340 extern int orig_umask;
341 char *p;
342
343 while (*fname == '/') fname++;
344 while (strncmp(fname,"./",2)==0) fname += 2;
345
346 p = fname;
347 while ((p=strchr(p,'/'))) {
348 *p = 0;
1b2d733a 349 do_mkdir(fname,0777 & ~orig_umask);
6574b4f7
AT
350 *p = '/';
351 p++;
352 }
353 return 0;
354}
950ab32d
AT
355
356
357/* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
358 Return LEN upon success, write's (negative) error code otherwise.
359
360 derived from GNU C's cccp.c.
361*/
362int full_write(int desc, char *ptr, int len)
363{
364 int total_written;
365
366 total_written = 0;
367 while (len > 0) {
368 int written = write (desc, ptr, len);
369 if (written < 0) {
370#ifdef EINTR
371 if (errno == EINTR)
372 continue;
373#endif
374 return written;
375 }
376 total_written += written;
377 ptr += written;
378 len -= written;
379 }
380 return total_written;
381}
382
383/* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
384 Return the actual number of bytes read, zero for EOF, or negative
385 for an error.
386
387 derived from GNU C's cccp.c. */
388int safe_read(int desc, char *ptr, int len)
389{
390 int n_chars;
391
392 if (len <= 0)
393 return len;
394
395#ifdef EINTR
396 do {
397 n_chars = read(desc, ptr, len);
398 } while (n_chars < 0 && errno == EINTR);
399#else
400 n_chars = read(desc, ptr, len);
401#endif
402
403 return n_chars;
404}
405
406
407/* copy a file - this is used in conjunction with the --temp-dir option */
408int copy_file(char *source, char *dest, mode_t mode)
409{
410 int ifd;
411 int ofd;
412 char buf[1024 * 8];
413 int len; /* Number of bytes read into `buf'. */
414
415 ifd = open(source, O_RDONLY);
416 if (ifd == -1) {
9486289c 417 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
418 source,strerror(errno));
419 return -1;
420 }
421
31e12522 422 if (do_unlink(dest) && errno != ENOENT) {
9486289c 423 rprintf(FERROR,"unlink %s: %s\n",
950ab32d
AT
424 dest,strerror(errno));
425 return -1;
426 }
427
31e12522 428 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
950ab32d 429 if (ofd < 0) {
9486289c 430 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
431 dest,strerror(errno));
432 close(ifd);
433 return -1;
434 }
435
436 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
437 if (full_write(ofd, buf, len) < 0) {
9486289c 438 rprintf(FERROR,"write %s: %s\n",
950ab32d
AT
439 dest,strerror(errno));
440 close(ifd);
441 close(ofd);
442 return -1;
443 }
444 }
445
446 close(ifd);
447 close(ofd);
448
449 if (len < 0) {
9486289c 450 rprintf(FERROR,"read %s: %s\n",
950ab32d
AT
451 source,strerror(errno));
452 return -1;
453 }
454
455 return 0;
456}
feaa89c4
AT
457
458/* sleep for a while via select */
459void u_sleep(int usec)
460{
461 struct timeval tv;
462
463 tv.tv_sec = 0;
464 tv.tv_usec = usec;
465 select(0, NULL, NULL, NULL, &tv);
466}
3ba62a83
AT
467
468
469static pid_t all_pids[10];
470static int num_pids;
471
472/* fork and record the pid of the child */
473pid_t do_fork(void)
474{
475 pid_t newpid = fork();
476
477 if (newpid) {
478 all_pids[num_pids++] = newpid;
479 }
480 return newpid;
481}
482
483/* kill all children */
484void kill_all(int sig)
485{
486 int i;
487 for (i=0;i<num_pids;i++) {
488 if (all_pids[i] != getpid())
489 kill(all_pids[i], sig);
490 }
491}
9486289c 492
7a6421fa
AT
493/* like strncpy but does not 0 fill the buffer and always null
494 terminates (thus it can use maxlen+1 space in d) */
495void strlcpy(char *d, char *s, int maxlen)
496{
497 int len = strlen(s);
498 if (len > maxlen) len = maxlen;
499 memcpy(d, s, len);
500 d[len] = 0;
501}
8ef4ffd6 502
e42c9458
AT
503/* like strncat but does not 0 fill the buffer and always null
504 terminates (thus it can use maxlen+1 space in d) */
505void strlcat(char *d, char *s, int maxlen)
506{
507 int len1 = strlen(d);
508 int len2 = strlen(s);
509 if (len1+len2 > maxlen) {
510 len2 = maxlen-len1;
511 }
512 if (len2 > 0) {
513 memcpy(d+len1, s, len2);
514 d[len1+len2] = 0;
515 }
516}
517
8ef4ffd6
AT
518/* turn a user name into a uid */
519int name_to_uid(char *name, uid_t *uid)
520{
521 struct passwd *pass;
522 if (!name || !*name) return 0;
523 pass = getpwnam(name);
524 if (pass) {
525 *uid = pass->pw_uid;
526 return 1;
527 }
528 return 0;
529}
530
531/* turn a group name into a gid */
532int name_to_gid(char *name, gid_t *gid)
533{
534 struct group *grp;
535 if (!name || !*name) return 0;
536 grp = getgrnam(name);
537 if (grp) {
538 *gid = grp->gr_gid;
539 return 1;
540 }
541 return 0;
542}
543
ff8b29b8 544
0c515f17
AT
545/****************************************************************************
546check if a process exists.
547****************************************************************************/
548int process_exists(int pid)
549{
550 return(kill(pid,0) == 0 || errno != ESRCH);
551}
552
31593dd6
AT
553/* lock a byte range in a open file */
554int lock_range(int fd, int offset, int len)
0c515f17 555{
31593dd6 556 struct flock lock;
0c515f17 557
31593dd6
AT
558 lock.l_type = F_WRLCK;
559 lock.l_whence = SEEK_SET;
560 lock.l_start = offset;
561 lock.l_len = len;
562 lock.l_pid = 0;
563
564 return fcntl(fd,F_SETLK,&lock) == 0;
0c515f17 565}
874895d5
AT
566
567
087bf010 568static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
874895d5
AT
569{
570#ifndef HAVE_GLOB
e42c9458 571 if (!*s) s = ".";
087bf010 572 argv[*argc] = strdup(s);
874895d5
AT
573 (*argc)++;
574 return;
575#else
576 glob_t globbuf;
577 int i;
578
e42c9458
AT
579 if (!*s) s = ".";
580
087bf010
AT
581 argv[*argc] = strdup(s);
582
874895d5
AT
583 memset(&globbuf, 0, sizeof(globbuf));
584 glob(argv[*argc], 0, NULL, &globbuf);
585 if (globbuf.gl_pathc == 0) {
586 (*argc)++;
587 globfree(&globbuf);
588 return;
589 }
590 for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
591 if (i == 0) free(argv[*argc]);
592 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
593 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
594 }
595 globfree(&globbuf);
596 (*argc) += i;
597#endif
598}
5a96ee05 599
ba5e128d 600void glob_expand(char *base1, char **argv, int *argc, int maxargs)
087bf010
AT
601{
602 char *s = argv[*argc];
603 char *p, *q;
ba5e128d 604 char *base = base1;
087bf010
AT
605
606 if (!s || !*s) return;
607
e42c9458
AT
608 if (strncmp(s, base, strlen(base)) == 0) {
609 s += strlen(base);
610 }
611
087bf010
AT
612 s = strdup(s);
613 if (!s) out_of_memory("glob_expand");
614
ba5e128d
AT
615 base = (char *)malloc(strlen(base1)+3);
616 if (!base) out_of_memory("glob_expand");
617
618 sprintf(base," %s/", base1);
619
087bf010
AT
620 q = s;
621 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
ba5e128d
AT
622 /* split it at this point */
623 *p = 0;
624 glob_expand_one(q, argv, argc, maxargs);
625 q = p+strlen(base);
087bf010
AT
626 }
627
628 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
629
630 free(s);
ba5e128d 631 free(base);
087bf010 632}
5a96ee05
AT
633
634/*******************************************************************
635 convert a string to lower case
636********************************************************************/
637void strlower(char *s)
638{
639 while (*s) {
640 if (isupper(*s)) *s = tolower(*s);
641 s++;
642 }
643}
e42c9458
AT
644
645/* this is like vsnprintf but the 'n' limit does not include
646 the terminating null. So if you have a 1024 byte buffer then
647 pass 1023 for n */
648int vslprintf(char *str, int n, const char *format, va_list ap)
649{
650#ifdef HAVE_VSNPRINTF
651 int ret = vsnprintf(str, n, format, ap);
652 if (ret > n || ret < 0) {
653 str[n] = 0;
654 return -1;
655 }
656 str[ret] = 0;
657 return ret;
658#else
659 static char *buf;
660 static int len=MAXPATHLEN*8;
661 int ret;
662
663 /* this code is NOT a proper vsnprintf() implementation. It
664 relies on the fact that all calls to slprintf() in rsync
665 pass strings which have already been checked to be less
666 than MAXPATHLEN in length and never more than 2 strings are
667 concatenated. This means the above buffer is absolutely
668 ample and can never be overflowed.
669
670 In the future we would like to replace this with a proper
671 vsnprintf() implementation but right now we need a solution
672 that is secure and portable. This is it. */
673
674 if (!buf) {
675 buf = malloc(len);
676 if (!buf) {
677 /* can't call debug or we would recurse */
8d9dc9f9 678 exit_cleanup(1);
e42c9458
AT
679 }
680 }
681
f72399f8
AT
682 vsprintf(buf, format, ap);
683 ret = strlen(buf);
684 if (ret > n) {
685 /* yikes! */
8d9dc9f9 686 exit_cleanup(1);
e42c9458 687 }
f72399f8 688 buf[ret] = 0;
e42c9458 689
f72399f8 690 memcpy(str, buf, ret+1);
e42c9458
AT
691
692 return ret;
693#endif
694}
695
696
697/* like snprintf but always null terminates */
698int slprintf(char *str, int n, char *format, ...)
699{
700 va_list ap;
701 int ret;
702
703 va_start(ap, format);
704 ret = vslprintf(str,n,format,ap);
705 va_end(ap);
706 return ret;
707}
8d9dc9f9 708