]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
Some improvements for --msgs2stderr and --daemon.
authorWayne Davison <wayne@opencoder.net>
Sun, 31 May 2020 22:25:11 +0000 (15:25 -0700)
committerWayne Davison <wayne@opencoder.net>
Sun, 31 May 2020 23:02:46 +0000 (16:02 -0700)
- Set am_daemon to -1 (from 1) when the daemon is run via rsh.
- Only disable --msgs2stderr for a normal (socket) daemon.
- Forward a -q to the server if --msgs2stderr was also specified.
- Added --no-msgs2stderr option to allow it to be overridden.

clientserver.c
log.c
options.c
rsync.yo

index a6c24cf38ee810d2e1e330acb591b56e5a09f7bc..3af97d84516b8435f73e4a1d333b1c82f4aadb4b 100644 (file)
@@ -30,6 +30,7 @@ extern int am_sender;
 extern int am_server;
 extern int am_daemon;
 extern int am_root;
+extern int msgs2stderr;
 extern int rsync_port;
 extern int protect_args;
 extern int ignore_errors;
@@ -543,7 +544,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
                return -1;
        }
 
-       if (am_daemon && am_server) {
+       if (am_daemon > 0) {
                rprintf(FLOG, "rsync allowed access on module %s from %s (%s)\n",
                        name, host, addr);
        }
@@ -883,6 +884,8 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
                orig_early_argv = NULL;
 
        munge_symlinks = save_munge_symlinks; /* The client mustn't control this. */
+       if (am_daemon > 0)
+               msgs2stderr = 0; /* A non-rsh-run daemon doesn't have stderr for msgs. */
 
        if (pre_exec_pid) {
                err_msg = finish_pre_exec(pre_exec_pid, pre_exec_arg_fd, pre_exec_error_fd,
@@ -1029,7 +1032,7 @@ static void send_listing(int fd)
 static int load_config(int globals_only)
 {
        if (!config_file) {
-               if (am_server && am_root <= 0)
+               if (am_daemon < 0 && am_root <= 0)
                        config_file = RSYNCD_USERCONF;
                else
                        config_file = RSYNCD_SYSCONF;
@@ -1047,6 +1050,13 @@ int start_daemon(int f_in, int f_out)
        char *p;
        int i;
 
+       /* At this point, am_server is only set for a daemon started via rsh.
+        * Because am_server gets forced on soon, we'll set am_daemon to -1 as
+        * a flag that can be checked later on to distinguish a normal daemon
+        * from an rsh-run daemon. */
+       if (am_server)
+               am_daemon = -1;
+
        io_set_sock_fds(f_in, f_out);
 
        /* We must load the config file before calling any function that
@@ -1096,7 +1106,7 @@ int start_daemon(int f_in, int f_out)
        host = lp_reverse_lookup(-1) ? client_name(f_in) : undetermined_hostname;
        rprintf(FLOG, "connect from %s (%s)\n", host, addr);
 
-       if (!am_server) {
+       if (am_daemon > 0) {
                set_socket_options(f_in, "SO_KEEPALIVE");
                set_nonblocking(f_in);
        }
diff --git a/log.c b/log.c
index 653867549ea67ad50824e4bcd494f8bc47d5a113..ded8045b593c6e9a8a81d5b81353822e13d92429 100644 (file)
--- a/log.c
+++ b/log.c
@@ -264,14 +264,13 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
                exit_cleanup(RERR_MESSAGEIO);
 
        if (msgs2stderr) {
-               if (!am_daemon) {
-                       if (code == FLOG)
-                               return;
-                       goto output_msg;
-               }
-               if (code == FCLIENT)
-                       return;
-               code = FLOG;
+               /* A normal daemon can get msgs2stderr set if the socket is busted, so we
+                * change the message destination into an FLOG message in order to try to
+                * get some info about an abnormal-exit into the log file. An rsh daemon
+                * can have this set via user request, so we'll leave the code alone so
+                * that the msg gets logged and then sent to stderr after that. */
+               if (am_daemon > 0 && code != FCLIENT)
+                       code = FLOG;
        } else if (send_msgs_to_gen) {
                assert(!is_utf8);
                /* Pass the message to our sibling in native charset. */
@@ -307,10 +306,28 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
        } else if (code == FLOG)
                return;
 
-       if (quiet && code == FINFO)
-               return;
+       switch (code) {
+       case FERROR_XFER:
+               got_xfer_error = 1;
+               /* FALL THROUGH */
+       case FERROR:
+       case FWARNING:
+               f = stderr;
+               break;
+       case FINFO:
+               if (quiet)
+                       return;
+               break;
+       //case FLOG:
+       //case FCLIENT:
+       //case FERROR_UTF8:
+       //case FERROR_SOCKET:
+       default:
+               fprintf(stderr, "Bad logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
+               exit_cleanup(RERR_MESSAGEIO);
+       }
 
-       if (am_server) {
+       if (am_server && !msgs2stderr) {
                enum msgcode msg = (enum msgcode)code;
                if (protocol_version < 30) {
                        if (msg == MSG_ERROR)
@@ -321,33 +338,13 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
                /* Pass the message to the non-server side. */
                if (send_msg(msg, buf, len, !is_utf8))
                        return;
-               if (am_daemon) {
+               if (am_daemon > 0) {
                        /* TODO: can we send the error to the user somehow? */
                        return;
                }
                f = stderr;
        }
 
-output_msg:
-       switch (code) {
-       case FERROR_XFER:
-               got_xfer_error = 1;
-               /* FALL THROUGH */
-       case FERROR:
-       case FERROR_UTF8:
-       case FERROR_SOCKET:
-       case FWARNING:
-               f = stderr;
-               break;
-       case FLOG:
-       case FINFO:
-       case FCLIENT:
-               break;
-       default:
-               fprintf(stderr, "Unknown logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
-               exit_cleanup(RERR_MESSAGEIO);
-       }
-
        if (output_needs_newline) {
                fputc('\n', f);
                output_needs_newline = 0;
index 6a7e7aac1f6d1de7a7352560a4c5851e3e288776..73f80ad2e783385f0793dfd25e8a10be5fdfc24c 100644 (file)
--- a/options.c
+++ b/options.c
@@ -731,7 +731,7 @@ void usage(enum logcode F)
   rprintf(F," -v, --verbose               increase verbosity\n");
   rprintf(F,"     --info=FLAGS            fine-grained informational verbosity\n");
   rprintf(F,"     --debug=FLAGS           fine-grained debug verbosity\n");
-  rprintf(F,"     --msgs2stderr           special output handling for debugging\n");
+  rprintf(F,"     --msgs2stderr           output messages directly to stderr\n");
   rprintf(F," -q, --quiet                 suppress non-error messages\n");
   rprintf(F,"     --no-motd               suppress daemon-mode MOTD (see manpage caveat)\n");
   rprintf(F," -c, --checksum              skip based on checksum, not mod-time & size\n");
@@ -901,6 +901,7 @@ static struct poptOption long_options[] = {
   {"info",             0,  POPT_ARG_STRING, 0, OPT_INFO, 0, 0 },
   {"debug",            0,  POPT_ARG_STRING, 0, OPT_DEBUG, 0, 0 },
   {"msgs2stderr",      0,  POPT_ARG_NONE,   &msgs2stderr, 0, 0, 0 },
+  {"no-msgs2stderr",   0,  POPT_ARG_VAL,    &msgs2stderr, 0, 0, 0 },
   {"quiet",           'q', POPT_ARG_NONE,   0, 'q', 0, 0 },
   {"motd",             0,  POPT_ARG_VAL,    &output_motd, 1, 0, 0 },
   {"no-motd",          0,  POPT_ARG_VAL,    &output_motd, 0, 0, 0 },
@@ -2578,7 +2579,8 @@ void server_options(char **args, int *argc_p)
        for (i = 0; i < verbose; i++)
                argstr[x++] = 'v';
 
-       /* the -q option is intentionally left out */
+       if (quiet && msgs2stderr)
+               argstr[x++] = 'q';
        if (make_backups)
                argstr[x++] = 'b';
        if (update_only)
index 37421c94c53a65cd7387cd1ad176e38138ea82b6..02481084e34f94035b89d5659d52099238c80799 100644 (file)
--- a/rsync.yo
+++ b/rsync.yo
@@ -342,7 +342,7 @@ to the detailed description below for a complete description.  verb(
  -v, --verbose               increase verbosity
      --info=FLAGS            fine-grained informational verbosity
      --debug=FLAGS           fine-grained debug verbosity
-     --msgs2stderr           special output handling for debugging
+     --msgs2stderr           output messages directly to stderr 
  -q, --quiet                 suppress non-error messages
      --no-motd               suppress daemon-mode MOTD (see caveat)
  -c, --checksum              skip based on checksum, not mod-time & size
@@ -584,15 +584,20 @@ verb(    rsync -aiv {-M,}--debug=del2 src/ dest/ )
 
 dit(bf(--msgs2stderr)) This option changes rsync to send all its output
 directly to stderr rather than to send messages to the client side via the
-protocol (which normally outputs info messages via stdout).  This is mainly
-intended for debugging in order to avoid changing the data sent via the
-protocol, since the extra protocol data can change what is being tested.
+protocol. The protocol allows rsync to output normal messages via stdout and
+errors via stderr, but it can delay messages behind a slew of data.
+
+One case where this is helpful is when sending really large files, since errors
+that happen on a remote receiver tend to get delayed until afer the file's data
+is fully sent.  It is also helpful for debugging, since it helps to avoid
+overpopulating the protocol data with extra message data.
+
 The option does not affect the remote side of a transfer without using
-bf(--remote-option) -- e.g. bf(-M--msgs2stderr).
-Also keep in mind that a daemon connection does not have a stderr channel to send
-messages back to the client side, so if you are doing any daemon-transfer
-debugging using this option, you should start up a daemon using bf(--no-detach)
-so that you can see the stderr output on the daemon side.
+bf(--remote-option) -- e.g. bf(-M--msgs2stderr) or bf({-M,}--msgs2stderr).
+
+Also keep in mind that connecting to a normal (non-remote-shell) daemon does
+not have a stderr channel to send messages back to the client side, so a modern
+rsync only allows the option on a remote-shell-run daemon.
 
 This option has the side-effect of making stderr output get line-buffered so
 that the merging of the output of 3 programs happens in a more readable manner.