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