fixed typo in socket test
[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
bcacc18b 35struct map_struct *map_file(int fd,OFF_T len)
c627d613 36{
c6e7fcb4
AT
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
d9bea2dd 49#ifdef HAVE_MMAP
94c9ef1f
AT
50 if (len < MAX_MAP_SIZE) {
51 ret->map = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
52 if (ret->map == (char *)-1) {
53 ret->map = NULL;
54 }
55 }
d9bea2dd 56#endif
c627d613
AT
57 return ret;
58}
59
0b910560 60
bcacc18b 61char *map_ptr(struct map_struct *map,OFF_T offset,int len)
d9bea2dd 62{
0cfcfa29
AT
63 int nread = -2;
64
c6e7fcb4
AT
65 if (map->map)
66 return map->map+offset;
d9bea2dd
AT
67
68 if (len == 0)
69 return NULL;
70
0b910560
AT
71 if (len > (map->size-offset))
72 len = map->size-offset;
d9bea2dd 73
c6e7fcb4
AT
74 if (offset >= map->p_offset &&
75 offset+len <= map->p_offset+map->p_len) {
76 return (map->p + (offset - map->p_offset));
d9bea2dd
AT
77 }
78
34ccb63e 79 len = MAX(len,CHUNK_SIZE);
0b910560
AT
80 if (len > (map->size-offset))
81 len = map->size-offset;
d9bea2dd 82
c6e7fcb4
AT
83 if (len > map->p_size) {
84 if (map->p) free(map->p);
85 map->p = (char *)malloc(len);
86 if (!map->p) out_of_memory("map_ptr");
87 map->p_size = len;
d9bea2dd
AT
88 }
89
73233f0f 90 if (do_lseek(map->fd,offset,SEEK_SET) != offset ||
0cfcfa29 91 (nread=read(map->fd,map->p,len)) != len) {
9486289c 92 rprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n",
feaa89c4
AT
93 (int)offset, len, nread, errno);
94 exit_cleanup(1);
d9bea2dd
AT
95 }
96
c6e7fcb4
AT
97 map->p_offset = offset;
98 map->p_len = len;
d9bea2dd 99
c6e7fcb4 100 return map->p;
d9bea2dd
AT
101}
102
103
c6e7fcb4 104void unmap_file(struct map_struct *map)
c627d613 105{
7bec6a5c 106#ifdef HAVE_MMAP
c6e7fcb4
AT
107 if (map->map)
108 munmap(map->map,map->size);
7bec6a5c 109#endif
c6e7fcb4
AT
110 if (map->p) free(map->p);
111 free(map);
c627d613
AT
112}
113
114
c627d613
AT
115/* this is taken from CVS */
116int piped_child(char **command,int *f_in,int *f_out)
117{
118 int pid;
119 int to_child_pipe[2];
120 int from_child_pipe[2];
121
122 if (pipe(to_child_pipe) < 0 ||
123 pipe(from_child_pipe) < 0) {
9486289c 124 rprintf(FERROR,"pipe: %s\n",strerror(errno));
34ccb63e 125 exit_cleanup(1);
c627d613
AT
126 }
127
128
3ba62a83 129 pid = do_fork();
c627d613 130 if (pid < 0) {
9486289c 131 rprintf(FERROR,"fork: %s\n",strerror(errno));
34ccb63e 132 exit_cleanup(1);
c627d613
AT
133 }
134
135 if (pid == 0)
136 {
6574b4f7 137 extern int orig_umask;
c627d613
AT
138 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
139 close(to_child_pipe[1]) < 0 ||
140 close(from_child_pipe[0]) < 0 ||
141 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
9486289c 142 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
34ccb63e 143 exit_cleanup(1);
c627d613 144 }
773f2bd4
AT
145 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
146 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
6574b4f7 147 umask(orig_umask);
c627d613 148 execvp(command[0], command);
9486289c 149 rprintf(FERROR,"Failed to exec %s : %s\n",
c627d613 150 command[0],strerror(errno));
34ccb63e 151 exit_cleanup(1);
c627d613
AT
152 }
153
154 if (close(from_child_pipe[1]) < 0 ||
155 close(to_child_pipe[0]) < 0) {
9486289c 156 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
34ccb63e 157 exit_cleanup(1);
c627d613
AT
158 }
159
160 *f_in = from_child_pipe[0];
161 *f_out = to_child_pipe[1];
162
163 return pid;
164}
165
366345fe
AT
166int local_child(int argc, char **argv,int *f_in,int *f_out)
167{
168 int pid;
169 int to_child_pipe[2];
170 int from_child_pipe[2];
171
172 if (pipe(to_child_pipe) < 0 ||
173 pipe(from_child_pipe) < 0) {
9486289c 174 rprintf(FERROR,"pipe: %s\n",strerror(errno));
366345fe
AT
175 exit_cleanup(1);
176 }
177
178
179 pid = do_fork();
180 if (pid < 0) {
9486289c 181 rprintf(FERROR,"fork: %s\n",strerror(errno));
366345fe
AT
182 exit_cleanup(1);
183 }
184
185 if (pid == 0) {
186 extern int am_sender;
187 extern int am_server;
188
189 am_sender = !am_sender;
190 am_server = 1;
191
192 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
193 close(to_child_pipe[1]) < 0 ||
194 close(from_child_pipe[0]) < 0 ||
195 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
9486289c 196 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
366345fe
AT
197 exit_cleanup(1);
198 }
199 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
200 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
9486289c 201 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
366345fe
AT
202 }
203
204 if (close(from_child_pipe[1]) < 0 ||
205 close(to_child_pipe[0]) < 0) {
9486289c 206 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
366345fe
AT
207 exit_cleanup(1);
208 }
209
210 *f_in = from_child_pipe[0];
211 *f_out = to_child_pipe[1];
212
213 return pid;
214}
215
216
c627d613
AT
217
218void out_of_memory(char *str)
219{
9486289c 220 rprintf(FERROR,"ERROR: out of memory in %s\n",str);
575f2fca
AT
221 exit_cleanup(1);
222}
223
224void overflow(char *str)
225{
9486289c 226 rprintf(FERROR,"ERROR: buffer overflow in %s\n",str);
34ccb63e 227 exit_cleanup(1);
c627d613
AT
228}
229
230
c627d613
AT
231
232int set_modtime(char *fname,time_t modtime)
233{
31e12522
AT
234 extern int dry_run;
235 if (dry_run) return 0;
236 {
1e9f155a 237#ifdef HAVE_UTIMBUF
31e12522
AT
238 struct utimbuf tbuf;
239 tbuf.actime = time(NULL);
240 tbuf.modtime = modtime;
241 return utime(fname,&tbuf);
c627d613 242#elif defined(HAVE_UTIME)
31e12522
AT
243 time_t t[2];
244 t[0] = time(NULL);
245 t[1] = modtime;
246 return utime(fname,t);
c627d613 247#else
31e12522
AT
248 struct timeval t[2];
249 t[0].tv_sec = time(NULL);
250 t[0].tv_usec = 0;
251 t[1].tv_sec = modtime;
252 t[1].tv_usec = 0;
253 return utimes(fname,t);
c627d613 254#endif
31e12522 255 }
c627d613 256}
94481d91 257
720b47f2
AT
258
259
260/****************************************************************************
261Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
262else
263if SYSV use O_NDELAY
264if BSD use FNDELAY
265****************************************************************************/
266int set_blocking(int fd, int set)
267{
268 int val;
269#ifdef O_NONBLOCK
270#define FLAG_TO_SET O_NONBLOCK
271#else
272#ifdef SYSV
273#define FLAG_TO_SET O_NDELAY
274#else /* BSD */
275#define FLAG_TO_SET FNDELAY
276#endif
277#endif
278
279 if((val = fcntl(fd, F_GETFL, 0)) == -1)
280 return -1;
281 if(set) /* Turn blocking on - ie. clear nonblock flag */
282 val &= ~FLAG_TO_SET;
283 else
284 val |= FLAG_TO_SET;
285 return fcntl( fd, F_SETFL, val);
286#undef FLAG_TO_SET
287}
6574b4f7
AT
288
289/****************************************************************************
290create any necessary directories in fname. Unfortunately we don't know
291what perms to give the directory when this is called so we need to rely
292on the umask
293****************************************************************************/
294int create_directory_path(char *fname)
295{
296 extern int orig_umask;
297 char *p;
298
299 while (*fname == '/') fname++;
300 while (strncmp(fname,"./",2)==0) fname += 2;
301
302 p = fname;
303 while ((p=strchr(p,'/'))) {
304 *p = 0;
1b2d733a 305 do_mkdir(fname,0777 & ~orig_umask);
6574b4f7
AT
306 *p = '/';
307 p++;
308 }
309 return 0;
310}
950ab32d
AT
311
312
313/* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
314 Return LEN upon success, write's (negative) error code otherwise.
315
316 derived from GNU C's cccp.c.
317*/
318int full_write(int desc, char *ptr, int len)
319{
320 int total_written;
321
322 total_written = 0;
323 while (len > 0) {
324 int written = write (desc, ptr, len);
325 if (written < 0) {
326#ifdef EINTR
327 if (errno == EINTR)
328 continue;
329#endif
330 return written;
331 }
332 total_written += written;
333 ptr += written;
334 len -= written;
335 }
336 return total_written;
337}
338
339/* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
340 Return the actual number of bytes read, zero for EOF, or negative
341 for an error.
342
343 derived from GNU C's cccp.c. */
344int safe_read(int desc, char *ptr, int len)
345{
346 int n_chars;
347
348 if (len <= 0)
349 return len;
350
351#ifdef EINTR
352 do {
353 n_chars = read(desc, ptr, len);
354 } while (n_chars < 0 && errno == EINTR);
355#else
356 n_chars = read(desc, ptr, len);
357#endif
358
359 return n_chars;
360}
361
362
363/* copy a file - this is used in conjunction with the --temp-dir option */
364int copy_file(char *source, char *dest, mode_t mode)
365{
366 int ifd;
367 int ofd;
368 char buf[1024 * 8];
369 int len; /* Number of bytes read into `buf'. */
370
371 ifd = open(source, O_RDONLY);
372 if (ifd == -1) {
9486289c 373 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
374 source,strerror(errno));
375 return -1;
376 }
377
31e12522 378 if (do_unlink(dest) && errno != ENOENT) {
9486289c 379 rprintf(FERROR,"unlink %s: %s\n",
950ab32d
AT
380 dest,strerror(errno));
381 return -1;
382 }
383
31e12522 384 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
950ab32d 385 if (ofd < 0) {
9486289c 386 rprintf(FERROR,"open %s: %s\n",
950ab32d
AT
387 dest,strerror(errno));
388 close(ifd);
389 return -1;
390 }
391
392 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
393 if (full_write(ofd, buf, len) < 0) {
9486289c 394 rprintf(FERROR,"write %s: %s\n",
950ab32d
AT
395 dest,strerror(errno));
396 close(ifd);
397 close(ofd);
398 return -1;
399 }
400 }
401
402 close(ifd);
403 close(ofd);
404
405 if (len < 0) {
9486289c 406 rprintf(FERROR,"read %s: %s\n",
950ab32d
AT
407 source,strerror(errno));
408 return -1;
409 }
410
411 return 0;
412}
feaa89c4
AT
413
414/* sleep for a while via select */
415void u_sleep(int usec)
416{
417 struct timeval tv;
418
419 tv.tv_sec = 0;
420 tv.tv_usec = usec;
421 select(0, NULL, NULL, NULL, &tv);
422}
3ba62a83
AT
423
424
425static pid_t all_pids[10];
426static int num_pids;
427
428/* fork and record the pid of the child */
429pid_t do_fork(void)
430{
431 pid_t newpid = fork();
432
433 if (newpid) {
434 all_pids[num_pids++] = newpid;
435 }
436 return newpid;
437}
438
439/* kill all children */
440void kill_all(int sig)
441{
442 int i;
443 for (i=0;i<num_pids;i++) {
444 if (all_pids[i] != getpid())
445 kill(all_pids[i], sig);
446 }
447}
9486289c 448
7a6421fa
AT
449/* like strncpy but does not 0 fill the buffer and always null
450 terminates (thus it can use maxlen+1 space in d) */
451void strlcpy(char *d, char *s, int maxlen)
452{
453 int len = strlen(s);
454 if (len > maxlen) len = maxlen;
455 memcpy(d, s, len);
456 d[len] = 0;
457}