From 5c9730a46c44e5913a4d4767bd99ec23f2f81073 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 31 Oct 1999 03:21:02 +0000 Subject: [PATCH] added --address option for virtual hosting --- options.c | 15 ++++++++++++++- rsync.yo | 7 +++++++ socket.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/options.c b/options.c index 7bfe6921..cd56b2a1 100644 --- 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; diff --git a/rsync.yo b/rsync.yo index 7364718a..0b46cde8 100644 --- 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. diff --git a/socket.c b/socket.c index 4c81d597..1e7a9edb 100644 --- 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); +} -- 2.34.1