preparing for release of 2.0.14
[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
35
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) {
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
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) {
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
139void out_of_memory(char *str)
140{
141 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
142 exit_cleanup(1);
143}
144
145void overflow(char *str)
146{
147 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
148 exit_cleanup(1);
149}
150
151
152
153int 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/****************************************************************************
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;
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*/
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) {
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 */
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}
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}
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) */
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}
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) */
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
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
391
392/****************************************************************************
393check if a process exists.
394****************************************************************************/
395int process_exists(int pid)
396{
397 return(kill(pid,0) == 0 || errno != ESRCH);
398}
399
400/* lock a byte range in a open file */
401int 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
415static 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
447void 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********************************************************************/
484void 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 */
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 */
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 */
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}
555
556
557void *Realloc(void *p, int size)
558{
559 if (!p) return (void *)malloc(size);
560 return (void *)realloc(p, size);
561}