check for munmap as well as mmap. NextStep only has mmap in standard
[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 int num_waiting(int fd)
28 {
29   int len=0;
30   ioctl(fd,FIONREAD,&len);
31   return(len);
32 }
33
34
35 struct 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 USE_MMAP
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         }
57 #endif
58         return ret;
59 }
60
61
62 char *map_ptr(struct map_struct *map,OFF_T offset,int len)
63 {
64         int nread;
65
66         if (len == 0) 
67                 return NULL;
68
69         if (len > (map->size-offset))
70                 len = map->size-offset;
71
72 #ifdef USE_MMAP
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         }
107 #endif
108
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; 
141 }
142
143
144 void unmap_file(struct map_struct *map)
145 {
146 #ifdef USE_MMAP
147         if (map->map) {
148                 munmap(map->map,map->p_len);
149                 map->map = NULL;
150         }
151 #endif
152         if (map->p) {
153                 free(map->p);
154                 map->p = NULL;
155         }
156         memset(map, 0, sizeof(*map));
157         free(map);
158 }
159
160
161 /* this is taken from CVS */
162 int 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) {
170     rprintf(FERROR,"pipe: %s\n",strerror(errno));
171     exit_cleanup(1);
172   }
173
174
175   pid = do_fork();
176   if (pid < 0) {
177     rprintf(FERROR,"fork: %s\n",strerror(errno));
178     exit_cleanup(1);
179   }
180
181   if (pid == 0)
182     {
183       extern int orig_umask;
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) {
188         rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
189         exit_cleanup(1);
190       }
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]);
193       umask(orig_umask);
194       execvp(command[0], command);
195       rprintf(FERROR,"Failed to exec %s : %s\n",
196               command[0],strerror(errno));
197       exit_cleanup(1);
198     }
199
200   if (close(from_child_pipe[1]) < 0 ||
201       close(to_child_pipe[0]) < 0) {
202     rprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
203     exit_cleanup(1);
204   }
205
206   *f_in = from_child_pipe[0];
207   *f_out = to_child_pipe[1];
208   
209   return pid;
210 }
211
212 int 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) {
220                 rprintf(FERROR,"pipe: %s\n",strerror(errno));
221                 exit_cleanup(1);
222         }
223
224
225         pid = do_fork();
226         if (pid < 0) {
227                 rprintf(FERROR,"fork: %s\n",strerror(errno));
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) {
242                         rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
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]);
247                 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
248         }
249
250         if (close(from_child_pipe[1]) < 0 ||
251             close(to_child_pipe[0]) < 0) {
252                 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
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
263
264 void out_of_memory(char *str)
265 {
266   rprintf(FERROR,"ERROR: out of memory in %s\n",str);
267   exit_cleanup(1);
268 }
269
270 void overflow(char *str)
271 {
272   rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
273   exit_cleanup(1);
274 }
275
276
277
278 int set_modtime(char *fname,time_t modtime)
279 {
280         extern int dry_run;
281         if (dry_run) return 0;
282         {
283 #ifdef HAVE_UTIMBUF
284                 struct utimbuf tbuf;  
285                 tbuf.actime = time(NULL);
286                 tbuf.modtime = modtime;
287                 return utime(fname,&tbuf);
288 #elif defined(HAVE_UTIME)
289                 time_t t[2];
290                 t[0] = time(NULL);
291                 t[1] = modtime;
292                 return utime(fname,t);
293 #else
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);
300 #endif
301         }
302 }
303
304
305
306 /****************************************************************************
307 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
308 else
309 if SYSV use O_NDELAY
310 if BSD use FNDELAY
311 ****************************************************************************/
312 int 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 }
334
335 /****************************************************************************
336 create any necessary directories in fname. Unfortunately we don't know
337 what perms to give the directory when this is called so we need to rely
338 on the umask
339 ****************************************************************************/
340 int 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;
351                 do_mkdir(fname,0777 & ~orig_umask); 
352                 *p = '/';
353                 p++;
354         }
355         return 0;
356 }
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 */
364 int 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. */
390 int 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 */
410 int 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) {
419                 rprintf(FERROR,"open %s: %s\n",
420                         source,strerror(errno));
421                 return -1;
422         }
423
424         if (do_unlink(dest) && errno != ENOENT) {
425                 rprintf(FERROR,"unlink %s: %s\n",
426                         dest,strerror(errno));
427                 return -1;
428         }
429
430         ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
431         if (ofd < 0) {
432                 rprintf(FERROR,"open %s: %s\n",
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) {
440                         rprintf(FERROR,"write %s: %s\n",
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) {
452                 rprintf(FERROR,"read %s: %s\n",
453                         source,strerror(errno));
454                 return -1;
455         }
456
457         return 0;
458 }
459
460 /* sleep for a while via select */
461 void 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 }
469
470
471 static pid_t all_pids[10];
472 static int num_pids;
473
474 /* fork and record the pid of the child */
475 pid_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 */
486 void 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 }
494
495 /* like strncpy but does not 0 fill the buffer and always null 
496    terminates (thus it can use maxlen+1 space in d) */
497 void 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 }
504
505 /* like strncat but does not 0 fill the buffer and always null 
506    terminates (thus it can use maxlen+1 space in d) */
507 void 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
520 /* turn a user name into a uid */
521 int 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 */
534 int 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
546
547 /****************************************************************************
548 check if a process exists. 
549 ****************************************************************************/
550 int process_exists(int pid)
551 {
552         return(kill(pid,0) == 0 || errno != ESRCH);
553 }
554
555 /* lock a byte range in a open file */
556 int lock_range(int fd, int offset, int len)
557 {
558         struct flock lock;
559
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;
567 }
568
569
570 static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
571 {
572 #ifndef HAVE_GLOB
573         if (!*s) s = ".";
574         argv[*argc] = strdup(s);
575         (*argc)++;
576         return;
577 #else
578         glob_t globbuf;
579         int i;
580
581         if (!*s) s = ".";
582
583         argv[*argc] = strdup(s);
584
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 }
601
602 void glob_expand(char *base1, char **argv, int *argc, int maxargs)
603 {
604         char *s = argv[*argc];
605         char *p, *q;
606         char *base = base1;
607
608         if (!s || !*s) return;
609
610         if (strncmp(s, base, strlen(base)) == 0) {
611                 s += strlen(base);
612         }
613
614         s = strdup(s);
615         if (!s) out_of_memory("glob_expand");
616
617         base = (char *)malloc(strlen(base1)+3);
618         if (!base) out_of_memory("glob_expand");
619
620         sprintf(base," %s/", base1);
621
622         q = s;
623         while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
624                 /* split it at this point */
625                 *p = 0;
626                 glob_expand_one(q, argv, argc, maxargs);
627                 q = p+strlen(base);
628         }
629
630         if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
631
632         free(s);
633         free(base);
634 }
635
636 /*******************************************************************
637   convert a string to lower case
638 ********************************************************************/
639 void strlower(char *s)
640 {
641         while (*s) {
642                 if (isupper(*s)) *s = tolower(*s);
643                 s++;
644         }
645 }
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 */
650 int 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 */
680                         exit_cleanup(1);
681                 }
682         }
683
684         vsprintf(buf, format, ap);
685         ret = strlen(buf);
686         if (ret > n) {
687                 /* yikes! */
688                 exit_cleanup(1);
689         }
690         buf[ret] = 0;
691         
692         memcpy(str, buf, ret+1);
693
694         return ret;
695 #endif
696 }
697
698
699 /* like snprintf but always null terminates */
700 int 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 }
710