preparing for release of 2.0.14
[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
c627d613 35
c627d613
AT
36/* this is taken from CVS */
37int 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) {
9486289c 45 rprintf(FERROR,"pipe: %s\n",strerror(errno));
34ccb63e 46 exit_cleanup(1);
c627d613
AT
47 }
48
49
3ba62a83 50 pid = do_fork();
c627d613 51 if (pid < 0) {
9486289c 52 rprintf(FERROR,"fork: %s\n",strerror(errno));
34ccb63e 53 exit_cleanup(1);
c627d613
AT
54 }
55
56 if (pid == 0)
57 {
6574b4f7 58 extern int orig_umask;
c627d613
AT
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) {
9486289c 63 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
34ccb63e 64 exit_cleanup(1);
c627d613 65 }
773f2bd4
AT
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]);
6574b4f7 68 umask(orig_umask);
c627d613 69 execvp(command[0], command);
9486289c 70 rprintf(FERROR,"Failed to exec %s : %s\n",
c627d613 71 command[0],strerror(errno));
34ccb63e 72 exit_cleanup(1);
c627d613
AT
73 }
74
75 if (close(from_child_pipe[1]) < 0 ||
76 close(to_child_pipe[0]) < 0) {
9486289c 77 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
34ccb63e 78 exit_cleanup(1);
c627d613
AT
79 }
80
81 *f_in = from_child_pipe[0];
82 *f_out = to_child_pipe[1];
83
84 return pid;
85}
86
366345fe
AT
87int 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) {
9486289c 95 rprintf(FERROR,"pipe: %s\n",strerror(errno));
366345fe
AT
96 exit_cleanup(1);
97 }
98
99
100 pid = do_fork();
101 if (pid < 0) {
9486289c 102 rprintf(FERROR,"fork: %s\n",strerror(errno));
366345fe
AT
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) {
9486289c 117 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
366345fe
AT
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]);
9486289c 122 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
366345fe
AT
123 }
124
125 if (close(from_child_pipe[1]) < 0 ||
126 close(to_child_pipe[0]) < 0) {
9486289c 127 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
366345fe
AT
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
c627d613
AT
138
139void out_of_memory(char *str)
140{
9486289c 141 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
575f2fca
AT
142 exit_cleanup(1);
143}
144
145void overflow(char *str)
146{
9486289c 147 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
34ccb63e 148 exit_cleanup(1);
c627d613
AT
149}
150
151
c627d613
AT
152
153int set_modtime(char *fname,time_t modtime)
154{
31e12522
AT
155 extern int dry_run;
156 if (dry_run) return 0;
157 {
1e9f155a 158#ifdef HAVE_UTIMBUF
31e12522
AT
159 struct utimbuf tbuf;
160 tbuf.actime = time(NULL);
161 tbuf.modtime = modtime;
162 return utime(fname,&tbuf);
c627d613 163#elif defined(HAVE_UTIME)
31e12522
AT
164 time_t t[2];
165 t[0] = time(NULL);
166 t[1] = modtime;
167 return utime(fname,t);
c627d613 168#else
31e12522
AT
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);
c627d613 175#endif
31e12522 176 }
c627d613 177}
94481d91 178
720b47f2 179
6574b4f7
AT
180/****************************************************************************
181create any necessary directories in fname. Unfortunately we don't know
182what perms to give the directory when this is called so we need to rely
183on the umask
184****************************************************************************/
185int 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;
1b2d733a 196 do_mkdir(fname,0777 & ~orig_umask);
6574b4f7
AT
197 *p = '/';
198 p++;
199 }
200 return 0;
201}
950ab32d
AT
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*/
209int 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. */
235int 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 */
255int 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) {
9486289c 264 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
265 source,strerror(errno));
266 return -1;
267 }
268
31e12522 269 if (do_unlink(dest) && errno != ENOENT) {
9486289c 270 rprintf(FERROR,"unlink %s: %s\n",
950ab32d
AT
271 dest,strerror(errno));
272 return -1;
273 }
274
31e12522 275 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
950ab32d 276 if (ofd < 0) {
9486289c 277 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
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) {
9486289c 285 rprintf(FERROR,"write %s: %s\n",
950ab32d
AT
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) {
9486289c 297 rprintf(FERROR,"read %s: %s\n",
950ab32d
AT
298 source,strerror(errno));
299 return -1;
300 }
301
302 return 0;
303}
feaa89c4
AT
304
305/* sleep for a while via select */
306void 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}
3ba62a83
AT
314
315
316static pid_t all_pids[10];
317static int num_pids;
318
319/* fork and record the pid of the child */
320pid_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 */
331void 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}
9486289c 339
7a6421fa
AT
340/* like strncpy but does not 0 fill the buffer and always null
341 terminates (thus it can use maxlen+1 space in d) */
342void 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}
8ef4ffd6 349
e42c9458
AT
350/* like strncat but does not 0 fill the buffer and always null
351 terminates (thus it can use maxlen+1 space in d) */
352void 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
8ef4ffd6
AT
365/* turn a user name into a uid */
366int 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 */
379int 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
ff8b29b8 391
0c515f17
AT
392/****************************************************************************
393check if a process exists.
394****************************************************************************/
395int process_exists(int pid)
396{
397 return(kill(pid,0) == 0 || errno != ESRCH);
398}
399
31593dd6
AT
400/* lock a byte range in a open file */
401int lock_range(int fd, int offset, int len)
0c515f17 402{
31593dd6 403 struct flock lock;
0c515f17 404
31593dd6
AT
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;
0c515f17 412}
874895d5
AT
413
414
087bf010 415static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
874895d5
AT
416{
417#ifndef HAVE_GLOB
e42c9458 418 if (!*s) s = ".";
087bf010 419 argv[*argc] = strdup(s);
874895d5
AT
420 (*argc)++;
421 return;
422#else
423 glob_t globbuf;
424 int i;
425
e42c9458
AT
426 if (!*s) s = ".";
427
087bf010
AT
428 argv[*argc] = strdup(s);
429
874895d5
AT
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}
5a96ee05 446
ba5e128d 447void glob_expand(char *base1, char **argv, int *argc, int maxargs)
087bf010
AT
448{
449 char *s = argv[*argc];
450 char *p, *q;
ba5e128d 451 char *base = base1;
087bf010
AT
452
453 if (!s || !*s) return;
454
e42c9458
AT
455 if (strncmp(s, base, strlen(base)) == 0) {
456 s += strlen(base);
457 }
458
087bf010
AT
459 s = strdup(s);
460 if (!s) out_of_memory("glob_expand");
461
ba5e128d
AT
462 base = (char *)malloc(strlen(base1)+3);
463 if (!base) out_of_memory("glob_expand");
464
465 sprintf(base," %s/", base1);
466
087bf010
AT
467 q = s;
468 while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
ba5e128d
AT
469 /* split it at this point */
470 *p = 0;
471 glob_expand_one(q, argv, argc, maxargs);
472 q = p+strlen(base);
087bf010
AT
473 }
474
475 if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
476
477 free(s);
ba5e128d 478 free(base);
087bf010 479}
5a96ee05
AT
480
481/*******************************************************************
482 convert a string to lower case
483********************************************************************/
484void strlower(char *s)
485{
486 while (*s) {
487 if (isupper(*s)) *s = tolower(*s);
488 s++;
489 }
490}
e42c9458
AT
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 */
495int 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 */
8d9dc9f9 525 exit_cleanup(1);
e42c9458
AT
526 }
527 }
528
f72399f8
AT
529 vsprintf(buf, format, ap);
530 ret = strlen(buf);
531 if (ret > n) {
532 /* yikes! */
8d9dc9f9 533 exit_cleanup(1);
e42c9458 534 }
f72399f8 535 buf[ret] = 0;
e42c9458 536
f72399f8 537 memcpy(str, buf, ret+1);
e42c9458
AT
538
539 return ret;
540#endif
541}
542
543
544/* like snprintf but always null terminates */
545int 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}
8d9dc9f9 555
fe8c0a98
AT
556
557void *Realloc(void *p, int size)
558{
559 if (!p) return (void *)malloc(size);
560 return (void *)realloc(p, size);
561}