X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/f0fca04e4e136c4a487a922e8fb09acf46aeafa0..f578043391634ae1d345e84657fec7ecfb0f34a0:/socket.c diff --git a/socket.c b/socket.c index 7027338b..790a86d9 100644 --- a/socket.c +++ b/socket.c @@ -81,7 +81,7 @@ static int open_socket_in(int type, int port) return -1; } - bzero((char *)&sock,sizeof(sock)); + memset((char *)&sock,0,sizeof(sock)); memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length); sock.sin_port = htons(port); sock.sin_family = hp->h_addrtype; @@ -116,21 +116,21 @@ int is_a_socket(int fd) } -int start_accept_loop(int port, int (*fn)(int )) +void start_accept_loop(int port, int (*fn)(int )) { int s; - signal(SIGCLD, SIG_IGN); + signal(SIGCHLD, SIG_IGN); /* open an incoming socket */ s = open_socket_in(SOCK_STREAM, port); if (s == -1) - return(-1); + exit_cleanup(1); /* ready to listen */ if (listen(s, 5) == -1) { close(s); - return -1; + exit_cleanup(1); } @@ -163,7 +163,6 @@ int start_accept_loop(int port, int (*fn)(int )) close(fd); } - return 0; } @@ -217,6 +216,8 @@ set user socket options void set_socket_options(int fd, char *options) { char *tok; + if (!options || !*options) return; + options = strdup(options); if (!options) out_of_memory("set_socket_options"); @@ -295,3 +296,70 @@ void become_daemon(void) close(1); close(2); } + +/******************************************************************* + return the IP addr of the client as a string + ******************************************************************/ +char *client_addr(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static char addr_buf[100]; + + if (getpeername(fd, &sa, &length)) { + exit_cleanup(1); + } + + strlcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr), sizeof(addr_buf)-1); + + return addr_buf; +} + + +/******************************************************************* + return the DNS name of the client + ******************************************************************/ +char *client_name(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static char name_buf[100]; + struct hostent *hp; + char **p; + char *def = "UNKNOWN"; + + strcpy(name_buf,def); + + if (getpeername(fd, &sa, &length)) { + exit_cleanup(1); + } + + /* Look up the remote host name. */ + if ((hp = gethostbyaddr((char *) &sockin->sin_addr, + sizeof(sockin->sin_addr), + AF_INET))) { + strlcpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); + } + + + /* do a forward lookup as well to prevent spoofing */ + hp = gethostbyname(name_buf); + if (!hp) { + strcpy(name_buf,def); + rprintf(FERROR,"reverse name lookup failed\n"); + } else { + for (p=hp->h_addr_list;*p;p++) { + if (memcmp(*p, &sockin->sin_addr, hp->h_length) == 0) { + break; + } + } + if (!*p) { + strcpy(name_buf,def); + rprintf(FERROR,"reverse name lookup mismatch - spoofed address?\n"); + } + } + + return name_buf; +}