added --address option for virtual hosting
authorAndrew Tridgell <tridge@samba.org>
Sun, 31 Oct 1999 03:21:02 +0000 (03:21 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 31 Oct 1999 03:21:02 +0000 (03:21 +0000)
options.c
rsync.yo
socket.c

index 7bfe692..cd56b2a 100644 (file)
--- a/options.c
+++ b/options.c
@@ -78,6 +78,8 @@ int quiet = 0;
 int always_checksum = 0;
 int list_only = 0;
 
+struct in_addr socket_address = {INADDR_ANY};
+
 void usage(int F)
 {
   rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
@@ -140,6 +142,7 @@ void usage(int F)
   rprintf(F,"     --include-from=FILE     don't exclude patterns listed in FILE\n");
   rprintf(F,"     --version               print version number\n");  
   rprintf(F,"     --daemon                run as a rsync daemon\n");  
+  rprintf(F,"     --address               bind to the specified address\n");  
   rprintf(F,"     --config=FILE           specify alternate rsyncd.conf file\n");  
   rprintf(F,"     --port=PORT             specify alternate rsyncd port number\n");
   rprintf(F,"     --stats                 give some file transfer stats\n");  
@@ -159,7 +162,7 @@ enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
       OPT_RSYNC_PATH, OPT_FORCE, OPT_TIMEOUT, OPT_DAEMON, OPT_CONFIG, OPT_PORT,
       OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
       OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
-      OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY};
+      OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS};
 
 static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
 
@@ -217,6 +220,7 @@ static struct option long_options[] = {
   {"config",      1,     0,    OPT_CONFIG},
   {"port",        1,     0,    OPT_PORT},
   {"log-format",  1,     0,    OPT_LOG_FORMAT},
+  {"address",     1,     0,    OPT_ADDRESS},
   {0,0,0,0}};
 
 
@@ -518,6 +522,15 @@ int parse_arguments(int argc, char *argv[], int frommain)
                        log_format = optarg;
                        break;
 
+               case OPT_ADDRESS:
+                       {
+                               struct in_addr *ia;
+                               if ((ia = ip_address(optarg))) {
+                                       socket_address = *ia;
+                               }
+                       }
+                       break;
+
                default:
                        slprintf(err_buf,sizeof(err_buf),"unrecognised option\n");
                        return 0;
index 7364718..0b46cde 100644 (file)
--- a/rsync.yo
+++ b/rsync.yo
@@ -272,6 +272,7 @@ Options
      --include-from=FILE     don't exclude patterns listed in FILE
      --version               print version number
      --daemon                run as a rsync daemon
+     --address               bind to the specified address
      --config=FILE           specify alternate rsyncd.conf file
      --port=PORT             specify alternate rsyncd port number
      --stats                 give some file transfer stats
@@ -589,6 +590,12 @@ config file (/etc/rsyncd.conf) on each connect made by a client and
 respond to requests accordingly. See the rsyncd.conf(5) man page for more
 details. 
 
+dit(bf(--address)) By default rsync will bind to the wildcard address
+when run as a daemon with the --daemon option. The --address option
+allows you to specify a specific IP address (or hostname) to bind
+to. This makes virtual hosting possible in conjunction with the
+--config option.
+
 dit(bf(--config=FILE)) This specifies an alternate config file than
 the default /etc/rsyncd.conf. This is only relevant when --daemon is
 specified. 
index 4c81d59..1e7a9ed 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -157,7 +157,7 @@ int open_socket_out(char *host, int port)
 /****************************************************************************
 open a socket of the specified type, port and address for incoming data
 ****************************************************************************/
-static int open_socket_in(int type, int port)
+static int open_socket_in(int type, int port, struct in_addr *address)
 {
        struct hostent *hp;
        struct sockaddr_in sock;
@@ -181,7 +181,11 @@ static int open_socket_in(int type, int port)
        memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
        sock.sin_port = htons(port);
        sock.sin_family = hp->h_addrtype;
-       sock.sin_addr.s_addr = INADDR_ANY;
+       if (address) {
+               sock.sin_addr = *address;
+       } else {
+               sock.sin_addr.s_addr = INADDR_ANY;
+       }
        res = socket(hp->h_addrtype, type, 0);
        if (res == -1) { 
                rprintf(FERROR,"socket failed\n"); 
@@ -215,9 +219,10 @@ int is_a_socket(int fd)
 void start_accept_loop(int port, int (*fn)(int ))
 {
        int s;
+       extern struct in_addr socket_address;
 
        /* open an incoming socket */
-       s = open_socket_in(SOCK_STREAM, port);
+       s = open_socket_in(SOCK_STREAM, port, &socket_address);
        if (s == -1)
                exit_cleanup(RERR_SOCKETIO);
 
@@ -480,3 +485,39 @@ char *client_name(int fd)
 
        return name_buf;
 }
+
+/*******************************************************************
+convert a string to an IP address. The string can be a name or
+dotted decimal number
+  ******************************************************************/
+struct in_addr *ip_address(const char *str)
+{
+       static struct in_addr ret;
+       struct hostent *hp;
+
+       /* try as an IP address */
+       if (inet_aton(str, &ret) != 0) {
+               return &ret;
+       }
+
+       /* otherwise assume it's a network name of some sort and use 
+          gethostbyname */
+       if ((hp = gethostbyname(str)) == 0) {
+               rprintf(FERROR, "gethostbyname: Unknown host. %s\n",str);
+               return NULL;
+       }
+
+       if (hp->h_addr == NULL) {
+               rprintf(FERROR, "gethostbyname: host address is invalid for host %s\n",str);
+               return NULL;
+       }
+
+       if (hp->h_length > sizeof(ret)) {
+               rprintf(FERROR, "gethostbyname: host address is too large\n");
+               return NULL;
+       }
+
+       memcpy(&ret.s_addr, hp->h_addr, hp->h_length);
+
+       return(&ret);
+}