Receiving an @ERROR line from the server is (I think) always fatal, so
[rsync/rsync.git] / clientserver.c
index 5667b1d..2babcff 100644 (file)
@@ -38,9 +38,15 @@ extern int sanitize_paths;
  * Run a client connected to an rsyncd.  The alternative to this
  * function for remote-shell connections is do_cmd().
  *
- * After initial server startup, hands over to client_run().
+ * After negotiating which module to use and reading the server's
+ * motd, this hands over to client_run().  Telling the server the
+ * module will cause it to chroot/setuid/etc.
+ *
+ * Instead of doing a transfer, the client may at this stage instead
+ * get a listing of remote modules and exit.
  *
  * @return -1 for error in startup, or the result of client_run().
+ * Either way, it eventually gets passed to exit_cleanup().
  **/
 int start_socket_client(char *host, char *path, int argc, char *argv[])
 {
@@ -147,12 +153,22 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
 
                if (strcmp(line,"@RSYNCD: OK") == 0) break;
 
-               if (strcmp(line,"@RSYNCD: EXIT") == 0) exit(0);
+               if (strcmp(line,"@RSYNCD: EXIT") == 0) {
+                       /* This is sent by recent versions of the
+                        * server to terminate the listing of modules.
+                        * We don't want to go on and transfer
+                        * anything; just exit. */
+                       exit(0);
+               }
 
-               if (strncmp(line, "@ERROR", 6) == 0)
+               if (strncmp(line, "@ERROR", 6) == 0) {
                        rprintf(FERROR,"%s\n", line);
-               else
+                       /* This is always fatal; the server will now
+                        * close the socket. */
+                       return RERR_STARTCLIENT;
+               } else {
                        rprintf(FINFO,"%s\n", line);
+               }
        }
        kludge_around_eof = False;