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