/****************************************************************************** tests wwwd - an inetd based World Wide Web server it listens on port 2784 for connections and the forks and execs wwwd passing it the client socket on file descriptor 0 Dave Raggett, HP Labs, Bristol UK. Copyright Hewlett Packard 1993, All rights reserved. *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include /* for string processing functions */ #include /* for setting listen socket to be non-blocking */ #include /* for trapping signals e.g. SIGPIPE */ #include /* for timeouts with select() */ #define PORT 2784 /* port for tcp relay service */ struct sockaddr_in server; /* address info */ struct sockaddr_in client; /* address info */ struct sockaddr_in myself; /* address info */ struct hostent *hp; /* pointer to host info for remote host */ #define HP_SUBNET 15 /* HP has a level 0 IP address */ char *ClientName(int skt) { int len; struct hostent *hp; struct sockaddr_in client; len = sizeof(struct sockaddr_in); if (getpeername(skt, &client, &len) < 0) return "(unknown host)"; hp = gethostbyaddr((char *)&client.sin_addr, sizeof(struct in_addr), client.sin_family); if (hp == NULL) /* host info unavailable so format its address */ return inet_ntoa(client.sin_addr); return hp->h_name; } main(int argc, char **argv) { struct timeval timeout; fd_set readfds, writefds, exceptfds; int i, s, cs, ls, len, addrlen, childpid, world_readable; char *p, sec[20], usec[20], sock[10]; struct timeval tp; struct timezone tzp; /* ensure that children won't become zombies */ signal(SIGCLD, SIG_IGN); world_readable = 0; if (argc > 1 && strcmp(argv[1], "-world") == 0) world_readable = 1; /* set up address structure for receiving requests from clients */ myself.sin_family = AF_INET; myself.sin_addr.s_addr = INADDR_ANY; /* listen on wildcard address */ myself.sin_port = PORT; /* create the listen socket */ ls = socket(AF_INET, SOCK_STREAM, 0); if (ls == -1) { printf("can't create socket: %m\n"); exit(1); } /* bind the listen address to the socket */ if (bind(ls, &myself, sizeof(myself)) == -1) { printf("can't bind address: %m\n"); exit(1); } /* Initiate listen on the socket so remote users can connect, setting listen backlog to 5 (largest currently supported) */ if (listen(ls, 5) == -1) { printf("unable to listen on socket\n: %m"); exit(1); } timeout.tv_sec = 5; /* giving a 5 second timer resolution */ timeout.tv_usec = 0; /* set listen socket to be non-blocking */ i = 1; ioctl(ls, FIOSNBIO, &i); /* enter indefinite loop waiting for requests from clients */ for (;;) { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(ls, &readfds); if ((i = select(NFDBITS, (int*)(&readfds), (int*)(&writefds), (int*)(&exceptfds), 0)) == -1) { printf("select failed"); break; } else if (i == 0) { /* printf("timechk\n"); */ continue; } if (FD_ISSET(ls, &readfds)) /* read from socket skt */ { addrlen = sizeof(struct sockaddr_in); cs = accept(ls, &client, &addrlen); if (cs == -1) { perror("can't accept new client"); continue; } i = client.sin_addr.s_addr; if (i >> 24 != HP_SUBNET) { printf("unauthorised access from %s\n", inet_ntoa(client.sin_addr)); close(cs); continue; } printf("hello from %s\n", ClientName(cs)); childpid = fork(); if (childpid < 0) { perror("fork failed"); close(cs); continue; } if (childpid == 0) { close(0); /* close(1); close(2); */ dup2(cs, 0); /* dup2(cs, 1); dup2(cs, 2); */ close(cs); if (world_readable) execl("/nfs/hplose/permanent/dsr/www/wwwd", "wwwd", "-world", (char *)0); else execl("/nfs/hplose/permanent/dsr/www/wwwd", "wwwd", (char *)0); perror("exec failed"); exit(1); } close(cs); } } }