summaryrefslogtreecommitdiff
path: root/apps/JAWS/clients/WebSTONE/src/webclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/JAWS/clients/WebSTONE/src/webclient.c')
-rw-r--r--apps/JAWS/clients/WebSTONE/src/webclient.c1295
1 files changed, 0 insertions, 1295 deletions
diff --git a/apps/JAWS/clients/WebSTONE/src/webclient.c b/apps/JAWS/clients/WebSTONE/src/webclient.c
deleted file mode 100644
index 881c9db0ae8..00000000000
--- a/apps/JAWS/clients/WebSTONE/src/webclient.c
+++ /dev/null
@@ -1,1295 +0,0 @@
-/**************************************************************************
- * $Header$
- * 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. *
- * *
- **************************************************************************/
-
-#include <thread.h>
-
-#include <stdio.h>
-
-#ifdef WIN32
-#include <windows.h>
-#include <winsock.h>
-#include <time.h>
-#include <process.h>
-#include <io.h>
-#endif /* WIN32 */
-
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef WIN32
-#include <netdb.h>
-#include <unistd.h>
-#endif /* WIN32 */
-
-#include <time.h>
-#include <math.h>
-
-#ifndef WIN32
-#include <sys/param.h>
-#endif /* WIN32 */
-
-#include <sys/types.h>
-
-#ifndef WIN32
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/errno.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif /* WIN32 */
-
-#include <ctype.h>
-
-#include "sysdep.h"
-#include "bench.h"
-
-#define _BSD_SIGNALS
-#define INFINITY 100000000
-#define DEFAULTWWWPORT 80
-#define LOG_FILE "logfile"
-#ifdef WIN32
-#define DEBUG_FILE "c:/tmp/webstone-debug"
-#else
-#define DEBUG_FILE "/tmp/webstone-debug"
-#endif /* WIN32 */
-#define NCCARGS 4096
-
-/* global variables */
-
- THREAD FILE *debugfile = stderr;
- page_list_t *load_file_list; /* actually a dynamic array */
-
-int amclient = 0;
-int havewebserver = 0;
-int haveproxyserver = 0;
-int savefile = 0;
-NETPORT portnum = DEFAULTWWWPORT;
-int timeexpired = 0;
-int debug = 0;
-long int number_of_pages = 0;
-char webmaster[MAXHOSTNAMELEN];
-char webserver[MAXHOSTNAMELEN];
-char proxyserver[MAXHOSTNAMELEN];
-
-
-#ifdef WIN32
-HANDLE hSemaphore;
-int CounterSemaphore = 0; /* counter semaphore for children */
-#endif /* WIN32 */
-
-static void ClientThread(void *);
-
-/* used to bypass DNS/YP name resolution for every page */
-struct hostent webserv_phe, webmast_phe;
-struct protoent webserv_ppe, webmast_ppe;
-unsigned long webserv_addr, webmast_addr;
-short webserv_type, webmast_type; /* socket type */
-
-/* End of globals */
-
-
-static void
-usage(const char *progname)
-{
- returnerr("Usage: %s [-d] [-w webserver] [-p port_num]\n",
- progname);
- returnerr("\t[-c masterhost:port] [-t run_time | -l loops]\n");
- returnerr("\t[-n numclients] [-R]\n");
- returnerr("\t[-f config_file] [-u uilfile | url ...]\n");
- errexit("\n");
-} /* END usage() */
-
-static void
-alarmhandler(void)
-{
- /* RECEIVED AN ALARM SIGNAL */
- timeexpired = 1;
-} /* END alarmhandler() */
-
-#ifndef WIN32
-static void
-childhandler(void)
-{
- int status;
-
- /* RECEIVED A SIGNAL THAT A CHILD PROCESS HAS DIED */
- D_PRINTF( "A child process has died\n" );
- while (wait3(&status, WNOHANG, (struct rusage *)0) >= 0)
- {
- /* do nothing */
- ;
- }
-} /* END childhandler() */
-#endif /* WIN32 */
-
-
-/* look up the host name and protocol
- * called once by main() since all threads
- * use the same protocol and address
- */
-
-int resolve_addrs(char *host, char *protocol, struct hostent *host_phe, struct protoent *proto_ppe, unsigned long *addr,
- short *type) {
-struct hostent *phe;
-struct protoent *ppe;
-
- /* if IP address given, convert to internal form */
- if (host[0] >= '0' && host[0] <= '9') {
- *addr = inet_addr(host);
- if (*addr == INADDR_NONE)
- return(returnerr("Invalid IP address %s\n", host));
-
- } else {
- /* look up by name */
- phe = gethostbyname(host);
- if (phe == NULL)
- {
- D_PRINTF( "Gethostbyname failed: %s", neterrstr() );
- return(returnerr("Can't get %s host entry\n", host));
- }
- memcpy(host_phe, phe, sizeof(struct hostent));
- memcpy((char *)addr, phe->h_addr, sizeof(*addr));
- }
-
- /* Map protocol name to protocol number */
- ppe = getprotobyname(protocol);
-
- if (ppe == 0)
- {
- D_PRINTF( "protobyname returned %d\n", ppe );
- return(returnerr("Can't get %s protocol entry\n",protocol));
- }
- memcpy(proto_ppe, ppe, sizeof(struct protoent));
-
- D_PRINTF( "Protocol number %d\n", ppe->p_proto );
-
- /* Use protocol to choose a socket type */
- if (strcmp(protocol,"udp") == 0)
- {
- *type = SOCK_DGRAM;
- }
- else
- {
- *type = SOCK_STREAM;
- D_PRINTF( "Choosing SOCK_STREAM %d type %d %s\n",
- SOCK_STREAM, *type, neterrstr() );
- }
-
- return 0;
-}
-
-/* connect to a socket given the hostname and protocol */
-SOCKET
-connectsock(char *host, NETPORT portnum, char *protocol)
- {
- struct sockaddr_in sin; /* an Internet endpoint address */
- SOCKET s; /* socket descriptor */
- int type; /* socket type */
- short proto;
- int returnval; /* temporary return value */
-
- D_PRINTF( "Beginning connectsock; host=%s port=%d proto=%s\n", host,
- portnum, protocol );
-
- sin.sin_family = AF_INET;
- memset((char *)&sin, 0, sizeof(sin));
- D_PRINTF( "Zeroed address structure\n" );
-
- sin.sin_port = htons(portnum);
- D_PRINTF( "Set port number %d\n", portnum );
-
- /* get the contact information */
- if (strcmp(host, webserver) == 0) {
- sin.sin_addr.S_ADDR = webserv_addr;
- sin.sin_family = PF_INET;
- proto = webserv_ppe.p_proto;
- type = webserv_type;
- } else if (strcmp(host, webmaster) == 0) {
- sin.sin_addr.S_ADDR = webmast_addr;
- sin.sin_family = PF_INET;
- proto = webmast_ppe.p_proto;
- type = webmast_type;
- } else {
- struct hostent host_phe;
- struct protoent host_ppe;
- unsigned long host_addr;
- short host_type; /* socket type */
-
- if (resolve_addrs(host, "tcp", &host_phe, &host_ppe, &host_addr, &host_type))
- return returnerr("Can't resolve hostname %s in get()\n", host);
- sin.sin_addr.S_ADDR = host_addr;
- sin.sin_family = PF_INET;
- proto = host_ppe.p_proto;
- type = host_type;
- }
-
- /* Allocate a socket */
- s = socket(PF_INET, type, proto);
- D_PRINTF( "Socket %d returned %d, %s\n",
- type, s, neterrstr() );
-
- if (BADSOCKET(s))
- {
- D_PRINTF( "Can't create socket: %s\n",neterrstr() );
- return BADSOCKET_VALUE;
- }
-
- /* Connect the socket */
- D_PRINTF( "Trying to connect %d with size %d, %s\n",
- s, sizeof(sin), neterrstr() );
- D_PRINTF( "Address is family %d, port %d, addr %s\n",
- sin.sin_family, ntohs(sin.sin_port),
- inet_ntoa(sin.sin_addr) );
-
- returnval = connect(s, (struct sockaddr *)&sin, sizeof(sin));
- D_PRINTF( "Connect returned %d, %s\n",
- returnval, neterrstr() );
- if (returnval < 0)
- {
- D_PRINTF( "Can't connect: %s\n", neterrstr() );
- NETCLOSE(s);
- return BADSOCKET_VALUE;
- }
-
- /* all done, returning socket descriptor */
- D_PRINTF( "Returning %d from connectsock call\n", s );
- return(s);
-
-} /* END connectsock() */
-
-SOCKET
-connecttomaster(char *str)
-{
- char *tempch;
- SOCKET sock;
- char msg[100];
- char ConnectStr[100]; /* Fix to handle multiple threads */
- int tries;
-
- strcpy(ConnectStr, str);
-
- /*
- * BREAK UP THE connectstr INTO A HOSTNAME/HOST-IP AND A PORT NUMBER.
- */
- if((tempch = strpbrk(ConnectStr,":")) == NULL)
- {
- /*
- * INCORRECT FORMAT OF ConnectStr. CORRECT FORMAT IS
- * HOSTNAME:PORT OR HOST-IP:PORT
- */
- D_PRINTF( "Incorrect format %s: use hostname:port or ip_addr:port\n",
- ConnectStr );
- return(returnerr("Incorrect format %s: use host:port or ip_addr:port\n",
- ConnectStr));
- }
-
- /*
- * ZERO OUT THE COLON SO WE HAVE TWO STRINGS, THE HOSTNAME AND THE PORT
- */
- *tempch = '\0';
- tempch++;
-
- /* loop here to connect to webmaster - TCP/IP allows no more than 5
- * connection requests outstanding at once and thus the webmaster may
- * reject a connection if there are a lot of client processes
- */
-#define MAXTRIES 30
-#define TRYDELAY_SEC 1
- for (tries = 0; tries < MAXTRIES; tries++) {
-
- sock = connectsock(ConnectStr,(NETPORT)atoi(tempch),"tcp");
-
- if (!BADSOCKET(sock))
- break;
-
- sleep(TRYDELAY_SEC);
- }
-
- if (BADSOCKET(sock))
- {
- /* ERROR CONNECTING TO MASTER PROCESS */
- return(returnerr("Could not connect to master process\n"));
- }
-
- /*
- * SIGNAL THE MASTER THAT WE ARE READY TO PROCEED. WHEN ALL
- * CHILD PROCESSES HAVE CONNECTED AND SENT THIS SIGNAL,
- * THE MASTER WILL ISSUE US A GO SIGNAL.
- */
- if(NETWRITE(sock,READYSTR,READYSTRLEN) != READYSTRLEN)
- {
- return(returnerr("Error sending READY message to master"));
- }
-
- memset(msg,0,GOSTRLEN+1);
- if(NETREAD(sock,msg,GOSTRLEN) != GOSTRLEN)
- {
- D_PRINTF( "Error receiving GO message from master: %s\n", neterrstr()
- );
- return(returnerr("Error receiving GO message from master\n"));
- }
-
- if(strncmp(GOSTR,msg,GOSTRLEN))
- {
- /*
- * WE RECEIVED A MESSAGE OTHER THAN GO. PRINT IT OUT AND RETURN ERROR
- */
- return(returnerr("Received non-GO message %s\n",msg));
- }
-
- return(sock);
-
-} /* END connecttomaster() */
-
-
-static void
-accumstats(rqst_timer_t *rqsttimer, page_stats_t *pagestats, stats_t *timestat)
-{
- rqst_stats_t rqststats;
-
-#define TFMT "%10u:%10u"
- /*
- * DUMP THE TIMING INFORMATION HERE, OR COMPUTE WHAT YOU WANT TO
- * PRINT OUT LATER.
- */
-
- D_PRINTF( "Total bytes read: %d \t Body size read: %d\n",
- rqsttimer->totalbytes,
- rqsttimer->bodybytes );
-
- D_PRINTF( "Enter time: " TFMT " \t Exit Time: " TFMT "\n",
- rqsttimer->entertime.tv_sec,
- rqsttimer->entertime.tv_usec,
- rqsttimer->exittime.tv_sec,
- rqsttimer->exittime.tv_usec );
- D_PRINTF( "Before connect: " TFMT " \t After connect: " TFMT "\n",
- rqsttimer->beforeconnect.tv_sec,
- rqsttimer->beforeconnect.tv_usec,
- rqsttimer->afterconnect.tv_sec,
- rqsttimer->afterconnect.tv_usec );
- D_PRINTF( "Before header: " TFMT " \t After header: " TFMT "\n",
- rqsttimer->beforeheader.tv_sec,
- rqsttimer->beforeheader.tv_usec,
- rqsttimer->afterheader.tv_sec,
- rqsttimer->afterheader.tv_usec );
- D_PRINTF( "After body: " TFMT "\n",
- rqsttimer->afterbody.tv_sec,
- rqsttimer->afterbody.tv_usec );
-
- rqstat_times(&(rqststats), rqsttimer);
- rqstat_sum(&(timestat->rs), &(rqststats));
- rqstat_sum(&(pagestats->rs), &(rqststats));
-
- if (rqsttimer->page_number != 999)
- {
- timestat->page_numbers[rqsttimer->page_number] += 1;
- }
-
-#undef TFMT
-} /* END accumstats */
-
-
-/*
- * fetch the set of files that constitute a page
- *
- * maxcount = the number of files in the WWW page
- * pageval = the number of the WWW page (offset in load_file_list[])
- * (if -1, use page # 0 - does this still work?)
- *
- * returns the number of files retrieved
- */
-static int
-makeload(int maxcount, int pageval, THREAD rqst_timer_t *timerarray, THREAD stats_t *timestat, THREAD SOCKET mastersock, THREAD page_stats_t *page_stats)
-{
- int cnt;
- int returnval;
- page_stats_t page_stats_tmp;
- char server[MAXHOSTNAMELEN];
-
- NETPORT loc_portnum;
-
- D_PRINTF( "Starting makeload(maxcount %d, pageval %d)\n",
- maxcount, pageval );
-
- strcpy( server, webserver); /* Put in default value */
-
- page_stats_init(&page_stats_tmp);
- D_PRINTF( "Page stats initialized\n" );
-
- for (cnt = 0; cnt < maxcount; cnt++)
- {
- D_PRINTF( "Loop count %d in makeload()\n", cnt );
- if (pageval == -1)
- {
- pageval = cnt;
- }
- if (timeexpired)
- {
- break;
- }
-
- /* check for a filename */
- if (strlen(load_file_list[pageval].filename[cnt]) < 1)
- {
- D_PRINTF( "Bad filename at pageval %d, count %d\n",
- pageval, cnt );
- return(returnerr("Bad filename at pageval %d, count %d\n",
- pageval, cnt));
- }
-
- /* if (load_file_list[pageval].port_number[cnt] != 0)
- {
- loc_portnum = load_file_list[pageval].port_number[cnt];
- }
- else
- {
- loc_portnum = portnum;
- } */
- loc_portnum = portnum;
- if ((load_file_list[pageval].servername[cnt] != NULL)
- &&
- *load_file_list[pageval].servername[cnt])
- {
- D_PRINTF( "Copying URL server %s to server\n",
- load_file_list[pageval].servername[cnt] );
- strcpy(server, load_file_list[pageval].servername[cnt]);
- }
-
- if (haveproxyserver)
- {
- D_PRINTF( "Copying proxy %s to webserver\n", proxyserver );
- strcpy(server, proxyserver);
- }
-
-
- D_PRINTF( "Calling get(%s, %d, %s, &(timearray[%d]))\n",
- server, loc_portnum, load_file_list[pageval].filename[cnt],
- cnt );
-
- returnval = get(server, loc_portnum,
- load_file_list[pageval].filename[cnt],
- &(timerarray[cnt]));
- if (returnval < 0)
- {
- D_PRINTF( "***GET() RETURNED AN ERROR\n" );
- }
-
- /*
- * DID GET() RETURN A VALID TIME?
- */
- if ((returnval == 0) && (timerarray[cnt].valid == 2))
- {
- timerarray[cnt].page_number = pageval;
-
- accumstats(&timerarray[cnt], &page_stats_tmp, timestat);
- }
- else if (!timeexpired) /* INVALID, INCREMENT THE ERROR COUNTER */
- {
- D_PRINTF( "GET error counter incremented\n" );
- timestat->rs.totalerrs++;
- }
-
- if (amclient) {
- fd_set readfds;
- struct timeval timeout;
- int rv;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&readfds);
- FD_SET(mastersock, &readfds);
-
- /* if the webmaster has aborted, quit */
- D_PRINTF("Before select() on webmaster socket\n");
- if (rv = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)) {
- D_PRINTF("select() returned %d\n", rv);
- D_PRINTF("Client terminating at request of webmaster\n");
- exit(2);
- }
- }
-
- } /* END for cnt */
-
- /*
- * DO WE HAVE A VALID RETURN FROM GET()?
- * WHY NOT USE returnval HERE?
- */
- if ((returnval == 0) &&
- (cnt == load_file_list[pageval].num_of_files) &&
- (timerarray[cnt-1].valid == 2))
- {
- rqst_stats_t *ps_rs;
- rqst_stats_t *pst_rs;
-
- ps_rs = &(page_stats[pageval].rs);
- pst_rs = &(page_stats_tmp.rs);
-
- rqstat_sum(ps_rs, pst_rs);
-
- page_stats[pageval].totalpages++;
-
- if (page_stats[pageval].page_size == 0)
- {
- page_stats[pageval].page_size = (unsigned)
- page_stats_tmp.rs.totalbody;
- }
- }
-
- D_PRINTF( "\nMakeload output page %d: %d errors, %d pages\n",
- pageval, timestat->rs.totalerrs, page_stats[pageval].totalpages );
- D_PRINTF( "Makeload returning %d\n", cnt );
-
- return(cnt);
-
-} /* END makeload() */
-
-#ifdef WIN32
-/* close socket library at exit() time */
-void sock_cleanup(void) {
-
- WSACleanup();
-}
-#endif /* WIN32 */
-
-/* globalize variables that were in main() */
-long int numfiles = 0;
-int testtime = 0;
-int numloops = 0;
-int numclients = 0;
-int record_all_transactions = 0;
-int uil_filelist_f = 0; /* filedescriptor of URLs to fetch? */
-int verbose = 0;
-int total_weight;
-char uil_filelist[NCCARGS];
-char filelist[MAXNUMOFFILES][MAXPATHLEN];
-char configfile[MAXPATHLEN];
-char connectstr[MAXHOSTNAMELEN+10];
-
-void
-main(int argc, char *argv[])
-{
- int file_count=0;
- int getoptch;
- int currarg;
- extern char *optarg;
- extern int optind;
- int i, j;
- char *tempch;
- int err;
-
-#define SLEEP_USEC 100
-#ifdef WIN32
- WSADATA WSAData;
-#else
-
- struct timeval sleeptime;
-
- /* set the amount of time that we'll pause before sending a "." to the
- webmaster */
-
- sleeptime.tv_sec = SLEEP_USEC/1000000;
- sleeptime.tv_usec = SLEEP_USEC % 1000000;
-#endif /* WIN32 */
-
- debugfile = stderr;
-
-#ifdef WIN32
- MessageBeep(~0U); /* announce our existence */
- MessageBeep(~0U);
- MessageBeep(~0U);
-
- err = WSAStartup(MAKEWORD(1,1), &WSAData);
- if (err != 0) {
- errexit("Error in WSAStartup()\n");
- }
-
- atexit(sock_cleanup);
-
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
-
- /* create semaphore in locked state */
- hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
- if(hSemaphore == NULL)
- {
- errexit("Create semaphore failed: %d", GetLastError());
- }
-#endif /* WIN32 */
-
- memset(webserver, 0, sizeof(webserver));
- memset(webmaster, 0, sizeof(webmaster));
- memset(proxyserver, 0, sizeof(proxyserver));
- memset(connectstr, 0, sizeof(connectstr));
-
- /*
- * PARSE THE COMMAND LINE OPTIONS
- */
-
- while((getoptch = getopt(argc,argv,"P:f:t:l:p:u:R:w:c:n:sdv")) != EOF)
- {
- switch(getoptch)
- {
- case 'c':
- sprintf(connectstr, "%s", optarg);
- amclient = 1;
- printf("%s", OKSTR); /* sent back to webmaster */
- fflush(stdout);
- break;
- case 'd':
- debug = 0; /* sumedh */
- break;
- case 'f':
- sprintf(configfile, "%s", optarg);
- break;
- case 'l':
- numloops = atoi(optarg);
- break;
- case 'n':
- numclients = atoi(optarg);
- break;
- case 'u':
- sprintf(uil_filelist, "%s", optarg);
- uil_filelist_f = 1;
- break;
- case 'p':
- portnum = atoi(optarg);
- break;
- case 's':
- savefile = 1;
- break;
- case 't':
- testtime = 60 * atoi(optarg);
- break;
- case 'v':
- verbose = 1;
- break;
- case 'w':
- havewebserver = 1;
- sprintf(webserver,"%s",optarg);
- break;
- case 'P':
- haveproxyserver = 1;
- sprintf(proxyserver, "%s", optarg);
- break;
- case 'R':
- record_all_transactions = 1;
- break;
- default:
- usage(argv[0]);
- }
- }
-
- returnerr("Client begins...\n");
- D_PRINTF( "Running in debug mode\n\n" );
-
- /* print the command line */
- for (i = 0; i < argc; i++)
- D_PRINTF( "%s ", argv[i] );
- D_PRINTF( "\n\n" );
-
- if(testtime && numloops)
- {
- /*
- * EITHER numloops OR testtime, BUT NOT BOTH.
- */
- usage(argv[0]);
- }
-
- if(havewebserver != 1)
- {
-#ifdef WIN32
- /*
- * THE SERVER'S NAME MUST BE SPECIFIED
- */
- returnerr("No WWW Server specified\n");
- usage(argv[0]);
-#else
- /* IF IT ISN'T, WE ASSUME LOCALHOST */
- sprintf(webserver, "%s", "localhost");
- havewebserver = 1;
-#endif /* WIN32 */
- }
-
- currarg = optind;
- numfiles = 0;
- while(currarg != argc)
- {
- /*
- * GET THE URLS TO RETRIEVE.
- */
- if (numfiles == MAXNUMOFFILES) {
- returnerr("Maximum of %d files on the command line.\n");
- usage(argv[0]);
- }
- sscanf(argv[currarg],"%s",filelist[numfiles]);
- numfiles++;
- currarg++;
- }
-
- if ((numfiles != 0) && uil_filelist_f)
- {
- returnerr("Both a filelist and UIL specified.\n");
- usage(argv[0]);
- }
-
- if((numfiles == 0) && !(uil_filelist_f))
- {
- /*
- * AT LEAST ONE FILE MUST BE SPECIFIED
- */
- returnerr("No UIL resources or filelist specified \n");
- usage(argv[0]);
- }
-
- if((numloops == 0) && (testtime == 0))
- {
- /*
- * NO SPECIFIED NUMBER OF LOOPS, AND NO TEST TIME
- */
- usage(argv[0]);
- }
- if(numclients > MAXPROCSPERNODE || numclients < 1)
- {
- returnerr("Number of Clients must be between 1 and %d\n", MAXPROCSPERNODE);
- exit(1);
- }
-
- /* allow use of IP address */
- if(amclient) {
- if((tempch = strpbrk(connectstr,":")) == NULL)
- {
- /*
- * INCORRECT FORMAT OF ConnectStr. CORRECT FORMAT IS
- * HOSTNAME:PORT OR HOST-IP:PORT
- */
- D_PRINTF( "Incorrect format %s: use hostname:port or ip_addr:port\n",
- connectstr );
- returnerr("Incorrect format %s: use host:port or ip_addr:port\n", connectstr);
- exit(1);
- } else {
- strncpy(webmaster, connectstr, tempch-connectstr);
- }
- if(resolve_addrs(webmaster, "tcp", &webmast_phe, &webmast_ppe, &webmast_addr, &webmast_type))
- exit(1);
- }
-
- if (haveproxyserver)
- {
- D_PRINTF( "Copying proxy %s to webserver\n", proxyserver );
- strcpy(webserver, proxyserver);
- }
-
- if (resolve_addrs(webserver, "tcp", &webserv_phe, &webserv_ppe, &webserv_addr, &webserv_type))
- exit(1);
-
- /*
- * INITIALIZE DATA
- */
- /* allocate space for dynamic arrays */
- load_file_list =
- (page_list_t *)mymalloc((MAXNUMOFPAGES)*sizeof(page_list_t));
-
- if (uil_filelist_f)
- {
- /* take a guess at the number of URLs in the file */
- D_PRINTF( "About to parse filelist %s\n", uil_filelist );
- number_of_pages = count_file_list(uil_filelist);
- numfiles = 1;
-
- /* IF WE HAVE A FILELIST, PARSE IT */
- /* allocate memory */
- D_PRINTF( "Allocating page list: %ld by %d\n",
- number_of_pages, numfiles );
- for (i=0; i<number_of_pages; i++)
- {
- for (j=0; j<MAXNUMOFFILES; j++)
- {
- load_file_list[i].servername[j] =
- (char *)mymalloc(URL_SIZE);
- load_file_list[i].filename[j] =
- (char *)mymalloc(URL_SIZE);
- }
- }
-
- D_PRINTF( "Parsing file list: %s\n", uil_filelist );
- parse_file_list(uil_filelist, load_file_list,
- &number_of_pages, &numfiles);
- /* free memory for pages that won't be used? */
- D_PRINTF( "Actual page list: %ld by %d\n",
- number_of_pages, MAXNUMOFFILES );
-
- D_PRINTF( "Setting up weighting for %ld pages\n",
- number_of_pages );
- total_weight = load_percent(load_file_list, number_of_pages);
- /* total_weight = load_percent(load_file_list, number_of_pages, pages); */
- }
- else
- {
- /* no uil file */
- number_of_pages = numfiles;
- }
-
- if (number_of_pages < 1)
- {
- /* no pages - exit */
- D_PRINTF( "No valid URLs found\n" );
- errexit("No valid URLs found\n");
- }
-
-#ifndef WIN32
- /*
- * IF WE ARE TO FORK ADDITIONAL CLIENTS ON THIS MACHINE,
- * WE MUST DO IT BEFORE WE CONNECT TO THE MASTER.
- *
- * FIRST, SET UP SIGNAL HANDLING
- */
- signal(SIGCHLD, childhandler);
- for(i = 0; i < numclients; i++)
- {
- thr_create (NULL, NULL, ClientThread, NULL, THR_BOUND, NULL);
-
- /* switch(fork())
- {
- case 0:
- numclients = 1;
- ClientThread(NULL);
- exit(0);
- break;
- case -1:
- errexit("Error forking child processes\n");
- exit(1);
- default:
- break;
- } */
- select(0,(fd_set *)0,(fd_set *)0, (fd_set *)0, &sleeptime);
- }
-
- /*
- * Wait for all children to exit.
- */
-
- while (thr_join(NULL, NULL, NULL) == 0);
-
- /* for(;;)
- {
- int pid = wait((int*)0);
- if ((pid == -1) && errno == ECHILD) break;
- } */
-#else
- /* start threads on NT */
- for (i = 0; i < numclients; i++)
- {
- if (_beginthread(ClientThread, 0, NULL) == -1)
- {
- errexit("_beginthread failed: %d", GetLastError());
- }
- }
-#endif /* WIN32 */
-
-#ifdef WIN32
- /* wait for children to get to sync point */
- while (CounterSemaphore < numclients)
- sleep(1);
- CounterSemaphore = 0;
-
- /* start all children simultaneously */
- ReleaseSemaphore(hSemaphore, 1, NULL);
-
- if (testtime) {
- sleep(testtime);
- alarmhandler(); /* signal end of test to threads */
- }
-
- /*
- * Wait for all threads to exit.
- */
- while (CounterSemaphore < numclients)
- sleep(1);
-
- CloseHandle(hSemaphore);
-#endif /* WIN32 */
-
- return;
-} /* end main() */
-
-void ClientThread(void *dummy)
-{
-
- THREAD FILE *logfile;
-
- THREAD stats_t timestat;
-
- THREAD rqst_timer_t timerarray[MAXNUMOFFILES];
- THREAD SOCKET mastersock = BADSOCKET_VALUE; /* connection to webmaster */
-
-
- THREAD page_stats_t *page_stats; /* actually a dynamic array */
-
- int loopcnt = 0;
- int filecnt;
- int loop;
- int ran_number;
- int page_index;
- int page_number;
- int file_count = 0;
- char file_name[50];
- struct timeval runningtime;
- time_t junk;
- int i;
- int returnval;
-
- /*
- * INITIALIZE DATA
- */
-
- page_stats =
- (page_stats_t *)mymalloc((number_of_pages)*sizeof(page_stats_t));
-
- for (i=0; i < number_of_pages; i++) {
- page_stats_init(&(page_stats[i]));
- }
-
- if (debug)
- {
- /*
- * OPEN A DEBUG FILE
- */
- fflush(stderr);
- sprintf(file_name, "%s.%d", DEBUG_FILE, (int)getpid());
- debugfile = fopen(file_name, "w+");
- if (debugfile == NULL)
- errexit("Can't open debug file\n");
- D_PRINTF( "Running in debug mode, %d\n",amclient );
- }
-
- if (record_all_transactions)
- {
- /*
- * OPEN A LOG FILE.
- */
- sprintf(file_name, "%s%d", LOG_FILE, (int)getpid());
- returnerr("Log file is %s\n", file_name);
- logfile = fopen(file_name, "w+");
- }
-
- /* Initialize random number generator */
- junk = getpid ();
- rand_r(&junk);
- D_PRINTF( "Random seed: %d\n", junk );
-
- for (i=0; i < MAXNUMOFFILES; i++)
- {
- rqtimer_init(&(timerarray[i]));
- }
- stats_init(&timestat);
-
- D_PRINTF( "Number of files %d\n", numfiles );
-
- timestat.total_num_of_files = numfiles;
-
- if (amclient)
- {
- /*
- * WE ARE A CLIENT PROCESS. (i.e. WE ARE NOT RUN BY A USER, BUT BY
- * THE MASTER WWWSTONE PROCESS. WE NEED TO CONNECT TO THE
- * MASTER WHO WILL SYNCHRONIZE ALL THE CLIENTS.
- */
- D_PRINTF( "Trying to connect with %s\n",connectstr );
-
- mastersock = connecttomaster(connectstr);
-
- D_PRINTF( "connecttomaster returns %d, %s\n",
- mastersock, neterrstr() );
-
- if(BADSOCKET(mastersock))
- {
- /*
- * ERROR CONNECTING TO THE MASTER. ABORT.
- */
- errexit("Error connecting to the master: %s\n", neterrstr());
- }
- } /* END IF CLIENT */
-
-#ifdef WIN32
- /* Tell parent we're ready */
- InterlockedIncrement(&CounterSemaphore);
-
- /* Wait for main() thread to release us */
- WaitForSingleObject(hSemaphore, INFINITE);
- ReleaseSemaphore(hSemaphore, 1, NULL);
-#endif /* WIN32 */
- if (testtime != 0)
- {
- /*
- * IF RUNNING A TIMED TEST, WE WILL LOOP
- * UNTIL THE ALARM GOES OFF.
- * WE'LL ALSO NEED TO SET THE SIGNAL HANDLER
- */
-#ifndef WIN32
- /*signal(SIGALRM, alarmhandler);*/
- /*
- * SEND SIGALRM IN testtime SECONDS
- */
- /*alarm(testtime);*/
-#endif /* WIN32 */
- }
-
- /*
- * AND THEY'RE OFF...
- */
-
- if (testtime)
- numloops = INFINITY;
- GETTIMEOFDAY(&(timestat.starttime), &(timestat.starttimezone));
-
- /* LOOP UNTIL WE HIT numloops, OR WE RUN OUT OF TIME */
- for(loopcnt = 0; (loopcnt < numloops) && !timeexpired; loopcnt++)
- {
- /*
- * THIS IS WHERE LOAD TESTING IS DONE.
- * GET A RANDOM NUMBER, THEN INDEX INTO THE
- * PAGE, AND THEN REQUEST THAT SET OF FILES.
- */
- if (uil_filelist_f) /* HAVE FILELIST */
- {
- D_PRINTF( "Have filelist\n" );
- /* if (testtime != 0) /* RUNNING IN TIMED MODE */
- if (1)
- {
- D_PRINTF( "Running in timed mode\n" );
- /* random number between 0 and totalweight-1 */
- junk = getpid ();
- ran_number = (rand_r(&junk) % total_weight);
- D_PRINTF( "random %ld\n", ran_number );
-
- /* loop through pages, find correct one
- * while ran_number is positive, decrement it
- * by the load_num of the current page
- * example: ran_number is 5, pages have weights of 10 and 10
- * first iteration page_index = 0, ran_number = -5
- * iteration halted, page_index = 0
- */
- page_index = -1;
- while (ran_number >= 0)
- {
- page_index++;
- D_PRINTF( "Current page index %d: %ld - %d\n",
- page_index, ran_number,
- load_file_list[page_index].load_num
- );
- ran_number -= load_file_list[page_index].load_num;
- }
-
- if (page_index >= number_of_pages) { page_index--; }
-
- D_PRINTF( "Final page index %d\n", page_index );
- filecnt = makeload(load_file_list[page_index].num_of_files,
- page_index, timerarray, &timestat, mastersock, page_stats);
- testtime = 1;
- }
- else /* NOT RUNNING IN TIMED MODE */
- {
- for (page_number = 0;
- page_number < number_of_pages;
- page_number++)
- {
- filecnt = makeload(load_file_list[page_number].num_of_files,
- page_number, timerarray, &timestat, mastersock, page_stats);
-
- } /* END for page_number */
- } /* END if/else TIMED MODE */
- }
- else /* NO FILELIST */
- {
- D_PRINTF( "No filelist\n" );
- /*
- * LOOP THROUGH UNTIL numfiles TIMES OR UNTIL TIMER EXPIRES
- * AND ALARM SETS filecnt TO INFINITY.
- */
-
- /* does this still work?? */
- /* filecnt = makeload(numfiles, -1, timerarray); */
- } /* END if HAVE FILELIST */
-
- if (filecnt > 0)
- file_count += filecnt;
-
- } /* END while loopcnt */
-
- GETTIMEOFDAY(&(timestat.endtime), &(timestat.endtimezone));
- D_PRINTF( "Test run complete\n" );
- signal(SIGALRM, NULL);
-
- if (testtime == 0)
- {
- numfiles = loopcnt;
-
- if (uil_filelist_f)
- {
- numfiles = file_count;
- }
- }
-
- /* This option ( "-R" ) looks broken (e.g. l > 50) -- JEF 2/15/96 */
- if (record_all_transactions)
- {
- /*
- * DUMP THE LOG FILE INFORMATION.
- */
- for (loop=0; loop < (loopcnt * file_count); loop++)
- {
- fprintf(logfile, " entertime \t%d.%d\n"
- " beforeconnect \t%d.%d\n"
- " afterconnect \t%d.%d\n"
- " beforeheader \t%d.%d\n"
- " afterheader \t%d.%d\n"
- " afterbody \t%d.%d\n"
- " exittime \t%d.%d\n"
- " total bytes \t%d\n"
- " body bytes\t%d\n",
- timerarray[loop].entertime.tv_sec,
- timerarray[loop].entertime.tv_usec,
- timerarray[loop].beforeconnect.tv_sec,
- timerarray[loop].beforeconnect.tv_usec,
- timerarray[loop].afterconnect.tv_sec,
- timerarray[loop].afterconnect.tv_usec,
- timerarray[loop].beforeheader.tv_sec,
- timerarray[loop].beforeheader.tv_usec,
- timerarray[loop].afterheader.tv_sec,
- timerarray[loop].afterheader.tv_usec,
- timerarray[loop].afterbody.tv_sec,
- timerarray[loop].afterbody.tv_usec,
- timerarray[loop].exittime.tv_sec,
- timerarray[loop].exittime.tv_usec,
- timerarray[loop].totalbytes,
- timerarray[loop].bodybytes);
- } /* end for loop */
- } /* end if recording all transactions */
-
- D_PRINTF( "total errors: %d\n",timestat.rs.totalerrs );
- /* gethostname(timestat.hostname,MAXHOSTNAMELEN); */
- /* D_PRINTF( "Test for host: %s\n",timestat.hostname ); */
- D_PRINTF( "Server is: %s running at port number: %d\n",
- webserver,portnum );
-
- /* sprintf(timestat.hostname,"%s:%d",timestat.hostname,getpid()); */
- if (amclient) /* CLIENT TO A WEBMASTER */
- {
- char *stats_as_text;
-
- /*
- * SEND THE TIMING DATA TO THE MASTER
- */
- stats_as_text = stats_to_text(&timestat);
- D_PRINTF( "stats_to_text returned %s\n", stats_as_text );
-
- returnval = senddata(mastersock, stats_as_text,
- SIZEOF_STATSTEXTBASE + number_of_pages*SIZEOF_DOUBLETEXT);
- D_PRINTF( "Wrote time stats to master %d\n", returnval );
-
- if (returnval < 1)
- {
- D_PRINTF( "Error while writing time stats: %s\n",
- neterrstr() );
- errexit("Error while writing time stats: %s\n",
- neterrstr());
- }
-
- if (uil_filelist_f)
- /* write pagestats */
- {
- char *page_stats_as_text;
- for (i = 0; i < number_of_pages; i++)
- {
- D_PRINTF( "On page_stats[%d]\n", i );
- page_stats_as_text = page_stats_to_text(&page_stats[i]);
- returnval = strlen(page_stats_as_text);
- D_PRINTF( "page_stats_to_text[%d] returned %d\n",
- i, returnval );
- returnval = senddata(mastersock, page_stats_as_text,
- SIZEOF_PAGESTATSTEXT);
- if (returnval < 1)
- {
- D_PRINTF( "Error while writing page_stats[%d]: %s\n",
- i, neterrstr() );
- errexit("Error while writing page_stats[%d]: %s\n",
- i, neterrstr());
- } /* end if */
- D_PRINTF( "Wrote %d bytes of page_stats[%d] to master\n",
- returnval, i );
- } /* end for */
- } /* end if filelist */
-
- D_PRINTF( "About to close socket\n" );
- if (NETCLOSE(mastersock))
- D_PRINTF( "Close socket error: %s\n", neterrstr() );
- }
- else /* NOT A CLIENT TO A WEBMASTER */
- {
- if (testtime)
- {
- printf("Test ran for: %d minutes\n",(testtime/60));
- }
- else
- {
- printf("Test ran for: %d iterations.\n",numloops);
- }
- compdifftime(&(timestat.endtime), &(timestat.starttime),
- &(runningtime));
- printf("Total time of test (sec) %d.%d\n", runningtime.tv_sec,
- runningtime.tv_usec);
- printf("Files retrieved per iteration: %d\n",numfiles); /* 'per iteration' */
- printf("----------------------------------\n");
- printf("Totals:\n\n");
- rqstat_print(&(timestat.rs));
-
- if (timestat.rs.totalconnects == 0)
- goto end;
- printf("Thruput = %5.2lf Kbytes/sec\n",
- thruputpersec(timestat.rs.totalbytes, &runningtime) / 1000);
-
- if (uil_filelist_f && numloops && verbose)
- {
- for (loop = 0; loop < number_of_pages; loop++)
- {
- if (timestat.page_numbers[loop] != 0)
- {
- printf ("===============================================================================\n");
- printf ("Page # %d\n\n", loop);
- printf ("Total number of times page was hit %d\n",
- page_stats[loop].totalpages);
- rqstat_print(&(page_stats[loop].rs));
- printf ("Page size %d \n", page_stats[loop].page_size);
- printf ("===============================================================================\n\n");
- } /* END if timestat */
- } /* END for loop */
- } /* END if filelist */
- } /* END if client */
-
-end:
- if(record_all_transactions)
- fclose(logfile);
- if(debug)
- {
- D_PRINTF( "Client exiting.\n" );
- fclose(debugfile);
- }
-
-#ifdef WIN32
- /* tell parent we're done */
- InterlockedIncrement(&CounterSemaphore);
-#endif /* WIN32 */
-
-} /* END ClientThread() */