changed strlcat() and strlcpy() to have the same semantics as the
[rsync/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 /****************************************************************************
28 Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
29 else
30 if SYSV use O_NDELAY
31 if BSD use FNDELAY
32 ****************************************************************************/
33 int 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 */
55 int 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(RERR_IPC);
65   }
66
67
68   pid = do_fork();
69   if (pid < 0) {
70     rprintf(FERROR,"fork: %s\n",strerror(errno));
71     exit_cleanup(RERR_IPC);
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(RERR_IPC);
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(RERR_IPC);
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(RERR_IPC);
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
108 int 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(RERR_IPC);
118         }
119
120
121         pid = do_fork();
122         if (pid < 0) {
123                 rprintf(FERROR,"fork: %s\n",strerror(errno));
124                 exit_cleanup(RERR_IPC);
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(RERR_IPC);
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(RERR_IPC);
150         }
151
152         *f_in = from_child_pipe[0];
153         *f_out = to_child_pipe[1];
154   
155         return pid;
156 }
157
158
159
160 void out_of_memory(char *str)
161 {
162   rprintf(FERROR,"ERROR: out of memory in %s\n",str);
163   exit_cleanup(RERR_MALLOC);
164 }
165
166 void overflow(char *str)
167 {
168   rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
169   exit_cleanup(RERR_MALLOC);
170 }
171
172
173
174 int 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 /****************************************************************************
202 create any necessary directories in fname. Unfortunately we don't know
203 what perms to give the directory when this is called so we need to rely
204 on the umask
205 ****************************************************************************/
206 int 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 */
230 static 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. */
256 static 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 */
276 int 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 */
327 void 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
337 static pid_t all_pids[10];
338 static int num_pids;
339
340 /* fork and record the pid of the child */
341 pid_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 */
352 void 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. bufsize is the size of the destination buffer */
363 size_t strlcpy(char *d, const char *s, size_t bufsize)
364 {
365         size_t len = strlen(s);
366         size_t ret = len;
367         if (len >= bufsize) len = bufsize-1;
368         memcpy(d, s, len);
369         d[len] = 0;
370         return ret;
371 }
372
373 /* like strncat but does not 0 fill the buffer and always null 
374    terminates. bufsize is the length of the buffer, which should
375    be one more than the maximum resulting string length */
376 size_t strlcat(char *d, const char *s, size_t bufsize)
377 {
378         size_t len1 = strlen(d);
379         size_t len2 = strlen(s);
380         size_t ret = len1 + len2;
381
382         if (len1+len2 >= bufsize) {
383                 len2 = bufsize - (len1+1);
384         }
385         if (len2 > 0) {
386                 memcpy(d+len1, s, len2);
387                 d[len1+len2] = 0;
388         }
389         return ret;
390 }
391
392 /* turn a user name into a uid */
393 int name_to_uid(char *name, uid_t *uid)
394 {
395         struct passwd *pass;
396         if (!name || !*name) return 0;
397         pass = getpwnam(name);
398         if (pass) {
399                 *uid = pass->pw_uid;
400                 return 1;
401         }
402         return 0;
403 }
404
405 /* turn a group name into a gid */
406 int name_to_gid(char *name, gid_t *gid)
407 {
408         struct group *grp;
409         if (!name || !*name) return 0;
410         grp = getgrnam(name);
411         if (grp) {
412                 *gid = grp->gr_gid;
413                 return 1;
414         }
415         return 0;
416 }
417
418
419 /* lock a byte range in a open file */
420 int lock_range(int fd, int offset, int len)
421 {
422         struct flock lock;
423
424         lock.l_type = F_WRLCK;
425         lock.l_whence = SEEK_SET;
426         lock.l_start = offset;
427         lock.l_len = len;
428         lock.l_pid = 0;
429         
430         return fcntl(fd,F_SETLK,&lock) == 0;
431 }
432
433
434 static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
435 {
436 #if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
437         if (!*s) s = ".";
438         argv[*argc] = strdup(s);
439         (*argc)++;
440         return;
441 #else
442         glob_t globbuf;
443         int i;
444
445         if (!*s) s = ".";
446
447         argv[*argc] = strdup(s);
448
449         memset(&globbuf, 0, sizeof(globbuf));
450         glob(argv[*argc], 0, NULL, &globbuf);
451         if (globbuf.gl_pathc == 0) {
452                 (*argc)++;
453                 globfree(&globbuf);
454                 return;
455         }
456         for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
457                 if (i == 0) free(argv[*argc]);
458                 argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
459                 if (!argv[(*argc) + i]) out_of_memory("glob_expand");
460         }
461         globfree(&globbuf);
462         (*argc) += i;
463 #endif
464 }
465
466 void glob_expand(char *base1, char **argv, int *argc, int maxargs)
467 {
468         char *s = argv[*argc];
469         char *p, *q;
470         char *base = base1;
471
472         if (!s || !*s) return;
473
474         if (strncmp(s, base, strlen(base)) == 0) {
475                 s += strlen(base);
476         }
477
478         s = strdup(s);
479         if (!s) out_of_memory("glob_expand");
480
481         base = (char *)malloc(strlen(base1)+3);
482         if (!base) out_of_memory("glob_expand");
483
484         sprintf(base," %s/", base1);
485
486         q = s;
487         while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
488                 /* split it at this point */
489                 *p = 0;
490                 glob_expand_one(q, argv, argc, maxargs);
491                 q = p+strlen(base);
492         }
493
494         if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
495
496         free(s);
497         free(base);
498 }
499
500 /*******************************************************************
501   convert a string to lower case
502 ********************************************************************/
503 void strlower(char *s)
504 {
505         while (*s) {
506                 if (isupper(*s)) *s = tolower(*s);
507                 s++;
508         }
509 }
510
511 /* this is like vsnprintf but it always null terminates, so you
512    can fit at most n-1 chars in */
513 int vslprintf(char *str, int n, const char *format, va_list ap)
514 {
515         int ret = vsnprintf(str, n, format, ap);
516         if (ret >= n || ret < 0) {
517                 str[n-1] = 0;
518                 return -1;
519         }
520         str[ret] = 0;
521         return ret;
522 }
523
524
525 /* like snprintf but always null terminates */
526 int slprintf(char *str, int n, char *format, ...)
527 {
528         va_list ap;  
529         int ret;
530
531         va_start(ap, format);
532         ret = vslprintf(str,n,format,ap);
533         va_end(ap);
534         return ret;
535 }
536
537
538 void *Realloc(void *p, int size)
539 {
540         if (!p) return (void *)malloc(size);
541         return (void *)realloc(p, size);
542 }
543
544
545 void clean_fname(char *name)
546 {
547         char *p;
548         int l;
549         int modified = 1;
550
551         if (!name) return;
552
553         while (modified) {
554                 modified = 0;
555
556                 if ((p=strstr(name,"/./"))) {
557                         modified = 1;
558                         while (*p) {
559                                 p[0] = p[2];
560                                 p++;
561                         }
562                 }
563
564                 if ((p=strstr(name,"//"))) {
565                         modified = 1;
566                         while (*p) {
567                                 p[0] = p[1];
568                                 p++;
569                         }
570                 }
571
572                 if (strncmp(p=name,"./",2) == 0) {      
573                         modified = 1;
574                         do {
575                                 p[0] = p[2];
576                         } while (*p++);
577                 }
578
579                 l = strlen(p=name);
580                 if (l > 1 && p[l-1] == '/') {
581                         modified = 1;
582                         p[l-1] = 0;
583                 }
584         }
585 }
586
587 /*
588  * Make path appear as if a chroot had occurred:
589  *    1. remove leading "/" (or replace with "." if at end)
590  *    2. remove leading ".." components
591  *    3. delete any other "<dir>/.." (recursively)
592  * While we're at it, remove double slashes and "." components like
593  *   clean_fname does(), but DON'T remove a trailing slash because that
594  *   is sometimes significant on command line arguments.
595  * Return a malloc'ed copy.
596  * Contributed by Dave Dykstra <dwd@bell-labs.com>
597  */
598
599 char *sanitize_path(char *p)
600 {
601         char *copy, *copyp;
602
603         copy = (char *) malloc(strlen(p)+1);
604         copyp = copy;
605         while (*p == '/') {
606                 /* remove leading slashes */
607                 p++;
608         }
609         while (*p != '\0') {
610                 /* this loop iterates once per filename component in p.
611                  * both p (and copyp if the original had a slash) should
612                  * always be left pointing after a slash
613                  */
614                 if ((*p == '.') && ((*(p+1) == '/') || (*(p+1) == '\0'))) {
615                         /* skip "." component */
616                         while (*++p == '/') {
617                                 /* skip following slashes */
618                                 ;
619                         }
620                 } else if ((*p == '.') && (*(p+1) == '.') &&
621                             ((*(p+2) == '/') || (*(p+2) == '\0'))) {
622                         /* skip ".." component followed by slash or end */
623                         p += 2;
624                         if (*p == '/')
625                                 p++;
626                         if (copyp != copy) {
627                                 /* back up the copy one level */
628                                 --copyp; /* now pointing at slash */
629                                 while ((copyp > copy) && (*(copyp - 1) != '/')) {
630                                         /* skip back up to slash */
631                                         copyp--;
632                                 }
633                         }
634                 } else {
635                         while (1) {
636                                 /* copy one component through next slash */
637                                 *copyp++ = *p++;
638                                 if ((*p == '\0') || (*(p-1) == '/')) {
639                                         while (*p == '/') {
640                                                 /* skip multiple slashes */
641                                                 p++;
642                                         }
643                                         break;
644                                 }
645                         }
646                 }
647         }
648         if (copyp == copy) {
649                 /* ended up with nothing, so put in "." component */
650                 *copyp++ = '.';
651         }
652         *copyp = '\0';
653         return(copy);
654 }
655
656
657 static char curr_dir[MAXPATHLEN];
658
659 /* like chdir() but can be reversed with pop_dir() if save is set. It
660    is also much faster as it remembers where we have been */
661 char *push_dir(char *dir, int save)
662 {
663         char *ret = curr_dir;
664         static int initialised;
665
666         if (!initialised) {
667                 initialised = 1;
668                 getcwd(curr_dir, sizeof(curr_dir)-1);
669         }
670
671         if (chdir(dir)) return NULL;
672
673         if (save) {
674                 ret = strdup(curr_dir);
675         }
676
677         if (*dir == '/') {
678                 strlcpy(curr_dir, dir, sizeof(curr_dir));
679         } else {
680                 strlcat(curr_dir,"/", sizeof(curr_dir));
681                 strlcat(curr_dir,dir, sizeof(curr_dir));
682         }
683
684         clean_fname(curr_dir);
685
686         return ret;
687 }
688
689 /* reverse a push_dir call */
690 int pop_dir(char *dir)
691 {
692         int ret;
693
694         ret = chdir(dir);
695         if (ret) {
696                 free(dir);
697                 return ret;
698         }
699
700         strlcpy(curr_dir, dir, sizeof(curr_dir));
701
702         free(dir);
703
704         return 0;
705 }
706
707 /* we need to supply our own strcmp function for file list comparisons
708    to ensure that signed/unsigned usage is consistent between machines. */
709 int u_strcmp(const char *cs1, const char *cs2)
710 {
711         const uchar *s1 = (uchar *)cs1;
712         const uchar *s2 = (uchar *)cs2;
713
714         while (*s1 && *s2 && (*s1 == *s2)) {
715                 s1++; s2++;
716         }
717         
718         return (int)*s1 - (int)*s2;
719 }
720
721 static OFF_T last_ofs;
722
723 void end_progress(void)
724 {
725         extern int do_progress, am_server;
726
727         if (do_progress && !am_server) {
728                 rprintf(FINFO,"\n");
729         }
730         last_ofs = 0;
731 }
732
733 void show_progress(OFF_T ofs, OFF_T size)
734 {
735         extern int do_progress, am_server;
736
737         if (do_progress && !am_server) {
738                 if (ofs > last_ofs + 1000) {
739                         int pct = (int)((100.0*ofs)/size);
740                         rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
741                         last_ofs = ofs;
742                 }
743         }
744 }
745
746 /* determine if a symlink points outside the current directory tree */
747 int unsafe_symlink(char *dest, char *src)
748 {
749         char *tok;
750         int depth = 0;
751
752         /* all absolute and null symlinks are unsafe */
753         if (!dest || !(*dest) || (*dest == '/')) return 1;
754
755         src = strdup(src);
756         if (!src) out_of_memory("unsafe_symlink");
757
758         /* find out what our safety margin is */
759         for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
760                 if (strcmp(tok,"..") == 0) {
761                         depth=0;
762                 } else if (strcmp(tok,".") == 0) {
763                         /* nothing */
764                 } else {
765                         depth++;
766                 }
767         }
768         free(src);
769
770         /* drop by one to account for the filename portion */
771         depth--;
772
773         dest = strdup(dest);
774         if (!dest) out_of_memory("unsafe_symlink");
775
776         for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
777                 if (strcmp(tok,"..") == 0) {
778                         depth--;
779                 } else if (strcmp(tok,".") == 0) {
780                         /* nothing */
781                 } else {
782                         depth++;
783                 }
784                 /* if at any point we go outside the current directory then
785                    stop - it is unsafe */
786                 if (depth < 0) break;
787         }
788
789         free(dest);
790         return (depth < 0);
791 }
792
793
794 /****************************************************************************
795   return the date and time as a string
796 ****************************************************************************/
797 char *timestring(time_t t)
798 {
799         static char TimeBuf[200];
800         struct tm *tm = localtime(&t);
801
802 #ifdef HAVE_STRFTIME
803         strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
804 #else
805         strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf));
806 #endif
807
808         if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
809                 TimeBuf[strlen(TimeBuf)-1] = 0;
810         }
811
812         return(TimeBuf);
813 }
814