⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webmaster.c

📁 ACE源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 void
usage(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 SOCKET
passivesock(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" );
}

#else
static int
echo_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 + -