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

📄 webmaster.c

📁 最新的版本ACE-5.6.8,刚从外文网上搬下,与大家分享.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: webmaster.c 81998 2008-06-17 09:31:15Z sma $ */
/**************************************************************************
 *                    *
 *     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 */
/* FUZZ: disable check_for_improper_main_declaration */

#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, 0, 0, &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 0;
    } else {
  /* we have a hostname, use the webserver hostname */
  return master_phe->h_name;
    }

    for (i = 0; master_phe->h_addr_list[i] != 0; 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 )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -