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