📄 webmaster.c
字号:
/* webmaster.c,v 1.5 2000/09/22 19:30:37 brunsch Exp *//************************************************************************** * * * Copyright (C) 1995 Silicon Graphics, Inc. * * * * These coded instructions, statements, and computer programs were * * developed by SGI for public use. If any changes are made to this code* * please try to get the changes back to the author. Feel free to make * * modifications and changes to the code and release it. * * * **************************************************************************//* FUZZ: disable check_for_math_include */#include <stdio.h>#include <errno.h>#include <signal.h>#include <stdlib.h>#include <string.h>#include <time.h>#ifndef WIN32#include <unistd.h>#endif /* WIN32 */#include <math.h>#ifndef WIN32#include <sys/param.h>#include <sys/types.h>#include <sys/errno.h>#include <sys/socket.h>#include <sys/time.h>#include <netinet/in.h>#include <netdb.h>#else#define FD_SETSIZE 1024 /* max size for select() - keep before <winsock.h> * and same size as MAXCLIENTS */#include <windows.h>#include <winsock.h>#include <io.h>#include <process.h>#endif /* WIN32 */#include "sysdep.h"#include "bench.h"/* command line options/data */int savefile = 0;int debug = 0;int norexec = 0;int haveproxyserver = 0;char proxyserver[MAXHOSTNAMELEN];char network_mask_str[30] = "255.255.255.0";unsigned network_mask = 0;int servaddrin_config = 0;int dumpall = 0;int testtime = 0;int havewebserver = 0;int numloops = 0;NETPORT portnum = 0;int redirect = 0;int record_all_transactions = 0;int uil_filelist_f = 0;int verbose = 0;char webserver[MAXHOSTNAMELEN];char configfile[MAXPATHLEN];char uil_filelist[NCCARGS];char filelist[256][MAXPATHLEN];fd_set zerofdset;/* other key data */long int number_of_pages = 0;int totalnumclients = 0;int num_rexecs = 0;SOCKET socknum[MAXCLIENTS];SOCKET sockIO[MAXTOTALPROCS];SOCKET sockErr[MAXTOTALPROCS];THREAD FILE *debugfile = stderr; struct hostent *master_phe; /* IP addresses for webmaster */struct timeval sumedh_start, sumedh_end;void HostEntCpy(struct hostent *dest, struct hostent *src);static voidusage(const char *progname){ fprintf(stderr, "Usage: %s [-a] [-d] -f config_file [-l numloops]\n", progname); fprintf(stderr, " [-p port_num] [-r] [-s] [-t run_time] \n"); fprintf(stderr, "\n"); fprintf(stderr, "-w webserver URL [URL ...]\n\n"); fprintf(stderr, "-a print timing information for all clients\n"); fprintf(stderr, "-d turn on debug statements\n"); fprintf(stderr, "-f config_file\tfile specifying clients\n"); fprintf(stderr, "-l number of iterations to retrieve uils\n"); fprintf(stderr, "-p port number of web server if not 80\n"); fprintf(stderr, "-r redirect stdout of clients to /tmp/webstone.xxx\n"); fprintf(stderr, "-s save client gets to /tmp/webstone.data.*\n"); fprintf(stderr, "-t run_time\tduration of test in minutes\n"); fprintf(stderr, "-w webserver\tname of webserver host to contact\n"); fprintf(stderr, "-u URL file\tfilelist of URLs\n"); fprintf(stderr, "-v verbose mode\n"); fprintf(stderr, "-P servername\tuse proxy server for transactions\n"); fprintf(stderr, "-W webserver addresses are in the config file\n"); fprintf(stderr, "-R record all transactions\n"); errexit("\n");}static SOCKETpassivesock(const NETPORT portnum, const char *protocol, const int qlen){ struct protoent *ppe; /* pointer to protocol info entry */ struct sockaddr_in sin; /* Internet endpoint address */ SOCKET s; /* socket descriptor */ int type; /* socket type */ D_PRINTF( "Beginning passivesock with errno %d\n",errno ); D_PRINTF( "Zeroing address structure\n" ); memset((char *)&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; /* NOT USED: Map service name to portnumber */ D_PRINTF( "Mapping portnum errno %d\n",errno ); sin.sin_port = htons(portnum); /* Map protocol name to number */ D_PRINTF( "Mapping protocol name errno %d\n",errno ); if ((ppe = getprotobyname(protocol)) == 0) { errexit("Can't get \"%s\" protocol entry\n", protocol); } errno = 0; /* use protocol to choose socket type */ D_PRINTF( "Changing socket type, errno %d\n",errno ); if (strcmp(protocol, "udp") == 0) { type = SOCK_DGRAM; D_PRINTF( "Choosing SOCK_DGRAM\n" ); } else { type = SOCK_STREAM; D_PRINTF( "Choosing SOCK_STREAM, errno %d\n",errno ); } /* allocate a socket */ s = socket(PF_INET, type, ppe->p_proto); if (BADSOCKET(s)) { D_PRINTF( "Socket PF_INET %d %d returned %d with %s\n", type, ppe->p_proto, s, neterrstr() ); errexit("Can't create socket: %s\n", neterrstr()); } D_PRINTF( "Socket %d created with errno %d\n",s,errno ); /* Bind the socket */ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { errexit("Can't bind to port %d: %s\n", portnum, neterrstr()); } D_PRINTF( "Bind succeeded\n" ); /* If it's a stream, listen for connections */ /* NOTE: ON NT, the listen() backlog parm is silently limited to 5 conns */ if ((type == SOCK_STREAM) && BADSOCKET(listen(s, qlen))) { errexit("Can't listen on port %s: %s\n", portnum, neterrstr()); } D_PRINTF( "Listen succeeded\n" ); /* all done, return socket descriptor */ return(s);} /* abort clients -- called by SIGINT handler */static void abort_clients(void){ /* Not supposed to have fprintf in a signal handler, but... */ fprintf(stdout, "Webmaster received SIGINT. Terminating.\n"); /* exit will close all open connections */ exit(2);}/* signal handler for SIGINT */static void sig_int(int sig) { abort_clients();}#ifdef WIN32/* echo stdout/stderr from clients */void echo_client(void *stream){ SOCKET *sockarr; FILE *outfile; int which_stream = (int) stream; char buf[BUFSIZ]; int i, len, rv; fd_set readfds; /* This code which handles the timeout may need to be ifdef'ed for WIN32 */ struct timeval timeout; timeout.tv_sec = (long)5; timeout.tv_usec = (long)0; if (which_stream) { sockarr = sockIO; outfile = stdout; } else { sockarr = sockErr; outfile = stderr; } D_PRINTF( "echo_client running\n" ); signal( SIGINT, SIG_DFL); /* restore default behavior for SIGINT */ while (1) { FD_ZERO(&readfds); for (i = 0; i < num_rexecs; i++) if (sockarr[i] != BADSOCKET_VALUE) FD_SET(sockarr[i], &readfds); rv = select(num_rexecs, &readfds, NULL, NULL, &timeout); if ( rv == 0) continue; if (rv < 0 && WSAGetLastError() == WSANOTINITIALISED) return; if (rv < 0) errexit("Error in echo_client(): select() returns %d: %s\n", rv, neterrstr()); /* loop over the sockets that are ready with data */ for (i = 0; i < num_rexecs; i++) { if (sockarr[i] != BADSOCKET_VALUE && FD_ISSET(sockarr[i], &readfds)) { len = NETREAD(sockarr[i], buf, sizeof(buf)); if (len <= 0) { /* mark connection closed */ sockarr[i] = BADSOCKET_VALUE; if (len < 0 && WSAGetLastError() == WSANOTINITIALISED) return; if (len < 0) fprintf(stderr, "Error in echo_client() after NETREAD(): %s\n", neterrstr()); continue; } /* copy to stdout or stderr */ fwrite(buf, sizeof(char), len, outfile); } } } D_PRINTF( "Exiting echo_client\n" );}#elsestatic intecho_client(char *hostname, const int fd){ /* * WRITE TEXT FROM FILE DESCRIPTOR INTO STDOUT */ char buf[BUFSIZ]; int cc; D_PRINTF( "echo_client running\n" ); while (getppid() != 1) { cc = NETREAD(fd, buf, sizeof(buf)); if (cc > 0) { write(STDOUT_FILENO, buf, cc); } } D_PRINTF( "Exiting echo_client\n" ); NETCLOSE(fd);}#endif /* WIN32 *//* Picks the appropriate webmaster IP address based on the address of the client. * This is significant only for hosts with multiple interfaces * * return value is a string with the IP address or hostname (or NULL) */char *pick_webmaster_IP_address(char *client_hostname, struct hostent *master_phe, unsigned netmask) {static char buf[20];unsigned char addr[4];int client_addr;int i; if (client_hostname[0] >= '0' && client_hostname[0] <= '9') { /* we have an IP address */ client_addr = inet_addr(client_hostname); if (client_addr == INADDR_NONE) return NULL; } else { /* we have a hostname, use the webserver hostname */ return master_phe->h_name; } for (i = 0; master_phe->h_addr_list[i] != NULL; i++) { if ((*(int *)(master_phe->h_addr_list[i]) & netmask) == (client_addr & netmask)) goto gotit; } i = 0; /* give up */gotit: memcpy((char *)addr, master_phe->h_addr_list[i], sizeof(addr)); /* Internet specific */ sprintf(buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); return buf;}/* Command line parsing*/void ParseCmdLine(int argc, char **argv ){char getoptch;int currarg;extern char *optarg;extern int optind; /* * PARSE THE COMMAND LINE OPTIONS */ while((getoptch = getopt(argc,argv,"P:f:t:l:p:u:R:w:n:M:adrsvWX")) != (const char)EOF) { switch(getoptch) { case 'M': strcpy(network_mask_str, optarg); break; case 'P': haveproxyserver = 1; strcpy(proxyserver, optarg); break; case 'R': record_all_transactions = 1; break; case 'X': norexec = 1; break; case 'W': servaddrin_config = 1; break; case 'a': dumpall = 1; break; case 'd': debug = 1; break; case 'f': strcpy(configfile, optarg); break; case 'l': numloops = atoi(optarg); break; case 'p': portnum = atoi(optarg); break; case 'r': redirect = 1; break; case 's': savefile = 1; break; case 't': testtime = atoi(optarg); break; case 'u': uil_filelist_f = 1; strcpy(uil_filelist, optarg); break; case 'v': verbose = 1; break; case 'w': havewebserver = 1; strcpy(webserver, optarg); break; default: usage(argv[0]); } /* end switch */ } /* end while */ if (numloops && testtime) errexit("Can't have both -l and -t\n"); if(!havewebserver && !servaddrin_config) { /* * THE SERVERS NAME MUST BE SPECIFIED */ fprintf(stderr,"No WWW Server specified\n"); usage(argv[0]); } if (havewebserver && servaddrin_config) { /* * CAN'T HAVE BOTH -w and -W */ fprintf(stderr, "Can't have both -w and -W options\n"); usage(argv[0]); } network_mask = inet_addr(network_mask_str); if (network_mask == INADDR_NONE) { fprintf(stderr, "Invalid network mask (-M %s)\n", network_mask_str); usage(argv[0]); } if(strlen(configfile) == 0) { /* * THE MASTER MUST HAVE A CONFIGURATION FILE TO READ. */ fprintf(stderr,"No Configuration file specified\n"); usage(argv[0]); } /* IF WE DO NOT HAVE A FILE LIST THEN THERE ARE UIL'S AT THE END OF THE * COMMAND LINE SO GRAB THEM. */ if (uil_filelist_f == 0) { currarg = optind; number_of_pages = 0; while(currarg != argc) { /* * GET THE UILS TO RETRIEVE. */ sscanf(argv[currarg],"%s",filelist[number_of_pages]); number_of_pages++; currarg++; } } else { /* have filelist; take a stab at the number of valid URLs */ D_PRINTF( "About to parse filelist %s\n", uil_filelist ); number_of_pages = count_file_list(uil_filelist); } if (number_of_pages == 0) { /* * AT LEAST ONE FILE MUST BE SPECIFIED */ fprintf(stderr,"No URL resources specified\n"); usage(argv[0]); }}/* This function sets up the socket we will use to synchronize with the clients. Returns the socket number if successful, doesn't return if it fails*/SOCKET SetupSyncSocket( serveraddr )struct sockaddr_in *serveraddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -