+
+/* copy a file - this is used in conjunction with the --temp-dir option */
+int copy_file(char *source, char *dest, mode_t mode)
+{
+ int ifd;
+ int ofd;
+ char buf[1024 * 8];
+ int len; /* Number of bytes read into `buf'. */
+
+ ifd = open(source, O_RDONLY);
+ if (ifd == -1) {
+ rprintf(FERROR,"open %s: %s\n",
+ source,strerror(errno));
+ return -1;
+ }
+
+ if (do_unlink(dest) && errno != ENOENT) {
+ rprintf(FERROR,"unlink %s: %s\n",
+ dest,strerror(errno));
+ return -1;
+ }
+
+ ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
+ if (ofd < 0) {
+ rprintf(FERROR,"open %s: %s\n",
+ dest,strerror(errno));
+ close(ifd);
+ return -1;
+ }
+
+ while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
+ if (full_write(ofd, buf, len) < 0) {
+ rprintf(FERROR,"write %s: %s\n",
+ dest,strerror(errno));
+ close(ifd);
+ close(ofd);
+ return -1;
+ }
+ }
+
+ close(ifd);
+ close(ofd);
+
+ if (len < 0) {
+ rprintf(FERROR,"read %s: %s\n",
+ source,strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+/* sleep for a while via select */
+void u_sleep(int usec)
+{
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = usec;
+ select(0, NULL, NULL, NULL, &tv);
+}
+
+
+static pid_t all_pids[10];
+static int num_pids;
+
+/* fork and record the pid of the child */
+pid_t do_fork(void)
+{
+ pid_t newpid = fork();
+
+ if (newpid) {
+ all_pids[num_pids++] = newpid;
+ }
+ return newpid;
+}
+
+/* kill all children */
+void kill_all(int sig)
+{
+ int i;
+ for (i=0;i<num_pids;i++) {
+ if (all_pids[i] != getpid())
+ kill(all_pids[i], sig);
+ }
+}
+
+/* this is the rsync debugging function. Call it with FINFO or FERROR */
+void rprintf(int fd, const char *format, ...)
+{
+ va_list ap;
+ char buf[1024];
+ int len;
+ FILE *f=NULL;
+
+ va_start(ap, format);
+
+#if HAVE_VSNPRINTF
+ len = vsnprintf(buf, sizeof(buf)-1, format, ap);
+#else
+ len = vsprintf(buf, format, ap);
+#endif
+ va_end(ap);
+
+ if (len < 0) exit_cleanup(1);
+
+ if (fd == FERROR) {
+ f = stderr;
+ }
+
+ if (fd == FINFO) {
+ extern int am_server;
+ if (am_server)
+ f = stderr;
+ else
+ f = stdout;
+ }
+
+ if (!f) exit_cleanup(1);
+
+ if (fwrite(buf, len, 1, f) != 1) exit_cleanup(1);
+}
+
+void rflush(int fd)
+{
+ FILE *f = NULL;
+
+ if (fd == FERROR) {
+ f = stderr;
+ }
+
+ if (fd == FINFO) {
+ extern int am_server;
+ if (am_server)
+ f = stderr;
+ else
+ f = stdout;
+ }
+
+ if (!f) exit_cleanup(1);
+ fflush(f);
+}