$NetBSD: patch-ag,v 1.2 1999/09/17 18:23:55 tron Exp $ --- socket.c.orig Thu Sep 16 13:52:48 1999 +++ socket.c Thu Sep 16 12:54:06 1999 @@ -9,6 +9,9 @@ #include #include +#ifdef USE_INET6 +#include +#endif /* USE_INET6 */ #include #include #include @@ -18,6 +21,8 @@ #else #include #endif +#include +#include #include "globals.h" /* global variables */ @@ -34,9 +39,17 @@ char *progname ; /* name of the game */ char *pipe_program = NULL ; /* program to execute in two-way pipe */ +#ifndef USE_INET6 void server A((int port, char *service_name)) ; -void handle_server_connection A((void)) ; void client A((char *host, int port, char *service_name)) ; +#else /* USE_INET6 */ +void server A((char *port)) ; +void client A((char *host, char *port)) ; +#endif /* USE_INET6 */ + +void handle_server_connection A((void)) ; +extern void init_signals A((void)) ; +extern void do_io A((void)) ; int main(argc, argv) int argc ; @@ -46,9 +59,11 @@ int opt ; /* option character */ int error = 0 ; /* usage error occurred */ extern int optind ; /* from getopt() */ - char *host ; /* name of remote host */ + /* char *host ; */ /* name of remote host */ +#ifndef USE_INET6 int port ; /* port number for socket */ char *service_name ; /* name of service for port */ +#endif /* USE_INET6 */ /* print version ID if requested */ if (argv[1] && !strcmp(argv[1], "-version")) { @@ -58,7 +73,8 @@ /* set up progname for later use */ progname = argv[0] ; - if (cp = strrchr(progname, '/')) progname = cp + 1 ; + cp = strrchr(progname, '/'); + if (cp) progname = cp + 1 ; /* parse options */ while ((opt = getopt(argc, argv, "bcflp:qrsvw?")) != -1) { @@ -126,6 +142,7 @@ /* set up signal handling */ init_signals() ; +#ifndef USE_INET6 /* get port number */ port = resolve_service(argv[optind + 1 - serverflag], "tcp", &service_name) ; @@ -134,41 +151,81 @@ exit(5) ; } +#endif /* not USE_INET6 */ /* and go */ if (serverflag) { if (backgflag) { background() ; } +#ifndef USE_INET6 server(port, service_name) ; +#else /* USE_INET6 */ + server(argv[optind]) ; +#endif /* USE_INET6 */ } else { +#ifndef USE_INET6 client(argv[optind], port, service_name) ; +#else /* USE_INET6 */ + client(argv[optind], argv[optind + 1]) ; +#endif /* USE_INET6 */ } exit(0) ; } +#ifndef USE_INET6 void server(port, service_name) int port ; char *service_name ; +#else /* USE_INET6 */ +void server(port) +char *port ; +#endif /* USE_INET6 */ { +#ifndef USE_INET6 int socket_handle, alen ; +#else /* USE_INET6 */ + int *socket_handle_list ; +#endif /* USE_INET6 */ /* allocate server socket */ +#ifndef USE_INET6 socket_handle = create_server_socket(port, 1) ; if (socket_handle < 0) { +#else /* USE_INET6 */ + socket_handle_list = create_server_sockets(&port, 1) ; + if (!socket_handle_list) { +#endif /* USE_INET6 */ perror2("server socket") ; exit(1) ; } +#ifdef USE_INET6 + +#endif /* USE_INET6 */ if (verboseflag) { +#ifndef USE_INET6 fprintf(stderr, "listening on port %d", port) ; if (service_name) { fprintf(stderr, " (%s)", service_name) ; } fprintf(stderr, "\n") ; +#else /* USE_INET6 */ + char *ip, *port; + int fd, i; + + fd = socket_handle_list[1]; + for (i = 1; i <= socket_handle_list[0]; i++) { + if (!fd || fd < socket_handle_list[i]) + fd = socket_handle_list[i]; + socket_local_name (fd, NULL, &ip, &port); + fprintf(stderr, "listening at address %s on port %s\n", ip, port) ; + } +#endif /* USE_INET6 */ } /* server loop */ do { +#ifndef USE_INET6 struct sockaddr_in sa ; alen = sizeof(sa) ; @@ -185,16 +242,76 @@ long norder ; char dotted[20] ; - he = gethostbyaddr(&sa.sin_addr.s_addr, + he = gethostbyaddr((const char *)&sa.sin_addr.s_addr, sizeof(sa.sin_addr.s_addr), AF_INET) ; if (!he) { norder = htonl(sa.sin_addr.s_addr) ; sprintf(dotted, "%d.%d.%d.%d", - (norder >> 24) & 0xff, - (norder >> 16) & 0xff, - (norder >> 8) & 0xff, - norder & 0xff) ; + (int)((norder >> 24) & 0xff), + (int)((norder >> 16) & 0xff), + (int)((norder >> 8) & 0xff), + (int)(norder & 0xff)) ; +#else /* USE_INET6 */ + struct timeval tv; + fd_set readfd; + int fd, i, nfds, retval; + + fd = socket_handle_list[1]; + for (i = 1; i <= socket_handle_list[0]; i++) { + if (!fd || fd < socket_handle_list[i]) + fd = socket_handle_list[i]; + } + nfds=fd+1; + + FD_ZERO(&readfd); + for (i = 1; i <= socket_handle_list[0]; i++) + FD_SET(socket_handle_list[i],&readfd); + + tv.tv_sec = 10; + tv.tv_usec = 0; + + retval = select(nfds, &readfd, NULL, NULL, &tv); + + if(retval!=-1) { + for (i = 1; i <= socket_handle_list[0]; i++) { + fd = socket_handle_list[i]; + if (FD_ISSET(fd, &readfd)) { + + /* accept a connection */ + active_socket = accept(fd, (struct sockaddr *) 0, (int *)0); + if (active_socket == -1) { + perror2("accept") ; + } else { + /* if verbose, get name of peer and give message */ + if (verboseflag) { + char *host, *ip, *port; + + if(!socket_remote_name(active_socket,&host, &ip, &port)) { + fprintf(stderr, "connection from %s at %s to %s\n", host, ip, port); + } + else + fprintf(stderr, "cannot get name or address of peer") ; + } + + if (forkflag) { + switch (fork()) { + case 0: + handle_server_connection() ; + exit(0) ; + case -1: + perror2("fork") ; + break ; + default: + close(active_socket) ; + wait_for_children() ; + } + } else { + handle_server_connection() ; + } + } +#endif /* USE_INET6 */ } +#ifndef USE_INET6 fprintf(stderr, "connection from %s\n", (he ? he->h_name : dotted)) ; } @@ -212,9 +329,14 @@ } } else { handle_server_connection() ; +#endif /* not USE_INET6 */ } } } while (loopflag) ; +#ifdef USE_INET6 + + free (socket_handle_list); +#endif /* USE_INET6 */ } @@ -235,13 +357,25 @@ } +#ifndef USE_INET6 void client(host, port, service_name) +#else /* USE_INET6 */ +void client(host, port) +#endif /* USE_INET6 */ char *host ; +#ifndef USE_INET6 int port ; char *service_name ; +#else /* USE_INET6 */ +char *port ; +#endif /* USE_INET6 */ { /* get connection */ +#ifndef USE_INET6 active_socket = create_client_socket(&host, port) ; +#else /* USE_INET6 */ + active_socket = create_client_socket(&host, &port) ; +#endif /* USE_INET6 */ if (active_socket == -1) { perror2("client socket") ; exit(errno) ; @@ -250,11 +384,18 @@ exit(13) ; } if (verboseflag) { +#ifndef USE_INET6 fprintf(stderr, "connected to %s port %d", host, port) ; if (service_name) { fprintf(stderr, " (%s)", service_name) ; } fprintf(stderr, "\n") ; +#else /* USE_INET6 */ + char *host, *ip, *port; + + socket_local_name (active_socket, &host, &ip, &port); + fprintf(stderr, "connected to %s with address %s at port %s\n", host, ip, port) ; +#endif /* USE_INET6 */ } /* open pipes to program if requested */