+#include "inums.h"
+#include "io.h"
+#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+extern int dry_run;
+extern int list_only;
+extern int am_root;
+extern int am_server;
+extern int am_sender;
+extern int am_daemon;
+extern int inc_recurse;
+extern int blocking_io;
+extern int always_checksum;
+extern int remove_source_files;
+extern int output_needs_newline;
+extern int need_messages_from_generator;
+extern int kluge_around_eof;
+extern int got_xfer_error;
+extern int msgs2stderr;
+extern int module_id;
+extern int copy_links;
+extern int copy_dirlinks;
+extern int copy_unsafe_links;
+extern int keep_dirlinks;
+extern int preserve_hard_links;
+extern int protocol_version;
+extern int file_total;
+extern int recurse;
+extern int xfer_dirs;
+extern int protect_args;
+extern int relative_paths;
+extern int sanitize_paths;
+extern int curr_dir_depth;
+extern int curr_dir_len;
+extern int module_id;
+extern int rsync_port;
+extern int whole_file;
+extern int read_batch;
+extern int write_batch;
+extern int batch_fd;
+extern int filesfrom_fd;
+extern int connect_timeout;
+extern pid_t cleanup_child_pid;
+extern unsigned int module_dirlen;
+extern struct stats stats;
+extern char *stdout_format;
+extern char *logfile_format;
+extern char *filesfrom_host;
+extern char *partial_dir;
+extern char *dest_option;
+extern char *rsync_path;
+extern char *shell_cmd;
+extern char *batch_name;
+extern char *password_file;
+extern char curr_dir[MAXPATHLEN];
+extern char *basis_dir[MAX_BASIS_DIRS+1];
+extern struct file_list *first_flist;
+extern struct filter_list_struct daemon_filter_list;
+
+uid_t our_uid;
+int am_generator = 0;
+int local_server = 0;
+int daemon_over_rsh = 0;
+mode_t orig_umask = 0;
+int batch_gen_fd = -1;
+int sender_keeps_checksum = 0;
+
+/* There's probably never more than at most 2 outstanding child processes,
+ * but set it higher, just in case. */
+#define MAXCHILDPROCS 7
+
+#ifdef HAVE_SIGACTION
+# ifdef HAVE_SIGPROCMASK
+# define SIGACTMASK(n,h) SIGACTION(n,h), sigaddset(&sigmask,(n))
+# else
+# define SIGACTMASK(n,h) SIGACTION(n,h)
+# endif
+static struct sigaction sigact;
+#endif
+
+struct pid_status {
+ pid_t pid;
+ int status;
+} pid_stat_table[MAXCHILDPROCS];
+
+static time_t starttime, endtime;
+static int64 total_read, total_written;
+
+static void show_malloc_stats(void);
+
+/* Works like waitpid(), but if we already harvested the child pid in our
+ * remember_children(), we succeed instead of returning an error. */
+pid_t wait_process(pid_t pid, int *status_ptr, int flags)
+{
+ pid_t waited_pid;
+
+ do {
+ waited_pid = waitpid(pid, status_ptr, flags);
+ } while (waited_pid == -1 && errno == EINTR);
+
+ if (waited_pid == -1 && errno == ECHILD) {
+ /* Status of requested child no longer available: check to
+ * see if it was processed by remember_children(). */
+ int cnt;
+ for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
+ if (pid == pid_stat_table[cnt].pid) {
+ *status_ptr = pid_stat_table[cnt].status;
+ pid_stat_table[cnt].pid = 0;
+ return pid;
+ }
+ }
+ }