diff options
Diffstat (limited to 'ACE/apps/JAWS')
198 files changed, 38117 insertions, 0 deletions
diff --git a/ACE/apps/JAWS/ChangeLog b/ACE/apps/JAWS/ChangeLog new file mode 100644 index 00000000000..8fbcef9842b --- /dev/null +++ b/ACE/apps/JAWS/ChangeLog @@ -0,0 +1,1047 @@ +Fri Dec 7 22:00:18 UTC 2007 Will Otte <wotte@dre.Vanderbilt.Edu> + + * server/HTTP_Helpers.cpp: + Replaced format strings passed sscanf as char arrays to be + string literals instead, to address a gcc warning. + +Wed Jul 17 14:40:28 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> + + * clients/Caching/http_handler.cpp: + Fixed gcc warning + +Fri Jul 13 20:21:08 UTC 2007 Ossama Othman <ossama_othman at symantec dot com> + + * clients/Blobby/Blob_Handler.cpp (receive_reply): + + Instead of casting an unsigned value to a signed one, check if + the signed value is less than zero, and then cast the signed + value to unsigned. Prevents wrap-around errors caused by + casting a negative value to an unsigned type from occuring. + +Thu Jul 12 15:54:28 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> + + * clients/Blobby/Blob_Handler.cpp: + * clients/Caching/http_handler.h: + Fixed 64bit warnings + + * stress_testing/benchd.cpp: + Use ACE_DEBUG instead of cout + +Tue Jul 3 10:56:28 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> + + * clients/Blobby/Blob_Handler.cpp (ACE_Blob_Writer::receive_reply): + Don't use the return value of recv_n to set the last byte to zero, but + use the optional argument num_recvd + + * server/HTTP_Response.cpp: + Fixed typo in error message + + * server/IO.cpp (ACE_Blob_Writer::receive_reply): + Close the file handle after we have send the file + +Mon Jul 2 12:24:28 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> + + * server/HTTP_Handler.cpp: + Layout changes and initialise some pointers with 0 + + * server/HTTP_Server.cpp: + * server/IO.h + Layout changes + + * server/IO.cpp: + Layout changes, fixed memory leak + + * server/JAWS_Concurrency.cpp: + Initialiser pointer with 0 + +Mon Jul 2 10:48:28 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> + + * server/*.{h,cpp}: + Converted to doxygen format and replaced NULL with 0 + +Fri Oct 28 03:23:18 UTC 2006 Ossama Othman <ossama_othman at symantec dot com> + + * server/IO.cpp: + + Addressed 64-bit conversion warnings. + +Mon Feb 6 01:00:55 UTC 2006 William Otte <wotte@dre.vanderbilt.edu> + + * server/HTTP_Server.h + + Surrounded a proactor forward declaration with versioned + namespace macros. + +Thu Jan 5 00:42:28 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com> + + * ChangeLog: + + Untabify. + Delete-trailing-whitespace. + +Wed Jan 4 22:57:37 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com> + + * ChangeLog: + + Added "Local Variables" section defining "add-log-time-format" + to a really ugly lambda expression that formats changelog + timestamps in UTC and works with both GNU Emacs and XEmacs. + +Fri Apr 22 21:42:30 2005 Ossama Othman <ossama@dre.vanderbilt.edu> + + * server/HTTP_Helpers.cpp (HTTP_mktime): + + Made rfc1123_date, rfc850_date and asctime_date strings into + string literals. Allows g++ format specifier argument checking + to work, and addresses a related g++ 4.0 warning. + + * server/IO.h (~JAWS_IO_Handler): + * server/IO.cpp (~JAWS_IO_Handler): + + Added virtual destructor to silence g++ 4.0 warnings. + +Thu Aug 26 08:13:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * clients/Caching/http_client.cpp: + * server/HTTP_Response.cpp: + Added include of ace/os_include/os_ctype.h to fix compile problems + in our daily builds. + +Tue Feb 25 18:58:26 2003 Carlos O'Ryan <coryan@atdesk.com> + + * clients/WebSTONE/src/cgi-send: + Removed pre-compiled binary for MIPS (R3000 of all things!) + +Wed Dec 26 09:35:35 2001 Douglas C. Schmidt <schmidt@ace.cs.wustl.edu> + + * clients/Blobby/Options.cpp + server/HTTP_Server.cpp + stress_testing/benchd.cpp + JAWS2/JAWS/Server.cpp: Replaced all uses of getopt.optarg + with getopt.opt_arg(). + +Thu Dec 6 09:00:31 2001 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * clients/Caching/http_client.cpp (main): Make sure to remove the + trailing '\n' so the example works properly. Thanks to Andrey + Shkinev <andreyshkinev@rogers.com> for reporting this. + +Wed Nov 14 16:21:46 2001 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * clients/Blobby/Blob.{h,cpp}, + * clients/Blobby/Blob_Handler.{h,cpp}, + * clients/Blobby/blobby.{h,cpp}, + * clients/Blobby/Options.{h,cpp}: + Fixed the code to be Unicode-compliant. Thanks to Johnny + Willemsen for contributing this. + +Fri Aug 24 18:39:39 2001 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * server/HTTP_Response.cpp (normal_response), + * server/HTTP_Helpers.cpp (HTTP_decode_base64): Use delete [] buf + rather than delete buf. Thanks to Don Hinton for reporting + this. + +Thu Aug 16 09:57:15 2001 Balachandran Natarajan <bala@cs.wustl.edu> + + * */Makefile: Updated dependencies. + +Mon Aug 13 14:04:44 2001 Douglas C. Schmidt <schmidt@ace.cs.wustl.edu> + + * Applied the following fixes courtesy of Blair Zajac + <blair@gps.caltech.edu>: + + 1) Allow a static libHTTPU.a to be built when + "make static_libs_only=1" is used. + + 2) When I try to build both JAWS and JAWS2 with the same + ACE_ROOT, the libJAWS.* that is built and installed first + prevents the other JAWS from properly compiling. This + resolves this problem by renaming the JAWS2 library to + libJAWS2.*. + + 3) The JAWS2 subdirectory is now descended into by + apps/Makefile. + + 4) The Makefile in JAWS2 now descends into HTTPU and JAWS to + build those libraries. + +Tue Jun 12 20:35:26 2001 Krishnakumar B <kitty@cs.wustl.edu> + + * clients/Blobby/Blob_Handler.cpp: + + Fixed a size_t printf to make gcc happy on IA-64 Linux. + +Sun Feb 18 09:33:33 2001 Douglas C. Schmidt <schmidt@ace.cs.wustl.edu> + + * server/IO.cpp (handle): Added a const to the handle() method + to make compilers happy. Thanks to Kitty for reporting this. + +Mon Jun 12 14:22:35 PDT 2000 James Hu <jxh@entera.com> + + * server/HTTP_Response.cpp: Added content length support. + Thanks to Greg Gallant (gcg@micrografx.com) for the fixes! + + * server/HTTP_Helpers.cpp: Fix date handling for NT. + Thanks to Greg Gallant (gcg@micrografx.com) for the fixes! + +Sun Jun 4 14:57:04 2000 Darrell Brunsch <brunsch@uci.edu> + + * clients/WebSTONE/bin/WebStone-common.pl: + * clients/WebSTONE/bin/WebStone-manage.pl: + * clients/WebSTONE/bin/WebStone-run.pl: + * clients/WebSTONE/bin/WebStone-setup.pl: + * clients/WebSTONE/bin/killbench.pl: + * clients/WebSTONE/bin/mine-logs.pl: + * clients/WebSTONE/bin/move-filelist.pl: + * clients/WebSTONE/bin/move-runs.pl: + * clients/WebSTONE/bin/runbench.pl: + * clients/WebSTONE/bin/view-results.pl: + * clients/WebSTONE/bin/webstone-gui.pl: + * clients/WebSTONE/bin/write-testbed.pl: + * clients/WebSTONE/bin/wscollect.pl: + * clients/WebSTONE/conf/paths.pl: + * clients/WebSTONE/doc/FAQ-webstone.html: + * clients/WebSTONE/doc/LICENSE.html: + * clients/WebSTONE/doc/WebStone.html: + * clients/WebSTONE/doc/webstone2.html: + * clients/WebSTONE/src/acconfig.h: + * clients/WebSTONE/src/bench.c: + * clients/WebSTONE/src/bench.h: + * clients/WebSTONE/src/cgi-send.c: + * clients/WebSTONE/src/config.h: + * clients/WebSTONE/src/debug.h: + * clients/WebSTONE/src/errexit.c: + * clients/WebSTONE/src/genrand.c: + * clients/WebSTONE/src/get.c: + * clients/WebSTONE/src/get.h: + * clients/WebSTONE/src/getopt.c: + * clients/WebSTONE/src/gettimeofday.c: + * clients/WebSTONE/src/nsapi-send.c: + * clients/WebSTONE/src/parse_file_list.c: + * clients/WebSTONE/src/parse_file_list.h: + * clients/WebSTONE/src/rexec.c: + * clients/WebSTONE/src/statistics.c: + * clients/WebSTONE/src/statistics.h: + * clients/WebSTONE/src/sysdep.c: + * clients/WebSTONE/src/sysdep.h: + * clients/WebSTONE/src/timefunc.c: + * clients/WebSTONE/src/timefunc.h: + * clients/WebSTONE/src/webclient.c: + * clients/WebSTONE/src/webmaster.c: + * clients/WebSTONE/src/nsapi-includes/netsite.h: + * clients/WebSTONE/src/nsapi-includes/base/buffer.h: + * clients/WebSTONE/src/nsapi-includes/base/cinfo.h: + * clients/WebSTONE/src/nsapi-includes/base/crit.h: + * clients/WebSTONE/src/nsapi-includes/base/daemon.h: + * clients/WebSTONE/src/nsapi-includes/base/dll.h: + * clients/WebSTONE/src/nsapi-includes/base/ereport.h: + * clients/WebSTONE/src/nsapi-includes/base/eventlog.h: + * clients/WebSTONE/src/nsapi-includes/base/file.h: + * clients/WebSTONE/src/nsapi-includes/base/minissl.h: + * clients/WebSTONE/src/nsapi-includes/base/net.h: + * clients/WebSTONE/src/nsapi-includes/base/nodelock.h: + * clients/WebSTONE/src/nsapi-includes/base/nterrors.h: + * clients/WebSTONE/src/nsapi-includes/base/objndx.h: + * clients/WebSTONE/src/nsapi-includes/base/pblock.h: + * clients/WebSTONE/src/nsapi-includes/base/sem.h: + * clients/WebSTONE/src/nsapi-includes/base/session.h: + * clients/WebSTONE/src/nsapi-includes/base/shexp.h: + * clients/WebSTONE/src/nsapi-includes/base/shmem.h: + * clients/WebSTONE/src/nsapi-includes/base/systems.h: + * clients/WebSTONE/src/nsapi-includes/base/systhr.h: + * clients/WebSTONE/src/nsapi-includes/base/util.h: + * clients/WebSTONE/src/nsapi-includes/frame/conf.h: + * clients/WebSTONE/src/nsapi-includes/frame/dnfilter.h: + * clients/WebSTONE/src/nsapi-includes/frame/func.h: + * clients/WebSTONE/src/nsapi-includes/frame/http.h: + * clients/WebSTONE/src/nsapi-includes/frame/httpact.h: + * clients/WebSTONE/src/nsapi-includes/frame/ipfilter.h: + * clients/WebSTONE/src/nsapi-includes/frame/log.h: + * clients/WebSTONE/src/nsapi-includes/frame/object.h: + * clients/WebSTONE/src/nsapi-includes/frame/objset.h: + * clients/WebSTONE/src/nsapi-includes/frame/protocol.h: + * clients/WebSTONE/src/nsapi-includes/frame/req.h: + * clients/WebSTONE/src/nsapi-includes/frame/servact.h: + + Added missing CVS Id strings. + +Wed Mar 22 12:36:00 2000 James Hu <jxh@cs.wustl.edu> + + * stress_testing/connection.h: + + Fixes to class declaration. Method return types should never + be implicit. Thanks to Craig Rodrigues (rodrigc@mediaone.net) + for the heads up. + + * stress_testing/Makefile: + + Fixed it so that the programs actually link. Thanks to Craig + Rodrigues (rodrigc@mediaone.net) for the heads up. + +Tue Sep 21 11:47:00 1999 Ossama Othman <othman@cs.wustl.edu> + + * server/HTTP_Server.cpp (init): + + Changed cast style to make gcc 2.95.1 happy. Thanks to Jeffrey + Franks <Jeffrey_Franks@i-o.com> for reporting the problems. + +Tue Aug 31 05:10:32 1999 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * server/HTTP_Handler.cpp (destroy_http_handler): Switched + the order in which handler and io were deleted since the current + order seems to destroy handler first, which is problematic since + io is contained within handler! Thanks to Yosi Sarusi + <yosi@appstream.com> for reporting this. + +Wed Aug 18 16:00:46 1999 David L. Levine <levine@cs.wustl.edu> + + * server/Makefile,client/Caching/Makefile: don't build if + ACE_COMPONENTS is FOR_TAO, because we now exclude Filecache + from the ACE library in that case. + +Thu Jul 29 16:05:59 1999 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * PROTOTYPE/JAWS/IO.cpp (transmit_file): Added some fixes so this + code will compile on NT. Thanks to Brian Jones + <bjones@edgemail.com> for reporting this problem and to James Hu + for fixing it. + +Tue Jun 22 13:42:51 1999 David L. Levine <levine@cs.wustl.edu> + + * remora/app/Makefile: replaced rm -f with $(RM). + +Tue Mar 16 01:08:05 1999 Nanbor Wang <nanbor@cs.wustl.edu> + + * server/Makefile: + * server/jaws.dsp: Updated makefiles to build shared library. + + * server/svc.conf: Added example settings for using HTTP_Server as + a dynamic service. + + * server/HTTP_Server.{h,cpp}: Added macros to build dynamic + HTTP_Server service. + + * server/main.cpp (main): Since we use static service in JAWS, we + must open the service configure without ignoring the static + svcs. Thanks to Bill Rizzi <rizzi@softserv.com> for pointing + this out. + +Mon Feb 01 17:04:39 1999 David L. Levine <levine@cs.wustl.edu> + + * clients/WebSTONE/conf/paths.{pl,sh}.old: + removed these apparently useless files. + +Sat Jan 02 08:44:48 1999 David L. Levine <levine@cs.wustl.edu> + + * server/HTTP_Request.cpp,Parse_Headers.cpp: initialized + third param to strtok_r with 0. DU 4.0 cxx was complaining + about it, with ACE_NDEBUG. According to the strtok_r + man page on DU 4.0, it must be initialized to 0 on the + first call to strtok_r. + +Fri Sep 25 23:29:14 1998 David L. Levine <levine@cs.wustl.edu> + + * server/IO.cpp (receive_file,transmit_file): changed + NOMAP to ACE_NOMAP. Thanks to Dann Corbit + <DCorbit@SolutionsIQ.com> for reporting this. + +Thu Sep 17 18:53:05 1998 Carlos O'Ryan <coryan@cs.wustl.edu> + + * server/IO.cpp: + * PROTOTYPE/JAWS/IO.cpp: + Revert back to iovec. Also added some missing casts. + +Wed Sep 16 22:53:06 1998 Carlos O'Ryan <coryan@cs.wustl.edu> + + * server/IO.cpp: + * PROTOTYPE/JAWS/IO.cpp: + Use ACE_IO_Vector instead of iovec, because it is more + protable. + +Tue Aug 25 10:18:16 1998 David L. Levine <levine@cs.wustl.edu> + + * clients/Caching/URL_Properties.cpp: removed explicit + ACE_Auto_Basic_Array_Ptr <char> instantiation because it's + now in libACE. This file doesn't compile with g++/Solaris, + but the Makefile doesn't build it anyways. + +Fri Jul 31 18:31:32 1998 Gonzalo Diethelm <gonzo@tango.cs.wustl.edu> + + * PROTOTYPE/HTTP_10.cpp + * PROTOTYPE/HTTP_10_Parse.cpp + * PROTOTYPE/HTTP_10_Read.cpp + * PROTOTYPE/HTTP_10_Request.cpp + * PROTOTYPE/HTTP_10_Write.cpp + * PROTOTYPE/HTTP_Policy.cpp + * PROTOTYPE/main.cpp + * PROTOTYPE/JAWS/Assoc_Array.cpp + * PROTOTYPE/JAWS/Concurrency.cpp + * PROTOTYPE/JAWS/Data_Block.cpp + * PROTOTYPE/JAWS/IO.cpp + * PROTOTYPE/JAWS/IO_Acceptor.cpp + * PROTOTYPE/JAWS/IO_Handler.cpp + * PROTOTYPE/JAWS/Pipeline.cpp + * PROTOTYPE/JAWS/Pipeline_Handler.cpp + * PROTOTYPE/JAWS/Pipeline_Tasks.cpp + * PROTOTYPE/JAWS/Policy.cpp + * PROTOTYPE/JAWS/Reaper.cpp + * PROTOTYPE/JAWS/Server.cpp + * PROTOTYPE/JAWS/Waiter.cpp + * clients/Blobby/Blob.cpp + * clients/Blobby/Blob_Handler.cpp + * clients/Blobby/Options.cpp + * clients/Blobby/blobby.cpp + * clients/Caching/ID_Generator.cpp + * clients/Caching/Local_Locator.cpp + * clients/Caching/Locator_Request_Reply.cpp + * clients/Caching/URL_Array_Helper.cpp + * clients/Caching/URL_Locator.cpp + * clients/Caching/URL_Properties.cpp + * clients/Caching/http_client.cpp + * clients/Caching/http_handler.cpp + * clients/Caching/test_URL.cpp + * server/HTTP_Config.cpp + * server/HTTP_Handler.cpp + * server/HTTP_Helpers.cpp + * server/HTTP_Request.cpp + * server/HTTP_Response.cpp + * server/HTTP_Server.cpp + * server/IO.cpp + * server/JAWS_Concurrency.cpp + * server/JAWS_Pipeline.cpp + * server/JAWS_Pipeline_Handler.cpp + * server/Parse_Headers.cpp + * server/main.cpp + * stress_testing/benchd.cpp + * stress_testing/connection.cpp + * stress_testing/cp.cpp + * stress_testing/http_tester.cpp + * stress_testing/stats.cpp + * stress_testing/util.cpp + Added ACE_RCSID to these files. + +Thu Feb 19 22:14:09 1998 Alexander Babu Arulanthu <alex@merengue.cs.wustl.edu> + + * server/JAWS_Concurrency.cpp (put): Modified line number 11 to + get away with a compilation error. + +Wed Feb 18 12:31:28 1998 Carlos O'Ryan <coryan@cs.wustl.edu> + + * server/JAWS_Pipeline.cpp: + Removed extra definitions for default arguments. + +Sun Feb 15 08:05:28 1998 David L. Levine <levine@cs.wustl.edu> + + * server/JAWS_Pipeline.h: added missing ; at end of constructor + declaration. + +Wed Jan 7 17:26:43 1998 James C Hu <jxh@cs.wustl.edu> + + * server/Pipeline.cpp: Put base class initialization of + JAWS_Protocol_Filter ahead of data members. + +Fri Jan 2 16:28:00 1998 Nanbor Wang <nw1@cs.wustl.edu> + + * clients/Caching/http_handler.cpp: + * clients/Blobby/Blob.cpp: Added missing explicit template + instantiations. + +Mon Dec 29 20:20:36 1997 James C Hu <jxh@cs.wustl.edu> + + * clients/Caching/http_handler.cpp: Idem to previous change. + +Mon Dec 29 18:50:02 1997 James C Hu <jxh@cs.wustl.edu> + + * server/IO.cpp: Idem to previous change, but fixes to improve + compatibility and portability to Windows NT. + +Thu Dec 18 15:37:36 1997 James C Hu <jxh@cs.wustl.edu> + + * server/IO.cpp: Modified to account for changes in ACE_Filecache + to not map file on NT. + +Tue Dec 16 09:29:11 1997 David L. Levine <levine@cs.wustl.edu> + + * server/Makefile: expanded rules.bin.GNU, but without + $(VOBJS), to avoid make warnings. + + * client/WebSTONE/src/nsapi-includes/base/systems.h: + #ifdef linux, not LINUX. + +Fri Dec 12 03:06:16 1997 James C Hu <jxh@cs.wustl.edu> + + * server/Parse_Headers.cpp: Many things have been touched, but + only a few things have significantly changed. I originally + attempted to change the implementation entirely to use + Hash_Map_Manager instead, but it was getting more complicated + than I wanted, so I went back to debugging. + + - Trailing whitespace has been removed. + - A couple of debug messages have been added the + Headers::parse_header_line (). + - Method declarations had to be changed to account for the + fact that the Map_Item class (which had previously + been declared inside of Headers_Map) is now in global + scope and has been renamed to Headers_Map_Item. + - The no_value_ data member and the char* cast operator of + Map_Item have been removed. + - The assignment operator for Map_Item has been made a bit + tidier in its memory management (say no to memory + leaks!). + - Debugged the Headers_Map data structure. This involved + the following: + . Re-implementation of strcasecmp (red-herring). + . Re-implementation of Headers::compare (). This is + needed because empty table entries need to compare as + infinity against real strings, so that real strings get + inserted correctly. + . Debugging the Headers_Map::find () method by + implementing first a linear search, and then my own binary + search. It turns out the C library ::bsearch() does work, + but I will leave in my implementation for now, since + ::bsearch () is not in ACE_OS yet. + . Re-implementation of Headers::place (). The old one + was badly written. The new one is more efficient, and + less error prone. This method turned out to be the main + problem. It was the reason that binary search was + previously failing (but linear search worked). The + reason? It was corrupting memory, believe it or not. + No longer! + + In addition, Headers::place () had a serious bug in which a call + to ACE_OS::free () was added, but included the ++ operator on + the pointer from the previous line. Ug. + + * server/Parse_Headers.h: See comments for HTTP_Request.cpp. + + * server/HTTP_Request.cpp: Removed extraneous whitespace. It's + not what you think Doug! Just trailing whitespace at the end of + lines that somehow get added on when people use LoseNT editors. + Also, changes were made to Parse_Headers which made it necessary + to explicitly use the value () accessor method when examining + parsed headers. There use to be a operator char* () method. + + * server/HTTP_Response.cpp: See comments for HTTP_Request.cpp. + + * server/HTTP_Helpers.cpp: Added a comment to + HTTP_Helper::fixyear (). + +Tue Dec 9 01:19:09 1997 James C Hu <jxh@cs.wustl.edu> + + * stress_testing/util.cpp: Off by one errors when parsing a URL. + Did I write this code? I don't think so. Thanks to Valik + Solorzano Barboza <valik@geodan.nl> for pointing this out. + +Thu Nov 20 00:36:34 1997 James C Hu <jxh@cs.wustl.edu> + + * server/Pipeline.h: Added methods and members so that the + pipeline can be both push and pull driven. + + * server/Pipeline.cpp: Made the pipeline a doubly linked list of + components, so that it can be operated as push-driven or + pull-driven pipelines. + +Wed Nov 19 05:10:38 1997 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * server/HTTP_Handler.h: Added the keyword "virtual" on the open() + method which is inherited from ACE_Sevice_Handler. Perhaps this + will fix a bug with BORLANDC reported by Valik Solorzano Barboza + <valik@xs4all.nl>. + +Mon Nov 17 07:34:09 1997 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * server/Parse_Headers.cpp (end_of_line): Replaced a const char * + with a char * to work with the new ACE_OS::strchr() signature. + Thanks to James for finding this. + +Tue Nov 11 19:52:38 1997 James C Hu <jxh@cs.wustl.edu> + + * server/Pipeline.{h,cpp}: The beginning of a new Pipeline + framework has been added. + +Sun Oct 12 16:21:32 1997 Carlos O'Ryan <coryan@macarena.cs.wustl.edu> + + * clients/Caching/Makefile: + * stress_testing/Makefile: + There is no need to set LDLIBS to add local object files + anymore, using FILES is enough. + +Fri Oct 10 18:41:47 1997 Carlos O'Ryan <coryan@macarena.cs.wustl.edu> + + * clients/Blobby/Makefile: + Fixed problem that made compilation fail. + +Thu Sep 11 10:40:38 1997 Carlos O'Ryan <coryan@polka.cs.wustl.edu> + + * server/HTTP_Request.cpp: + I checked the use of MAXNAMELEN vs. MAXPATHLEN; all buffers + intended to keep full filenames should have at least + MAXPATHLEN+1 chars. + Only buffers that will keep basenames (without any directories) + should have MAXNAMELEN+1 bytes. + I also added a new macro ACE_MAX_FULLY_QUALIFIED_NAME_LEN which + is the maximum number of characters for a fully qualified + internet hostname. + There remain one obscure usage of these macros in ace/Malloc.h + and Local_Naming_Space_T.{h,cpp}, but a quick fix broke + something, I will try again soon. + +Tue Sep 9 22:08:36 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/HTTP_Server.{cpp,h}: Changes which answer questions + brought up in design review. Mostly additional comments. Also + changes to have a task spawn a number of threads rather than + iterating through calls to the activate method. + +Fri Aug 29 11:07:43 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/*.{cpp,h}: Changes to make JAWS comply with ACE + coding standards. In particular, broke up CGI method in + HTTP_Request, remove dependency on static object in + HTTP_Config, and answered all questions from Doug. + +Tue Aug 26 21:34:11 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * clients/Caching/ID_Generator.h: Made some minor changes to + the programming style. + +Sun Aug 10 13:44:14 1997 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * server/HTTP_Helpers.cpp (HTTP_date): We can't use + ACE_Thread_Mutex directly in the code since that breaks + platforms that lack threads. + +Wed Aug 6 16:45:48 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/main.cpp: Added another signal handler so I can kill JAWS + when purifying. + +Mon Aug 4 00:07:24 1997 Nanbor Wang <nw1@cumbia.cs.wustl.edu> + + * server/main.cpp (main): Service configurator now doesn't return + -1 when errors occur. Therefore, we check for not success + instread of fail when opening the service contifurator. + +Mon Jul 28 04:54:01 1997 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * server/Parse_Headers.cpp (place): Reformatted the same + stuff again... + +Mon Jul 28 01:48:40 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/README: Updated the README file to reflect new features + and server flags. + + * server/Parse_Headers.cpp (place): Fixed a compile error found by + David Levine. I don't know why this was compiling for me. + +Sun Jul 27 21:56:12 1997 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * server/Parse_Headers.cpp (place): Reformatted a few things + to make them easier to read. + +Fri Jul 25 02:05:20 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/HTTP_Server.cpp: Changes to allow the thread creation + flags to be specified from the command line. Removed some code + that was used to track down memory leaks. + + * server/HTTP_Helpers.{h,cpp}: Added another method + HTTP_date (char *), so that a buffer to which the date will be + written to can be passed into the HTTP_date routine. + + * server/HTTP_Response.cpp: Changed some code so that the baseline + implementation can be created at compile time. + + * server/IO.cpp: Changed some code so that the baseline + implementation can be created at compile time. + + * server/main.cpp: Changed the signal handler to wait for threads + to die. However, this code will remain dormant for now, until + we design a nice way to shut down a thread pool. + + * server/svc.conf: Changes to add some other entries people can + try. + + * server/Makefile: Changes to allow JAWS to be built with static + linking only, to ease the process of using Purify and Quantify. + Dynamic linking will be re-configured in the future when we have + all the memory leaks worked out. + +Mon Jul 22 16:55:00 1997 Chris Cleeland <cleeland@cs.wustl.edu> + + * Changed references to WRAPPER_ROOT to ACE_ROOT in every + place except ChangeLog entries. + +Mon Jul 21 15:09:03 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/HTTP_Server.{h,cpp}: Got rid of Solaris specific + debugging code (thr_create, thr_join). + +Fri Jul 11 02:15:12 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/HTTP_Response.cpp: Changes so that the HEADER is not + rebuilt all the time. + + * server/IO.cpp (JAWS_Synch_IO::transmit_file): Changed to use + writev () instead of multiple send ()s. + +Thu Jul 10 01:53:48 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * server/HTTP_Helpers.{h,cpp}: Changed so that creating the date + header is less expensive. + + * server/HTTP_Response.cpp: Changes to match above. + + * clients/Caching/README: Added to the repository. + + * clients/Caching/http_handler.{h,cpp}: Added some comments to the + code. Also, moved the code to check to see if the file is in + cache already into the connector, so that a connect is not + done if the file is cached. This required a filename () + accessor method to be added to the handler. + +Wed Jul 9 13:08:00 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * clients/Caching/http_handler.cpp (svc): Added code to check to + see if the file is already cached before trying to cache it. + + * clients/Caching/http_client.cpp (main): Added a comment block at + the top of the file. + + * server/HTTP_Handler.cpp and IO.cpp: Changes that were needed + since JAWS_File is now integrated into ACE (as ACE_Filecache). + + * server/HTTP_Server.*: Attempting to track down memory leak. + This code may be in a state a flux for the next week or so. + +Mon Jul 7 23:40:13 1997 Nanbor Wang <nw1@cumbia.cs.wustl.edu> + + * clients/WebSTONE/src/webclient.c: Removed a bunch of THREAD + storage class decorators from function makeload() because auto + variables can't be declared as TSS. Also #ifdef random number + generation code so it uses rand_r on Solaris() and rand() on NT. + + * clients/WebSTONE/src/rexec.c: Modified prototypes for + PassOutputThread() and PassErrorThread() to avoid warnings from + MSVC. Still need more refinement on this one. ;( + + * clients/WebSTONE/src/webmaster.c: Added prototype for + HostEntCpy() and a null statement to avoid warning from MSVC. + + * clients/WebSTONE/src/gendata/genrand.mak: + * clients/WebSTONE/src/master/webmaster.mak: + * clients/WebSTONE/src/client/webclient.mak: Updated file paths + and dependencies. + +Sat Jul 5 14:19:20 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * Renamed the client directory "clients" to reflect the fact that + we've got multiple client tests now. Also, moved the original + contents of the client directory into a new clients/Blobby + directory and added Caching and WebSTONE. + + * Moved the ChangeLog from the ./server directory into the ./JAWS + directory since we want to apply ChangeLog entries to all + aspects of JAWS, not just the server. + + * HTTP_Server.cpp (open): Added THR_DETACHED as a flag to + activate(). This should prevent a memory leak that was + occurring since no thread was ever "joining" the threads that + were spawned. + +Thu Jul 3 23:33:47 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * HTTP_Response.cpp (~HTTP_Response): changed delete to delete [], + removing a major memory leak from JAWS. Still to find is a + memory lead associated with thread per request. Nanbor's fix is + about what I did to EMPTY_HEADER too. + + * JAWS_File.cpp: David points out I need to add specializations + for the GNU C++ compiler. + +Thu Jul 3 22:38:04 1997 Nanbor Wang <nw1@cumbia.cs.wustl.edu> + + * HTTP_Response.cpp (build_headers): Added explicit cast for + EMPTY_HEADER from (const char *) to (char *) in order to make + MSVC happy. This is probably very badly styled. But + HTTP_HEADER is only used in places that require (const char *), + so I think it's safe to do so. + +Thu Jul 3 15:34:30 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * HTTP_Response.cpp (HTTP_Response): Moved a call to delete out of + constructor into the destructor where it belongs. + +Thu Jul 3 12:28:44 1997 Sumedh Mungee <sumedh@lindy.cs.wustl.edu> + + * Parse_Headers.cpp: Line 137, Changed pt to ptr (it was a typo) + +Wed Jul 2 22:33:52 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * JAWS_File.{h,cpp}: Fixed deadlock bug, since RW_MUTEX's are not + recursive (drat!). + +Wed Jul 2 21:03:12 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * Made a major pass through all the code and made the style + consistent with that found in ACE. + +Wed Jul 2 14:33:27 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * JAWS_File.cpp: Added double check locking pattern to the fetch + routine of the virtual filesystem. This slows things down + considerably for files which change frequently and for cache + misses in general, but it should be correct. + +Wed Jul 2 14:59:29 1997 Nanbor Wang <nw1@cumbia.cs.wustl.edu> + + * HTTP_Helpers.cpp (HTTP_decode_string): Added cast from strtol to + char explicitly to prevent NT from complaining. + +Wed Jul 2 14:33:27 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * JAWS_File.{h.cpp}: Modifications to support RW_MUTEX for both + the virtual filesystem and the low level ACE_File. Next major + change will be to re-implement the virtual filesystem to use a + hash table ala ACE_Hash_Map_Manager. + +Wed Jul 2 00:23:22 1997 James C Hu <jxh@polka.cs.wustl.edu> + + * HTTP_Server.{h,cpp}: Changed parsing of options to use + mnemonic names rather than numbers. Added a new thread + strategy, THROTTLE. This is thread-per-request until some + maximum number. Unfortunately, it does not become thread-pool + at this point... yet :-). Added a new option to pass in a + backlog value. + + * svc.conf: adjusted to account for the changed options. + + * README: changed to explain new svc.conf options. + + * JAWS_File.cpp: Changed it so that when the file is added to the + cache, it is also acquired. When it is removed from the cache, + it is released. This is so that the reference count is at least + one while the file is in the cache. Also, fixed the virtual + filesystem by giving it a simple replacement strategy if the + table is full. For now, it will replace the largest file in the + cache with the request for the current file. + +Tue Jul 1 19:13:44 1997 Nanbor Wang <nw1@cumbia.cs.wustl.edu> + + * JAWS_File.cpp (JAWS_File): Changes the creation method of a + cached copy from using plain file copy to using mmap and memcpy. + This avoid the extra complexity caused by FILE_FLAG_OVERLAPPED. + +Sat Jun 28 11:55:38 1997 James C Hu <jxh@tango.cs.wustl.edu> + + * HTTP_Handler.cpp (open): fixed a typo + + * HTTP_Handler.cpp (cgi): fixed a bug, strdup fails on NULL + +Sat Jun 28 16:14:38 1997 Sumedh Mungee <sumedh@cumbia.cs.wustl.edu> + + * HTTP_Handler.cpp (open): Changed socket send-buffer to 64k + +Wed Jun 25 01:11:50 1997 Nanbor Wang <nw1@dingo.wolfpack.cs.wustl.edu> + + * JAWS_File.cpp: Removed initialization of vfs_ (see below) and + changed all references of vfs_ to + JAWS_Virtual_Filesystem::instance (). Thanks to Detlef Becker + <detlef.becker@med.siemens.de> for pointing this out. + (init): Added initialization of reference_count_ to 0. + + * JAWS_File.h: Removed private member JAWS_Virtual_Filesystem vfs_ + since JAWS_Virtual_Filesystem is a singleton already. Caching + it doesn't seem to win much and depends on the order of static + variables initialization, which is non-portable. + +Fri Jun 13 02:42:39 1997 Nanbor Wang <nw1@dingo.wolfpack.cs.wustl.edu> + + * jaws.{mdp,mak}: Updated to incoporate latest changes. + +Thu Jun 5 14:13:22 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * HTTP_Server.cpp: Added more informative comments to the + asynch_thread_pool() method due to comments posed by Mehul + (MehulM@spa-marketing.com). + +Wed Jun 4 23:00:47 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * JAWS_File.cpp (JAWS_File): Fixed a bug where JAWS_File wanted + the file to have write permissions before openning it. This is + now only true if the file is to be written to. + +Wed Jun 4 22:30:41 1997 Nanbor Wang <nw1@dingo.wolfpack.cs.wustl.edu> + + * main.cpp (main): Changed SIGCLD to SIGCHLD for better + portability. + + * IO.cpp (transmit_file): The third argument passed + ACE_Asynch_Transmit_File::Header_And_Trailer() should be an + address (&). + +Mon Jun 2 16:35:18 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * HTTP_Helpers.cpp: Serious bug in base64 decoder routine + squashed. Didn't initialize an array with 0's. The original + source had them declared static. Also, changed sizeof alphabet_ + to strlen (alphabet_), because original code had alphabet_ as an + array, but my translation has alphabet_ as a pointer. + + * HTTP_Response.cpp: Added some code to check to see if the + decoder returns 0. If it does, flag this as a failed + authorization attempt. + + * HTTP_Handler.cpp: Added a "\r\n" to the confirmation message in + receive_file_complete () method. + + * HTTP_Request.cpp: In parse_request_line (), created conditional + expressions in the debugging print statement so that a null + string will not cause the server to crash. + + * HTTP_Response.cpp: + (1) cgi_resposnse () no longer has to wait for the process to + die. The fix to ACE_Process of closing down child handles was + enough to get the connection to die on its own. + (2) Mike (mrm@cisco.com) pointed out that the output for CGI + responses was not create. The fix was to output a small header + before execing the CGI program. + + * test.cgi: a sample cgi program to use when testing the JAWS + server. + +Sat May 31 13:34:14 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * *.h, *.cpp: Changed include lines from "apps/JAWS/server/..." to + "..." to avoid dependencies on the WRAPPER_ROOT tree. + + * jaws.auth: This file is added to be a sample authorization + file. This is the file which JAWS is currently hardcoded to use + to verify authenticated PUT requests. + + * HTTP_Response.cpp: Added code to normal_response () and to + error_response () to better handle authentication. Now, all PUT + methods are required to be authenticated. The strategy now is + very simple, there is only one authorization file and only one + realm of authorization. This will be easy to bring up to spec + later, though. + + * HTTP_Helpers.h: Added alphabet_ data member for the + decode/encode base64 methods. + + * HTTP_Helpers.cpp: Added HTTP_decode_base64 and + HTTP_encode_base64 methods. HTTP_encode_base64 is currently not + used, but HTTP_decode_base64 is being used for Basic + authentication. + + * *.h, *.cpp: Changed include lines from "JAWS/server/..." to + "apps/JAWS/server/..." to fix an error reported by Rob Payne + <repayne@jeeves.net>. This was really due to a bug in the + platform_macros.GNU file not adding INCLDIRS to the CCFLAGS + during compilation, but in the case other platforms have the + same problem, changing the source is a better fix. + +Fri May 30 23:19:03 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * README: updated to better reflect the status of JAWS. + + * main.cpp (handler): Added a signal handler for SIGINT, and also + set SIG_IGN for SIGCLD. The first handler calls exit (0) if + SIGINT is received, so that static destructors are called. The + second is so that zombies are not formed. + + * HTTP_Response.cpp (cgi_response): Debugging. (1) The CGI + program spewed output on the server side instead of the client. + (2) The CGI program had environment variable being set even + though there was no associated value. (3) The client connection + was not being closed after the CGI program executed. Problem + (1) was fixed by using set_handles () in cgi_options. Problem + (2) was fixed by testing to see if the header had an associated + value before assigning it to the environment. Problem (3) was + fixed by sending an empty confirmation message after waiting for + the CGI process to exit. + + * HTTP_Request.cpp (cgi): Debugging. It was not looking for a + ".cgi" extension during the stage of determining if a URI is a + CGI script. This will later be fixed when a full mime-type + facility is implemented. + +Fri May 23 00:45:24 1997 James C Hu <jxh@lambada.cs.wustl.edu> + + * JAWS/server: Debugged HTTP/0.9 GET requests, and HTTP/1.0 PUT + requests. Both work now, with minor problems: e.g. the + Content-type header doesn't really work (always sends text/html + as the content type). What it should do is see if the request + included a content type header, and use it, otherwise, resort to + some file suffix and mimetype matching algorithm. + + * Parse_Headers.h (complete_header_line): Added comments + explaining the new return values of -1, 0 and 1 (see comments + for Parse_Headers.cpp below). + + * Parse_Headers.cpp (complete_header_line): modified so that it + returns three values instead of two. -1 means that an end of + line was encountered, but nothing after it yet to verify if it + is really a complete header line. 0 means the read cut off in + the middle of a line (no end of line character found). 1 means + the line is verified to be a complete header line. + + * HTTP_Request.cpp (parse_request): Changed the test so that an + HTTP/0.9 request would be sent immediately after being issued. + This involved changes to Parse_Headers. + + * JAWS_File.cpp (acquire): Changes involved adding some debugging + statements to understand why PUT was not working. Discovered a + bug in how ACE_Mem_Map was being used. + + * HTTP_Request.cpp (content_length): Changed to extract value from + the headers, if available. + +Thu May 22 16:22:03 1997 James C. Hu <jxh@pride.cs.wustl.edu> + + * HTTP_Request.cpp (cgi_env): Added a cast so that a warning + generated by SGI C++ compiler goes away. + + * Makefile: Reordered the way the files are compiled/linked so + that useless warnings about object files not resolving any + symbols go away. + +Wed May 21 15:33:33 1997 James C Hu <jxh@polka.cs.wustl.edu> + + * JAWS_File.{h,cpp}: Added some comments. Will add a copy () + method soon, after I move my workspace over to lambada. + + * JAWS_Tilde.{h,cpp}: This class is being implemented but has not + been added to the repository yet, since JAWS as yet does not use + it, and it is still being developed. This will be a cache of + the expansions from ~foo to the home directory of foo. + +Tue May 20 22:49:24 1997 James C Hu <jxh@polka.cs.wustl.edu> + + * JAWS_File.{h,cpp}: New class created to replace the old kludgy + VFS thingy. This new cached virtual filesystem is way cool: a + file which is being retrieved can be simultaneously replaced + without causing either reader or writer to wait. Reference + counts are maintained now, which was missing in VFS. Also, + there is no longer a dependency on the JXH_List template now, + which is a plus. + + * IO.cpp: Changes to adapt to the new virtual filesystem. The + changes all involved simplifications to the programming + interface. + + * HTTP_Handler.cpp: Changes required to deal with the more + generic error responses returned from the JAWS_File/JAWS_IO + interface. This generality will make it easier to adapt + JAWS_File and JAWS_IO into ACE. + + * test_JAWS_File.cpp: A test program written to see if the new + virtual filesystem works the way I expect it to. + +Local Variables: +mode: change-log +add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time)) +indent-tabs-mode: nil +End: diff --git a/ACE/apps/JAWS/Makefile.am b/ACE/apps/JAWS/Makefile.am new file mode 100644 index 00000000000..c922c992902 --- /dev/null +++ b/ACE/apps/JAWS/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +SUBDIRS = \ + clients \ + server + diff --git a/ACE/apps/JAWS/README b/ACE/apps/JAWS/README new file mode 100644 index 00000000000..e67da72afd1 --- /dev/null +++ b/ACE/apps/JAWS/README @@ -0,0 +1,15 @@ +This directory contains the source code and test examples for JAWS, +which is a high-performance HTTP Web server written with ACE. For +more information on JAWS, please see + +http://www.cs.wustl.edu/~jxh/research/ + +The subdirectories in this directory contain the following components + + . clients -- This contains the source code for various + client applications that exercise the file uploading and + downloading features of JAWS + + . server -- This contains the source code for the JAWS + HTTP Web server. It illustrates a number of sophisticated + ACE concurrency and event demultiplexing strategies. diff --git a/ACE/apps/JAWS/clients/Blobby/Blob.cpp b/ACE/apps/JAWS/clients/Blobby/Blob.cpp new file mode 100644 index 00000000000..3bd237c7a9c --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/Blob.cpp @@ -0,0 +1,77 @@ +// $Id$ + +#include "Blob.h" +#include "Blob_Handler.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(Blobby, Blob, "$Id$") + +ACE_Blob::ACE_Blob (void) +{ +} + +ACE_Blob::~ACE_Blob (void) +{ + this->close (); +} + +// initialize address and filename. No network i/o in open + +int +ACE_Blob::open (const ACE_TCHAR *filename, const ACE_TCHAR *hostname , u_short port) +{ + filename_ = ACE_OS::strdup (filename); + inet_addr_.set (port, hostname); + return 0; +} + +// read from connection length bytes from offset, into Message block + +int +ACE_Blob::read (ACE_Message_Block *mb, size_t length, size_t offset) +{ + + // Create a Blob Reader + ACE_Blob_Reader blob_reader (mb, length, offset, filename_); + ACE_Blob_Handler *brp = &blob_reader; + + // Connect to the server + if (connector_.connect (brp, inet_addr_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_Blob::read():Connector error"), -1); + + return blob_reader.byte_count (); + +} + +// write to connection length bytes from offset, into Message block + +int +ACE_Blob::write (ACE_Message_Block *mb, size_t length, size_t offset) +{ + + // Create a Blob Writer + ACE_Blob_Writer blob_writer (mb, length, offset, filename_); + ACE_Blob_Handler *bwp = &blob_writer; + + // Connect to the server + if (connector_.connect (bwp, inet_addr_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_Blob::write():Connector error"), -1); + + return blob_writer.byte_count (); +} + +// close down the blob + +int +ACE_Blob::close (void) +{ + + if (filename_) + { + ACE_OS::free ((void *) filename_); + filename_ = 0; + } + return 0; + +} + diff --git a/ACE/apps/JAWS/clients/Blobby/Blob.h b/ACE/apps/JAWS/clients/Blobby/Blob.h new file mode 100644 index 00000000000..9ba35fb0176 --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/Blob.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ + +//============================================================================ +// +// = LIBRARY +// JAWS +// +// = FILENAME +// Blob.h +// +// = DESCRIPTION +// This is the ACE_Blob class, which is the API for doing file +// uploads/downloads. +// +// = AUTHOR +// Prashant Jain and Sumedh Mungee +// +//============================================================================ + +#ifndef ACE_BLOB_H +#define ACE_BLOB_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/INET_Addr.h" +#include "ace/Svc_Handler.h" +#include "ace/SOCK_Connector.h" +#include "ace/Connector.h" +#include "ace/Message_Block.h" +#include "Blob_Handler.h" + +class ACE_Blob + // = TITLE + // Blob is intended to provide application API to + // classes that wish to do network i/o at a very + // high level of abstraction. + // + // = This class provides the ability to retrieve data from + // the network, of specified length and offset, and potentially + // use any protocol "under the hood" to do so. It currently + // uses HTTP. See Blob_Handler also. +{ +public: + ACE_Blob (void); + ~ACE_Blob (void); + + int open (const ACE_TCHAR *filename, + const ACE_TCHAR *hostname = ACE_DEFAULT_SERVER_HOST, + u_short port = 80); + // initializes the class with the given filename, hostname and port. + // it should be called with the filename, before any read/write calls + + + int read (ACE_Message_Block *mb, size_t length, size_t offset); + // starts a connection, and reads a file from the server, + // of length and offset as specified, into Message_Block mb + // The message block should have capacity to hold length number + // of bytes + + int write (ACE_Message_Block *mb, size_t length, size_t offset); + // starts a connection, and writes a file to the server, + // of length and offset as specified, from Message_Block mb + // thus the message block should contain atleast length + offset + // bytes of data + + + int close (); + // Frees memory allocated for filename. + +private: + ACE_INET_Addr inet_addr_; + // store the internet address of the server + + ACE_TCHAR *filename_; + // The filename + + ACE_Connector<ACE_Blob_Handler, ACE_SOCK_CONNECTOR> connector_; + // The connector endpoint to initiate the client connection + +}; + +#endif /* ACE_BLOB_H */ diff --git a/ACE/apps/JAWS/clients/Blobby/Blob_Handler.cpp b/ACE/apps/JAWS/clients/Blobby/Blob_Handler.cpp new file mode 100644 index 00000000000..8ae5cde6e9b --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/Blob_Handler.cpp @@ -0,0 +1,347 @@ +// $Id$ + +#include "Blob_Handler.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_strings.h" + +ACE_RCSID(Blobby, Blob_Handler, "$Id$") + +// Empty constructor for compliance with new Connector behavior. +ACE_Blob_Handler::ACE_Blob_Handler (void) +{ +} + +// Always use this constructor +ACE_Blob_Handler::ACE_Blob_Handler (ACE_Message_Block * mb, + size_t length, + size_t offset, + ACE_TCHAR *filename) : + mb_ (mb), + length_ (length), + offset_ (offset), + filename_ (ACE_OS::strdup (filename)), + bytecount_ (0) +{ +} + +ACE_Blob_Handler::~ACE_Blob_Handler (void) +{ + if (filename_) + { + ACE_OS::free ((void *) filename_); + filename_ = 0; + } +} + +// Called by Connector after connection is established +int +ACE_Blob_Handler::open (void *) +{ + if (this->send_request () != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_Blob_Handler::open():send_request failed"), -1); + + if (this->receive_reply () != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_Blob_Handler::open():receive_reply failed"), -1); + return 0; + +} + +// No-op +int +ACE_Blob_Handler::close (u_long flags) +{ + ACE_UNUSED_ARG (flags); + return 0; +} + + +// Always overridden by the derived classes +int +ACE_Blob_Handler::send_request (void) +{ + return -1; +} + +// Always overridden by the derived classes +int +ACE_Blob_Handler::receive_reply (void) +{ + return -1; +} + +// used to retrieve the number of bytes read/written by the +// last operation on the Blob +int +ACE_Blob_Handler::byte_count (void) +{ + return bytecount_; +} + +// Reader ************************************************** + +ACE_Blob_Reader::ACE_Blob_Reader (ACE_Message_Block * mb, + size_t length, + size_t offset, + ACE_TCHAR *filename, + const char *request_prefix, + const char *request_suffix) : + ACE_Blob_Handler (mb, length, offset, filename), + request_prefix_ (request_prefix), + request_suffix_ (request_suffix) +{ +} + +// Send the HTTP request +int +ACE_Blob_Reader::send_request (void) +{ + char mesg [MAX_HEADER_SIZE]; + + // Check to see if the request is too big + if (MAX_HEADER_SIZE < (ACE_OS::strlen (request_prefix_) + + ACE_OS::strlen (filename_) + + ACE_OS::strlen (request_suffix_) + 4)) + ACE_ERROR_RETURN((LM_ERROR,"Request too large!"), -1); + + // Create a message to send to the server requesting retrieval of the file + int len = ACE_OS::sprintf (mesg, "%s %s %s", request_prefix_, filename_, request_suffix_); + + // Send the message to server + if (peer ().send_n (mesg, len) != len) + ACE_ERROR_RETURN((LM_ERROR,"Error sending request"), -1); + + + return 0; +} + +// Recieve the HTTP Reply +int +ACE_Blob_Reader::receive_reply (void) +{ + ssize_t len; + char buf [MAX_HEADER_SIZE + 1]; + char *buf_ptr; + size_t bytes_read = 0; + size_t bytes_left = this->length_; + size_t offset_left = this->offset_; + + // Receive the first MAX_HEADER_SIZE bytes to be able to strip off the + // header. Note that we assume that the header will fit into the + // first MAX_HEADER_SIZE bytes of the transmitted data. + if ((len = peer ().recv_n (buf, MAX_HEADER_SIZE)) >= 0) + { + buf[len] = '\0'; + + // Search for the header termination string "\r\n\r\n", or "\n\n". If + // found, move past it to get to the data portion. + if ((buf_ptr = ACE_OS::strstr (buf,"\r\n\r\n")) != 0) + buf_ptr += 4; + else if ((buf_ptr = ACE_OS::strstr (buf, "\n\n")) != 0) + buf_ptr += 2; + else + buf_ptr = buf; + + // Determine number of data bytes read. This is equal to the + // total bytes read minus number of header bytes. + bytes_read = (buf + len) - buf_ptr; + } + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_Blob_Reader::receiveReply():Error while reading header"), -1); + + // *************************************************************** + // At this point, we have stripped off the header and are ready to + // process data. buf_ptr points to the data + + // First adjust for offset. There are two cases: + // (1) The first block of data encountered the offset. In this case + // we simply increment the buf_ptr by offset. + // (2) The first block of data did not encounter the offset. That + // is, the offset needs to go past the number of data bytes already read. + if (bytes_read > offset_left) + { + // The first case is true -- that is offset is less than the + // data bytes we just read. + buf_ptr += offset_left; + + // Determine how many data bytes are actually there. This is + // basically the total number of data bytes we read minus any + // offset we have. + size_t data_bytes = bytes_read - offset_left; + + // Check for the case where the bytes read are enough to fulfill + // our request (for length bytes). If this is the case, then we + // don't need to do any extra recvs and can simply return with + // the data. + if (data_bytes >= bytes_left) + { + // The first block contains enough data to satisfy the + // length. So copy the data into the message buffer. + if (mb_->copy (buf_ptr, bytes_left) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "ACE Blob_Reader::receiveReply():Error copying data into Message_Block"), -1); + bytecount_ = length_; + return 0; + } + + // Copy over all the data bytes into our message buffer. + if (mb_->copy (buf_ptr, data_bytes) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "ACE_Blob_Reader::receiveReply():Error copying data into Message_Block" ), -1); + + // Adjust bytes left + bytes_left -= data_bytes; + + // No more offset left. So set it to zero. + offset_left = 0; + } + else + { + // The second case is true -- that is offset is greater than + // the data bytes we just read. + offset_left -= bytes_read; + } + + // If we ad any offset left, take care of that. + while (offset_left > 0) + { + // MAX_HEADER_SIZE in which case we should do a receive of + // offset bytes into a temporary buffer. Otherwise, we should + // receive MAX_HEADER_SIZE bytes into temporary buffer and + // decrement offset_left. + if (offset_left < (sizeof buf)) + len = offset_left; + else + len = sizeof buf; + if (peer().recv_n (buf, len) != len) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "ACE_Blob_Reader::receiveReply():Read error" ), + -1); + offset_left -= len; + } + + // ***************************************************************** + // At this point we are all set to receive the actual data which the + // user wants. We have made adjustments for offset and are ready to + // receive the actual data. Receive the data directly into the + // message buffer. + + len = peer().recv_n (mb_->wr_ptr (), bytes_left); + + if (len < 0 || static_cast<size_t> (len) != bytes_left) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "ACE_Blob_Reader::receiveReply():Read error" ), + -1); + + // Adjust the message buffer write pointer by number of bytes we + // received. + mb_->wr_ptr (len); + + // Set the byte count to number of bytes received + this->bytecount_ = length_; + + return 0; +} + +// Writer ************************************************** + +ACE_Blob_Writer::ACE_Blob_Writer (ACE_Message_Block * mb, + size_t length, + size_t offset, + ACE_TCHAR *filename, + const char *request_prefix, + const char *request_suffix) : + ACE_Blob_Handler (mb, length, offset, filename), + request_prefix_ (request_prefix), + request_suffix_ (request_suffix) +{ +} + +int +ACE_Blob_Writer::send_request (void) +{ + // Check for sanity -- check if we have any data to send. + if (offset_+ length_ > mb_->length ()) + ACE_ERROR_RETURN((LM_ERROR, "%p\n", + "ACE_Blob_Writer::sendRequest():Invalid offset/length"), -1); + + // Determine the length of the header message we will be sending to + // the server. Note that we add 32 for safety -- this corresponds to + // the number of bytes needed for the length field. + size_t mesglen = + ACE_OS::strlen (request_prefix_) + + ACE_OS::strlen (filename_) + + ACE_OS::strlen (request_suffix_) + + 32; // safety + + // Allocate a buffer to hold the header + char *mesg = 0; + ACE_NEW_RETURN (mesg, char [mesglen], -1); + + // Create the header, store the actual length in mesglen. + // NOTE! %lu is really what's wanted. ACE_SIZE_T_FORMAT_SPECIFIER is + // defined in terms of ACE_TEXT which is NOT what we want here. + mesglen = ACE_OS::sprintf (mesg, "%s /%s %s %lu\n\n", + request_prefix_, filename_, request_suffix_, + (unsigned long)length_); + + // Send the header followed by the data + + // First send the header + if (peer ().send_n (mesg, mesglen) == -1) + ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Error sending request"), -1); + + // "Consume" the offset by moving the read pointer of the message + // buffer + mb_->rd_ptr (offset_); + + // Now send the data + if (peer ().send_n (mb_->rd_ptr (), length_) != (int)length_) + ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Error sending file"), -1); + + // Adjust the read pointer of the mesage buffer + mb_->rd_ptr (length_); + + return 0; +} + +int +ACE_Blob_Writer::receive_reply (void) +{ + // Allocate a buffer big enough to hold the header + char buf[MAX_HEADER_SIZE]; + + // Receive the reply from the server + size_t num_recvd = 0; + ssize_t len = peer ().recv_n (buf, sizeof buf - 1, 0, &num_recvd); // reserve one byte to store the \0 + if (len ==-1) + ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Error reading header"), -1); + + buf [num_recvd] = 0; + + // Parse the header + char *lasts = 0; + + // First check if this was a valid header -- HTTP/1.0 + char *token = ACE_OS::strtok_r (buf, " \t", &lasts); + + if ( (token == 0) || (ACE_OS::strcasecmp (token, "HTTP/1.0") != 0)) + ACE_ERROR_RETURN((LM_ERROR, "%p\n", "Did not receive a HTTP/1.0 response"), -1); + + // Get the return code. + int return_code = ACE_OS::atoi (ACE_OS::strtok_r (0, " \t", &lasts)); + + // Check if the transaction succeeded. The only success codes are in + // the range of 200-299 (HTTP specification). + if (return_code >= 200 && return_code < 300) + return 0; + else + { + // Something went wrong! + // Get the description from the header message of what went wrong. + char *description = ACE_OS::strtok_r (0, "\n\r", &lasts); + ACE_ERROR_RETURN((LM_ERROR, "%p\n", description), -1); + } + ACE_NOTREACHED(return 0); +} + diff --git a/ACE/apps/JAWS/clients/Blobby/Blob_Handler.h b/ACE/apps/JAWS/clients/Blobby/Blob_Handler.h new file mode 100644 index 00000000000..41e13ff9c03 --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/Blob_Handler.h @@ -0,0 +1,118 @@ +/* -*- C++ -*- */ +// $Id$ + +//============================================================================ +// +// = LIBRARY +// JAWS +// +// = FILENAME +// Blob.h +// +// = DESCRIPTION +// ACE_Blob_Handler is a base class for ACE_Blob_Reader and +// ACE_Blob_Writer which are created in response to calls to +// read/write, as appropriate +// +// = AUTHOR +// Prashant Jain and Sumedh Mungee +// +//============================================================================ + +#ifndef ACE_BLOB_HANDLER_H +#define ACE_BLOB_HANDLER_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Stream.h" +#include "ace/Svc_Handler.h" +#include "ace/Message_Block.h" + +class ACE_Blob_Handler : public ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH> + // = TITLE + // Blob is intended to provide application API to + // classes that wish to do network i/o at a very + // high level of abstraction. + // + // = This class provides the ability to retrieve data from + // the network, of specified length and offset, and potentially + // use any protocol "under the hood" to do so. It currently + // uses HTTP. See Blob_Handler also. +{ +public: + ACE_Blob_Handler (void); + // Null constructor, insures that it works properly with Connector + + ACE_Blob_Handler (ACE_Message_Block *mb, + size_t length, + size_t offset, + ACE_TCHAR *filename); + // Always use this constructor to make Blob_Handlers + + int byte_count (void); + // returns the number of bytes read/written in the last operation. + + virtual int open (void * = 0); + // Activate this instance of the <ACE_Blob_Handler> + + virtual int close (u_long flags = 0); + // Close down the Blob + + ~ACE_Blob_Handler (void); + +protected: + virtual int send_request (void); + virtual int receive_reply (void); + + ACE_Message_Block *mb_; + size_t length_; + size_t offset_; + ACE_TCHAR *filename_; + int bytecount_; + enum + { + MAX_HEADER_SIZE = 2048 + // The handler assumes that the first 2048 bytes of a server response + // contains the header + }; +}; + +class ACE_Blob_Reader : public ACE_Blob_Handler +{ +public: + ACE_Blob_Reader (ACE_Message_Block *mb, + size_t length, + size_t offset, + ACE_TCHAR *filename, + const char *request_prefix = "GET", + const char *request_suffix = "HTTP/1.0\r\n\r\n"); + +private: + int send_request (void); + int receive_reply (void); + const char *request_prefix_; + const char *request_suffix_; +}; + +class ACE_Blob_Writer : public ACE_Blob_Handler +{ +public: + ACE_Blob_Writer (ACE_Message_Block *mb, + size_t length, + size_t offset, + ACE_TCHAR *filename, + const char *request_prefix = "PUT", + const char *request_suffix = "HTTP/1.0\nContent-length:"); + +private: + int send_request (void); + int receive_reply (void); + const char *request_prefix_; + const char *request_suffix_; +}; + +#endif /* ACE_BLOB_HANDLER_H */ diff --git a/ACE/apps/JAWS/clients/Blobby/Makefile.am b/ACE/apps/JAWS/clients/Blobby/Makefile.am new file mode 100644 index 00000000000..1e0071f74d1 --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/Makefile.am @@ -0,0 +1,40 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.blobby.am + +noinst_PROGRAMS = blobby + +blobby_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +blobby_SOURCES = \ + Blob.cpp \ + Blob_Handler.cpp \ + Options.cpp \ + blobby.cpp \ + Blob.h \ + Blob_Handler.h \ + Options.h + +blobby_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/apps/JAWS/clients/Blobby/Options.cpp b/ACE/apps/JAWS/clients/Blobby/Options.cpp new file mode 100644 index 00000000000..08f7de4ad8b --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/Options.cpp @@ -0,0 +1,81 @@ +// $Id$ + +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "Blob.h" +#include "Blob_Handler.h" +#include "Options.h" + +ACE_RCSID(Blobby, Options, "$Id$") + +Options *Options::instance_ = 0; + +Options * +Options::instance (void) +{ + + if (Options::instance_ == 0) + Options::instance_ = new Options; + + return Options::instance_; +} + +void +Options::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("rwh:p:f:l:o:d")); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'd': + this->debug_ = 1; + break; + case 'r': + this->operation_ = 'r'; + break; + case 'w': + this->operation_ = 'w'; + break; + case 'h': + this->hostname_ = get_opt.opt_arg (); + break; + case 'p': + this->port_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'f': + this->filename_ = get_opt.opt_arg (); + break; + case 'l': + this->length_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'o': + this->offset_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + // Usage fallthrough. + default: + ACE_DEBUG ((LM_DEBUG, "%s -h hostname -f filename -[r/w] [-p port] [-l length] [-o offset] [-d]\n", argv[0])); + ACE_OS::exit (1); + } + if (this->hostname_ == 0 || this->filename_ == 0) + { + ACE_DEBUG ((LM_DEBUG, + "%s -h hostname -f filename -[r/w] [-p port] [-l length] [-o offset] [-d]\n", + argv[0])); + ACE_OS::exit (1); + } + +} + +Options::Options (void) + : hostname_ (0), + port_ (ACE_DEFAULT_HTTP_SERVER_PORT), + filename_ (0), + length_ (0), + offset_ (0), + operation_ ('r'), + debug_ (0) +{ +} diff --git a/ACE/apps/JAWS/clients/Blobby/Options.h b/ACE/apps/JAWS/clients/Blobby/Options.h new file mode 100644 index 00000000000..8396cf5535b --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/Options.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +// $Id$ + +//============================================================================ +// +// = LIBRARY +// JAWS +// +// = FILENAME +// Options.h +// +// = DESCRIPTION +// Options is an Singleton for blobby +// +// = AUTHOR +// Prashant Jain and Sumedh Mungee +// +//============================================================================ + +#ifndef ACE_BLOBBY_OPTIONS_H +#define ACE_BLOBBY_OPTIONS_H + +#include "Blob.h" +#include "Blob_Handler.h" +#include "ace/Get_Opt.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/ARGV.h" + +class Options +{ +public: + static Options *instance (void); + // Returns the singleton instance + + void parse_args (int argc, ACE_TCHAR *argv[]); + // parses commandline arguments + + ACE_TCHAR *hostname_; + // Hostname to connect to + + u_short port_; + // Port number to use + + ACE_TCHAR *filename_; + // Filename to upload/download + + int length_; + // number of bytes to read/write + + int offset_; + // offset to read/write + + char operation_; + // "r" means download (read), and "w" means upload (write). + + int debug_; + // turns on verbosity + +protected: + Options (void); + // protected constructor, singleton + + static Options *instance_; + // the singleton +}; + +#endif /* ACE_BLOBBY_OPTIONS_H */ diff --git a/ACE/apps/JAWS/clients/Blobby/README b/ACE/apps/JAWS/clients/Blobby/README new file mode 100644 index 00000000000..1a1cadf91ca --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/README @@ -0,0 +1,33 @@ +README for blobby, the example application for JAWS +--------------------------------------------------- + +Blobby is a simple application written using the ACE_Blob class, which +is capable of doing both file uploads and downloads from the JAWS +server. + +If a file is downloaded, the downloaded data is sent to standard +output, so that it can be piped as necessary. + +It is an ACE application, and should be compiled exactly like any +other ACE application. + +It accepts the following command line arguments: + + + -r Read (download) the file from the server + -w Write (upload) the file to the server + (Default is Read file) + + -h hostname Use the server running on hostname + (Default is localhost) + + -p port Port number of the server + (Default is 80) + + -f filename The file to upload/download from the server + + -l length The number of bytes to read/write from the server + -o offset The offset into the file to be read/written + + -d Puts blobby into debug mode, where it echoes + its command line arguments diff --git a/ACE/apps/JAWS/clients/Blobby/blobby.cpp b/ACE/apps/JAWS/clients/Blobby/blobby.cpp new file mode 100644 index 00000000000..e614b049c20 --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/blobby.cpp @@ -0,0 +1,125 @@ +// $Id$ + +//============================================================================ +// +// = LIBRARY +// JAWS +// +// = FILENAME +// blobby.c +// +// = DESCRIPTION +// Simple client application to illustrate the use of the ACE_Blob class +// +// It reads "length" number of bytes, after skipping offset "offset" +// from hostname, port and filename as specified. (if -r specified) +// +// It writes "length" number of bytes, after skipping offset "offset" +// to hostname, port and filename as specified (if -w specified) +// +// = AUTHOR +// Prashant Jain and Sumedh Mungee +// +//============================================================================ + +#include "Options.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(Blobby, blobby, "$Id$") + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + // Options is a singleton + Options *options = Options::instance (); + options->parse_args (argc, argv); + + // Explain what is going to happen + if (options->debug_) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("hostname = %C, port = %d, filename = %s, ") + ACE_TEXT ("length = %d, offset = %d, operation = %c\n"), + options->hostname_, + options->port_, + options->filename_, + options->length_, + options->offset_, + options->operation_)); + + // Create a blob + ACE_Blob blob; + + // User requested a read + if (options->operation_ == 'r') + { + ACE_Message_Block mb (0, options->length_); + + // Open the blob + if (blob.open (options->filename_, + options->hostname_, + options->port_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open error")), + -1); + + // Read from it + if (blob.read (&mb, options->length_, options->offset_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("read error")), + -1); + + // Write to STDOUT + if (ACE_OS::write (ACE_STDOUT, mb.rd_ptr(), mb.length()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("write error")), + -1); + } + else + { + int total = options->length_ + options->offset_; + ACE_Message_Block mb (total); + + // Open the file to be sent + ACE_HANDLE h = ACE_OS::open (options->filename_, O_RDONLY); + if (h == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("file open error")), + -1); + + // Open the blob + if (blob.open (options->filename_, options->hostname_, options->port_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("connection open error")), + -1); + + // Read from the file + if (ACE_OS::read (h, mb.wr_ptr (), total) != total) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("file read error")), + -1); + + // Close the file + ACE_OS::close (h); + + // Adjust the offset + mb.wr_ptr (mb.size ()); + + // Write to the blob + if (blob.write (&mb, options->length_, options->offset_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("network write error")), + -1); + } + + blob.close (); + return 0; +} diff --git a/ACE/apps/JAWS/clients/Blobby/blobby.mpc b/ACE/apps/JAWS/clients/Blobby/blobby.mpc new file mode 100644 index 00000000000..40bcf1bbe65 --- /dev/null +++ b/ACE/apps/JAWS/clients/Blobby/blobby.mpc @@ -0,0 +1,13 @@ +// -*- MPC -*- +// $Id$ + +project(blobby) : aceexe { + exename = blobby + Source_Files { + blobby.cpp + Blob.cpp + Blob_Handler.cpp + Options.cpp + } +} + diff --git a/ACE/apps/JAWS/clients/Caching/ID_Generator.cpp b/ACE/apps/JAWS/clients/Caching/ID_Generator.cpp new file mode 100644 index 00000000000..6e868611835 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/ID_Generator.cpp @@ -0,0 +1,61 @@ +// $Id$ + +#if !defined (ACE_ID_GENERATOR_C) +#define ACE_ID_GENERATOR_C + +#include "ace/Object_Manager.h" +#include "ID_Generator.h" + +ACE_RCSID(Caching, ID_Generator, "$Id$") + +time_t ACE_ID_Generator::last_time_ = 0; + +size_t ACE_ID_Generator::last_number_ = 0; + +ACE_SYNCH_MUTEX *ACE_ID_Generator::lock_ = 0; + +char * +ACE_ID_Generator::get_new_id (char *id) +{ + time_t t; + size_t sn; + + ACE_ID_Generator::get_serial_id (t, sn); + ACE_NEW_RETURN (id, char [ACE_OFFER_ID_LENGTH], 0); + + ACE_OS::sprintf (id, "%014d%06d", t, sn); + return id; +} + +void +ACE_ID_Generator::get_serial_id (time_t &t, size_t &s) +{ + ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, *ACE_ID_Generator::get_lock ())); + ACE_OS::time (&t); + + if (t != ACE_ID_Generator::last_time_) + { + ACE_ID_Generator::last_time_ = t; + s = ACE_ID_Generator::last_number_ = 0; + } + else + s = ACE_ID_Generator::last_number_++; +} + +ACE_SYNCH_MUTEX * +ACE_ID_Generator::get_lock (void) +{ +#if defined (ACE_HAS_THREADS) + if (ACE_ID_Generator::lock_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Static_Object_Lock::instance (), 0)); + + // Double-checked Locking Optimization. + if (ACE_ID_Generator::lock_ == 0) + ACE_NEW_RETURN (ACE_ID_Generator::lock_, ACE_SYNCH_MUTEX, 0); + } +#endif /* ACE_HAS_THREADS */ + return ACE_ID_Generator::lock_; +} + +#endif /* ACE_ID_GENERATOR_C */ diff --git a/ACE/apps/JAWS/clients/Caching/ID_Generator.h b/ACE/apps/JAWS/clients/Caching/ID_Generator.h new file mode 100644 index 00000000000..73c78fc5506 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/ID_Generator.h @@ -0,0 +1,62 @@ +/* -*- C++ -*- */ + +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// none +// +// = FILENAME +// ID_Generator.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_ID_GENERATOR_H +#define ACE_ID_GENERATOR_h + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#define ACE_OFFER_ID_LENGTH 21 + +class ACE_ID_Generator + // = TITLE + // An unique ID generator. + // + // = DESCRIPTION + + // Generate an offer ID according to current time and avoid + // duplicate ID. It guarantees ID uniqueness within a process, + // i.e. no two threads may get the same ID string. Using a + // similar method like the backery algorithm. +{ +public: + static char *get_new_id (char *id); + // allocate a new ID string and point <id> to it. + +private: + static void get_serial_id (time_t &t, size_t &s); + // Atomically get info required to generate an offer ID. + + static ACE_SYNCH_MUTEX *get_lock (void); + // Get the lock instance. + + static time_t last_time_; + // Record the time last offer ID generated. + + static size_t last_number_; + // Record serial number of last offer ID with same + // generation time. + + static ACE_SYNCH_MUTEX *lock_; + // mutex to access private member. +}; + +#endif /* ACE_ID_GENERATOR_H */ diff --git a/ACE/apps/JAWS/clients/Caching/Local_Locator.cpp b/ACE/apps/JAWS/clients/Caching/Local_Locator.cpp new file mode 100644 index 00000000000..2aab4f874d8 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/Local_Locator.cpp @@ -0,0 +1,248 @@ +// $Id$ + +#if !defined (ACE_LOCAL_LOCATOR_C) +#define ACE_LOCAL_LOCATOR_C + +#include "Local_Locator.h" + +#if !defined (__ACE_INLINE__) +#include "Local_Locator.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(Caching, Local_Locator, "$Id$") + +int +ACE_URL_Local_Locator::url_query (const ACE_URL_Locator::ACE_Selection_Criteria how, + const ACE_URL_Property_Seq *pseq, + const size_t how_many, + size_t &num_query, + ACE_URL_Offer_Seq *offer) +{ + ACE_URL_Record *item = 0; + + ACE_NEW_RETURN (offer, ACE_URL_Offer_Seq (how_many), -1); + + if (how >= ACE_URL_Locator::INVALID_SELECTION) + { + errno = ACE_URL_Locator::INVALID_ARGUMENT; + return -1; + } + + num_query = 0; + for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_); + iter.next (item) != 0; + iter.advance ()) + { + size_t i_query; + size_t i_db; + int found = 0; + + // Now this is a stupid implementation. Perhaps we can + // implement this using Hash_Map. Better yet, I think we should + // put this in a database and put SQL query here. + for (i_query = 0; found == 0 && i_query < pseq->size (); i_query++) + for (i_db = 0; i_db < item->offer_->url_properties ().size (); i_db++) + { + if ((*pseq)[i_query].name () == item->offer_->url_properties ()[i_db].name ()) + if (how == ACE_URL_Locator::SOME) + ; + + // if match and Some, copy to <offer>, inc <num_query>, advance iterator + + // else if All, advance iterator + + // else if None, check next property in <pseq>. + + if (all properties checked and found and ALL) + copy to <offer>; inc <num_query>; + else if (all properties checked and not found and NONE) + copy to <offer>; inc <num_query>; + else + shouldn't happen, internal error + + if (num_query == how_many) + break; + } + + return 0; +} + +int +ACE_URL_Local_Locator::export_offer (ACE_URL_Offer *offer, + ACE_WString &offer_id) +{ + ACE_URL_Record *item = 0; + + // First check if we have registered this URL already. + for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_); + iter.next (item) != 0; + iter.advance ()) + if (*item->offer_->url () == *offer->url ()) + { + errno = ACE_URL_Locator::OFFER_EXIST; + return -1; + } + + ACE_URL_Record *new_offer; + + // Offer is not in repository, we can add new one in safely. + ACE_NEW_RETURN (new_offer, ACE_URL_Record (offer), + ACE_URL_Locator::NOMEM); + + this->repository_.push (*new_offer); + + offer_id = *new_offer->id_; + return 0; +} + +int +ACE_URL_Local_Locator::withdraw_offer (const ACE_WString &offer_id) +{ + ACE_URL_Record *item = 0; + + // Iterate thru repository and remove offer with <offer_id>. + for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_); + iter.next (item) != 0; + iter.advance ()) + if (offer_id == *item->id_) + { + if (this->repository_.remove (*item) == 0) + return 0 + else + { + errno = ACE_URL_Locator::UNKNOWN; + return -1; + } + } + + errno = ACE_URL_Locator::NO_SUCH_OFFER; + return 0; +} + +int +ACE_URL_Local_Locator::describe_offer (const ACE_WString &offer_id, + ACE_URL_Offer *offer) +{ + ACE_URL_Record *item = 0; + + // Iterate thru the repository and produce a copy of offer's + // description. + for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_); + iter.next (item) != 0; + iter.advance ()) + if (offer_id == *item->id_) + { + ACE_NEW_RETURN (offer, ACE_URL_Offer (*item->offer_), -1); + return 0; + } + + errno = ACE_URL_Locator::NO_SUCH_OFFER; + return -1; +} + +int +ACE_URL_Local_Locator::modify_offer (const ACE_WString &offer_id, + const ACE_WString *url, + const ACE_URL_Property_Seq *del, + const ACE_URL_Property_Seq *modify) +{ + ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_); + ACE_URL_Record *item = 0; + ACE_URL_Record *target = 0; + + // Errno Checking + + for (; iter.next (item) != 0; iter.advance ()) + { + if (url != 0 && *url == item->offer_->url ()) + { + errno = ACE_URL_Locator::OFFER_EXIST; + return -1; + } + if (offer_id == *item->id_) + target = item; + } + + if (target != 0) // Aha, we found a target to work on + { + if (del != 0 && modify != 0) + { + // We need to make a copy of the original property sequence + // so if any error occurs, we can revert our change easily. + + // First we need to calculate the maximum number of perperties. + int psize = target->offer_->url_properties ().size (); + if (del != 0) + if ((psize -= del->size ()) < 0) + { + // If you try to delete more properties than we have, + // you are doomed. No need to proceed. + errno = ACE_URL_Locator::INVALID_ARGUMENT; + return -1; + } + if (modify != 0) + // In the worst case, all properties in <modify> will be added. + psize += modify->size (); + + // Now, create a temporary work space. + ACE_URL_Property_Seq working (psize); + size_t sz = 0; + for (; sz < item->offer_->url_properties ().size ()) + working[sz] = item->offer_->url_properties() [sz]; + + if (del != 0) + { + // Argh, this is really a stupid design. + // Go thru every property we want to delete + for (size_t i = 0; i < del->size () && sz > 0; i++) + // For earch, go thru our property sequence and + // search for the property. + for (size_t j = 0; j < sz; j++) + if ((*del)[i].name () == working[j].name ()) + { + sz -= 1; + working[j] = working[sz]; // pack the array. + break; + } + // Doesn't generate error when we want to delete an + // imaginary property. Is this appropriate? + } + + if (modify != 0) + { + // This is also stupid. + // Go thru every property we want to modify/add + for (size_t i = 0; i < modify->size () && sz > 0; i++) + { + // For each property, go thru our property list + // and search for the matching property + for (size_t j = 0; j < sz; j++) + if ((*modify)[i].name () == working[j].name ()) + { + // A match found. + working[j].value ((*modify)[i].value ().fast_rep ()); + break; + } + + // No matching property name were found, + // We want to add this property into the list. + if (j == sz) + working[sz++] = (*modify)[i]; + } + } + } + + // Yes, all operations passed. We can now copy the working version back. + item->offer_->url_properties (ACE_URL_Property_Seq (sz)); + for (size_t i = 0; i < sz; i ++) + item->offer_->url_properties ()[i] = working[i]; + + if (url != 0) + item->offer_->url (url->fast_rep ()); // replace URL location. + return 0; + } + errno = ACE_URL_Locator::NO_SUCH_OFFER; + return -1; +} + +#endif /* ACE_LOCAL_LOCATOR_C */ diff --git a/ACE/apps/JAWS/clients/Caching/Local_Locator.h b/ACE/apps/JAWS/clients/Caching/Local_Locator.h new file mode 100644 index 00000000000..38f25d1cab5 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/Local_Locator.h @@ -0,0 +1,119 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// none +// +// = FILENAME +// Local_Locator.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_LOCAL_LOCATOR_H +#define ACE_LOCAL_LOCATOR_H + +#include "URL_Locator.h" +#include "ace/Containers.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ID_Generator.h" + +class ACE_Svc_Export ACE_URL_Record + // = TITLE + // A URL Record. + // + // = DESCRIPTION + // A record placed in URL repository. Notice that + // both member pointers are own by URL_Record. + // They will get deallocated when the object goes + // out of scope. +{ + friend class ACE_URL_Local_Locator; + friend class ACE_Node<ACE_URL_Record>; + // We are making ACE_Node as friend class because we don't want + // others to access default constructor and pushing in an invalid + // record. However, container classes need to use default constructor + // for its head record. +public: + ACE_URL_Record (ACE_URL_Offer *offer); + // ctor. + + ~ACE_URL_Record (void); + // dtor. + + /// Two records are equal if they have the same offer id. + bool operator== (const ACE_URL_Record &rhs) const; + + /// Unequal, complement of equal. + bool operator!= (const ACE_URL_Record &rhs) const; + + +private: + ACE_URL_Record (void); + // Default ctor. This is put here to prevent users from + // pushing in an invalid record. + + ACE_WString *id_; + // Offer ID in the repository. + + ACE_URL_Offer *offer_; + // Offer (and its properties). +}; + +class ACE_Svc_Export ACE_URL_Local_Locator + // = TITLE + // A simple URL repository to store URL offer locally. + // + // = DESCRIPTION + // This class manage a collection of URL offers + // for local query and registration. But we should + // really use it within a server. +{ + virtual ~ACE_URL_Local_Locator (void); + // Default destructor. + + virtual int url_query (const ACE_URL_Locator::ACE_Selection_Criteria how, + const ACE_URL_Property_Seq *pseq, + const size_t how_many, + size_t &num_query, + ACE_URL_Offer_Seq *offer); + // Query the locator for HTTP with designate properties (none, some, + // or all). The locator being queried will return a sequence of + // offers with <how_many> offers in it. This interface allocates + // <offer> so users must deallocate it after use. + + virtual int export_offer (ACE_URL_Offer *offer, + ACE_WString &offer_id); + // Export an offer to the locator. + + virtual int withdraw_offer (const ACE_WString &offer_id); + // Withdraw an offer. return 0 if succeed, -1 otherwise. + + virtual int describe_offer (const ACE_WString &offer_id, + ACE_URL_Offer *offer); + // Query a specific offer. + + virtual int modify_offer (const ACE_WString &offer_id, + const ACE_WString *url = 0, + const ACE_URL_Property_Seq *del = 0, + const ACE_URL_Property_Seq *modify = 0); + // Modify a previously registered offer. + +protected: + ACE_Unbounded_Set<ACE_URL_Record> repository_; +}; + +#if defined (__ACE_INLINE__) +#include "Local_Locator.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_LOCAL_LOCATOR_H */ diff --git a/ACE/apps/JAWS/clients/Caching/Local_Locator.inl b/ACE/apps/JAWS/clients/Caching/Local_Locator.inl new file mode 100644 index 00000000000..0ef8e595f86 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/Local_Locator.inl @@ -0,0 +1,43 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE +ACE_URL_Record::ACE_URL_Record (void) + : id_ (0), + offer_ (0) +{ +} + +ACE_INLINE +ACE_URL_Record::ACE_URL_Record (ACE_URL_Offer *offer) + : offer_ (offer) +{ + char buf[ACE_OFFER_ID_LENGTH]; + + ACE_NEW (this->id_, ACE_WString (ACE_ID_Generator::get_new_id (buf))); +} + +ACE_INLINE +ACE_URL_Record::~ACE_URL_Record (void) +{ + delete this->id_; + delete this->offer_; +} + +ACE_INLINE bool +ACE_URL_Record::operator== (const ACE_URL_Record &rhs) const +{ + return this == &rhs || *this->id_ == *rhs.id_; +} + +ACE_INLINE bool +ACE_URL_Record::operator!= (const ACE_URL_Record &rhs) const +{ + return !(*this == rhs); +} + +ACE_INLINE +ACE_URL_Local_Locator::~ACE_URL_Local_Locator (void) +{ +} diff --git a/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.cpp b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.cpp new file mode 100644 index 00000000000..6c3f052aedc --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.cpp @@ -0,0 +1,459 @@ +// $Id$ + +#if !defined (ACE_LOCATOR_REQUEST_REPLY_C) +#define ACE_LOCATOR_REQUEST_REPLY_C + +#include "Locator_Request_Reply.h" + +#if !defined (__ACE_INLINE__) +#include "Locator_Request_Reply.inl" +#endif + +#include "ace/Auto_Ptr.h" +#include "URL_Properties.h" +#include "URL_Array_Helper.h" +#include "URL_Locator.h" + +ACE_RCSID(Caching, Locator_Request_Reply, "$Id$") + +int +ACE_URL_Locator_Request::url_query (const int how, + const ACE_URL_Property_Seq &pseq, + const int how_many) +{ + ACE_TRACE ("ACE_URL_Locator_Request::url_query"); + + if (how >= ACE_URL_Locator::INVALID_SELECTION) + return -1; + ACE_NEW_RETURN (this->seq1_, ACE_URL_Property_Seq (pseq), -1); + this->how_ = how; + this->how_many_ = how_many; + this->code_ = ACE_URL_Locator::QUERY; + return 0; +} + +int +ACE_URL_Locator_Request::export_offer (const ACE_URL_Offer &offer) +{ + ACE_TRACE ("ACE_URL_Locator_Request::export_offer"); + + ACE_NEW_RETURN (this->offer_, ACE_URL_Offer (offer), -1); + this->code_ = ACE_URL_Locator::EXPORT; + return 0; +} + +int +ACE_URL_Locator_Request::withdraw_offer (const ACE_WString &offer_id) +{ + ACE_TRACE ("ACE_URL_Locator_Request::withdraw_offer"); + + this->id_ = offer_id; + this->code_ = ACE_URL_Locator::WITHDRAW; + return 0; +} + +int +ACE_URL_Locator_Request::describe_offer (const ACE_WString &offer_id) +{ + ACE_TRACE ("ACE_URL_Locator_Request::describe_offer"); + + this->id_ = offer_id; + this->code_ = ACE_URL_Locator::DESCRIBE; + return 0; +} + +int +ACE_URL_Locator_Request::modify_offer (const ACE_WString &offer_id, + const ACE_WString *url, + const ACE_URL_Property_Seq &del, + const ACE_URL_Property_Seq &modify) +{ + ACE_TRACE ("ACE_URL_Locator_Request::modify_offer"); + + ACE_NEW_RETURN (this->seq1_, ACE_URL_Property_Seq (del), -1); + ACE_NEW_RETURN (this->seq2_, ACE_URL_Property_Seq (modify), -1); + + if (url != 0) + this->url_ = *url; + + this->id_ = offer_id; + this->code_ = ACE_URL_Locator::MODIFY; + return 0; +} + +#define ENCODE_UINT32(ADDR,LEN,V) \ + * (ACE_UINT32 *) (ADDR+LEN) = htonl (V); \ + LEN += sizeof (ACE_UINT32); + +#define DECODE_UINT32(ADDR,LEN,V) \ + V = ntohl (* (ACE_UINT32 *) (ADDR+LEN)); \ + LEN += sizeof (ACE_UINT32); + +size_t +ACE_URL_Locator_Request::encode (void) +{ + ACE_TRACE ("ACE_URL_Locator_Request::encode"); + + size_t buf_size = this->size (); + size_t total_length = 0; + + ACE_NEW_RETURN (this->buffer_, char [buf_size], 0); + + ENCODE_UINT32 (this->buffer_, total_length, buf_size); + // Encode buffer size. + + ENCODE_UINT32 (this->buffer_, total_length, this->code_); + // Encode Op code. + + ENCODE_UINT32 (this->buffer_, total_length, this->how_); + // Encode selection criteria. + + ENCODE_UINT32 (this->buffer_, total_length, this->how_many_); + // Encode number of offers interested. + + ENCODE_UINT32 (this->buffer_, total_length, this->valid_ptr_); + // Encode valide pointer flag. + + if (this->seq1_ != 0) + { + ENCODE_UINT32 (this->buffer_, total_length, this->seq1_->size ()); + total_length += ace_array_encode (this->buffer_ + total_length, *this->seq1_); + } + if (this->seq2_ != 0) + { + ENCODE_UINT32 (this->buffer_, total_length, this->seq2_->size ()); + total_length += ace_array_encode (this->buffer_ + total_length, *this->seq2_); + } + if (this->offer_ != 0) + total_length += this->offer_->encode (this->buffer_ + total_length); + + total_length += ACE_WString_Helper::encode (this->buffer_ + total_length, + this->id_); + total_length += ACE_WString_Helper::encode (this->buffer_ + total_length, + this->url_); + + ACE_ASSERT (total_length == buf_size); + return total_length; +} + +size_t +ACE_URL_Locator_Request::decode (void *buffer) +{ + ACE_TRACE ("ACE_URL_Locator_Request::decode"); + + if (buffer == 0) + return 0; + // Check if we have a valid buffer available. + + char *cbuffer = (char *) buffer; + + size_t buf_size; + size_t total_length = 0; + + DECODE_UINT32 (cbuffer, total_length, buf_size); + // Decode length of buffer size first. + + DECODE_UINT32 (cbuffer, total_length, this->code_); + // Get the operation code. + + DECODE_UINT32 (cbuffer, total_length, this->how_); + // Decode selection criteria. + + DECODE_UINT32 (cbuffer, total_length, this->how_many_); + // Decode number of offers interested. + + DECODE_UINT32 (cbuffer, total_length, this->valid_ptr_); + // Decode valide pointer flag. + + if ((this->valid_ptr_ & VALID_SEQ1) != 0) + { + size_t n; + DECODE_UINT32 (cbuffer, total_length, n); + ACE_NEW_RETURN (this->seq1_, ACE_URL_Property_Seq (n), 0); + total_length += ace_array_decode (cbuffer + total_length, *this->seq1_); + } + if ((this->valid_ptr_ & VALID_SEQ2) != 0) + { + size_t n; + DECODE_UINT32 (cbuffer, total_length, n); + ACE_NEW_RETURN (this->seq2_, ACE_URL_Property_Seq (n), 0); + total_length += ace_array_decode (cbuffer + total_length, *this->seq2_); + } + if ((this->valid_ptr_ & VALID_OFFER) != 0) + { + ACE_NEW_RETURN (this->offer_, ACE_URL_Offer, 0); + total_length += this->offer_->decode (cbuffer + total_length); + } + + this->id_ = ACE_WString ((ACE_USHORT16 *) (cbuffer + total_length)); + total_length += ACE_WString_Helper::decode (cbuffer + total_length); + this->url_ = ACE_WString ((ACE_USHORT16 *) (cbuffer + total_length)); + total_length += ACE_WString_Helper::decode (cbuffer + total_length); + + ACE_ASSERT (total_length == buf_size); + return total_length; +} + + +size_t +ACE_URL_Locator_Request::size (void) +{ + ACE_TRACE ("ACE_URL_Locator_Request::size"); + + size_t total_length = 5 * sizeof (ACE_UINT32); + // There are 5 UINT32 variables at the beginning + // of the buffer. <buffer size>, <code>, <how>, + // <how_many>, <valid_ptr>. + + this->valid_ptr_ = 0; + // Check valid pointers and mark corresponding flag in <valid_prt>. + + if (this->seq1_ != 0) + { + this->valid_ptr_ |= VALID_SEQ1; + total_length += ace_array_size (*this->seq1_); + } + if (this->seq2_ != 0) + { + this->valid_ptr_ |= VALID_SEQ2; + total_length += ace_array_size (*this->seq2_); + } + if (this->offer_ != 0) + { + this->valid_ptr_ |= VALID_OFFER; + total_length += this->offer_->size (); + } + + total_length += ACE_WString_Helper::size (this->id_); + total_length += ACE_WString_Helper::size (this->url_); + + return total_length; +} + +void +ACE_URL_Locator_Request::dump (void) const +{ + //ACE_TRACE ("ACE_URL_Locator_Request::dump"); + + size_t i; + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + if (this->code_ < ACE_URL_Locator::INVALID_OPERATION) + ACE_DEBUG ((LM_DEBUG, "%s Request:\n", ACE_URL_Locator::opname[this->code_])); + else + ACE_DEBUG ((LM_DEBUG, "Invalid Operation: %d\n", this->code_)); + + if (this->how_ < ACE_URL_Locator::INVALID_SELECTION) + ACE_DEBUG ((LM_DEBUG, "Select: %s\n", ACE_URL_Locator::selection_name[this->how_])); + else + ACE_DEBUG ((LM_DEBUG, "Invalid selection method: %d\n", this->how_)); + + ACE_DEBUG ((LM_DEBUG, "At most %d reply.\n", this->how_many_)); + + ACE_DEBUG ((LM_DEBUG, "Valid pointer pattern: %x\n", this->valid_ptr_)); + + ACE_DEBUG ((LM_DEBUG, "Property sequence 1: %x\n", this->seq1_)); + if (this->seq1_ != 0) + for (i = 0; i < this->seq1_->size (); i++) + (*this->seq1_)[i].dump (); + + ACE_DEBUG ((LM_DEBUG, "Property sequence 2: %x\n", this->seq2_)); + if (this->seq2_ != 0) + for (i = 0; i < this->seq2_->size (); i++) + (*this->seq2_)[i].dump(); + + ACE_DEBUG ((LM_DEBUG, "Offer: %x\n", this->offer_)); + if (this->offer_ != 0) + this->offer_->dump (); + + if (this->id_.length () > 0) + ACE_DEBUG ((LM_DEBUG, "Offer ID: %s\n", + ACE_Auto_Basic_Array_Ptr<char> (this->id_.char_rep ()).get ())); + else + ACE_DEBUG ((LM_DEBUG, "Offer ID: \"\"\n")); + + if (this->url_.length () > 0) + ACE_DEBUG ((LM_DEBUG, "URL: %s\n", + ACE_Auto_Basic_Array_Ptr<char> (this->url_.char_rep ()).get ())); + else + ACE_DEBUG ((LM_DEBUG, "URL: \"\"\n")); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_URL_Locator_Reply::status_reply (u_int op, int result) +{ + ACE_TRACE ("ACE_URL_Locator_Reply::status_reply"); + + this->code_ = op; + this->status_ = result; + return 0; +} + +int +ACE_URL_Locator_Reply::query_reply (int result, size_t num, + const ACE_URL_Offer_Seq &offers) +{ + ACE_TRACE ("ACE_URL_Locator_Reply::query_reply"); + + this->code_ = ACE_URL_Locator::QUERY; + this->status_ = result; + ACE_NEW_RETURN (this->offers_, ACE_URL_Offer_Seq (offers), -1); + return 0; +} + +int +ACE_URL_Locator_Reply::describe_reply (int result, + const ACE_URL_Offer &offer) +{ + ACE_TRACE ("ACE_URL_Locator_Reply::describe_reply"); + + this->code_ = ACE_URL_Locator::DESCRIBE; + this->status_ = result; + ACE_NEW_RETURN (this->offer_, ACE_URL_Offer (offer), -1); + return 0; +} + +size_t +ACE_URL_Locator_Reply::encode (void) +{ + ACE_TRACE ("ACE_URL_Locator_Reply::encode"); + + size_t buf_size = this->size (); + size_t total_length = 0; + + ACE_NEW_RETURN (this->buffer_, char [buf_size], 0); + + ENCODE_UINT32 (this->buffer_, total_length, buf_size); + // Encode buffer size. + + ENCODE_UINT32 (this->buffer_, total_length, this->code_); + // Encode Op code. + + ENCODE_UINT32 (this->buffer_, total_length, this->status_); + // Encode Op result status. + + ENCODE_UINT32 (this->buffer_, total_length, this->num_offers_); + // Encode number of offers in this->offers_. + + ENCODE_UINT32 (this->buffer_, total_length, this->valid_ptr_); + // Encode valid pointers mask. + + if (this->offer_ != 0) + total_length += this->offer_->encode (this->buffer_ + total_length); + + if (this->offers_ != 0) + { + ENCODE_UINT32 (this->buffer_, total_length, this->offers_->size ()); + total_length += ace_array_encode (this->buffer_ + total_length, *this->offers_); + } + + ACE_ASSERT (total_length == buf_size); + return 0; +} + +size_t +ACE_URL_Locator_Reply::decode (void *buffer) +{ + ACE_TRACE ("ACE_URL_Locator_Reply::decode"); + + if (buffer == 0) + return 0; + // Check if we have a buffer available. + + char *cbuffer = (char *) buffer; + + size_t buf_size; + size_t total_length = 0; + + DECODE_UINT32 (cbuffer, total_length, buf_size); + // Get the length of the buffer first. + + DECODE_UINT32 (cbuffer, total_length, this->code_); + // Decode Op code. + + DECODE_UINT32 (cbuffer, total_length, this->status_); + // Decode Op result status. + + DECODE_UINT32 (cbuffer, total_length, this->num_offers_); + // Decode number of offers in this->offers_. + + DECODE_UINT32 (cbuffer, total_length, this->valid_ptr_); + // Decode valid pointers mask. + + if ((this->valid_ptr_ & VALID_OFFER) != 0) + { + ACE_NEW_RETURN (this->offer_, ACE_URL_Offer, 0); + total_length += this->offer_->decode (cbuffer + total_length); + } + + if ((this->valid_ptr_ & VALID_OFFERS) != 0) + { + size_t n; + DECODE_UINT32 (cbuffer, total_length, n); + ACE_NEW_RETURN (this->offers_, ACE_URL_Offer_Seq (n), 0); + total_length += ace_array_decode (cbuffer + total_length, *this->offers_); + } + + ACE_ASSERT (total_length ==buf_size); + return 0; +} + +size_t +ACE_URL_Locator_Reply::size (void) +{ + ACE_TRACE ("ACE_URL_Locator_Reply:size"); + + size_t total_length = 5 * sizeof (ACE_UINT32); + // size for 5 ACE_UINT32 objects: <buffer size>, <code_>, + // <status_>, <num_offers_>, and <valid_ptr_>. + + this->valid_ptr_ = 0; + if (this->offer_ != 0) + { + this->valid_ptr_ |= VALID_OFFER; + total_length += this->offer_->size (); + } + if (this->offers_ != 0) + { + this->valid_ptr_ |= VALID_OFFERS; + total_length += ace_array_size (*this->offers_); + } + return total_length; +} + +void +ACE_URL_Locator_Reply::dump (void) const +{ + //ACE_TRACE ("ACE_URL_Locator_Reply::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + if (this->code_ < ACE_URL_Locator::INVALID_OPERATION) + ACE_DEBUG ((LM_DEBUG, "Original request: %s\n", ACE_URL_Locator::opname[this->code_])); + else + ACE_DEBUG ((LM_DEBUG, "Invalid Original Request: %d\n", this->code_)); + + if (this->status_ < ACE_URL_Locator::MAX_URL_ERROR) + ACE_DEBUG ((LM_DEBUG, "Reply status: %s\n", ACE_URL_Locator::err_name[this->status_])); + else + ACE_DEBUG ((LM_DEBUG, "Invalid reply status: %d\n", this->status_)); + + ACE_DEBUG ((LM_DEBUG, "Number of offers: %d\n", this->num_offers_)); + + ACE_DEBUG ((LM_DEBUG, "Valid pointer pattern: %x\n", this->valid_ptr_)); + + ACE_DEBUG ((LM_DEBUG, "Offer: %x\n", this->offer_)); + if (this->offer_ != 0) + this->offer_->dump (); + + ACE_DEBUG ((LM_DEBUG, "Offer sequence: %x\n", this->offers_)); + if (this->offers_ != 0) + for (size_t i = 0; i < this->offers_->size (); i++) + (*this->offers_)[i].dump(); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} +#endif /* ACE_LOCATOR_REQUEST_REPLY_C */ diff --git a/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.h b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.h new file mode 100644 index 00000000000..a4e6e5f993a --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.h @@ -0,0 +1,220 @@ +/* -*- C++ -*- */ + +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// none +// +// = FILENAME +// Locator_Request_Response.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_LOCATOR_REQUEST_REPLY_H +#define ACE_LOCATOR_REQUEST_REPLY_H + +#include "URL_Properties.h" + +class ACE_Svc_Export ACE_URL_Locator_Request + // = TITLE + // A URL request message formater/wrapper. + // + // = DESCRIPTION + // This class defines a URL request data. It is used + // to transform requests to an object so that we can + // ship them across network. +{ +public: + ACE_URL_Locator_Request (void); + // Default ctor. + + ~ACE_URL_Locator_Request (void); + // Default dtor. + + int url_query (const int how, + const ACE_URL_Property_Seq &pseq, + const int how_many); + // Query the locator for HTTP with designate properties (none, some, + // or all). The locator being queried will return a sequence of + // offers with <how_many> offers in it. This interface allocates + // <offer> so users must deallocate it after use. + + int export_offer (const ACE_URL_Offer &offer); + // Export an offer to the locator. + + int withdraw_offer (const ACE_WString &offer_id); + // Withdraw an offer. return 0 if succeed, -1 otherwise. + + int describe_offer (const ACE_WString &offer_id); + // Query a specific offer. + + int modify_offer (const ACE_WString &offer_id, + const char *url = 0, + const ACE_URL_Property_Seq &del = 0, + const ACE_URL_Property_Seq &modify = 0); + // Modify a previously registered offer. + + int modify_offer (const ACE_WString &offer_id, + const ACE_WString *url = 0, + const ACE_URL_Property_Seq &del = 0, + const ACE_URL_Property_Seq &modify = 0); + // Modify a previously registered offer. + + size_t encode (void); + // Encode request for network communication. If succeed, + // returns the size of the buffer, otherwise, return 0. + + size_t decode (void *buffer); + // Restore from network data. Returns size of the buffer + // if succeed, 0 otherwise. When passing in a buffer, + // caller must take the responsibility to delete the buffer + // afterward, if so needed. + + const int how (void) const; + const int how_many (void) const; + const u_int opcode (void) const; + const ACE_URL_Property_Seq *seq (void) const; + const ACE_URL_Property_Seq *del (void) const; + const ACE_URL_Property_Seq *modify (void) const; + const ACE_URL_Offer *offer (void) const; + const ACE_WString &id (void) const; + const ACE_WString &url (void) const; + const char *buffer (void) const; + // A bunch of methods to access internal data. + + void dump (void) const; + // Print out this object. + +protected: + size_t size (void); + // Return the size of the buffer required to encode + // this request. + + enum { + VALID_SEQ1 = 0x1, + VALID_SEQ2 = 0X2, + VALID_OFFER = 0X4 + }; + // These constants used to indicate which pointers are valid. + + u_int code_; + // Request type code. + + int how_; + // Query method (if code_ == QUERY.) + + int how_many_; + // How many offers are we interested in in this query. + + int valid_ptr_; + // Bit flag to mark valid pointers within this object. + + ACE_URL_Property_Seq *seq1_; + // For query or del in modify_offer. + + ACE_URL_Property_Seq *seq2_; + // For modify seq. in modify_offer. + + ACE_URL_Offer *offer_; + // Offer to export. + + ACE_WString id_; + // Offer ID. + + ACE_WString url_; + // URL of this offer. + + char *buffer_; + // Buffer to store encoded data. +}; + +class ACE_Svc_Export ACE_URL_Locator_Reply + // = TITLE + // A URL reply message formater/wrapper. + // + // = DESCRIPTION + // This class defines a URL reply data. It is used + // to transform reply messages to an object so that we can + // ship them across network. +{ +public: + ACE_URL_Locator_Reply (void); + // Default ctor. + + ~ACE_URL_Locator_Reply (void); + // Default dtor. + + int status_reply (u_int op, int result); + // Setup a reply message for EXPORT, WITHDRAW, or MODIFY operations. + + int query_reply (int result, size_t num, + const ACE_URL_Offer_Seq &offers); + // Setup a reply for QUERY operation. + + int describe_reply (int result, + const ACE_URL_Offer &offer); + // Construct a reply for DESCRIBE operation. + + size_t encode (void); + // Encode request for network communication. If succeed, + // returns the size of the buffer, otherwise, return 0. + + size_t decode (void *buffer); + // Restore from network data. Returns size of the buffer + // if succeed, 0 otherwise. When passing in a buffer, + // caller must take the responsibility to delete the buffer + // afterward, if so needed. + + // Accessor function. + const size_t num_offers (void) const; + const ACE_URL_Offer *offer (void) const; + const ACE_URL_Offer_Seq *offers (void) const; + const u_int opcode (void) const; + const u_int status (void) const; + const char *buffer (void) const ; + + void dump (void) const ; + // Print out this object. + +protected: + size_t size (void); + // Return the size of the buffer required to encode + // this request. + + enum { + VALID_OFFER = 0x1, + VALID_OFFERS = 0x2 + }; + // Valid pointer masks. + + u_int code_; + // Holds the original op code. + + int status_; + // Holds the result of an operation from the Location Server. + + size_t num_offers_; + // Holds the number of valid offers in the offers_ sequence. + + int valid_ptr_; + // Flag that marks valid internal pointers. + + ACE_URL_Offer *offer_; + // Holds a single offer. Used in query offer property. + + ACE_URL_Offer_Seq *offers_; + // Holds the replying offer sequence from a Locator. + + char *buffer_; + // Buffer to store encoded data. +}; +#if defined (__ACE_INLINE__) +#include "Locator_Request_Reply.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_LOCATOR_REQUEST_REPLY_H */ diff --git a/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.inl b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.inl new file mode 100644 index 00000000000..9dd2f851ceb --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.inl @@ -0,0 +1,138 @@ +/* -*- C++ -*- */ + +// $Id$ + +#include "URL_Locator.h" + +ACE_INLINE +ACE_URL_Locator_Request::ACE_URL_Locator_Request (void) + : code_(ACE_URL_Locator::INVALID_OPERATION), + seq1_ (0), + seq2_ (0), + offer_ (0), + buffer_ (0) +{ +} + +ACE_INLINE +ACE_URL_Locator_Request::~ACE_URL_Locator_Request (void) +{ + delete this->seq1_; + delete this->seq2_; + delete this->offer_; + delete [] this->buffer_; +} + +ACE_INLINE const int +ACE_URL_Locator_Request::how (void) const +{ + return this-> how_; +} + +ACE_INLINE const int +ACE_URL_Locator_Request::how_many (void) const +{ + return this->how_many_; +} + +ACE_INLINE const u_int +ACE_URL_Locator_Request::opcode (void) const +{ + return this->code_; +} + +ACE_INLINE const ACE_URL_Property_Seq * +ACE_URL_Locator_Request::seq (void) const +{ + return this->seq1_; +} + +ACE_INLINE const ACE_URL_Property_Seq * +ACE_URL_Locator_Request::del (void) const +{ + return this->seq1_; +} + +ACE_INLINE const ACE_URL_Property_Seq * +ACE_URL_Locator_Request::modify (void) const +{ + return this->seq2_; +} + +ACE_INLINE const ACE_URL_Offer * +ACE_URL_Locator_Request::offer (void) const +{ + return this->offer_; +} + +ACE_INLINE const ACE_WString & +ACE_URL_Locator_Request::id (void) const +{ + return this->id_; +} + +ACE_INLINE const ACE_WString & +ACE_URL_Locator_Request::url (void) const +{ + return this->url_; +} + +ACE_INLINE const char * +ACE_URL_Locator_Request::buffer (void) const +{ + return this->buffer_; +} + +ACE_INLINE +ACE_URL_Locator_Reply::ACE_URL_Locator_Reply (void) + : code_ (ACE_URL_Locator::INVALID_OPERATION), + offer_ (0), + offers_ (0), + buffer_ (0) +{ +} + +ACE_INLINE +ACE_URL_Locator_Reply::~ACE_URL_Locator_Reply (void) +{ + delete this->offer_; + delete this->offers_; + delete [] this->buffer_; +} + +ACE_INLINE const size_t +ACE_URL_Locator_Reply::num_offers (void) const +{ + return this->num_offers_; +} + + +ACE_INLINE const ACE_URL_Offer * +ACE_URL_Locator_Reply::offer (void) const +{ + return this->offer_; +} + +ACE_INLINE const ACE_URL_Offer_Seq * +ACE_URL_Locator_Reply::offers (void) const +{ + return this->offers_; +} + +ACE_INLINE const u_int +ACE_URL_Locator_Reply::opcode (void) const +{ + return this->code_; +} + +ACE_INLINE const u_int +ACE_URL_Locator_Reply::status (void) const +{ + return this->status_; +} + +ACE_INLINE const char * +ACE_URL_Locator_Reply::buffer (void) const +{ + return this->buffer_; +} diff --git a/ACE/apps/JAWS/clients/Caching/Makefile.am b/ACE/apps/JAWS/clients/Caching/Makefile.am new file mode 100644 index 00000000000..fa89230d919 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/Makefile.am @@ -0,0 +1,46 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.http_client.am + +if BUILD_ACE_FILECACHE +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS = http_client + +http_client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +http_client_SOURCES = \ + http_client.cpp \ + http_handler.cpp \ + Local_Locator.inl \ + Locator_Request_Reply.inl \ + URL_Properties.inl \ + http_handler.h + +http_client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_ACE_FILECACHE + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/apps/JAWS/clients/Caching/README b/ACE/apps/JAWS/clients/Caching/README new file mode 100644 index 00000000000..3dcfcd32815 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/README @@ -0,0 +1,83 @@ +# -*- text -*- +# Hey, Emacs! This is a TEXT file. + +---------------------------------- +README for the caching http_client +---------------------------------- + +This is the README file for the simple caching http_client. + +------------ +1. Compiling +------------ + +1a. Compiling on UNIX. + + On UNIX, with a properly configured ACE distribution, just +type make (using GNU make, of course). + +1b. Compiling on NT. + + Thus far, this code has only been tested under UNIX. A +Windows NT version will be out soon. + +------------ +2. Executing +------------ + +2a. Command line parameters. + + The program does not support any command line parameters. + +2b. General information. + + When the program runs, the client offers a ``*'' as a prompt. +At the prompt, you may enter a URL. The client will check to see if +the filename portion of the URL has already been cached. If so, a +message appears saying so. If not, the client will fetch the file +from the HTTP server and then cache it. + + Furthermore, the client supports the ``!'' shell escape +command. The content after the ``!'' will be executed by a shell. + + To exit the session, send the end-of-file character +(typically, ^D in UNIX). + + unix$ ./http_client + * http://www.cs.wustl.edu/cs/Art/brookings.gif + [1] sending request -- + GET /cs/Art/brookings.gif HTTP/1.0 + Accept: HTTP/1.0 + + ``brookings.gif'' is now cached. + * http://www.cs.wustl.edu/cs/Art/brookings.gif + ``brookings.gif'' is already cached. + * !ls + Makefile http_client http_handler.cpp zJAWSAAAa000Yg + brookings.gif http_client.cpp http_handler.h + * ^D + Bye! + unix$ ls + Makefile http_client http_handler.cpp + brookings.gif http_client.cpp http_handler.h + unix$ + +-------------- +3. Limitations +-------------- + + The caching mechanism as currently implemented requires a +``Content-length:'' to appear in the response header of the HTTP +response. This is because the caching utilizes mmap () to allocate +space for the file to be cached before the file is received. Unitl +the caching mecahnism is extended, you are limited to using servers +which will report the size of the file being transmitted. + + Currently, the cache creates temporary files (see the above +sample execution). + + The cache is not persistent between executions. + + Suggestions and other correspondence should be sent to me: + +James Hu <jxh@cs.wustl.edu> diff --git a/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.cpp b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.cpp new file mode 100644 index 00000000000..c8dbb55e197 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.cpp @@ -0,0 +1,43 @@ +// $Id$ + +// URL_Array_Helper.cpp + +#ifndef ACE_URL_ARRAY_HELPER_C +#define ACE_URL_ARRAY_HELPER_C + +#include "URL_Array_Helper.h" + +ACE_RCSID(Caching, URL_Array_Helper, "$Id$") + +// Some helper functions for encoding/decoding + +template <class T> +size_t ace_array_size (const T &x) +{ + size_t sum = sizeof (ACE_UINT32); + for (size_t i = 0; i < x.size (); i++) + sum += x[i].size (); + return sum; +} + +template <class T> +size_t ace_array_encode (void *buf, const T &x) +{ + size_t len = 0; + for (size_t i = 0; i < x.size (); i++) + len+= x[i].encode ((void *) ((char *) buf + len)); + return len ; +} + +template <class T> +size_t ace_array_decode (void *buf, T &x) +{ + size_t len = 0; + for (size_t i = 0; i < x.size (); i++) + len += x[i].decode ((void *) ((char *) buf + len)); + return len; +} + + + +#endif /* ACE_URL_ARRAY_HELPER_C */ diff --git a/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.h b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.h new file mode 100644 index 00000000000..f38f9ebf5dd --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.h @@ -0,0 +1,40 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// none +// +// = FILENAME +// URL_Array_Helper.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_URL_ARRAY_HELPER_H +#define ACE_URL_ARRAY_HELPER_H + +// ### These template functions are probably named improperly. +// You should find some way to avoid name space polution. + +template <class T> +size_t ace_array_size (const T &x); + +template <class T> +size_t ace_array_encode (void *buf, const T &x); + +template <class T> +size_t ace_array_decode (void *buf, T &x); + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "URL_Array_Helper.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("URL_Array_Helper.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_URL_ARRAY_HELPER_H */ diff --git a/ACE/apps/JAWS/clients/Caching/URL_Locator.cpp b/ACE/apps/JAWS/clients/Caching/URL_Locator.cpp new file mode 100644 index 00000000000..e7f6fb6c05b --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/URL_Locator.cpp @@ -0,0 +1,52 @@ +// $Id$ + +#if !defined (ACE_URL_LOCATOR_C) +#define ACE_URL_LOCATOR_C + +#include "URL_Locator.h" + +ACE_RCSID(Caching, URL_Locator, "$Id$") + +const char * const +ACE_URL_Locator::opname[] = +// Human readable operation name +{ + "Query", + "Export", + "Withdraw", + "Describe", + "Modify", + "Invalid Operation" +}; + +const char * const +ACE_URL_Locator::selection_name[] = +{ + "None", + "Some", + "All", + "Invalid Selection" +}; + +const char * const +ACE_URL_Locator::err_name[] = +{ + "No error", + "Offer already exist", + "no such offer", + "invalid argument", + "function not implemented", + "unknown error" +}; + +ACE_URL_Locator::~ACE_URL_Locator (void) +{ +} + +const char * +ACE_URL_Locator::error_status (void) +{ + return "Not implemented yet."; +} + +#endif /* ACE_URL_LOCATOR_C */ diff --git a/ACE/apps/JAWS/clients/Caching/URL_Locator.h b/ACE/apps/JAWS/clients/Caching/URL_Locator.h new file mode 100644 index 00000000000..751de52cfe5 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/URL_Locator.h @@ -0,0 +1,112 @@ +/* -*- C++ -*- */ + +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// none +// +// = FILENAME +// URL_Locator.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_URL_LOCATOR_H +#define ACE_URL_LOCATOR_H + +#include "URL_Properties.h" + +class ACE_Svc_Export ACE_URL_Locator + // = TITLE + // Abstract Base class designates what interfaces a URL_Locator + // should provide. + // + // = DESCRIPTION + // This class defines the basic URL_Locator APIs. + // An URL locator provides services for URL clients to + // query specific URL location that has certain properties + // and URL providers to export their services and a set of + // APIs to maintain their offers. +{ +public: + // Request type + enum ACE_URL_Locator_Op_Type + { + QUERY = 0, + EXPORT, + WITHDRAW, + DESCRIBE, + MODIFY, + INVALID_OPERATION // LAST + }; + + static const char * const opname[]; + // Human Readable operation name. + + // = Specify how to select offers. + enum ACE_Selection_Criteria + { + NONE = 0, // URL that contains none of the properties. + SOME, // URL that contains some of the properties. + ALL, // URL that contains all of the properties. + INVALID_SELECTION // Invalid. + }; + + static const char * const selection_name[]; + + enum ACE_URL_Locator_Error + // errno will set to one of these value. + { + OK, // Everything is fine. + OFFER_EXIST, // trying to register an offer. + // that is already exist in repository. + NO_SUCH_OFFER, // No such offer in the repository. + INVALID_ARGUMENT, // Invalid argument encountered. + UNIMPLEMENTED, // function not implemented. + UNKNOWN, // Unknown error. + MAX_URL_ERROR + }; + // Possible error code of URL_Locator. + + static const char * const err_name[]; + // Human readable error status. + + virtual ~ACE_URL_Locator (void) = 0; + // Default destructor. + + virtual int url_query (const ACE_Selection_Criteria how, + const ACE_URL_Property_Seq *pseq, + const size_t how_many, + size_t &num_query, + ACE_URL_Offer_Seq *offer) = 0; + // Query the locator for HTTP with designate properties (none, some, + // or all). The locator being queried will return a sequence of + // offers with <how_many> offers in it. This interface allocates + // <offer> so users must deallocate it after use. + + virtual int export_offer (ACE_URL_Offer *offer, + ACE_WString &offer_id) = 0; + // Export an offer to the locator. + + virtual int withdraw_offer (const ACE_WString &offer_id) = 0; + // Withdraw an offer. return 0 if succeed, -1 otherwise. + + virtual int describe_offer (const ACE_WString &offer_id, + ACE_URL_Offer *offer) = 0; + // Query a specific offer. + + virtual int modify_offer (const ACE_WString &offer_id, + const ACE_WString *url = 0, + const ACE_URL_Property_Seq *del = 0, + const ACE_URL_Property_Seq *modify = 0) = 0; + // Modify a previously registered offer. + + virtual const char *error_status (void); + // Provide a human readable error status. +}; + +#endif /* ACE_WEB_LOCATOR_H */ diff --git a/ACE/apps/JAWS/clients/Caching/URL_Properties.cpp b/ACE/apps/JAWS/clients/Caching/URL_Properties.cpp new file mode 100644 index 00000000000..71706d12ee1 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/URL_Properties.cpp @@ -0,0 +1,139 @@ +// $Id$ + +#if !defined (ACE_URL_PROPERTIES_C) +#define ACE_URL_PROPERTIES_C + +#include "URL_Properties.h" + +#if !defined (__ACE_INLINE__) +#include "URL_Properties.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Auto_Ptr.h" +#include "URL_Array_Helper.h" + +ACE_RCSID(Caching, URL_Properties, "$Id$") + +size_t +ACE_WString_Helper::encode (void *buf, const ACE_WString &wstr) +{ + ACE_USHORT16 *wptr = (ACE_USHORT16 *) buf; + size_t i; + + for (i= 0; i <= wstr.length (); i++) + wptr[i] = htons (wstr[i]); + + return i * sizeof (ACE_USHORT16); +} + +size_t +ACE_WString_Helper::decode (void *buf) +{ + ACE_USHORT16 *wptr = (ACE_USHORT16 *) buf; + size_t i; + + for (i = 0; wptr[i] != 0; i++) + wptr[i] = ntohs (wptr[i]); + + return (i + 1) * sizeof (ACE_USHORT16); +} + +size_t +ACE_URL_Property::encode (void *buf) const +{ + size_t blen = ACE_WString_Helper::encode (buf, this->name_); + blen += ACE_WString_Helper::encode ((void *) ((char *) buf + blen), + this->value_); + return blen; +} + +size_t +ACE_URL_Property::decode (void *buf) +{ + char *cbuf = (char *) buf; + size_t len = ACE_WString_Helper::decode(buf); + this->name ((ACE_USHORT16 *) cbuf); + + cbuf += len; + len += ACE_WString_Helper::decode ((void *) cbuf); + this->value ((ACE_USHORT16 *) cbuf); + return len; +} + +void +ACE_URL_Property::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + if (this->name_.length () > 0) + ACE_DEBUG ((LM_DEBUG, "\n name_: \"%s\"\n", + ACE_Auto_Basic_Array_Ptr<char> (this->name_.char_rep ()).get ())); + else + ACE_DEBUG ((LM_DEBUG, "\n name_: \"\"\n")); + + if (this->value_.length () > 0) + ACE_DEBUG ((LM_DEBUG, " value_: \"%s\"\n", + ACE_Auto_Basic_Array_Ptr<char> (this->value_.char_rep ()).get ())); + else + ACE_DEBUG ((LM_DEBUG, " value_: \"\"\n")); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +size_t +ACE_URL_Offer::size (void) const +{ + size_t sum = (this->url_.length () + 1) * sizeof (ACE_USHORT16); + sum += ::ace_array_size (this->prop_); + return sum; +} + +size_t +ACE_URL_Offer::encode (void *buf) const +{ + ACE_UINT32 *s_buf = (ACE_UINT32 *) buf; + *s_buf = htonl (this->prop_.size ()); + + size_t len = sizeof (ACE_UINT32); + len += ACE_WString_Helper::encode ((void *) ((char *) buf + len), + this->url_); + + len += ::ace_array_encode ((void *) ((char *) buf + len), + this->prop_); + return len; +} + +size_t +ACE_URL_Offer::decode (void *buf) +{ + size_t len = sizeof (ACE_UINT32); + size_t a_size = (size_t) ntohl (*(ACE_UINT32 *) buf); + len += ACE_WString_Helper::decode ((void *) ((char *) buf + len)); + this->url ((ACE_USHORT16 *) ((char *) buf + len)); + + ACE_URL_Property_Seq prop_seq (a_size); + this->url_properties (prop_seq); + + len += ::ace_array_decode ((void *)((char *) buf + len), + this->prop_); + return len; +} + +void +ACE_URL_Offer::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + if (this->url_.length () > 0) + ACE_DEBUG ((LM_DEBUG, "\n url_: \"%s\"\n", + ACE_Auto_Basic_Array_Ptr<char> (this->url_.char_rep ()).get ())); + else + ACE_DEBUG ((LM_DEBUG, "\n url_: \"\"\n")); + + for (size_t i = 0; i < this->prop_.size (); i++) + this->prop_[i].dump (); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#endif /* ACE_URL_PROPERTIES_C */ diff --git a/ACE/apps/JAWS/clients/Caching/URL_Properties.h b/ACE/apps/JAWS/clients/Caching/URL_Properties.h new file mode 100644 index 00000000000..a4f63f36b97 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/URL_Properties.h @@ -0,0 +1,201 @@ +// -*- C++ -*- + +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// none +// +// = FILENAME +// URL_Locator.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_URL_PROPERTIES_H +#define ACE_URL_PROPERTIES_H + +#include "ace/SString.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Containers.h" + +class ACE_Svc_Export ACE_WString_Helper + // = TITLE + // Some helper functions for manipulate ACE_WString. + // + // = DESCRIPTION + // These functions simplify encoding/decoding of + // ACE_WString objects for network communication. +{ +public: + static size_t size (const ACE_WString &wstr); + // Returns the actual size (in bytes) required to contain the + // ACE_WString. + + static size_t encode (void *buf, const ACE_WString &wstr); + // Encode <wstr> into <buf> for network communication. + // Return total octets consumed. + + static size_t decode (void *buf); + // This function doesn't relate to ACE_WString directly. + // It converts an ACE_USHORT16 string from network + // byte order to host byte order. Returns size of the string. +}; + +class ACE_Svc_Export ACE_URL_Property + // = TITLE + // Defines a property of a URL. + // + // = DESCRIPTION + // A property contains a <name> and a <value>. + // A URL may contain some properties and we can "locate" + // the URL's we are looking for by examming URL for certain + // properties that match our need. +{ +public: + ACE_URL_Property (const char *name = 0, + const char *value=0); + // Create a new property. + + ACE_URL_Property (const ACE_USHORT16 *name, + const ACE_USHORT16 *value); + // Create a new property using wchar strings. This is mostly used + // to support DBCS or UNICODE. + + ACE_URL_Property (const ACE_URL_Property &p); + // Copy constructor. + + ~ACE_URL_Property (void); + // Destructor. + + ACE_URL_Property &operator= (const ACE_URL_Property &rhs); + // Assignment operator. + + bool operator== (const ACE_URL_Property &rhs) const; + // Equals operator. + + bool operator!= (const ACE_URL_Property &rhs) const; + // Inequality operator. + + // = Query property name. + ACE_WString &name_rep (void); + const ACE_WString &name (void) const; + + // = Set property name. + void name (const ACE_USHORT16 *n); + void name (const char *n); + + // = Query property value. + ACE_WString &value_rep (void); + const ACE_WString &value (void) const; + + // = Set property value. + void value (const ACE_USHORT16 *v); + void value (const char *v); + + // = Helper functions for encoding and decoding. + size_t size (void) const; + // Returns memory size (in bytes) required to encode this object. + + size_t encode (void *buf) const; + // Encodes this object into buf for network transmission. + + size_t decode (void *buf); + // Decodes buf and modifies this object, you should + // probably create this with default ctor. + + void dump (void) const; + // Dump out this object for debug. + +protected: + ACE_WString name_; + // Property name pointer. + + ACE_WString value_; + // Property value. +} ; + +typedef ACE_Array<ACE_URL_Property> ACE_URL_Property_Seq; +// type of URL_Property collections. + +class ACE_Svc_Export ACE_URL_Offer + // = TITLE + // Defines a URL offer. + // + // = DESCRIPTION + // A URL offer is defined by a <url> and an + // <ACE_URL_Property_Seq>. An offer is stored at server end + // thru registering or reported back to querying client from the + // sever. +{ +public: + ACE_URL_Offer (const size_t size = 1, const char *url = 0); + // Create an offer. + + ACE_URL_Offer (const ACE_URL_Offer &o); + // Copy ctor. + + ~ACE_URL_Offer (void); + // Default destructor. + + ACE_URL_Offer &operator= (const ACE_URL_Offer &rhs); + // Assignment operator. + + bool operator== (const ACE_URL_Offer &rhs) const; + // Equality operator. + + bool operator!= (const ACE_URL_Offer &rhs) const; + // Inequality operator. + + // = Get URL string. + ACE_WString &url_rep (void); + const ACE_WString &url (void) const; + + // = Set URL. + void url (const char *url); + void url (const ACE_USHORT16 *url); + + ACE_URL_Property_Seq &url_properties (void); + // Get properties of this offer. + + void url_properties (const ACE_URL_Property_Seq &prop); + // Set properties of this offer. This operation virtually get a + // copy of the passed in prop. + + // = Helper functions for encoding and decoding. + size_t size (void) const; + // Returns memory size (in bytes) required to encode this object. + + size_t encode (void *buf) const; + // Encodes this object into buf for network transmission. + + size_t decode (void *buf); + // Decodes buf into current object, you better use + // the default ctor. + + void dump (void) const; + // Dump this object for debug. + +protected: + ACE_WString url_; + // URL of this offer. + + ACE_URL_Property_Seq prop_; + // Properties associate with this offer. +}; + +typedef ACE_Array<ACE_URL_Offer> ACE_URL_Offer_Seq; +// type of URL offer collections. + +#if defined (__ACE_INLINE__) +#include "URL_Properties.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_WEB_PROPERTIES_H */ diff --git a/ACE/apps/JAWS/clients/Caching/URL_Properties.inl b/ACE/apps/JAWS/clients/Caching/URL_Properties.inl new file mode 100644 index 00000000000..768ad967d94 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/URL_Properties.inl @@ -0,0 +1,203 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE size_t +ACE_WString_Helper::size (const ACE_WString &wstr) +{ + return (wstr.length () + 1) * sizeof (ACE_USHORT16); +} + +ACE_INLINE +ACE_URL_Property::ACE_URL_Property (const char *name, const char *value) + : name_ (name), + value_ (value) +{ +} + +ACE_INLINE +ACE_URL_Property::ACE_URL_Property (const ACE_USHORT16 *name, + const ACE_USHORT16 *value) + : name_ (name), + value_ (value) +{ +} + +ACE_INLINE +ACE_URL_Property::ACE_URL_Property (const ACE_URL_Property &p) + : name_ (p.name_), + value_ (p.value_) +{ +} + +ACE_INLINE +ACE_URL_Property::~ACE_URL_Property (void) +{ +} + +ACE_INLINE ACE_URL_Property & +ACE_URL_Property::operator= (const ACE_URL_Property &rhs) +{ + if (this != &rhs) + { + this->name_ = rhs.name_; + this->value_ = rhs.value_; + } + return *this; +} + +ACE_INLINE bool +ACE_URL_Property::operator== (const ACE_URL_Property &rhs) const +{ + if (this == &rhs || this->name_ != rhs.name_ || + this->value_ != rhs.value_) + return true; + else + return false; +} + +ACE_INLINE bool +ACE_URL_Property::operator!= (const ACE_URL_Property &rhs) const +{ + return !(*this == rhs); +} + +ACE_INLINE ACE_WString & +ACE_URL_Property::name_rep (void) +{ + return this->name_; +} + +ACE_INLINE const ACE_WString & +ACE_URL_Property::name (void) const +{ + return this->name_; +} + +ACE_INLINE void +ACE_URL_Property::name (const char *n) +{ + this->name_ = ACE_WString (n); +} + +ACE_INLINE void +ACE_URL_Property::name (const ACE_USHORT16 *n) +{ + this->name_ = ACE_WString (n); +} + +ACE_INLINE ACE_WString & +ACE_URL_Property::value_rep (void) +{ + return this->value_; +} + +ACE_INLINE const ACE_WString & +ACE_URL_Property::value (void) const +{ + return this->value_; +} + +ACE_INLINE void +ACE_URL_Property::value (const char *v) +{ + this->value_ = ACE_WString (v); +} + +ACE_INLINE void +ACE_URL_Property::value (const ACE_USHORT16 *v) +{ + this->value_ = ACE_WString (v); +} + + +ACE_INLINE size_t +ACE_URL_Property::size (void) const +{ + size_t len = 2; + len += this->name_.length () + this->value_.length (); + return len * sizeof (ACE_USHORT16); +} + +ACE_INLINE +ACE_URL_Offer::ACE_URL_Offer (const size_t size, const char *url) + : url_ (url), + prop_ (size) +{ +} + +ACE_INLINE +ACE_URL_Offer::ACE_URL_Offer (const ACE_URL_Offer &o) + : url_ (o.url_), + prop_ (o.prop_) +{ +} + +ACE_INLINE +ACE_URL_Offer::~ACE_URL_Offer (void) +{ +} + +ACE_INLINE ACE_URL_Offer & +ACE_URL_Offer::operator= (const ACE_URL_Offer &rhs) +{ + if (this != &rhs) + { + this->url_ = rhs.url_; + this->prop_ = rhs.prop_; + } + return *this; +} + +ACE_INLINE bool +ACE_URL_Offer::operator== (const ACE_URL_Offer &rhs) const +{ + if (this == &rhs + && this->url_ == rhs.url_ + && this->prop_ == rhs.prop_) + return true; + else + return false; +} + +ACE_INLINE bool +ACE_URL_Offer::operator!= (const ACE_URL_Offer &rhs) const +{ + return !(*this == rhs); +} + +ACE_INLINE ACE_WString & +ACE_URL_Offer::url_rep (void) +{ + return this->url_; +} + +ACE_INLINE const ACE_WString & +ACE_URL_Offer::url (void) const +{ + return this->url_; +} + +ACE_INLINE void +ACE_URL_Offer::url (const ACE_USHORT16 *url) +{ + this->url_ = ACE_WString (url); +} + +ACE_INLINE void +ACE_URL_Offer::url (const char *url) +{ + this->url_ = ACE_WString (url); +} + +ACE_INLINE ACE_URL_Property_Seq & +ACE_URL_Offer::url_properties (void) +{ + return this->prop_; +} + +ACE_INLINE void +ACE_URL_Offer::url_properties (const ACE_URL_Property_Seq &prop) +{ + this->prop_ = prop; +} diff --git a/ACE/apps/JAWS/clients/Caching/caching.mpc b/ACE/apps/JAWS/clients/Caching/caching.mpc new file mode 100644 index 00000000000..98481c0972e --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/caching.mpc @@ -0,0 +1,13 @@ +// -*- MPC -*- +// $Id$ + +project(http_client) : aceexe { + avoids += ace_for_tao + requires += ace_filecache + + exename = http_client + Source_Files { + http_handler.cpp + http_client.cpp + } +} diff --git a/ACE/apps/JAWS/clients/Caching/http_client.cpp b/ACE/apps/JAWS/clients/Caching/http_client.cpp new file mode 100644 index 00000000000..4fc1dcd1703 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/http_client.cpp @@ -0,0 +1,79 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// apps/JAWS/clients/Caching +// +// = FILENAME +// http_client.cpp +// +// = DESCRIPTION +// This is a very simple client. It accepts URLs from a prompt, and +// will try to fetch them. Also accepts shell escapes. +// +// = AUTHOR +// James Hu +// +// ============================================================================ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_ctype.h" +#include "http_handler.h" + +ACE_RCSID(Caching, http_client, "$Id$") + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Present a command line. + // * Accept a URL. + // Pass it to the HTTP_Connector. + // Connect. + // Report status. + // * Accept shell escape character. + + char buf[BUFSIZ]; + + ACE_DEBUG ((LM_DEBUG, "* ")); + + while (ACE_OS::fgets (buf, sizeof (buf), stdin) != 0) + { + char *s = buf; + + // get rid of trailing '\n' + int len = ACE_OS::strlen (s); + + if (len > 0 && s[len - 1] == '\n') + s[len - 1] = 0; + + while (ACE_OS::ace_isspace (*s)) + s++; + + if (*s == '!') + { + do + s++; + while (ACE_OS::ace_isspace (*s)); + + // Shell command. + if (ACE_OS::system (ACE_TEXT_CHAR_TO_TCHAR (s)) == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT (" ! Error executing: %C\n"), s)); + } + else if (ACE_OS::strncmp (s, "http://", 7) == 0) + { + // URL + HTTP_Connector connector; + connector.connect (s); + } + else + ACE_ERROR ((LM_ERROR, ACE_TEXT (" ? I don't understand: %C\n"), s)); + + ACE_ERROR ((LM_ERROR, ACE_TEXT ("* "))); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nBye!\n"))); + + return 0; +} diff --git a/ACE/apps/JAWS/clients/Caching/http_handler.cpp b/ACE/apps/JAWS/clients/Caching/http_handler.cpp new file mode 100644 index 00000000000..7f0ca9076c6 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/http_handler.cpp @@ -0,0 +1,240 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// apps/JAWS/clients/Caching +// +// = FILENAME +// http_handler.cpp +// +// = AUTHOR +// James Hu +// +// ============================================================================ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/Filecache.h" +#include "http_handler.h" + +ACE_RCSID(Caching, http_handler, "$Id$") + +HTTP_Handler::HTTP_Handler (void) +{ +} + +HTTP_Handler::HTTP_Handler (const char * path) +{ + // How long is the request going to be? + this->request_[0] = '\0'; + this->request_size_ = + ACE_OS::strlen ("GET ") + + ACE_OS::strlen (path) + + ACE_OS::strlen (" HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n"); + + // Make the request. + if ((u_int) this->request_size_ < sizeof (this->request_)) + ACE_OS::sprintf (this->request_, + "GET %s HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n", + path); + + // Find the filename. + const char *last = ACE_OS::strrchr (path, '/'); + + if (last == 0) + last = path; + else if (last[1] == '\0') + last = "index.html"; + else + last = last+1; + + ACE_OS::sprintf (this->filename_, "%s", last); +} + +int +HTTP_Handler::open (void *) +{ + // If you want threads, use the activate stuff. +#if 0 + if (this->activate () != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, "HTTP_Handler::open, whups!\n"), -1); + } + + return 0; +#else + return this->svc (); +#endif /* 0 */ +} + +int +HTTP_Handler::svc (void) +{ + static char buf[BUFSIZ]; + int count = 0; + + ACE_DEBUG ((LM_DEBUG, "[%t] sending request --\n%s", this->request_)); + + this->peer ().send_n (this->request_, this->request_size_); + + // Read in characters until encounter \r\n\r\n + int done = 0; + char *contentlength; + + do + { + while (((count += this->peer ().recv_n (buf + count, 1)) > 0) + && ((u_int) count < sizeof (buf))) + { + buf[count] = '\0'; + + if (count < 2) + continue; + done = ACE_OS::strcmp (buf + count - 4, "\n\n") == 0; + + if (done) + break; + + if (count < 4) + continue; + + done = ACE_OS::strcmp (buf + count - 4, "\r\n\r\n") == 0; + + if (done) + break; + } + + if (!done) + { + char *last = ACE_OS::strrchr (buf, '\n'); + last[0] = '\0'; + + if ((contentlength = ACE_OS::strstr (buf, "\nContent-length:")) + || (contentlength = ACE_OS::strstr (buf, "\nContent-Length:"))) + done = 1; + else + { + last[0] = '\n'; + count = ACE_OS::strlen (last); + ACE_OS::memmove (buf, last, count + 1); + } + } + else + { + contentlength = ACE_OS::strstr (buf, "\nContent-length:"); + + if (!contentlength) + contentlength = + ACE_OS::strstr (buf, "\nContent-Length:"); + } + + } + while (!done); + + // ASSERT (contentlength != 0) + int size = 0; + if (contentlength + && (::sscanf (contentlength, "\nContent-%*[lL]ength: %d ", + &size) == 1)) + { + this->response_size_ = size; + ACE_Filecache_Handle afh (ACE_TEXT_CHAR_TO_TCHAR (this->filename_), + this->response_size_); + + this->peer ().recv_n (afh.address (), this->response_size_); + + ACE_DEBUG ((LM_DEBUG, + " ``%s'' is now cached.\n", + this->filename_)); + } + else + { + // Maybe we should do something more clever here, such as extend + // ACE_Filecache_Handle to allow the creation of cache objects + // whose size is unknown? + + // Another possibility is to write the contents out to a file, + // and then cache it. + + // Perhaps make ACE_Filecache_Handle more savvy, and allow a + // constructor which accepts a PEER as a parameter. + ACE_DEBUG ((LM_DEBUG, + "HTTP_Handler, no content-length header!\n")); + } + + return 0; +} + +const char * +HTTP_Handler::filename (void) const +{ + return this->filename_; +} + +int +HTTP_Connector::connect (const char * url) +{ + char host[BUFSIZ]; + u_short port; + char path[BUFSIZ]; + + if (this->parseurl (url, host, &port, path) == -1) + { + ACE_DEBUG ((LM_DEBUG, + "HTTP_Connector, error parsing url: %s\n", + url)); + return -1; + } + + HTTP_Handler hh (path); + HTTP_Handler *hhptr = &hh; + + // First check the cache. + if (ACE_Filecache::instance ()->find (ACE_TEXT_CHAR_TO_TCHAR (hh.filename ())) == 0) + { + ACE_DEBUG ((LM_DEBUG, " ``%s'' is already cached.\n", + hh.filename ())); + return 0; + } + + return this->connector_.connect (hhptr, ACE_INET_Addr (port, host)); +} + +#define DEFAULT_SERVER_PORT 80 + +// extract the main components of a URL +int +HTTP_Connector::parseurl (const char *url, + char *host, + u_short *port, + char *path) +{ + int status = 0; + + // hackish, but useful + if (3 != ::sscanf (url, "http://%[^:/]:%hu%s", host, port, path)) + { + if (2 != ::sscanf (url, "http://%[^:/]:%hu", host, port)) + { + if (2 != ::sscanf (url, "http://%[^:/]%s", host, path)) + { + if (1 != ::sscanf (url, "http://%[^:/]", host)) + status = -1; + else + { + *port = DEFAULT_SERVER_PORT; + ACE_OS::strcpy (path, "/"); + } + } + else + *port = DEFAULT_SERVER_PORT; + } + else ACE_OS::strcpy (path, "/"); + } + + // 0 => success + // -1 => error + return status; +} + diff --git a/ACE/apps/JAWS/clients/Caching/http_handler.h b/ACE/apps/JAWS/clients/Caching/http_handler.h new file mode 100644 index 00000000000..db4c68aa200 --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/http_handler.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +// Hey, Emacs! This is a C++ file. +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// apps/JAWS/clients/Caching +// +// = FILENAME +// http_handler.h +// +// = AUTHOR +// James Hu +// +// ============================================================================ + +#include "ace/SOCK_Connector.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Connector.h" +#include "ace/Svc_Handler.h" + +class HTTP_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> + // = TITLE + // A simple HTTP protocol handler for clients. + // + // = DESCRIPTION + // Checks to see if the requested file is already cached. If + // so, it says so. If not, the request is issued to the + // connection. The fetched file is cached. +{ +public: + // = Initialization methods. + HTTP_Handler (void); + HTTP_Handler (const char * path); + + virtual int open (void *); + // Open hook. + + virtual int svc (void); + // Entry points defined by the abstract Svc_Handler. + + const char *filename (void) const; + // Accessor to the file being fetched. + +private: + char request_[BUFSIZ]; + size_t request_size_; + + char filename_[BUFSIZ]; + size_t response_size_; +}; + +class HTTP_Connector + // = TITLE + // A simple HTTP connector. + // + // = DESCRIPTION + // Creates an HTTP Handler based on the URL, and then delegates + // to to the SOCK_CONNECTOR. Adapter pattern. +{ +public: + int connect (const char * url); + // User entry point into the HTTP connector. + +private: + int parseurl (const char *url, + char *host, + u_short *port, + char *path); + // Helper function. + +private: + ACE_Connector<HTTP_Handler, ACE_SOCK_CONNECTOR> connector_; + // Factory that actively establishes a connection with an HTTP + // server. +}; diff --git a/ACE/apps/JAWS/clients/Caching/test_URL.cpp b/ACE/apps/JAWS/clients/Caching/test_URL.cpp new file mode 100644 index 00000000000..1a91ba8c64a --- /dev/null +++ b/ACE/apps/JAWS/clients/Caching/test_URL.cpp @@ -0,0 +1,34 @@ +// $Id$ + +#include "Locator_Request_Reply.h" + +ACE_RCSID(Caching, test_URL, "$Id$") + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); + + ACE_URL_Locator_Request original, derived; + + ACE_URL_Property_Seq ouch1(3); + ouch1[0].name ("name 1"); + ouch1[0].value ("value 1"); + ouch1[1].name ("name 2"); + ouch1[1].value ("value 2"); + ouch1[2].name ("name 3"); + ouch1[2].value ("value 3"); + + original.url_query (1, ouch1, 3); + + original.dump (); + derived.dump (); + + original.encode (); + + derived.decode ((void*) original.buffer ()); + + derived.dump (); + + return 0; +} diff --git a/ACE/apps/JAWS/clients/Makefile.am b/ACE/apps/JAWS/clients/Makefile.am new file mode 100644 index 00000000000..76571aa387d --- /dev/null +++ b/ACE/apps/JAWS/clients/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +SUBDIRS = \ + Blobby \ + Caching + diff --git a/ACE/apps/JAWS/clients/README b/ACE/apps/JAWS/clients/README new file mode 100644 index 00000000000..e35d7af53c9 --- /dev/null +++ b/ACE/apps/JAWS/clients/README @@ -0,0 +1,13 @@ +This directory contains the source code for various clients related to +JAWS, which is a high-performance HTTP Web server written with ACE. For +more information on JAWS, please see + +http://www.cs.wustl.edu/~jxh/research/ + +The subdirectories in this directory contain the following components + + . Blobby - a Blobby client + + . Caching - a Web client which caches + + . WebSTONE - modified to be multi-threaded diff --git a/ACE/apps/JAWS/clients/WebSTONE/COPYING b/ACE/apps/JAWS/clients/WebSTONE/COPYING new file mode 100644 index 00000000000..13057b45514 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/COPYING @@ -0,0 +1,348 @@ + While most of the source code in WebStone is covered by the terms +in the file LICENSE, the following files are covered by the GNU license, +reproduced below: + + config.guess + config.sub + +----------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ACE/apps/JAWS/clients/WebSTONE/README b/ACE/apps/JAWS/clients/WebSTONE/README new file mode 100644 index 00000000000..2d024b925a1 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/README @@ -0,0 +1,245 @@ +README WebStone 2.0.1 bug fix release + Proxy server bug fixed (now correctly handles proxy server) + Error reading page_stats error fixed + More Windows NT integration + Correctly handles URL's to different hostnames in the filelist + Improved Solaris compatibility + + NOTE: If you intend to run webstone with more than 100 URL +entries in the filelist, please edit src/bench.h and change the +MAXNUMOFPAGES value to reflect the higher number, and then recompile +everything. Copy the new binaries into the bin directory and then +run webstone. + +README WebStone 2.0 Release version + +WARNING: WebStone 2.0 results should not be compared with WebStone 1.1 + results. Even under the same fileset performance will not be + equivalent. + +Please see the notes for 2.0beta6 for quick and dirty install + This version includes a port of the webstone source code to Windows +NT. This port is still in progress, so it is not possible to guarantee +that everything is working correctly - however in our test configurations +it has performed correctly. Note that the supporting scripts and report +generating code has not been ported to NT yet. + + This version also institutes some basic run rules to eliminate the +lack of conformity in Webstone performance quotes. + To report Webstone numbers, some basic rules should be followed: + + 1) The fileset used for the test must be the fileset.standard fileset + included in the distribution. Tests of CGI performance must be + with the file filelist.cgi-heavy, and tests of NSAPI performance + must be carried out with filelist.dynamic-heavy + + 2) The run time should be set for 10 minutes, and the number of + clients should vary from 20 clients to 100 clients in increments + of 10. When a connections/second time is quoted, it must include + information about the number of clients involved. + + 3) Any special TCP/IP tuning which the server has recieved should + be documented, as well as HTTPD server version and configuration + information such as logging, DNS lookups and number of threads. + + +README - WebStone 2.0beta6 + +WARNING: Do not compare WebStone 2.0 results with WebStone 1.0 results. + WebStone 2.0 introduces significant changes in testing methodology + and reporting. + +This is the WebStone benchmark. Quick and dirty install: + - set up a Web server + - put this directory (WebStone) on a seperate machine (the "controller") + - "./webstone -setup", which does the following: + - gui-configure + This script may fail if you don't have a Web browser or + Perl5. Don't worry, unless you want to use the GUI. + - autoconf + If the GNU autoconf fails for your OS, please forward the + error messages, and any porting hints, to the author. + - make install + This may not be necessary, since IRIX binaries are included. + - edit conf/testbed to reflect your site + See the doc/FAQ-webstone.html for details. + - ./webstone -genfiles will put the files in conf/fileset + onto your Web server. + - ./webstone + - to display a table of results: ./webstone -results + +If you'd like to try out the GUI for WebStone: + - run "./webstone -setup", as above. + - make sure you have a Web browser installed + - ./configure + - ./webstone -gui + +Files of interest: + README: This document. + README.FIRST: Quick and dirty directions. + README.DynamicWorkload: Information on the CGI and NSAPI workloads. + webstone: wrapper shell script for everything. + Takes options: + -gui: start the GUI mode + -kill: kill stray WebStone processes + -genfiles: build files (from conf/fileset) + and rcp onto the server $SERVER + - results: print table of results + -setup: initial make and setup + -silent: runs in the background + -tail: tail -f of most recent run + +Files of interest (./src): + Makefile, *.c, *.h: The Webstone source code + +Files of interest (./bin): + checkfilelist: uses rsh to check web server for files in filelist. + genfiles, genrand: generates files of arbitrary length. + getstats: Collects network statistics from Web server, clients. + killbench: terminates stray WebStone processes. + rebootall: reboots all WebStone webclients. + runbench: wrapper script for WebStone. + webmaster: WebStone controller executable. + webstone: WebStone client executable. + wscollect: reports results in tabular format. + +Files of interest (./conf): + filelist: default list of files on the Web server, + with workload description. + filelist.photo: Model of a popular Web site + containing photographic images. + filelist.ss: Model of SGI's Silicon Surf WWW site. + fileset: list of files for genfiles to create. + testbed: config file describing Web server, client, and network setup. + +Documentation (./doc): + FAQ.html: The FAQ, current as of this distribution. + LICENSE: Legal status of WebStone. + testbed.help: Explains the parameters in conf/testbed. + webstone-white-paper.ps: The original WebStone white paper. + webstone.gif: The WebStone logo. + +Additional documentation: + FAQ.html: Frequently Asked Questions, with answers + webstone.ps: PostScript white paper on WebStone + +Problems, etc. may be addressed to the WebStone mailing list. +Read the FAQ for details. + +Release Notes (2.0 beta6): + * fixed a bug for Web servers not on port 80 + * further changes to bin/wscollect.pl + +Release Notes (2.0 beta5): + * numerous minor fixes suggested by gcc -Wall -pedantic + * updated FAQ + * changed bin/wscollect.pl to use Perl formats + +Release Notes (2.0 beta4): + * added #include <sys/time.h> to bench.h + * changed webclient located to $TMPDIR - this should help people + who don't want to run WebStone as root + * changed check for libm to floor() instead of sqrt(). Apparently + some systems implement sqrt() in libc - let's hope no one implement + floor() in libc and sqrt() in libm! + +Release Notes (2.0 beta3): + * more portability fixes + * successfully compiled on FreeBSD 2.2, IRIX without any source + changes + +Release Notes (2.0 beta2): + * additional timezone fixes for SunOS + +Release Notes (2.0 beta1): + * fixed a bug in the rexec portion of webmaster.c + * fixed a bug in the usage() routine of webmaster.c + * added bin/genfiles-from-filelist.sh + - bin/genfiles-from-filelist.sh <filename> + - generates appropriate-length files from <filename> + - <filename> must contain three fields: + <relative URL> <weight> #<size in bytes> + example: /file.html 1 #1024 + * added bin/mine-logs.pl + - usage: mine-logs.pl <filename> + where <filename> is an http server log file + - writes a WebStone workload to standard output + +Release Notes (2.0 alpha5): + * revised default testbed file + * changed wscollect to wscollect.pl for consistency + * changed webstone-gui to webstone-gui.pl for consistency + * added some NT porting hints + * added autoconf, which should help Linux and SunOS porting + +Release Notes (2.0 alpha4): + * added SunOS and Linux portability elements + * new scheme for random access to pages + * converted several static arrays to dynamic pointers + +Release Notes (2.0 alpha2): + * fixed per-page statistics + * new, client-independent data-passing scheme + * added support for proxy servers + +Release Notes (2.0 alpha1): + * new filelist scheme - however, this breaks per-page statistics + * minor fixes + +Release Notes (1.1): + * Improved webclient performance by combining GET and ACCEPT + HTTP headers in one write() call. + * Improved webclient performance on systems that always attempt + to map protocol names to numbers using YP. + * WARNING: since the old code introduced a significant latency + in some systems, DO NOT compare WebStone 1.1 results + with results generated by any previous versions. + +Release Notes (1.0.3): + * Netscape Server 1.1.2 exposed a couple bugs, which I've now fixed. + +Release Notes (1.0.2): + * Fixed runbench so that ITERATIONS, MINCLIENTS, and MAXCLIENTS don't + have to have a common denominator any more. + * Fixed a few cosmetic bugs. + +Release Notes (1.0.1): + * Fixed select() bug in webmaster + +Release Notes (1.0 final): + * Fixed the "Error reading 2nd timing info" bug + * Fixed numerous bugs in the GUI + * Froze feature set. Work can now begin on WebStone 1.1 + +Release Notes (1.0b3): + * New Web browser GUI + NOTE: most Web browsers take up substantial CPU time. + If you run the GUI, we recommend that you make the controller + a separate machine, and don't run any WebStone clients on it. + * Minor bug fixes + Squashed some dubious error messages, fixed some client- + controller communications problems. + * Reporting changes + Changes the units and order of the final summary statistics. + Basically, this is for my own convenience, so I don't have to + massage the data quite so much before using it. wscollect + now reports only the metrics I regard as important - but all + metrics are still reported in the runs/*/run files. + +LEGAL STUFF: + +This file and all files contained in this directory are +copyright 1995, Silicon Graphics, Inc. + +This software is provided without support and without any obligation on the +part of Silicon Graphics, Inc. to assist in its use, correction, modification +or enhancement. There is no guarantee that this software will be included in +future software releases, and it probably will not be included. + +THIS SOFTWARE IS PROVIDED "AS IS" WITH NO WARRANTIES OF ANY KIND INCLUDING THE +WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE, +OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + +In no event will Silicon Graphics, Inc. be liable for any lost revenue or +profits or other special, indirect and consequential damages, even if +Silicon Graphics, Inc. has been advised of the possibility of such damages.
\ No newline at end of file diff --git a/ACE/apps/JAWS/clients/WebSTONE/README.DynamicWorkload b/ACE/apps/JAWS/clients/WebSTONE/README.DynamicWorkload new file mode 100644 index 00000000000..a263d1a8a0e --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/README.DynamicWorkload @@ -0,0 +1,37 @@ +WebStone Dynamic Workload + + WebStone now includes a workload that tests dynamically generated +Web pages. + + To use the dynamic workload models, you must install a dynamic module +on the Web server to be tested. The Web server must also be configured such +that a request for "/file.dyn-send?size=1024" (for example) will cause the +module to be run, and will return 1024 bytes of data. + +Example configuration (Netscape server, executable is "nsapi-send"): + cd src + make nsapi + cp nsapi-send.so /usr/lib + cd /usr/ns-home/httpd-80/config + in magnus.conf, add the line: + Init fn=load-modules shlib=nsapi.so funcs=nsapi-send + in obj.conf, add the line: + Service method=(GET|HEAD) fn=nsapi-send \ + type=magnus-internal/dyn-send + in mime.types, add the line: + type=magnus-internal/dyn-send exts=dyn-send + restart the Web server + + Example code for CGI and NS-API is included as src/cgi-send.c +and src/nsapi-send.c - if you implement other APIs, please forward a copy +of your code to the WebStone mailing list or to the WebStone authors. + +Included workloads: + conf/workload.dynamic-heavy: All content is dynamically generated. + conf/filelist.dynamic-medium: About 50% of content is dynamically + generated. + conf/filelist.dynamic-light: About 25% of content is dynamically + generated. + +As always, we encourage you to design your own workloads, tailored for your +environment. diff --git a/ACE/apps/JAWS/clients/WebSTONE/README.FIRST b/ACE/apps/JAWS/clients/WebSTONE/README.FIRST new file mode 100644 index 00000000000..b93c02afe3b --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/README.FIRST @@ -0,0 +1,21 @@ +QUICK AND DIRTY README FOR WEBSTONE 2.0 + +For more details, consult the README* files and the doc/FAQ-webstone.html + +First, run: + + ./webstone -setup + + This script uses GNU autoconf, makes the binaries, and then +puts you into the vi editor with the conf/testbed file. For details on +how to edit conf/testbed, consult the FAQ. + +Next, if you have a Web broswer available, and you'd like to try the GUI + + ./webstone -gui + +Otherwise, run the benchmark by typing + + ./webstone + + diff --git a/ACE/apps/JAWS/clients/WebSTONE/WEBSTONE-VERSION-2.0 b/ACE/apps/JAWS/clients/WebSTONE/WEBSTONE-VERSION-2.0 new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/WEBSTONE-VERSION-2.0 diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-common.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-common.pl new file mode 100755 index 00000000000..9e52c1dec97 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-common.pl @@ -0,0 +1,63 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +1; + +sub show_model { + $model = `head -1 $wd/conf/filelist`; + $model =~ s/\#//; + ( $model ) = split(':', $model); + + print CLIENT <<EOF +<P><STRONG> +<A HREF=\"$wd/bin/WebStone-setup.pl\">$model +</A></STRONG> +EOF + ; +} + +sub html_begin { + + ( $title ) = @_; + + close(STDOUT); + open(STDOUT, ">&CLIENT"); + close(STDERR); + open(STDERR, ">&CLIENT"); + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>WebStone $title</TITLE> +<A HREF="$wd/doc/WebStone.html"> +<IMG SRC="$wd/doc/webstone.gif" ALT="WebStone" BORDER=0 ></A> +<H1>World Wide Web Server Benchmarking</H1> +<DL> +<DT><EM>If you have any questions, please read the +<A HREF="$wd/doc/FAQ-webstone.html">WebStone FAQ</A>.</EM> +<HR> +EOF + ; + +} + +sub html_end { + + print CLIENT <<EOF +<HR> +<ADDRESS><A HREF="$wd/doc/LICENSE.html">copyright 1995 Silicon Graphics</A> +</ADDRESS> +</BODY> +</HTML> +EOF + ; + + close(STDERR); + close(STDOUT); + open(STDOUT); + open(STDERR); +} + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-manage.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-manage.pl new file mode 100755 index 00000000000..77d2495a741 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-manage.pl @@ -0,0 +1,33 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin("Administration"); + +$runsdir = "$wd/bin/runs"; +$thelength = length($runsdir) + 10; +$oldrunsdir = $runsdir; +$oldfilelist = "$wd/conf/filelist"; + +print CLIENT <<EOF +<FORM METHOD="POST" ACTION="$wd/bin/killbench.pl"> +<H3>Clean up stray WebStone processes</H3> +<INPUT TYPE="SUBMIT" VALUE="Kill"> +</FORM> + +<HR> +<FORM METHOD="POST" ACTION="$wd/bin/move-runs.pl"> +<H3>Move Results Directory to:</H3> +<INPUT TYPE=TEXT NAME=runsdir SIZE=$thelength VALUE=$runsdir> +<INPUT TYPE="SUBMIT" VALUE="Move Directory"> +</FORM> +EOF + ; + +html_end(); + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-run.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-run.pl new file mode 100755 index 00000000000..28efe90c4d5 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-run.pl @@ -0,0 +1,39 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +$testbed = "conf/testbed"; + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin("Run"); + +print CLIENT <<EOF +<H3><CENTER><A HREF="WebStone-setup.pl">Edit Configuration</A> +</CENTER></H3> +EOF + ; + +&show_model(); +print CLIENT "<PRE>"; + +open(FILEHANDLE, $testbed); +while (<FILEHANDLE>) { + (/^\#/) || print CLIENT $_; +} +close(FILEHANDLE); + +print CLIENT <<EOF +</PRE> +<CENTER> +<FORM METHOD=POST ACTION="http://localhost:$html_port$wd/bin/runbench.pl"> +<INPUT TYPE="submit" VALUE="Run WebStone"> +</CENTER> +EOF + ; + +html_end(); + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-setup.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-setup.pl new file mode 100755 index 00000000000..f47ac6a8f06 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/WebStone-setup.pl @@ -0,0 +1,97 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +@keylist = (); + +html_begin("Setup"); + +show_model(); + +print CLIENT <<EOF +<FORM METHOD="POST" ACTION="$wd/bin/write-testbed.pl"> +EOF + ; + +&gettestbed(); +&getconfig(); + +print CLIENT <<EOF +</DL> +<P><INPUT TYPE="SUBMIT" VALUE="Write Configuration"> +</FORM> + +<HR> +<FORM METHOD="POST" ACTION="$wd/bin/move-filelist.pl"> +<H3>Choose a Web site model:</H3> +<DL> +EOF + ; + +for $key (sort(keys %filelist)) { + print CLIENT "<DD><INPUT TYPE=RADIO NAME=filelist "; + if ($key eq "filelist") { + print CLIENT " CHECKED "; + } + print CLIENT " VALUE=\"$wd/conf/$key\"> $key: $filelist{$key}"; +} + +print CLIENT <<EOF +</DL> +<INPUT TYPE="SUBMIT" VALUE="Set Workload"> + +EOF + ; + +html_end(); + +# end of main program + +sub gettestbed { + open(TESTBED, "$wd/conf/testbed"); + while (<TESTBED>) { + if (/^\#|^(\w)*$/) { # do nothing + } + else { + ( $textvalue, $thevalue ) = split( '=', $_ ); + ( $thevalue ) = split( '#', $thevalue); + $testbed{$textvalue} = $thevalue; + push(@keylist, $textvalue); + } + } + close(TESTBED); + + open(HELPFILE, "$wd/doc/testbed.help"); + while (<HELPFILE>) { + ( $key, $textvalue ) = split( ':', $_ ); + $helptext{$key} = $textvalue; + } + close(HELPFILE); + + foreach $key (@keylist) { + print CLIENT "<P><DT>$helptext{$key}"; + $thesize = length($testbed{$key}) + 5; + print CLIENT "<DD>$key <INPUT TYPE=TEXT NAME=$key "; + print CLIENT "SIZE=$thesize VALUE=$testbed{$key}>\n"; + } +} + +sub getconfig { + opendir(CONF, "$wd/conf") || die "open $wd/conf: $!"; + %filelist = ""; + foreach $file (sort readdir(CONF)) { + if ( $file =~ /^filelist.*/ ) { + $headtext = `head -1 $wd/conf/$file`; + $headtext =~ s/\#//; + ( $headtext ) = split(':', $headtext); + $filelist{$file} = $headtext; + } + } + closedir(CONF); +} + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/checkfilelist b/ACE/apps/JAWS/clients/WebSTONE/bin/checkfilelist new file mode 100755 index 00000000000..4cc2d11c49e --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/checkfilelist @@ -0,0 +1,35 @@ +#! /bin/sh + +# +# NAME +# checkfilelist - try retrieving files from server +# +# SYNOPSIS +# checkfilelist servername portno filelist +# +# + +if test "$#" -lt 3 ; then + echo "usage: $0 servername portno filelist" + exit 2 +fi + +HOSTNAME=$1 ; export HOSTNAME +PORTNO=$2 ; export PORTNO +FILELIST=$3 ; export FILELIST + +grep '^/' $FILELIST | cut -f1 | +( +while read URL +do + export URL + echo ">>>>> $URL" + ( + telnet $HOSTNAME $PORTNO << _EOF_ +GET $URL HTTP/1.0 + +_EOF_ + ) 2> /dev/null | head -5 | grep 'HTTP/1.0' + killall telnet +done +) diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/genfiles b/ACE/apps/JAWS/clients/WebSTONE/bin/genfiles new file mode 100755 index 00000000000..d5f06aee6df --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/genfiles @@ -0,0 +1,41 @@ +#! /bin/sh +# + +# get configuration +. $WEBSTONEROOT/conf/testbed + +cat $WEBSTONEROOT/conf/fileset | +nawk ' +($1 ~ /^[0-9][0-9]*[kK][bB]*$/) { + sub(/[kK][bB]*/, "", $1); + cmd = "$WEBSTONEROOT/bin/genrand " $1*1024 " " $2 + print cmd; + system(cmd); + next +} + +($1 ~ /^[0-9][0-9]*[mM][bB]*$/) { + sub(/[kK][bB]*/, "", $1); + cmd = "$WEBSTONEROOT/bin/genrand " $1*1024*1024 " " $2 + print cmd; + system(cmd); + next +} + +($1 ~ /^[0-9][0-9]*$/) { + sub(/[kK][bB]*/, "", $1); + cmd = "$WEBSTONEROOT/bin/genrand " $1 " " $2 + print cmd; + system(cmd); + next +} ' $* + +# copy files +files=`cat $WEBSTONEROOT/conf/fileset | cut -f2 -d' '` +for f in $files +do + $RCP $f $SERVER:$WEBDOCDIR + rm -f $f +done + +#end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/genfiles-from-filelist.sh b/ACE/apps/JAWS/clients/WebSTONE/bin/genfiles-from-filelist.sh new file mode 100755 index 00000000000..1293709238c --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/genfiles-from-filelist.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# + +# get configuration +[ -n "$WEBSTONEROOT" ] || WEBSTONEROOT=`pwd`/.. +. $WEBSTONEROOT/conf/testbed + +case $# in + 1) + FILELIST=$1 + ;; + *) + FILELIST=$WEBSTONEROOT/conf/filelist + ;; +esac + +TIMESTAMP=`date +"%y%m%d_%H%M"` +mkdir $TMPDIR/webstone-genfiles.$TIMESTAMP +cd $TMPDIR/webstone-genfiles.$TIMESTAMP + +cat $FILELIST | +nawk ' +($3 ~ /^\#[0-9]*/) { + sub(/^\#/, "", $3); + cmd = WEBSTONEROOT "/bin/genrand " $3 " ."$1 + print cmd; + system(cmd); + cmd = RCP " ." $1 " " SERVER ":" WEBDOCDIR + print cmd; + system(cmd); + cmd = "rm -f ." $1 + print cmd; + system(cmd); + next +} +' $* WEBSTONEROOT=$WEBSTONEROOT RCP=$RCP SERVER=$SERVER WEBDOCDIR=$WEBDOCDIR + +cd $TMPDIR +rm -rf $TMPDIR/webstone-genfiles.$TIMESTAMP + +#end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/gui-configure b/ACE/apps/JAWS/clients/WebSTONE/bin/gui-configure new file mode 100755 index 00000000000..dcea4e3fe1c --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/gui-configure @@ -0,0 +1,174 @@ +#!/bin/sh -- because we're not sure where perl is yet +# + +'true' || eval 'exec perl -S $0 $argv:q'; +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' +& eval 'exec /usr/local/bin/perl -S $0 $argv:q' + if 0; + +# Usage: [perl] configure [file] +# +# This replaces the program paths (e.g. /bin/awk) with an +# alternate path that is found in the file "file.paths". It also finds +# perl5 and changes the path in all the stand-alone perl programs. +# + +$debug = 0; + +# +# Target shell scripts in question: +@shell_scripts=("conf/paths.pl", "conf/paths.sh"); +@perl5_src = < bin/webstone-gui.pl bin/WebStone-common.pl bin/killbench.pl bin/view-results.pl bin/WebStone-manage.pl bin/move-filelist.pl bin/write-testbed.pl bin/WebStone-run.pl bin/move-runs.pl bin/WebStone-setup.pl bin/runbench.pl >; +@perl_src = < bin/wscollect.pl bin/mine-logs.pl >; +@benchmark_dir_src = < webstone bin/killbench bin/runbench >; + +# all the HTML browsers we know about, IN ORDER OF PREFERENCE! +@all_www= ("netscape", "Mosaic", "xmosaic", "lynx"); + +# +# Potential directories to find commands; first, find the user's path... +$PATH = $ENV{"PATH"}; + +# additional dirs; *COLON* separated! +$other_dirs="/usr/ccs/bin:/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/ucb/bin:/usr/sbin:/usr/etc:/usr/local/bin:/usr/bin/X11:/usr/X11/bin:/usr/openwin/bin"; + +# +# split into a more reasonable format. Personal aliases come last. +@all_dirs = split(/:/, $other_dirs . ":" . $PATH); + +print "checking to make sure all the target(s) are here...\n"; + +for (@shell_scripts) { + die "ERROR -- $_ not found!\n" unless -f $_; + } + +# find perl +print "Trying to find perl...\n"; +for $dir (@all_dirs) { + # first, find where it might be + next if (! -d $dir); + while (<$dir/perl*>) { + if (-x $_) { + $perl_version=`($_ -v 2> /dev/null) | + awk '/This is perl/ { print $NF }'`; + if ($perl_version) { + $PERL=$_; + $pflag="1"; + last; + } + } + last if $pflag; + } + last if $pflag; + } + +if ($PERL) { + print "\nPerl is in $PERL\n"; + for (@perl_src) { $perl_src .= "$_ "; } + print "\nchanging the source in: $perl_src\n"; + system "$PERL -pi -e \"s@^#!.*/perl.*@#!$PERL@;\" $perl_src"; + + # make sure things are executable... + system("chmod u+x $perl_src"); +} +else +{ + printf "\nSome WebStone functions require Perl\n" unless $PERL; +} +# end if $PERL + +# find perl5 +$pflag = 0; +print "Trying to find perl5...\n"; +for $dir (@all_dirs) { + # first, find where it might be; oftentimes you'll see perl, + # perl4, perl5, etc. in the same dir + next if (! -d $dir); + while (<$dir/perl5* $dir/perl*>) { + if (-x $_) { + $perl_version=`($_ -v 2> /dev/null) | + awk '/This is perl, version 5/ { print $NF }'`; + if ($perl_version) { + $PERL5=$_; + $pflag="1"; + last; + } + } + last if $pflag; + } + last if $pflag; +} + +if ($PERL5) { + print "\nPerl5 is in $PERL5\n"; + + for (@perl5_src) { $perl5_src .= "$_ "; } + print "\nchanging the source in: $perl5_src\n"; + system "$PERL5 -pi -e \"s@^#!.*/perl.*@#!$PERL5@;\" $perl5_src"; + system("chmod u+x $perl5_src"); +} +else +{ + printf "\nThe WebStone GUI requires Perl5\n" unless $PERL5; +} +#end if $PERL5 + +# find the most preferred www viewer first. +for $www (@all_www) { + for $dir (@all_dirs) { + if (!$MOSAIC) { + if (-x "$dir/$www") { + $MOSAIC="$dir/$www"; + next; + } + } + } + } +if ($MOSAIC) { + print "\nHTML/WWW Browser is $MOSAIC\n"; + + $upper{"MOSAIC"} = $MOSAIC; + } +else { print "Cannot find a web browser! WebStone cannot be run except in CLI"; } + +print "\nOk, now doing substitutions on the shell scripts...\n"; +for $shell (@shell_scripts) { + print "Changing paths in $shell...\n"; + die "Can't open $shell\n" unless open(SCRIPT, $shell); + rename($shell, $shell . '.old'); + die "Can't open $shell\n" unless open(OUT, ">$shell"); + + # + # Open up the script, search for lines beginning with + # stuff like "TEST", "AWK", etc. If the file ends in "pl", + # assume it's a perl script and change it accordingly + while (<SCRIPT>) { + $found = 0; + for $command (keys %upper) { + if(/^\$?$command=/) { + # shell script + if ($shell !~ /.pl$/) { + print OUT "$command=$upper{$command}\n"; } + # perl script + else { + print OUT "\$" . "$command=\"$upper{$command}\";\n"; + } + $found = 1; + } + } + print OUT $_ if !$found; + + } + close(SCRIPT); + close(OUT); + } + + +for (@benchmark_dir_src) { $benchmark_dir_src .= "$_ "; } +print "\nchanging the source in: $benchmark_dir_src\n"; +$BENCHMARK_DIR=`pwd`; +chop $BENCHMARK_DIR; +$BENCHMARK_DIR =~ s/\//\\\//g; +system "$PERL -pi -e \"s/<BENCHMARK_DIR>/$BENCHMARK_DIR/\" $benchmark_dir_src"; + +# done... diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/killbench b/ACE/apps/JAWS/clients/WebSTONE/bin/killbench new file mode 100755 index 00000000000..2997d891dca --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/killbench @@ -0,0 +1,13 @@ +#!/bin/sh -x +# +# get configuration +. $WEBSTONEROOT/conf/testbed + +for i in $CLIENTS +do + $RSH -l root $i /etc/killall $1 webclient +done +# +sleep 1 +/etc/killall $1 webmaster +/etc/killall $1 runbench diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/killbench.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/killbench.pl new file mode 100755 index 00000000000..db9b0368632 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/killbench.pl @@ -0,0 +1,17 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin(); + +print CLIENT "<P>Killing WebStone processes<PRE>"; +system("$wd/bin/killbench"); +print CLIENT "</PRE><P>Done."; + +html_end(); + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/mine-logs.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/mine-logs.pl new file mode 100755 index 00000000000..af2c470fb0c --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/mine-logs.pl @@ -0,0 +1,90 @@ +#!/pkg/gnu/bin//perl +# +#$Id$ +# +# mine-logs.pl: +# script to transform access logs into WebStone workload +# +# created 18 December 1995 mblakele@engr.sgi.com +# +# functional map: +# usage: mine-logs.pl access.log +# +# 1. For each line in the input +# a. parse the URL and the time, the outcome code, and the size +# b. if the code is 200, and it's a GET, +# do we already know about this URL? +# i. yes - increment its counter +# ii. no - create a slot for it, record size, +# and set counter=1 +# + +$debug = 0; +$line_number = 0; + +while (<>) { + chomp; + + $line_number++; + ($line_number % 1000) || printf STDERR "."; + # parse line + ( $client, $junk1, $junk2, $date, $timezone, + $command, $url, $version, $result_code, $size ) = + split; + # strip some junk + $command =~ s/\"//; + $date =~ s/\[//; + + ($debug) && printf STDERR "$client, $date, $command, $url, $result_code, $size\n"; + + # is it a GET? Did it succeed? (i.e., is the result code 200?) + if (($command eq 'GET') && ($result_code == 200)) { + # is this URL already in the key set? + if (exists $counter{$url}) { + # URL is in key set + ($debug) && printf STDERR "URL $url already in key set: incrementing\n"; + $counter{$url}++; + if ($size == $size{$url}) { + ($debug) && printf STDERR "size mismatch on $url: $size != $size{$url}\n"; + if ($size <=> $size{$url}) { $size{$url} = $size; } + } + } + else { + # URL isn't in key set + ($debug) && printf STDERR "URL $url isn't in key set: adding size $size\n"; + $counter{$url} = 1; + $size{$url} = $size; + } + # end if key set + } # end if GET +} +# end of input file +printf STDERR "\n"; + +# now we print out a workload file + +# first, the headline +$date = `date`; +chomp($date); +printf "# WebStone workload file\n# \tgenerated by $0 $date\n#\n"; + +# next, sort the keys +@sorted_keys = sort by_counter keys(%counter); + +# iterate through sorted keys +foreach $key (@sorted_keys) { + # print url, weighting, and (commented) the size in bytes + ($debug) && printf STDERR "printing data for $key\n"; + printf "$key\t$counter{$key}\t#$size{$key}\n"; +} +# end foreach + +# end main + +sub +by_counter { + $counter{$b} <=> $counter{$a}; +} +# end by_counter + +# end mine-logs.pl diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/move-filelist.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/move-filelist.pl new file mode 100755 index 00000000000..eb263a04bf5 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/move-filelist.pl @@ -0,0 +1,28 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +$oldfilelist = "$wd/conf/filelist"; + +html_begin(); + +if ($filelist ne $oldfilelist) { + $backup = $oldfilelist . ".bak"; + print CLIENT "<BODY>Backing up $oldfilelist to $backup"; + rename($oldfilelist, $backup); + print CLIENT "<P>Copying $filelist to $oldfilelist"; + link($filelist, $oldfilelist); + print CLIENT "<P>Done."; +} +else +{ + print CLIENT "<STRONG>Can't move $filelist <P>to $filelist</STRONG>"; +} + +html_end(); + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/move-runs.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/move-runs.pl new file mode 100755 index 00000000000..3412f992008 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/move-runs.pl @@ -0,0 +1,26 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin(); + +if ($runsdir ne $oldrunsdir) { + print CLIENT "<BODY>Moving $oldrunsdir to $runsdir..."; + if (-e $runsdir) { + print CLIENT "<STRONG>Error: $runsdir already exists!</STRONG>"; + } + rename($oldrunsdir, $runsdir); + print CLIENT "<P>Done."; +} +else +{ + print CLIENT "<STRONG>Can't move $runsdir <P>to $oldrunsdir</STRONG>"; +} + +html_end(); + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/rebootall b/ACE/apps/JAWS/clients/WebSTONE/bin/rebootall new file mode 100755 index 00000000000..2de65110027 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/rebootall @@ -0,0 +1,9 @@ +#! /bin/sh -x + +# get configuration +. $WEBSTONEROOT/conf/testbed + +for i in $CLIENTS +do + $RSH -l root $i "sleep 5 ; init 6" & +done diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/runbench b/ACE/apps/JAWS/clients/WebSTONE/bin/runbench new file mode 100755 index 00000000000..409351f8f55 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/runbench @@ -0,0 +1,193 @@ +#!/bin/sh +# $Header$ +# set -x +set +x +[ -n "$WEBSTONEROOT" ] || WEBSTONEROOT=`pwd`/../ + +case $# in + 1) + FILELIST=$1 + ;; + *) + FILELIST=$WEBSTONEROOT/conf/filelist + ;; +esac + +# load configurations +. $WEBSTONEROOT/conf/testbed + +[ -n "$DEBUG" ] && set +x + +# check variables +[ -n "$ITERATIONS" ] || ITERATIONS="1" +[ -n "$MINCLIENTS" ] || MINCLIENTS="1" +[ -n "$MAXCLIENTS" ] || MAXCLIENTS="1" +[ -n "$CLIENTINCR" ] || CLIENTINCR="1" +[ -n "$TIMEPERRUN" ] || TIMEPERRUN="1" +# don't care about PROXYSERVER +[ -n "$SERVER" ] || SERVER="www" +[ -n "$PORTNO" ] || PORTNO="80" +# [ -n "$SERVERINFO" ] || SERVERINFO="uname -a" +# OSTUNINGFILES +# WEBSERVERDIR +# WEBDOCDIR +# WEBSERVERTUNINGFILES +[ -n "$CLIENTS" ] || CLIENTS="localhost" +[ -n "$CLIENTACCOUNT" ] || CLIENTACCOUNT=$USER +[ -n "$CLIENTPASSWORD" ] || CLIENTPASSWORD=$CLIENTACCOUNT +# [ -n "$CLIENTINFO" ] || CLIENTINFO="uname -a" +[ -n "$TMPDIR" ] || TMPDIR="/tmp" +[ -n "$RCP" ] || RCP="rcp" +[ -n "$RSH" ] || RSH="rsh" + +export ITERATIONS MINCLIENTS MAXCLIENTS CLIENTINCR TIMEPERRUN +export SERVER PORTNO SERVERINFO +export CLIENTS CLIENTACCOUNT CLIENTPASSWORD CLIENTINFO +export TMPDIR RCP RSH + +echo "Clients: " $CLIENTS + +# +# Estimate run time +# +NUMCLIENTHOSTS=`echo $CLIENTS | wc -w` +TRIALS=`expr 1 + \( $MAXCLIENTS - $MINCLIENTS \) / $CLIENTINCR` +RUNTIME=`expr 60 \* $ITERATIONS \* $TRIALS \* $TIMEPERRUN` +RUNTIME=`expr $RUNTIME + $TRIALS \* \( $MAXCLIENTS + $MINCLIENTS \) \ + / \( 2 \* $NUMCLIENTHOSTS \)` + +echo "Estimated run time:" `expr $RUNTIME / 3600` "hours" \ + `expr $RUNTIME % 3600 / 60` "minutes" + +# +# Checking for valid set of benchmark files to retrieve +# +#if [ -z "$PROXYSERVER" ] +#then +# echo "Checking for a valid set of benchmark files" +# CHECKLISTTMP=$TMPDIR/webstone-checkfilelist.$$ +# rm -f $CHECKFILELISTTMP +# $WEBSTONEROOT/bin/checkfilelist $SERVER $PORTNO $FILELIST > $CHECKLISTTMP 2>&1 +# if [ `grep -c ' 4[0-9][0-9] '< $CHECKLISTTMP` -gt 0 ] +# then +# echo "ERROR: not all files in filelist are on server:" +# echo "----- checkfilelist results -----" +# cat $CHECKLISTTMP +# echo "----- checkfilelist results -----" +# rm -f $CHECKLISTTMP +# exit 1 +# else +# echo "OK: All files found" +# fi +# rm -f $CHECKLISTTMP +#fi +# end if $PROXYSERVER + +# +# distribute webclient binary +# +for i in $CLIENTS +do + $RCP $WEBSTONEROOT/bin/webclient $i:$TMPDIR #/usr/local/bin +done + +# BEGIN iterations +J=1 +while [ $J -le $ITERATIONS ] +do + NUMCLIENTS=$MINCLIENTS + while [ $NUMCLIENTS -le $MAXCLIENTS ] + do + echo "***** Iteration $J, Total clients "`expr $NUMCLIENTS`" **********" + date + TIMESTAMP=`date +"%y%m%d_%H%M"` + LOGDIR=$WEBSTONEROOT/bin/runs/$TIMESTAMP + + # + # nuke debug files + # + for client in $CLIENTS + do + $RSH $client "rm /tmp/webstone-debug*" > /dev/null 2>&1 + done + + mkdir -p $LOGDIR + rm -f $LOGDIR/config + touch $LOGDIR/config + CLIENTSPERHOST=`expr $NUMCLIENTS / $NUMCLIENTHOSTS` + EXTRACLIENTS=`expr $NUMCLIENTS % $NUMCLIENTHOSTS` + + for i in $CLIENTS + do + if [ $EXTRACLIENTS -gt 0 ] + then + echo "$i $CLIENTACCOUNT $CLIENTPASSWORD `expr $CLIENTSPERHOST + 1`" \ + >> $LOGDIR/config + EXTRACLIENTS=`expr $EXTRACLIENTS - 1` + else + echo "$i $CLIENTACCOUNT $CLIENTPASSWORD $CLIENTSPERHOST" \ + >> $LOGDIR/config + fi + done + cp $FILELIST $LOGDIR/`basename $FILELIST` + + # + # Put test configuration files on clients + # + for i in $CLIENTS localhost + do + $RSH $i "rm -f $TMPDIR/config $TMPDIR/`basename $FILELIST`" + $RCP $LOGDIR/config $i:$TMPDIR/config + $RCP $LOGDIR/`basename $FILELIST` $i:$TMPDIR/filelist + done + + # + # Get starting configuration and stats from each participant + # + $RSH $SERVER "$SERVERINFO" > $LOGDIR/hardware.$SERVER 2>&1 + for i in $CLIENTS + do + $RSH $i "$CLIENTINFO" > $LOGDIR/hardware.$i 2>&1 + done + + # set -x + for i in $OSTUNINGFILES $WEBSERVERTUNINGFILES + do + $RCP $SERVER:$i $LOGDIR + done + set +x + + # + # Run benchmark + # + date + CMD="$WEBSTONEROOT/bin/webmaster -v -u $TMPDIR/filelist" + CMD=$CMD" -f $TMPDIR/config -l $TIMEPERRUN" + [ -n "$SERVER" ] && CMD=$CMD" -w $SERVER" + [ -n "$PORTNO" ] && CMD=$CMD" -p $PORTNO" + [ -n "$PROXYSERVER" ] && CMD=$CMD" -P $PROXYSERVER" + [ -n "$DEBUG" ] && CMD=$CMD" -d" + echo $CMD + + # dump environment into $LOGDIR + rm -rf $LOGDIR/controller.env + env > $LOGDIR/controller.env + + $CMD | tee $LOGDIR/run + + # + # Get ending configuration and stats from each participant + # + date + #for i in $SERVER $CLIENTS + #do + #$WEBSTONEROOT/bin/getstats $i > $LOGDIR/end.$i 2>&1 + #done + #date + NUMCLIENTS=`expr $NUMCLIENTS + $CLIENTINCR` + done + # while NUMCLIENTS + J=`expr $J + 1` +done +# while J +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/runbench.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/runbench.pl new file mode 100755 index 00000000000..fdd12e4d530 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/runbench.pl @@ -0,0 +1,38 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); +require('flush.pl'); + +# force flush after every write or print +$| = 1; + +html_begin("In Progress"); + +print CLIENT "<H3><CENTER>Running WebStone</CENTER></H3><PRE>"; +show_model(); +&flush(CLIENT); +&flush(STDOUT); + +&start_runbench(); + +print CLIENT <<EOF +<TITLE>WebStone Completed</TITLE> +</PRE><CENTER> +<FORM METHOD=POST ACTION="http://localhost:$html_port$wd/bin/view-results.pl"> +<INPUT TYPE="submit" VALUE="View Results"> +</CENTER> +EOF + ; + +html_end(); + +sub start_runbench { + $command = "cd $wd/bin; ./runbench"; + system($command); +} + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/tabs2html b/ACE/apps/JAWS/clients/WebSTONE/bin/tabs2html new file mode 100755 index 00000000000..8c7d851c357 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/tabs2html @@ -0,0 +1,13 @@ +#! /bin/sh + +nawk ' +BEGIN { FS=" " ; print "<BODY><TABLE>" } +{ + print "<TR ALIGN=RIGHT VALIGN=BOTTOM>" + for (i=1; i <= NF; i++) { + print "<TD>" $i "</TD>" + } + print "</TR>" +} +END { print "</TABLE></BODY>" } +' $* diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/view-results.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/view-results.pl new file mode 100755 index 00000000000..ac375746e8a --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/view-results.pl @@ -0,0 +1,55 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +require('wscollect.pl'); + +$debug = 0; + +$printedTitles = 0; + +html_begin("Results"); + +print CLIENT "<H3>WebStone Results</H3>"; + +($debug) && print STDERR "opening table\n"; +print CLIENT "<BODY><TABLE BORDER=1>\r"; + +@directories = ("$wd/bin/runs"); +directory: for (@directories) { + &find($_); +} + +($debug) && print STDERR "closing table\n"; +print CLIENT "</TABLE></BODY>\r"; + +html_end(); + +# end main + +sub printcustom { + if (!$printedTitles) { + $printedTitles = 1; + print CLIENT "<TR>"; + for $title (@title) { + print CLIENT "<TH>$title</TH>\r"; + } # end for title + print CLIENT "</TR>\r"; + } + print CLIENT "<TR>"; + $first_column = 1; + for $data (@data) { + if ($first_column) { + $first_column = 0; + print CLIENT "<TD><A HREF=$wd/bin/runs/$data>$data</A></TD>\r"; + } else { + print CLIENT "<TD ALIGN=RIGHT>$data</TD>\r"; + } + } # end for data + print CLIENT "</TR>\r"; +} + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/webstone-gui.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/webstone-gui.pl new file mode 100755 index 00000000000..cb0c7224c09 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/webstone-gui.pl @@ -0,0 +1,318 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ + +require 'conf/paths.pl'; + +#$debug = 1; +$HELPME="http://reality.sgi.com/employees/mblakele_engr/WebStone/"; +$| = 1; # set pipes to hot + +&html(); + +sub html { + local($helper, $wd); + + &start_html_server(); + # These strings are used in, among others, PERL-to-HTML scripts. + # + $wd = `pwd`; + chop $wd; + + print "$html_port\n" if $debug; + + $HTML_STARTPAGE = "http://localhost:$html_port$wd/doc/WebStone.html"; + + # + # Fork off the HTML client, and fork off a server process that + # handles requests from that client. The parent process waits + # until the client exits and terminates the server. + # + print "Starting $MOSAIC...\n" if $debug; + + if (($client = fork()) == 0) { + foreach (keys %ENV) { + delete $ENV{$_} if (/proxy/i && !/no_proxy/i); + } + exec($MOSAIC, "$HTML_STARTPAGE") + || die "cannot exec $MOSAIC: $!"; + } + + if (($server = fork()) == 0) { + if (($helper = fork()) == 0) { + alarm 3600; + &patience(); + } + kill 'TERM',$helper; + $SIG{'PIPE'} = 'IGNORE'; + for (;;) { + accept(CLIENT, SOCK) || die "accept: $!"; + select((select(CLIENT), $| = 1)[0]); + &process_html_request(); + close(CLIENT); + } + } + + # + # Wait until the client terminates, then terminate the server. + # + close(SOCK); + waitpid($client, 0); + kill('TERM', $server); + exit; +} + +# +# Set up a listener on an arbitrary port. There is no good reason to +# listen on a well-known port number. +# +sub start_html_server { + local($sockaddr, $proto, $junk); + + $AF_INET = 2; + $SOCK_STREAM = 2; + $PORT = 0; #1024; + + $sockaddr = 'S n a4 x8'; + $this = pack($sockaddr, $AF_INET, $PORT, "\0\0\0\0"); + ($junk, $junk, $proto) = getprotobyname('tcp'); + socket(SOCK, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!"; + setsockopt(SOCK, 0xffff, 0x0004, 1) || die "setsockopt: $!"; + bind(SOCK, $this) || die "bind: $!"; + listen(SOCK, 1) || die "listen: $!"; + ($junk, $html_port) = unpack($sockaddr, getsockname(SOCK)); +} + + +# +# Process one client request. We expect the client to send stuff that +# begins with: +# +# command /password/perl_script junk +# +# Where perl_script is the name of a perl file that is executed via +# do "perl_script"; +# +# In case of a POST command the values in the client's attribute-value +# list are assigned to the corresponding global PERL variables. +# +sub process_html_request { + local($request, $command, $script, $magic, $url, $peer); + local(%args); + + # + # Parse the command and URL. Update the default file prefix. + # + $request = <CLIENT>; + print $request if $debug; + ($command, $url) = split(/\s+/, $request); + if ($command eq "" || $command eq "QUIT") { + return; + } + + #($junk, $script) = split(/\//, $url, 2); + #($script, $html_script_args) = split(',', $script, 2); + #($HTML_CWD = "file:$script") =~ s/\/[^\/]*$//; + $script = $url; + + while (<CLIENT>) { + last if (/^\s+$/); + } + + if ($command eq "GET") { + if (-d $script) { + get_dir($script); + } + elsif ($script =~ /\.pl\b/) { + perl_html_script($script); + } + else { + get_file($script); + } + } elsif ($command eq "POST") { + + print $request if $debug; + flush; + # + # Process the attribute-value list. + # + if ($_ = <CLIENT>) { + print "Hi $_" if $debug; + flush; + s/\s+$//; + s/^/\n/; + s/&/\n/g; + $html_post_attributes = ''; + $* = 1; + for (split(/(%[0-9][0-9A-Z])/, $_)) { + $html_post_attributes .= (/%([0-9][0-9A-Z])/) ? + pack('c',hex($1)) : $_; + } + %args = ('_junk_', split(/\n([^=]+)=/, $html_post_attributes)); + delete $args{'_junk_'}; + for (keys %args) { + print "\$$_ = $args{$_}\n" if $debug; + ${$_} = $args{$_}; + } + perl_html_script($script); + } else { + &bad_html_form($script); + } + } else { + &bad_html_command($request); + } +} + + +# +# Unexpected HTML command. +# +sub bad_html_command { + local($request) = @_; + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>Unknown command</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>Unknown command</H1> +The command <TT>$request<TT> was not recognized. +</BODY> +</HTML> +EOF +; +} + +# +# Execute PERL script +# +sub perl_html_script { + local($script) = @_; + + if (! -e $script) { + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>File not found</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>File not found</H1> +The file <TT>$script</TT> does not exist or is not accessible. +</BODY> +</HTML> +EOF +; return; + } + do $script; + if ($@ && ($@ ne "\n")) { + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>Command failed</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>Command failed</H1> +$@ +</BODY> +</HTML> +EOF +; + } +} + +# +# Missing attribute list +# +sub bad_html_form { + local($script) = @_; + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>No attribute list</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>No attribute list</H1> + +No attribute list was found. +</BODY> +</HTML> +EOF +; +} + +# +# Give them something to read while the server is initializing. +# +sub patience { + for (;;) { + accept(CLIENT, SOCK) || die "accept: $!"; + <CLIENT>; + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>Initializing...</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>Initializing...</H1> +WebStone is initializing... +</BODY> +</HTML> +EOF +; + close(CLIENT); + } +} + +sub get_file { + local($file) = @_; + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>$file</TITLE> +</HEAD> +<H1>$file</H1> +<BODY><PRE> +EOF + unless ($file =~ /(html|htm|gif|jpeg|jpg)\b/); + + open(FILE, $file); + while (<FILE>) { + print CLIENT $_; + } + close(FILE); + + print CLIENT <<EOF +</PRE> +</HTML> +EOF + unless ($file =~ /(html|htm|gif|jpeg|jpg)\b/); +} + +sub get_dir { + local($dir) = @_; + opendir(DIRECTORY, $dir); + @listing = readdir(DIRECTORY); + closedir(DIRECTORY); + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>$dir</TITLE> +</HEAD> +<H1>$dir</H1> +<BODY> +EOF + ; + + while (<@listing>) { + print CLIENT "<P><A HREF=$dir/$_>$_</A>"; + } + print CLIENT "</HTML>"; +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/write-testbed.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/write-testbed.pl new file mode 100755 index 00000000000..f16d626f2ad --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/write-testbed.pl @@ -0,0 +1,49 @@ +#!/pkg/gnu/bin//perl5 +# +#$Id$ +# +# write new values from form to $wd/conf/testbed, and run WebStone +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin("Current Configuration"); + +&show_model(); +&write_data(); + +print CLIENT <<EOF +<HR> +<FORM METHOD="POST" ACTION="$wd/bin/runbench.pl"> +<P><INPUT TYPE="SUBMIT" VALUE="Run WebStone"> +</FORM> +</DL> + +EOF + ; + +html_end(); + +# end main + +sub write_data { + rename("$wd/conf/testbed", "$wd/conf/testbed.bak") || + die "rename testbed: $!\n"; + open(TESTBED, ">>$wd/conf/testbed") || die "open testbed: $!\n"; + + print CLIENT "<PRE>"; + + foreach $key (@keylist) { + $$key =~ s/\+/ /g; + $newvalue = "$key=\"$$key\"\n"; + print CLIENT $newvalue; + print TESTBED $newvalue; + } + + print CLIENT "</PRE>"; + + close(TESTBED); +} + +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/bin/wscollect.pl b/ACE/apps/JAWS/clients/WebSTONE/bin/wscollect.pl new file mode 100755 index 00000000000..13511bdbb53 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/bin/wscollect.pl @@ -0,0 +1,142 @@ +#!/pkg/gnu/bin//perl +# +#$Id$ +# +# $Header$ +# updated version of the old wscollect script which goes through +# webstone run directories and summarizes the output in tabular +# format. +# syc 4/25/96 +# + +require "find.pl"; + +# +# the list @runs contains the timestamps for the runs which are found +# during the traversal of the runs directory. This list is used for +# indices into the associative arrays for storing run information. +# +# $numclients{ $time } - number of clients for the run +# $connrate{ $time } - connection rate average +# $littlesload{ $time } - little's load factor +# $latency{ $time } - latency average +# $error{ $time } - error rate +# $throughput{ $time } - throughput + +local( @runs, + %numclients, + %connrate, + %littlesload, + %latency, + %error, + %throughput); + +# Got rid of the trick hack of the title names, someone can put it +# back in later +@title = ( "Timestamp", + "Total number of clients", + "Connection rate average (conn/s)", + "Little's Load Factor", + "Average Latency (seconds)", + "Error Level (%)", + "Throughput avg. for all connections (MBits/s)"); + + +push( @ARGV, ".") if ( !@ARGV ); + +for (@ARGV) { + &find( $_ ); +} + +&PrintOutput; + +1; + +sub wanted { + local( $filename ) = $_; + + return unless ( $filename =~ /run/ ); + + local( $instats) = 0; + local( $runtime, $tag, $data, $cruft, @cruft ); + + open( FILE, $filename ) || return; # bail if failed to open + $runtime = `pwd`; + @cruft = split(/\//,$runtime); + $runtime = pop( @cruft); + chop( $runtime); + push( @runs, $runtime); + while ( $line = <FILE>) { + if (! $instats) { + $instats = 1 if ( $line =~ /^WEBSTONE 2\.0 results/ ); + next; + } + chop( $line ); + ( $tag, $data ) = split( /:?\s{2,}|\t/, $line); + + # perl hack to emulate case/switch statement + $tag =~ /number of clients/ && + ($numclients{ $runtime } = $data, next); + $tag =~ /error rate/ && + (( $error{ $runtime }) = $data =~ /([\d\.]+)/, next); + $tag =~ /connection rate/ && + (( $connrate{ $runtime }) = $data =~ /([\d\.]+)/, next); + $tag =~ /Server thruput/ && + (( $throughput{ $runtime }) = $data =~ /([\d\.]+)/, next); + $tag =~ /Little's Load/ && + (( $littlesload{ $runtime}) = $data =~ /([\d\.]+)/, next); # ' + $tag =~ /Average response time/ && + (( $latency{ $runtime } ) = $data =~ /([\d\.]+)/, next); + } + close( FILE ); + unless ( $throughput{ $runtime} ) { + pop( @runs); # if we didn't get a throughput, then the + # data is incomplete and just drop this run + } +} + + +sub printdata { + local ($timestamp, $num_clients, $conn_rate, + $load, $latency, $error, $tput) = @_; + format STDOUT = +@<<<<<<<<<<< @###### @######.## @####.## @###.#### @####.#### @######.## +$timestamp, $num_clients, $conn_rate, $load, $latency, $error, $tput +. + + if (!$printedTitles) { + $printedTitles = 1; + ($ttimestamp, $tnum_clients, $tconn_rate, + $tload, $tlatency, $terror, $ttput) = @title; + format STDOUT_TOP = +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +---------------------------------------------------------------------------- +. + # write STDOUT_TOP; + } # end if printedTitles + write STDOUT; +} + +sub PrintOutput { + local( $runtime ); + + for $runtime (sort @runs) { + &printdata( $runtime, $numclients{ $runtime}, $connrate{ $runtime}, + $littlesload{ $runtime}, $latency{ $runtime}, $error{ $runtime}, + $throughput{ $runtime}); + } +} + + + + + diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist new file mode 100644 index 00000000000..5368e28e460 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist @@ -0,0 +1,6 @@ +# Sample filelist, abstracted from access logs +/file500.html 350 #500 +/file5k.html 500 #5125 +/file50k.html 140 #51250 +/file500k.html 9 #512500 +/file5m.html 1 #5248000 diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.cgi-heavy b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.cgi-heavy new file mode 100644 index 00000000000..84272eee0f7 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.cgi-heavy @@ -0,0 +1,6 @@ +# Modified sample model; fully dynamic content +/file.cgi-send?size=500 350 +/file.cgi-send?size=5125 500 +/file.cgi-send?size=51250 140 +/file.cgi-send?size=512500 9 +/file.cgi-send?size=5248000 1 diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-heavy b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-heavy new file mode 100644 index 00000000000..de9c4fe4765 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-heavy @@ -0,0 +1,6 @@ +# Modified sample model; fully dynamic content +/file.dyn-send?size=500 350 +/file.dyn-send?size=5125 500 +/file.dyn-send?size=51250 140 +/file.dyn-send?size=512500 9 +/file.dyn-send?size=5248000 1 diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-light b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-light new file mode 100644 index 00000000000..2c35810e75d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-light @@ -0,0 +1,6 @@ +# Modified sample model; added light dynamic content use +/file500.html 350 #500 +/file5k.html 500 #5125 +/file.dyn-send?size=51250 140 +/file500k.html 9 #512500 +/file5m.html 1 #5248000 diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-medium b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-medium new file mode 100644 index 00000000000..2a0abbb2b9f --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.dynamic-medium @@ -0,0 +1,6 @@ +# Modified sample model; added medium dynamic content use +/file.dyn-send?size=500 350 +/file5k.html 500 #5125 +/file.dyn-send?size=51250 140 +/file500k.html 9 #512500 +/file5m.html 1 #5248000 diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.homepage b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.homepage new file mode 100644 index 00000000000..b759828757a --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.homepage @@ -0,0 +1,2 @@ +# home page /index.html only +/index.html diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.sample b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.sample new file mode 100644 index 00000000000..5368e28e460 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.sample @@ -0,0 +1,6 @@ +# Sample filelist, abstracted from access logs +/file500.html 350 #500 +/file5k.html 500 #5125 +/file50k.html 140 #51250 +/file500k.html 9 #512500 +/file5m.html 1 #5248000 diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.standard b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.standard new file mode 100644 index 00000000000..5368e28e460 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/filelist.standard @@ -0,0 +1,6 @@ +# Sample filelist, abstracted from access logs +/file500.html 350 #500 +/file5k.html 500 #5125 +/file50k.html 140 #51250 +/file500k.html 9 #512500 +/file5m.html 1 #5248000 diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/fileset b/ACE/apps/JAWS/clients/WebSTONE/conf/fileset new file mode 100644 index 00000000000..064fd7b3098 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/fileset @@ -0,0 +1,32 @@ +0k file0k.html +500 file500.html +1k file1k.html +2k file2k.html +3k file3k.html +4k file4k.html +5k file5k.html +6k file6k.html +7k file7k.html +8k file8k.html +9k file9k.html +10k file10k.html +11k file11k.html +12k file12k.html +13k file13k.html +14k file14k.html +15k file15k.html +16k file16k.html +17k file17k.html +18k file18k.html +19k file19k.html +20k file20k.html +21k file21k.html +29k file29k.html +33k file33k.html +45k file45k.html +50k file50k.html +64k file64k.html +115k file115k.html +200k file200k.html +500k file500k.html +5m file5m.html diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/paths.pl b/ACE/apps/JAWS/clients/WebSTONE/conf/paths.pl new file mode 100755 index 00000000000..e6fee6764e5 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/paths.pl @@ -0,0 +1,4 @@ +#$Id$ + +$MOSAIC="/pkg/www/bin/netscape"; + diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/paths.sh b/ACE/apps/JAWS/clients/WebSTONE/conf/paths.sh new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/paths.sh diff --git a/ACE/apps/JAWS/clients/WebSTONE/conf/testbed b/ACE/apps/JAWS/clients/WebSTONE/conf/testbed new file mode 100644 index 00000000000..13452b41a56 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/conf/testbed @@ -0,0 +1,33 @@ +### BENCHMARK PARAMETERS -- EDIT THESE AS REQUIRED +ITERATIONS="1" +MINCLIENTS="15" +MAXCLIENTS="15" +CLIENTINCR="3" +### this is actually the number of loops: +TIMEPERRUN="1000" + + +### SERVER PARAMETERS -- EDIT AS REQUIRED +PROXYSERVER= +SERVER="tango-cip" +PORTNO=6666 +SERVERINFO=uname +#OSTUNINGFILES="/var/sysgen/master.d/bsd" +#OSTUNINGFILES="/dev/null" +#WEBSERVERDIR="/usr/ns-home" +#WEBDOCDIR="$WEBSERVERDIR/docs" +#WEBSERVERTUNINGFILES="$WEBSERVERDIR/httpd-80/config/magnus.conf $WEBSERVERDIR/httpd-80/config/obj.conf" + +# WE NEED AN ACCOUNT WITH A FIXED PASSWORD, SO WE CAN REXEC +# THE WEBSTONE CLIENTS +CLIENTS="mambo merengue lambada" +#CLIENTS="lindy cumbia" +CLIENTACCOUNT=sumedh +CLIENTPASSWORD=yourpasswd +CLIENTINFO=uname +TMPDIR=/tmp + +# Possibly system-specific +RCP="rcp" +RSH="rsh" + diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/COPYING b/ACE/apps/JAWS/clients/WebSTONE/doc/COPYING new file mode 100644 index 00000000000..13057b45514 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/COPYING @@ -0,0 +1,348 @@ + While most of the source code in WebStone is covered by the terms +in the file LICENSE, the following files are covered by the GNU license, +reproduced below: + + config.guess + config.sub + +----------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/FAQ-webstone.html b/ACE/apps/JAWS/clients/WebSTONE/doc/FAQ-webstone.html new file mode 100644 index 00000000000..e52f00490fc --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/FAQ-webstone.html @@ -0,0 +1,403 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<HTML VERSION="2.0"> +<HEAD> +<!-- $Id$ --> +<!-- WEBMAGIC VERSION NUMBER="2.0.1" --> +<!-- WEBMAGIC TRANSLATION NAME="ServerRoot" SRC="/var/www/htdocs/" DST="/" --> +<!-- WEBMAGIC TRANSLATION NAME="ProjectRoot" SRC="./" DST="" --> +<TITLE>WebStone FAQ</TITLE> +</HEAD> +<BODY> +<P><!-- Changed by: Michael Blakeley, 9-Nov-1995 --></P> +<H1><IMG SRC="webstone.gif" WIDTH="534" HEIGHT="174" SGI_SETWIDTH SGI_SETHEIGHT SGI_FULLPATH="/disk6/WebStone-2.0/doc/webstone.gif"></H1> +<CENTER><H1 ALIGN="CENTER">WebStone</H1> +</CENTER><CENTER><H2 ALIGN="CENTER">Frequently Asked Questions, with Answers</H2> +</CENTER><CENTER><ADDRESS ALIGN="CENTER"><A HREF="mailto:schan@engr.sgi.com">Stephen Chan, schan@engr.sgi.com</A></ADDRESS> +</CENTER><CENTER><ADDRESS ALIGN="CENTER"><A HREF="http://www.sgi.com/Products/WebFORCE/">WebFORCE</A> Technical Marketing, <A HREF="http://www.sgi.com">Silicon Graphics</A></ADDRESS> +</CENTER><CENTER><ADDRESS ALIGN="CENTER">Last revised: 9 November 1995</ADDRESS> +</CENTER><HR> +<P><STRONG>This document answers frequently-asked questions about WebStone.</STRONG> </P> +<UL> +<LI><A HREF="#meta-FAQ">Meta-FAQ</A>: What is this document? Where can I get a copy? +<LI><A HREF="#diff">What is the difference between WebStone 1.1 and WebStone 2.0?</A> +<LI><A HREF="#compare1.1&2">Can I compare WebStone 1.1 and WebStone 2.0 numbers against each other?</A> +<LI><A HREF="#what-is">What is WebStone?</A> +<LI><A HREF="#webperf">What about Webperf?</A> +<LI><A HREF="#what-does">What does WebStone do?</A> +<LI><STRONG><A HREF="#_wmh2_815967937">Feature Enhancements in WebStone 2.0</STRONG></A> +<LI><A HREF="#does-not">What doesn't WebStone do?</A> +<LI><A HREF="#obtaining">Where can I get WebStone?</A> +<LI><A HREF="#running">How do I run WebStone?</A> +<UL> +<LI>Experimental GUI +</UL> +<LI><A HREF="#common-problems">Common problems when running WebStone</A> +<UL> +<LI><A HREF="#swap-space">Out of swap space</A> +<LI><A HREF="#timing-info">Error reading timing info</A> +</UL> +<LI><A HREF="#interpreting">What do the results mean?</A> +<LI><A HREF="#majordomo">I'm still having problems. Where can I get help?</A> +<LI><A HREF="#legal">Legal issues</A> +</UL> +<P>If you have comments about this document, please forward them to the <A HREF="mailto:mblakele@engr.sgi.com">author</A>. </P> +<HR> +<H2><A NAME="meta-FAQ">Meta-FAQ: What is this document? Where can I get a copy?</A></H2> +<P>This is a list of answers to Frequently Asked Questions (FAQ) about WebStone. +The latest copy is always available at <A HREF="http://www.sgi.com/Products/WebFORCE/WebStone">http://www.sgi.com/Products/WebFORCE/WebStone/</A> and via the WebStone mailing list. The FAQ is periodically posted to the <A HREF="#majordomo">WebStone mailing list</A>, and to the USENET newsgroup <A HREF="news:comp.benchmarks">comp.benchmarks</A>. </P> +<HR> +<H2><A NAME="diff">What is the difference between WebStone 1.1 and WebStone 2.0?</A></H2> +<P>WebStone 2.0 is a rewrite of the WebStone 1.1 code. Significant changes +have been made both in the code and in the fileset and run rules. Many bugs +were eliminated, support for other platforms has been included and many +new features have been added. The WebStone 1.1 and WebStone 2.0 numbers +cannot be compared, since so much has changed. In general, WebStone 1.1 +will give higher connections/second values, but lower throughput numbers +than WebStone 2.0.</P> +<HR> +<H2><A NAME="compare1.1&2">Can I compare WebStone 1.1 and WebStone 2.0 numbers against each other?</A></H2> +<P>Absolutely NOT! WebStone 1.1 numbers are based on a different fileset, as +well as an older version of the benchmarking software. The WebStone 1.1 +fileset was based on a fileset with a smaller average filesize, so that +the number of connections per second will tend to be higher (all things +being equal). The WebStone 2.0 fileset is based on observations of several +real world sites, and the distribution of the filesizes found there. This +fileset is also similar to the fileset chosen by the SPEC committee for +their benchmark.</P> +<P>While it is possible to convert the 1.1 fileset to a 2.0 format and then +test it, the resulting numbers will not be the same, because the underlying +software used to perform the testing has changed. WebStone 1.1 was also +heavily abused because of the lack of run rules, and reporting rules. It +is recommended that everyone move to WebStone 2.0.</P> +<HR> +<P></P> +<H2><A NAME="what-is">What is WebStone?</A></H2> +<P>WebStone is a highly-configurable client-server benchmark for HTTP servers. </P> +<P>The original WebStone benchmark was released in March, 1995. The original +white paper describing this benchmark is available from <A HREF="http://www.sgi.com/Products/WebFORCE/WebStone">http://www.sgi.com/Products/WebFORCE/WebStone/.</A> </P> +<P>WebStone is not a proprietary benchmark - it is an open benchmark. The source +code is freely available, and anyone can examine it. By design, WebStone +does not unfairly favor SGI, Netscape, or any other company - it is simply +a performance measurement tool. </P> +<HR> +<H2><A NAME="webperf">What about Webperf?</A></H2> +<P>A SPEC SFS working group is presently adapting SPEC SFS to Web server benchmarking. +SGI's WebStone team is part of this working group, and we support fully +the effort. WebStone is available to fulfill the immediate Web benchmarking +needs - not to confuse the public.</P> +<P>Basically, if you like WebStone, use it. When SPEC releases Webperf, check +it out.</P> +<HR> +<H2><A NAME="what-does">What does WebStone do?</A></H2> +<P>WebStone makes a user-configurable number of HTTP 1.0 GET requests for specific +pages on a Web server. Any Web server can be tested, and any HTML content +can be used. </P> +<P>WebStone measures the throughput and latency of each HTTP transfer. By default, +only statistical data are returned, but the user may optionally request +data for each and every transaction. WebStone also reports transaction failures, +which translate into those little "Connection Refused" alerts in the real +world.</P> +<HR> +<H2><A NAME="_wmh2_815967937">Feature Enhancements in WebStone 2.0</A></H2> +<P>WebStone 2.0 includes support for testing proxy servers, as well as more +flexible handling of URL's that enable WebStone to test a wide variety of +content types. The code has also been significantly rewritten so that it +is more robust and portable.</P> +<HR> +<H2><A NAME="does-not">What doesn't WebStone do?</A></H2> +<P>WebStone does not yet do any of the following (listed roughly in order of +planned implementation): </P> +<UL> +<LI>POST transactions, widely used for CGI-bin scripts +</UL> +<P>If you have additional requests for WebStone functionality, contact the <A HREF="#majordomo">WebStone mailing list</A>. </P> +<HR> +<H2><A NAME="obtaining">Where can I get WebStone?</A></H2> +<P>The latest copy of WebStone, and of this FAQ, is available at <A HREF="http://www.sgi.com/Products/WebFORCE/WebStone">http://www.sgi.com/Products/WebFORCE/WebStone</A> </P> +<HR> +<H2><A NAME="running">How do I run WebStone?</A></H2> +<P>WebStone includes a README file which may answer some of your questions. +However, here's a brief overview. </P> +<OL> +<LI><A HREF="#test-bed">Set up your test-bed</A> +<LI><A HREF="#loading-webstone">Load WebStone onto your webmaster </A> +<LI><A HREF="#edit-runbench">Edit <CODE>testbed</CODE></A> +<LI><A HREF="#file-list">Write a file list</A> +<LI><A HREF="#start-benchmark">Start the benchmark</A> +<LI><A HREF="#collect-results">Collect the results</A> +</OL> +<H3>WebStone now has an experimental GUI!</H3> +<P>To try the GUI, make sure you have a Web browser, and run <CODE>./webstone -gui</CODE> from the WebStone base directory. You don't need to hand-edit the <CODE>testbed</CODE> file anymore, but you still need to edit <CODE>filelist</CODE> if you want to change the workload. This may not be necessary, since we've +distributed two real-world workload models with WebStone. </P> +<P>These are the stepts to follow to run the GUI </P> +<OL> +<LI><A HREF="#test-bed">Set up your test-bed</A> +<LI><A HREF="#loading-webstone">Load WebStone onto your webmaster </A> +<LI><CODE>./configure</CODE> +<LI><CODE>./webstone -gui</CODE> +</OL> +<P>If the GUI appears to hang, you can kill stray WebStone processes with <CODE>./webstone -kill</CODE> </P> +<H3><A NAME="test-bed">Setting up your test bed</A></H3> +<P>Your test bed should include, at minimum, two machines and a network. The +first machine is your Web server - it can be any HTTP 1.0-compliant server. +As far as WebStone is concerned, it's a black box. </P> +<P>You'll also need a webmaster and one or more webclients. These should be +Unix hosts, since WebStone hasn't been tested on any non-Unix operating +systems (feel free to port it, if you like). The webmaster and the webclient +may be the same machine, if desired: we've run up to 120 webclients and +the webmaster on a single 32MB Indy. </P> +<P>You must establish a trust relationship between your webmaster and webclients. +Each webclient must be set up so that the webmaster can use <CODE>rexec</CODE> to execute the WebStone on the client. This can be done with a guest account. +It's also helpful if root can <CODE>rexec</CODE> and <CODE>rcp</CODE> to the webclients, and even to the web server. This requires editing the <CODE>/.rhosts</CODE> and <CODE>/etc/host.equiv</CODE> files. Here's an example: </P> +<P><CODE>/.rhosts</CODE> (on each webclient) </P> +<PRE> +webmaster root +</PRE> +<P><CODE>/etc/hosts/equiv</CODE> (on each webclient) </P> +<PRE> +webmaster +</PRE> +<P>To make best use of WebStone, your webmaster should be equipped with a C +compiler, Perl, awk, and a Web browser. A data analysis program such as +GnuPlot may also come in handy. </P> +<P>Connect the webclients, the webmaster, and the web server to a common network. +To check your setup, load a browser on one of the webclients, and make sure +it can connect to the Web server. </P> +<H3><A NAME="loading-webstone">Loading WebStone</A></H3> +<P>Copy the WebStone distribution onto your webmaster. If your webmaster isn't +an SGI IRIX 5.3 machine, you'll have to make the binaries. Type <KBD>make</KBD> from the WebStone directory - this creates the following binaries: </P> +<PRE> +webmaster +webclient +</PRE> +<P>Common porting errors </P> +<UL> +<LI>If you want to use gcc instead of cc, change the CC variable in <CODE>src/Makefile</CODE>. +<LI>Many System V-based Unix implementations (such as Solaris 2.x) will need<CODE> LIBS = -lsocket -lnsl</CODE> in <CODE>src/Makefile</CODE>. +<LI>Some users may also need to comment out the definition of <CODE>rexec</CODE> in <CODE>webmaster.c</CODE> +</UL> +<P>If you encounter other errors, please contact the <A HREF="#majordomo">WebStone mailing list</A>. </P> +<P>Type <CODE>make install</CODE> to put the binaries in the <CODE>bin</CODE> directory. </P> +<P>When you run WebStone, the <CODE>distribute</CODE> script automatically copies the <CODE>webclient</CODE> binary to the other client systems. If you're running diverse clients (e.g., +a couple Suns, a couple BSD hosts), you'll want to comment the <CODE>distribute</CODE> script out of <CODE>bin/runbench</CODE>, and distribute host-specific versions of <CODE>webclient</CODE> by hand. </P> +<H3><A NAME="edit-runbench">Edit <CODE></A>testbed</CODE></H3> +<P>If you use the <CODE>webstone</CODE> script to automate WebStone, you'll want to edit the <CODE>conf/testbed</CODE> script. The <CODE>testbed</CODE> script contains several configurable parameters that WebStone relies on. +Here is an example: </P> +<PRE> +### BENCHMARK PARAMETERS -- EDIT THESE AS REQUIRED +ITERATIONS="3" +MINCLIENTS="8" +MAXCLIENTS="128" +CLIENTINCR="8" +TIMEPERRUN="30" + +### SERVER PARAMETERS -- EDIT AS REQUIRED +#PROXY= +SERVER="www" +PORTNO=80 +SERVERINFO=hinv +OSTUNINGFILES="/var/sysgen/master.d/bsd" +WEBSERVERDIR="/usr/ns-home" +WEBDOCDIR="$WEBSERVERDIR/docs" +WEBSERVERTUNINGFILES="$WEBSERVERDIR/httpd-80/config/magnus.conf $WEBSERVERDIR/httpd-80/config/obj.conf" + +# WE NEED AN ACCOUNT WITH A FIXED PASSWORD, SO WE CAN REXEC +# THE WEBSTONE CLIENTS +CLIENTS="webstone1 webstone2 webstone3 webstone4 webstone5" +CLIENTACCOUNT=guest +CLIENTPASSWORD=guest +CLIENTINFO=hinv +TMPDIR=/tmp +</PRE> +<P>Briefly, the first set of parameters means that the WebStone benchmark will +run from 8 clients to 128 clients, in increments of 8. Each increment will +run for 30 minutes, and the whole test will be repeated three times. This +test suite would take roughly 24 hours to complete. </P> +<P>Why multiple iterations? The WebStone benchmark is a stochastic process +so there will be variation from run to run, especially if your test file +sets have large files or if you approach overloading the server. 3 iterations +is about the minimum you should run just to see if there is variation and +to gauge the amount of variation. the <TT>TIMEPERRUN</TT> needs to be long enough to establish a steady state and allow it to dominate +the run. 30 minutes seems to be enough if the sizes of the files are small. +You may want to run the benchmark longer per run to minimize variation if +the files are large. </P> +<P>The second set of parameters means that we will test a server called "www" +at port 80 (note that the port number may be changed to accomodate proxy +servers or multiple servers on the same host). We will use four clients. +Also, we specify the location of a system tuning file (on Sun Solaris, one +could use /etc/system), and web server tuning files (specified for Netscape). +These files will be copied into the <CODE>runs</CODE> subdirectories for later reference. </P> +<P>Finally, we specify the WebStone account on the clients. Here, we use the +guest account, with a fixed password: guest. </P> +<H3><A NAME="file-list">Write a file list</A></H3> +<P>The basic WebStone tests expect a set of files to reside on the server to +be retrieved by the <TT>webstone</TT> client programs. The file list tells WebStone which files to retrieve. </P> +<P>It's possible to use an arbitrary set of fixed-length files for WebStone. +Although these files have the <TT>.html</TT> extension, they are used to represent files of many types. Basically we +treat "bits-as-bits". You can use the programs in the <TT>genfileset</TT> subdirectory to create the needed set of files, and copy them onto your +server: </P> +<PRE> + ./webstone -genfiles +</PRE> +<P>The sample file list shipped with WebStone uses the files created by genfiles: </P> +<P># Sample filelist, abstracted from access logs<BR> +/file500.html 350 #500<BR> +/file5k.html 500 #5125<BR> +/file50k.html 140 #51250<BR> +/file500k.html 9 #512500<BR> +/file5m.html 1 #5248000<BR> +</P> +<P>This filelist consists of 5 different files. The number following the filename +is the weight of this file in the distribution. All the weights are summed +together and the frequency of each file is the weight of that file over +the total weights.</P> +<P>For example, in this fileset the weights add up to 1000. So the the file500k.html +page will occur 350 out of 1000 times, and the file5m.html will occur once +every 1000 pages. </P> +<P>Note that the URI should be changed to a full URI when testing proxy servers, +for example, if the proxy server is called proxy, but the actual server +which stores the file is called seltzer1, you could use the following filelist:</P> +<P> #Sample filelist, abstracted from access logs<BR> +http://seltzer1.sgi.com/file500.html 350 #500<BR> +http://seltzer1.sgi.com/file5k.html 500 #5125<BR> +http://seltzer1.sgi.com/file50k.html 140 #51250<BR> +http://seltzer1.sgi.com/file500k.html 9 #512500<BR> +http://seltzer1.sgi.com/file5m.html 1 #5248000</P> +<P>This URI is the one which is passed to the proxy server, which in turn uses +it to fetch the file from seltzer1.sgi.com. Notice that the particular files +and the distribution are identical to the previous filelist. The other change +which would need to be made for testing proxy servers is to have an entry +"PROXY=proxy" in the testbed file and to specify the port where the proxy +server listens for requests.</P> +<P>Wherever possible, use the same pages for WebStone that you will use in +the real world. This means that you'll have a harder time comparing your +results with published results, but your results will more accurately reflect <STRONG>your</STRONG> situation. </P> +<H3><A NAME="start-benchmark">Start the benchmark</A></H3> +<P>type <CODE>./webstone</CODE> </P> +<P>The results of each run will be saved in a directory called <TT>runs</TT>. Note that the runbench script attempts to collect configuration information +about your client and server configurations such as netstat results. You +may see some error messages if your clients don't have netstat or other +utilities. </P> +<H3><A NAME="collect-results">Collect the results</A></H3> +<P>The WebStone summary statistics generated by <TT>webmaster</TT> are saved by <TT>runbench</TT> in a date stamped subdirectory of the <TT>runs</TT> directory in the current directory similar to: </P> +<PRE> + runs/950804_2304/run +</PRE> +<P>The script wscollect is provided as a tool for collected the results of +all of the runs and generating a tab delimited file with all of the results. +This file can be read into a spreadsheet or read by other analysis programs. </P> +<PRE> + wscollect runs > runs.tabs +</PRE> +<P>An additional script called <TT>tabs2html</TT> will take a tab delimited file and produce an HTML 3.0 style table of the +results: </P> +<PRE> + tabs2html runs.tabs > runs.html +</PRE> +<HR> +<H2><A NAME="common-problems">Common problems when running WebStone</A></H2> +<H3><A NAME="swap-space">Out of swap space</A></H3> +<P>It's fairly common for the Web server under test to run out of swap space. +As a rule of thumb, make sure that you have swap space equal to the number +of server processes times the size of the largest test file. </P> +<P>For instance, if you're testing a 10MB file on a Netscape server with 64 +processes, you'll need to have at least 640MB of swap space. <CITE>N.B.</CITE>: On SGI IRIX 5.x, you can substitute large amounts of <EM>virtual swap space</EM>, since Netscape doesn't actually use all the space it asks for. </P> +<P>See your operating system-specific administration guide for details on adding +and configuring swap space. </P> +<H3><A NAME="timing-info">Error reading timing info</A></H3> +<P><STRONG>Question</STRONG>: </P> +<P>Running: </P> +<PRE> +webmaster -w webmaster -p 9990 -u flist -f config +</PRE> +<P>on jan.near.net </P> +<P>outputs: </P> +<PRE> +Waiting for READY from 6 clients +All READYs received +Sending GO to all clients +All clients started at Tue Aug 8 11:57:30 1995 +Waiting for clients completion +Reading results +.Error second reading timing info from one of the clients: +Interrupted system call +web child 1 did not respond. 3456 bytes read +.Error second reading timing info from one of the clients: +Interrupted system call +web child 0 did not respond. 3456 bytes read +</PRE> +<P>What does the second reading timing info contain? What might cause the second +read to fail while the first passes? </P> +<P><STRONG>Answer</STRONG>: </P> +<P>It's most likely that one of the WebStone clients died before it could report +results to the webmaster. We've squashed many circumstances in which this +happens, but bugs continue to appear, especially on systems we haven't tested. </P> +<P>We can't do much for this kind of problem without debugging traces. Edit <CODE>testbed</CODE>, and set the <CODE>DEBUG</CODE> parameter to <CODE>DEBUG=-d</CODE>, so that debugging info will be written to files named /tmp/webstone-debug.<PID>. </P> +<P>If you can replicate this problem with debugging turned on, please let us +know. We'd love to examine the traces. </P> +<P>Another possible source of problems with reading timing info is when a page +in the filelist did not get read by a client, but the webmaster was expecting +to find it. This can happen when the test time, number of clients and filelist +distribution are set up so that a file which gets read infrequently does +not get read _yet_ before the test period ends.This will get ironed out +in a later release of WebStone.</P> +<HR> +<H2><A NAME="interpreting">What do the results mean?</A></H2> +<P>WebStone primarily measures throughput (bytes/second) and latency (time +to complete a request). WebStone also reports pages/minute, connection rate +averages, and other numbers. Some of these may help you to sanity-check +the throughput measurements. </P> +<P>Two types of throughput are measured: aggregate and per-client. Both are +averaged over the entire test time and the entire client base. Aggregate +throughput is simply total bytes (body + header) transferred throughout +the test, divided by the total test time. Per-client throughput divides +aggregate throughput by the number of clients. </P> +<P>Two types of latency are reported: connection latency and request latency. +For each metric, the mean time is provided, as well as the standard deviation +of all data, plus the minimum and maximum times. Connection latency reflects +the time taken to establish a connection, while request latency reflects +the time to complete the data transfer once the connection has been established. </P> +<P>User-perceived latency will include the sum of connection and request latencies, +plus any network latency due to WAN connections, routers, modems, etc. </P> +<P>WebStone also reports a metric called <EM>Little's Ls</EM>. <EM>Ls</EM> is derived from Little's Law, and reflects how much time is spent by the +server on request processing, rather than overhead and errors. Ls. is also an indirect indicator of the average number of connections which +the web server has open at any particular instant. This number should stay +very close to the number of clients, or else some clients are being denied +access to the server at any given time.</P> +<P>If you load your Web servers high enough, you'll begin to see errors in +the results. That's fine (at least as far as WebStone is concerned). It +just means that your server is heavily loaded, and some clients aren't being +serviced before they time out. In fact, the number of errors at a given +load can be an excellent indicator of how your server will perform under +extremely heavy loads. </P> +<HR> +<H2><A NAME="majordomo">I'm still having problems. Where can I get help?</A></H2> +<P>Subscribe to the WebStone mailing list! Send a message to <A HREF="mailto:majordomo@engr.sgi.com">majordomo@engr.sgi.com</A> - the subject doesn't matter, but the content should be: </P> +<PRE> +subscribe webstone +</PRE> +<P>You should receive a message shortly, confirming that you've been added +to the mailing list. You can send to the whole list at <A HREF="mailto:webstone@engr.sgi.com">webstone@engr.sgi.com</A> - the authors of WebStone read the list, and they'll do their best to help. +Other list members may also be able to help. </P> +<P>If you have access to USENET News, you can also read and post to <A HREF="news:comp.benchmarks">comp.benchmarks</A>. As with any newsgroup, read the FAQ before posting! </P> +<P>There's also a mailing list devoted to the performance limits of the HTTP +protocol. You can subscribe by sending e-mail to <A HREF="mailto:www-speed-request@tipper.oit.unc.edu">www-speed-request@tipper.oit.unc.edu</A> with the text </P> +<PRE> +subscribe <your-email-address> +</PRE> +<HR> +<H2><A NAME="legal">Legal Stuff</A></H2> +<P>This file and all files contained in the WebStone distribution are copyright +© 1995, 1996 Silicon Graphics, Inc. </P> +<P>This software is provided without support and without any obligation on +the part of Silicon Graphics, Inc. to assist in its use, correction, modification +or enhancement. There is no guarantee that this software will be included +in future software releases, and it probably will not be included. </P> +<P>THIS SOFTWARE IS PROVIDED "AS IS" WITH NO WARRANTIES OF ANY KIND INCLUDING +THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE, +OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. </P> +<P>In no event will Silicon Graphics, Inc. be liable for any lost revenue or +profits or other special, indirect and consequential damages, even if Silicon +Graphics, Inc. has been advised of the possibility of such damages. </P> +</BODY> +</HTML> diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/LICENSE.html b/ACE/apps/JAWS/clients/WebSTONE/doc/LICENSE.html new file mode 100644 index 00000000000..c55918d1c3a --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/LICENSE.html @@ -0,0 +1,17 @@ +$Id$ +This file and all files contained in this directory are +copyright 1995, Silicon Graphics, Inc. + +This software is provided without support and without any obligation on the +part of Silicon Graphics, Inc. to assist in its use, correction, modification +or enhancement. There is no guarantee that this software will be included in +future software releases, and it probably will not be included. + +THIS SOFTWARE IS PROVIDED "AS IS" WITH NO WARRANTIES OF ANY KIND INCLUDING THE +WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE, +OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + +In no event will Silicon Graphics, Inc. be liable for any lost revenue or +profits or other special, indirect and consequential damages, even if +Silicon Graphics, Inc. has been advised of the possibility of such damages. + diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/WebStone.html b/ACE/apps/JAWS/clients/WebSTONE/doc/WebStone.html new file mode 100644 index 00000000000..e36a9b2d10d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/WebStone.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<HTML VERSION="2.0"> +<HEAD> +<!-- $Id$ --> +<!-- WEBMAGIC VERSION NUMBER="2.0" --> +<!-- WEBMAGIC TRANSLATION NAME="ServerRoot" SRC="/var/www/htdocs/" DST="/" --> +<!-- WEBMAGIC TRANSLATION NAME="ProjectRoot" SRC="./" DST="" --> +<TITLE>WebStone</TITLE> +</HEAD> +<BODY> +<P><A HREF="WebStone.html"><IMG SRC="webstone.gif" WIDTH="534" HEIGHT="174" BORDER="0" SGI_SETWIDTH SGI_SETHEIGHT SGI_FULLPATH="/usr/people/mblakele/WebStone-working/doc/webstone.gif"></A> +<H1>World Wide Web Server Benchmarking</H1> +<P>If you have any questions, please read the <EM><A HREF="FAQ-webstone.html">WebStone FAQ</EM></A>. +<HR> +<H2><A HREF="../bin/WebStone-setup.pl">Set up WebStone</A></H2> +<HR> +<H2><A HREF="../bin/WebStone-run.pl">Run WebStone</A></H2> +<HR> +<H2><A HREF="../bin/view-results.pl">View WebStone Results</A></H2> +<HR> +<H2><A HREF="../bin/WebStone-manage.pl">Administer WebStone</A></H2> +<HR> +<ADDRESS><A HREF="LICENSE.html">copyright 1995 Silicon Graphics</A></ADDRESS> +</BODY> +</HTML> diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/testbed.help b/ACE/apps/JAWS/clients/WebSTONE/doc/testbed.help new file mode 100755 index 00000000000..4b25a16e1fe --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/testbed.help @@ -0,0 +1,21 @@ +ITERATIONS: Total Number of times to run test suite. +MINCLIENTS: Start the test suite by running this number of clients. +MAXCLIENTS: End the test suite when this number of clients have run. +CLIENTINCR: Increment the number of clients by this number after each run. +TIMEPERRUN: Minutes to run each test. +PORTNO: TCP/IP port to test on the Web server. +SERVER: Name or IP number of Web server to be tested. +PROXYSERVER: Name or IP number of a proxy server through which to test. +CLIENTS: Name(s) or IP address(es) of machine(s) to use as WebStone clients. +OSTUNINGFILES: Full pathname(s) of OS tuning files to copy into the bin/runs directory. +WEBSERVERDIR: Base directory name for Web server. +WEBDOCDIR: Base directory name for Web server document root. +WEBSERVERTUNINGFILES: Full pathname(s) of Web server tuning files to copy into bin/runs. +CLIENTINFO: Name of an informational binary to run on each client. +SERVERINFO: Name of an informational binary to run on each server. +TMPDIR: Full pathname of a directory where temporary files may be stored. +CLIENTACCOUNT: Run WebStone on CLIENTS as this username, via rsh. +CLIENTPASSWORD: Password for CLIENTACCOUNT. This cannot be blank. +DEBUG: Leave blank, or set to -d to activate debugging mode. Debug files are written to TMPDIR. +RCP: Command to use for remote copying. Default: rcp. +RSH: Command to use for remote execution of a command. Default: rsh. diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/webstone-white-paper.ps b/ACE/apps/JAWS/clients/WebSTONE/doc/webstone-white-paper.ps new file mode 100644 index 00000000000..1ed0a6523f5 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/webstone-white-paper.ps @@ -0,0 +1,8974 @@ +%!PS-Adobe-3.0 + +%%Creator: Windows PSCRIPT + +%%Title: Microsoft Word - WEBSTON7.DOC + +%%BoundingBox: 18 9 593 784 + +%%DocumentNeededResources: (atend) + +%%DocumentSuppliedResources: (atend) + +%%Pages: (atend) + +%%BeginResource: procset Win35Dict 3 1 + +/Win35Dict 290 dict def Win35Dict begin/bd{bind def}bind def/in{72 + +mul}bd/ed{exch def}bd/ld{load def}bd/tr/translate ld/gs/gsave ld/gr + +/grestore ld/M/moveto ld/L/lineto ld/rmt/rmoveto ld/rlt/rlineto ld + +/rct/rcurveto ld/st/stroke ld/n/newpath ld/sm/setmatrix ld/cm/currentmatrix + +ld/cp/closepath ld/ARC/arcn ld/TR{65536 div}bd/lj/setlinejoin ld/lc + +/setlinecap ld/ml/setmiterlimit ld/sl/setlinewidth ld/scignore false + +def/sc{scignore{pop pop pop}{0 index 2 index eq 2 index 4 index eq + +and{pop pop 255 div setgray}{3{255 div 3 1 roll}repeat setrgbcolor}ifelse}ifelse}bd + +/FC{bR bG bB sc}bd/fC{/bB ed/bG ed/bR ed}bd/HC{hR hG hB sc}bd/hC{ + +/hB ed/hG ed/hR ed}bd/PC{pR pG pB sc}bd/pC{/pB ed/pG ed/pR ed}bd/sM + +matrix def/PenW 1 def/iPen 5 def/mxF matrix def/mxE matrix def/mxUE + +matrix def/mxUF matrix def/fBE false def/iDevRes 72 0 matrix defaultmatrix + +dtransform dup mul exch dup mul add sqrt def/fPP false def/SS{fPP{ + +/SV save def}{gs}ifelse}bd/RS{fPP{SV restore}{gr}ifelse}bd/EJ{gsave + +showpage grestore}bd/#C{userdict begin/#copies ed end}bd/FEbuf 2 string + +def/FEglyph(G )def/FE{1 exch{dup 16 FEbuf cvrs FEglyph exch 1 exch + +putinterval 1 index exch FEglyph cvn put}for}bd/SM{/iRes ed/cyP ed + +/cxPg ed/cyM ed/cxM ed 72 100 div dup scale dup 0 ne{90 eq{cyM exch + +0 eq{cxM exch tr -90 rotate -1 1 scale}{cxM cxPg add exch tr +90 rotate}ifelse}{cyP + +cyM sub exch 0 ne{cxM exch tr -90 rotate}{cxM cxPg add exch tr -90 + +rotate 1 -1 scale}ifelse}ifelse}{pop cyP cyM sub exch 0 ne{cxM cxPg + +add exch tr 180 rotate}{cxM exch tr 1 -1 scale}ifelse}ifelse 100 iRes + +div dup scale 0 0 transform .25 add round .25 sub exch .25 add round + +.25 sub exch itransform translate}bd/SJ{1 index 0 eq{pop pop/fBE false + +def}{1 index/Break ed div/dxBreak ed/fBE true def}ifelse}bd/ANSIVec[ + +16#0/grave 16#1/acute 16#2/circumflex 16#3/tilde 16#4/macron 16#5/breve + +16#6/dotaccent 16#7/dieresis 16#8/ring 16#9/cedilla 16#A/hungarumlaut + +16#B/ogonek 16#C/caron 16#D/dotlessi 16#27/quotesingle 16#60/grave + +16#7C/bar 16#82/quotesinglbase 16#83/florin 16#84/quotedblbase 16#85 + +/ellipsis 16#86/dagger 16#87/daggerdbl 16#88/circumflex 16#89/perthousand + +16#8A/Scaron 16#8B/guilsinglleft 16#8C/OE 16#91/quoteleft 16#92/quoteright + +16#93/quotedblleft 16#94/quotedblright 16#95/bullet 16#96/endash 16#97 + +/emdash 16#98/tilde 16#99/trademark 16#9A/scaron 16#9B/guilsinglright + +16#9C/oe 16#9F/Ydieresis 16#A0/space 16#A1/exclamdown 16#A4/currency + +16#A5/yen 16#A6/brokenbar 16#A7/section 16#A8/dieresis 16#A9/copyright + +16#AA/ordfeminine 16#AB/guillemotleft 16#AC/logicalnot 16#AD/hyphen + +16#AE/registered 16#AF/macron 16#B0/degree 16#B1/plusminus 16#B2/twosuperior + +16#B3/threesuperior 16#B4/acute 16#B5/mu 16#B6/paragraph 16#B7/periodcentered + +16#B8/cedilla 16#B9/onesuperior 16#BA/ordmasculine 16#BB/guillemotright + +16#BC/onequarter 16#BD/onehalf 16#BE/threequarters 16#BF/questiondown + +16#C0/Agrave 16#C1/Aacute 16#C2/Acircumflex 16#C3/Atilde 16#C4/Adieresis + +16#C5/Aring 16#C6/AE 16#C7/Ccedilla 16#C8/Egrave 16#C9/Eacute 16#CA + +/Ecircumflex 16#CB/Edieresis 16#CC/Igrave 16#CD/Iacute 16#CE/Icircumflex + +16#CF/Idieresis 16#D0/Eth 16#D1/Ntilde 16#D2/Ograve 16#D3/Oacute 16#D4 + +/Ocircumflex 16#D5/Otilde 16#D6/Odieresis 16#D7/multiply 16#D8/Oslash + +16#D9/Ugrave 16#DA/Uacute 16#DB/Ucircumflex 16#DC/Udieresis 16#DD/Yacute + +16#DE/Thorn 16#DF/germandbls 16#E0/agrave 16#E1/aacute 16#E2/acircumflex + +16#E3/atilde 16#E4/adieresis 16#E5/aring 16#E6/ae 16#E7/ccedilla 16#E8 + +/egrave 16#E9/eacute 16#EA/ecircumflex 16#EB/edieresis 16#EC/igrave + +16#ED/iacute 16#EE/icircumflex 16#EF/idieresis 16#F0/eth 16#F1/ntilde + +16#F2/ograve 16#F3/oacute 16#F4/ocircumflex 16#F5/otilde 16#F6/odieresis + +16#F7/divide 16#F8/oslash 16#F9/ugrave 16#FA/uacute 16#FB/ucircumflex + +16#FC/udieresis 16#FD/yacute 16#FE/thorn 16#FF/ydieresis ] def/reencdict + +12 dict def/IsChar{basefontdict/CharStrings get exch known}bd/MapCh{dup + +IsChar not{pop/bullet}if newfont/Encoding get 3 1 roll put}bd/MapDegree{16#b0 + +/degree IsChar{/degree}{/ring}ifelse MapCh}bd/MapBB{16#a6/brokenbar + +IsChar{/brokenbar}{/bar}ifelse MapCh}bd/ANSIFont{reencdict begin/newfontname + +ed/basefontname ed FontDirectory newfontname known not{/basefontdict + +basefontname findfont def/newfont basefontdict maxlength dict def basefontdict{exch + +dup/FID ne{dup/Encoding eq{exch dup length array copy newfont 3 1 roll + +put}{exch newfont 3 1 roll put}ifelse}{pop pop}ifelse}forall newfont + +/FontName newfontname put 127 1 159{newfont/Encoding get exch/bullet + +put}for ANSIVec aload pop ANSIVec length 2 idiv{MapCh}repeat MapDegree + +MapBB newfontname newfont definefont pop}if newfontname end}bd/SB{FC + +/ULlen ed/str ed str length fBE not{dup 1 gt{1 sub}if}if/cbStr ed + +/dxGdi ed/y0 ed/x0 ed str stringwidth dup 0 ne{/y1 ed/x1 ed y1 y1 + +mul x1 x1 mul add sqrt dxGdi exch div 1 sub dup x1 mul cbStr div exch + +y1 mul cbStr div}{exch abs neg dxGdi add cbStr div exch}ifelse/dyExtra + +ed/dxExtra ed x0 y0 M fBE{dxBreak 0 BCh dxExtra dyExtra str awidthshow}{dxExtra + +dyExtra str ashow}ifelse fUL{x0 y0 M dxUL dyUL rmt ULlen fBE{Break + +add}if 0 mxUE transform gs rlt cyUL sl [] 0 setdash st gr}if fSO{x0 + +y0 M dxSO dySO rmt ULlen fBE{Break add}if 0 mxUE transform gs rlt cyUL + +sl [] 0 setdash st gr}if n/fBE false def}bd/font{/name ed/Ascent ed + +0 ne/fT3 ed 0 ne/fSO ed 0 ne/fUL ed/Sy ed/Sx ed 10.0 div/ori ed -10.0 + +div/esc ed/BCh ed name findfont/xAscent 0 def/yAscent Ascent def/ULesc + +esc def ULesc mxUE rotate pop fT3{/esc 0 def xAscent yAscent mxUE transform + +/yAscent ed/xAscent ed}if [Sx 0 0 Sy neg xAscent yAscent] esc mxE + +rotate mxF concatmatrix makefont setfont [Sx 0 0 Sy neg 0 Ascent] mxUE + +mxUF concatmatrix pop fUL{currentfont dup/FontInfo get/UnderlinePosition + +known not{pop/Courier findfont}if/FontInfo get/UnderlinePosition get + +1000 div 0 exch mxUF transform/dyUL ed/dxUL ed}if fSO{0 .3 mxUF transform + +/dySO ed/dxSO ed}if fUL fSO or{currentfont dup/FontInfo get/UnderlineThickness + +known not{pop/Courier findfont}if/FontInfo get/UnderlineThickness get + +1000 div Sy mul/cyUL ed}if}bd/min{2 copy gt{exch}if pop}bd/max{2 copy + +lt{exch}if pop}bd/CP{/ft ed{{ft 0 eq{clip}{eoclip}ifelse}stopped{currentflat + +1 add setflat}{exit}ifelse}loop}bd/patfont 10 dict def patfont begin + +/FontType 3 def/FontMatrix [1 0 0 -1 0 0] def/FontBBox [0 0 16 16] + +def/Encoding StandardEncoding def/BuildChar{pop pop 16 0 0 0 16 16 + +setcachedevice 16 16 false [1 0 0 1 .25 .25]{pat}imagemask}bd end/p{ + +/pat 32 string def{}forall 0 1 7{dup 2 mul pat exch 3 index put dup + +2 mul 1 add pat exch 3 index put dup 2 mul 16 add pat exch 3 index + +put 2 mul 17 add pat exch 2 index put pop}for}bd/pfill{/PatFont patfont + +definefont setfont/ch(AAAA)def X0 64 X1{Y1 -16 Y0{1 index exch M ch + +show}for pop}for}bd/vert{X0 w X1{dup Y0 M Y1 L st}for}bd/horz{Y0 w + +Y1{dup X0 exch M X1 exch L st}for}bd/fdiag{X0 w X1{Y0 M X1 X0 sub dup + +rlt st}for Y0 w Y1{X0 exch M Y1 Y0 sub dup rlt st}for}bd/bdiag{X0 w + +X1{Y1 M X1 X0 sub dup neg rlt st}for Y0 w Y1{X0 exch M Y1 Y0 sub dup + +neg rlt st}for}bd/AU{1 add cvi 15 or}bd/AD{1 sub cvi -16 and}bd/SHR{pathbbox + +AU/Y1 ed AU/X1 ed AD/Y0 ed AD/X0 ed}bd/hfill{/w iRes 37.5 div round + +def 0.1 sl [] 0 setdash n dup 0 eq{horz}if dup 1 eq{vert}if dup 2 eq{fdiag}if + +dup 3 eq{bdiag}if dup 4 eq{horz vert}if 5 eq{fdiag bdiag}if}bd/F{/ft + +ed fm 256 and 0 ne{gs FC ft 0 eq{fill}{eofill}ifelse gr}if fm 1536 + +and 0 ne{SHR gs HC ft CP fm 1024 and 0 ne{/Tmp save def pfill Tmp restore}{fm + +15 and hfill}ifelse gr}if}bd/S{PenW sl PC st}bd/m matrix def/GW{iRes + +12 div PenW add cvi}bd/DoW{iRes 50 div PenW add cvi}bd/DW{iRes 8 div + +PenW add cvi}bd/SP{/PenW ed/iPen ed iPen 0 eq iPen 6 eq or{[] 0 setdash}if + +iPen 1 eq{[DW GW] 0 setdash}if iPen 2 eq{[DoW GW] 0 setdash}if iPen + +3 eq{[DW GW DoW GW] 0 setdash}if iPen 4 eq{[DW GW DoW GW DoW GW] 0 + +setdash}if}bd/E{m cm pop tr scale 1 0 moveto 0 0 1 0 360 arc cp m sm}bd + +/AG{/sy ed/sx ed sx div 4 1 roll sy div 4 1 roll sx div 4 1 roll sy + +div 4 1 roll atan/a2 ed atan/a1 ed sx sy scale a1 a2 ARC}def/A{m cm + +pop tr AG m sm}def/P{m cm pop tr 0 0 M AG cp m sm}def/RRect{n 4 copy + +M 3 1 roll exch L 4 2 roll L L cp}bd/RRCC{/r ed/y1 ed/x1 ed/y0 ed/x0 + +ed x0 x1 add 2 div y0 M x1 y0 x1 y1 r arcto 4{pop}repeat x1 y1 x0 y1 + +r arcto 4{pop}repeat x0 y1 x0 y0 r arcto 4{pop}repeat x0 y0 x1 y0 r + +arcto 4{pop}repeat cp}bd/RR{2 copy 0 eq exch 0 eq or{pop pop RRect}{2 + +copy eq{pop RRCC}{m cm pop/y2 ed/x2 ed/ys y2 x2 div 1 max def/xs x2 + +y2 div 1 max def/y1 exch ys div def/x1 exch xs div def/y0 exch ys div + +def/x0 exch xs div def/r2 x2 y2 min def xs ys scale x0 x1 add 2 div + +y0 M x1 y0 x1 y1 r2 arcto 4{pop}repeat x1 y1 x0 y1 r2 arcto 4{pop}repeat + +x0 y1 x0 y0 r2 arcto 4{pop}repeat x0 y0 x1 y0 r2 arcto 4{pop}repeat + +m sm cp}ifelse}ifelse}bd/PP{{rlt}repeat}bd/OB{gs 0 ne{7 3 roll/y ed + +/x ed x y translate ULesc rotate x neg y neg translate x y 7 -3 roll}if + +sc B fill gr}bd/B{M/dy ed/dx ed dx 0 rlt 0 dy rlt dx neg 0 rlt cp}bd + +/CB{B clip n}bd/ErrHandler{errordict dup maxlength exch length gt + +dup{errordict begin}if/errhelpdict 12 dict def errhelpdict begin/stackunderflow(operand stack underflow)def + +/undefined(this name is not defined in a dictionary)def/VMerror(you have used up all the printer's memory)def + +/typecheck(operator was expecting a different type of operand)def + +/ioerror(input/output error occured)def end{end}if errordict begin + +/handleerror{$error begin newerror{/newerror false def showpage 72 + +72 scale/x .25 def/y 9.6 def/Helvetica findfont .2 scalefont setfont + +x y moveto(Offending Command = )show/command load{dup type/stringtype + +ne{(max err string)cvs}if show}exec/y y .2 sub def x y moveto(Error = )show + +errorname{dup type dup( max err string )cvs show( : )show/stringtype + +ne{( max err string )cvs}if show}exec errordict begin errhelpdict errorname + +known{x 1 add y .2 sub moveto errhelpdict errorname get show}if end + +/y y .4 sub def x y moveto(Stack =)show ostack{/y y .2 sub def x 1 + +add y moveto dup type/stringtype ne{( max err string )cvs}if show}forall + +showpage}if end}def end}bd end + +%%EndResource + +/SVDoc save def + +%%EndProlog + +%%BeginSetup + +Win35Dict begin + +ErrHandler + +statusdict begin 0 setjobtimeout end + +statusdict begin statusdict /jobname (Microsoft Word - WEBSTON7.DOC) put end + +/oldDictCnt countdictstack def {}stopped + +{ countdictstack oldDictCnt lt { Win35Dict begin } + +{1 1 countdictstack oldDictCnt sub {pop end } for } ifelse } if + +/oldDictCnt countdictstack def {letter + +}stopped + +{ countdictstack oldDictCnt lt { Win35Dict begin } + +{1 1 countdictstack oldDictCnt sub {pop end } for } ifelse } if + +[ +{mark 1.0 1.0 .98 .9 .82 .68 .56 .48 .28 .1 .06 .0 counttomark dup 3 add -1 roll exch 2 sub mul dup floor cvi dup 3 1 roll sub exch dup 3 add index exch 2 add index dup 4 1 roll sub mul add counttomark 1 add 1 roll cleartomark } bind + +/exec load currenttransfer /exec load] cvx settransfer + +%%EndSetup + +%%Page: 1 1 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 83 83 0 0 0 75 /Times-Bold /font29 ANSIFont font + +0 0 0 fC + +278 772 1843 (WebSTONE: The First Generation in HTTP Server) 1843 SB + +938 869 524 (Benchmarking) 524 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +1087 1033 226 (Gene Trent) 226 SB + +1148 1092 103 (MTS) 103 SB + +1037 1151 326 (Silicon Graphics) 326 SB + +1091 1269 218 (Mark Sake) 218 SB + +1148 1328 103 (MTS) 103 SB + +1037 1387 326 (Silicon Graphics) 326 SB + +1055 1505 290 (February 1995) 290 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1041 1978 317 (ABSTRACT) 317 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +225 2097 110 (With ) 111 SB + +336 2097 74 (the ) 75 SB + +411 2097 145 (advent ) 146 SB + +557 2097 54 (of ) 55 SB + +612 2097 74 (the ) 76 SB + +688 2097 136 (Hyper ) 138 SB + +826 2097 105 (Text ) 107 SB + +933 2097 180 (Transfer ) 182 SB + +1115 2097 185 (Protocol ) 187 SB + +1302 2097 173 (\(HTTP\) ) 175 SB + +1477 2097 13 ( ) 15 SB + +1492 2097 40 (it ) 42 SB + +1534 2097 90 (was ) 92 SB + +1626 2097 84 (just ) 86 SB + +1712 2097 35 (a ) 37 SB + +1749 2097 141 (matter ) 143 SB + +1892 2097 54 (of ) 56 SB + +1948 2097 99 (time ) 101 SB + +2049 2097 126 (before) 126 SB + +225 2156 74 (the ) 81 SB + +306 2156 242 (commercial ) 249 SB + +555 2156 79 (use ) 86 SB + +641 2156 137 (would ) 144 SB + +785 2156 59 (be ) 66 SB + +851 2156 170 (evident. ) 177 SB + +1028 2156 13 ( ) 20 SB + +1048 2156 265 (Performance ) 272 SB + +1320 2156 145 (testing ) 152 SB + +1472 2156 54 (of ) 61 SB + +1533 2156 180 (different ) 187 SB + +1720 2156 198 (hardware ) 205 SB + +1925 2156 201 (platforms ) 209 SB + +2134 2156 41 (as) 41 SB + +225 2215 95 (well ) 96 SB + +321 2215 54 (as ) 55 SB + +376 2215 180 (different ) 182 SB + +558 2215 337 (implementations ) 339 SB + +897 2215 54 (of ) 56 SB + +953 2215 139 (HTTP ) 141 SB + +1094 2215 78 (has ) 80 SB + +1174 2215 119 (made ) 121 SB + +1295 2215 40 (it ) 42 SB + +1337 2215 203 (necessary ) 205 SB + +1542 2215 54 (to ) 56 SB + +1598 2215 133 (create ) 135 SB + +1733 2215 35 (a ) 37 SB + +1770 2215 95 (new ) 97 SB + +1867 2215 230 (benchmark ) 232 SB + +2099 2215 76 (that) 76 SB + +225 2274 85 (will ) 92 SB + +317 2274 121 (allow ) 128 SB + +445 2274 35 (a ) 43 SB + +488 2274 196 (customer ) 204 SB + +692 2274 123 (easily ) 131 SB + +823 2274 54 (to ) 62 SB + +885 2274 231 (understand ) 239 SB + +1124 2274 74 (the ) 82 SB + +1206 2274 262 (performance ) 270 SB + +1476 2274 271 (characterizes ) 279 SB + +1755 2274 54 (of ) 62 SB + +1817 2274 180 (different ) 188 SB + +2005 2274 170 (vendors.) 170 SB + +225 2333 90 (The ) 107 SB + +332 2333 280 (WebSTONE, ) 297 SB + +629 2333 35 (a ) 52 SB + +681 2333 95 (web ) 112 SB + +793 2333 156 (serving ) 173 SB + +966 2333 230 (benchmark ) 247 SB + +1213 2333 78 (has ) 95 SB + +1308 2333 105 (been ) 122 SB + +1430 2333 216 (developed ) 233 SB + +1663 2333 49 (in ) 66 SB + +1729 2333 59 (an ) 77 SB + +1806 2333 164 (attempt ) 182 SB + +1988 2333 54 (to ) 72 SB + +2060 2333 115 (better) 115 SB + +225 2392 231 (understand ) 237 SB + +462 2392 74 (the ) 81 SB + +543 2392 262 (performance ) 269 SB + +812 2392 249 (characterics ) 256 SB + +1068 2392 54 (of ) 61 SB + +1129 2392 102 (both ) 109 SB + +1238 2392 198 (hardware ) 205 SB + +1443 2392 84 (and ) 91 SB + +1534 2392 198 (software. ) 205 SB + +1739 2392 13 ( ) 20 SB + +1759 2392 90 (The ) 97 SB + +1856 2392 201 (following ) 208 SB + +2064 2392 111 (paper) 111 SB + +225 2451 195 (describes ) 203 SB + +428 2451 74 (the ) 82 SB + +510 2451 230 (benchmark ) 239 SB + +749 2451 49 (in ) 58 SB + +807 2451 188 (technical ) 197 SB + +1004 2451 121 (detail ) 130 SB + +1134 2451 84 (and ) 93 SB + +1227 2451 129 (issues ) 138 SB + +1365 2451 182 (involved ) 191 SB + +1556 2451 49 (in ) 58 SB + +1614 2451 230 (developing ) 239 SB + +1853 2451 83 (this ) 92 SB + +1945 2451 230 (benchmark.) 230 SB + +225 2510 99 (This ) 100 SB + +325 2510 230 (benchmark ) 231 SB + +556 2510 90 (was ) 91 SB + +647 2510 216 (developed ) 217 SB + +864 2510 169 (because ) 170 SB + +1034 2510 113 (there ) 114 SB + +1148 2510 44 (is ) 46 SB + +1194 2510 190 (currently ) 192 SB + +1386 2510 63 (no ) 65 SB + +1451 2510 117 (other ) 119 SB + +1570 2510 94 (way ) 96 SB + +1666 2510 54 (of ) 56 SB + +1722 2510 145 (testing ) 147 SB + +1869 2510 74 (the ) 76 SB + +1945 2510 230 (application.) 230 SB + +225 2569 1891 (This benchmark is intended for free distribution both this white paper and code. It is the intent ) 1892 SB + +2117 2569 58 (for) 58 SB + +225 2628 83 (this ) 89 SB + +314 2628 230 (benchmark ) 236 SB + +550 2628 54 (to ) 60 SB + +610 2628 117 (grow ) 123 SB + +733 2628 84 (and ) 90 SB + +823 2628 128 (better ) 134 SB + +957 2628 96 (help ) 102 SB + +1059 2628 84 (test ) 90 SB + +1149 2628 148 (system ) 154 SB + +1303 2628 262 (performance ) 268 SB + +1571 2628 71 (for ) 77 SB + +1648 2628 132 (future ) 138 SB + +1786 2628 167 (systems ) 173 SB + +1959 2628 84 (and ) 90 SB + +2049 2628 126 (HTTP) 126 SB + +225 2687 337 (implementations.) 337 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 2 2 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (2) 21 SB + +gr + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Page: 3 3 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (3) 21 SB + +gr + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 406 285 (Contents) 285 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +225 581 29 (1) 29 SB + +375 581 369 (Web Overview) 369 SB + +1575 581 160 (page 5) 160 SB + +225 719 29 (2) 29 SB + +375 719 549 (WebSTONE overview) 549 SB + +1575 719 160 (page 5) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 797 63 (2.1) 63 SB + +525 797 818 (The WebSTONE as a performance tester) 818 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 788 160 (page 6) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 866 76 (2.2 ) 76 SB + +525 866 533 (WebSTONE\222s measure of ) 533 SB + +1058 866 386 (server Performance) 386 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 857 160 (page 6) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 935 63 (2.3) 63 SB + +525 935 692 (What the WebSTONE doesn\222t test) 692 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 926 160 (page 7) 160 SB + +225 1064 29 (3) 29 SB + +375 1064 642 (WebSTONE Architecture) 642 SB + +1575 1064 160 (page 7) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1142 63 (3.1) 63 SB + +525 1142 448 (WebSTONE Software) 448 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1133 160 (page 8) 160 SB + +225 1261 29 (4) 29 SB + +375 1261 649 (Configuration Parameters) 649 SB + +1575 1261 160 (page 9) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1339 63 (4.1) 63 SB + +525 1339 274 (Duration test) 274 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1330 160 (page 9) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1408 63 (4.2) 63 SB + +525 1408 303 (Repetition test) 303 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1399 160 (page 9) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1477 63 (4.3) 63 SB + +525 1477 308 (Number of files) 308 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1468 160 (page 9) 160 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1546 63 (4.4) 63 SB + +525 1546 341 (Number of pages) 341 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1537 189 (page 10) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1615 63 (4.5) 63 SB + +525 1615 875 (Server software and hardware configuration) 875 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1606 189 (page 10) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1684 63 (4.6) 63 SB + +525 1684 478 (Number of Webchildren) 478 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1675 189 (page 10) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1753 63 (4.7) 63 SB + +525 1753 412 (Number of networks) 412 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1744 189 (page 10) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1822 63 (4.8) 63 SB + +525 1822 354 (Number of clients) 354 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1813 189 (page 11) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1891 63 (4.9) 63 SB + +525 1891 379 (Workload of pages) 379 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1882 189 (page 11) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1960 88 (4.10) 88 SB + +525 1960 167 (Logging) 167 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 1951 189 (page 11) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2029 88 (4.11) 88 SB + +525 2029 218 (Debugging) 218 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2020 189 (page 11) 189 SB + +225 2158 29 (5) 29 SB + +375 2158 551 (Workload Parameters) 551 SB + +1575 2158 189 (page 11) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2236 63 (5.1) 63 SB + +525 2236 401 (General modem mix) 401 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2227 189 (page 11) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2305 63 (5.2) 63 SB + +525 2305 241 (General mix) 241 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2296 189 (page 12) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2374 63 (5.3) 63 SB + +525 2374 299 (Media rich mix) 299 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2365 189 (page 12) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2443 63 (5.4) 63 SB + +525 2443 544 (General and media rich mix) 544 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2434 189 (page 12) 189 SB + +225 2572 29 (6) 29 SB + +375 2572 420 (Load Generation) 420 SB + +1575 2572 189 (page 12) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2650 76 (6.1 ) 76 SB + +525 2650 284 (Page selection) 284 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2641 189 (page 12) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2719 63 (6.2) 63 SB + +525 2719 236 (Page access) 236 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2710 189 (page 13) 189 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2788 63 (6.3) 63 SB + +525 2788 389 (Duration of the test) 389 SB + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +1575 2779 189 (page 13) 189 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 4 4 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (4) 21 SB + +gr + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +225 238 29 (7) 29 SB + +375 238 482 (Benchmark Results) 482 SB + +1575 238 189 (page 13) 189 SB + +225 307 73 (7.1) 73 SB + +375 307 485 (Summary of results) 485 SB + +1575 307 189 (page 20) 189 SB + +225 445 29 (8) 29 SB + +375 445 327 (Future Work) 327 SB + +1575 445 189 (page 21) 189 SB + +225 583 29 (9) 29 SB + +375 583 449 (Acknowledgments) 449 SB + +1575 583 189 (page 22) 189 SB + +225 721 58 (10) 58 SB + +375 721 491 (Author Information) 491 SB + +1575 721 189 (page 22) 189 SB + +225 859 58 (11) 58 SB + +375 859 114 (Refe) 114 SB + +489 859 158 (rences) 158 SB + +1575 859 189 (page 22) 189 SB + +225 997 58 (12) 58 SB + +375 997 309 (Trademarks) 309 SB + +1575 997 189 (page 22) 189 SB + +225 1135 187 (Figures) 187 SB + +225 1263 208 (Figure 3) 208 SB + +675 1263 798 (A WebSTONE test environment) 798 SB + +1575 1263 160 (page 7) 160 SB + +225 1332 267 (Figure 3.1 ) 267 SB + +675 1332 484 (Webchildren client ) 484 SB + +1575 1332 160 (page 8) 160 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 5 5 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (5) 21 SB + +gr + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 347 551 (1. Web Overview) 551 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 522 108 (Since) 108 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +483 498 19 ( ) 25 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +508 522 74 (the ) 80 SB + +588 522 145 (advent ) 151 SB + +739 522 54 (of ) 60 SB + +799 522 74 (the ) 81 SB + +880 522 164 (internet ) 171 SB + +1051 522 102 (over ) 109 SB + +1160 522 63 (20 ) 70 SB + +1230 522 116 (years ) 123 SB + +1353 522 99 (ago, ) 106 SB + +1459 522 113 (there ) 120 SB + +1579 522 78 (has ) 85 SB + +1664 522 78 (not ) 85 SB + +1749 522 105 (been ) 112 SB + +1861 522 59 (an ) 66 SB + +1927 522 99 (easy ) 106 SB + +2033 522 94 (way ) 101 SB + +2134 522 41 (to) 41 SB + +225 581 139 (access ) 140 SB + +365 581 243 (information ) 244 SB + +609 581 63 (on ) 64 SB + +673 581 74 (the ) 75 SB + +748 581 178 (network ) 179 SB + +927 581 134 (unless ) 135 SB + +1062 581 87 (you ) 88 SB + +1150 581 110 (were ) 111 SB + +1261 581 203 (proficient ) 204 SB + +1465 581 100 (with ) 101 SB + +1566 581 35 (a ) 37 SB + +1603 581 162 (number ) 164 SB + +1767 581 54 (of ) 56 SB + +1823 581 138 (UNIX ) 140 SB + +1963 581 212 (commands) 212 SB + +225 640 84 (and ) 86 SB + +311 640 237 (understood ) 239 SB + +550 640 99 (how ) 101 SB + +651 640 74 (the ) 76 SB + +727 640 178 (network ) 180 SB + +907 640 236 (functioned. ) 238 SB + +1145 640 13 ( ) 16 SB + +1161 640 86 (But ) 89 SB + +1250 640 112 (now, ) 115 SB + +1365 640 142 (thanks ) 145 SB + +1510 640 54 (to ) 57 SB + +1567 640 152 (HTTP, ) 155 SB + +1722 640 74 (the ) 77 SB + +1799 640 133 (ability ) 136 SB + +1935 640 54 (to ) 57 SB + +1992 640 183 (reference) 183 SB + +225 699 1548 (information and to travel the net \(known as surfing\) has been made incredibly ) 1549 SB + +1774 699 153 (simple. ) 154 SB + +1928 699 13 ( ) 14 SB + +1942 699 48 (A ) 49 SB + +1991 699 96 (user ) 97 SB + +2088 699 87 (with) 87 SB + +225 758 35 (a ) 39 SB + +264 758 102 (GUI ) 106 SB + +370 758 211 (\(graphical ) 215 SB + +585 758 96 (user ) 101 SB + +686 758 13 ( ) 18 SB + +704 758 201 (interface\) ) 206 SB + +910 758 81 (can ) 86 SB + +996 758 179 (navigate ) 184 SB + +1180 758 169 (through ) 174 SB + +1354 758 74 (the ) 79 SB + +1433 758 164 (internet ) 169 SB + +1602 758 54 (as ) 59 SB + +1661 758 123 (easily ) 128 SB + +1789 758 54 (as ) 59 SB + +1848 758 97 (they ) 102 SB + +1950 758 64 (do ) 69 SB + +2019 758 156 (through) 156 SB + +225 817 1438 (their windows based personal computers with the click of mouse button.) 1438 SB + +375 935 139 (HTTP ) 148 SB + +523 935 44 (is ) 53 SB + +576 935 59 (an ) 68 SB + +644 935 339 (application-level ) 348 SB + +992 935 182 (protocol ) 191 SB + +1183 935 100 (with ) 109 SB + +1292 935 87 (low ) 96 SB + +1388 935 195 (overhead ) 204 SB + +1592 935 84 (and ) 93 SB + +1685 935 74 (the ) 83 SB + +1768 935 126 (speed ) 136 SB + +1904 935 203 (necessary ) 213 SB + +2117 935 58 (for) 58 SB + +225 994 237 (distributed, ) 248 SB + +473 994 282 (collaborative, ) 293 SB + +766 994 242 (hypermedia ) 254 SB + +1020 994 243 (information ) 255 SB + +1275 994 180 (systems. ) 192 SB + +1467 994 13 ( ) 25 SB + +1492 994 45 (It ) 57 SB + +1549 994 44 (is ) 56 SB + +1605 994 35 (a ) 47 SB + +1652 994 170 (generic, ) 182 SB + +1834 994 191 (stateless, ) 203 SB + +2037 994 138 (object-) 138 SB + +225 1053 176 (oriented ) 178 SB + +403 1053 182 (protocol ) 185 SB + +588 1053 131 (which ) 134 SB + +722 1053 81 (can ) 84 SB + +806 1053 59 (be ) 62 SB + +868 1053 104 (used ) 107 SB + +975 1053 71 (for ) 74 SB + +1049 1053 119 (many ) 122 SB + +1171 1053 126 (tasks, ) 129 SB + +1300 1053 103 (such ) 106 SB + +1406 1053 54 (as ) 57 SB + +1463 1053 118 (name ) 121 SB + +1584 1053 153 (servers ) 156 SB + +1740 1053 84 (and ) 87 SB + +1827 1053 224 (distributed ) 227 SB + +2054 1053 121 (object) 121 SB + +225 1112 1768 (management systems, through extensions of its request methods \(commands\). A feature ) 1769 SB + +1994 1112 54 (of ) 55 SB + +2049 1112 126 (HTTP) 126 SB + +225 1171 44 (is ) 45 SB + +270 1171 74 (the ) 75 SB + +345 1171 137 (typing ) 138 SB + +483 1171 84 (and ) 85 SB + +568 1171 236 (negotiation ) 238 SB + +806 1171 54 (of ) 56 SB + +862 1171 97 (data ) 99 SB + +961 1171 308 (representation, ) 310 SB + +1271 1171 182 (allowing ) 184 SB + +1455 1171 167 (systems ) 169 SB + +1624 1171 54 (to ) 56 SB + +1680 1171 59 (be ) 61 SB + +1741 1171 101 (built ) 103 SB + +1844 1171 288 (independently ) 290 SB + +2134 1171 41 (of) 41 SB + +225 1230 74 (the ) 85 SB + +310 1230 97 (data ) 108 SB + +418 1230 120 (being ) 131 SB + +549 1230 241 (transferred. ) 252 SB + +801 1230 13 ( ) 24 SB + +825 1230 90 (The ) 101 SB + +926 1230 182 (protocol ) 193 SB + +1119 1230 44 (is ) 55 SB + +1174 1230 179 (typically ) 191 SB + +1365 1230 156 (layered ) 168 SB + +1533 1230 63 (on ) 75 SB + +1608 1230 79 (top ) 91 SB + +1699 1230 54 (of ) 66 SB + +1765 1230 164 (TCP/IP ) 176 SB + +1941 1230 49 (in ) 61 SB + +2002 1230 120 (order ) 132 SB + +2134 1230 41 (to) 41 SB + +225 1289 207 (guarantee ) 213 SB + +438 1289 97 (data ) 103 SB + +541 1289 177 (transfer. ) 183 SB + +724 1289 13 ( ) 19 SB + +743 1289 127 (Other ) 133 SB + +876 1289 181 (methods ) 188 SB + +1064 1289 54 (of ) 61 SB + +1125 1289 97 (data ) 104 SB + +1229 1289 164 (transfer ) 171 SB + +1400 1289 141 (maybe ) 148 SB + +1548 1289 117 (used, ) 124 SB + +1672 1289 90 (but, ) 97 SB + +1769 1289 74 (the ) 81 SB + +1850 1289 93 (vast ) 100 SB + +1950 1289 177 (majority ) 184 SB + +2134 1289 41 (of) 41 SB + +225 1348 982 (existing systems use TCP/IP for HTTP transfers. ) 983 SB + +1208 1348 13 ( ) 14 SB + +1222 1348 90 (The ) 91 SB + +1313 1348 182 (protocol ) 183 SB + +1496 1348 169 (consists ) 170 SB + +1666 1348 54 (of ) 55 SB + +1721 1348 35 (a ) 36 SB + +1757 1348 158 (request ) 159 SB + +1916 1348 84 (and ) 85 SB + +2001 1348 174 (response) 174 SB + +225 1407 1182 (paradigm. See reference for further information on HTTP.) 1182 SB + +375 1525 117 (Once ) 119 SB + +494 1525 35 (a ) 37 SB + +531 1525 161 (content ) 163 SB + +694 1525 56 (or ) 58 SB + +752 1525 242 (commercial ) 244 SB + +996 1525 181 (provider ) 183 SB + +1179 1525 78 (has ) 80 SB + +1259 1525 103 (their ) 105 SB + +1364 1525 139 (HTTP ) 141 SB + +1505 1525 134 (server ) 136 SB + +1641 1525 63 (on ) 65 SB + +1706 1525 74 (the ) 76 SB + +1782 1525 169 (Internet ) 171 SB + +1953 1525 35 (a ) 37 SB + +1990 1525 96 (user ) 98 SB + +2088 1525 87 (with) 87 SB + +225 1584 74 (the ) 79 SB + +304 1584 79 (use ) 84 SB + +388 1584 54 (of ) 59 SB + +447 1584 59 (an ) 65 SB + +512 1584 164 (internet ) 170 SB + +682 1584 174 (browser ) 180 SB + +862 1584 13 ( ) 19 SB + +881 1584 44 (is ) 50 SB + +931 1584 93 (able ) 99 SB + +1030 1584 54 (to ) 60 SB + +1090 1584 139 (access ) 145 SB + +1235 1584 74 (the ) 80 SB + +1315 1584 181 (provider ) 187 SB + +1502 1584 100 (with ) 106 SB + +1608 1584 35 (a ) 41 SB + +1649 1584 185 (common ) 191 SB + +1840 1584 184 (interface ) 190 SB + +2030 1584 145 (defined) 145 SB + +225 1643 169 (through ) 179 SB + +404 1643 74 (the ) 84 SB + +488 1643 136 (Hyper ) 146 SB + +634 1643 105 (Text ) 115 SB + +749 1643 171 (Markup ) 182 SB + +931 1643 208 (Language ) 219 SB + +1150 1643 201 (\(HTML\), ) 212 SB + +1362 1643 131 (which ) 142 SB + +1504 1643 44 (is ) 55 SB + +1559 1643 35 (a ) 46 SB + +1605 1643 137 (subset ) 148 SB + +1753 1643 54 (of ) 65 SB + +1818 1643 151 (SGML ) 162 SB + +1980 1643 195 (\(Standard) 195 SB + +225 1702 645 (Generalized Markup Language\).) 645 SB + +375 1820 1335 (HTML is a simple markup language used to create documents that ) 1336 SB + +1711 1820 95 (may ) 96 SB + +1807 1820 59 (be ) 60 SB + +1867 1820 142 (shared ) 143 SB + +2010 1820 165 (between) 165 SB + +225 1879 180 (different ) 183 SB + +408 1879 214 (platforms. ) 217 SB + +625 1879 13 ( ) 16 SB + +641 1879 90 (The ) 94 SB + +735 1879 190 (language ) 194 SB + +929 1879 140 (allows ) 144 SB + +1073 1879 102 (text, ) 106 SB + +1179 1879 110 (data, ) 114 SB + +1293 1879 192 (graphics, ) 196 SB + +1489 1879 127 (news, ) 131 SB + +1620 1879 96 (mail ) 100 SB + +1720 1879 84 (and ) 88 SB + +1808 1879 35 (a ) 39 SB + +1847 1879 162 (number ) 166 SB + +2013 1879 54 (of ) 58 SB + +2071 1879 104 (other) 104 SB + +225 1938 157 (utilities ) 159 SB + +384 1938 54 (to ) 57 SB + +441 1938 162 (interact ) 165 SB + +606 1938 100 (with ) 103 SB + +709 1938 74 (the ) 77 SB + +786 1938 139 (HTTP ) 142 SB + +928 1938 134 (server ) 137 SB + +1065 1938 84 (and ) 87 SB + +1152 1938 187 (browser. ) 190 SB + +1342 1938 13 ( ) 16 SB + +1358 1938 99 (This ) 102 SB + +1460 1938 115 (gives ) 118 SB + +1578 1938 74 (the ) 77 SB + +1655 1938 96 (user ) 99 SB + +1754 1938 74 (the ) 77 SB + +1831 1938 177 (freedom ) 180 SB + +2011 1938 54 (to ) 57 SB + +2068 1938 107 (enjoy) 107 SB + +225 1997 1501 (the benefits of the provider without having to know how it is accomplished.) 1501 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2234 57 (2.) 57 SB + +375 2234 708 (WebSTONE overview) 708 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2409 90 (The ) 92 SB + +467 2409 267 (WebSTONE ) 269 SB + +736 2409 44 (is ) 46 SB + +782 2409 35 (a ) 38 SB + +820 2409 95 (new ) 98 SB + +918 2409 230 (benchmark ) 233 SB + +1151 2409 89 (that ) 92 SB + +1243 2409 103 (tests ) 106 SB + +1349 2409 74 (the ) 77 SB + +1426 2409 262 (performance ) 265 SB + +1691 2409 54 (of ) 57 SB + +1748 2409 139 (HTTP ) 142 SB + +1890 2409 13 ( ) 16 SB + +1906 2409 49 (in ) 52 SB + +1958 2409 173 (contrast ) 176 SB + +2134 2409 41 (to) 41 SB + +225 2468 435 (server platform\222s and ) 436 SB + +661 2468 180 (different ) 181 SB + +842 2468 337 (implementations ) 338 SB + +1180 2468 54 (of ) 55 SB + +1235 2468 152 (HTTP. ) 153 SB + +1388 2468 13 ( ) 14 SB + +1402 2468 178 (Because ) 179 SB + +1581 2468 113 (there ) 114 SB + +1695 2468 74 (are ) 75 SB + +1770 2468 119 (many ) 120 SB + +1890 2468 180 (different ) 181 SB + +2071 2468 104 (types) 104 SB + +225 2527 54 (of ) 55 SB + +280 2527 134 (server ) 135 SB + +415 2527 185 (software ) 186 SB + +601 2527 89 (that ) 90 SB + +691 2527 44 (is ) 45 SB + +736 2527 190 (currently ) 191 SB + +927 2527 198 (available, ) 199 SB + +1126 2527 13 ( ) 15 SB + +1141 2527 54 (as ) 56 SB + +1197 2527 95 (well ) 97 SB + +1294 2527 54 (as ) 56 SB + +1350 2527 180 (different ) 182 SB + +1532 2527 198 (hardware ) 200 SB + +1732 2527 214 (platforms, ) 216 SB + +1948 2527 113 (there ) 115 SB + +2063 2527 112 (needs) 112 SB + +225 2586 54 (to ) 55 SB + +280 2586 59 (be ) 60 SB + +340 2586 35 (a ) 36 SB + +376 2586 232 (mechanism ) 233 SB + +609 2586 71 (for ) 72 SB + +681 2586 145 (testing ) 146 SB + +827 2586 291 (benchmarking ) 293 SB + +1120 2586 134 (server ) 136 SB + +1256 2586 185 (software ) 187 SB + +1443 2586 84 (and ) 86 SB + +1529 2586 198 (hardware ) 200 SB + +1729 2586 182 (platform ) 184 SB + +1913 2586 262 (performance.) 262 SB + +225 2645 90 (The ) 99 SB + +324 2645 267 (WebSTONE ) 276 SB + +600 2645 44 (is ) 53 SB + +653 2645 35 (a ) 44 SB + +697 2645 230 (benchmark ) 239 SB + +936 2645 89 (that ) 98 SB + +1034 2645 183 (attempts ) 192 SB + +1226 2645 54 (to ) 63 SB + +1289 2645 64 (do ) 73 SB + +1362 2645 96 (this. ) 105 SB + +1467 2645 13 ( ) 23 SB + +1490 2645 67 (As ) 77 SB + +1567 2645 100 (with ) 110 SB + +1677 2645 82 (any ) 92 SB + +1769 2645 95 (new ) 105 SB + +1874 2645 230 (benchmark ) 240 SB + +2114 2645 61 (the) 61 SB + +225 2704 267 (WebSTONE ) 269 SB + +494 2704 44 (is ) 46 SB + +540 2704 35 (a ) 37 SB + +577 2704 162 (starting ) 164 SB + +741 2704 128 (point. ) 130 SB + +871 2704 13 ( ) 15 SB + +886 2704 117 (Once ) 119 SB + +1005 2704 74 (the ) 76 SB + +1081 2704 230 (benchmark ) 232 SB + +1313 2704 44 (is ) 46 SB + +1359 2704 226 (introduced ) 228 SB + +1587 2704 90 (into ) 92 SB + +1679 2704 74 (the ) 76 SB + +1755 2704 157 (general ) 159 SB + +1914 2704 13 ( ) 15 SB + +1929 2704 139 (World ) 141 SB + +2070 2704 105 (Wide) 105 SB + +225 2763 1669 (Web \(WWW\) community, improvements and enhancements will be made to further ) 1670 SB + +1895 2763 74 (the ) 75 SB + +1970 2763 79 (use ) 80 SB + +2050 2763 54 (of ) 55 SB + +2105 2763 70 (this) 70 SB + +225 2822 1068 (benchmark in support of better end user performance.) 1068 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 6 6 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (6) 21 SB + +gr + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 219 121 (Since ) 125 SB + +500 219 74 (the ) 78 SB + +578 219 260 (functionality ) 264 SB + +842 219 54 (of ) 58 SB + +900 219 74 (the ) 78 SB + +978 219 105 (Web ) 109 SB + +1087 219 44 (is ) 48 SB + +1135 219 144 (similar ) 148 SB + +1283 219 54 (to ) 58 SB + +1341 219 74 (the ) 78 SB + +1419 219 260 (functionality ) 265 SB + +1684 219 54 (of ) 59 SB + +1743 219 166 (NFS\231, ) 171 SB + +1914 219 74 (the ) 79 SB + +1993 219 182 (LADDIS) 182 SB + +225 278 230 (benchmark ) 233 SB + +458 278 90 (was ) 93 SB + +551 278 193 (reviewed ) 196 SB + +747 278 71 (for ) 74 SB + +821 278 13 ( ) 16 SB + +837 278 172 (possible ) 175 SB + +1012 278 54 (as ) 57 SB + +1069 278 74 (the ) 77 SB + +1146 278 95 (web ) 98 SB + +1244 278 243 (benchmark. ) 246 SB + +1490 278 13 ( ) 16 SB + +1506 278 302 (Unfortunately, ) 305 SB + +1811 278 113 (there ) 117 SB + +1928 278 90 (was ) 94 SB + +2022 278 63 (no ) 67 SB + +2089 278 86 (easy) 86 SB + +225 337 94 (way ) 97 SB + +322 337 54 (to ) 57 SB + +379 337 122 (adapt ) 125 SB + +504 337 83 (this ) 86 SB + +590 337 243 (benchmark. ) 246 SB + +836 337 13 ( ) 16 SB + +852 337 209 (However, ) 212 SB + +1064 337 195 (LADDIS ) 198 SB + +1262 337 75 (did ) 78 SB + +1340 337 108 (offer ) 111 SB + +1451 337 35 (a ) 38 SB + +1489 337 238 (perspective ) 241 SB + +1730 337 63 (on ) 67 SB + +1797 337 99 (how ) 103 SB + +1900 337 54 (to ) 58 SB + +1958 337 217 (benchmark) 217 SB + +225 396 255 (client/server ) 258 SB + +483 396 273 (environment. ) 276 SB + +759 396 13 ( ) 16 SB + +775 396 90 (The ) 93 SB + +868 396 267 (WebSTONE ) 270 SB + +1138 396 44 (is ) 47 SB + +1185 396 104 (used ) 107 SB + +1292 396 54 (to ) 58 SB + +1350 396 177 (measure ) 181 SB + +1531 396 207 (maximum ) 211 SB + +1742 396 84 (and ) 88 SB + +1830 396 167 (average ) 171 SB + +2001 396 174 (response) 174 SB + +225 455 118 (times ) 133 SB + +358 455 71 (for ) 87 SB + +445 455 229 (connecting ) 245 SB + +690 455 54 (to ) 70 SB + +760 455 74 (the ) 90 SB + +850 455 147 (server. ) 163 SB + +1013 455 13 ( ) 29 SB + +1042 455 54 (In ) 70 SB + +1112 455 174 (addition ) 190 SB + +1302 455 234 (throughput ) 250 SB + +1552 455 97 (data ) 113 SB + +1665 455 44 (is ) 60 SB + +1725 455 92 (also ) 108 SB + +1833 455 220 (generated. ) 236 SB + +2069 455 13 ( ) 29 SB + +2098 455 77 (The) 77 SB + +225 514 267 (WebSTONE ) 268 SB + +493 514 13 ( ) 14 SB + +507 514 44 (is ) 45 SB + +552 514 190 (executed ) 191 SB + +743 514 306 (simultaneously ) 307 SB + +1050 514 63 (on ) 64 SB + +1114 514 85 (one ) 86 SB + +1200 514 56 (or ) 57 SB + +1257 514 115 (more ) 116 SB + +1373 514 139 (clients ) 141 SB + +1514 514 169 (resident ) 171 SB + +1685 514 63 (on ) 65 SB + +1750 514 74 (the ) 76 SB + +1826 514 169 (server\222s ) 171 SB + +1997 514 178 (network.) 178 SB + +225 573 112 (Each ) 118 SB + +343 573 120 (client ) 126 SB + +469 573 44 (is ) 50 SB + +519 573 93 (able ) 99 SB + +618 573 54 (to ) 60 SB + +678 573 142 (launch ) 148 SB + +826 573 35 (a ) 41 SB + +867 573 162 (number ) 169 SB + +1036 573 54 (of ) 61 SB + +1097 573 171 (children ) 178 SB + +1275 573 145 (\(called ) 152 SB + +1427 573 280 (Webchildren\) ) 287 SB + +1714 573 217 (depending ) 224 SB + +1938 573 63 (on ) 70 SB + +2008 573 99 (how ) 106 SB + +2114 573 61 (the) 61 SB + +225 632 290 (system load is ) 291 SB + +516 632 239 (configured. ) 240 SB + +756 632 13 ( ) 14 SB + +770 632 112 (Each ) 113 SB + +883 632 263 (Webchildren ) 264 SB + +1147 632 44 (is ) 45 SB + +1192 632 93 (able ) 94 SB + +1286 632 54 (to ) 55 SB + +1341 632 158 (request ) 159 SB + +1500 632 243 (information ) 244 SB + +1744 632 108 (from ) 109 SB + +1853 632 74 (the ) 75 SB + +1928 632 134 (server ) 135 SB + +2063 632 112 (based) 112 SB + +225 691 63 (on ) 70 SB + +295 691 35 (a ) 42 SB + +337 691 120 (given ) 127 SB + +464 691 74 (file ) 81 SB + +545 691 111 (load. ) 118 SB + +663 691 13 ( ) 20 SB + +683 691 90 (The ) 97 SB + +780 691 267 (WebSTONE ) 274 SB + +1054 691 44 (is ) 51 SB + +1105 691 154 (written ) 161 SB + +1266 691 54 (to ) 62 SB + +1328 691 59 (be ) 67 SB + +1395 691 253 (independent ) 261 SB + +1656 691 54 (of ) 62 SB + +1718 691 74 (the ) 82 SB + +1800 691 134 (server ) 142 SB + +1942 691 182 (platform ) 190 SB + +2132 691 43 (or) 43 SB + +225 750 1347 (software running on it. In essence it treats the server as a blackbox.) 1347 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 869 95 (2.1) 95 SB + +375 869 1477 (The WebSTONE as a measure of performance) 1477 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1044 54 (In ) 59 SB + +434 1044 174 (addition ) 179 SB + +613 1044 54 (to ) 59 SB + +672 1044 35 (a ) 40 SB + +712 1044 230 (benchmark ) 236 SB + +948 1044 89 (that ) 95 SB + +1043 1044 201 (generates ) 207 SB + +1250 1044 263 (standardized ) 269 SB + +1519 1044 97 (data ) 103 SB + +1622 1044 71 (for ) 77 SB + +1699 1044 243 (comparison ) 249 SB + +1948 1044 54 (of ) 60 SB + +2008 1044 167 (different) 167 SB + +225 1103 1542 (platforms, the WebSTONE is also a performance tester and maybe used as a ) 1543 SB + +1768 1103 92 (tool ) 93 SB + +1861 1103 54 (to ) 55 SB + +1916 1103 13 ( ) 14 SB + +1930 1103 96 (help ) 97 SB + +2027 1103 148 (identify) 148 SB + +225 1162 262 (performance ) 265 SB + +490 1162 348 (characterizations ) 351 SB + +841 1162 54 (of ) 57 SB + +898 1162 134 (server ) 137 SB + +1035 1162 214 (platforms. ) 217 SB + +1252 1162 13 ( ) 16 SB + +1268 1162 45 (It ) 48 SB + +1316 1162 44 (is ) 48 SB + +1364 1162 81 (our ) 85 SB + +1449 1162 98 (goal ) 102 SB + +1551 1162 89 (that ) 93 SB + +1644 1162 74 (the ) 78 SB + +1722 1162 230 (benchmark ) 234 SB + +1956 1162 85 (will ) 89 SB + +2045 1162 130 (evolve) 130 SB + +225 1221 1687 (and will help define a standard the WWW community may use when comparing data.) 1687 SB + +375 1339 115 (Used ) 122 SB + +497 1339 54 (as ) 61 SB + +558 1339 35 (a ) 42 SB + +600 1339 262 (performance ) 270 SB + +870 1339 92 (tool ) 100 SB + +970 1339 74 (the ) 82 SB + +1052 1339 280 (WebSTONE, ) 288 SB + +1340 1339 98 (uses ) 106 SB + +1446 1339 202 (workload ) 210 SB + +1656 1339 231 (parameters ) 239 SB + +1895 1339 84 (and ) 92 SB + +1987 1339 139 (clients ) 147 SB + +2134 1339 41 (to) 41 SB + +225 1398 182 (generate ) 185 SB + +410 1398 139 (HTTP ) 142 SB + +552 1398 131 (traffic ) 134 SB + +686 1398 89 (that ) 92 SB + +778 1398 140 (allows ) 144 SB + +922 1398 59 (an ) 63 SB + +985 1398 139 (HTTP ) 143 SB + +1128 1398 134 (server ) 138 SB + +1266 1398 54 (to ) 58 SB + +1324 1398 59 (be ) 63 SB + +1387 1398 171 (stressed ) 175 SB + +1562 1398 49 (in ) 53 SB + +1615 1398 35 (a ) 39 SB + +1654 1398 162 (number ) 166 SB + +1820 1398 54 (of ) 58 SB + +1878 1398 180 (different ) 184 SB + +2062 1398 113 (ways.) 113 SB + +225 1457 1867 (This can gives insight into the server\222s behavior and performance in a variety of environments.) 1867 SB + +375 1575 129 (There ) 131 SB + +506 1575 96 (four ) 98 SB + +604 1575 180 (different ) 182 SB + +786 1575 221 (workloads ) 223 SB + +1009 1575 89 (that ) 91 SB + +1100 1575 196 (represent ) 198 SB + +1298 1575 35 (a ) 37 SB + +1335 1575 150 (sample ) 152 SB + +1487 1575 54 (of ) 57 SB + +1544 1575 74 (the ) 77 SB + +1621 1575 166 (existing ) 169 SB + +1790 1575 153 (servers ) 156 SB + +1946 1575 190 (currently ) 193 SB + +2139 1575 36 (in) 36 SB + +225 1634 311 (use on the web.) 311 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 1691 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 1696 1647 (The first one is a workload for general use actives that is sensitive to modem users.) 1647 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 1753 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 1758 90 (The ) 93 SB + +393 1758 151 (second ) 154 SB + +547 1758 202 (workload ) 205 SB + +752 1758 44 (is ) 47 SB + +799 1758 35 (a ) 39 SB + +838 1758 157 (general ) 161 SB + +999 1758 86 (mix ) 90 SB + +1089 1758 89 (that ) 93 SB + +1182 1758 44 (is ) 48 SB + +1230 1758 78 (not ) 82 SB + +1312 1758 54 (as ) 58 SB + +1370 1758 217 (concerned ) 221 SB + +1591 1758 100 (with ) 104 SB + +1695 1758 74 (the ) 78 SB + +1773 1758 160 (modem ) 164 SB + +1937 1758 109 (user, ) 113 SB + +2050 1758 90 (but, ) 94 SB + +2144 1758 31 (is) 31 SB + +300 1817 646 (still sensitive to download times.) 646 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 1874 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 1879 1204 (The third mix is a media rich mix that has very large content.) 1204 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 1936 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 1941 1228 (the fourth mix is a combination of both the first and third mix.) 1228 SB + +375 2059 45 (It ) 50 SB + +425 2059 144 (should ) 149 SB + +574 2059 59 (be ) 64 SB + +638 2059 125 (noted ) 130 SB + +768 2059 89 (that ) 94 SB + +862 2059 112 (since ) 117 SB + +979 2059 74 (the ) 79 SB + +1058 2059 95 (web ) 100 SB + +1158 2059 44 (is ) 49 SB + +1207 2059 83 (still ) 89 SB + +1296 2059 49 (in ) 55 SB + +1351 2059 59 (its ) 65 SB + +1416 2059 155 (infancy ) 161 SB + +1577 2059 40 (it ) 46 SB + +1623 2059 85 (will ) 91 SB + +1714 2059 97 (take ) 103 SB + +1817 2059 99 (time ) 105 SB + +1922 2059 54 (to ) 60 SB + +1982 2059 105 (have ) 111 SB + +2093 2059 82 (well) 82 SB + +225 2118 158 (defined ) 165 SB + +390 2118 127 (mixes ) 134 SB + +524 2118 89 (that ) 96 SB + +620 2118 85 (will ) 93 SB + +713 2118 59 (be ) 67 SB + +780 2118 227 (considered ) 235 SB + +1015 2118 195 (standard. ) 203 SB + +1218 2118 13 ( ) 21 SB + +1239 2118 45 (It ) 53 SB + +1292 2118 92 (also ) 100 SB + +1392 2118 144 (should ) 152 SB + +1544 2118 59 (be ) 67 SB + +1611 2118 125 (noted ) 133 SB + +1744 2118 89 (that ) 97 SB + +1841 2118 113 (there ) 121 SB + +1962 2118 44 (is ) 52 SB + +2014 2118 92 (also ) 100 SB + +2114 2118 61 (the) 61 SB + +225 2177 149 (chance ) 152 SB + +377 2177 89 (that ) 92 SB + +469 2177 113 (there ) 116 SB + +585 2177 85 (will ) 88 SB + +673 2177 59 (be ) 62 SB + +735 2177 63 (no ) 66 SB + +801 2177 103 (such ) 106 SB + +907 2177 13 ( ) 16 SB + +923 2177 113 (thing ) 116 SB + +1039 2177 54 (as ) 57 SB + +1096 2177 35 (a ) 38 SB + +1134 2177 182 (standard ) 185 SB + +1319 2177 86 (mix ) 89 SB + +1408 2177 84 (and ) 87 SB + +1495 2177 103 (each ) 106 SB + +1601 2177 196 (customer ) 199 SB + +1800 2177 85 (will ) 88 SB + +1888 2177 105 (have ) 109 SB + +1997 2177 54 (to ) 58 SB + +2055 2177 120 (define) 120 SB + +225 2236 1681 (their own mix based on individual sites and run the test against the selected systems.) 1681 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2414 1578 (2.2 WebSTONE\222s measure of server performance) 1578 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2589 90 (The ) 96 SB + +471 2589 267 (WebSTONE ) 273 SB + +744 2589 44 (is ) 51 SB + +795 2589 35 (a ) 42 SB + +837 2589 259 (configurable ) 266 SB + +1103 2589 230 (benchmark ) 237 SB + +1340 2589 89 (that ) 96 SB + +1436 2589 140 (allows ) 147 SB + +1583 2589 262 (performance ) 269 SB + +1852 2589 275 (measurement ) 282 SB + +2134 2589 41 (of) 41 SB + +225 2648 646 (the server in the following ways:) 646 SB + +225 2707 755 (- Average and maximum connect time) 755 SB + +225 2766 774 (- Average and maximum response time) 774 SB + +225 2825 448 (- Data throughput rate) 448 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Symbol + +%%+ font Times-Bold + +%%+ font Times-Roman + +%%Page: 7 7 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (7) 21 SB + +gr + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +225 169 560 (- Number of pages retrieved) 560 SB + +225 228 527 (- Number of files retrieved) 527 SB + +375 346 1572 (The benchmark\222s goal is to control as much of the clients running environment ) 1573 SB + +1948 346 54 (as ) 55 SB + +2003 346 172 (possible.) 172 SB + +225 405 1192 (The WebSTONE has no interest in the server configuration.) 1192 SB + +375 523 121 (Since ) 122 SB + +497 523 74 (the ) 76 SB + +573 523 134 (object ) 136 SB + +709 523 44 (is ) 46 SB + +755 523 54 (to ) 56 SB + +811 523 155 (control ) 157 SB + +968 523 54 (as ) 56 SB + +1024 523 121 (much ) 123 SB + +1147 523 54 (of ) 56 SB + +1203 523 74 (the ) 76 SB + +1279 523 120 (client ) 122 SB + +1401 523 260 (environment ) 262 SB + +1663 523 54 (as ) 56 SB + +1719 523 172 (possible ) 174 SB + +1893 523 71 (we ) 73 SB + +1966 523 166 (decided ) 168 SB + +2134 523 41 (to) 41 SB + +225 582 44 (is ) 50 SB + +275 582 115 (write ) 121 SB + +396 582 74 (the ) 80 SB + +476 582 230 (benchmark ) 236 SB + +712 582 49 (in ) 55 SB + +767 582 46 (C ) 52 SB + +819 582 84 (and ) 90 SB + +909 582 78 (not ) 84 SB + +993 582 54 (to ) 60 SB + +1053 582 79 (use ) 85 SB + +1138 582 166 (existing ) 172 SB + +1310 582 108 (code ) 114 SB + +1424 582 170 (libraries ) 176 SB + +1600 582 54 (as ) 60 SB + +1660 582 97 (they ) 103 SB + +1763 582 74 (are ) 80 SB + +1843 582 78 (not ) 84 SB + +1927 582 154 (written ) 161 SB + +2088 582 87 (with) 87 SB + +225 641 262 (performance ) 264 SB + +489 641 49 (in ) 51 SB + +540 641 124 (mind. ) 126 SB + +666 641 13 ( ) 15 SB + +681 641 90 (The ) 92 SB + +773 641 230 (benchmark ) 232 SB + +1005 641 122 (sends ) 124 SB + +1129 641 139 (HTTP ) 141 SB + +1270 641 177 (requests ) 179 SB + +1449 641 54 (to ) 56 SB + +1505 641 74 (the ) 77 SB + +1582 641 134 (server ) 137 SB + +1719 641 84 (and ) 87 SB + +1806 641 98 (then ) 101 SB + +1907 641 204 (processes ) 207 SB + +2114 641 61 (the) 61 SB + +225 700 262 (performance ) 269 SB + +494 700 97 (data ) 104 SB + +598 700 119 (when ) 126 SB + +724 700 123 (done. ) 130 SB + +854 700 13 ( ) 20 SB + +874 700 99 (This ) 106 SB + +980 700 151 (insures ) 159 SB + +1139 700 89 (that ) 97 SB + +1236 700 98 (only ) 106 SB + +1342 700 74 (the ) 82 SB + +1424 700 108 (code ) 116 SB + +1540 700 203 (necessary ) 211 SB + +1751 700 54 (to ) 62 SB + +1813 700 165 (execute ) 173 SB + +1986 700 74 (the ) 82 SB + +2068 700 107 (given) 107 SB + +225 759 879 (request is performed in the most direct path.) 879 SB + +375 877 168 (Though ) 178 SB + +553 877 113 (there ) 123 SB + +676 877 85 (will ) 95 SB + +771 877 147 (always ) 157 SB + +928 877 59 (be ) 69 SB + +997 877 132 (added ) 142 SB + +1139 877 195 (overhead ) 205 SB + +1344 877 49 (in ) 59 SB + +1403 877 74 (the ) 84 SB + +1487 877 230 (benchmark ) 240 SB + +1727 877 83 (this ) 94 SB + +1821 877 161 (ensures ) 172 SB + +1993 877 74 (the ) 85 SB + +2078 877 97 (most) 97 SB + +225 936 155 (control ) 160 SB + +385 936 102 (over ) 107 SB + +492 936 74 (the ) 79 SB + +571 936 188 (accuracy ) 193 SB + +764 936 54 (of ) 59 SB + +823 936 74 (the ) 79 SB + +902 936 243 (benchmark. ) 248 SB + +1150 936 13 ( ) 18 SB + +1168 936 110 (With ) 116 SB + +1284 936 83 (this ) 89 SB + +1373 936 162 (method ) 168 SB + +1541 936 74 (the ) 80 SB + +1621 936 109 (layer ) 115 SB + +1736 936 54 (of ) 60 SB + +1796 936 166 (existing ) 172 SB + +1968 936 170 (libraries ) 176 SB + +2144 936 31 (is) 31 SB + +225 995 1754 (removed and only what is needed to measure the pure performance of the server is used.) 1754 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1114 95 (2.3) 95 SB + +375 1114 1185 (Metrics the WebSTONE doesn\222t test) 1185 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1289 121 (Since ) 134 SB + +509 1289 83 (this ) 96 SB + +605 1289 230 (benchmark ) 243 SB + +848 1289 44 (is ) 57 SB + +905 1289 217 (concerned ) 230 SB + +1135 1289 98 (only ) 111 SB + +1246 1289 100 (with ) 113 SB + +1359 1289 74 (the ) 87 SB + +1446 1289 134 (server ) 147 SB + +1593 1289 185 (software ) 198 SB + +1791 1289 84 (and ) 98 SB + +1889 1289 211 (hardware, ) 225 SB + +2114 1289 61 (the) 61 SB + +225 1348 267 (WebSTONE ) 273 SB + +498 1348 105 (does ) 111 SB + +609 1348 78 (not ) 84 SB + +693 1348 84 (test ) 91 SB + +784 1348 74 (the ) 81 SB + +865 1348 174 (browser ) 181 SB + +1046 1348 56 (or ) 63 SB + +1109 1348 120 (client ) 127 SB + +1236 1348 91 (side ) 98 SB + +1334 1348 249 (applications ) 256 SB + +1590 1348 56 (or ) 63 SB + +1653 1348 183 (libraries. ) 190 SB + +1843 1348 13 ( ) 20 SB + +1863 1348 13 ( ) 20 SB + +1883 1348 168 (Though ) 175 SB + +2058 1348 49 (in ) 56 SB + +2114 1348 61 (the) 61 SB + +225 1407 132 (future ) 138 SB + +363 1407 40 (it ) 46 SB + +409 1407 126 (might ) 132 SB + +541 1407 59 (be ) 65 SB + +606 1407 54 (of ) 60 SB + +666 1407 159 (interest ) 165 SB + +831 1407 54 (to ) 61 SB + +892 1407 85 (add ) 92 SB + +984 1407 83 (this ) 90 SB + +1074 1407 54 (to ) 61 SB + +1135 1407 74 (the ) 81 SB + +1216 1407 243 (benchmark. ) 250 SB + +1466 1407 13 ( ) 20 SB + +1486 1407 138 (Please ) 145 SB + +1631 1407 76 (see ) 83 SB + +1714 1407 132 (future ) 139 SB + +1853 1407 193 (additions ) 200 SB + +2053 1407 54 (to ) 61 SB + +2114 1407 61 (the) 61 SB + +225 1466 654 (benchmark in chapter 8, later on ) 655 SB + +880 1466 49 (in ) 50 SB + +930 1466 83 (this ) 84 SB + +1014 1466 124 (paper ) 125 SB + +1139 1466 71 (for ) 72 SB + +1211 1466 117 (other ) 118 SB + +1329 1466 157 (metrics ) 158 SB + +1487 1466 89 (that ) 90 SB + +1577 1466 83 (this ) 84 SB + +1661 1466 230 (benchmark ) 231 SB + +1892 1466 190 (currently ) 191 SB + +2083 1466 92 (does) 92 SB + +225 1525 837 (not test but will need to in the near future.) 837 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1673 57 (3.) 57 SB + +375 1673 826 (WebSTONE Architecture) 826 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1848 90 (The ) 92 SB + +467 1848 267 (WebSTONE ) 269 SB + +736 1848 248 (architecture ) 251 SB + +987 1848 44 (is ) 47 SB + +1034 1848 142 (shown ) 145 SB + +1179 1848 49 (in ) 52 SB + +1231 1848 129 (figure ) 132 SB + +1363 1848 93 (2-1. ) 96 SB + +1459 1848 13 ( ) 16 SB + +1475 1848 90 (The ) 93 SB + +1568 1848 263 (Webchildren ) 266 SB + +1834 1848 74 (are ) 77 SB + +1911 1848 214 (controlled ) 217 SB + +2128 1848 47 (by) 47 SB + +225 1907 74 (the ) 76 SB + +301 1907 320 (WebMASTER. ) 322 SB + +623 1907 13 ( ) 15 SB + +638 1907 90 (The ) 92 SB + +730 1907 307 (WebMASTER ) 309 SB + +1039 1907 174 (controls ) 177 SB + +1216 1907 74 (the ) 77 SB + +1293 1907 202 (operation ) 205 SB + +1498 1907 54 (of ) 57 SB + +1555 1907 74 (the ) 77 SB + +1632 1907 230 (benchmark ) 233 SB + +1865 1907 92 (run. ) 95 SB + +1960 1907 13 ( ) 16 SB + +1976 1907 67 (As ) 70 SB + +2046 1907 129 (shown) 129 SB + +225 1966 49 (in ) 50 SB + +275 1966 129 (figure ) 130 SB + +405 1966 80 (2-1 ) 81 SB + +486 1966 113 (there ) 114 SB + +600 1966 74 (are ) 75 SB + +675 1966 38 (4 ) 39 SB + +714 1966 263 (Webchildren ) 264 SB + +978 1966 215 (connected ) 216 SB + +1194 1966 54 (to ) 55 SB + +1249 1966 74 (the ) 75 SB + +1324 1966 139 (HTTP ) 140 SB + +1464 1966 134 (server ) 135 SB + +1599 1966 102 (over ) 103 SB + +1702 1966 35 (a ) 36 SB + +1738 1966 203 (dedicated ) 204 SB + +1942 1966 114 (LAN ) 115 SB + +2057 1966 118 (\(LAN) 118 SB + +225 2025 68 (1\). ) 77 SB + +302 2025 13 ( ) 22 SB + +324 2025 90 (The ) 99 SB + +423 2025 307 (WebMASTER ) 316 SB + +739 2025 44 (is ) 53 SB + +792 2025 190 (executed ) 199 SB + +991 2025 63 (on ) 72 SB + +1063 2025 35 (a ) 44 SB + +1107 2025 177 (separate ) 186 SB + +1293 2025 148 (system ) 158 SB + +1451 2025 157 (outside ) 167 SB + +1618 2025 54 (of ) 64 SB + +1682 2025 74 (the ) 84 SB + +1766 2025 276 (Webchildren. ) 286 SB + +2052 2025 13 ( ) 23 SB + +2075 2025 13 ( ) 23 SB + +2098 2025 77 (The) 77 SB + +225 2084 307 (WebMASTER ) 317 SB + +542 2084 81 (can ) 91 SB + +633 2084 59 (be ) 69 SB + +702 2084 79 (run ) 89 SB + +791 2084 63 (on ) 73 SB + +864 2084 85 (one ) 95 SB + +959 2084 54 (of ) 64 SB + +1023 2084 74 (the ) 85 SB + +1108 2084 139 (clients ) 150 SB + +1258 2084 56 (or ) 67 SB + +1325 2084 63 (on ) 74 SB + +1399 2084 35 (a ) 46 SB + +1445 2084 177 (separate ) 188 SB + +1633 2084 189 (machine. ) 200 SB + +1833 2084 13 ( ) 24 SB + +1857 2084 90 (The ) 101 SB + +1958 2084 217 (benchmark) 217 SB + +225 2143 190 (currently ) 191 SB + +416 2143 44 (is ) 45 SB + +461 2143 226 (configured ) 227 SB + +688 2143 54 (to ) 55 SB + +743 2143 79 (run ) 80 SB + +823 2143 74 (the ) 75 SB + +898 2143 307 (WebMASTER ) 308 SB + +1206 2143 63 (on ) 64 SB + +1270 2143 35 (a ) 36 SB + +1306 2143 176 (machine ) 177 SB + +1483 2143 89 (that ) 90 SB + +1573 2143 44 (is ) 45 SB + +1618 2143 78 (not ) 80 SB + +1698 2143 63 (on ) 65 SB + +1763 2143 74 (the ) 76 SB + +1839 2143 113 (same ) 115 SB + +1954 2143 178 (network ) 180 SB + +2134 2143 41 (as) 41 SB + +225 2202 505 (the clients and the server.) 505 SB + +255 255 255 fC + +/fm 256 def + +150 60 1185 2533 B + +1 F + +n + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +gs 143 53 1189 2537 CB + +1189 2539 117 (LAN 1) 117 SB + +gr + +255 255 255 fC + +/fm 256 def + +150 60 705 2533 B + +1 F + +n + +0 0 0 fC + +gs 143 53 709 2537 CB + +709 2539 117 (LAN 2) 117 SB + +gr + +0 lc + +0 lj + +0 0 0 pC + +0 3 SP + +255 255 255 fC + +/fm 256 def + +240 420 1695 2383 B + +1 F + +S + +n + +0 0 0 fC + +gs 229 409 1701 2389 CB + +1763 2491 104 (HTTP) 104 SB + +gr + +gs 229 409 1701 2389 CB + +1761 2541 109 (Server) 109 SB + +gr + +255 255 255 fC + +/fm 256 def + +210 90 1245 2413 B + +1 F + +S + +n + +32 0 0 33 33 0 0 0 29 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +gs 199 79 1251 2419 CB + +1251 2420 166 (Webchildren) 166 SB + +gr + +255 255 255 fC + +/fm 256 def + +210 90 975 2413 B + +1 F + +S + +n + +0 0 0 fC + +gs 199 79 981 2419 CB + +981 2420 166 (Webchildren) 166 SB + +gr + +255 255 255 fC + +/fm 256 def + +210 90 1245 2683 B + +1 F + +S + +n + +0 0 0 fC + +gs 199 79 1251 2689 CB + +1251 2690 166 (Webchildren) 166 SB + +gr + +255 255 255 fC + +/fm 256 def + +210 90 975 2683 B + +1 F + +S + +n + +0 0 0 fC + +gs 199 79 981 2689 CB + +981 2690 166 (Webchildren) 166 SB + +gr + +255 255 255 fC + +/fm 256 def + +210 240 465 2473 B + +1 F + +S + +n + +0 0 0 fC + +gs 199 229 471 2479 CB + +473 2580 194 (WebMASTER) 194 SB + +gr + +1 lc + +1 lj + +1065 2503 M 0 180 1 PP + +S + +n + +1365 2503 M 0 180 1 PP + +S + +n + +1065 2593 M 630 0 1 PP + +S + +n + +885 2593 M 0 -240 1 PP + +S + +n + +885 2593 M 0 240 1 PP + +S + +n + +1065 2353 M 0 60 1 PP + +S + +n + +1335 2353 M 0 60 1 PP + +S + +n + +1365 2833 M 0 -60 1 PP + +S + +n + +1065 2833 M 0 -60 1 PP + +S + +n + +675 2593 M 210 0 1 PP + +S + +n + +885 2833 M 480 0 1 PP + +S + +n + +885 2353 M 450 0 1 PP + +S + +n + +255 255 255 fC + +/fm 256 def + +1050 90 435 2903 B + +1 F + +n + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +0 0 0 fC + +gs 1043 83 439 2907 CB + +439 2909 1021 (Figure 3 A WebSTONE test environment) 1021 SB + +gr + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 8 8 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (8) 21 SB + +gr + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 307 110 (With ) 116 SB + +491 307 74 (the ) 80 SB + +571 307 133 (ability ) 139 SB + +710 307 54 (to ) 60 SB + +770 307 105 (have ) 111 SB + +881 307 74 (the ) 80 SB + +961 307 307 (WebMASTER ) 313 SB + +1274 307 63 (on ) 70 SB + +1344 307 35 (a ) 42 SB + +1386 307 180 (different ) 187 SB + +1573 307 148 (system ) 155 SB + +1728 307 115 (gives ) 122 SB + +1850 307 74 (the ) 81 SB + +1931 307 196 (flexibility ) 203 SB + +2134 307 41 (to) 41 SB + +225 366 1845 (have different networks talking to the same server and to have different client configurations.) 1845 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 485 95 (3.1) 95 SB + +375 485 709 (WebSTONE Software) 709 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 660 90 (The ) 110 SB + +485 660 267 (WebSTONE ) 287 SB + +772 660 44 (is ) 64 SB + +836 660 35 (a ) 55 SB + +891 660 237 (distributed, ) 257 SB + +1148 660 281 (multi-process ) 302 SB + +1450 660 243 (benchmark. ) 264 SB + +1714 660 13 ( ) 34 SB + +1748 660 90 (The ) 111 SB + +1859 660 145 (master ) 166 SB + +2025 660 150 (process) 150 SB + +225 719 341 (\(WebMASTER\) ) 360 SB + +585 719 118 (reads ) 137 SB + +722 719 74 (the ) 93 SB + +815 719 120 (client ) 140 SB + +955 719 278 (configuration ) 298 SB + +1253 719 93 (files ) 113 SB + +1366 719 54 (as ) 74 SB + +1440 719 95 (well ) 115 SB + +1555 719 54 (as ) 74 SB + +1629 719 74 (the ) 94 SB + +1723 719 206 (command ) 226 SB + +1949 719 96 (line. ) 116 SB + +2065 719 13 ( ) 33 SB + +2098 719 77 (The) 77 SB + +225 778 307 (WebMASTER ) 311 SB + +536 778 98 (then ) 103 SB + +639 778 217 (constructs ) 222 SB + +861 778 35 (a ) 40 SB + +901 778 206 (command ) 211 SB + +1112 778 83 (line ) 88 SB + +1200 778 71 (for ) 76 SB + +1276 778 103 (each ) 108 SB + +1384 778 276 (Webchildren. ) 281 SB + +1665 778 13 ( ) 18 SB + +1683 778 90 (The ) 95 SB + +1778 778 307 (WebMASTER ) 312 SB + +2090 778 85 (then) 85 SB + +225 837 187 (remotely ) 193 SB + +418 837 158 (spawns ) 164 SB + +582 837 74 (the ) 80 SB + +662 837 276 (Webchildren. ) 282 SB + +944 837 13 ( ) 19 SB + +963 837 112 (Each ) 118 SB + +1081 837 54 (of ) 60 SB + +1141 837 74 (the ) 80 SB + +1221 837 263 (Webchildren ) 269 SB + +1490 837 98 (then ) 105 SB + +1595 837 118 (reads ) 125 SB + +1720 837 74 (the ) 81 SB + +1801 837 206 (command ) 213 SB + +2014 837 83 (line ) 90 SB + +2104 837 71 (and) 71 SB + +225 896 151 (startup ) 156 SB + +381 896 317 (communication ) 322 SB + +703 896 100 (with ) 105 SB + +808 896 74 (the ) 79 SB + +887 896 320 (WebMASTER. ) 325 SB + +1212 896 13 ( ) 18 SB + +1230 896 117 (After ) 122 SB + +1352 896 59 (all ) 64 SB + +1416 896 74 (the ) 79 SB + +1495 896 263 (Webchildren ) 268 SB + +1763 896 105 (have ) 111 SB + +1874 896 105 (been ) 111 SB + +1985 896 190 (initialized) 190 SB + +225 955 1482 (the WebMASTER instructs the Webchildren to commence the benchmark.) 1482 SB + +375 1073 67 (As ) 69 SB + +444 1073 103 (each ) 105 SB + +549 1073 263 (Webchildren ) 265 SB + +814 1073 160 (finishes ) 163 SB + +977 1073 59 (its ) 62 SB + +1039 1073 79 (run ) 82 SB + +1121 1073 74 (the ) 77 SB + +1198 1073 307 (WebMASTER ) 310 SB + +1508 1073 163 (collects ) 166 SB + +1674 1073 74 (the ) 77 SB + +1751 1073 97 (data ) 100 SB + +1851 1073 108 (from ) 111 SB + +1962 1073 103 (each ) 106 SB + +2068 1073 107 (client) 107 SB + +225 1132 84 (and ) 89 SB + +314 1132 199 (coalesces ) 204 SB + +518 1132 74 (the ) 79 SB + +597 1132 97 (data ) 102 SB + +699 1132 90 (into ) 96 SB + +795 1132 35 (a ) 41 SB + +836 1132 148 (report. ) 154 SB + +990 1132 13 ( ) 19 SB + +1009 1132 152 (During ) 158 SB + +1167 1132 74 (the ) 80 SB + +1247 1132 79 (run ) 85 SB + +1332 1132 74 (the ) 80 SB + +1412 1132 263 (Webchildren ) 269 SB + +1681 1132 74 (are ) 80 SB + +1761 1132 258 (autonomous ) 264 SB + +2025 1132 54 (of ) 60 SB + +2085 1132 90 (each) 90 SB + +225 1191 582 (other and the WebMASTER.) 582 SB + +375 1309 141 (Figure ) 142 SB + +517 1309 76 (3.1 ) 77 SB + +594 1309 137 (shows ) 139 SB + +733 1309 59 (an ) 61 SB + +794 1309 177 (example ) 179 SB + +973 1309 54 (of ) 56 SB + +1029 1309 35 (a ) 37 SB + +1066 1309 144 (typical ) 146 SB + +1212 1309 120 (client ) 122 SB + +1334 1309 164 (running ) 166 SB + +1500 1309 38 (3 ) 40 SB + +1540 1309 276 (Webchildren. ) 278 SB + +1818 1309 13 ( ) 15 SB + +1833 1309 90 (The ) 92 SB + +1925 1309 250 (Webchildren) 250 SB + +225 1368 74 (are ) 78 SB + +303 1368 186 (spawned ) 190 SB + +493 1368 60 (by ) 64 SB + +557 1368 74 (the ) 78 SB + +635 1368 320 (WebMASTER. ) 324 SB + +959 1368 13 ( ) 18 SB + +977 1368 112 (Each ) 117 SB + +1094 1368 200 (Webchild ) 205 SB + +1299 1368 98 (then ) 103 SB + +1402 1368 118 (reads ) 123 SB + +1525 1368 59 (its ) 64 SB + +1589 1368 278 (configuration ) 283 SB + +1872 1368 93 (files ) 98 SB + +1970 1368 84 (and ) 89 SB + +2059 1368 116 (opens) 116 SB + +225 1427 513 (log files if part of the test.) 513 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 241 121 1515 1683 CB + +1515 1685 104 (HTTP) 104 SB + +gr + +gs 241 121 1515 1683 CB + +1515 1735 109 (Server) 109 SB + +gr + +1 lc + +1 lj + +0 0 0 pC + +0 1 SP + +gs 151 1 675 1683 CB + +825 1683 M -150 0 1 PP + +S + +n + +gr + +gs 1 301 1215 1653 CB + +1215 1653 M 0 300 1 PP + +S + +n + +gr + +gs 1 541 675 1683 CB + +675 1683 M 0 540 1 PP + +S + +n + +gr + +255 255 255 fC + +/fm 256 def + +210 60 855 1653 B + +1 F + +n + +32 0 0 33 33 0 0 0 29 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +gs 211 61 855 1653 CB + +855 1654 166 (Webchildren) 166 SB + +gr + +120 45 944 1667 E + +S + +n + +255 255 255 fC + +/fm 256 def + +210 60 855 1773 B + +1 F + +n + +0 0 0 fC + +gs 211 61 855 1773 CB + +855 1774 166 (Webchildren) 166 SB + +gr + +120 45 944 1787 E + +S + +n + +255 255 255 fC + +/fm 256 def + +210 60 855 1923 B + +1 F + +n + +0 0 0 fC + +gs 211 61 855 1923 CB + +855 1924 166 (Webchildren) 166 SB + +gr + +120 45 944 1937 E + +S + +n + +0 lc + +0 lj + +0 3 SP + +930 750 555 1593 B + +S + +n + +255 255 255 fC + +/fm 256 def + +90 120 915 2133 B + +1 F + +n + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +gs 83 113 919 2137 CB + +919 2139 66 (Log) 66 SB + +gr + +gs 83 113 919 2137 CB + +919 2189 71 (files) 71 SB + +gr + +1 lc + +1 lj + +255 255 255 fC + +/fm 256 def + +45 30 959 2102 E + +1 F + +S + +n + +1005 2103 M 0 180 1 PP + +S + +n + +915 2103 M 0 180 1 PP + +S + +n + +/fm 256 def + +45 30 959 2282 E + +1 F + +S + +n + +814 1653 M -368 0 1 PP + +S + +n + +0 1 SP + +0 0 0 fC + +/fm 256 def + +450 1663 M 15 10 -15 10 0 -20 3 PP + +1 F + +S + +n + +/fm 256 def + +810 1643 M -15 -10 15 -10 0 20 3 PP + +1 F + +S + +n + +0 3 SP + +814 1773 M -368 0 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +450 1783 M 15 10 -15 9 0 -19 3 PP + +1 F + +S + +n + +/fm 256 def + +810 1764 M -15 -9 15 -10 0 19 3 PP + +1 F + +S + +n + +0 3 SP + +814 1923 M -368 0 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +450 1933 M 15 10 -15 10 0 -20 3 PP + +1 F + +S + +n + +/fm 256 def + +810 1913 M -15 -10 15 -10 0 20 3 PP + +1 F + +S + +n + +32 0 0 38 38 0 0 0 34 /Times-Roman /font32 ANSIFont font + +gs 241 61 315 1593 CB + +315 1595 233 ( WebMASTER) 233 SB + +gr + +gs 241 61 315 1711 CB + +315 1713 233 ( WebMASTER) 233 SB + +gr + +gs 241 61 315 1863 CB + +315 1865 233 ( WebMASTER) 233 SB + +gr + +0 3 SP + +1076 1653 M 128 0 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +1200 1643 M -15 -10 15 -10 0 20 3 PP + +1 F + +S + +n + +/fm 256 def + +1080 1663 M 15 10 -15 10 0 -20 3 PP + +1 F + +S + +n + +0 3 SP + +1076 1803 M 128 0 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +1200 1794 M -15 -9 15 -10 0 19 3 PP + +1 F + +S + +n + +/fm 256 def + +1080 1813 M 15 10 -15 9 0 -19 3 PP + +1 F + +S + +n + +0 3 SP + +1076 1953 M 128 0 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +1200 1943 M -15 -10 15 -10 0 20 3 PP + +1 F + +S + +n + +/fm 256 def + +1080 1963 M 15 10 -15 10 0 -20 3 PP + +1 F + +S + +n + +0 3 SP + +1226 1803 M 428 0 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +1650 1794 M -15 -9 15 -10 0 19 3 PP + +1 F + +S + +n + +/fm 256 def + +1230 1813 M 15 10 -15 9 0 -19 3 PP + +1 F + +S + +n + +gs 151 1 675 1803 CB + +825 1803 M -150 0 1 PP + +S + +n + +gr + +gs 151 1 675 1953 CB + +825 1953 M -150 0 1 PP + +S + +n + +gr + +0 3 SP + +675 2223 M 229 0 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +900 2213 M -15 -10 15 -10 0 20 3 PP + +1 F + +S + +n + +255 255 255 fC + +/fm 256 def + +120 120 1155 2133 B + +1 F + +n + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +gs 113 113 1159 2137 CB + +1159 2139 106 (config) 106 SB + +gr + +gs 113 113 1159 2137 CB + +1159 2189 71 (files) 71 SB + +gr + +0 3 SP + +255 255 255 fC + +/fm 256 def + +60 30 1214 2102 E + +1 F + +S + +n + +1275 2103 M 0 180 1 PP + +S + +n + +1155 2103 M 0 180 1 PP + +S + +n + +/fm 256 def + +60 30 1214 2282 E + +1 F + +S + +n + +1215 2073 M -146 -380 1 PP + +S + +n + +0 1 SP + +0 0 0 fC + +/fm 256 def + +1061 1701 M -4 18 -14 -10 18 -8 3 PP + +1 F + +S + +n + +0 3 SP + +1185 2073 M -144 -230 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +1034 1851 M -1 18 -16 -8 17 -10 3 PP + +1 F + +S + +n + +0 3 SP + +1155 2103 M -112 -112 1 PP + +S + +n + +0 1 SP + +/fm 256 def + +1038 2000 M 3 17 -17 -4 14 -13 3 PP + +1 F + +S + +n + +32 0 0 58 58 0 0 0 54 /Times-Bold /font29 ANSIFont font + +gs 691 91 645 2373 CB + +645 2375 587 (Figure 3.1 Webchildren) 587 SB + +gr + +gs 691 91 645 2373 CB + +645 2444 134 (client) 134 SB + +gr + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 9 9 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 21 50 2154 2899 CB + +2154 2901 21 (9) 21 SB + +gr + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 170 912 (4. Configuration Parameters) 912 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 326 1800 (Since the WebSTONE can has many variables this gives the flexibility to configure and run) 1800 SB + +225 385 119 (many ) 123 SB + +348 385 180 (different ) 184 SB + +532 385 138 (suites. ) 142 SB + +674 385 13 ( ) 17 SB + +691 385 90 (The ) 94 SB + +785 385 182 (standard ) 186 SB + +971 385 86 (mix ) 90 SB + +1061 385 54 (of ) 58 SB + +1119 385 93 (files ) 97 SB + +1216 385 85 (will ) 89 SB + +1305 385 96 (give ) 100 SB + +1405 385 35 (a ) 40 SB + +1445 385 157 (general ) 162 SB + +1607 385 262 (performance ) 267 SB + +1874 385 201 (indicator. ) 206 SB + +2080 385 13 ( ) 18 SB + +2098 385 77 (The) 77 SB + +225 444 979 (parameters that are configurable are listed below:) 979 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 639 23 (\267) 24 SB + +250 639 13 ( ) 51 SB + +225 639 23 (\267) 24 SB + +249 639 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 643 336 (Duration of test) 336 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 700 23 (\267) 24 SB + +250 700 13 ( ) 51 SB + +225 700 23 (\267) 24 SB + +249 700 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 704 365 (Repetition of test) 365 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 761 23 (\267) 24 SB + +250 761 13 ( ) 51 SB + +225 761 23 (\267) 24 SB + +249 761 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 765 327 (Number of files) 327 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 822 23 (\267) 24 SB + +250 822 13 ( ) 51 SB + +225 822 23 (\267) 24 SB + +249 822 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 826 362 (Number of pages) 362 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 883 23 (\267) 24 SB + +250 883 13 ( ) 51 SB + +225 883 23 (\267) 24 SB + +249 883 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 887 947 (Server software and hardware configuration) 947 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 944 23 (\267) 24 SB + +250 944 13 ( ) 51 SB + +225 944 23 (\267) 24 SB + +249 944 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 948 519 (Number of Webchildren) 519 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 1005 23 (\267) 24 SB + +250 1005 13 ( ) 51 SB + +225 1005 23 (\267) 24 SB + +249 1005 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 1009 438 (Number of networks) 438 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 1066 23 (\267) 24 SB + +250 1066 13 ( ) 51 SB + +225 1066 23 (\267) 24 SB + +249 1066 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 1070 378 (Number of clients) 378 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 1127 23 (\267) 24 SB + +250 1127 13 ( ) 51 SB + +225 1127 23 (\267) 24 SB + +249 1127 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 1131 400 (Workload of pages) 400 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 1188 23 (\267) 24 SB + +250 1188 13 ( ) 51 SB + +225 1188 23 (\267) 24 SB + +249 1188 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 1192 175 (Logging) 175 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +226 1249 23 (\267) 24 SB + +250 1249 13 ( ) 51 SB + +225 1249 23 (\267) 24 SB + +249 1249 13 ( ) 51 SB + +32 0 0 50 50 0 0 0 46 /Times-Bold /font29 ANSIFont font + +300 1253 231 (Debugging) 231 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1382 615 (4.1 Duration of test) 615 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1557 1219 (The WebSTONE is designed to run for a specified duration. ) 1220 SB + +1595 1557 48 (A ) 49 SB + +1644 1557 120 (given ) 121 SB + +1765 1557 84 (test ) 85 SB + +1850 1557 44 (is ) 45 SB + +1895 1557 79 (run ) 80 SB + +1975 1557 49 (in ) 50 SB + +2025 1557 108 (units ) 109 SB + +2134 1557 41 (of) 41 SB + +225 1616 180 (minutes. ) 189 SB + +414 1616 90 (The ) 99 SB + +513 1616 207 (maximum ) 216 SB + +729 1616 164 (running ) 173 SB + +902 1616 99 (time ) 108 SB + +1010 1616 44 (is ) 53 SB + +1063 1616 217 (dependent ) 226 SB + +1289 1616 63 (on ) 72 SB + +1361 1616 104 (your ) 113 SB + +1474 1616 120 (client ) 129 SB + +1603 1616 175 (memory ) 184 SB + +1787 1616 84 (and ) 93 SB + +1880 1616 74 (the ) 83 SB + +1963 1616 162 (number ) 171 SB + +2134 1616 41 (of) 41 SB + +225 1675 515 (Webchildren to be spawn.) 515 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1794 576 (4.2 Repetition test) 576 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1969 90 (The ) 91 SB + +466 1969 267 (WebSTONE ) 268 SB + +734 1969 78 (has ) 80 SB + +814 1969 74 (the ) 76 SB + +890 1969 133 (ability ) 135 SB + +1025 1969 54 (to ) 56 SB + +1081 1969 79 (run ) 81 SB + +1162 1969 71 (for ) 73 SB + +1235 1969 35 (a ) 37 SB + +1272 1969 162 (number ) 164 SB + +1436 1969 54 (of ) 56 SB + +1492 1969 210 (iterations. ) 212 SB + +1704 1969 13 ( ) 15 SB + +1719 1969 99 (This ) 101 SB + +1820 1969 44 (is ) 46 SB + +1866 1969 181 (basically ) 183 SB + +2049 1969 35 (a ) 37 SB + +2086 1969 89 (loop) 89 SB + +225 2028 177 (counter. ) 178 SB + +403 2028 13 ( ) 14 SB + +417 2028 83 (For ) 84 SB + +501 2028 191 (example: ) 192 SB + +693 2028 13 ( ) 14 SB + +707 2028 45 (If ) 46 SB + +753 2028 74 (the ) 75 SB + +828 2028 84 (test ) 85 SB + +913 2028 169 (consists ) 170 SB + +1083 2028 54 (of ) 55 SB + +1138 2028 35 (a ) 36 SB + +1174 2028 69 (set ) 71 SB + +1245 2028 54 (of ) 56 SB + +1301 2028 38 (4 ) 40 SB + +1341 2028 93 (files ) 95 SB + +1436 2028 84 (and ) 86 SB + +1522 2028 74 (the ) 76 SB + +1598 2028 84 (test ) 86 SB + +1684 2028 54 (to ) 56 SB + +1740 2028 59 (be ) 61 SB + +1801 2028 79 (run ) 81 SB + +1882 2028 90 (was ) 92 SB + +1974 2028 54 (to ) 56 SB + +2030 2028 145 (request) 145 SB + +225 2087 103 (each ) 105 SB + +330 2087 74 (file ) 76 SB + +406 2087 38 (1 ) 40 SB + +446 2087 99 (time ) 101 SB + +547 2087 84 (and ) 86 SB + +633 2087 98 (then ) 100 SB + +733 2087 135 (report ) 137 SB + +870 2087 106 (back ) 108 SB + +978 2087 74 (the ) 76 SB + +1054 2087 128 (status ) 131 SB + +1185 2087 54 (of ) 57 SB + +1242 2087 89 (that ) 92 SB + +1334 2087 79 (run ) 82 SB + +1416 2087 74 (the ) 77 SB + +1493 2087 230 (benchmark ) 233 SB + +1726 2087 137 (would ) 140 SB + +1866 2087 98 (then ) 101 SB + +1967 2087 164 (attempt ) 167 SB + +2134 2087 41 (to) 41 SB + +225 2146 1427 (retrieve each file one time and then generate a report based on this data.) 1427 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2265 605 (4.3 Number of files) 605 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2440 1019 (There are two different ways to read files or UIL\222s ) 1020 SB + +1395 2440 90 (into ) 91 SB + +1486 2440 74 (the ) 75 SB + +1561 2440 243 (benchmark. ) 244 SB + +1805 2440 13 ( ) 14 SB + +1819 2440 90 (The ) 91 SB + +1910 2440 265 (configuration) 265 SB + +225 2499 712 (file \223filelist\224 contains a list of pages ) 713 SB + +938 2499 84 (and ) 85 SB + +1023 2499 93 (files ) 94 SB + +1117 2499 89 (that ) 90 SB + +1207 2499 74 (are ) 75 SB + +1282 2499 156 (already ) 157 SB + +1439 2499 303 (preconfigured. ) 304 SB + +1743 2499 13 ( ) 14 SB + +1757 2499 129 (There ) 130 SB + +1887 2499 44 (is ) 45 SB + +1932 2499 35 (a ) 36 SB + +1968 2499 101 (limit ) 102 SB + +2070 2499 54 (of ) 55 SB + +2125 2499 50 (50) 50 SB + +225 2558 1240 (files per page in the current implementation of this benchmark.) 1240 SB + +375 2676 90 (The ) 91 SB + +466 2676 117 (other ) 118 SB + +584 2676 94 (way ) 95 SB + +679 2676 54 (to ) 55 SB + +734 2676 99 (read ) 100 SB + +834 2676 93 (files ) 94 SB + +928 2676 90 (into ) 91 SB + +1019 2676 74 (the ) 75 SB + +1094 2676 79 (run ) 80 SB + +1174 2676 44 (is ) 45 SB + +1219 2676 50 (at ) 51 SB + +1270 2676 74 (the ) 75 SB + +1345 2676 206 (command ) 207 SB + +1552 2676 96 (line. ) 97 SB + +1649 2676 13 ( ) 14 SB + +1663 2676 90 (The ) 91 SB + +1754 2676 96 (user ) 97 SB + +1851 2676 95 (may ) 96 SB + +1947 2676 71 (list ) 72 SB + +2019 2676 74 (the ) 76 SB + +2095 2676 80 (files) 80 SB + +225 2735 54 (to ) 59 SB + +284 2735 59 (be ) 64 SB + +348 2735 131 (tested ) 136 SB + +484 2735 63 (on ) 68 SB + +552 2735 74 (the ) 79 SB + +631 2735 206 (command ) 211 SB + +842 2735 96 (line. ) 102 SB + +944 2735 13 ( ) 19 SB + +963 2735 99 (This ) 105 SB + +1068 2735 44 (is ) 50 SB + +1118 2735 148 (limited ) 154 SB + +1272 2735 60 (by ) 66 SB + +1338 2735 74 (the ) 80 SB + +1418 2735 162 (number ) 168 SB + +1586 2735 54 (of ) 60 SB + +1646 2735 219 (arguments ) 225 SB + +1871 2735 168 (allowed ) 174 SB + +2045 2735 63 (on ) 69 SB + +2114 2735 61 (the) 61 SB + +225 2794 289 (command line.) 289 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Symbol + +%%+ font Times-Bold + +%%+ font Times-Roman + +%%Page: 10 10 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (10) 42 SB + +gr + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 239 654 (4.4 Number of pages) 654 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 414 261 (At this point ) 262 SB + +637 414 74 (the ) 75 SB + +712 414 169 (concept ) 170 SB + +882 414 54 (of ) 55 SB + +937 414 35 (a ) 36 SB + +973 414 107 (page ) 108 SB + +1081 414 125 (needs ) 126 SB + +1207 414 54 (to ) 55 SB + +1262 414 59 (be ) 60 SB + +1322 414 239 (introduced. ) 240 SB + +1562 414 13 ( ) 14 SB + +1576 414 121 (Since ) 122 SB + +1698 414 74 (the ) 75 SB + +1773 414 169 (concept ) 170 SB + +1943 414 54 (of ) 55 SB + +1998 414 35 (a ) 36 SB + +2034 414 141 (HTML) 141 SB + +225 473 209 (document ) 214 SB + +439 473 44 (is ) 49 SB + +488 473 85 (one ) 90 SB + +578 473 89 (that ) 94 SB + +672 473 78 (has ) 83 SB + +755 473 89 (text ) 94 SB + +849 473 100 (with ) 105 SB + +954 473 119 (inline ) 124 SB + +1078 473 150 (images ) 155 SB + +1233 473 84 (like ) 89 SB + +1322 473 93 (GIF ) 98 SB + +1420 473 84 (and ) 89 SB + +1509 473 127 (JPEG ) 132 SB + +1641 473 49 (in ) 54 SB + +1695 473 53 (it, ) 58 SB + +1753 473 113 (there ) 118 SB + +1871 473 44 (is ) 49 SB + +1920 473 35 (a ) 40 SB + +1960 473 215 (conceptual) 215 SB + +225 532 107 (view ) 108 SB + +333 532 89 (that ) 90 SB + +423 532 35 (a ) 36 SB + +459 532 107 (page ) 108 SB + +567 532 44 (is ) 45 SB + +612 532 74 (the ) 75 SB + +687 532 154 (HTML ) 155 SB + +842 532 89 (text ) 90 SB + +932 532 94 (plus ) 95 SB + +1027 532 59 (all ) 61 SB + +1088 532 74 (the ) 76 SB + +1164 532 93 (GIF ) 95 SB + +1259 532 84 (and ) 86 SB + +1345 532 127 (JPEG ) 129 SB + +1474 532 93 (files ) 95 SB + +1569 532 89 (that ) 91 SB + +1660 532 74 (are ) 76 SB + +1736 532 217 (associated ) 219 SB + +1955 532 100 (with ) 102 SB + +2057 532 40 (it ) 42 SB + +2099 532 76 (that) 76 SB + +225 591 119 (make ) 120 SB + +345 591 54 (to ) 55 SB + +400 591 133 (whole ) 134 SB + +534 591 222 (document. ) 223 SB + +757 591 13 ( ) 14 SB + +771 591 99 (This ) 100 SB + +871 591 196 (approach ) 197 SB + +1068 591 90 (was ) 91 SB + +1159 591 121 (taken ) 122 SB + +1281 591 54 (to ) 55 SB + +1336 591 133 (mimic ) 134 SB + +1470 591 54 (as ) 55 SB + +1525 591 149 (closely ) 150 SB + +1675 591 54 (to ) 55 SB + +1730 591 35 (a ) 36 SB + +1766 591 86 (real ) 87 SB + +1853 591 74 (life ) 75 SB + +1928 591 247 (environment) 247 SB + +225 650 126 (usage ) 128 SB + +353 650 148 (patters ) 150 SB + +503 650 134 (where ) 137 SB + +640 650 93 (GIF ) 96 SB + +736 650 84 (and ) 87 SB + +823 650 127 (JPEG ) 130 SB + +953 650 144 (inlined ) 147 SB + +1100 650 150 (images ) 153 SB + +1253 650 74 (are ) 77 SB + +1330 650 278 (automatically ) 281 SB + +1611 650 124 (down ) 127 SB + +1738 650 98 (load ) 101 SB + +1839 650 113 (upon ) 116 SB + +1955 650 176 (retrieval ) 179 SB + +2134 650 41 (of) 41 SB + +225 709 74 (the ) 78 SB + +303 709 154 (HTML ) 158 SB + +461 709 89 (text ) 93 SB + +554 709 120 (page. ) 125 SB + +679 709 13 ( ) 18 SB + +697 709 209 (Therefore ) 214 SB + +911 709 108 (from ) 113 SB + +1024 709 83 (this ) 88 SB + +1112 709 115 (point ) 120 SB + +1232 709 63 (on ) 68 SB + +1300 709 35 (a ) 40 SB + +1340 709 107 (page ) 112 SB + +1452 709 85 (will ) 90 SB + +1542 709 59 (be ) 64 SB + +1606 709 227 (considered ) 232 SB + +1838 709 74 (the ) 79 SB + +1917 709 69 (set ) 74 SB + +1991 709 54 (of ) 59 SB + +2050 709 93 (files ) 98 SB + +2148 709 27 (it) 27 SB + +225 768 116 (takes ) 117 SB + +342 768 54 (to ) 55 SB + +397 768 133 (create ) 134 SB + +531 768 59 (an ) 60 SB + +591 768 154 (HTML ) 155 SB + +746 768 187 (viewable ) 188 SB + +934 768 222 (document. ) 223 SB + +1157 768 13 ( ) 14 SB + +1171 768 126 (Note: ) 127 SB + +1298 768 13 ( ) 14 SB + +1312 768 168 (Though ) 169 SB + +1481 768 49 (in ) 50 SB + +1531 768 86 (real ) 87 SB + +1618 768 74 (life ) 76 SB + +1694 768 59 (an ) 61 SB + +1755 768 249 (applications ) 251 SB + +2006 768 169 (program) 169 SB + +225 827 137 (would ) 142 SB + +367 827 74 (lite ) 79 SB + +446 827 69 (off ) 74 SB + +520 827 59 (all ) 64 SB + +584 827 74 (the ) 79 SB + +663 827 158 (request ) 163 SB + +826 827 71 (for ) 76 SB + +902 827 74 (the ) 79 SB + +981 827 93 (files ) 98 SB + +1079 827 50 (at ) 55 SB + +1134 827 85 (one ) 90 SB + +1224 827 112 (time, ) 117 SB + +1341 827 40 (it ) 45 SB + +1386 827 90 (was ) 95 SB + +1481 827 166 (decided ) 171 SB + +1652 827 89 (that ) 94 SB + +1746 827 83 (this ) 88 SB + +1834 827 90 (was ) 95 SB + +1929 827 78 (not ) 84 SB + +2013 827 59 (an ) 65 SB + +2078 827 97 (issue) 97 SB + +225 886 112 (since ) 129 SB + +354 886 173 (multiple ) 190 SB + +544 886 171 (children ) 188 SB + +732 886 79 (run ) 96 SB + +828 886 63 (on ) 80 SB + +908 886 103 (each ) 120 SB + +1028 886 120 (client ) 138 SB + +1166 886 84 (and ) 102 SB + +1268 886 89 (that ) 107 SB + +1375 886 74 (the ) 92 SB + +1467 886 183 (acquired ) 201 SB + +1668 886 124 (affect ) 142 SB + +1810 886 54 (of ) 72 SB + +1882 886 293 (simultaneously) 293 SB + +225 945 609 (connections is stilled achieved.) 609 SB + +375 1092 90 (The ) 91 SB + +466 1092 267 (WebSTONE ) 268 SB + +734 1092 44 (is ) 45 SB + +779 1092 187 (designed ) 188 SB + +967 1092 54 (to ) 55 SB + +1022 1092 79 (use ) 80 SB + +1102 1092 74 (the ) 75 SB + +1177 1092 169 (concept ) 170 SB + +1347 1092 54 (of ) 55 SB + +1402 1092 126 (pages ) 127 SB + +1529 1092 141 (during ) 142 SB + +1671 1092 158 (testing. ) 159 SB + +1830 1092 90 (The ) 91 SB + +1921 1092 254 (WebSTONE) 254 SB + +225 1151 1104 (is able to handle up to 100 pages with 50 files per page.) 1104 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1270 1837 (4.5 All of the server software and hardware configuration) 1837 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1445 168 (Though ) 186 SB + +561 1445 74 (the ) 92 SB + +653 1445 267 (WebSTONE ) 285 SB + +938 1445 44 (is ) 62 SB + +1000 1445 140 (design ) 158 SB + +1158 1445 54 (to ) 72 SB + +1230 1445 84 (test ) 102 SB + +1332 1445 180 (different ) 198 SB + +1530 1445 134 (server ) 153 SB + +1683 1445 185 (software ) 204 SB + +1887 1445 84 (and ) 103 SB + +1990 1445 185 (hardware) 185 SB + +225 1504 297 (configurations ) 300 SB + +525 1504 74 (the ) 77 SB + +602 1504 230 (benchmark ) 233 SB + +835 1504 49 (in ) 52 SB + +887 1504 108 (itself ) 111 SB + +998 1504 105 (does ) 108 SB + +1106 1504 78 (not ) 81 SB + +1187 1504 252 (discriminate ) 255 SB + +1442 1504 54 (as ) 57 SB + +1499 1504 54 (to ) 57 SB + +1556 1504 291 (configuration. ) 294 SB + +1850 1504 13 ( ) 17 SB + +1867 1504 99 (This ) 103 SB + +1970 1504 140 (allows ) 144 SB + +2114 1504 61 (the) 61 SB + +225 1563 123 (tester ) 134 SB + +359 1563 54 (to ) 65 SB + +424 1563 68 (try ) 80 SB + +504 1563 180 (different ) 192 SB + +696 1563 297 (configurations ) 309 SB + +1005 1563 49 (in ) 61 SB + +1066 1563 120 (order ) 132 SB + +1198 1563 54 (to ) 66 SB + +1264 1563 161 (achieve ) 173 SB + +1437 1563 162 (optimal ) 174 SB + +1611 1563 262 (performance ) 274 SB + +1885 1563 71 (for ) 83 SB + +1968 1563 74 (the ) 86 SB + +2054 1563 121 (server) 121 SB + +225 1622 185 (software ) 189 SB + +414 1622 84 (and ) 88 SB + +502 1622 211 (hardware. ) 215 SB + +717 1622 13 ( ) 17 SB + +734 1622 161 (NOTE: ) 165 SB + +899 1622 54 (In ) 58 SB + +957 1622 163 (fairness ) 167 SB + +1124 1622 74 (the ) 78 SB + +1202 1622 103 (tests ) 107 SB + +1309 1622 144 (should ) 148 SB + +1457 1622 59 (be ) 63 SB + +1520 1622 79 (run ) 83 SB + +1603 1622 100 (with ) 104 SB + +1707 1622 74 (the ) 78 SB + +1785 1622 113 (same ) 117 SB + +1902 1622 198 (hardware ) 202 SB + +2104 1622 71 (and) 71 SB + +225 1681 544 (software as reported in the ) 545 SB + +770 1681 84 (test ) 85 SB + +855 1681 155 (results. ) 156 SB + +1011 1681 13 ( ) 14 SB + +1025 1681 72 (All ) 73 SB + +1098 1681 198 (hardware ) 199 SB + +1297 1681 84 (and ) 85 SB + +1382 1681 117 (sever ) 118 SB + +1500 1681 185 (software ) 186 SB + +1686 1681 297 (configurations ) 298 SB + +1984 1681 144 (should ) 145 SB + +2129 1681 46 (be) 46 SB + +225 1740 651 (disclosed when a test is released.) 651 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1869 1018 (4.6 The number of Webchildren) 1018 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2044 296 (On each client ) 297 SB + +672 2044 97 (host ) 98 SB + +770 2044 74 (the ) 75 SB + +845 2044 162 (number ) 163 SB + +1008 2044 54 (of ) 55 SB + +1063 2044 263 (Webchildren ) 264 SB + +1327 2044 219 (requesting ) 220 SB + +1547 2044 126 (pages ) 127 SB + +1674 2044 56 (or ) 57 SB + +1731 2044 93 (files ) 94 SB + +1825 2044 108 (from ) 109 SB + +1934 2044 74 (the ) 75 SB + +2009 2044 134 (server ) 135 SB + +2144 2044 31 (is) 31 SB + +225 2103 272 (configurable. ) 276 SB + +501 2103 13 ( ) 17 SB + +518 2103 112 (Note ) 116 SB + +634 2103 89 (that ) 93 SB + +727 2103 54 (as ) 59 SB + +786 2103 74 (the ) 79 SB + +865 2103 162 (number ) 167 SB + +1032 2103 54 (of ) 59 SB + +1091 2103 263 (Webchildren ) 268 SB + +1359 2103 173 (increase ) 178 SB + +1537 2103 85 (less ) 90 SB + +1627 2103 175 (memory ) 180 SB + +1807 2103 44 (is ) 49 SB + +1856 2103 185 (available ) 190 SB + +2046 2103 63 (on ) 68 SB + +2114 2103 61 (the) 61 SB + +225 2162 120 (client ) 121 SB + +346 2162 116 (hosts ) 117 SB + +463 2162 71 (for ) 72 SB + +535 2162 164 (running ) 165 SB + +700 2162 103 (tests ) 104 SB + +804 2162 84 (and ) 85 SB + +889 2162 113 (there ) 114 SB + +1003 2162 123 (could ) 124 SB + +1127 2162 59 (be ) 60 SB + +1187 2162 35 (a ) 37 SB + +1224 2162 262 (performance ) 264 SB + +1488 2162 156 (penalty ) 158 SB + +1646 2162 217 (depending ) 219 SB + +1865 2162 63 (on ) 65 SB + +1930 2162 74 (the ) 76 SB + +2006 2162 126 (speed ) 128 SB + +2134 2162 41 (of) 41 SB + +225 2221 731 (the clients running on the client host.) 731 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2369 770 (4.7 Number of networks) 770 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2544 45 (It ) 48 SB + +423 2544 44 (is ) 47 SB + +470 2544 172 (possible ) 175 SB + +645 2544 54 (to ) 57 SB + +702 2544 105 (have ) 108 SB + +810 2544 115 (more ) 118 SB + +928 2544 98 (then ) 102 SB + +1030 2544 85 (one ) 89 SB + +1119 2544 178 (network ) 182 SB + +1301 2544 215 (connected ) 219 SB + +1520 2544 54 (to ) 58 SB + +1578 2544 74 (the ) 78 SB + +1656 2544 134 (server ) 138 SB + +1794 2544 84 (and ) 88 SB + +1882 2544 54 (to ) 58 SB + +1940 2544 105 (have ) 109 SB + +2049 2544 126 (clients) 126 SB + +225 2603 63 (on ) 68 SB + +293 2603 180 (different ) 185 SB + +478 2603 197 (networks ) 202 SB + +680 2603 164 (running ) 169 SB + +849 2603 74 (the ) 79 SB + +928 2603 243 (benchmark. ) 248 SB + +1176 2603 13 ( ) 18 SB + +1194 2603 168 (Though ) 173 SB + +1367 2603 83 (this ) 88 SB + +1455 2603 90 (was ) 95 SB + +1550 2603 78 (not ) 83 SB + +1633 2603 110 (done ) 115 SB + +1748 2603 49 (in ) 54 SB + +1802 2603 83 (this ) 89 SB + +1891 2603 157 (version ) 163 SB + +2054 2603 54 (of ) 60 SB + +2114 2603 61 (the) 61 SB + +225 2662 1491 (benchmark there should be no reason that it would not work provided that ) 1492 SB + +1717 2662 74 (the ) 75 SB + +1792 2662 134 (server ) 135 SB + +1927 2662 97 (host ) 98 SB + +2025 2662 118 (name ) 119 SB + +2144 2662 31 (is) 31 SB + +225 2721 522 (the same on all the clients.) 522 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 11 11 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (11) 42 SB + +gr + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 170 679 (4.8 Number of clients) 679 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 345 90 (The ) 94 SB + +469 345 267 (WebSTONE ) 271 SB + +740 345 184 (supports ) 188 SB + +928 345 74 (the ) 78 SB + +1006 345 133 (ability ) 137 SB + +1143 345 54 (to ) 58 SB + +1201 345 105 (have ) 109 SB + +1310 345 54 (as ) 59 SB + +1369 345 119 (many ) 124 SB + +1493 345 171 (children ) 176 SB + +1669 345 63 (on ) 68 SB + +1737 345 103 (each ) 108 SB + +1845 345 120 (client ) 125 SB + +1970 345 54 (as ) 59 SB + +2029 345 100 (long ) 105 SB + +2134 345 41 (as) 41 SB + +225 404 113 (there ) 119 SB + +344 404 44 (is ) 51 SB + +395 404 159 (enough ) 166 SB + +561 404 175 (memory ) 182 SB + +743 404 63 (on ) 70 SB + +813 404 102 (both ) 109 SB + +922 404 74 (the ) 81 SB + +1003 404 307 (WebMASTER ) 314 SB + +1317 404 84 (and ) 91 SB + +1408 404 120 (client ) 127 SB + +1535 404 180 (systems. ) 187 SB + +1722 404 13 ( ) 20 SB + +1742 404 112 (Note ) 119 SB + +1861 404 113 (there ) 120 SB + +1981 404 141 (maybe ) 148 SB + +2129 404 46 (an) 46 SB + +225 463 802 (issue of performance bottlenecks on the ) 803 SB + +1028 463 120 (client ) 121 SB + +1149 463 91 (side ) 92 SB + +1241 463 40 (if ) 41 SB + +1282 463 113 (there ) 114 SB + +1396 463 74 (are ) 75 SB + +1471 463 80 (too ) 81 SB + +1552 463 119 (many ) 120 SB + +1672 463 263 (Webchildren ) 264 SB + +1936 463 56 (or ) 57 SB + +1993 463 74 (the ) 75 SB + +2068 463 107 (client) 107 SB + +225 522 150 (is slow.) 150 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 651 712 (4.9 Workload of pages) 712 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 738 112 (Each ) 114 SB + +489 738 107 (page ) 109 SB + +598 738 49 (in ) 52 SB + +650 738 74 (the ) 77 SB + +727 738 267 (WebSTONE ) 270 SB + +997 738 78 (has ) 81 SB + +1078 738 35 (a ) 38 SB + +1116 738 147 (weight ) 150 SB + +1266 738 217 (associated ) 220 SB + +1486 738 100 (with ) 103 SB + +1589 738 53 (it. ) 56 SB + +1645 738 13 ( ) 16 SB + +1661 738 48 (A ) 51 SB + +1712 738 107 (page ) 110 SB + +1822 738 95 (may ) 98 SB + +1920 738 59 (be ) 62 SB + +1982 738 108 (from ) 111 SB + +2093 738 38 (1 ) 41 SB + +2134 738 41 (to) 41 SB + +225 797 130 (100% ) 133 SB + +358 797 54 (of ) 57 SB + +415 797 74 (the ) 77 SB + +492 797 97 (test. ) 100 SB + +592 797 13 ( ) 16 SB + +608 797 85 (See ) 88 SB + +696 797 74 (the ) 77 SB + +773 797 132 (filelist ) 135 SB + +908 797 71 (for ) 74 SB + +982 797 148 (further ) 151 SB + +1133 797 243 (information ) 246 SB + +1379 797 63 (on ) 66 SB + +1445 797 291 (configuration. ) 294 SB + +1739 797 13 ( ) 17 SB + +1756 797 218 (Weighting ) 222 SB + +1978 797 44 (is ) 48 SB + +2026 797 104 (used ) 108 SB + +2134 797 41 (to) 41 SB + +225 856 177 (simulate ) 180 SB + +405 856 89 (that ) 92 SB + +497 856 158 (activity ) 161 SB + +658 856 54 (of ) 57 SB + +715 856 35 (a ) 38 SB + +753 856 120 (given ) 123 SB + +876 856 120 (page. ) 123 SB + +999 856 13 ( ) 16 SB + +1015 856 90 (The ) 93 SB + +1108 856 137 (higher ) 140 SB + +1248 856 74 (the ) 77 SB + +1325 856 229 (percentage ) 233 SB + +1558 856 74 (the ) 78 SB + +1636 856 115 (more ) 119 SB + +1755 856 115 (often ) 119 SB + +1874 856 74 (the ) 78 SB + +1952 856 107 (page ) 111 SB + +2063 856 44 (is ) 48 SB + +2111 856 64 (hit.) 64 SB + +225 915 1182 (The lower the percentage the less often the page will be hit.) 1182 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1113 415 (4.10 Logging) 415 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1288 180 (Logging ) 189 SB + +564 1288 44 (is ) 54 SB + +618 1288 132 (added ) 142 SB + +760 1288 54 (to ) 64 SB + +824 1288 74 (the ) 84 SB + +908 1288 243 (benchmark, ) 253 SB + +1161 1288 77 (but ) 87 SB + +1248 1288 159 (caution ) 169 SB + +1417 1288 144 (should ) 154 SB + +1571 1288 59 (be ) 69 SB + +1640 1288 198 (exercised ) 208 SB + +1848 1288 119 (when ) 129 SB + +1977 1288 118 (using ) 128 SB + +2105 1288 70 (this) 70 SB + +225 1347 141 (option ) 151 SB + +376 1347 54 (as ) 64 SB + +440 1347 103 (each ) 113 SB + +553 1347 263 (Webchildren ) 273 SB + +826 1347 95 (logs ) 105 SB + +931 1347 121 (every ) 131 SB + +1062 1347 230 (connection ) 240 SB + +1302 1347 84 (and ) 94 SB + +1396 1347 171 (relevant ) 181 SB + +1577 1347 97 (data ) 107 SB + +1684 1347 49 (in ) 59 SB + +1743 1347 35 (a ) 45 SB + +1788 1347 177 (separate ) 188 SB + +1976 1347 87 (file. ) 98 SB + +2074 1347 13 ( ) 24 SB + +2098 1347 77 (The) 77 SB + +225 1406 1859 (logging information contains additional information that is not returned to the WebMASTER.) 1859 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1585 497 (4.11 Debugging) 497 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1760 231 (Debugging ) 235 SB + +610 1760 44 (is ) 48 SB + +658 1760 132 (added ) 136 SB + +794 1760 54 (to ) 58 SB + +852 1760 96 (help ) 100 SB + +952 1760 206 (debugged ) 210 SB + +1162 1760 40 (if ) 44 SB + +1206 1760 113 (there ) 118 SB + +1324 1760 44 (is ) 49 SB + +1373 1760 35 (a ) 40 SB + +1413 1760 176 (problem ) 181 SB + +1594 1760 100 (with ) 105 SB + +1699 1760 74 (the ) 79 SB + +1778 1760 134 (server ) 139 SB + +1917 1760 56 (or ) 61 SB + +1978 1760 133 (client. ) 138 SB + +2116 1760 13 ( ) 18 SB + +2134 1760 41 (In) 41 SB + +225 1819 1454 (debugging mode the HTTP header is display for each request that is sent.) 1454 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1938 864 (5. Workload configuration) 864 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2113 95 (One ) 100 SB + +475 2113 54 (of ) 59 SB + +534 2113 74 (the ) 79 SB + +613 2113 117 (goals ) 122 SB + +735 2113 71 (for ) 76 SB + +811 2113 74 (the ) 79 SB + +890 2113 267 (WebSTONE ) 272 SB + +1162 2113 44 (is ) 49 SB + +1211 2113 54 (to ) 59 SB + +1270 2113 135 (model ) 140 SB + +1410 2113 35 (a ) 40 SB + +1450 2113 86 (real ) 91 SB + +1541 2113 129 (world ) 134 SB + +1675 2113 202 (workload ) 207 SB + +1882 2113 71 (via ) 76 SB + +1958 2113 35 (a ) 41 SB + +1999 2113 176 (synthetic) 176 SB + +225 2172 1678 (workloads based on data gathered from different sites \(Hotwired, IUMA, Netscape, ) 1679 SB + +1904 2172 84 (and ) 85 SB + +1989 2172 54 (of ) 55 SB + +2044 2172 131 (course) 131 SB + +225 2231 553 (SGI\). Unfortunately this is ) 554 SB + +779 2231 115 (small ) 116 SB + +895 2231 97 (data ) 98 SB + +993 2231 69 (set ) 70 SB + +1063 2231 54 (to ) 55 SB + +1118 2231 87 (pull ) 88 SB + +1206 2231 108 (from ) 109 SB + +1315 2231 90 (but, ) 91 SB + +1406 2231 40 (it ) 41 SB + +1447 2231 78 (has ) 79 SB + +1526 2231 105 (been ) 106 SB + +1632 2231 128 (found ) 129 SB + +1761 2231 89 (that ) 90 SB + +1851 2231 40 (it ) 41 SB + +1892 2231 105 (does ) 106 SB + +1998 2231 177 (currently) 177 SB + +225 2290 215 (represents ) 217 SB + +442 2290 74 (the ) 76 SB + +518 2290 157 (general ) 159 SB + +677 2290 79 (use ) 81 SB + +758 2290 54 (of ) 56 SB + +814 2290 152 (HTTP. ) 154 SB + +968 2290 13 ( ) 15 SB + +983 2290 54 (In ) 56 SB + +1039 2290 83 (this ) 85 SB + +1124 2290 230 (benchmark ) 232 SB + +1356 2290 113 (there ) 116 SB + +1472 2290 74 (are ) 77 SB + +1549 2290 38 (4 ) 41 SB + +1590 2290 180 (different ) 183 SB + +1773 2290 127 (mixes ) 130 SB + +1903 2290 108 (from ) 111 SB + +2014 2290 74 (the ) 77 SB + +2091 2290 84 (data) 84 SB + +225 2349 478 (gather from those sites.) 478 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2468 759 (5.1 General modem mix) 759 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2643 772 (The General modem mix is a synthetic ) 773 SB + +1148 2643 107 (page ) 108 SB + +1256 2643 86 (mix ) 87 SB + +1343 2643 89 (that ) 90 SB + +1433 2643 137 (would ) 138 SB + +1571 2643 59 (be ) 60 SB + +1631 2643 104 (used ) 105 SB + +1736 2643 40 (if ) 41 SB + +1777 2643 160 (modem ) 161 SB + +1938 2643 115 (users ) 116 SB + +2054 2643 121 (where) 121 SB + +225 2702 1596 (to be considered. Two concerns to a potential server site should be the size of ) 1597 SB + +1822 2702 74 (the ) 75 SB + +1897 2702 126 (pages ) 127 SB + +2024 2702 89 (that ) 90 SB + +2114 2702 61 (are) 61 SB + +225 2761 63 (on ) 69 SB + +294 2761 103 (their ) 110 SB + +404 2761 148 (system ) 155 SB + +559 2761 84 (and ) 91 SB + +650 2761 98 (type ) 105 SB + +755 2761 54 (of ) 61 SB + +816 2761 139 (access ) 146 SB + +962 2761 54 (to ) 61 SB + +1023 2761 74 (the ) 81 SB + +1104 2761 147 (server. ) 154 SB + +1258 2761 13 ( ) 20 SB + +1278 2761 45 (If ) 52 SB + +1330 2761 35 (a ) 42 SB + +1372 2761 84 (end ) 91 SB + +1463 2761 96 (user ) 103 SB + +1566 2761 44 (is ) 51 SB + +1617 2761 200 (accessing ) 207 SB + +1824 2761 74 (the ) 81 SB + +1905 2761 134 (server ) 141 SB + +2046 2761 100 (with ) 107 SB + +2153 2761 22 (a) 22 SB + +225 2820 169 (14.4kbs ) 170 SB + +395 2820 160 (modem ) 161 SB + +556 2820 98 (then ) 99 SB + +655 2820 40 (it ) 41 SB + +696 2820 137 (would ) 138 SB + +834 2820 59 (be ) 60 SB + +894 2820 49 (in ) 50 SB + +944 2820 74 (the ) 76 SB + +1020 2820 93 (best ) 95 SB + +1115 2820 159 (interest ) 161 SB + +1276 2820 54 (of ) 56 SB + +1332 2820 74 (the ) 76 SB + +1408 2820 81 (site ) 83 SB + +1491 2820 54 (to ) 56 SB + +1547 2820 105 (have ) 107 SB + +1654 2820 115 (small ) 117 SB + +1771 2820 126 (pages ) 128 SB + +1899 2820 54 (as ) 56 SB + +1955 2820 54 (to ) 56 SB + +2011 2820 78 (not ) 80 SB + +2091 2820 84 (take) 84 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 12 12 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (12) 42 SB + +gr + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +225 169 35 (a ) 37 SB + +262 169 100 (long ) 103 SB + +365 169 99 (time ) 102 SB + +467 169 54 (to ) 57 SB + +524 169 209 (download ) 212 SB + +736 169 74 (the ) 77 SB + +813 169 110 (data. ) 113 SB + +926 169 13 ( ) 16 SB + +942 169 99 (This ) 102 SB + +1044 169 86 (mix ) 89 SB + +1133 169 116 (takes ) 119 SB + +1252 169 74 (the ) 77 SB + +1329 169 84 (end ) 87 SB + +1416 169 96 (user ) 99 SB + +1515 169 89 (that ) 92 SB + +1607 169 78 (has ) 81 SB + +1688 169 54 (to ) 57 SB + +1745 169 79 (use ) 82 SB + +1827 169 35 (a ) 38 SB + +1865 169 160 (modem ) 163 SB + +2028 169 54 (as ) 57 SB + +2085 169 90 (their) 90 SB + +225 228 230 (connection ) 235 SB + +460 228 90 (into ) 95 SB + +555 228 182 (account. ) 187 SB + +742 228 13 ( ) 19 SB + +761 228 99 (This ) 105 SB + +866 228 86 (mix ) 92 SB + +958 228 85 (will ) 91 SB + +1049 228 150 (consist ) 156 SB + +1205 228 54 (of ) 60 SB + +1265 228 115 (small ) 121 SB + +1386 228 126 (pages ) 132 SB + +1518 228 89 (that ) 95 SB + +1613 228 74 (are ) 80 SB + +1693 228 85 (less ) 91 SB + +1784 228 98 (then ) 104 SB + +1888 228 88 (20k ) 94 SB + +1982 228 116 (bytes ) 122 SB + +2104 228 71 (and) 71 SB + +225 287 741 (mainly text with sparse graphics files.) 741 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 435 509 (5.2 General mix) 509 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 581 90 (The ) 101 SB + +476 581 168 (General ) 179 SB + +655 581 86 (mix ) 97 SB + +752 581 44 (is ) 55 SB + +807 581 85 (one ) 96 SB + +903 581 89 (that ) 100 SB + +1003 581 44 (is ) 55 SB + +1058 581 78 (not ) 90 SB + +1148 581 217 (concerned ) 229 SB + +1377 581 100 (with ) 112 SB + +1489 581 147 (modem) 147 SB + +1636 581 13 ( ) 25 SB + +1661 581 115 (users ) 127 SB + +1788 581 197 (however, ) 209 SB + +1997 581 40 (it ) 52 SB + +2049 581 44 (is ) 56 SB + +2105 581 70 (still) 70 SB + +225 640 960 (concerned with the network responsiveness and ) 961 SB + +1186 640 247 (throughput. ) 248 SB + +1434 640 13 ( ) 14 SB + +1448 640 86 (File ) 87 SB + +1535 640 107 (sizes ) 108 SB + +1643 640 49 (in ) 50 SB + +1693 640 83 (this ) 84 SB + +1777 640 86 (mix ) 87 SB + +1864 640 85 (will ) 86 SB + +1950 640 59 (be ) 60 SB + +2010 640 165 (between) 165 SB + +225 699 351 (1 and 100k bytes.) 351 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 847 604 (5.3 Media rich mix) 604 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1022 138 (Media ) 141 SB + +516 1022 88 (rich ) 91 SB + +607 1022 44 (is ) 47 SB + +654 1022 158 (defined ) 161 SB + +815 1022 60 (by ) 63 SB + +878 1022 74 (the ) 77 SB + +955 1022 98 (type ) 101 SB + +1056 1022 84 (and ) 88 SB + +1144 1022 88 (size ) 92 SB + +1236 1022 54 (of ) 58 SB + +1294 1022 97 (data ) 101 SB + +1395 1022 150 (stored. ) 154 SB + +1549 1022 13 ( ) 17 SB + +1566 1022 138 (Media ) 142 SB + +1708 1022 169 (referees ) 173 SB + +1881 1022 54 (to ) 58 SB + +1939 1022 236 (multi-media) 236 SB + +225 1081 161 (content ) 164 SB + +389 1081 103 (such ) 106 SB + +495 1081 68 (as: ) 71 SB + +566 1081 13 ( ) 16 SB + +582 1081 152 (MPEG ) 155 SB + +737 1081 84 (and ) 87 SB + +824 1081 219 (Quicktime ) 222 SB + +1046 1081 134 (movie ) 137 SB + +1183 1081 106 (files, ) 110 SB + +1293 1081 152 (MPEG ) 156 SB + +1449 1081 84 (and ) 88 SB + +1537 1081 77 (aiff ) 81 SB + +1618 1081 111 (..etc. ) 115 SB + +1733 1081 132 (sound ) 136 SB + +1869 1081 116 (clips, ) 120 SB + +1989 1081 84 (and ) 88 SB + +2077 1081 98 (large) 98 SB + +225 1140 179 (graphics ) 183 SB + +408 1140 106 (files. ) 111 SB + +519 1140 13 ( ) 18 SB + +537 1140 138 (Media ) 143 SB + +680 1140 88 (rich ) 93 SB + +773 1140 161 (content ) 166 SB + +939 1140 100 (sites ) 105 SB + +1044 1140 74 (are ) 79 SB + +1123 1140 78 (not ) 83 SB + +1206 1140 168 (worried ) 173 SB + +1379 1140 125 (about ) 130 SB + +1509 1140 74 (the ) 79 SB + +1588 1140 88 (size ) 93 SB + +1681 1140 54 (of ) 59 SB + +1740 1140 103 (their ) 108 SB + +1848 1140 106 (files. ) 111 SB + +1959 1140 131 (These ) 136 SB + +2095 1140 80 (files) 80 SB + +225 1199 151 (usually ) 155 SB + +380 1199 150 (consist ) 154 SB + +534 1199 54 (of ) 58 SB + +592 1199 134 (movie ) 138 SB + +730 1199 103 (clips ) 107 SB + +837 1199 84 (and ) 88 SB + +925 1199 132 (sound ) 136 SB + +1061 1199 106 (files. ) 110 SB + +1171 1199 13 ( ) 17 SB + +1188 1199 99 (This ) 104 SB + +1292 1199 86 (mix ) 91 SB + +1383 1199 44 (is ) 49 SB + +1432 1199 104 (used ) 109 SB + +1541 1199 54 (to ) 59 SB + +1600 1199 124 (cover ) 129 SB + +1729 1199 83 (this ) 88 SB + +1817 1199 119 (need. ) 124 SB + +1941 1199 13 ( ) 18 SB + +1959 1199 131 (These ) 136 SB + +2095 1199 80 (files) 80 SB + +225 1258 732 (range in size from 20k to megabytes.) 732 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1406 1005 (5.4 General and media rich mix) 1005 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1552 929 (To cover the combination of a site that wishes ) 930 SB + +1305 1552 54 (to ) 55 SB + +1360 1552 134 (server ) 135 SB + +1495 1552 102 (both ) 103 SB + +1598 1552 115 (small ) 116 SB + +1714 1552 161 (content ) 162 SB + +1876 1552 84 (and ) 85 SB + +1961 1552 138 (Media ) 139 SB + +2100 1552 75 (rich) 75 SB + +225 1611 1279 (content this mix was created. This mix will most suite this need.) 1279 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1759 619 (6. Load Generation) 619 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1934 90 (The ) 98 SB + +473 1934 155 (current ) 163 SB + +636 1934 98 (load ) 106 SB + +742 1934 222 (generation ) 230 SB + +972 1934 54 (of ) 62 SB + +1034 1934 74 (the ) 82 SB + +1116 1934 267 (WebSTONE ) 275 SB + +1391 1934 44 (is ) 52 SB + +1443 1934 54 (to ) 62 SB + +1505 1934 158 (request ) 166 SB + +1671 1934 126 (pages ) 134 SB + +1805 1934 84 (and ) 92 SB + +1897 1934 93 (files ) 101 SB + +1998 1934 108 (from ) 116 SB + +2114 1934 61 (the) 61 SB + +225 1993 134 (server ) 142 SB + +367 1993 54 (as ) 62 SB + +429 1993 84 (fast ) 92 SB + +521 1993 54 (as ) 62 SB + +583 1993 74 (the ) 82 SB + +665 1993 134 (server ) 142 SB + +807 1993 81 (can ) 89 SB + +896 1993 103 (send ) 111 SB + +1007 1993 124 (them. ) 132 SB + +1139 1993 13 ( ) 21 SB + +1160 1993 215 (Reflecting ) 223 SB + +1383 1993 74 (the ) 82 SB + +1465 1993 155 (current ) 163 SB + +1628 1993 260 (environment ) 268 SB + +1896 1993 49 (in ) 58 SB + +1954 1993 74 (the ) 83 SB + +2037 1993 138 (WWW) 138 SB + +225 2052 1376 (community. To generate a load there are four things that are needed.) 1376 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 2109 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2114 48 (A ) 51 SB + +351 2114 162 (number ) 165 SB + +516 2114 54 (of ) 57 SB + +573 2114 276 (Webchildern. ) 279 SB + +852 2114 13 ( ) 16 SB + +868 2114 90 (The ) 93 SB + +961 2114 115 (more ) 118 SB + +1079 2114 263 (Webchildern ) 266 SB + +1345 2114 89 (that ) 92 SB + +1437 2114 74 (are ) 77 SB + +1514 2114 219 (requesting ) 222 SB + +1736 2114 126 (pages ) 129 SB + +1865 2114 108 (from ) 111 SB + +1976 2114 74 (the ) 78 SB + +2054 2114 121 (server) 121 SB + +300 2173 667 (the more load that this will cause.) 667 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 2230 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2235 1764 (The type of page. This is mainly determined by the page size and the weight of the page.) 1764 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 2292 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2297 174 (Number ) 175 SB + +475 2297 54 (of ) 55 SB + +530 2297 152 (clients. ) 153 SB + +683 2297 13 ( ) 14 SB + +697 2297 90 (The ) 91 SB + +788 2297 115 (more ) 116 SB + +904 2297 139 (clients ) 140 SB + +1044 2297 89 (that ) 90 SB + +1134 2297 74 (are ) 75 SB + +1209 2297 49 (in ) 50 SB + +1259 2297 74 (the ) 75 SB + +1334 2297 84 (test ) 85 SB + +1419 2297 74 (the ) 75 SB + +1494 2297 115 (more ) 116 SB + +1610 2297 263 (Webchildern ) 264 SB + +1874 2297 89 (that ) 90 SB + +1964 2297 74 (are ) 75 SB + +2039 2297 93 (able ) 95 SB + +2134 2297 41 (to) 41 SB + +300 2356 651 (be brought to bear on the server.) 651 SB + +32 0 0 50 50 0 0 0 50 /Symbol font + +225 2413 36 (\267 ) 75 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2418 1703 (The number of pages. The more pages that are requested test other aspects of server.) 1703 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2596 579 (6.1 Page selection) 579 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2771 1140 (Each page in the mix has a percentage associated with it. ) 1141 SB + +1516 2771 13 ( ) 14 SB + +1530 2771 99 (This ) 100 SB + +1630 2771 229 (percentage ) 230 SB + +1860 2771 44 (is ) 45 SB + +1905 2771 74 (the ) 75 SB + +1980 2771 195 (weighting) 195 SB + +225 2830 143 (factor. ) 151 SB + +376 2830 13 ( ) 21 SB + +397 2830 90 (The ) 98 SB + +495 2830 137 (higher ) 145 SB + +640 2830 74 (the ) 82 SB + +722 2830 162 (number ) 170 SB + +892 2830 74 (the ) 82 SB + +974 2830 115 (more ) 123 SB + +1097 2830 178 (frequent ) 186 SB + +1283 2830 74 (the ) 82 SB + +1365 2830 107 (page ) 115 SB + +1480 2830 85 (will ) 93 SB + +1573 2830 59 (be ) 67 SB + +1640 2830 77 (hit. ) 85 SB + +1725 2830 13 ( ) 21 SB + +1746 2830 48 (A ) 56 SB + +1802 2830 164 (random ) 172 SB + +1974 2830 162 (number ) 170 SB + +2144 2830 31 (is) 31 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Symbol + +%%+ font Times-Bold + +%%+ font Times-Roman + +%%Page: 13 13 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (13) 42 SB + +gr + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +225 169 833 (generated and then compared to the page ) 834 SB + +1059 169 160 (weight. ) 161 SB + +1220 169 13 ( ) 14 SB + +1234 169 45 (If ) 46 SB + +1280 169 74 (the ) 75 SB + +1355 169 164 (random ) 165 SB + +1520 169 162 (number ) 163 SB + +1683 169 174 (matches ) 175 SB + +1858 169 74 (the ) 75 SB + +1933 169 107 (page ) 108 SB + +2041 169 134 (weight) 134 SB + +225 228 98 (then ) 100 SB + +325 228 89 (that ) 91 SB + +416 228 142 (pages\222 ) 144 SB + +560 228 93 (files ) 95 SB + +655 228 74 (are ) 76 SB + +731 228 189 (retrieved ) 192 SB + +923 228 85 (one ) 88 SB + +1011 228 50 (at ) 53 SB + +1064 228 35 (a ) 38 SB + +1102 228 112 (time. ) 115 SB + +1217 228 13 ( ) 16 SB + +1233 228 112 (Each ) 115 SB + +1348 228 263 (Webchildren ) 266 SB + +1614 228 78 (has ) 81 SB + +1695 228 59 (its ) 62 SB + +1757 228 99 (own ) 102 SB + +1859 228 164 (random ) 167 SB + +2026 228 149 (number) 149 SB + +225 287 194 (sequence.) 194 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 406 498 (6.2 Page Access) 498 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 581 117 (After ) 119 SB + +494 581 35 (a ) 38 SB + +532 581 107 (page ) 110 SB + +642 581 44 (is ) 47 SB + +689 581 172 (selected ) 175 SB + +864 581 60 (by ) 63 SB + +927 581 164 (random ) 167 SB + +1094 581 147 (weight ) 150 SB + +1244 581 98 (then ) 101 SB + +1345 581 103 (each ) 106 SB + +1451 581 200 (Webchild ) 203 SB + +1654 581 178 (contacts ) 181 SB + +1835 581 74 (the ) 77 SB + +1912 581 139 (HTTP ) 142 SB + +2054 581 121 (server) 121 SB + +225 640 84 (and ) 88 SB + +313 640 177 (requests ) 181 SB + +494 640 74 (the ) 78 SB + +572 640 91 (first ) 95 SB + +667 640 74 (file ) 78 SB + +745 640 54 (of ) 58 SB + +803 640 74 (the ) 78 SB + +881 640 120 (page. ) 124 SB + +1005 640 13 ( ) 17 SB + +1022 640 117 (After ) 121 SB + +1143 640 74 (the ) 78 SB + +1221 640 200 (Webchild ) 204 SB + +1425 640 173 (receives ) 177 SB + +1602 640 74 (the ) 78 SB + +1680 640 91 (first ) 95 SB + +1775 640 107 (page ) 112 SB + +1887 640 40 (it ) 45 SB + +1932 640 177 (requests ) 182 SB + +2114 640 61 (the) 61 SB + +225 699 98 (next ) 101 SB + +326 699 85 (one ) 89 SB + +415 699 101 (until ) 105 SB + +520 699 59 (all ) 63 SB + +583 699 74 (the ) 78 SB + +661 699 93 (files ) 97 SB + +758 699 71 (for ) 75 SB + +833 699 89 (that ) 93 SB + +926 699 107 (page ) 111 SB + +1037 699 105 (have ) 109 SB + +1146 699 105 (been ) 109 SB + +1255 699 218 (requested. ) 222 SB + +1477 699 13 ( ) 17 SB + +1494 699 73 (On ) 77 SB + +1571 699 103 (each ) 107 SB + +1678 699 107 (page ) 111 SB + +1789 699 74 (the ) 78 SB + +1867 699 99 (time ) 103 SB + +1970 699 40 (it ) 44 SB + +2014 699 116 (takes ) 120 SB + +2134 699 41 (to) 41 SB + +225 758 1465 (connect and down load the file is recorded and log if logging is turned on.) 1465 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 936 733 (6.3 Duration of the test) 733 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1111 90 (The ) 100 SB + +475 1111 267 (WebSTONE ) 277 SB + +752 1111 44 (is ) 54 SB + +806 1111 187 (designed ) 197 SB + +1003 1111 54 (to ) 64 SB + +1067 1111 79 (run ) 89 SB + +1156 1111 101 (until ) 112 SB + +1268 1111 74 (the ) 85 SB + +1353 1111 139 (clients ) 150 SB + +1503 1111 79 (run ) 90 SB + +1593 1111 79 (out ) 90 SB + +1683 1111 54 (of ) 65 SB + +1748 1111 175 (memory ) 186 SB + +1934 1111 56 (or ) 67 SB + +2001 1111 74 (the ) 85 SB + +2086 1111 89 (loop) 89 SB + +225 1170 164 (counter ) 165 SB + +390 1170 83 (hits ) 84 SB + +474 1170 151 (20000. ) 152 SB + +626 1170 13 ( ) 14 SB + +640 1170 90 (The ) 91 SB + +731 1170 102 (loop ) 103 SB + +834 1170 164 (counter ) 165 SB + +999 1170 44 (is ) 45 SB + +1044 1170 74 (the ) 75 SB + +1119 1170 133 (ability ) 134 SB + +1253 1170 54 (to ) 55 SB + +1308 1170 79 (run ) 80 SB + +1388 1170 35 (a ) 36 SB + +1424 1170 84 (test ) 85 SB + +1509 1170 49 (in ) 50 SB + +1559 1170 203 (repetition ) 204 SB + +1763 1170 54 (as ) 55 SB + +1818 1170 54 (to ) 56 SB + +1874 1170 112 (time. ) 114 SB + +1988 1170 13 ( ) 15 SB + +2003 1170 99 (This ) 101 SB + +2104 1170 71 (test) 71 SB + +225 1229 44 (is ) 45 SB + +270 1229 148 (limited ) 149 SB + +419 1229 169 (because ) 170 SB + +589 1229 54 (of ) 55 SB + +644 1229 13 ( ) 14 SB + +658 1229 120 (client ) 121 SB + +779 1229 188 (memory. ) 189 SB + +968 1229 13 ( ) 14 SB + +982 1229 45 (If ) 46 SB + +1028 1229 120 (client ) 121 SB + +1149 1229 175 (memory ) 176 SB + +1325 1229 44 (is ) 45 SB + +1370 1229 78 (not ) 79 SB + +1449 1229 59 (an ) 60 SB + +1509 1229 110 (issue ) 111 SB + +1620 1229 83 (this ) 84 SB + +1704 1229 162 (number ) 163 SB + +1867 1229 81 (can ) 83 SB + +1950 1229 59 (be ) 61 SB + +2011 1229 164 (changed) 164 SB + +225 1288 1483 (and the benchmark recompiled. Most tests do not last longer than 1 hour..) 1483 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1466 696 (7. Benchmark Results) 696 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1641 90 (The ) 91 SB + +466 1641 201 (following ) 202 SB + +668 1641 44 (is ) 45 SB + +713 1641 35 (a ) 36 SB + +749 1641 144 (typical ) 145 SB + +894 1641 79 (run ) 80 SB + +974 1641 54 (of ) 55 SB + +1029 1641 74 (the ) 75 SB + +1104 1641 243 (benchmark. ) 244 SB + +1348 1641 13 ( ) 14 SB + +1362 1641 90 (The ) 91 SB + +1453 1641 91 (first ) 92 SB + +1545 1641 79 (run ) 81 SB + +1626 1641 44 (is ) 46 SB + +1672 1641 54 (of ) 56 SB + +1728 1641 74 (the ) 76 SB + +1804 1641 230 (benchmark ) 232 SB + +2036 1641 139 (against) 139 SB + +225 1700 962 (the Netsite server followed by the NCSA server.) 962 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +225 1847 943 (The following parameters were modified to run the test:) 943 SB + +225 1897 204 (nm_clusters) 204 SB + +225 1947 279 (somaxconn = 50) 279 SB + +225 1997 334 (nm_clusters = 4000) 334 SB + +225 2047 371 (tcp_keepidle = \(1200\)) 371 SB + +225 2097 488 (tcp_keep_timer_in_close = 1) 488 SB + +225 2197 333 (Hardware platform:) 333 SB + +225 2297 459 (1 150 MHZ IP22 Processor) 459 SB + +225 2347 897 (FPU: MIPS R4010 Floating Point Chip Revision: 0.0) 897 SB + +225 2397 822 (CPU: MIPS R4400 Processor Chip Revision: 5.0) 822 SB + +225 2447 403 (On-board serial ports: 2) 403 SB + +225 2497 617 (On-board bi-directional parallel port) 617 SB + +225 2547 453 (Data cache size: 16 Kbytes) 453 SB + +225 2597 557 (Instruction cache size: 16 Kbytes) 557 SB + +225 2647 924 (Secondary unified instruction/data cache size: 1 Mbyte) 924 SB + +225 2697 534 (Main memory size: 256 Mbytes) 534 SB + +225 2747 934 (Integral ISDN: Basic Rate Interface unit 0, revision 1.0) 934 SB + +225 2797 1077 (XPI FDDI controller: xpi0, firmware version 9411032038, SAS) 1077 SB + +225 2847 546 (Integral Ethernet: ec3, version 1) 546 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 14 14 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (14) 42 SB + +gr + +225 169 546 (Integral Ethernet: ec0, version 1) 546 SB + +225 219 1215 (Integral SCSI controller 5: Version WD33C95A, differential, revision 0) 1215 SB + +225 269 657 (Disk drive: unit 4 on SCSI controller 5) 657 SB + +225 319 657 (Disk drive: unit 3 on SCSI controller 5) 657 SB + +225 369 657 (Disk drive: unit 2 on SCSI controller 5) 657 SB + +225 419 657 (Disk drive: unit 1 on SCSI controller 5) 657 SB + +225 469 1215 (Integral SCSI controller 4: Version WD33C95A, differential, revision 0) 1215 SB + +225 519 1012 (Integral SCSI controller 0: Version WD33C93B, revision D) 1012 SB + +225 569 657 (Disk drive: unit 5 on SCSI controller 0) 657 SB + +225 619 633 (CDROM: unit 4 on SCSI controller 0) 633 SB + +225 669 657 (Disk drive: unit 2 on SCSI controller 0) 657 SB + +225 769 1633 (The file set used for this test is listed below. In this case a general and media rich mix was used.) 1633 SB + +225 869 1097 (#This file is used to configure the pages and files to be tested for.) 1097 SB + +225 919 21 (6) 21 SB + +225 969 74 (40 3) 74 SB + +225 1019 199 (/file3k.html) 199 SB + +225 1069 199 (/file4k.html) 199 SB + +225 1119 199 (/file5k.html) 199 SB + +225 1169 53 (5 3) 53 SB + +225 1219 220 (/file10k.html) 220 SB + +225 1269 220 (/file17k.html) 220 SB + +225 1319 220 (/file20k.html) 220 SB + +225 1369 53 (5 2) 53 SB + +225 1419 211 (/file5m.html) 211 SB + +225 1469 211 (/file1m.html) 211 SB + +225 1519 74 (20 3) 74 SB + +225 1569 199 (/file6k.html) 199 SB + +225 1619 199 (/file7k.html) 199 SB + +225 1669 241 (/file200k.html) 241 SB + +225 1719 74 (20 2) 74 SB + +225 1769 211 (/file3m.html) 211 SB + +225 1819 220 (/file21k.html) 220 SB + +225 1869 74 (10 2) 74 SB + +225 1919 241 (/file500k.html) 241 SB + +225 1969 220 (/file13k.html) 220 SB + +225 2069 1890 (What follows is the results of a test ran for 10 minutes with the above page sets. The first set of data is from the) 1890 SB + +225 2119 242 (Netsite server.) 242 SB + +225 2219 182 (Netsite 1.0) 182 SB + +225 2269 1428 (********************************************************************) 1428 SB + +225 2319 1239 (/usr/local/bin/webstone -w xpi0-alfalfa -c sulu:2959 -u filelist -t 35 -n %d) 1239 SB + +225 2369 773 (Client: gateweb-indy8 Number of Clients: 6) 773 SB + +225 2419 773 (Client: gateweb-indy9 Number of Clients: 6) 773 SB + +225 2469 783 (Client: gateweb-indy10 Number of Clients: 6) 783 SB + +225 2519 783 (Client: gateweb-indy11 Number of Clients: 6) 783 SB + +225 2619 616 (Waiting for READY from 24 clients) 616 SB + +225 2669 375 (All READYs received) 375 SB + +225 2719 428 (Sending GO to all clients) 428 SB + +225 2769 793 (All clients started at Fri Mar 17 11:23:10 1995) 793 SB + +225 2819 516 (Waiting for clients completion) 516 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Page: 15 15 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (15) 42 SB + +gr + +225 169 780 (All clients ended at Fri Mar 17 11:58:34 1995) 780 SB + +225 219 145 (Page # 0) 145 SB + +225 269 1944 (=================================================================================) 1944 SB + +225 319 692 (Total number of times page was hit 6649) 692 SB + +225 369 560 (Total time 4238.492450 seconds) 560 SB + +225 419 611 (Maximum Response time 2.071999) 611 SB + +225 469 666 (Total connect time for page 77.660191) 666 SB + +225 519 615 (Maximum time to connect 0.052151) 615 SB + +225 569 655 (Total amount of data moved 81702912) 655 SB + +225 619 273 (Page size 12288) 273 SB + +225 669 546 (Total number of connects 19947) 546 SB + +225 719 1944 (=================================================================================) 1944 SB + +225 819 145 (Page # 1) 145 SB + +225 869 1944 (=================================================================================) 1944 SB + +225 919 671 (Total number of times page was hit 607) 671 SB + +225 969 539 (Total time 526.552497 seconds) 539 SB + +225 1019 611 (Maximum Response time 1.805497) 611 SB + +225 1069 645 (Total connect time for page 8.111734) 645 SB + +225 1119 615 (Maximum time to connect 0.036912) 615 SB + +225 1169 655 (Total amount of data moved 29213696) 655 SB + +225 1219 273 (Page size 48128) 273 SB + +225 1269 525 (Total number of connects 1821) 525 SB + +225 1319 1944 (=================================================================================) 1944 SB + +225 1419 145 (Page # 2) 145 SB + +225 1469 1944 (=================================================================================) 1944 SB + +225 1519 671 (Total number of times page was hit 980) 671 SB + +225 1569 581 (Total time 15710.908864 seconds) 581 SB + +225 1619 632 (Maximum Response time 22.764984) 632 SB + +225 1669 666 (Total connect time for page 19.605667) 666 SB + +225 1719 615 (Maximum time to connect 5.785718) 615 SB + +225 1769 697 (Total amount of data moved 6165626880) 697 SB + +225 1819 315 (Page size 6291456) 315 SB + +225 1869 525 (Total number of connects 1960) 525 SB + +225 1919 1944 (=================================================================================) 1944 SB + +225 2019 145 (Page # 3) 145 SB + +225 2069 1944 (=================================================================================) 1944 SB + +225 2119 692 (Total number of times page was hit 2866) 692 SB + +225 2169 560 (Total time 2581.663009 seconds) 560 SB + +225 2219 611 (Maximum Response time 3.341992) 611 SB + +225 2269 666 (Total connect time for page 33.253920) 666 SB + +225 2319 615 (Maximum time to connect 0.046310) 615 SB + +225 2369 676 (Total amount of data moved 625108992) 676 SB + +225 2419 294 (Page size 218112) 294 SB + +225 2469 525 (Total number of connects 8598) 525 SB + +225 2519 1944 (=================================================================================) 1944 SB + +225 2619 145 (Page # 4) 145 SB + +225 2669 1944 (=================================================================================) 1944 SB + +225 2719 692 (Total number of times page was hit 3040) 692 SB + +225 2769 581 (Total time 25083.667145 seconds) 581 SB + +225 2819 632 (Maximum Response time 11.803875) 632 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Page: 16 16 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (16) 42 SB + +gr + +225 169 666 (Total connect time for page 26.375753) 666 SB + +225 219 615 (Maximum time to connect 0.036555) 615 SB + +225 269 697 (Total amount of data moved 9628385280) 697 SB + +225 319 315 (Page size 3167232) 315 SB + +225 369 525 (Total number of connects 6080) 525 SB + +225 419 1944 (=================================================================================) 1944 SB + +225 519 145 (Page # 5) 145 SB + +225 569 1944 (=================================================================================) 1944 SB + +225 619 692 (Total number of times page was hit 1628) 692 SB + +225 669 560 (Total time 2148.113647 seconds) 560 SB + +225 719 611 (Maximum Response time 2.793287) 611 SB + +225 769 666 (Total connect time for page 14.345538) 666 SB + +225 819 615 (Maximum time to connect 0.036117) 615 SB + +225 869 676 (Total amount of data moved 855207936) 676 SB + +225 919 294 (Page size 525312) 294 SB + +225 969 525 (Total number of connects 3256) 525 SB + +225 1019 1944 (=================================================================================) 1944 SB + +225 1119 816 (==================================) 816 SB + +225 1169 453 (WEBSTONE number: 450) 453 SB + +225 1219 459 (Total number of clients: 24) 459 SB + +225 1269 1051 (Total cumulative time of test for all hosts \(sec\): 50333.931099) 1051 SB + +225 1319 872 (Total number of pages retrieved from server: 15770) 872 SB + +225 1369 583 (Total number of errors to server: 0) 583 SB + +225 1419 714 (Total number of connects to server: 41672) 714 SB + +225 1469 756 (Average time per connect: 0.004304 seconds) 756 SB + +225 1519 769 (Maximum time to connect: 5.782854 seconds) 769 SB + +225 1569 711 (Total mount of data moved: 17409474560) 711 SB + +225 1619 1438 (Total bytes of body moved: 17401507840 bytes.Total bytes of header moved 7966720) 1438 SB + +225 1669 1081 (Average body size: 417583 bytes. Average retrieval size 417774) 1081 SB + +225 1719 470 (Thruput = 345879 bytes/sec) 470 SB + +225 1769 719 (Average Response time: 1.207859 seconds) 719 SB + +225 1819 775 (Maximum Response time: 19.524160 seconds) 775 SB + +225 1969 1491 (***********************************************************************) 1491 SB + +225 2019 175 (NCSA 1.3) 175 SB + +225 2069 1512 (************************************************************************) 1512 SB + +225 2169 1380 (/usr/local/bin/webstone -w xpi0-alfalfa -c sulu:2920 -p 1081 -u filelist -t 35 -n %d) 1380 SB + +225 2219 773 (Client: gateweb-indy8 Number of Clients: 6) 773 SB + +225 2269 773 (Client: gateweb-indy9 Number of Clients: 6) 773 SB + +225 2319 783 (Client: gateweb-indy10 Number of Clients: 6) 783 SB + +225 2369 783 (Client: gateweb-indy11 Number of Clients: 6) 783 SB + +225 2469 616 (Waiting for READY from 24 clients) 616 SB + +225 2519 375 (All READYs received) 375 SB + +225 2569 428 (Sending GO to all clients) 428 SB + +225 2619 793 (All clients started at Fri Mar 17 10:46:38 1995) 793 SB + +225 2669 516 (Waiting for clients completion) 516 SB + +225 2719 780 (All clients ended at Fri Mar 17 11:22:02 1995) 780 SB + +225 2769 145 (Page # 0) 145 SB + +225 2819 1944 (=================================================================================) 1944 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Page: 17 17 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (17) 42 SB + +gr + +225 169 692 (Total number of times page was hit 1414) 692 SB + +225 219 581 (Total time 16772.472590 seconds) 581 SB + +225 269 632 (Maximum Response time 23.797445) 632 SB + +225 319 666 (Total connect time for page 93.585630) 666 SB + +225 369 615 (Maximum time to connect 5.997783) 615 SB + +225 419 655 (Total amount of data moved 17375232) 655 SB + +225 469 273 (Page size 12288) 273 SB + +225 519 525 (Total number of connects 4242) 525 SB + +225 569 1944 (=================================================================================) 1944 SB + +225 669 145 (Page # 1) 145 SB + +225 719 1944 (=================================================================================) 1944 SB + +225 769 671 (Total number of times page was hit 144) 671 SB + +225 819 560 (Total time 1797.158479 seconds) 560 SB + +225 869 632 (Maximum Response time 23.050203) 632 SB + +225 919 645 (Total connect time for page 0.673942) 645 SB + +225 969 615 (Maximum time to connect 0.013216) 615 SB + +225 1019 634 (Total amount of data moved 6930432) 634 SB + +225 1069 273 (Page size 48128) 273 SB + +225 1119 504 (Total number of connects 432) 504 SB + +225 1169 1944 (=================================================================================) 1944 SB + +225 1269 145 (Page # 2) 145 SB + +225 1319 1944 (=================================================================================) 1944 SB + +225 1369 671 (Total number of times page was hit 102) 671 SB + +225 1419 560 (Total time 4813.787541 seconds) 560 SB + +225 1469 632 (Maximum Response time 56.573603) 632 SB + +225 1519 645 (Total connect time for page 6.192456) 645 SB + +225 1569 615 (Maximum time to connect 5.905150) 615 SB + +225 1619 676 (Total amount of data moved 641728512) 676 SB + +225 1669 315 (Page size 6291456) 315 SB + +225 1719 504 (Total number of connects 204) 504 SB + +225 1769 1944 (=================================================================================) 1944 SB + +225 1869 145 (Page # 3) 145 SB + +225 1919 1944 (=================================================================================) 1944 SB + +225 1969 671 (Total number of times page was hit 580) 671 SB + +225 2019 560 (Total time 7588.192121 seconds) 560 SB + +225 2069 632 (Maximum Response time 25.115934) 632 SB + +225 2119 645 (Total connect time for page 2.897182) 645 SB + +225 2169 615 (Maximum time to connect 0.019975) 615 SB + +225 2219 676 (Total amount of data moved 126504960) 676 SB + +225 2269 294 (Page size 218112) 294 SB + +225 2319 525 (Total number of connects 1740) 525 SB + +225 2369 1944 (=================================================================================) 1944 SB + +225 2469 145 (Page # 4) 145 SB + +225 2519 1944 (=================================================================================) 1944 SB + +225 2569 671 (Total number of times page was hit 600) 671 SB + +225 2619 581 (Total time 16247.815216 seconds) 581 SB + +225 2669 632 (Maximum Response time 39.003870) 632 SB + +225 2719 645 (Total connect time for page 1.790447) 645 SB + +225 2769 615 (Maximum time to connect 0.015736) 615 SB + +225 2819 697 (Total amount of data moved 1900339200) 697 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Page: 18 18 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (18) 42 SB + +gr + +225 169 315 (Page size 3167232) 315 SB + +225 219 525 (Total number of connects 1200) 525 SB + +225 269 1944 (=================================================================================) 1944 SB + +225 369 145 (Page # 5) 145 SB + +225 419 1944 (=================================================================================) 1944 SB + +225 469 671 (Total number of times page was hit 294) 671 SB + +225 519 560 (Total time 2922.036210 seconds) 560 SB + +225 569 632 (Maximum Response time 20.210504) 632 SB + +225 619 666 (Total connect time for page 18.487052) 666 SB + +225 669 615 (Maximum time to connect 5.843007) 615 SB + +225 719 676 (Total amount of data moved 154441728) 676 SB + +225 769 294 (Page size 525312) 294 SB + +225 819 504 (Total number of connects 588) 504 SB + +225 869 1944 (=================================================================================) 1944 SB + +225 969 816 (==================================) 816 SB + +225 1019 432 (WEBSTONE number: 89) 432 SB + +225 1069 459 (Total number of clients: 24) 459 SB + +225 1119 1051 (Total cumulative time of test for all hosts \(sec\): 50244.193163) 1051 SB + +225 1169 851 (Total number of pages retrieved from server: 3134) 851 SB + +225 1219 583 (Total number of errors to server: 0) 583 SB + +225 1269 693 (Total number of connects to server: 8420) 693 SB + +225 1319 756 (Average time per connect: 0.014684 seconds) 756 SB + +225 1369 769 (Maximum time to connect: 5.995063 seconds) 769 SB + +225 1419 690 (Total mount of data moved: 2848899584) 690 SB + +225 1469 1417 (Total bytes of body moved: 2847382528 bytes.Total bytes of header moved 1517056) 1417 SB + +225 1519 1081 (Average body size: 338169 bytes. Average retrieval size 338349) 1081 SB + +225 1569 460 (Thruput = 56701 bytes/sec) 460 SB + +225 1619 719 (Average Response time: 5.967243 seconds) 719 SB + +225 1669 775 (Maximum Response time: 42.658441 seconds) 775 SB + +225 1769 904 (cern 3.0 ************************************) 904 SB + +225 1819 1380 (/usr/local/bin/webstone -w xpi0-alfalfa -c sulu:2996 -p 1080 -u filelist -t 45 -n %d) 1380 SB + +225 1869 773 (Client: gateweb-indy8 Number of Clients: 6) 773 SB + +225 1919 773 (Client: gateweb-indy9 Number of Clients: 6) 773 SB + +225 1969 783 (Client: gateweb-indy10 Number of Clients: 6) 783 SB + +225 2019 783 (Client: gateweb-indy11 Number of Clients: 6) 783 SB + +225 2119 616 (Waiting for READY from 24 clients) 616 SB + +225 2169 375 (All READYs received) 375 SB + +225 2219 428 (Sending GO to all clients) 428 SB + +225 2269 793 (All clients started at Fri Mar 17 15:10:43 1995) 793 SB + +225 2319 516 (Waiting for clients completion) 516 SB + +225 2369 780 (All clients ended at Fri Mar 17 15:56:07 1995) 780 SB + +225 2419 145 (Page # 0) 145 SB + +225 2469 1944 (=================================================================================) 1944 SB + +225 2519 692 (Total number of times page was hit 3724) 692 SB + +225 2569 581 (Total time 16302.320093 seconds) 581 SB + +225 2619 632 (Maximum Response time 62.488345) 632 SB + +225 2669 708 (Total connect time for page 7149.901812) 708 SB + +225 2719 636 (Maximum time to connect 59.671519) 636 SB + +225 2769 655 (Total amount of data moved 45530112) 655 SB + +225 2819 273 (Page size 12288) 273 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Page: 19 19 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (19) 42 SB + +gr + +225 169 546 (Total number of connects 11105) 546 SB + +225 219 1944 (=================================================================================) 1944 SB + +225 319 145 (Page # 1) 145 SB + +225 369 1944 (=================================================================================) 1944 SB + +225 419 671 (Total number of times page was hit 501) 671 SB + +225 469 560 (Total time 2637.893006 seconds) 560 SB + +225 519 632 (Maximum Response time 38.798005) 632 SB + +225 569 708 (Total connect time for page 1229.359340) 708 SB + +225 619 636 (Maximum time to connect 35.484663) 636 SB + +225 669 655 (Total amount of data moved 24018944) 655 SB + +225 719 273 (Page size 48128) 273 SB + +225 769 525 (Total number of connects 1496) 525 SB + +225 819 1944 (=================================================================================) 1944 SB + +225 919 145 (Page # 2) 145 SB + +225 969 1944 (=================================================================================) 1944 SB + +225 1019 671 (Total number of times page was hit 432) 671 SB + +225 1069 560 (Total time 3164.881323 seconds) 560 SB + +225 1119 632 (Maximum Response time 41.850207) 632 SB + +225 1169 708 (Total connect time for page 1267.914110) 708 SB + +225 1219 636 (Maximum time to connect 35.819251) 636 SB + +225 1269 697 (Total amount of data moved 2707423232) 697 SB + +225 1319 315 (Page size 6291456) 315 SB + +225 1369 504 (Total number of connects 862) 504 SB + +225 1419 1944 (=================================================================================) 1944 SB + +225 1519 145 (Page # 3) 145 SB + +225 1569 1944 (=================================================================================) 1944 SB + +225 1619 692 (Total number of times page was hit 2080) 692 SB + +225 1669 560 (Total time 8849.459607 seconds) 560 SB + +225 1719 632 (Maximum Response time 63.461733) 632 SB + +225 1769 708 (Total connect time for page 3450.850531) 708 SB + +225 1819 636 (Maximum time to connect 59.909275) 636 SB + +225 1869 676 (Total amount of data moved 453441536) 676 SB + +225 1919 294 (Page size 218112) 294 SB + +225 1969 525 (Total number of connects 6205) 525 SB + +225 2019 1944 (=================================================================================) 1944 SB + +225 2119 145 (Page # 4) 145 SB + +225 2169 1944 (=================================================================================) 1944 SB + +225 2219 692 (Total number of times page was hit 1732) 692 SB + +225 2269 581 (Total time 10588.881744 seconds) 581 SB + +225 2319 632 (Maximum Response time 63.663196) 632 SB + +225 2369 708 (Total connect time for page 5386.565167) 708 SB + +225 2419 636 (Maximum time to connect 59.516712) 636 SB + +225 2469 697 (Total amount of data moved 5447897088) 697 SB + +225 2519 315 (Page size 3167232) 315 SB + +225 2569 525 (Total number of connects 3452) 525 SB + +225 2619 1944 (=================================================================================) 1944 SB + +225 2719 145 (Page # 5) 145 SB + +225 2769 1944 (=================================================================================) 1944 SB + +225 2819 671 (Total number of times page was hit 943) 671 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Page: 20 20 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (20) 42 SB + +gr + +225 169 560 (Total time 3968.363226 seconds) 560 SB + +225 219 632 (Maximum Response time 62.245675) 632 SB + +225 269 708 (Total connect time for page 2099.311825) 708 SB + +225 319 636 (Maximum time to connect 59.244292) 636 SB + +225 369 676 (Total amount of data moved 491273216) 676 SB + +225 419 294 (Page size 525312) 294 SB + +225 469 525 (Total number of connects 1878) 525 SB + +225 519 1896 (===============================================================================) 1896 SB + +225 619 816 (==================================) 816 SB + +225 669 453 (WEBSTONE number: 209) 453 SB + +225 719 459 (Total number of clients: 24) 459 SB + +225 769 1051 (Total cumulative time of test for all hosts \(sec\): 45943.710179) 1051 SB + +225 819 851 (Total number of pages retrieved from server: 9412) 851 SB + +225 869 625 (Total number of errors to server: 247) 625 SB + +225 919 714 (Total number of connects to server: 25167) 714 SB + +225 969 756 (Average time per connect: 0.823767 seconds) 756 SB + +225 1019 790 (Maximum time to connect: 30.002288 seconds) 790 SB + +225 1069 690 (Total mount of data moved: 9394691072) 690 SB + +225 1119 1417 (Total bytes of body moved: 9389627392 bytes.Total bytes of header moved 5063680) 1417 SB + +225 1169 1081 (Average body size: 373093 bytes. Average retrieval size 373294) 1081 SB + +225 1219 470 (Thruput = 204483 bytes/sec) 470 SB + +225 1269 719 (Average Response time: 1.825553 seconds) 719 SB + +225 1319 775 (Maximum Response time: 34.973206 seconds) 775 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1420 736 (7.1 Summary of results) 736 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +225 1595 182 (Netsite 1.0) 182 SB + +225 1645 453 (WEBSTONE number: 450) 453 SB + +225 1695 459 (Total number of clients: 24) 459 SB + +225 1745 1051 (Total cumulative time of test for all hosts \(sec\): 50333.931099) 1051 SB + +225 1795 872 (Total number of pages retrieved from server: 15770) 872 SB + +225 1845 583 (Total number of errors to server: 0) 583 SB + +225 1895 714 (Total number of connects to server: 41672) 714 SB + +225 1945 756 (Average time per connect: 0.004304 seconds) 756 SB + +225 1995 769 (Maximum time to connect: 5.782854 seconds) 769 SB + +225 2045 711 (Total mount of data moved: 17409474560) 711 SB + +225 2095 1438 (Total bytes of body moved: 17401507840 bytes.Total bytes of header moved 7966720) 1438 SB + +225 2145 1081 (Average body size: 417583 bytes. Average retrieval size 417774) 1081 SB + +225 2195 470 (Thruput = 345879 bytes/sec) 470 SB + +225 2245 719 (Average Response time: 1.207859 seconds) 719 SB + +225 2295 775 (Maximum Response time: 19.524160 seconds) 775 SB + +225 2395 147 (Cern 3.0) 147 SB + +225 2445 453 (WEBSTONE number: 209) 453 SB + +225 2495 459 (Total number of clients: 24) 459 SB + +225 2545 1051 (Total cumulative time of test for all hosts \(sec\): 45943.710179) 1051 SB + +225 2595 851 (Total number of pages retrieved from server: 9412) 851 SB + +225 2645 625 (Total number of errors to server: 247) 625 SB + +225 2695 714 (Total number of connects to server: 25167) 714 SB + +225 2745 756 (Average time per connect: 0.823767 seconds) 756 SB + +225 2795 790 (Maximum time to connect: 30.002288 seconds) 790 SB + +225 2845 690 (Total mount of data moved: 9394691072) 690 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 21 21 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (21) 42 SB + +gr + +225 169 1417 (Total bytes of body moved: 9389627392 bytes.Total bytes of header moved 5063680) 1417 SB + +225 219 1081 (Average body size: 373093 bytes. Average retrieval size 373294) 1081 SB + +225 269 470 (Thruput = 204483 bytes/sec) 470 SB + +225 319 719 (Average Response time: 1.825553 seconds) 719 SB + +225 369 775 (Maximum Response time: 34.973206 seconds) 775 SB + +225 469 175 (NCSA 1.3) 175 SB + +225 519 432 (WEBSTONE number: 89) 432 SB + +225 569 459 (Total number of clients: 24) 459 SB + +225 619 1051 (Total cumulative time of test for all hosts \(sec\): 50244.193163) 1051 SB + +225 669 851 (Total number of pages retrieved from server: 3134) 851 SB + +225 719 583 (Total number of errors to server: 0) 583 SB + +225 769 693 (Total number of connects to server: 8420) 693 SB + +225 819 756 (Average time per connect: 0.014684 seconds) 756 SB + +225 869 769 (Maximum time to connect: 5.995063 seconds) 769 SB + +225 919 690 (Total mount of data moved: 2848899584) 690 SB + +225 969 1417 (Total bytes of body moved: 2847382528 bytes.Total bytes of header moved 1517056) 1417 SB + +225 1019 1081 (Average body size: 338169 bytes. Average retrieval size 338349) 1081 SB + +225 1069 460 (Thruput = 56701 bytes/sec) 460 SB + +225 1119 719 (Average Response time: 5.967243 seconds) 719 SB + +225 1169 775 (Maximum Response time: 42.658441 seconds) 775 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +225 1307 1818 (The three examples above show a typical output from a run of the WebSTONE benchmark.) 1818 SB + +225 1366 1393 (The WebSTONE number is the number of pages retrieved per minute.) 1393 SB + +225 1425 1863 (Average time to connect: This is calculated by dividing the total time to connect by the total ) 1863 SB + +375 1484 403 (number of connects.) 403 SB + +225 1543 1907 (Maximum time to connect: This is defined as the longest time it took to connect during the run.) 1907 SB + +225 1602 1579 (Total amount of data moved: This is the amount of data transferred during the ) 1580 SB + +1805 1602 92 (run. ) 93 SB + +1898 1602 30 (\( ) 31 SB + +1929 1602 161 (NOTE: ) 162 SB + +2091 1602 13 ( ) 14 SB + +2105 1602 70 (this) 70 SB + +375 1661 1756 (also includes data moved of pages that where incomplete. Incomplete pages means that ) 1756 SB + +375 1720 1401 (the page was interrupted during retrieval and was unable to complete.\)) 1401 SB + +225 1779 1909 (Average Response time: This is calculated by dividing the total response time by the number of ) 1909 SB + +375 1838 187 (response.) 187 SB + +225 1897 1649 (Maximum response time: This is the maximum time to connect and transfer a page.) 1649 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2045 1455 (8. Future of the WebSTONE and future work) 1455 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 2220 67 (As ) 69 SB + +444 2220 83 (this ) 85 SB + +529 2220 44 (is ) 46 SB + +575 2220 74 (the ) 76 SB + +651 2220 91 (first ) 93 SB + +744 2220 157 (version ) 159 SB + +903 2220 54 (of ) 56 SB + +959 2220 74 (the ) 76 SB + +1035 2220 230 (benchmark ) 232 SB + +1267 2220 40 (it ) 42 SB + +1309 2220 44 (is ) 46 SB + +1355 2220 54 (to ) 56 SB + +1411 2220 59 (be ) 62 SB + +1473 2220 227 (considered ) 230 SB + +1703 2220 35 (a ) 38 SB + +1741 2220 122 (living ) 125 SB + +1866 2220 230 (benchmark ) 233 SB + +2099 2220 76 (that) 76 SB + +225 2279 699 (will continue to grow and improve.) 699 SB + +375 2397 482 (In the future there are a ) 483 SB + +858 2397 162 (number ) 163 SB + +1021 2397 54 (of ) 55 SB + +1076 2397 132 (things ) 133 SB + +1209 2397 89 (that ) 90 SB + +1299 2397 106 (need ) 107 SB + +1406 2397 54 (to ) 55 SB + +1461 2397 59 (be ) 60 SB + +1521 2397 132 (added ) 133 SB + +1654 2397 54 (to ) 55 SB + +1709 2397 74 (the ) 75 SB + +1784 2397 230 (benchmark ) 231 SB + +2015 2397 89 (that ) 90 SB + +2105 2397 70 (this) 70 SB + +225 2456 1529 (author at this time did not have time to add. The following is but a small list.) 1529 SB + +32 0 0 75 75 0 0 0 75 /Symbol font + +226 2513 34 (\267) 35 SB + +261 2513 19 ( ) 40 SB + +225 2513 34 (\267) 35 SB + +260 2513 19 ( ) 40 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2543 893 (Effects of the CGI \(Common Gate Interface\)) 893 SB + +32 0 0 75 75 0 0 0 75 /Symbol font + +226 2600 34 (\267) 35 SB + +261 2600 19 ( ) 40 SB + +225 2600 34 (\267) 35 SB + +260 2600 19 ( ) 40 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2630 798 (Security \(encryption and authentication\)) 798 SB + +32 0 0 75 75 0 0 0 75 /Symbol font + +226 2687 34 (\267) 35 SB + +261 2687 19 ( ) 40 SB + +225 2687 34 (\267) 35 SB + +260 2687 19 ( ) 40 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2717 298 (HTML parsing) 298 SB + +32 0 0 75 75 0 0 0 75 /Symbol font + +226 2774 34 (\267) 35 SB + +261 2774 19 ( ) 40 SB + +225 2774 34 (\267) 35 SB + +260 2774 19 ( ) 40 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +300 2804 436 (RDBMS performance) 436 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Symbol + +%%+ font Times-Bold + +%%+ font Times-Roman + +%%Page: 22 22 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (22) 42 SB + +gr + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 257 1067 (These and others are of importance in the near future.) 1067 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 376 658 (9. Acknowledgments) 658 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 551 129 (There ) 139 SB + +514 551 74 (are ) 84 SB + +598 551 35 (a ) 45 SB + +643 551 162 (number ) 172 SB + +815 551 54 (of ) 64 SB + +879 551 145 (people ) 155 SB + +1034 551 89 (that ) 99 SB + +1133 551 105 (have ) 115 SB + +1248 551 143 (helped ) 153 SB + +1401 551 100 (with ) 111 SB + +1512 551 83 (this ) 94 SB + +1606 551 230 (benchmark ) 241 SB + +1847 551 102 (over ) 113 SB + +1960 551 74 (the ) 85 SB + +2045 551 94 (past ) 105 SB + +2150 551 25 (2) 25 SB + +225 610 171 (months. ) 180 SB + +405 610 13 ( ) 22 SB + +427 610 103 (First ) 112 SB + +539 610 84 (and ) 93 SB + +632 610 190 (foremost ) 199 SB + +831 610 121 (Mark ) 130 SB + +961 610 110 (Sake ) 120 SB + +1081 610 99 (who ) 109 SB + +1190 610 143 (helped ) 153 SB + +1343 610 108 (code ) 118 SB + +1461 610 84 (and ) 94 SB + +1555 610 448 (developed/architected ) 458 SB + +2013 610 74 (the ) 84 SB + +2097 610 78 (first) 78 SB + +225 669 1412 (version of the benchmark. Steffen Low for support and belief that this ) 1413 SB + +1638 669 144 (should ) 145 SB + +1783 669 168 (happen. ) 169 SB + +1952 669 13 ( ) 14 SB + +1966 669 70 (To ) 71 SB + +2037 669 138 (Helena) 138 SB + +225 728 339 (Winkler-Parenty ) 353 SB + +578 728 71 (for ) 85 SB + +663 728 59 (all ) 73 SB + +736 728 76 (her ) 90 SB + +826 728 109 (help. ) 123 SB + +949 728 13 ( ) 27 SB + +976 728 30 (I ) 44 SB + +1020 728 137 (would ) 151 SB + +1171 728 92 (also ) 107 SB + +1278 728 84 (like ) 99 SB + +1377 728 54 (to ) 69 SB + +1446 728 147 (special ) 162 SB + +1608 728 123 (thank ) 138 SB + +1746 728 132 (David ) 147 SB + +1893 728 209 (Ceimwize ) 224 SB + +2117 728 58 (for) 58 SB + +225 787 535 (contributions to this paper.) 535 SB + +375 905 221 (Additional ) 222 SB + +597 905 142 (thanks ) 143 SB + +740 905 54 (to ) 55 SB + +795 905 105 (Neal ) 106 SB + +901 905 177 (Nucklus ) 178 SB + +1079 905 84 (and ) 85 SB + +1164 905 82 (Bill ) 83 SB + +1247 905 182 (Nowicki ) 183 SB + +1430 905 71 (for ) 72 SB + +1502 905 147 (critical ) 148 SB + +1650 905 114 (input ) 115 SB + +1765 905 54 (to ) 55 SB + +1820 905 83 (this ) 84 SB + +1904 905 124 (paper ) 125 SB + +2029 905 84 (and ) 85 SB + +2114 905 61 (the) 61 SB + +225 964 230 (benchmark.) 230 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1083 742 (10. Author information) 742 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +375 1258 117 (Gene ) 128 SB + +503 1258 122 (Trent ) 133 SB + +636 1258 44 (is ) 55 SB + +691 1258 35 (a ) 46 SB + +737 1258 179 (Member ) 190 SB + +927 1258 54 (of ) 65 SB + +992 1258 204 (Technical ) 215 SB + +1207 1258 99 (staff ) 110 SB + +1317 1258 49 (in ) 61 SB + +1378 1258 74 (the ) 86 SB + +1464 1258 187 (Advance ) 199 SB + +1663 1258 108 (Data ) 120 SB + +1783 1258 178 (Division ) 190 SB + +1973 1258 54 (of ) 66 SB + +2039 1258 136 (Silicon) 136 SB + +225 1317 203 (Graphics. ) 220 SB + +445 1317 13 ( ) 30 SB + +475 1317 87 (Mr. ) 104 SB + +579 1317 122 (Trent ) 139 SB + +718 1317 44 (is ) 61 SB + +779 1317 74 (the ) 91 SB + +870 1317 184 (principal ) 201 SB + +1071 1317 194 (Software ) 211 SB + +1282 1317 190 (Engineer ) 207 SB + +1489 1317 89 (that ) 106 SB + +1595 1317 216 (developed ) 234 SB + +1829 1317 74 (the ) 92 SB + +1921 1317 254 (WebSTONE) 254 SB + +225 1376 230 (benchmark ) 231 SB + +456 1376 84 (and ) 85 SB + +541 1376 142 (author ) 143 SB + +684 1376 54 (of ) 55 SB + +739 1376 83 (this ) 84 SB + +823 1376 122 (white ) 124 SB + +947 1376 137 (paper. ) 139 SB + +1086 1376 13 ( ) 15 SB + +1101 1376 117 (Gene ) 119 SB + +1220 1376 119 (holds ) 121 SB + +1341 1376 35 (a ) 37 SB + +1378 1376 201 (bachelors ) 203 SB + +1581 1376 146 (degree ) 148 SB + +1729 1376 49 (in ) 51 SB + +1780 1376 216 (Electronic ) 218 SB + +1998 1376 177 (Engineer) 177 SB + +225 1435 232 (technology ) 235 SB + +460 1435 108 (from ) 111 SB + +571 1435 135 (Devry ) 138 SB + +709 1435 177 (Institute ) 180 SB + +889 1435 54 (of ) 57 SB + +946 1435 261 (Technology. ) 264 SB + +1210 1435 13 ( ) 16 SB + +1226 1435 71 (He ) 74 SB + +1300 1435 81 (can ) 84 SB + +1384 1435 59 (be ) 63 SB + +1447 1435 167 (reached ) 171 SB + +1618 1435 50 (at ) 54 SB + +1672 1435 249 (et@sgi.com ) 253 SB + +1925 1435 56 (or ) 60 SB + +1985 1435 50 (at ) 54 SB + +2039 1435 136 (Silicon) 136 SB + +225 1494 757 (Graphics 2011 N. Mountain View, Ca) 757 SB + +375 1612 121 (Mark ) 133 SB + +508 1612 110 (Sake ) 122 SB + +630 1612 44 (is ) 56 SB + +686 1612 35 (a ) 47 SB + +733 1612 179 (Member ) 191 SB + +924 1612 54 (of ) 66 SB + +990 1612 204 (Technical ) 216 SB + +1206 1612 99 (staff ) 111 SB + +1317 1612 49 (in ) 61 SB + +1378 1612 74 (the ) 86 SB + +1464 1612 187 (Advance ) 199 SB + +1663 1612 108 (Data ) 120 SB + +1783 1612 178 (Division ) 190 SB + +1973 1612 54 (of ) 66 SB + +2039 1612 136 (Silicon) 136 SB + +225 1671 1238 (Graphics. Mr. Sake co-authored the WebSTONE benchmark.) 1238 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 1938 486 (11. References:) 486 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +383 2094 59 ([1]) 59 SB + +525 2094 862 (Berners-Lee, Fielding, and Frystyk Nielsen.) 862 SB + +525 2153 303 (\223Hypertext Tra) 303 SB + +828 2153 550 (nsfer Protocol - HTTP/1.0\224) 550 SB + +525 2212 986 (Network Working Group INTERRNET_DRAFT) 986 SB + +525 2271 639 (<draft-fielding-http-spec-01.ps>) 639 SB + +525 2330 1311 (<URL:http://www.ics.uci.edu/pub/ietf/http/> December 19, 1994) 1311 SB + +375 2439 59 ([2]) 59 SB + +525 2439 566 (Mark Wittle, Bruce E. Keith) 566 SB + +525 2498 1359 (\223LADDIS: The Next Generation In NFS File Server Benchmarking\224) 1359 SB + +525 2557 1031 (USENIX Association Conference Proceeding, 1993) 1031 SB + +32 0 0 75 75 0 0 0 69 /Times-Bold /font29 ANSIFont font + +225 2726 507 (12. Trademarks) 507 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Bold + +%%+ font Times-Roman + +%%Page: 23 23 + +%%PageResources: (atend) + +SS + +0 0 25 11 798 1100 300 SM + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +0 0 0 fC + +225 2951 226 (Gene Trent) 226 SB + +225 3010 716 (Copyright \251 Silicon Graphics, 1995) 716 SB + +32 0 0 42 42 0 0 0 38 /Times-Roman /font32 ANSIFont font + +gs 42 50 2133 2899 CB + +2133 2901 42 (23) 42 SB + +gr + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +225 169 91 (NFS) 91 SB + +32 0 0 31 31 0 0 0 28 /Times-Roman /font32 ANSIFont font + +316 163 32 (tm) 32 SB + +32 0 0 50 50 0 0 0 45 /Times-Roman /font32 ANSIFont font + +348 169 828 ( is a trademark of Sun Microsystems, Inc.) 828 SB + +225 228 1274 (UNIX is a registered trademark of UNIX Systems Laboratories.) 1274 SB + +1 #C + +statusdict begin /manualfeed false store end + +EJ RS + +%%PageTrailer + +%%PageResources: font Times-Roman + +%%Trailer + +SVDoc restore + +end + +%%Pages: 23 + +% TrueType font name key: + +% MSTT31c0e8 = 2b0fDTimes New RomanF0000002a000001900000 + +% MSTT31c0f9 = 089fDTimes New RomanF0000003a000002bc0000 + +% MSTT31c106 = 089fDTimes New RomanF0000003a000001900000 + +% MSTT31c113 = 089fDTimes New RomanF00000053000002bc0000 + +% MSTT31c120 = 089fDTimes New RomanF00000032000001900000 + +% MSTT31c132 = 089fDTimes New RomanF0000002a000001900000 + +% MSTT31c13f = 089fDTimes New RomanF0000004b000002bc0000 + +% MSTT31c14c = 089fDSymbolF00000032000001900000 + +% MSTT31c157 = 089fDTimes New RomanF00000021000001900000 + +% MSTT31c164 = 089fDTimes New RomanF00000026000001900000 + +% MSTT31c171 = 089fDSymbolF00000032000002bc0000 + +% MSTT31c17c = 089fDTimes New RomanF00000032000002bc0000 + +% MSTT31c189 = 089fDSymbolF0000004b000002bc0000 + +% MSTT31c194 = 089fDTimes New RomanF0000001f000001900000 + +% MSTT31c1aa = 089fDTimes New RomanF0000004b000001900000 + +% MSTT31c1b7 = 09dfDTimes New RomanF0000003a000002bc0000 + +% MSTT31c1c4 = 09dfDTimes New RomanF00000053000002bc0000 + +% MSTT31c1d1 = 09dfDTimes New RomanF00000032000001900000 + +% MSTT31c1de = 09dfDTimes New RomanF0000003a000001900000 + +% MSTT31c1eb = 09dfDTimes New RomanF0000002a000001900000 + +% MSTT31c1f8 = 09dfDTimes New RomanF0000004b000002bc0000 + +% MSTT31c205 = 09dfDSymbolF00000032000001900000 + +% MSTT31c210 = 09dfDTimes New RomanF00000021000001900000 + +% MSTT31c21d = 09dfDSymbolF00000032000002bc0000 + +% MSTT31c228 = 09dfDTimes New RomanF00000032000002bc0000 + +% MSTT31c235 = 09dfDTimes New RomanF00000026000001900000 + +% MSTT31c242 = 09dfDSymbolF0000004b000002bc0000 + +% MSTT31c24d = 09dfDTimes New RomanF0000001f000001900000 + +%%DocumentSuppliedResources: procset Win35Dict 3 1 + + + +%%DocumentNeededResources: font Symbol + +%%+ font Times-Bold + +%%+ font Times-Roman + + + +%%EOF + + diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/webstone.gif b/ACE/apps/JAWS/clients/WebSTONE/doc/webstone.gif Binary files differnew file mode 100644 index 00000000000..c7cd76d9a59 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/webstone.gif diff --git a/ACE/apps/JAWS/clients/WebSTONE/doc/webstone2.html b/ACE/apps/JAWS/clients/WebSTONE/doc/webstone2.html new file mode 100644 index 00000000000..5ea2650158d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/doc/webstone2.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<HTML VERSION="2.0"> +<HEAD> +<!-- $Id$ --> +<!-- WEBMAGIC VERSION NUMBER="2.0.1" --> +<!-- WEBMAGIC TRANSLATION NAME="ServerRoot" SRC="/var/www/htdocs/" DST="/" --> +<!-- WEBMAGIC TRANSLATION NAME="ProjectRoot" SRC="./" DST="" --> +<TITLE>What is Webstone 2.0</TITLE> +</HEAD> +<BODY> +<CENTER><H1 ALIGN="CENTER"><IMG SRC="webstone.gif" WIDTH="534" HEIGHT="174" SGI_FULLPATH="/disk6/WebStone-2.0/doc/webstone.gif"></H1> +</CENTER><H1>Introducing WebStone 2.0</H1> +<P>WebStone 2.0 is the second generation Webstone web server benchmark. It +incorporates numerous bug fixes, modifications for compatibility with other +platforms and adds the new functionality of benchmark proxy servers, cgi +and NSAPI programs as well as introducing run rules which should make Webstone +numbers significantly more meaningful for comparison.</P> +<H2>New Features</H2> +<P>Webstone 2.0 provides facilities for benchmarking proxy servers. This is +accomplished by putting in a value for the the PROXYSERVER entry in the +conf/testbed file, and changing the filelist to include URL's that have +the hostname for the actual web server.</P> +<P>Dynamic content benchmarking is now explicitly supported in Webstone 2.0. +The file README.DynamicWorkload has directions for testing of NSAPI. The +included filelist.dynamic-{light,medium,heavy} serve as sample loads, with +the filelist.dynamic-heavy being the load that should be reported for NSAPI +performance. The cgi-send numbers should be quored for the filelist.cgi-heavy +fileset.</P> +<P>A port of the WebStone 2.0 benchmark to Windows NT is also included in this +release. This port is still in progress, so full functionality is not assured. +Specifically only the benchmark code has been ported - the supporting scripts +have not.</P> +<H2>Run Rules</H2> +<P>As of Webstone 2.0, there are now run rules which must be adhered to for +published Webstone numbers. These are fairly basic, but they provide important +constraints on the benchmarking which make Webstone numbers more meaningful.</P> +<P><B>Fileset: </B>Included in the Webstone distribution is filelist.standard, which was previously +called filelist.sample. This filelist has a distribution of fileset sizes +that matches the kind of distributions seen in live web sites. The largest +file in the distribution is a 5 MB in length, which simulates the occasional +MPEG or other animation file which is downloaded. This filelist should be +used for all published Webstone numbers. Note that running WebStone 2.0 +with the sort of fileset given in WebStone 1.1 will not yield a comparable +benchmark. In general, the WebStone 2.0 filelist will yield lower rates +for connections/second, but higher rates for throughput - the two sets of +numbers cannot be compared.</P> +<P>When reporting NSAPI numbers, the filelist.dynamic-heavy filelist should +be used. For CGI numbers, the filelist.cgi-heavy filelist should be used.</P> +<P><B>Benchmark Run Configuration:</B> For a reported WebStone run, the runtime must be set at least 10 minutes. +This provides adequate time for the server and client configuration to reach +a steady state, and then provides a length of time long enough to cancel +out the high variations seen in the first few minutes of the run. The number +of clients should also vary from 20 to 100 in increments of 10 so that performance +of the server under a wide variety of loads can be observed.</P> +<P><B>Server Configuration:</B> The number of threads/processes is open to the discretion of the benchmarkers. +However, whether server side logging is on must be explicitly reported. +When logging is turned on, it must be in the common logfile format, and +only IP addresses should be logged. Parsed HTML is recommended to be turned +off.</P> +<P>Proxy Configuration: The configuration of how often the proxy server polls +the actual server for refreshes of it's cache should be described, as well +as any information</P> +<P><B>Server Machine Configuration:</B> When reporting runs, it is necessary that the operating system, memory +configuration and any special operating system modifications be reported, +especially changes to the TCP/IP stack.</P> +<P><B>Testbed configuration: </B>Reported runs must include information about the network topology being +used, as well as the number and type of machines generating load.</P> +<P>All reported runs must include the information summarized by webstone -results, +excluding the timestamp. This includes: number of clients, connections per +second, little's law number, latency, error level and throughput. Preferably +in a table format.</P> +</BODY> +</HTML> diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/README b/ACE/apps/JAWS/clients/WebSTONE/src/README new file mode 100644 index 00000000000..2061342b7ae --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/README @@ -0,0 +1,232 @@ +README WebStone 2.0 Release version + +WARNING: WebStone 2.0 results should not be compared with WebStone 1.1 + results. Even under the same fileset performance will not be + equivalent. + +Please see the notes for 2.0beta6 for quick and dirty install + This version includes a port of the webstone source code to Windows +NT. This port is still in progress, so it is not possible to guarantee +that everything is working correctly - however in our test configurations +it has performed correctly. Note that the supporting scripts and report +generating code has not been ported to NT yet. + + This version also institutes some basic run rules to eliminate the +lack of conformity in Webstone performance quotes. + To report Webstone numbers, some basic rules should be followed: + + 1) The fileset used for the test must be the fileset.standard fileset + included in the distribution. Tests of CGI performance must be + with the file filelist.cgi-heavy, and tests of NSAPI performance + must be carried out with filelist.dynamic-heavy + + 2) The run time should be set for 10 minutes, and the number of + clients should vary from 20 clients to 100 clients in increments + of 10. When a connections/second time is quoted, it must include + information about the number of clients involved. + + 3) Any special TCP/IP tuning which the server has recieved should + be documented, as well as HTTPD server version and configuration + information such as logging, DNS lookups and number of threads. + + +README - WebStone 2.0beta6 + +WARNING: Do not compare WebStone 2.0 results with WebStone 1.0 results. + WebStone 2.0 introduces significant changes in testing methodology + and reporting. + +This is the WebStone benchmark. Quick and dirty install: + - set up a Web server + - put this directory (WebStone) on a seperate machine (the "controller") + - "./webstone -setup", which does the following: + - gui-configure + This script may fail if you don't have a Web browser or + Perl5. Don't worry, unless you want to use the GUI. + - autoconf + If the GNU autoconf fails for your OS, please forward the + error messages, and any porting hints, to the author. + - make install + This may not be necessary, since IRIX binaries are included. + - edit conf/testbed to reflect your site + See the doc/FAQ-webstone.html for details. + - ./webstone -genfiles will put the files in conf/fileset + onto your Web server. + - ./webstone + - to display a table of results: ./webstone -results + +If you'd like to try out the GUI for WebStone: + - run "./webstone -setup", as above. + - make sure you have a Web browser installed + - ./configure + - ./webstone -gui + +Files of interest: + README: This document. + README.FIRST: Quick and dirty directions. + README.DynamicWorkload: Information on the CGI and NSAPI workloads. + webstone: wrapper shell script for everything. + Takes options: + -gui: start the GUI mode + -kill: kill stray WebStone processes + -genfiles: build files (from conf/fileset) + and rcp onto the server $SERVER + - results: print table of results + -setup: initial make and setup + -silent: runs in the background + -tail: tail -f of most recent run + +Files of interest (./src): + Makefile, *.c, *.h: The Webstone source code + +Files of interest (./bin): + checkfilelist: uses rsh to check web server for files in filelist. + genfiles, genrand: generates files of arbitrary length. + getstats: Collects network statistics from Web server, clients. + killbench: terminates stray WebStone processes. + rebootall: reboots all WebStone webclients. + runbench: wrapper script for WebStone. + webmaster: WebStone controller executable. + webstone: WebStone client executable. + wscollect: reports results in tabular format. + +Files of interest (./conf): + filelist: default list of files on the Web server, + with workload description. + filelist.photo: Model of a popular Web site + containing photographic images. + filelist.ss: Model of SGI's Silicon Surf WWW site. + fileset: list of files for genfiles to create. + testbed: config file describing Web server, client, and network setup. + +Documentation (./doc): + FAQ.html: The FAQ, current as of this distribution. + LICENSE: Legal status of WebStone. + testbed.help: Explains the parameters in conf/testbed. + webstone-white-paper.ps: The original WebStone white paper. + webstone.gif: The WebStone logo. + +Additional documentation: + FAQ.html: Frequently Asked Questions, with answers + webstone.ps: PostScript white paper on WebStone + +Problems, etc. may be addressed to the WebStone mailing list. +Read the FAQ for details. + +Release Notes (2.0 beta6): + * fixed a bug for Web servers not on port 80 + * further changes to bin/wscollect.pl + +Release Notes (2.0 beta5): + * numerous minor fixes suggested by gcc -Wall -pedantic + * updated FAQ + * changed bin/wscollect.pl to use Perl formats + +Release Notes (2.0 beta4): + * added #include <sys/time.h> to bench.h + * changed webclient located to $TMPDIR - this should help people + who don't want to run WebStone as root + * changed check for libm to floor() instead of sqrt(). Apparently + some systems implement sqrt() in libc - let's hope no one implement + floor() in libc and sqrt() in libm! + +Release Notes (2.0 beta3): + * more portability fixes + * successfully compiled on FreeBSD 2.2, IRIX without any source + changes + +Release Notes (2.0 beta2): + * additional timezone fixes for SunOS + +Release Notes (2.0 beta1): + * fixed a bug in the rexec portion of webmaster.c + * fixed a bug in the usage() routine of webmaster.c + * added bin/genfiles-from-filelist.sh + - bin/genfiles-from-filelist.sh <filename> + - generates appropriate-length files from <filename> + - <filename> must contain three fields: + <relative URL> <weight> #<size in bytes> + example: /file.html 1 #1024 + * added bin/mine-logs.pl + - usage: mine-logs.pl <filename> + where <filename> is an http server log file + - writes a WebStone workload to standard output + +Release Notes (2.0 alpha5): + * revised default testbed file + * changed wscollect to wscollect.pl for consistency + * changed webstone-gui to webstone-gui.pl for consistency + * added some NT porting hints + * added autoconf, which should help Linux and SunOS porting + +Release Notes (2.0 alpha4): + * added SunOS and Linux portability elements + * new scheme for random access to pages + * converted several static arrays to dynamic pointers + +Release Notes (2.0 alpha2): + * fixed per-page statistics + * new, client-independent data-passing scheme + * added support for proxy servers + +Release Notes (2.0 alpha1): + * new filelist scheme - however, this breaks per-page statistics + * minor fixes + +Release Notes (1.1): + * Improved webclient performance by combining GET and ACCEPT + HTTP headers in one write() call. + * Improved webclient performance on systems that always attempt + to map protocol names to numbers using YP. + * WARNING: since the old code introduced a significant latency + in some systems, DO NOT compare WebStone 1.1 results + with results generated by any previous versions. + +Release Notes (1.0.3): + * Netscape Server 1.1.2 exposed a couple bugs, which I've now fixed. + +Release Notes (1.0.2): + * Fixed runbench so that ITERATIONS, MINCLIENTS, and MAXCLIENTS don't + have to have a common denominator any more. + * Fixed a few cosmetic bugs. + +Release Notes (1.0.1): + * Fixed select() bug in webmaster + +Release Notes (1.0 final): + * Fixed the "Error reading 2nd timing info" bug + * Fixed numerous bugs in the GUI + * Froze feature set. Work can now begin on WebStone 1.1 + +Release Notes (1.0b3): + * New Web browser GUI + NOTE: most Web browsers take up substantial CPU time. + If you run the GUI, we recommend that you make the controller + a separate machine, and don't run any WebStone clients on it. + * Minor bug fixes + Squashed some dubious error messages, fixed some client- + controller communications problems. + * Reporting changes + Changes the units and order of the final summary statistics. + Basically, this is for my own convenience, so I don't have to + massage the data quite so much before using it. wscollect + now reports only the metrics I regard as important - but all + metrics are still reported in the runs/*/run files. + +LEGAL STUFF: + +This file and all files contained in this directory are +copyright 1995, Silicon Graphics, Inc. + +This software is provided without support and without any obligation on the +part of Silicon Graphics, Inc. to assist in its use, correction, modification +or enhancement. There is no guarantee that this software will be included in +future software releases, and it probably will not be included. + +THIS SOFTWARE IS PROVIDED "AS IS" WITH NO WARRANTIES OF ANY KIND INCLUDING THE +WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE, +OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + +In no event will Silicon Graphics, Inc. be liable for any lost revenue or +profits or other special, indirect and consequential damages, even if +Silicon Graphics, Inc. has been advised of the possibility of such damages. diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/acconfig.h b/ACE/apps/JAWS/clients/WebSTONE/src/acconfig.h new file mode 100644 index 00000000000..2183ecd4a7f --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/acconfig.h @@ -0,0 +1,15 @@ +/* $Id$ */ +/* Special definitions for autoheader + Copyright (C) 1995 Silicon Graphics, Inc. +*/ + +/* Define to the name of the distribution. */ +#undef PRODUCT + +/* Define to the version of the distribution. */ +#undef VERSION + +/* Should we use timezone in gettimeofday? */ +#undef USE_TIMEZONE + +/* end */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/bench.c b/ACE/apps/JAWS/clients/WebSTONE/src/bench.c new file mode 100644 index 00000000000..ace35460a1d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/bench.c @@ -0,0 +1,635 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <math.h> +#include <limits.h> +#include <float.h> +#ifndef WIN32 +#include <unistd.h> +#include <sys/time.h> +#include <sys/uio.h> +#include <sys/param.h> +#include <netdb.h> +#else +#include <windows.h> +#include <winsock.h> +#endif /* WIN32 */ +#include "sysdep.h" +#include "bench.h" + + +/* allocate memory and exit if out of memory */ +void *mymalloc(size_t size) { +void *ptr; + + ptr = malloc(size); + if (ptr == 0) + errexit("Call to malloc() failed\n"); + return ptr; +} + +/* + * Receive n bytes from a socket + */ +int +recvdata(SOCKET sock, char *ptr, int nbytes) { + + int nleft, nread; + + nleft = nbytes; + while (nleft > 0) + { + D_PRINTF( "In recvdata(%d, %d)\n", sock, nleft ); + nread = NETREAD(sock, ptr, nleft); + D_PRINTF( "NETREAD() returned %d\n", nread ); + if (BADSOCKET(nread) || nread == 0) + { + /* return error value NETWRITE */ + D_PRINTF( "Error in recvdata(): %s\n",neterrstr() ); + return(nread); + } + + D_PRINTF( "NETREAD() data: \"%.*s\"\n", nread, ptr); + nleft -= nread; + ptr += nread; + } /* end while */ + + /* return >= 0 */ + return(nbytes - nleft); + +} /* end recvdata */ + + +/* + * Send n bytes to a socket + */ +int +senddata(SOCKET sock, char *ptr, int nbytes) { + int nleft, nwritten; + + D_PRINTF( "In senddata(%d, \"%.*s\", %d)\n", sock, nbytes, ptr, nbytes ); + nleft = nbytes; + while (nleft > 0) + { + nwritten = NETWRITE(sock, ptr, nleft); + D_PRINTF( "senddata() returned %d\n", nwritten ); + if (BADSOCKET(nwritten)) + { + /* return error value from NETWRITE */ + D_PRINTF( "Error in senddata(): %s\n", neterrstr() ); + return(nwritten); + } + nleft -= nwritten; + ptr += nwritten; + } + return(nbytes - nleft); + +} /* end senddata */ + +/* GENERAL NOTE: the conversion routines that follow pass their results + * back in a static arrays. A second call to the same routine overwrites + * the previous buffer value for that routine. If you want to save the + * value in the buffer copy it to another variable. + */ + +char * +timeval_to_text(const struct timeval *the_timeval) { + /* + * given a timeval (seconds and microseconds), put the text + * "seconds.microseconds" into timeval_as_text + */ + THREAD static char timeval_as_text[SIZEOF_TIMEVALTEXT+1]; + int seconds, microseconds; + int returnval = 0; + + seconds = the_timeval->tv_sec; + microseconds = the_timeval->tv_usec; + returnval = sprintf(timeval_as_text, + "%10d.%6.6d\t", seconds, microseconds); + return timeval_as_text; +} + + +char * +double_to_text(const double the_double) { + /* + * given a double, return text + */ + THREAD static char double_as_text[SIZEOF_DOUBLETEXT + 1]; + int returnval = 0; + + returnval = sprintf(double_as_text, "%17.01f\t", the_double); + return(double_as_text); +} + +struct timeval +text_to_timeval(char *timeval_as_text) { + int returnval = 0; + long int seconds, microseconds; + struct timeval the_timeval; + + D_PRINTF("T/%d %s\n", (int)timeval_as_text, timeval_as_text); + returnval = sscanf(timeval_as_text, "%ld.%ld", + &seconds, µseconds); + the_timeval.tv_sec = seconds; + the_timeval.tv_usec = microseconds; + return the_timeval; +} + +double +text_to_double(char *double_as_text) { + double the_double = 0; + int returnval = 0; + + D_PRINTF("D/%d %s\n", (int)double_as_text, double_as_text); + returnval = sscanf(double_as_text, "%lf", &the_double); + return(the_double); +} + + +rqst_stats_t * +text_to_rqst_stats(char *rqst_stats_as_text) { + THREAD static rqst_stats_t rqst_stats; + rqst_stats_t *the_rqst_stats = &rqst_stats; + + the_rqst_stats->totalresponsetime = + text_to_timeval(strtok(rqst_stats_as_text, "\t")); + + the_rqst_stats->totalresponsetimesq = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->minresponsetime = + text_to_timeval(strtok((char *)0, "\t")); + + the_rqst_stats->maxresponsetime = + text_to_timeval(strtok((char *)0, "\t")); + + the_rqst_stats->totalconnecttime = + text_to_timeval(strtok((char *)0, "\t")); + + the_rqst_stats->totalconnecttimesq = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->minconnecttime = + text_to_timeval(strtok((char *)0, "\t")); + + the_rqst_stats->maxconnecttime = + text_to_timeval(strtok((char *)0, "\t")); + + the_rqst_stats->totalconnects = (unsigned long) + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->totalerrs = (unsigned long) + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->totalerrortime = + text_to_timeval(strtok((char *)0, "\t")); + + the_rqst_stats->totalbytes = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->totalbytessq = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->minbytes = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->maxbytes = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->totalbody = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->totalbodysq = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->minbody = + text_to_double(strtok((char *)0, "\t")); + + the_rqst_stats->maxbody = + text_to_double(strtok((char *)0, "\t")); + + return(the_rqst_stats); +} /* end text_to_rqst_stats */ + + +char * +rqst_stats_to_text(rqst_stats_t *the_rqst_stats) { + THREAD static char rqst_stats_as_text[SIZEOF_RQSTSTATSTEXT]; + char *tmpbuf; + + *rqst_stats_as_text = 0; + + tmpbuf = timeval_to_text(&(the_rqst_stats->totalresponsetime)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalresponsetimesq)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_rqst_stats->minresponsetime)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_rqst_stats->maxresponsetime)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_rqst_stats->totalconnecttime)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalconnecttimesq)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_rqst_stats->minconnecttime)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_rqst_stats->maxconnecttime)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalconnects)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalerrs)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_rqst_stats->totalerrortime)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalbytes)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalbytessq)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->minbytes)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->maxbytes)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalbody)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->totalbodysq)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->minbody)); + strcat(rqst_stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_rqst_stats->maxbody)); + strcat(rqst_stats_as_text, tmpbuf); + + D_PRINTF( "rqst_stats_to_text returning %d: %s\n", + strlen(rqst_stats_as_text), + rqst_stats_as_text ); + + return(rqst_stats_as_text); +} + + +stats_t * +text_to_stats(char *stats_as_text) { + int i; + rqst_stats_t *the_rqst_stats; + THREAD static stats_t stats; + stats_t *the_stats = &stats; + + D_PRINTF( "Parsing stats: %s\n", stats_as_text ); + /* grab stats.rs */ + the_rqst_stats = text_to_rqst_stats(stats_as_text); + the_stats->rs = *the_rqst_stats; + + /* grab main structure */ + the_stats->starttime = text_to_timeval(strtok((char *)0, "\t")); + the_stats->endtime = text_to_timeval(strtok((char *)0, "\t")); + the_stats->datatime = text_to_timeval(strtok((char *)0, "\t")); + the_stats->totalpages = (unsigned long) text_to_double(strtok((char *)0, "\t")); + the_stats->total_num_of_files = (unsigned int) text_to_double(strtok((char *)0, "\t")); + for (i = 0; i < number_of_pages; i++) + { + the_stats->page_numbers[i] = (unsigned int) text_to_double(strtok((char *)0, "\t")); + } + /* return bytes read */ + D_PRINTF( "Returning stats\n"); + return(the_stats); +} /* end text_to_stats */ + + + +char * +stats_to_text(const stats_t *the_stats) { + int i; + THREAD static char stats_as_text[SIZEOF_STATSTEXT]; + char *tmpbuf; + rqst_stats_t the_rqst_stats; + + *stats_as_text = 0; + + /* stats.rs */ + the_rqst_stats = the_stats->rs; + tmpbuf = rqst_stats_to_text(&the_rqst_stats); + strcat(stats_as_text, tmpbuf); + + /* main structure */ + + tmpbuf = timeval_to_text(&(the_stats->starttime)); + strcat(stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_stats->endtime)); + strcat(stats_as_text, tmpbuf); + + tmpbuf = timeval_to_text(&(the_stats->datatime)); + strcat(stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_stats->totalpages)); + strcat(stats_as_text, tmpbuf); + + tmpbuf = double_to_text((the_stats->total_num_of_files)); + strcat(stats_as_text, tmpbuf); + + for (i = 0; i < number_of_pages; i++) + { + tmpbuf = double_to_text((the_stats->page_numbers[i])); + strcat(stats_as_text, tmpbuf); + } + + strcat(stats_as_text, "\n"); + + return(stats_as_text); +} /* end stats_to_text */ + + + +page_stats_t * +text_to_page_stats(char *page_stats_as_text) { + rqst_stats_t *the_rqst_stats; + THREAD static page_stats_t pagestat; + page_stats_t *pagestats = &pagestat; + + /* grab stats.rs */ + the_rqst_stats = text_to_rqst_stats(page_stats_as_text); + + /* grab main structure */ + pagestats->totalpages = (unsigned long) text_to_double(strtok((char *)0, "\t")); + + pagestats->page_size = (unsigned int) text_to_double(strtok((char *)0, "\t")); + + pagestats->page_valid = (int) text_to_double(strtok((char *)0, "\t")); + + pagestats->rs = *the_rqst_stats; + /* return bytes read */ + + return(pagestats); +} /* end text_to_page_stats */ + + + +char * +page_stats_to_text(const page_stats_t *pagestats) { + THREAD static char page_stats_as_text[SIZEOF_PAGESTATSTEXT]; + char *tmpbuf; + rqst_stats_t the_rqst_stats; + + *page_stats_as_text = 0; + + /* stats.rs */ + the_rqst_stats = pagestats->rs; + tmpbuf = rqst_stats_to_text(&the_rqst_stats); + strcat(page_stats_as_text, tmpbuf); + + /* main structure */ + tmpbuf = double_to_text(pagestats->totalpages); + strcat(page_stats_as_text, tmpbuf); + + tmpbuf = double_to_text(pagestats->page_size); + strcat(page_stats_as_text, tmpbuf); + + tmpbuf = double_to_text(pagestats->page_valid); + strcat(page_stats_as_text, tmpbuf); + + strcat(page_stats_as_text, "\n"); + + return(page_stats_as_text); +} /* end page_stats_to_text */ + +void +rqtimer_init(rqst_timer_t *p) { + memset(p, 0, sizeof(*p)); +} + +void +rqstat_init(rqst_stats_t *p) { + memset(p, 0, sizeof(*p)); + + p->minbytes = DBL_MAX; + p->minbody = DBL_MAX; + p->minconnecttime.tv_sec = LONG_MAX; + p->minconnecttime.tv_usec = LONG_MAX; + p->minresponsetime.tv_sec = LONG_MAX; + p->minresponsetime.tv_usec = LONG_MAX; +} + +void +stats_init(stats_t *p) { + + memset(p, 0, sizeof(*p)); + + p->rs.minbytes = DBL_MAX; + p->rs.minbody = DBL_MAX; + p->rs.minconnecttime.tv_sec = LONG_MAX; + p->rs.minconnecttime.tv_usec = LONG_MAX; + p->rs.minresponsetime.tv_sec = LONG_MAX; + p->rs.minresponsetime.tv_usec = LONG_MAX; +} + +void +page_stats_init(page_stats_t *p) { + + memset(p, 0, sizeof(*p)); + + /* commented out so that unread pages result in + page_stats_as_text buffer overflow + p->rs.minbytes = DBL_MAX; + p->rs.minbody = DBL_MAX; + p->rs.minconnecttime.tv_sec = LONG_MAX; + p->rs.minconnecttime.tv_usec = LONG_MAX; + p->rs.minresponsetime.tv_sec = LONG_MAX; + p->rs.minresponsetime.tv_usec = LONG_MAX; + + */ +} + +void +rqstat_times(rqst_stats_t *rs, rqst_timer_t *rt) +{ + double t; + + compdifftime(&(rt->exittime), &(rt->entertime), + &(rs->totalresponsetime)); + t = timevaldouble(&(rs->totalresponsetime)); + rs->totalresponsetimesq = t * t; + + rs->minresponsetime = rs->totalresponsetime; + rs->maxresponsetime = rs->totalresponsetime; + + compdifftime(&(rt->afterconnect), &(rt->beforeconnect), + &(rs->totalconnecttime)); + + t = timevaldouble(&(rs->totalconnecttime)); + rs->totalconnecttimesq = t * t; + + rs->minconnecttime = rs->totalconnecttime; + rs->maxconnecttime = rs->totalconnecttime; + + rs->totalbody = rt->bodybytes; + rs->totalbodysq = ((double)(rt->bodybytes)) * ((double)(rt->bodybytes)); + rs->minbody = rt->bodybytes; + rs->maxbody = rt->bodybytes; + + rs->totalbytes = rt->totalbytes; + rs->totalbytessq = ((double)(rt->totalbytes)) * ((double)(rt->totalbytes)); + rs->minbytes = rt->totalbytes; + rs->maxbytes = rt->totalbytes; + + rs->totalconnects = 1; + rs->totalerrs = 0; + rs->totalerrortime.tv_sec = 0; + rs->totalerrortime.tv_usec = 0; +} + +void +rqstat_sum(rqst_stats_t *sum, rqst_stats_t *incr) +{ + addtime( &(sum->totalresponsetime), &(incr->totalresponsetime)); + mintime( &(sum->minresponsetime), &(incr->minresponsetime)); + maxtime( &(sum->maxresponsetime), &(incr->maxresponsetime)); + sum->totalresponsetimesq += incr->totalresponsetimesq; + + addtime( &(sum->totalconnecttime), &(incr->totalconnecttime)); + mintime( &(sum->minconnecttime), &(incr->minconnecttime)); + maxtime( &(sum->maxconnecttime), &(incr->maxconnecttime)); + sum->totalconnecttimesq += incr->totalconnecttimesq; + + sum->totalconnects += incr->totalconnects; + sum->totalerrs += incr->totalerrs; + addtime( &(sum->totalerrortime), &(incr->totalerrortime)); + + sum->totalbytes += incr->totalbytes; + + sum->totalbytessq += incr->totalbytessq; + sum->minbytes = min(sum->minbytes, incr->minbytes); + sum->maxbytes = max(sum->maxbytes, incr->maxbytes); + + sum->totalbody += incr->totalbody; + + sum->totalbodysq += incr->totalbodysq; + sum->minbody = min(sum->minbody, incr->minbody); + sum->maxbody = max(sum->maxbody, incr->maxbody); + +} + + +void +rqstat_print(rqst_stats_t *stats) +{ + rqstat_fprint(stdout, stats); +} + + +void +rqstat_fprint(FILE *f, rqst_stats_t *stats) +{ + struct timeval meantime, /*vartime,*/ stdtime; + + fprintf(f, "%d connection(s) to server, %d errors\n", + stats->totalconnects, stats->totalerrs); + + if (stats->totalconnects == 0) { + fprintf(f,"NO CONNECTIONS, THEREFORE NO STATISTICS\n" + "IS YOUR WEBSERVER RUNNING?\n" + "DO THE PAGES EXIST ON THE SERVER?\n"); + return; + } + + /* title */ + fprintf(f, "\n\t\t\t Average Std Dev Minimum Maximum\n\n"); + + /* first line (connect time) */ + avgtime(&(stats->totalconnecttime), + stats->totalconnects, &meantime); + + /* variancetime(&(stats->totalconnecttime), + stats->totalconnecttimesq, + stats->totalconnects, &vartime); */ + + stddevtime(&(stats->totalconnecttime), + stats->totalconnecttimesq, + stats->totalconnects, &stdtime); + + fprintf(f, "Connect time (sec) \t%3d.%6.6d %3d.%6.6d %3d.%6.6d %3d.%6.6d\n", + meantime.tv_sec, + meantime.tv_usec, + stdtime.tv_sec, + stdtime.tv_usec, + stats->minconnecttime.tv_sec, + stats->minconnecttime.tv_usec, + stats->maxconnecttime.tv_sec, + stats->maxconnecttime.tv_usec); + + /* second line (response time) */ + avgtime(&(stats->totalresponsetime), + stats->totalconnects, &meantime); + + /* variancetime(&(stats->totalresponsetime), + stats->totalresponsetimesq, + stats->totalconnects, &vartime); */ + + stddevtime(&(stats->totalresponsetime), + stats->totalresponsetimesq, + stats->totalconnects, &stdtime); + + fprintf(f, "Response time (sec) \t%3d.%6.6d %3d.%6.6d %3d.%6.6d %3d.%6.6d\n", + meantime.tv_sec, + meantime.tv_usec, + stdtime.tv_sec, + stdtime.tv_usec, + stats->minresponsetime.tv_sec, + stats->minresponsetime.tv_usec, + stats->maxresponsetime.tv_sec, + stats->maxresponsetime.tv_usec); + + /* 3rd-5th lines (response size, body size, # bytes moved */ + fprintf(f, "Response size (bytes) \t%10.0lf %10.0lf %10.0lf %10.0lf\n", + mean(stats->totalbytes, stats->totalconnects), + stddev(stats->totalbytes, stats->totalbytessq, + stats->totalconnects), + stats->minbytes, + stats->maxbytes); + + fprintf(f, "Body size (bytes) \t%10.0lf %10.0lf %10.0lf %10.0lf\n\n", + mean(stats->totalbody, stats->totalconnects), + stddev(stats->totalbody, stats->totalbodysq, + stats->totalconnects), + stats->minbody, + stats->maxbody); + + fprintf(f, "%.0lf body bytes moved + %.0lf header bytes moved = %.0lf total\n", + stats->totalbody, + stats->totalbytes - stats->totalbody, + stats->totalbytes); + +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/bench.h b/ACE/apps/JAWS/clients/WebSTONE/src/bench.h new file mode 100644 index 00000000000..489b6596efc --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/bench.h @@ -0,0 +1,274 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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. * + * * + **************************************************************************/ +#ifndef __BENCH_H__ +#define __BENCH_H__ +#include <stdio.h> +#include <stdarg.h> +#ifndef WIN32 +#include <sys/time.h> +#endif /* WIN32 */ + +#define USECINSEC 1000000 +#define MSECINSEC 1000 +#define MAX_ACCEPT_SECS 180 /* maximum time master will wait for listen() */ + +#define NCCARGS 4096 +#define MAXCLIENTS 1024 +#define MAXUSERNAME 25 +#define MAXPASSWD 20 +#define BUFSIZE 4096 + +#define MAXTOTALPROCS MAXCLIENTS /* overall max # of procs */ +#define MAXPROCSPERNODE MAXCLIENTS /* max # of procs/node */ + + +#define CONTENT_LENGTH_STRING "CONTENT-LENGTH:" +#define OKSTR "OK" +#define OKSTRLEN ((int)strlen(OKSTR)) +#define GOSTR "GO" +#define GOSTRLEN ((int)strlen(GOSTR)) +#define READYSTR "READY" +#define READYSTRLEN ((int)strlen(READYSTR)) +#define ABORTSTR "ABORT" +#define ABORTSTRLEN ((int)strlen(ABORTSTR)) + + +#define MAXNUMOFFILES 1 /* max # of files per page */ +#define URL_SIZE 1024 +#define MAXNUMOFPAGES 100 +#define SIZEOF_TIMEVALTEXT 18 +#define SIZEOF_DOUBLETEXT 18 +#define SIZEOF_RQSTSTATSTEXT ((7 * SIZEOF_TIMEVALTEXT) + \ + (12 * SIZEOF_DOUBLETEXT) + 1) +#define SIZEOF_STATSTEXTBASE (SIZEOF_RQSTSTATSTEXT + \ + (3 * SIZEOF_TIMEVALTEXT) + \ + (2 * SIZEOF_DOUBLETEXT) + 1) +#define SIZEOF_STATSTEXT (SIZEOF_STATSTEXTBASE + MAXNUMOFPAGES * SIZEOF_DOUBLETEXT) +#define SIZEOF_PAGESTATSTEXT (SIZEOF_RQSTSTATSTEXT + \ + (0 * SIZEOF_TIMEVALTEXT) + \ + (3 * SIZEOF_DOUBLETEXT) + 1) + +#define D_PRINTF debug && d_printf + +#ifdef USE_TIMEZONE +typedef struct rqst_timer { + struct timeval entertime; + struct timezone entertimezone; + struct timeval beforeconnect; + struct timezone beforeconnectzone; + struct timeval afterconnect; + struct timezone afterconnectzone; + struct timeval beforeheader; + struct timezone beforeheaderzone; + struct timeval afterheader; + struct timezone afterheaderzone; + struct timeval afterbody; + struct timezone afterbodyzone; + struct timeval exittime; + struct timezone exittimezone; + long unsigned int totalbytes; + long unsigned int bodybytes; + int valid; + long unsigned int page_number; +} rqst_timer_t; +#else +typedef struct rqst_timer { + struct timeval entertime; + struct timeval beforeconnect; + struct timeval afterconnect; + struct timeval beforeheader; + struct timeval afterheader; + struct timeval afterbody; + struct timeval exittime; + long unsigned int totalbytes; + long unsigned int bodybytes; + int valid; + long unsigned int page_number; +} rqst_timer_t; +#endif /* USE_TIMEZONE */ + +extern void rqtimer_init(rqst_timer_t *); + +#ifdef USE_TIMEZONE +typedef struct rqst_stats { + struct timeval totalresponsetime; + struct timezone totalresponsetimezone; + double totalresponsetimesq; + struct timeval minresponsetime; + struct timezone minresponsetimezone; + struct timeval maxresponsetime; + struct timezone maxresponsetimezone; + struct timeval totalconnecttime; + struct timezone totalconnecttimezone; + double totalconnecttimesq; + struct timeval minconnecttime; + struct timezone minconnecttimezone; + struct timeval maxconnecttime; + struct timezone maxconnecttimezone; + long unsigned int totalconnects; + long unsigned int totalerrs; + struct timeval totalerrortime; + struct timezone totalerrortimezone; + double totalbytes; + double totalbytessq; + double minbytes; + double maxbytes; + double totalbody; + double totalbodysq; + double minbody; + double maxbody; +} rqst_stats_t; +#else +typedef struct rqst_stats { + struct timeval totalresponsetime; + double totalresponsetimesq; + struct timeval minresponsetime; + struct timeval maxresponsetime; + struct timeval totalconnecttime; + double totalconnecttimesq; + struct timeval minconnecttime; + struct timeval maxconnecttime; + long unsigned int totalconnects; + long unsigned int totalerrs; + struct timeval totalerrortime; + double totalbytes; + double totalbytessq; + double minbytes; + double maxbytes; + double totalbody; + double totalbodysq; + double minbody; + double maxbody; +} rqst_stats_t; +#endif /* USE_TIMEZONE */ + +extern void rqstat_init(rqst_stats_t *); +extern void rqstat_sum(rqst_stats_t *, rqst_stats_t *); +extern void rqstat_print(rqst_stats_t *); +extern void rqstat_fprint(FILE *, rqst_stats_t *); +extern void rqstat_times(rqst_stats_t *, rqst_timer_t *); + +#ifdef USE_TIMEZONE +typedef struct stats { + /* char hostname[MAXHOSTNAMELEN]; */ + rqst_stats_t rs; + struct timeval starttime; + struct timezone starttimezone; + struct timeval endtime; + struct timezone endtimezone; + struct timeval datatime; + struct timezone datatimezone; + long unsigned int totalpages; + unsigned int total_num_of_files; + unsigned int page_numbers[MAXNUMOFPAGES]; +} stats_t; +#else +typedef struct stats { + /* char hostname[MAXHOSTNAMELEN]; */ + rqst_stats_t rs; + struct timeval starttime; + struct timeval endtime; + struct timeval datatime; + long unsigned int totalpages; + unsigned int total_num_of_files; + unsigned int page_numbers[MAXNUMOFPAGES]; +} stats_t; +#endif /* USE_TIMEZONE */ + +extern void stats_init(stats_t *); +extern stats_t * text_to_stats(char *); +extern char * stats_to_text(const stats_t *); + +typedef struct page_stats { + rqst_stats_t rs; + long unsigned int totalpages; + unsigned int page_size; + int page_valid; +} page_stats_t; + +extern void page_stats_init(page_stats_t *); +extern page_stats_t * text_to_page_stats(char *); +extern char * page_stats_to_text(const page_stats_t *); + +/* THIS STRUCTURE DEFINES A PAGE. */ +typedef struct page_list { + int load_num; + int num_of_files; + char *(filename[MAXNUMOFFILES]); + char *(servername[MAXNUMOFFILES]); + int port_number[MAXNUMOFFILES]; +}page_list_t; + + + +/* shared variables */ +extern THREAD FILE *debugfile; +extern int debug; + +extern int savefile; +extern int timeexpired; +extern long int number_of_pages; + +/* routines in bench.c */ + +extern void *mymalloc(size_t size); +extern int recvdata(SOCKET sock, char *ptr, int nbytes); +extern int senddata(SOCKET sock, char *ptr, int nbytes); +extern void rqstat_times(rqst_stats_t *rs, rqst_timer_t *rt); +/* note several others listed above */ + +/* routines in errexit.c */ + +void errexit(const char *, ...); +extern int returnerr(const char *, ...); +extern int d_printf(const char *, ...); +extern char *neterrstr(void); + +/* routines in get.c */ + +extern int get(char *loc, NETPORT port, char *url, rqst_timer_t *timer); + +/* routines in parse_file_list.c */ + +extern int count_file_list(const char *url_list_file); +extern void parse_file_list (const char *url_list_file, page_list_t *page_list, + long int *num_of_pages, long int *num_of_files); +extern long int load_percent(page_list_t *page_list, long int number_of_pages); + +/* routines in statistics.c (formerly statistics.h) */ + +extern double mean(const double, const int); +extern double variance(const double, const double, const int); +extern double stddev(const double, const double, const int); + +/* routines in timefunc.c (formerly timefunc.h) */ + +extern double timevaldouble(struct timeval *); +extern void doubletimeval(const double, struct timeval *); + +extern void addtime(struct timeval *, struct timeval *); +extern void compdifftime(struct timeval *, struct timeval *, struct timeval *); +extern void mintime(struct timeval *, struct timeval *); +extern void maxtime(struct timeval *, struct timeval *); +extern void avgtime(struct timeval *, int, struct timeval *); +extern void variancetime(struct timeval *, double, int, struct timeval *); +extern void stddevtime(struct timeval *, double, int, struct timeval *); + +extern void sqtime(struct timeval *, struct timeval *); + +extern double thruputpersec(const double, struct timeval *); + +/* routines in webclient.c */ + +extern SOCKET connectsock(char *host, NETPORT portnum, char *protocol); + +#endif /* !__BENCH_H__ */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/cgi-send.c b/ACE/apps/JAWS/clients/WebSTONE/src/cgi-send.c new file mode 100644 index 00000000000..f1474d34c28 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/cgi-send.c @@ -0,0 +1,48 @@ +/* $Id$ */ +/* + * Send 10K file; send random bits. + * + */ + +//FUZZ: disable check_for_improper_main_declaration + +#include <stdio.h> +#include <stdlib.h> + +#define FILE_SIZE 10240 +#define MALLOC_FAILURE "Out of memory" + +int +main() +{ + int filesize; + char *str_filesize; + char *buffer; + int index; + + printf("Content-type: text/plain\r\n\r\n"); + + if ( !(str_filesize = getenv("QUERY_STRING")) ) + filesize = FILE_SIZE; + else { + if ( !strncmp(str_filesize, "size=", 5) ) + filesize = atoi(&(str_filesize[5])); + else + filesize = FILE_SIZE; + } + + if ( !(buffer = (char *)malloc(filesize)) ) { + fwrite(MALLOC_FAILURE, strlen(MALLOC_FAILURE), 1, stdout); + return -1; + } + + for (index=0; index< filesize; index++) + /* generate random characters from A-Z */ + buffer[index] = rand() %26 + 63; + + fwrite(buffer, filesize, 1, stdout); + + free(buffer); + + return 0; +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/config.cache b/ACE/apps/JAWS/clients/WebSTONE/src/config.cache new file mode 100644 index 00000000000..c8705dca2f4 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/config.cache @@ -0,0 +1,47 @@ +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +ac_cv_c_const=${ac_cv_c_const='yes'} +ac_cv_c_cross=${ac_cv_c_cross='no'} +ac_cv_func_gethostname=${ac_cv_func_gethostname='yes'} +ac_cv_func_gettimeofday=${ac_cv_func_gettimeofday='yes'} +ac_cv_func_memcmp=${ac_cv_func_memcmp='yes'} +ac_cv_func_select=${ac_cv_func_select='yes'} +ac_cv_func_socket=${ac_cv_func_socket='yes'} +ac_cv_func_strerror=${ac_cv_func_strerror='yes'} +ac_cv_func_vprintf=${ac_cv_func_vprintf='yes'} +ac_cv_func_wait3=${ac_cv_func_wait3='yes'} +ac_cv_header_fcntl_h=${ac_cv_header_fcntl_h='yes'} +ac_cv_header_limits_h=${ac_cv_header_limits_h='yes'} +ac_cv_header_sgtty_h=${ac_cv_header_sgtty_h='yes'} +ac_cv_header_stdc=${ac_cv_header_stdc='yes'} +ac_cv_header_sys_time_h=${ac_cv_header_sys_time_h='yes'} +ac_cv_header_sys_wait_h=${ac_cv_header_sys_wait_h='yes'} +ac_cv_header_time=${ac_cv_header_time='yes'} +ac_cv_header_unistd_h=${ac_cv_header_unistd_h='yes'} +ac_cv_lib_compat=${ac_cv_lib_compat='no'} +ac_cv_lib_m=${ac_cv_lib_m='yes'} +ac_cv_lib_socket=${ac_cv_lib_socket='yes'} +ac_cv_lib_ucb=${ac_cv_lib_ucb='no'} +ac_cv_path_PERL=${ac_cv_path_PERL='/usr/sbin/perl'} +ac_cv_prog_AWK=${ac_cv_prog_AWK='nawk'} +ac_cv_prog_CC=${ac_cv_prog_CC='cc'} +ac_cv_prog_CPP=${ac_cv_prog_CPP='cc -E'} +ac_cv_prog_gcc=${ac_cv_prog_gcc='no'} +ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set='yes'} +ac_cv_struct_tm=${ac_cv_struct_tm='time.h'} +ac_cv_struct_tm_zone=${ac_cv_struct_tm_zone='no'} +ac_cv_type_signal=${ac_cv_type_signal='void'} +ac_cv_type_size_t=${ac_cv_type_size_t='yes'} +ac_cv_var_tzname=${ac_cv_var_tzname='yes'} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/config.guess b/ACE/apps/JAWS/clients/WebSTONE/src/config.guess new file mode 100755 index 00000000000..2ff0eba28ac --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/config.guess @@ -0,0 +1,565 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner <bothner@cygnus.com>. +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:V*:*) + # After 1.2, OSF1 uses "V1.3" for uname -r. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'` + exit 0 ;; + alpha:OSF1:*:*) + # 1.2 uses "1.2" for uname -r. + echo alpha-dec-osf${UNAME_RELEASE} + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + Pyramid*:OSx*:*:*) + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + sun4*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + mips:*:4*:UMIPS) + echo mips-mips-riscos4sysv + exit 0 ;; + mips:*:5*:RISCos) + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i[34]86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?[79] ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*C90:*:*:*) + echo c90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + i[34]86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + if echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then + echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 + elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then + echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0 + elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then + echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0 + elif test "${UNAME_MACHINE}" = "alpha" ; then + echo alpha-unknown-linux ; exit 0 + else + # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us + # useful --help. Gcc wants to distinguish between linuxoldld and linuxaout. + test ! -d /usr/lib/ldscripts/. \ + && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0 + # Determine whether the default compiler is a.out or elf + cat >dummy.c <<EOF +main(argc, argv) +int argc; +char *argv[]; +{ +#ifdef __ELF__ + printf ("%s-unknown-linux\n", argv[1]); +#else + printf ("%s-unknown-linuxaout\n", argv[1]); +#endif + return 0; +} +EOF + ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i[34]86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i[34]86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-unknown-sysv32 + fi + exit 0 ;; + Intel:Mach:3*:*) + echo i386-unknown-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M680[234]0:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3 && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m680[234]0:LynxOS:2.[23]*:*) + echo m68k-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i[34]86:LynxOS:2.[23]*:*) + echo i386-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.[23]*:*) + echo sparc-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.[23]*:*) + echo rs6000-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3"); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-unknown-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/config.h b/ACE/apps/JAWS/clients/WebSTONE/src/config.h new file mode 100644 index 00000000000..782ba57a71b --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/config.h @@ -0,0 +1,91 @@ +/* $Id$ */ +/* config.h. Generated automatically by configure. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#define HAVE_TZNAME 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the wait3 system call. */ +#define HAVE_WAIT3 1 + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if your <sys/time.h> declares struct tm. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define to the name of the distribution. */ +#define PRODUCT "webstone" + +/* Define to the version of the distribution. */ +#define VERSION "2.0b4" + +/* Should we use timezone in gettimeofday? */ +#define USE_TIMEZONE 1 + +/* Define if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the <sgtty.h> header file. */ +#define HAVE_SGTTY_H 1 + +/* Define if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the compat library (-lcompat). */ +/* #undef HAVE_LIBCOMPAT */ + +/* Define if you have the m library (-lm). */ +#define HAVE_LIBM 1 + +/* Define if you have the socket library (-lsocket). */ +#define HAVE_LIBSOCKET 1 + +/* Define if you have the ucb library (-lucb). */ +/* #undef HAVE_LIBUCB */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/config.h.in b/ACE/apps/JAWS/clients/WebSTONE/src/config.h.in new file mode 100644 index 00000000000..91299ae624b --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/config.h.in @@ -0,0 +1,89 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you don't have vprintf but do have _doprnt. */ +#undef HAVE_DOPRNT + +/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define if your struct tm has tm_zone. */ +#undef HAVE_TM_ZONE + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#undef HAVE_TZNAME + +/* Define if you have the vprintf function. */ +#undef HAVE_VPRINTF + +/* Define if you have the wait3 system call. */ +#undef HAVE_WAIT3 + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME + +/* Define if your <sys/time.h> declares struct tm. */ +#undef TM_IN_SYS_TIME + +/* Define to the name of the distribution. */ +#undef PRODUCT + +/* Define to the version of the distribution. */ +#undef VERSION + +/* Should we use timezone in gettimeofday? */ +#undef USE_TIMEZONE + +/* Define if you have the gethostname function. */ +#undef HAVE_GETHOSTNAME + +/* Define if you have the gettimeofday function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the select function. */ +#undef HAVE_SELECT + +/* Define if you have the socket function. */ +#undef HAVE_SOCKET + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR + +/* Define if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the <sgtty.h> header file. */ +#undef HAVE_SGTTY_H + +/* Define if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the compat library (-lcompat). */ +#undef HAVE_LIBCOMPAT + +/* Define if you have the m library (-lm). */ +#undef HAVE_LIBM + +/* Define if you have the socket library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define if you have the ucb library (-lucb). */ +#undef HAVE_LIBUCB diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/config.log b/ACE/apps/JAWS/clients/WebSTONE/src/config.log new file mode 100644 index 00000000000..1b2fa65abd8 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/config.log @@ -0,0 +1,4 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +cc -c -g conftest.c diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/config.status b/ACE/apps/JAWS/clients/WebSTONE/src/config.status new file mode 100755 index 00000000000..2f00f63aba7 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/config.status @@ -0,0 +1,288 @@ +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host tango: +# +# configure +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]" +for ac_option +do + case "$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running ${CONFIG_SHELL-/bin/sh} configure --no-create --no-recursion" + exec ${CONFIG_SHELL-/bin/sh} configure --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "./config.status generated by autoconf version 2.7" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "$ac_cs_usage"; exit 0 ;; + *) echo "$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=. + +trap 'rm -fr Makefile config.h conftest*; exit 1' 1 2 15 + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g; + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF +/^[ ]*VPATH[ ]*=[^:]*$/d + +s%@CFLAGS@%-g%g +s%@CPPFLAGS@%%g +s%@CXXFLAGS@%%g +s%@DEFS@%-DHAVE_CONFIG_H%g +s%@LDFLAGS@%%g +s%@LIBS@%-lsocket -lm %g +s%@exec_prefix@%${prefix}%g +s%@prefix@%bin%g +s%@program_transform_name@%s,x,x,%g +s%@bindir@%${exec_prefix}/bin%g +s%@sbindir@%${exec_prefix}/sbin%g +s%@libexecdir@%${exec_prefix}/libexec%g +s%@datadir@%${prefix}/share%g +s%@sysconfdir@%${prefix}/etc%g +s%@sharedstatedir@%${prefix}/com%g +s%@localstatedir@%${prefix}/var%g +s%@libdir@%${exec_prefix}/lib%g +s%@includedir@%${prefix}/include%g +s%@oldincludedir@%/usr/include%g +s%@infodir@%${prefix}/info%g +s%@mandir@%${prefix}/man%g +s%@PRODUCT@%webstone%g +s%@VERSION@%2.0b4%g +s%@host@%sparc-sun-solaris2.5.1%g +s%@host_alias@%sparc-sun-solaris2.5.1%g +s%@host_cpu@%sparc%g +s%@host_vendor@%sun%g +s%@host_os@%solaris2.5.1%g +s%@target@%sparc-sun-solaris2.5.1%g +s%@target_alias@%sparc-sun-solaris2.5.1%g +s%@target_cpu@%sparc%g +s%@target_vendor@%sun%g +s%@target_os@%solaris2.5.1%g +s%@build@%sparc-sun-solaris2.5.1%g +s%@build_alias@%sparc-sun-solaris2.5.1%g +s%@build_cpu@%sparc%g +s%@build_vendor@%sun%g +s%@build_os@%solaris2.5.1%g +s%@CC@%cc%g +s%@SET_MAKE@%%g +s%@AWK@%nawk%g +s%@PERL@%/usr/sbin/perl%g +s%@PERL_SCRIPTS@%bin/wscollect.pl%g +s%@CPP@%cc -E%g +s%@LIBOBJS@%%g + +CEOF + +CONFIG_FILES=${CONFIG_FILES-"Makefile"} +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust relative srcdir, etc. for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file +fi; done +rm -f conftest.subs + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"} +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + cp $ac_given_srcdir/$ac_file_in conftest.in + + cat > conftest.frag <<CEOF +${ac_dA}PRODUCT${ac_dB}PRODUCT${ac_dC}"webstone"${ac_dD} +${ac_uA}PRODUCT${ac_uB}PRODUCT${ac_uC}"webstone"${ac_uD} +${ac_eA}PRODUCT${ac_eB}PRODUCT${ac_eC}"webstone"${ac_eD} +${ac_dA}VERSION${ac_dB}VERSION${ac_dC}"2.0b4"${ac_dD} +${ac_uA}VERSION${ac_uB}VERSION${ac_uC}"2.0b4"${ac_uD} +${ac_eA}VERSION${ac_eB}VERSION${ac_eC}"2.0b4"${ac_eD} +${ac_dA}HAVE_LIBM${ac_dB}HAVE_LIBM${ac_dC}1${ac_dD} +${ac_uA}HAVE_LIBM${ac_uB}HAVE_LIBM${ac_uC}1${ac_uD} +${ac_eA}HAVE_LIBM${ac_eB}HAVE_LIBM${ac_eC}1${ac_eD} +${ac_dA}HAVE_LIBSOCKET${ac_dB}HAVE_LIBSOCKET${ac_dC}1${ac_dD} +${ac_uA}HAVE_LIBSOCKET${ac_uB}HAVE_LIBSOCKET${ac_uC}1${ac_uD} +${ac_eA}HAVE_LIBSOCKET${ac_eB}HAVE_LIBSOCKET${ac_eC}1${ac_eD} +CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag <<CEOF +${ac_dA}STDC_HEADERS${ac_dB}STDC_HEADERS${ac_dC}1${ac_dD} +${ac_uA}STDC_HEADERS${ac_uB}STDC_HEADERS${ac_uC}1${ac_uD} +${ac_eA}STDC_HEADERS${ac_eB}STDC_HEADERS${ac_eC}1${ac_eD} +${ac_dA}HAVE_SYS_WAIT_H${ac_dB}HAVE_SYS_WAIT_H${ac_dC}1${ac_dD} +${ac_uA}HAVE_SYS_WAIT_H${ac_uB}HAVE_SYS_WAIT_H${ac_uC}1${ac_uD} +${ac_eA}HAVE_SYS_WAIT_H${ac_eB}HAVE_SYS_WAIT_H${ac_eC}1${ac_eD} +${ac_dA}HAVE_FCNTL_H${ac_dB}HAVE_FCNTL_H${ac_dC}1${ac_dD} +${ac_uA}HAVE_FCNTL_H${ac_uB}HAVE_FCNTL_H${ac_uC}1${ac_uD} +${ac_eA}HAVE_FCNTL_H${ac_eB}HAVE_FCNTL_H${ac_eC}1${ac_eD} +${ac_dA}HAVE_LIMITS_H${ac_dB}HAVE_LIMITS_H${ac_dC}1${ac_dD} +${ac_uA}HAVE_LIMITS_H${ac_uB}HAVE_LIMITS_H${ac_uC}1${ac_uD} +${ac_eA}HAVE_LIMITS_H${ac_eB}HAVE_LIMITS_H${ac_eC}1${ac_eD} +CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag <<CEOF +${ac_dA}HAVE_SGTTY_H${ac_dB}HAVE_SGTTY_H${ac_dC}1${ac_dD} +${ac_uA}HAVE_SGTTY_H${ac_uB}HAVE_SGTTY_H${ac_uC}1${ac_uD} +${ac_eA}HAVE_SGTTY_H${ac_eB}HAVE_SGTTY_H${ac_eC}1${ac_eD} +${ac_dA}HAVE_SYS_TIME_H${ac_dB}HAVE_SYS_TIME_H${ac_dC}1${ac_dD} +${ac_uA}HAVE_SYS_TIME_H${ac_uB}HAVE_SYS_TIME_H${ac_uC}1${ac_uD} +${ac_eA}HAVE_SYS_TIME_H${ac_eB}HAVE_SYS_TIME_H${ac_eC}1${ac_eD} +${ac_dA}HAVE_UNISTD_H${ac_dB}HAVE_UNISTD_H${ac_dC}1${ac_dD} +${ac_uA}HAVE_UNISTD_H${ac_uB}HAVE_UNISTD_H${ac_uC}1${ac_uD} +${ac_eA}HAVE_UNISTD_H${ac_eB}HAVE_UNISTD_H${ac_eC}1${ac_eD} +${ac_dA}RETSIGTYPE${ac_dB}RETSIGTYPE${ac_dC}void${ac_dD} +${ac_uA}RETSIGTYPE${ac_uB}RETSIGTYPE${ac_uC}void${ac_uD} +${ac_eA}RETSIGTYPE${ac_eB}RETSIGTYPE${ac_eC}void${ac_eD} +CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag <<CEOF +${ac_dA}TIME_WITH_SYS_TIME${ac_dB}TIME_WITH_SYS_TIME${ac_dC}1${ac_dD} +${ac_uA}TIME_WITH_SYS_TIME${ac_uB}TIME_WITH_SYS_TIME${ac_uC}1${ac_uD} +${ac_eA}TIME_WITH_SYS_TIME${ac_eB}TIME_WITH_SYS_TIME${ac_eC}1${ac_eD} +${ac_dA}HAVE_TZNAME${ac_dB}HAVE_TZNAME${ac_dC}1${ac_dD} +${ac_uA}HAVE_TZNAME${ac_uB}HAVE_TZNAME${ac_uC}1${ac_uD} +${ac_eA}HAVE_TZNAME${ac_eB}HAVE_TZNAME${ac_eC}1${ac_eD} +${ac_dA}USE_TIMEZONE${ac_dB}USE_TIMEZONE${ac_dC}1${ac_dD} +${ac_uA}USE_TIMEZONE${ac_uB}USE_TIMEZONE${ac_uC}1${ac_uD} +${ac_eA}USE_TIMEZONE${ac_eB}USE_TIMEZONE${ac_eC}1${ac_eD} +${ac_dA}RETSIGTYPE${ac_dB}RETSIGTYPE${ac_dC}void${ac_dD} +${ac_uA}RETSIGTYPE${ac_uB}RETSIGTYPE${ac_uC}void${ac_uD} +${ac_eA}RETSIGTYPE${ac_eB}RETSIGTYPE${ac_eC}void${ac_eD} +CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag <<CEOF +${ac_dA}HAVE_VPRINTF${ac_dB}HAVE_VPRINTF${ac_dC}1${ac_dD} +${ac_uA}HAVE_VPRINTF${ac_uB}HAVE_VPRINTF${ac_uC}1${ac_uD} +${ac_eA}HAVE_VPRINTF${ac_eB}HAVE_VPRINTF${ac_eC}1${ac_eD} +${ac_dA}HAVE_WAIT3${ac_dB}HAVE_WAIT3${ac_dC}1${ac_dD} +${ac_uA}HAVE_WAIT3${ac_uB}HAVE_WAIT3${ac_uC}1${ac_uD} +${ac_eA}HAVE_WAIT3${ac_eB}HAVE_WAIT3${ac_eC}1${ac_eD} +${ac_dA}HAVE_GETHOSTNAME${ac_dB}HAVE_GETHOSTNAME${ac_dC}1${ac_dD} +${ac_uA}HAVE_GETHOSTNAME${ac_uB}HAVE_GETHOSTNAME${ac_uC}1${ac_uD} +${ac_eA}HAVE_GETHOSTNAME${ac_eB}HAVE_GETHOSTNAME${ac_eC}1${ac_eD} +${ac_dA}HAVE_GETTIMEOFDAY${ac_dB}HAVE_GETTIMEOFDAY${ac_dC}1${ac_dD} +${ac_uA}HAVE_GETTIMEOFDAY${ac_uB}HAVE_GETTIMEOFDAY${ac_uC}1${ac_uD} +${ac_eA}HAVE_GETTIMEOFDAY${ac_eB}HAVE_GETTIMEOFDAY${ac_eC}1${ac_eD} +CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + cat > conftest.frag <<CEOF +${ac_dA}HAVE_SELECT${ac_dB}HAVE_SELECT${ac_dC}1${ac_dD} +${ac_uA}HAVE_SELECT${ac_uB}HAVE_SELECT${ac_uC}1${ac_uD} +${ac_eA}HAVE_SELECT${ac_eB}HAVE_SELECT${ac_eC}1${ac_eD} +${ac_dA}HAVE_SOCKET${ac_dB}HAVE_SOCKET${ac_dC}1${ac_dD} +${ac_uA}HAVE_SOCKET${ac_uB}HAVE_SOCKET${ac_uC}1${ac_uD} +${ac_eA}HAVE_SOCKET${ac_eB}HAVE_SOCKET${ac_eC}1${ac_eD} +${ac_dA}HAVE_STRERROR${ac_dB}HAVE_STRERROR${ac_dC}1${ac_dD} +${ac_uA}HAVE_STRERROR${ac_uB}HAVE_STRERROR${ac_uC}1${ac_uD} +${ac_eA}HAVE_STRERROR${ac_eB}HAVE_STRERROR${ac_eC}1${ac_eD} +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in + + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + + + +exit 0 diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/config.sub b/ACE/apps/JAWS/clients/WebSTONE/src/config.sub new file mode 100755 index 00000000000..e67a800b515 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/config.sub @@ -0,0 +1,867 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS (if any). +basic_machine=`echo $1 | sed 's/-[^-]*$//'` +if [ $basic_machine != $1 ] +then os=`echo $1 | sed 's/.*-/-/'` +else os=; fi + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp ) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \ + | arme[lb] | pyramid \ + | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ + | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \ + | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \ + | pdp11 | mips64el | mips64orion | mips64orionel \ + | sparc) + basic_machine=$basic_machine-unknown + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \ + | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ + | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ + | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ + | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ + | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigados) + basic_machine=m68k-cbm + os=-amigados + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[345]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv32 + ;; + i[345]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv4 + ;; + i[345]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv + ;; + i[345]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | p6) + # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium + basic_machine=i586-intel + ;; + pentium-* | p5-* | p6-*) + # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + k5) + # We don't have specific support for AMD's K5 yet, so just call it a Pentium + basic_machine=i586-amd + ;; + nexen) + # We don't have specific support for Nexgen yet, so just call it a Pentium + basic_machine=i586-nexgen + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + basic_machine=mips-mips + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware* | svr4*) + os=-sysv4 + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \ + | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ + | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* ) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigados + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -lynxos*) + vendor=lynx + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxworks*) + vendor=wrs + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/configure b/ACE/apps/JAWS/clients/WebSTONE/src/configure new file mode 100755 index 00000000000..8e1ad6e8369 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/configure @@ -0,0 +1,2132 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.7 +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_default_prefix=bin + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.7" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=webclient.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='echo $CPP $CPPFLAGS 1>&5; +$CPP $CPPFLAGS' +ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5; +${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5' +ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5; +${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5' + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +PRODUCT=webstone +VERSION=2.0b4 +cat >> confdefs.h <<EOF +#define PRODUCT "$PRODUCT" +EOF + +cat >> confdefs.h <<EOF +#define VERSION "$VERSION" +EOF + + + + + +# set system type +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`$ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`$ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`$ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`$ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# +# checks for programs +# +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 +if test $ac_cv_prog_gcc = yes; then + GCC=yes + if test "${CFLAGS+set}" != set; then + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_gcc_g=yes +else + ac_cv_prog_gcc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 + if test $ac_cv_prog_gcc_g = yes; then + CFLAGS="-g -O" + else + CFLAGS="-O" + fi + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +set dummy ${MAKE-make}; ac_make=$2 +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +for ac_prog in mawk gawk nawk awk +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AWK="$ac_cv_prog_AWK" +if test -n "$AWK"; then + echo "$ac_t""$AWK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$AWK" && break +done + + + +# We use a path for perl so the #! line in bin/wscollect.pl will work. +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$PERL" in + /*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_PERL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="no" + ;; +esac +fi +PERL="$ac_cv_path_PERL" +if test -n "$PERL"; then + echo "$ac_t""$PERL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +if test "$PERL" != no; then + PERL_SCRIPTS="bin/wscollect.pl" +else + echo "configure: warning: Some functions may work correctly" 1>&2 +fi + +# +# checks for libraries +# +# Replace `main' with a function in -lm: +echo $ac_n "checking for -lm""... $ac_c" 1>&6 +ac_lib_var=`echo m | tr '.-/+' '___p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lm $LIBS" +cat > conftest.$ac_ext <<EOF +#line 832 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { +floor() +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo m | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lm $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for -lcompat""... $ac_c" 1>&6 +ac_lib_var=`echo compat | tr '.-/+' '___p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcompat $LIBS" +cat > conftest.$ac_ext <<EOF +#line 872 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { +rexec() +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo compat | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lcompat $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for -lucb""... $ac_c" 1>&6 +ac_lib_var=`echo ucb | tr '.-/+' '___p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lucb $LIBS" +cat > conftest.$ac_ext <<EOF +#line 912 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { +wait3() +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo ucb | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lucb $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for -lsocket""... $ac_c" 1>&6 +ac_lib_var=`echo socket | tr '.-/+' '___p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket -lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 952 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { +connect() +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lsocket $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + +# +# checks for header files +# +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 1003 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 1017 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +# If we cannot run a trivial program, we must be cross compiling. +echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_cross=yes +else +cat > conftest.$ac_ext <<EOF +#line 1051 "configure" +#include "confdefs.h" +main(){return(0);} +EOF +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + ac_cv_c_cross=no +else + ac_cv_c_cross=yes +fi +fi +rm -fr conftest* +fi + +echo "$ac_t""$ac_cv_c_cross" 1>&6 +cross_compiling=$ac_cv_c_cross + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1073 "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 1095 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 1113 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else +cat > conftest.$ac_ext <<EOF +#line 1134 "configure" +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + ac_cv_header_stdc=no +fi +fi +rm -fr conftest* +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1169 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <sys/wait.h> +#ifndef WEXITSTATUS +#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif +int main() { return 0; } +int t() { +int s; +wait (&s); +s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_header_sys_wait_h=yes +else + rm -rf conftest* + ac_cv_header_sys_wait_h=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 +if test $ac_cv_header_sys_wait_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_WAIT_H 1 +EOF + +fi + +for ac_hdr in fcntl.h limits.h sgtty.h sys/time.h unistd.h +do +ac_safe=`echo "$ac_hdr" | tr './\055' '___'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1213 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +# +# checks for typedefs, structures, and compiler characteristics +# +echo $ac_n "checking for working const""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1250 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { + +/* Ultrix mips cc rejects this. */ +typedef int charset[2]; const charset x; +/* SunOS 4.1.1 cc rejects this. */ +char const *const *ccp; +char **p; +/* NEC SVR4.0.2 mips cc rejects this. */ +struct point {int x, y;}; +static struct point const zero = {0,0}; +/* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in an arm + of an if-expression whose if-part is not a constant expression */ +const char *g = "string"; +ccp = &g + (g ? g-g : 0); +/* HPUX 7.0 cc rejects these. */ +++ccp; +p = (char**) ccp; +ccp = (char const *const *) p; +{ /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; +} +{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; +} +{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; +} +{ /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_c_const=yes +else + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1324 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "size_t" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1355 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <signal.h> +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { return 0; } +int t() { +int i; +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_type_signal=void +else + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <<EOF +#define RETSIGTYPE $ac_cv_type_signal +EOF + + +echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1395 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> +int main() { return 0; } +int t() { +struct tm *tp; +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_header_time=yes +else + rm -rf conftest* + ac_cv_header_time=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_header_time" 1>&6 +if test $ac_cv_header_time = yes; then + cat >> confdefs.h <<\EOF +#define TIME_WITH_SYS_TIME 1 +EOF + +fi + +echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1429 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <time.h> +int main() { return 0; } +int t() { +struct tm *tp; tp->tm_sec; +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_struct_tm=time.h +else + rm -rf conftest* + ac_cv_struct_tm=sys/time.h +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_struct_tm" 1>&6 +if test $ac_cv_struct_tm = sys/time.h; then + cat >> confdefs.h <<\EOF +#define TM_IN_SYS_TIME 1 +EOF + +fi + +echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1462 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <$ac_cv_struct_tm> +int main() { return 0; } +int t() { +struct tm tm; tm.tm_zone; +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_struct_tm_zone=yes +else + rm -rf conftest* + ac_cv_struct_tm_zone=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_struct_tm_zone" 1>&6 +if test "$ac_cv_struct_tm_zone" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_TM_ZONE 1 +EOF + +else + echo $ac_n "checking for tzname""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1494 "configure" +#include "confdefs.h" +#include <time.h> +#ifndef tzname /* For SGI. */ +extern char *tzname[]; /* RS6000 and others reject char **tzname. */ +#endif +int main() { return 0; } +int t() { +atoi(*tzname); +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + ac_cv_var_tzname=yes +else + rm -rf conftest* + ac_cv_var_tzname=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_var_tzname" 1>&6 + if test $ac_cv_var_tzname = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_TZNAME 1 +EOF + + fi +fi + +cat > conftest.$ac_ext <<EOF +#line 1526 "configure" +#include "confdefs.h" +#include <sys/time.h> +int main() { return 0; } +int t() { +struct timeval thetime; struct timezone thezone; + gettimeofday(&thetime, &thezone); +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + cat >> confdefs.h <<\EOF +#define USE_TIMEZONE 1 +EOF + +fi +rm -f conftest* + + +# +# checks for library functions +# +echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_func_memcmp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp=no +else +cat > conftest.$ac_ext <<EOF +#line 1556 "configure" +#include "confdefs.h" + +main() +{ + char c0 = 0x40, c1 = 0x80, c2 = 0x81; + exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1); +} + +EOF +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + ac_cv_func_memcmp=yes +else + ac_cv_func_memcmp=no +fi +fi +rm -fr conftest* +fi + +echo "$ac_t""$ac_cv_func_memcmp" 1>&6 +test $ac_cv_func_memcmp = no && LIBOBJS="$LIBOBJS memcmp.o" + +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1584 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <signal.h> +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { return 0; } +int t() { +int i; +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_type_signal=void +else + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <<EOF +#define RETSIGTYPE $ac_cv_type_signal +EOF + + +echo $ac_n "checking for vprintf""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1624 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char vprintf(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +char vprintf(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_vprintf) || defined (__stub___vprintf) +choke me +#else +vprintf(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func_vprintf=yes" +else + rm -rf conftest* + eval "ac_cv_func_vprintf=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_VPRINTF 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +if test "$ac_cv_func_vprintf" != yes; then +echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1672 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +char _doprnt(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub__doprnt) || defined (__stub____doprnt) +choke me +#else +_doprnt(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func__doprnt=yes" +else + rm -rf conftest* + eval "ac_cv_func__doprnt=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_DOPRNT 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking for wait3 that fills in rusage""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_func_wait3'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_wait3=no +else +cat > conftest.$ac_ext <<EOF +#line 1724 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <stdio.h> +/* HP-UX has wait3 but does not fill in rusage at all. */ +main() { + struct rusage r; + int i; + /* Use a field that we can force nonzero -- + voluntary context switches. + For systems like NeXT and OSF/1 that don't set it, + also use the system CPU time. And page faults (I/O) for Linux. */ + r.ru_nvcsw = 0; + r.ru_stime.tv_sec = 0; + r.ru_stime.tv_usec = 0; + r.ru_majflt = r.ru_minflt = 0; + switch (fork()) { + case 0: /* Child. */ + sleep(1); /* Give up the CPU. */ + _exit(0); + case -1: _exit(0); /* What can we do? */ + default: /* Parent. */ + wait3(&i, 0, &r); + sleep(2); /* Avoid "text file busy" from rm on fast HP-UX machines. */ + exit(r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0 + && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0); + } +} +EOF +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + ac_cv_func_wait3=yes +else + ac_cv_func_wait3=no +fi +fi +rm -fr conftest* +fi + +echo "$ac_t""$ac_cv_func_wait3" 1>&6 +if test $ac_cv_func_wait3 = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_WAIT3 1 +EOF + +fi + +for ac_func in gethostname gettimeofday select socket strerror +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1780 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +char $ac_func(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +# +# checks for system services +# + +# +# all done +# +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ + >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.7" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@PRODUCT@%$PRODUCT%g +s%@VERSION@%$VERSION%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@SET_MAKE@%$SET_MAKE%g +s%@AWK@%$AWK%g +s%@PERL@%$PERL%g +s%@PERL_SCRIPTS@%$PERL_SCRIPTS%g +s%@CPP@%$CPP%g +s%@LIBOBJS@%$LIBOBJS%g + +CEOF +EOF +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust relative srcdir, etc. for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file +fi; done +rm -f conftest.subs + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"} +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + cp $ac_given_srcdir/$ac_file_in conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. +# Maximum number of lines to put in a single here document. +ac_max_here_lines=12 + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + + + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + +# +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/configure.in b/ACE/apps/JAWS/clients/WebSTONE/src/configure.in new file mode 100644 index 00000000000..449a6a16cef --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/configure.in @@ -0,0 +1,99 @@ +# configure.in +# Configure template for WebStone +# Process this file with autoconf to produce a configure script. +# +# This file and all files contained in this directory are +# copyright 1995, Silicon Graphics, Inc. +# +# This software is provided without support and without any obligation on the +# part of Silicon Graphics, Inc. to assist in its use, correction, modification +# or enhancement. There is no guarantee that this software will be included in +# future software releases, and it probably will not be included. +# +# THIS SOFTWARE IS PROVIDED "AS IS" WITH NO WARRANTIES OF ANY KIND INCLUDING +# THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +# PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +# +# In no event will Silicon Graphics, Inc. be liable for any lost revenue or +# profits or other special, indirect and consequential damages, even if +# Silicon Graphics, Inc. has been advised of the possibility of such damages. + +AC_INIT(webclient.c) +AC_CONFIG_HEADER(config.h) +PRODUCT=webstone +VERSION=2.0b6 +AC_DEFINE_UNQUOTED(PRODUCT, "$PRODUCT") +AC_DEFINE_UNQUOTED(VERSION, "$VERSION") +AC_SUBST(PRODUCT) +AC_SUBST(VERSION) +AC_PREFIX_DEFAULT(bin) + +# set system type +AC_CANONICAL_SYSTEM + +# +# checks for programs +# +AC_PROG_CC +AC_PROG_MAKE_SET +AC_PROG_AWK + + +# We use a path for perl so the #! line in bin/wscollect.pl will work. +AC_PATH_PROG(PERL, perl, no) +AC_SUBST(PERL) +AC_SUBST(PERL_SCRIPTS) +if test "$PERL" != no; then + PERL_SCRIPTS="bin/wscollect.pl" +else + AC_MSG_WARN(Some functions may work correctly, since perl was not found) +fi + +# +# checks for libraries +# +# Replace `main' with a function in -lm: +AC_CHECK_LIB(m, floor) +AC_CHECK_LIB(compat, rexec) +AC_CHECK_LIB(ucb, wait3) +AC_CHECK_LIB(socket, connect, AC_SUBST(LIBS), , -lnsl) + +# +# checks for header files +# +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h limits.h sgtty.h sys/time.h unistd.h) + +# +# checks for typedefs, structures, and compiler characteristics +# +AC_C_CONST +AC_TYPE_SIZE_T +AC_TYPE_SIGNAL +AC_HEADER_TIME +AC_STRUCT_TIMEZONE +AC_TRY_COMPILE([#include <sys/time.h>], + [struct timeval thetime; struct timezone thezone; + gettimeofday(&thetime, &thezone); ], + AC_DEFINE(USE_TIMEZONE), ) + +# +# checks for library functions +# +AC_FUNC_MEMCMP +AC_TYPE_SIGNAL +AC_FUNC_VPRINTF +AC_FUNC_WAIT3 +AC_CHECK_FUNCS(gethostname gettimeofday select socket strerror) + +# +# checks for system services +# + +# +# all done +# +AC_OUTPUT(Makefile) +# +# end diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/debug.h b/ACE/apps/JAWS/clients/WebSTONE/src/debug.h new file mode 100644 index 00000000000..2322c287931 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/debug.h @@ -0,0 +1,18 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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. * + * * + **************************************************************************/ +#ifndef __DEBUG_H__ + +#define D_PRINTF debug && fprintf(debugfile, +#define D_FLUSH );fflush(debugfile) + +#define __DEBUG_H__ +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/errexit.c b/ACE/apps/JAWS/clients/WebSTONE/src/errexit.c new file mode 100644 index 00000000000..a9bc024d4b6 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/errexit.c @@ -0,0 +1,106 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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. * + * * + **************************************************************************/ + +/* errexit call for general error handling */ + +#include <stdio.h> +#ifndef WIN32 +#include <errno.h> +#include <netdb.h> +#include <unistd.h> +#endif /* WIN32 */ +#include <stdarg.h> +#include <sys/types.h> + +#include "sysdep.h" +#include "bench.h" + +#ifdef HAVE_VPRINTF +#define VPRINTF(stderr, format, args) vfprintf((stderr), (format), (args)) +#else +#ifdef HAVE_DOPRNT +#define VPRINTF(stderr, format, args) _doprnt((format), (args), (stderr)) +#endif /* HAVE_DOPRNT */ +#endif /* HAVE_VPRINTF */ + +/* print an error message and exit 1 */ +void +errexit(const char *format, ...) +{ +va_list args; +char hostname[64] = ""; +pid_t PID; + + PID = getpid(); + gethostname(hostname, sizeof(hostname)); + fprintf(stderr, "%s PID %d: ", hostname, PID); + + va_start(args, format); + VPRINTF(stderr, format, args); + debug && VPRINTF(debugfile, format, args); + va_end(args); + fflush(stderr); + exit(1); +} +/* that's it */ + +/* print an error message and return -1 */ +int +returnerr(const char *format, ...) +{ +va_list args; +char hostname[64] = ""; +pid_t PID; + + PID = getpid(); + gethostname(hostname, sizeof(hostname)); + fprintf(stderr, "%s PID %d: ", hostname, PID); + + va_start(args, format); + VPRINTF(stderr, format, args); + debug && VPRINTF(debugfile, format, args); + va_end(args); + fflush(stderr); + debug && fflush(debugfile); + return(-1); +} +/* that's it */ + +/* print a debug message and then flush */ +int +d_printf(const char *format, ...) +{ +va_list args; + + va_start(args, format); + VPRINTF(debugfile, format, args); + va_end(args); + + fflush(debugfile); + return 0; +} +/* that's it */ + +/* returns the last network error as a string */ +char *neterrstr(void) { +static char buf[200]; + +#ifdef WIN32 + sprintf(buf, "WSAGetLastError() = %d", WSAGetLastError()); + WSASetLastError(0); +#else + sprintf(buf, "errno = %d: %s", errno, strerror(errno)); + errno = 0; +#endif /* WIN32 */ + + return buf; +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/genrand.c b/ACE/apps/JAWS/clients/WebSTONE/src/genrand.c new file mode 100644 index 00000000000..4c2c9598fd0 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/genrand.c @@ -0,0 +1,70 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 <fcntl.h> +#include <math.h> + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "sysdep.h" + +void +main(const int argc, char* argv[]) +{ + FILE* file; + int i; + int my_random; + int size; + char *cp; + + if (argc != 3) + { + printf("usage: %s file_size_in_bytes[K|M] name\n", argv[0]); + exit(2); + } + + if ((file = fopen(argv[2], "w")) == 0) + { + perror("fopen"); + exit(1); + } + + size = atoi(argv[1]); + + for (cp = argv[1]; *cp; cp++) + { + switch(*cp) + { + case 'k': + case 'K': + size *= 1024; + break; + case 'm': + case 'M': + size *= 1024*1024; + break; + } + } + + for (i = 0; i < size; i++) + { + my_random = ((RANDOM() % 94) + 33); + fputc((char)my_random, file); + } + + fclose(file); +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/get.c b/ACE/apps/JAWS/clients/WebSTONE/src/get.c new file mode 100644 index 00000000000..8a6d9232deb --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/get.c @@ -0,0 +1,318 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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. * + * * + **************************************************************************/ + +/* THIS IS WHERE WE GO OUT AND FETCH A URL */ + +#include <stdio.h> +#include <errno.h> + +#ifndef WIN32 +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/socket.h> +#include <sys/param.h> +#include <netinet/in.h> +#include <netdb.h> +#endif /* WIN32 */ + +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#ifdef SUNOS +#include <unistd.h> +#endif +#include <ctype.h> + +#ifdef WIN32 +#include <io.h> +#include <windows.h> +#include <winsock.h> +#endif /* WIN32 */ + +#include "sysdep.h" +#include "bench.h" + +#define ACCEPT_COMMAND "Accept: */* HTTP/1.0\r\n\r\n" +#define ACCEPT_COMMAND_LEN ((int)strlen(ACCEPT_COMMAND)) +#define MAXCOMMANDLEN 256 +#define HEADERBUFSIZ (8*1024) + +#define UPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) + 'A' - 'a' : (c)) + +/* compare two strings with max length, ignoring case */ +int mystrincmp(const char *str1, const char *str2, int len) { +register int diff; + + while (*str1 && *str2 && len--) { + if (diff = UPPER(*str1) - UPPER(*str2)) + return diff < 0 ? -1 : 1; + str1++; + str2++; + } + return 0; +} + +int +get(char *loc, NETPORT port, char *url, rqst_timer_t *timer) +{ + SOCKET sock = BADSOCKET_VALUE; + int writelen; + int bytesread; + int totalbytesread; + int headerlen; + int bodylength; + int contentlength = 0; + int outputfile = -1; + int status; + char getcommand[MAXCOMMANDLEN]; + char headerbuffer[HEADERBUFSIZ+1]; + char *offset; + char outputfilename[MAXPATHLEN]; + char version[100]; + int count; + +/*#define ABORTIVE_CLOSE 1*/ +#ifdef ABORTIVE_CLOSE +#error don't enable this option + struct linger { + int l_onoff; + int l_linger; + } linger_opt; +#endif /* ABORTIVE_CLOSE */ + + /* can you really get an error from gettimeofday?? */ + if(GETTIMEOFDAY(&timer->entertime, &timer->entertimezone) != 0) + { + returnerr("Error retrieving entertime\n"); + goto error; + } + timer->valid = 1; + + if(GETTIMEOFDAY(&timer->beforeconnect, &timer->beforeconnectzone) != 0) + { + returnerr("Error retrieving beforeconnect\n"); + goto error; + } + + sock = connectsock(loc, port, "tcp"); + if (BADSOCKET(sock)) + { + D_PRINTF( "Call to connectsock returned %d (%s)\n", sock, neterrstr() ); + returnerr("Couldn't connect to WWW server: %s\n", neterrstr()); + goto error; + } + +#ifdef ABORTIVE_CLOSE +#error don't enable this option + /* set up for abortive close */ + linger_opt.l_onoff = 1; + linger_opt.l_linger = 0; + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, + (char *) &linger_opt, sizeof(linger_opt)) < 0) { + fprintf(stderr, "Can't set sockopt SO_LINGER"); + returnerr("Couldn't set SO_LINGER = 0\n"); + goto error; + } +#endif /* ABORTIVE_CLOSE */ + + if(GETTIMEOFDAY(&timer->afterconnect, &timer->afterconnectzone) != 0) + { + NETCLOSE(sock); + GETTIMEOFDAY(&timer->exittime, &timer->exittimezone); + returnerr("Error retrieving afterconnect\n"); + goto error; + } + + /* + * SEND THE GET AND THE ACCEPT. + */ + sprintf(getcommand, "GET %s HTTP/1.0\r\n%s", url, + ACCEPT_COMMAND); + D_PRINTF( "Writing to server: %s\n", getcommand ); + writelen = strlen(getcommand); + status = NETWRITE(sock, getcommand, writelen); + if(status != writelen) + { + returnerr("Error sending command line to server: %s\n", + neterrstr()); + goto error; + } + /* + * WE HAVE NOW SENT THE REQUEST SUCCESSFULLY. + * WAIT FOR THE REPLY AND FIND THE HEADER + */ + + if(GETTIMEOFDAY(&timer->beforeheader, &timer->beforeheaderzone) != 0) + { + returnerr("Error retrieving beforeheader\n"); + goto error; + } + + /* read the header and part of the file */ + totalbytesread = 0; + headerlen = 0; + while (totalbytesread < HEADERBUFSIZ) + { + bytesread = NETREAD(sock, headerbuffer+totalbytesread, HEADERBUFSIZ-totalbytesread); + if (BADSOCKET(bytesread)) + { + D_PRINTF( "Did not receive full header\n" ); + D_PRINTF( "NETREAD returned %d\n", bytesread ); + returnerr("Did not receive full header: %s\n", + neterrstr()); + goto error; + } + totalbytesread += bytesread; + + /* search for end of header */ + headerbuffer[totalbytesread] = 0; + if (offset = strstr(headerbuffer, "\n\n")) { + headerlen = offset - headerbuffer + 2; + break; + } else if (offset = strstr(headerbuffer, "\n\r\n")) { + headerlen = offset - headerbuffer + 3; + break; + } + } + + if (headerlen == 0) { + returnerr("Can't find the end of the header in \"%s\"\n", headerbuffer); + goto error; + } + + /* get and check status code from the first line of the header */ + count = sscanf(headerbuffer, "HTTP/%s %d", version, &status); + if (count != 2) { + returnerr("Bad status line in get(): %s\n", headerbuffer); + goto error; + } + if (status < 200 || status > 300) { + returnerr("Bad status (%d) in get() for url %s\n", status, url); + goto error; + } + + /* get the content length line from the header */ + offset = headerbuffer; + while (offset < headerbuffer+headerlen && *offset) { + if (*offset++ != '\n') + continue; + + if (mystrincmp(offset, CONTENT_LENGTH_STRING, strlen(CONTENT_LENGTH_STRING)) == 0) { + sscanf(offset+strlen(CONTENT_LENGTH_STRING), "%d", &contentlength); + D_PRINTF( "Content-Length: %d\n", contentlength ); + } + } + + if(GETTIMEOFDAY(&timer->afterheader, &timer->afterheaderzone) != 0) + { + returnerr("Error retrieving afterheader\n"); + goto error; + } + + if(savefile) + { + sprintf(outputfilename,"/tmp/webstone.data.%d", (int)getpid()); + if((outputfile = open(outputfilename,(O_WRONLY|O_CREAT),0777)) < 0) + { + D_PRINTF( "outputfile %d %d\n", outputfile, errno ); + returnerr("Error saving file: %s\n", strerror(errno)); + goto error; + } + lseek(outputfile,1,SEEK_END); /* this is odd... JEF */ + + /* if we have part of the file already, save that part */ + if(totalbytesread > headerlen) + { + write(outputfile, headerbuffer+headerlen, totalbytesread-headerlen); + } + } + + /* read the body of the file */ + do + { + bytesread = NETREAD(sock, headerbuffer, HEADERBUFSIZ); + D_PRINTF( "Read %d bytes from socket %d\n", bytesread, sock ); + + if (BADSOCKET(bytesread)) + { + D_PRINTF( "Read returns %d, error: %s\n", bytesread, + neterrstr() ); + returnerr("Error during read of page body. Read " + "returns %d on socket %d, error: %s\n", + bytesread, sock, neterrstr()); + goto error; + } + + totalbytesread += bytesread; + + if (outputfile != -1 && bytesread) + { + write(outputfile, headerbuffer, bytesread); + } + + } while (bytesread); + + /* done reading body */ + if ( contentlength && (totalbytesread - headerlen) != contentlength) + { + D_PRINTF( "Warning: file length (%d) doesn't match Content-length (%d)\n", + totalbytesread - headerlen, contentlength); + } + + bodylength = totalbytesread - headerlen; + + if(GETTIMEOFDAY(&timer->afterbody, &timer->afterbodyzone) != 0) + { + returnerr("Error retrieving afterbody\n"); + goto error; + } + + NETCLOSE(sock); + if (outputfile != -1) + { + close(outputfile); + } + + D_PRINTF( "Read %d bytes, %d of that being body\n", + totalbytesread, bodylength ); + + if(GETTIMEOFDAY(&timer->exittime, &timer->exittimezone) != 0) + { + D_PRINTF( "Error retrieving exit time: %s\n", strerror(errno) ); + returnerr("Error retrieving exit time\n"); + goto error; + } + timer->valid = 2; + timer->totalbytes = totalbytesread; + timer->bodybytes = bodylength; + + D_PRINTF( "get returning totalbytes %d body %d valid %d\n", + timer->totalbytes, timer->bodybytes, timer->valid ); + + D_PRINTF( "get returning start %d, end %d\n", + timer->entertime.tv_sec, timer->exittime.tv_sec ); + + D_PRINTF( "get returning connect %d, request %d, header %d, body %d\n", + timer->afterconnect.tv_sec, timer->beforeheader.tv_sec, + timer->afterheader.tv_sec, timer->afterbody.tv_sec ); + + return 0; + +error: + if (!BADSOCKET(sock)) + NETCLOSE(sock); + if (outputfile != -1) + close(outputfile); + GETTIMEOFDAY(&timer->exittime, &timer->exittimezone); /* needed? */ + return -1; +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/get.h b/ACE/apps/JAWS/clients/WebSTONE/src/get.h new file mode 100644 index 00000000000..57ac8707445 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/get.h @@ -0,0 +1,17 @@ +#ifndef __GET_H__ +#define __GET_H__ +/* $Id$ */ +/************************************************************************** + * * + * Copyright (C) 1995 Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs where * + * deveolped by SGI for public use. If anychanges are made to this code * + * please try to get the changes back to the author. Feel free to make * + * modfications and changes to the code and release it. * + * * + **************************************************************************/ + +extern int get(char *loc, int port, char *url, rqst_timer_t *timer); + +#endif /* !__GET_H__ */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/getopt.c b/ACE/apps/JAWS/clients/WebSTONE/src/getopt.c new file mode 100644 index 00000000000..d04ea469aa6 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/getopt.c @@ -0,0 +1,67 @@ +/* $Id$ */ +/* this is a public domain version of getopt */ +/* FTP Site: ftp.uu.net/pub/OS/unix/bsd-sources/lib/librpc/etc/getopt.c */ + +#include <stdio.h> +#include <string.h> + +#define MYNULL 0 +#define ERR(s, c) if(opterr){\ + extern size_t strlen();\ + extern int write();\ + char errbuf[2];\ + errbuf[0] = c; errbuf[1] = '\n';\ + (void) write(2, argv[0], strlen(argv[0]));\ + (void) write(2, s, strlen(s));\ + (void) write(2, errbuf, 2);} + +int opterr = 1; +int optind = 1; +int optopt; +char *optarg; + +int +getopt(argc, argv, opts) +int argc; +char **argv, *opts; +{ + static int sp = 1; + register int c; + register char *cp; + + if(sp == 1) + if(optind >= argc || + argv[optind][0] != '-' || argv[optind][1] == '\0') + return(EOF); + else if(strcmp(argv[optind], "--") == MYNULL) { + optind++; + return(EOF); + } + optopt = c = argv[optind][sp]; + if(c == ':' || (cp=strchr(opts, c)) == 0) { + ERR(": unknown option, -", c); + if(argv[optind][++sp] == '\0') { + optind++; + sp = 1; + } + return('?'); + } + if(*++cp == ':') { + if(argv[optind][sp+1] != '\0') + optarg = &argv[optind++][sp+1]; + else if(++optind >= argc) { + ERR(": argument missing for -", c); + sp = 1; + return('?'); + } else + optarg = argv[optind++]; + sp = 1; + } else { + if(argv[optind][++sp] == '\0') { + sp = 1; + optind++; + } + optarg = 0; + } + return(c); +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/gettimeofday.c b/ACE/apps/JAWS/clients/WebSTONE/src/gettimeofday.c new file mode 100644 index 00000000000..dbe4e1d0d63 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/gettimeofday.c @@ -0,0 +1,58 @@ +/* $Id$ */ + +/* + * This file defines functions that are required for unix compatibility. + * + * These functions are not available in the Microsoft C/C++ Run Time + * and the Win32 API. + * + * The following functions list may not be complete + * + * FUNCTIONS: + * SHARED _gettimeofday + * + */ + + +#include <windows.h> +#include <errno.h> +#include <winsock.h> /* For definition of "timeval" structure */ +#include <sys/timeb.h> /* For prototype of "_ftime()" */ + + +/* + * gettimeofday() -- gets the current time in elapsed seconds and + * microsends since GMT Jan 1, 1970. + * + * ARGUMENTS: - Pointer to a timeval struct to return the time into + * + * RETURN CODES: - 0 on success + * -1 on failure + */ +int gettimeofday(curTimeP) + struct timeval *curTimeP; +{ +struct _timeb localTime; + + if (curTimeP == (struct timeval *) 0) + { + errno = EFAULT; + return (-1); + } + + /* + * Compute the elapsed time since Jan 1, 1970 by first + * obtaining the elapsed time from the system using the + * _ftime(..) call and then convert to the "timeval" + * equivalent. + */ + + _ftime(&localTime); + + curTimeP->tv_sec = localTime.time + localTime.timezone; + curTimeP->tv_usec = localTime.millitm * 1000; + + return(0); +} + + diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/install-sh b/ACE/apps/JAWS/clients/WebSTONE/src/install-sh new file mode 100755 index 00000000000..89fc9b098b8 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/logfile27859 b/ACE/apps/JAWS/clients/WebSTONE/src/logfile27859 new file mode 100644 index 00000000000..a65984d6f9a --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/logfile27859 @@ -0,0 +1,9 @@ + entertime 867794927.279188 + beforeconnect 867794927.279189 + afterconnect 867794927.280504 + beforeheader 867794927.280604 + afterheader 867794927.299170 + afterbody 867794932.215967 + exittime 867794932.216306 + total bytes 5243057 + body bytes 5242880 diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/buffer.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/buffer.h new file mode 100644 index 00000000000..f172efcb93a --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/buffer.h @@ -0,0 +1,220 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * buffer.h: For performing buffered I/O on a file or socket descriptor. + * + * This is an abstraction to allow I/O to be performed regardless of the + * current system. That way, an integer file descriptor can be used under + * UNIX but a stdio FILE structure could be used on systems which don't + * support that or don't support it as efficiently. + * + * Two abstractions are defined: A file buffer, and a network buffer. A + * distinction is made so that mmap() can be used on files (but is not + * required). Also, the file buffer takes a file name as the object to + * open instead of a file descriptor. A lot of the network buffering + * is almost an exact duplicate of the non-mmap file buffering. + * + * If an error occurs, system-independent means to obtain an error string + * are also provided. However, if the underlying system is UNIX the error + * may not be accurate in a threaded environment. + * + * Rob McCool + * + */ + + +#ifndef BUFFER_H +#define BUFFER_H + +#ifdef XP_WIN32 +#include <nt/ntbuffer.h> +#else + + +/* + * We need certain system specific functions and symbols. + */ + +#include "file.h" +#include "net.h" + +/* + * Requires that the macro MALLOC be set to a "safe" malloc that will + * exit if no memory is available. If not under MCC httpd, define MALLOC + * to be the real malloc and play with fire, or make your own function. + */ + +#include "../netsite.h" + +#ifdef FILE_UNIX_MMAP +#include <sys/types.h> /* caddr_t */ +#endif + + +/* ------------------------------ Structures ------------------------------ */ + +#ifdef FILE_UNIX_MMAP +typedef struct { + SYS_FILE fd; + caddr_t fp; + int len; + + char *inbuf; /* for buffer_grab */ + int cursize; + + int pos; + char *errmsg; +} filebuf; + +#else + +typedef struct { + SYS_FILE fd; + + int pos, cursize, maxsize; + char *inbuf; + char *errmsg; +} filebuf; + +#endif + +typedef struct { + SYS_NETFD sd; + + int pos, cursize, maxsize, rdtimeout; + char *inbuf; + char *errmsg; +} netbuf; + + +/* -------------------------------- Macros -------------------------------- */ + + +/* + * netbuf_getc gets a character from the given network buffer and returns + * it. (as an integer). + * + * It will return (int) IO_ERROR for an error and (int) IO_EOF for + * an error condition or EOF respectively. + */ + +#define netbuf_getc(b) \ + ((b)->pos != (b)->cursize ? (int)((b)->inbuf[(b)->pos++]) : netbuf_next(b,1)) + +#ifdef FILE_UNIX_MMAP +#define filebuf_getc(b) ((b)->pos == (b)->len ? IO_EOF : (b)->fp[(b)->pos++]) +#else +#define filebuf_getc(b) \ + ((b)->pos != (b)->cursize ? (int)((b)->inbuf[(b)->pos++]) : filebuf_next(b,1)) +#endif + + +/* + * buffer_error returns the last error that occurred with buffer. Don't use + * this unless you know an error occurred. Independent of network/file type. + */ + +#define buffer_error(b) ((b)->errmsg) + +/* + * buffer_flush flushes any data after the current pos to the file + * descriptor fd. Regardless of buffer type. + */ + +#define buffer_flush(buf,fd) \ + system_write(fd,&(buf)->inbuf[(buf)->pos], (buf)->cursize - (buf)->pos) + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * buffer_open opens a new buffer reading the specified file, with an I/O + * buffer of size sz, and returns a new buffer structure which will hold + * the data. + * + * If FILE_UNIX_MMAP is defined, this may return NULL. If it does, check + * system_errmsg to get a message about the error. + */ + +filebuf *filebuf_open(SYS_FILE fd, int sz); +netbuf *netbuf_open(SYS_NETFD sd, int sz); + +/* + * filebuf_open_nostat is a convenience function for mmap() buffer opens, + * if you happen to have the stat structure already. + */ + +#ifdef FILE_UNIX_MMAP +#include <sys/stat.h> +filebuf *filebuf_open_nostat(SYS_FILE fd, int sz, struct stat *finfo); + +#else +#define filebuf_open_nostat(fd,sz,finfo) filebuf_open(fd,sz) +#endif + +/* + * buffer_next loads size more bytes into the given buffer and returns the + * first one, or BUFFER_EOF on EOF and BUFFER_ERROR on error. + */ + +int filebuf_next(filebuf *buf, int advance); +int netbuf_next(netbuf *buf, int advance); + +/* + * buffer_close deallocates a buffer and closes its associated files + * (does not close a network socket). + */ + +void filebuf_close(filebuf *buf); +void netbuf_close(netbuf *buf); + +/* + * buffer_grab will set the buffer's inbuf array to an array of sz bytes + * from the buffer's associated object. It returns the number of bytes + * actually read (between 1 and sz). It returns IO_EOF upon EOF or IO_ERROR + * upon error. The cursize entry of the structure will reflect the size + * of the iobuf array. + * + * The buffer will take care of allocation and deallocation of this array. + */ + +int filebuf_grab(filebuf *buf, int sz); +int netbuf_grab(netbuf *buf, int sz); + + +/* + * netbuf_buf2sd will send n bytes from the (probably previously read) + * buffer and send them to sd. If sd is -1, they are discarded. If n is + * -1, it will continue until EOF is recieved. Returns IO_ERROR on error + * and the number of bytes sent any other time. + */ + +int netbuf_buf2sd(netbuf *buf, SYS_NETFD sd, int len); + +/* + * filebuf_buf2sd assumes that nothing has been read from the filebuf, + * and just sends the file out to the given socket. Returns IO_ERROR on error + * and the number of bytes sent otherwise. + * + * Does not currently support you having read from the buffer previously. This + * can be changed transparently. + */ + +int filebuf_buf2sd(filebuf *buf, SYS_NETFD sd); + +#endif +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/cinfo.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/cinfo.h new file mode 100644 index 00000000000..13849531fd2 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/cinfo.h @@ -0,0 +1,146 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * cinfo.h: Content Information for a file, i.e. its type, etc. + * + * See cinfo.c for dependency information. + * + * Rob McCool + */ + + + +#ifndef CINFO_H +#define CINFO_H + + + +/* ------------------------------ Constants ------------------------------- */ + + +/* + * This will be the first string in the file, followed by x.x version + * where x is an integer. + * + * Updated due to trendy name change + */ + +#define MCC_MT_MAGIC "#--Mosaic Communications Corporation MIME Information" +#define MCC_MT_MAGIC_LEN 53 +#define NCC_MT_MAGIC "#--Netscape Communications Corporation MIME Information" +#define NCC_MT_MAGIC_LEN 55 + +/* The character which separates extensions with cinfo_find */ + +#define CINFO_SEPARATOR '.' + +/* The maximum length of a line in this file */ + +#define CINFO_MAX_LEN 1024 + +/* The hash function for the database. Hashed on extension. */ +#include <ctype.h> +#define CINFO_HASH(s) (isalpha(s[0]) ? tolower(s[0]) - 'a' : 26) + +/* The hash table size for that function */ +#define CINFO_HASHSIZE 27 + + +/* ------------------------------ Structures ------------------------------ */ + + +/* + * The ContentInfo structure. + * + * Currently, we support the following attributes: + * + * 1. Type: This identifies what kind of data is in the file. + * 2. Encoding: Identifies any compression or otherwise content-independent + * transformation which has been applied to the file (uuencode, etc.) + * 3. Language: Identifies the language a text document is in. + * 4. Description: A text string describing the file. + * 5. Viewer: The program to use to view the file. + * + * Multiple items are separated with a comma, e.g. + * encoding="x-gzip, x-uuencode" + */ + +typedef struct { + char *type; + char *encoding; + char *language; +} cinfo; + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * cinfo_init initializes the content info system. Call this before + * cinfo_merge. + */ + +void cinfo_init(void); + +/* + * cinfo_terminate frees the database for shutdown. + */ + +void cinfo_terminate(void); + +/* + * cinfo_merge merges the contents of the given filename with the current + * cinfo database. It returns NULL upon success and a string (which you + * must deallocate) upon error. + */ + +char *cinfo_merge(char *fn); + + +/* + * cinfo_find finds any content information for the given uri. The file name + * is the string following the last / in the uri. Multiple extensions are + * separated by CINFO_SEPARATOR. You may pass in a filename instead of uri. + * + * Returns a newly allocated cinfo structure with the information it + * finds. The elements of this structure are coming right out of the types + * database and so if you change it or want to keep it around for long you + * should strdup it. You should free only the structure itself when finished + * with it. + * + * If there is no information for any one of the extensions it + * finds, it will ignore that extension. If it cannot find information for + * any of the extensions, it will return NULL. + */ + +cinfo *cinfo_find(char *uri); + +/* + * cinfo_lookup finds the information about the given content-type, and + * returns a cinfo structure so you can look up description and icon. + */ + +cinfo *cinfo_lookup(char *type); + +/* + * cinfo_dump_database dumps the current database to the given file desc. + */ + +#include <stdio.h> +void cinfo_dump_database(FILE *dump); + + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/crit.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/crit.h new file mode 100644 index 00000000000..8511b058895 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/crit.h @@ -0,0 +1,127 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * crit.h: Critical section abstraction. Used in threaded servers to protect + * areas where two threads can interfere with each other. + * + * Condvars are condition variables that are used for thread-thread + * synchronization. + * + * Rob McCool + */ + +#ifndef CRIT_H +#define CRIT_H + + +#ifdef USE_NSPR +#include <nspr/prmon.h> +typedef PRMonitor* CRITICAL; +#else +typedef void *CRITICAL; +#endif + +/* + * crit_init creates and returns a new critical section variable. At the + * time of creation no one has entered it. + */ +#ifdef USE_NSPR +#define crit_init() PR_NewMonitor(0) +#else +#define crit_init() (0) +#endif + +/* + * crit_enter enters a critical section. If someone is already in the + * section, the calling thread is blocked until that thread exits. + */ +#ifdef USE_NSPR +#define crit_enter(id) PR_EnterMonitor(id) +#else +#define crit_enter(id) (0) +#endif + +/* + * crit_exit exits a critical section. If another thread is blocked waiting + * to enter, it will be unblocked and given ownership of the section. + */ +#ifdef USE_NSPR +#define crit_exit(id) PR_ExitMonitor(id) +#else +#define crit_exit(id) (0) +#endif + +/* + * crit_terminate removes a previously allocated critical section variable. + */ +#ifdef USE_NSPR +#define crit_terminate(id) PR_DestroyMonitor(id) +#else +#define crit_terminate(id) (0) +#endif + + +#ifdef USE_NSPR +typedef PRMonitor* CONDVAR; +#else +typedef void* CONDVAR; +#endif + +/* + * condvar_init initializes and returns a new condition variable. You + * must provide a critical section to be associated with this condition + * variable. + */ +#ifdef USE_NSPR +#define condvar_init(crit) (crit) +#else +#define condvar_init(crit) (crit) +#endif + +/* + * condvar_wait blocks on the given condition variable. The calling thread + * will be blocked until another thread calls condvar_notify on this variable. + * The caller must have entered the critical section associated with this + * condition variable prior to waiting for it. + */ +#ifdef USE_NSPR +#define condvar_wait(cv) (PR_Wait(cv, LL_MAXINT)) +#else +#define condvar_wait(cv) (0) +#endif + +/* + * condvar_notify awakens any threads blocked on the given condition + * variable. The caller must have entered the critical section associated + * with this variable first. + */ +#ifdef USE_NSPR +#define condvar_notify(cv) (PR_Notify(cv)) +#else +#define condvar_notify(cv) (0) +#endif + +/* + * condvar_terminate frees the given previously allocated condition variable + */ +#ifdef USE_NSPR +#define condvar_terminate(cv) (0) +#else +#define condvar_terminate(cv) (0) +#endif + + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/daemon.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/daemon.h new file mode 100644 index 00000000000..afe0cfe6e5e --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/daemon.h @@ -0,0 +1,120 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * daemon.h: Things related to the accepting connections + * + * Rob McCool + */ + + +#ifndef DAEMON_H +#define DAEMON_H + +#ifdef XP_WIN32 +#include <nt/ntdaemon.h> +#else + +#include "net.h" +#include "session.h" + +#include <pwd.h> /* struct passwd */ + + +/* ------------------------------- Defines -------------------------------- */ + + +#define child_exit exit + + +/* Codes for child_status */ +#define CHILD_EMPTY_SLOT 0xfe +#define CHILD_AWAIT_CONNECT 0xff +#define CHILD_PROCESSING 0x00 +#define CHILD_READING 0x01 +#define CHILD_WRITING 0x02 +#define CHILD_RESOLVING 0x03 + + +typedef struct { + char *ipstr; + int port; + struct passwd *pw; + char *chr; + char *pidfn; + void (*rcback)(int); +#if defined(DAEMON_UNIX_POOL) || defined(DAEMON_UNIX_MOBRULE) + int maxprocs, minprocs, proclife; +#endif +#ifdef NET_SSL + char *secure_keyfn; + char *secure_certfn; + char *secure_dongle; + int secure_auth; + int secure_session_timeout; + int security; +#endif +} daemon_s; + + +/* ------------------------------ Prototypes ------------------------------ */ + +#ifdef MCC_PROXY +/* A unique serial number assigned to each child. */ +extern int child_serial; +#endif + +/* + * daemon_run accepts whether or not it should detach from its parent process, + * and a daemon structure as its arguments. The daemon structure contains + * a port number, a root directory to chroot to (can be NULL), a filename to + * log the daemon pid to (can be NULL). daemon_run never returns. + * + * child_callback is a function which will be called every time a new + * connection is recieved. Session is a new session ID. + * + * rcback is a function which is a restart function: When SIGHUP is received, + * this function will be called. You may give SIG_DFL if you don't want to + * support restarting. The rcback will be passed SIGHUP. + * + * pw is the passwd entry to run the daemon as. If the effective user id is + * root, daemon_run will try to set its uid and gid to the user pointed + * to by this structure. You may pass NULL. + */ + +void daemon_run(int det, void (*child_callback)(Session *), daemon_s *d); + +/* + * fork is a wrapper for the system's fork function. This closes the listen + * socket for the mob. This also makes sure that a threaded daemon only gets + * the calling thread and not all of them. + */ + +pid_t child_fork(void); + + +/* + * Set status to the given code for statistics reporting + */ + +#ifdef DAEMON_STATS +void child_status(int code); +#else +#define child_status(code) (void)(code) +#endif + + +#endif +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/dll.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/dll.h new file mode 100644 index 00000000000..660de673845 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/dll.h @@ -0,0 +1,124 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * dll.h: Handle dynamically linked libraries + * + * Rob McCool + */ + +#ifndef _DLL_H +#define _DLL_H + +#include "systems.h" + +#if defined(DLL_CAPABLE) + +/* --------------------------- Data structures ---------------------------- */ + + +#if defined(USE_NSPR) +#include <nspr/prlink.h> +typedef int DLHANDLE; + +#elif defined(DLL_DLOPEN) +#include <dlfcn.h> +typedef void *DLHANDLE; /* DLOPEN */ + +#elif defined(DLL_HPSHL) +#include <dl.h> +typedef shl_t DLHANDLE; /* HP_SHL */ + +#elif defined(DLL_WIN32) +typedef HINSTANCE DLHANDLE; /* WIN32 */ +#endif + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * dll_open loads the library at the given path into memory, and returns + * a handle to be used in later calls to dll_findsym and dll_close. + */ +#if defined(USE_NSPR) +#define dll_open(libfn) PR_LoadLibrary(libfn) + +#elif defined(DLL_DLOPEN) +#define dll_open(libfn) dlopen(libfn, DLL_DLOPEN_FLAGS) + +#elif defined(DLL_HPSHL) +#define dll_open(libfn) shl_load((libfn), BIND_IMMEDIATE, 0) + +#elif defined(DLL_WIN32) +DLHANDLE dll_open(char *libfn); +#endif + + +/* + * dll_findsym looks for a symbol with the given name in the library + * pointed to by the given handle. Returns a pointer to the named function. + */ + +#if defined(USE_NSPR) +#define dll_findsym(dlp, name) PR_FindSymbol(name) + +#elif defined(DLL_DLOPEN) +#define dll_findsym(dlp, name) dlsym(dlp, name) + +#elif defined(DLL_HPSHL) +void *dll_findsym(DLHANDLE dlp, char *name); + +#elif defined(DLL_WIN32) +#define dll_findsym(dlp, name) GetProcAddress(dlp, name) +#endif + + +/* + * dll_error returns a string describing the last error on the given handle + */ +#if defined(USE_NSPR) +#define dll_error(dlp) system_errmsg(0) + +#elif defined(DLL_DLOPEN) +#define dll_error(dlp) dlerror() + +#elif defined(DLL_HPSHL) +#define dll_error(dlp) system_errmsg(0) + +#elif defined(DLL_WIN32) +#define dll_error(dlp) system_errmsg(0) +#endif + + +/* + * dll_close closes the previously opened library given by handle + */ +#if defined(USE_NSPR) +int dll_close(void *arg); + +#elif defined(DLL_DLOPEN) +#define dll_close dlclose + +#elif defined (DLL_HPSHL) +#define dll_close shl_unload + +#elif defined(DLL_WIN32) +#define dll_close FreeLibrary +#endif + + +#endif /* DLL_CAPABLE */ +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/ereport.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/ereport.h new file mode 100644 index 00000000000..b6ea5857e54 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/ereport.h @@ -0,0 +1,121 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * ereport.h: Records transactions, reports errors to administrators, etc. + * + * Rob McCool + */ + + +#ifndef EREPORT_H +#define EREPORT_H + + +#include "../base/session.h" /* Session structure */ +#ifdef XP_UNIX +#include <pwd.h> /* struct passwd */ +#endif /* XP_UNIX */ + + +/* ------------------------------ Constants ------------------------------- */ + + +/* + * The maximum length of an error message. NOT RUN-TIME CHECKED + */ + +#define MAX_ERROR_LEN 8192 + +/* A warning is a minor mishap, such as a 404 being issued. */ +#define LOG_WARN 0 + +/* + * A misconfig is when there is a syntax error or permission violation in + * a config. file. + */ +#define LOG_MISCONFIG 1 + +/* + * Security warnings are issued when authentication fails, or a host is + * given a 403 return code. + */ +#define LOG_SECURITY 2 + +/* + * A failure is when a request could not be fulfilled due to an internal + * problem, such as a CGI script exiting prematurely, or a filesystem + * permissions problem. + */ +#define LOG_FAILURE 3 + +/* + * A catastrophe is a fatal server error such as running out of + * memory or processes, or a system call failing, or even a server crash. + * The server child cannot recover from a catastrophe. + */ +#define LOG_CATASTROPHE 4 + +/* + * Informational message, of no concern. + */ +#define LOG_INFORM 5 + +/* + * The time format to use in the error log + */ + +#define ERR_TIMEFMT "[%d/%b/%Y:%H:%M:%S]" + + +/* The fd you will get if you are reporting errors to SYSLOG */ + +#define ERRORS_TO_SYSLOG -1 + + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * ereport logs an error of the given degree and formats the arguments with + * the printf() style fmt. Returns whether the log was successful. Records + * the current date. + */ + +int ereport(int degree, char *fmt, ...); + +/* + * ereport_init initializes the error logging subsystem and opens the static + * file descriptors. It returns NULL upon success and an error string upon + * error. If a userpw is given, the logs will be chowned to that user. + * + * email is the address of a person to mail upon catastrophic error. It + * can be NULL if no e-mail is desired. ereport_init will not duplicate + * its own copy of this string; you must make sure it stays around and free + * it when you shut down the server. + */ + +char *ereport_init(char *err_fn, char *email, struct passwd *pw); + +/* + * log_terminate closes the error and common log file descriptors. + */ +void ereport_terminate(void); + +/* For restarts */ +SYS_FILE ereport_getfd(void); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/eventlog.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/eventlog.h new file mode 100644 index 00000000000..ef2a1e12842 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/eventlog.h @@ -0,0 +1,61 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +// EVENTLOG.H +// +// This file contains the defines that make NT an installable service. +// +// 1/12/95 aruna +// + +// Functions in eventlog.c +// Win32 specific stuff, so FUZZ: disable check_for_tchar + +VOID InitializeAdminLogging(PCHAR ServiceName, PCHAR MessageFile); +VOID InitializeHttpdLogging(PCHAR ServiceName, PCHAR MessageFile); +VOID InitializeHttpsLogging(PCHAR ServiceName, PCHAR MessageFile); + +VOID TerminateAdminLogging(); +VOID TerminateHttpdLogging(); +VOID TerminateHttpsLogging(); + +VOID LogErrorEvent(PCHAR ServiceName, WORD fwEventType, WORD fwCategory, DWORD IDEvent, + LPTSTR chMsg, LPTSTR lpszMsg); + +// Functions in error.c + +VOID ReportError(PCHAR ErrorMsg); + +BOOL CALLBACK ErrorDialogProc( + HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam + ); + + + + + + + + + + + + + + + diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/file.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/file.h new file mode 100644 index 00000000000..34535963967 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/file.h @@ -0,0 +1,217 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * file.h: system specific functions for reading/writing files + * + * Rob McCool + */ + + +#ifndef FILE_H +#define FILE_H + +#ifdef XP_WIN32 +#include <nt/ntfile.h> +#else + + +#include "netsite.h" +#include "systems.h" + + +/* + * I cheat: These are set up such that system_read can be a macro for read + * under UNIX. IO_OKAY is anything positive. + */ + +#define IO_OKAY 1 +#define IO_ERROR -1 +#define IO_EOF 0 + + +#ifdef FILE_STDIO +#include <stdio.h> + +#elif defined(FILE_UNIX) +#include <sys/types.h> +#include <sys/file.h> +#include <fcntl.h> +#include <unistd.h> +#endif + + +/* -------------------------- File related defs --------------------------- */ + + +/* The disk page size on this machine. */ +#define FILE_BUFFERSIZE 4096 + + +/* + * The fd data type for this system. + */ + +#if defined(FILE_STDIO) +typedef FILE* SYS_FILE; +#define SYS_ERROR_FD 0 +#define SYS_STDERR stderr + +#elif defined(FILE_UNIX) +typedef int SYS_FILE; +#define SYS_ERROR_FD -1 +#define SYS_STDERR STDERR_FILENO + +#else +#error "undefined file typing for current system" +#endif + +#ifdef XP_UNIX +#define FILE_PATHSEP '/' +#define FILE_PARENT "../" + +#define system_chdir chdir +#endif + + +/* + * system_fread reads sz bytes from fd into to buf, return number of bytes + * read, or IO_EOF if EOF, or IO_ERROR if error. + */ + +#if defined(FILE_STDIO) +int system_fread(SYS_FILE fd, char *buf, int sz); + +#elif defined(FILE_UNIX) +#define system_fread(fd,buf,sz) read(fd,buf,sz) + +#endif + +/* + * system_fopenRO opens a given file for reading only + * system_fopenWA opens a given file for writing, appending new output + */ + +#if defined(FILE_STDIO) +#define system_fopenRO(path) fopen(path,"r") +#define system_fopenWA(path) fopen(path,"a") +#define system_fopenRW(path) fopen(path,"w") + +#elif defined(FILE_UNIX) +#define system_fopenRO(path) open(path, O_RDONLY) +#define system_fopenWA(path) \ + open(path, O_RDWR | O_CREAT | O_APPEND, 0644) +#define system_fopenRW(path) \ + open(path, O_RDWR | O_CREAT, 0644) + +#endif + + +/* + * system_fclose closes the file fd + */ + +#if defined(FILE_STDIO) +#define system_fclose(fd) fclose(fd) + +#elif defined(FILE_UNIX) +#define system_fclose(fd) close(fd) +#endif + +/* + * This call stops core dumps in a portable way. Returns -1 on error. + */ + +int system_nocoredumps(void); + + +#if defined(FILE_STDIO) +#define system_lseek fseek + +#elif defined(FILE_UNIX) +#define system_lseek lseek + +#endif + +/* + * system_write writes sz bytes from buf to fd. The handler function should + * handle partial writes and anything else like that. Returns IO_* + */ + +int system_fwrite(SYS_FILE fd,char *buf,int sz); + +/* + * system_fwrite_atomic locks the given fd before writing to it. This avoids + * interference between simultaneous writes. Returns IO_* + */ + +int system_fwrite_atomic(SYS_FILE fd, char *buf, int sz); + +/* + * system_errmsg returns the last error that occured while processing file + * descriptor fd. fd does not have to be specified (if the error is a global + * such as in UNIX systems). PPS: Rob is a halfwit. This parameter is useless. + */ + +#ifndef FILE_WIN32 +#include <errno.h> + +extern char *sys_errlist[]; +#define file_notfound() (errno == ENOENT) +#define system_errmsg(fd) (sys_errlist[errno]) +#endif + + +/* + * flock locks a file against interference from other processes + * ulock unlocks it. + */ +#ifdef BSD_FLOCK +#include <sys/file.h> +#define system_initlock(fd) (0) +#define system_flock(fd) flock(fd, LOCK_EX) +#define system_ulock(fd) flock(fd, LOCK_UN) + +#elif defined(FILE_UNIX) +#include <unistd.h> +#define system_initlock(fd) (0) +#define system_flock(fd) lockf(fd, F_LOCK, 0) +#define system_ulock(fd) lockf(fd, F_ULOCK, 0) + +#endif + + +/* + * unix2local converts a unix-style pathname to a local one + */ + +#ifdef XP_UNIX +#define file_unix2local(path,p2) strcpy(p2,path) +#endif + +/* -------------------------- Dir related defs ---------------------------- */ + + +#ifdef XP_UNIX +#include <dirent.h> +typedef DIR* SYS_DIR; +typedef struct dirent SYS_DIRENT; +#define dir_open opendir +#define dir_read readdir +#define dir_close closedir + +#endif +#endif +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/minissl.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/minissl.h new file mode 100644 index 00000000000..597e35a080e --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/minissl.h @@ -0,0 +1,27 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + + +/* Prototypes for SSL I/O functions */ +extern int SSL_Close(int); +extern int SSL_Socket(int, int, int); +extern int SSL_GetSockOpt(int, int, int, void *, int *); +extern int SSL_SetSockOpt(int, int, int, const void *, int); +extern int SSL_Bind(int, const void *, int); +extern int SSL_Listen(int, int); +extern int SSL_Accept(int, void *, int *); +extern int SSL_Read(int, void *, int); +extern int SSL_Write(int, const void *, int); +extern int SSL_GetPeerName(int, void *, int *); diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/net.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/net.h new file mode 100644 index 00000000000..44dfbdc68dc --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/net.h @@ -0,0 +1,180 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * net.h: system specific networking definitions + * + * Rob McCool + */ + + +#ifndef NET_H +#define NET_H + +#include "systems.h" + +#include "file.h" /* for client file descriptors */ + +#include "pblock.h" /* for client data block */ + + +/* This should be a user-given parameter later */ +#define NET_BUFFERSIZE 8192 +/* So should this. */ +#define NET_READ_TIMEOUT 120 +#define NET_WRITE_TIMEOUT 300 + +#define SSL_HANDSHAKE_TIMEOUT 300 + +#if defined(NET_SOCKETS) || defined(NET_SSL) + +#ifdef NET_WINSOCK +#include <winsock.h> +#else /* XP_UNIX */ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> /* sockaddr and in_addr */ +#include <arpa/inet.h> /* inet_ntoa */ +#include <netdb.h> /* hostent stuff */ +#endif /* NET_WINSOCK */ + +#ifdef NET_SSL +#include "minissl.h" +#endif + + +/* -------------------------------- Global -------------------------------- */ + +extern int net_enabledns; + + + +/* ------------------------------ Data types ------------------------------ */ + + +#ifdef NET_WINSOCK +typedef SOCKET SYS_NETFD; +#else /* XP_UNIX */ +typedef int SYS_NETFD; +#endif /* NET_WINSOCK */ + +#define SYS_NET_ERRORFD -1 + + +/* -------------------------------- Macros -------------------------------- */ + + +/* These may be different for non-UNIX systems. */ + + +#ifndef NET_SSL +#define net_socket socket +#define net_setsockopt setsockopt +#define net_getsockopt getsockopt +#define net_listen listen +#define net_select select +#define net_getpeername getpeername + +#ifndef NET_WINSOCK +#define net_close(sd) close(sd) +#define net_bind bind +#else /* NET_WINSOCK */ +#define net_close(sd) closesocket(sd) +#define system_netbind bind +int net_bind(SYS_NETFD s, const struct sockaddr *name, int namelen); +#endif /* NET_WINSOCK */ + +#ifdef DAEMON_NEEDS_SEMAPHORE +#define net_accept net_semaccept +#else /* ! DAEMON_NEEDS_SEMAPHORE */ +#define net_accept accept +#endif /* DAEMON_NEEDS_SEMAPHORE */ + +#else /* NET_SSL */ +#define net_close(sd) SSL_Close(sd) +#define net_socket SSL_Socket +#define net_setsockopt SSL_SetSockOpt +#define net_getsockopt SSL_GetSockOpt + +#ifdef XP_UNIX +#define net_bind SSL_Bind +#else /* WIN32 */ +#define system_netbind SSL_Bind +int net_bind(SYS_NETFD s, const struct sockaddr *name, int namelen); +#endif /* XP_UNIX */ + +#define net_listen SSL_Listen +#define net_select select /* !!! */ +#define net_getpeername SSL_GetPeerName +#define net_accept SSL_Accept +#endif /* ! NET_SSL */ + + +/* Users should never call the system_net* functions. */ +#ifdef NET_SSL +#define system_netread(sd, buf, sz) SSL_Read(sd, buf, sz) +#define system_netwrite SSL_Write +#else /* ! NET_SSL */ + +#if !defined(NET_WINSOCK) +#define system_netread(sd, buf, sz) read(sd, buf, sz) +#define system_netwrite write +#else /* NET_WINSOCK */ +#define system_netread(sd, buf, sz) recv(sd, buf, sz, 0) +#define system_netwrite(sd, buf, sz) send(sd, buf, sz, 0) +#endif /* ! NET_WINSOCK */ + +#endif /* NET_SSL */ + +int net_read(SYS_NETFD sd, char *buf, int sz, int timeout); +int net_write(SYS_NETFD sd, char *buf, int sz); + +#ifdef DAEMON_NEEDS_SEMAPHORE +int net_semaccept_init(int port); +int net_semaccept(int s, struct sockaddr *addr, int *addrlen); +void net_semaccept_terminate(void); +#endif + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * net_find_fqdn looks through the given hostent structure trying to find + * a FQDN for the host. If it finds none, it returns NULL. Otherwise, it + * returns a newly allocated copy of that string. + */ + +char *net_find_fqdn(struct hostent *p); + +/* + * net_ip2host transforms the given textual IP number into a FQDN. If it + * can't find a FQDN, it will return what it can get. Otherwise, NULL. + * + * verify is whether or not the function should verify the hostname it + * gets. This takes an extra query but is safer for use in access control. + */ + +char *net_ip2host(char *ip, int verify); + +/* + * net_sendmail sends mail to the specified recipient with the given subject + * and message. Currently uses external programs. + */ + +int net_sendmail(char *to, char *subject, char *msg); + +#endif +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/nodelock.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/nodelock.h new file mode 100644 index 00000000000..619c1df2621 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/nodelock.h @@ -0,0 +1,47 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * nodelock.h: licensing stuff + */ + +#ifndef _NODELOCK_H +#define _NODELOCK_H + +/* + * Do the initial IP address check and expiration date check. Reads a file + * from admin/config, as #define'd. + * + * Returns 1 on error, 0 on AOK. + */ + +int node_init(void); + +/* + * Check the expiration date against The Now. + * + * Returns 1 on error, 0 on AOK. + */ + +int node_check(void); + +/* + * So how we doin, license + * + * Returns 1 on error, 0 on AOK + */ +int node_status(void); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/nterrors.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/nterrors.h new file mode 100644 index 00000000000..5e0f109f711 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/nterrors.h @@ -0,0 +1,738 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* DO NOT EDIT THIS FILE - it is automatically generated */ + +struct _NtError { + int ErrorNumber; + char *ErrorString; + struct _NtError *next; +} ; + +typedef struct _NtError NtError; + +NtError NtErrorStrings[] = { +{ 0 , "ERROR_SUCCESS" }, +{ 0 , "NO_ERROR" }, +{ 1 , "ERROR_INVALID_FUNCTION" }, +{ 2 , "ERROR_FILE_NOT_FOUND" }, +{ 3 , "ERROR_PATH_NOT_FOUND" }, +{ 4 , "ERROR_TOO_MANY_OPEN_FILES" }, +{ 5 , "ERROR_ACCESS_DENIED" }, +{ 6 , "ERROR_INVALID_HANDLE" }, +{ 7 , "ERROR_ARENA_TRASHED" }, +{ 8 , "ERROR_NOT_ENOUGH_MEMORY" }, +{ 9 , "ERROR_INVALID_BLOCK" }, +{ 10 , "ERROR_BAD_ENVIRONMENT" }, +{ 11 , "ERROR_BAD_FORMAT" }, +{ 12 , "ERROR_INVALID_ACCESS" }, +{ 13 , "ERROR_INVALID_DATA" }, +{ 14 , "ERROR_OUTOFMEMORY" }, +{ 15 , "ERROR_INVALID_DRIVE" }, +{ 16 , "ERROR_CURRENT_DIRECTORY" }, +{ 17 , "ERROR_NOT_SAME_DEVICE" }, +{ 18 , "ERROR_NO_MORE_FILES" }, +{ 19 , "ERROR_WRITE_PROTECT" }, +{ 20 , "ERROR_BAD_UNIT" }, +{ 21 , "ERROR_NOT_READY" }, +{ 22 , "ERROR_BAD_COMMAND" }, +{ 23 , "ERROR_CRC" }, +{ 24 , "ERROR_BAD_LENGTH" }, +{ 25 , "ERROR_SEEK" }, +{ 26 , "ERROR_NOT_DOS_DISK" }, +{ 27 , "ERROR_SECTOR_NOT_FOUND" }, +{ 28 , "ERROR_OUT_OF_PAPER" }, +{ 29 , "ERROR_WRITE_FAULT" }, +{ 30 , "ERROR_READ_FAULT" }, +{ 31 , "ERROR_GEN_FAILURE" }, +{ 32 , "ERROR_SHARING_VIOLATION" }, +{ 33 , "ERROR_LOCK_VIOLATION" }, +{ 34 , "ERROR_WRONG_DISK" }, +{ 36 , "ERROR_SHARING_BUFFER_EXCEEDED" }, +{ 38 , "ERROR_HANDLE_EOF" }, +{ 39 , "ERROR_HANDLE_DISK_FULL" }, +{ 50 , "ERROR_NOT_SUPPORTED" }, +{ 51 , "ERROR_REM_NOT_LIST" }, +{ 52 , "ERROR_DUP_NAME" }, +{ 53 , "ERROR_BAD_NETPATH" }, +{ 54 , "ERROR_NETWORK_BUSY" }, +{ 55 , "ERROR_DEV_NOT_EXIST" }, +{ 56 , "ERROR_TOO_MANY_CMDS" }, +{ 57 , "ERROR_ADAP_HDW_ERR" }, +{ 58 , "ERROR_BAD_NET_RESP" }, +{ 59 , "ERROR_UNEXP_NET_ERR" }, +{ 60 , "ERROR_BAD_REM_ADAP" }, +{ 61 , "ERROR_PRINTQ_FULL" }, +{ 62 , "ERROR_NO_SPOOL_SPACE" }, +{ 63 , "ERROR_PRINT_CANCELLED" }, +{ 64 , "ERROR_NETNAME_DELETED" }, +{ 65 , "ERROR_NETWORK_ACCESS_DENIED" }, +{ 66 , "ERROR_BAD_DEV_TYPE" }, +{ 67 , "ERROR_BAD_NET_NAME" }, +{ 68 , "ERROR_TOO_MANY_NAMES" }, +{ 69 , "ERROR_TOO_MANY_SESS" }, +{ 70 , "ERROR_SHARING_PAUSED" }, +{ 71 , "ERROR_REQ_NOT_ACCEP" }, +{ 72 , "ERROR_REDIR_PAUSED" }, +{ 80 , "ERROR_FILE_EXISTS" }, +{ 82 , "ERROR_CANNOT_MAKE" }, +{ 83 , "ERROR_FAIL_I24" }, +{ 84 , "ERROR_OUT_OF_STRUCTURES" }, +{ 85 , "ERROR_ALREADY_ASSIGNED" }, +{ 86 , "ERROR_INVALID_PASSWORD" }, +{ 87 , "ERROR_INVALID_PARAMETER" }, +{ 88 , "ERROR_NET_WRITE_FAULT" }, +{ 89 , "ERROR_NO_PROC_SLOTS" }, +{ 100 , "ERROR_TOO_MANY_SEMAPHORES" }, +{ 101 , "ERROR_EXCL_SEM_ALREADY_OWNED" }, +{ 102 , "ERROR_SEM_IS_SET" }, +{ 103 , "ERROR_TOO_MANY_SEM_REQUESTS" }, +{ 104 , "ERROR_INVALID_AT_INTERRUPT_TIME" }, +{ 105 , "ERROR_SEM_OWNER_DIED" }, +{ 106 , "ERROR_SEM_USER_LIMIT" }, +{ 107 , "ERROR_DISK_CHANGE" }, +{ 108 , "ERROR_DRIVE_LOCKED" }, +{ 109 , "ERROR_BROKEN_PIPE" }, +{ 110 , "ERROR_OPEN_FAILED" }, +{ 111 , "ERROR_BUFFER_OVERFLOW" }, +{ 112 , "ERROR_DISK_FULL" }, +{ 113 , "ERROR_NO_MORE_SEARCH_HANDLES" }, +{ 114 , "ERROR_INVALID_TARGET_HANDLE" }, +{ 117 , "ERROR_INVALID_CATEGORY" }, +{ 118 , "ERROR_INVALID_VERIFY_SWITCH" }, +{ 119 , "ERROR_BAD_DRIVER_LEVEL" }, +{ 120 , "ERROR_CALL_NOT_IMPLEMENTED" }, +{ 121 , "ERROR_SEM_TIMEOUT" }, +{ 122 , "ERROR_INSUFFICIENT_BUFFER" }, +{ 123 , "ERROR_INVALID_NAME" }, +{ 124 , "ERROR_INVALID_LEVEL" }, +{ 125 , "ERROR_NO_VOLUME_LABEL" }, +{ 126 , "ERROR_MOD_NOT_FOUND" }, +{ 127 , "ERROR_PROC_NOT_FOUND" }, +{ 128 , "ERROR_WAIT_NO_CHILDREN" }, +{ 129 , "ERROR_CHILD_NOT_COMPLETE" }, +{ 130 , "ERROR_DIRECT_ACCESS_HANDLE" }, +{ 131 , "ERROR_NEGATIVE_SEEK" }, +{ 132 , "ERROR_SEEK_ON_DEVICE" }, +{ 133 , "ERROR_IS_JOIN_TARGET" }, +{ 134 , "ERROR_IS_JOINED" }, +{ 135 , "ERROR_IS_SUBSTED" }, +{ 136 , "ERROR_NOT_JOINED" }, +{ 137 , "ERROR_NOT_SUBSTED" }, +{ 138 , "ERROR_JOIN_TO_JOIN" }, +{ 139 , "ERROR_SUBST_TO_SUBST" }, +{ 140 , "ERROR_JOIN_TO_SUBST" }, +{ 141 , "ERROR_SUBST_TO_JOIN" }, +{ 142 , "ERROR_BUSY_DRIVE" }, +{ 143 , "ERROR_SAME_DRIVE" }, +{ 144 , "ERROR_DIR_NOT_ROOT" }, +{ 145 , "ERROR_DIR_NOT_EMPTY" }, +{ 146 , "ERROR_IS_SUBST_PATH" }, +{ 147 , "ERROR_IS_JOIN_PATH" }, +{ 148 , "ERROR_PATH_BUSY" }, +{ 149 , "ERROR_IS_SUBST_TARGET" }, +{ 150 , "ERROR_SYSTEM_TRACE" }, +{ 151 , "ERROR_INVALID_EVENT_COUNT" }, +{ 152 , "ERROR_TOO_MANY_MUXWAITERS" }, +{ 153 , "ERROR_INVALID_LIST_FORMAT" }, +{ 154 , "ERROR_LABEL_TOO_LONG" }, +{ 155 , "ERROR_TOO_MANY_TCBS" }, +{ 156 , "ERROR_SIGNAL_REFUSED" }, +{ 157 , "ERROR_DISCARDED" }, +{ 158 , "ERROR_NOT_LOCKED" }, +{ 159 , "ERROR_BAD_THREADID_ADDR" }, +{ 160 , "ERROR_BAD_ARGUMENTS" }, +{ 161 , "ERROR_BAD_PATHNAME" }, +{ 162 , "ERROR_SIGNAL_PENDING" }, +{ 164 , "ERROR_MAX_THRDS_REACHED" }, +{ 167 , "ERROR_LOCK_FAILED" }, +{ 170 , "ERROR_BUSY" }, +{ 173 , "ERROR_CANCEL_VIOLATION" }, +{ 174 , "ERROR_ATOMIC_LOCKS_NOT_SUPPORTED" }, +{ 180 , "ERROR_INVALID_SEGMENT_NUMBER" }, +{ 182 , "ERROR_INVALID_ORDINAL" }, +{ 183 , "ERROR_ALREADY_EXISTS" }, +{ 186 , "ERROR_INVALID_FLAG_NUMBER" }, +{ 187 , "ERROR_SEM_NOT_FOUND" }, +{ 188 , "ERROR_INVALID_STARTING_CODESEG" }, +{ 189 , "ERROR_INVALID_STACKSEG" }, +{ 190 , "ERROR_INVALID_MODULETYPE" }, +{ 191 , "ERROR_INVALID_EXE_SIGNATURE" }, +{ 192 , "ERROR_EXE_MARKED_INVALID" }, +{ 193 , "ERROR_BAD_EXE_FORMAT" }, +{ 194 , "ERROR_ITERATED_DATA_EXCEEDS_64k" }, +{ 195 , "ERROR_INVALID_MINALLOCSIZE" }, +{ 196 , "ERROR_DYNLINK_FROM_INVALID_RING" }, +{ 197 , "ERROR_IOPL_NOT_ENABLED" }, +{ 198 , "ERROR_INVALID_SEGDPL" }, +{ 199 , "ERROR_AUTODATASEG_EXCEEDS_64k" }, +{ 200 , "ERROR_RING2SEG_MUST_BE_MOVABLE" }, +{ 201 , "ERROR_RELOC_CHAIN_XEEDS_SEGLIM" }, +{ 202 , "ERROR_INFLOOP_IN_RELOC_CHAIN" }, +{ 203 , "ERROR_ENVVAR_NOT_FOUND" }, +{ 205 , "ERROR_NO_SIGNAL_SENT" }, +{ 206 , "ERROR_FILENAME_EXCED_RANGE" }, +{ 207 , "ERROR_RING2_STACK_IN_USE" }, +{ 208 , "ERROR_META_EXPANSION_TOO_LONG" }, +{ 209 , "ERROR_INVALID_SIGNAL_NUMBER" }, +{ 210 , "ERROR_THREAD_1_INACTIVE" }, +{ 212 , "ERROR_LOCKED" }, +{ 214 , "ERROR_TOO_MANY_MODULES" }, +{ 215 , "ERROR_NESTING_NOT_ALLOWED" }, +{ 230 , "ERROR_BAD_PIPE" }, +{ 231 , "ERROR_PIPE_BUSY" }, +{ 232 , "ERROR_NO_DATA" }, +{ 233 , "ERROR_PIPE_NOT_CONNECTED" }, +{ 234 , "ERROR_MORE_DATA" }, +{ 240 , "ERROR_VC_DISCONNECTED" }, +{ 254 , "ERROR_INVALID_EA_NAME" }, +{ 255 , "ERROR_EA_LIST_INCONSISTENT" }, +{ 259 , "ERROR_NO_MORE_ITEMS" }, +{ 266 , "ERROR_CANNOT_COPY" }, +{ 267 , "ERROR_DIRECTORY" }, +{ 275 , "ERROR_EAS_DIDNT_FIT" }, +{ 276 , "ERROR_EA_FILE_CORRUPT" }, +{ 277 , "ERROR_EA_TABLE_FULL" }, +{ 278 , "ERROR_INVALID_EA_HANDLE" }, +{ 282 , "ERROR_EAS_NOT_SUPPORTED" }, +{ 288 , "ERROR_NOT_OWNER" }, +{ 298 , "ERROR_TOO_MANY_POSTS" }, +{ 299 , "ERROR_PARTIAL_COPY" }, +{ 317 , "ERROR_MR_MID_NOT_FOUND" }, +{ 487 , "ERROR_INVALID_ADDRESS" }, +{ 534 , "ERROR_ARITHMETIC_OVERFLOW" }, +{ 535 , "ERROR_PIPE_CONNECTED" }, +{ 536 , "ERROR_PIPE_LISTENING" }, +{ 994 , "ERROR_EA_ACCESS_DENIED" }, +{ 995 , "ERROR_OPERATION_ABORTED" }, +{ 996 , "ERROR_IO_INCOMPLETE" }, +{ 997 , "ERROR_IO_PENDING" }, +{ 998 , "ERROR_NOACCESS" }, +{ 999 , "ERROR_SWAPERROR" }, +{ 1001 , "ERROR_STACK_OVERFLOW" }, +{ 1002 , "ERROR_INVALID_MESSAGE" }, +{ 1003 , "ERROR_CAN_NOT_COMPLETE" }, +{ 1004 , "ERROR_INVALID_FLAGS" }, +{ 1005 , "ERROR_UNRECOGNIZED_VOLUME" }, +{ 1006 , "ERROR_FILE_INVALID" }, +{ 1007 , "ERROR_FULLSCREEN_MODE" }, +{ 1008 , "ERROR_NO_TOKEN" }, +{ 1009 , "ERROR_BADDB" }, +{ 1010 , "ERROR_BADKEY" }, +{ 1011 , "ERROR_CANTOPEN" }, +{ 1012 , "ERROR_CANTREAD" }, +{ 1013 , "ERROR_CANTWRITE" }, +{ 1014 , "ERROR_REGISTRY_RECOVERED" }, +{ 1015 , "ERROR_REGISTRY_CORRUPT" }, +{ 1016 , "ERROR_REGISTRY_IO_FAILED" }, +{ 1017 , "ERROR_NOT_REGISTRY_FILE" }, +{ 1018 , "ERROR_KEY_DELETED" }, +{ 1019 , "ERROR_NO_LOG_SPACE" }, +{ 1020 , "ERROR_KEY_HAS_CHILDREN" }, +{ 1021 , "ERROR_CHILD_MUST_BE_VOLATILE" }, +{ 1022 , "ERROR_NOTIFY_ENUM_DIR" }, +{ 1051 , "ERROR_DEPENDENT_SERVICES_RUNNING" }, +{ 1052 , "ERROR_INVALID_SERVICE_CONTROL" }, +{ 1053 , "ERROR_SERVICE_REQUEST_TIMEOUT" }, +{ 1054 , "ERROR_SERVICE_NO_THREAD" }, +{ 1055 , "ERROR_SERVICE_DATABASE_LOCKED" }, +{ 1056 , "ERROR_SERVICE_ALREADY_RUNNING" }, +{ 1057 , "ERROR_INVALID_SERVICE_ACCOUNT" }, +{ 1058 , "ERROR_SERVICE_DISABLED" }, +{ 1059 , "ERROR_CIRCULAR_DEPENDENCY" }, +{ 1060 , "ERROR_SERVICE_DOES_NOT_EXIST" }, +{ 1061 , "ERROR_SERVICE_CANNOT_ACCEPT_CTRL" }, +{ 1062 , "ERROR_SERVICE_NOT_ACTIVE" }, +{ 1063 , "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT" }, +{ 1064 , "ERROR_EXCEPTION_IN_SERVICE" }, +{ 1065 , "ERROR_DATABASE_DOES_NOT_EXIST" }, +{ 1066 , "ERROR_SERVICE_SPECIFIC_ERROR" }, +{ 1067 , "ERROR_PROCESS_ABORTED" }, +{ 1068 , "ERROR_SERVICE_DEPENDENCY_FAIL" }, +{ 1069 , "ERROR_SERVICE_LOGON_FAILED" }, +{ 1070 , "ERROR_SERVICE_START_HANG" }, +{ 1071 , "ERROR_INVALID_SERVICE_LOCK" }, +{ 1072 , "ERROR_SERVICE_MARKED_FOR_DELETE" }, +{ 1073 , "ERROR_SERVICE_EXISTS" }, +{ 1074 , "ERROR_ALREADY_RUNNING_LKG" }, +{ 1075 , "ERROR_SERVICE_DEPENDENCY_DELETED" }, +{ 1076 , "ERROR_BOOT_ALREADY_ACCEPTED" }, +{ 1077 , "ERROR_SERVICE_NEVER_STARTED" }, +{ 1078 , "ERROR_DUPLICATE_SERVICE_NAME" }, +{ 1100 , "ERROR_END_OF_MEDIA" }, +{ 1101 , "ERROR_FILEMARK_DETECTED" }, +{ 1102 , "ERROR_BEGINNING_OF_MEDIA" }, +{ 1103 , "ERROR_SETMARK_DETECTED" }, +{ 1104 , "ERROR_NO_DATA_DETECTED" }, +{ 1105 , "ERROR_PARTITION_FAILURE" }, +{ 1106 , "ERROR_INVALID_BLOCK_LENGTH" }, +{ 1107 , "ERROR_DEVICE_NOT_PARTITIONED" }, +{ 1108 , "ERROR_UNABLE_TO_LOCK_MEDIA" }, +{ 1109 , "ERROR_UNABLE_TO_UNLOAD_MEDIA" }, +{ 1110 , "ERROR_MEDIA_CHANGED" }, +{ 1111 , "ERROR_BUS_RESET" }, +{ 1112 , "ERROR_NO_MEDIA_IN_DRIVE" }, +{ 1113 , "ERROR_NO_UNICODE_TRANSLATION" }, +{ 1114 , "ERROR_DLL_INIT_FAILED" }, +{ 1115 , "ERROR_SHUTDOWN_IN_PROGRESS" }, +{ 1116 , "ERROR_NO_SHUTDOWN_IN_PROGRESS" }, +{ 1117 , "ERROR_IO_DEVICE" }, +{ 1118 , "ERROR_SERIAL_NO_DEVICE" }, +{ 1119 , "ERROR_IRQ_BUSY" }, +{ 1120 , "ERROR_MORE_WRITES" }, +{ 1121 , "ERROR_COUNTER_TIMEOUT" }, +{ 1122 , "ERROR_FLOPPY_ID_MARK_NOT_FOUND" }, +{ 1123 , "ERROR_FLOPPY_WRONG_CYLINDER" }, +{ 1124 , "ERROR_FLOPPY_UNKNOWN_ERROR" }, +{ 1125 , "ERROR_FLOPPY_BAD_REGISTERS" }, +{ 1126 , "ERROR_DISK_RECALIBRATE_FAILED" }, +{ 1127 , "ERROR_DISK_OPERATION_FAILED" }, +{ 1128 , "ERROR_DISK_RESET_FAILED" }, +{ 1129 , "ERROR_EOM_OVERFLOW" }, +{ 1130 , "ERROR_NOT_ENOUGH_SERVER_MEMORY" }, +{ 1131 , "ERROR_POSSIBLE_DEADLOCK" }, +{ 1132 , "ERROR_MAPPED_ALIGNMENT" }, +{ 1140 , "ERROR_SET_POWER_STATE_VETOED" }, +{ 1141 , "ERROR_SET_POWER_STATE_FAILED" }, +{ 1150 , "ERROR_OLD_WIN_VERSION" }, +{ 1151 , "ERROR_APP_WRONG_OS" }, +{ 1152 , "ERROR_SINGLE_INSTANCE_APP" }, +{ 1153 , "ERROR_RMODE_APP" }, +{ 1154 , "ERROR_INVALID_DLL" }, +{ 1155 , "ERROR_NO_ASSOCIATION" }, +{ 1156 , "ERROR_DDE_FAIL" }, +{ 1157 , "ERROR_DLL_NOT_FOUND" }, +{ 2202 , "ERROR_BAD_USERNAME" }, +{ 2250 , "ERROR_NOT_CONNECTED" }, +{ 2401 , "ERROR_OPEN_FILES" }, +{ 2402 , "ERROR_ACTIVE_CONNECTIONS" }, +{ 2404 , "ERROR_DEVICE_IN_USE" }, +{ 1200 , "ERROR_BAD_DEVICE" }, +{ 1201 , "ERROR_CONNECTION_UNAVAIL" }, +{ 1202 , "ERROR_DEVICE_ALREADY_REMEMBERED" }, +{ 1203 , "ERROR_NO_NET_OR_BAD_PATH" }, +{ 1204 , "ERROR_BAD_PROVIDER" }, +{ 1205 , "ERROR_CANNOT_OPEN_PROFILE" }, +{ 1206 , "ERROR_BAD_PROFILE" }, +{ 1207 , "ERROR_NOT_CONTAINER" }, +{ 1208 , "ERROR_EXTENDED_ERROR" }, +{ 1209 , "ERROR_INVALID_GROUPNAME" }, +{ 1210 , "ERROR_INVALID_COMPUTERNAME" }, +{ 1211 , "ERROR_INVALID_EVENTNAME" }, +{ 1212 , "ERROR_INVALID_DOMAINNAME" }, +{ 1213 , "ERROR_INVALID_SERVICENAME" }, +{ 1214 , "ERROR_INVALID_NETNAME" }, +{ 1215 , "ERROR_INVALID_SHARENAME" }, +{ 1216 , "ERROR_INVALID_PASSWORDNAME" }, +{ 1217 , "ERROR_INVALID_MESSAGENAME" }, +{ 1218 , "ERROR_INVALID_MESSAGEDEST" }, +{ 1219 , "ERROR_SESSION_CREDENTIAL_CONFLICT" }, +{ 1220 , "ERROR_REMOTE_SESSION_LIMIT_EXCEEDED" }, +{ 1221 , "ERROR_DUP_DOMAINNAME" }, +{ 1222 , "ERROR_NO_NETWORK" }, +{ 1223 , "ERROR_CANCELLED" }, +{ 1224 , "ERROR_USER_MAPPED_FILE" }, +{ 1225 , "ERROR_CONNECTION_REFUSED" }, +{ 1226 , "ERROR_GRACEFUL_DISCONNECT" }, +{ 1227 , "ERROR_ADDRESS_ALREADY_ASSOCIATED" }, +{ 1228 , "ERROR_ADDRESS_NOT_ASSOCIATED" }, +{ 1229 , "ERROR_CONNECTION_INVALID" }, +{ 1230 , "ERROR_CONNECTION_ACTIVE" }, +{ 1231 , "ERROR_NETWORK_UNREACHABLE" }, +{ 1232 , "ERROR_HOST_UNREACHABLE" }, +{ 1233 , "ERROR_PROTOCOL_UNREACHABLE" }, +{ 1234 , "ERROR_PORT_UNREACHABLE" }, +{ 1235 , "ERROR_REQUEST_ABORTED" }, +{ 1236 , "ERROR_CONNECTION_ABORTED" }, +{ 1237 , "ERROR_RETRY" }, +{ 1238 , "ERROR_CONNECTION_COUNT_LIMIT" }, +{ 1239 , "ERROR_LOGIN_TIME_RESTRICTION" }, +{ 1240 , "ERROR_LOGIN_WKSTA_RESTRICTION" }, +{ 1241 , "ERROR_INCORRECT_ADDRESS" }, +{ 1242 , "ERROR_ALREADY_REGISTERED" }, +{ 1243 , "ERROR_SERVICE_NOT_FOUND" }, +{ 1244 , "ERROR_NOT_AUTHENTICATED" }, +{ 1245 , "ERROR_NOT_LOGGED_ON" }, +{ 1246 , "ERROR_CONTINUE" }, +{ 1247 , "ERROR_ALREADY_INITIALIZED" }, +{ 1248 , "ERROR_NO_MORE_DEVICES" }, +{ 1300 , "ERROR_NOT_ALL_ASSIGNED" }, +{ 1301 , "ERROR_SOME_NOT_MAPPED" }, +{ 1302 , "ERROR_NO_QUOTAS_FOR_ACCOUNT" }, +{ 1303 , "ERROR_LOCAL_USER_SESSION_KEY" }, +{ 1304 , "ERROR_NULL_LM_PASSWORD" }, +{ 1305 , "ERROR_UNKNOWN_REVISION" }, +{ 1306 , "ERROR_REVISION_MISMATCH" }, +{ 1307 , "ERROR_INVALID_OWNER" }, +{ 1308 , "ERROR_INVALID_PRIMARY_GROUP" }, +{ 1309 , "ERROR_NO_IMPERSONATION_TOKEN" }, +{ 1310 , "ERROR_CANT_DISABLE_MANDATORY" }, +{ 1311 , "ERROR_NO_LOGON_SERVERS" }, +{ 1312 , "ERROR_NO_SUCH_LOGON_SESSION" }, +{ 1313 , "ERROR_NO_SUCH_PRIVILEGE" }, +{ 1314 , "ERROR_PRIVILEGE_NOT_HELD" }, +{ 1315 , "ERROR_INVALID_ACCOUNT_NAME" }, +{ 1316 , "ERROR_USER_EXISTS" }, +{ 1317 , "ERROR_NO_SUCH_USER" }, +{ 1318 , "ERROR_GROUP_EXISTS" }, +{ 1319 , "ERROR_NO_SUCH_GROUP" }, +{ 1320 , "ERROR_MEMBER_IN_GROUP" }, +{ 1321 , "ERROR_MEMBER_NOT_IN_GROUP" }, +{ 1322 , "ERROR_LAST_ADMIN" }, +{ 1323 , "ERROR_WRONG_PASSWORD" }, +{ 1324 , "ERROR_ILL_FORMED_PASSWORD" }, +{ 1325 , "ERROR_PASSWORD_RESTRICTION" }, +{ 1326 , "ERROR_LOGON_FAILURE" }, +{ 1327 , "ERROR_ACCOUNT_RESTRICTION" }, +{ 1328 , "ERROR_INVALID_LOGON_HOURS" }, +{ 1329 , "ERROR_INVALID_WORKSTATION" }, +{ 1330 , "ERROR_PASSWORD_EXPIRED" }, +{ 1331 , "ERROR_ACCOUNT_DISABLED" }, +{ 1332 , "ERROR_NONE_MAPPED" }, +{ 1333 , "ERROR_TOO_MANY_LUIDS_REQUESTED" }, +{ 1334 , "ERROR_LUIDS_EXHAUSTED" }, +{ 1335 , "ERROR_INVALID_SUB_AUTHORITY" }, +{ 1336 , "ERROR_INVALID_ACL" }, +{ 1337 , "ERROR_INVALID_SID" }, +{ 1338 , "ERROR_INVALID_SECURITY_DESCR" }, +{ 1340 , "ERROR_BAD_INHERITANCE_ACL" }, +{ 1341 , "ERROR_SERVER_DISABLED" }, +{ 1342 , "ERROR_SERVER_NOT_DISABLED" }, +{ 1343 , "ERROR_INVALID_ID_AUTHORITY" }, +{ 1344 , "ERROR_ALLOTTED_SPACE_EXCEEDED" }, +{ 1345 , "ERROR_INVALID_GROUP_ATTRIBUTES" }, +{ 1346 , "ERROR_BAD_IMPERSONATION_LEVEL" }, +{ 1347 , "ERROR_CANT_OPEN_ANONYMOUS" }, +{ 1348 , "ERROR_BAD_VALIDATION_CLASS" }, +{ 1349 , "ERROR_BAD_TOKEN_TYPE" }, +{ 1350 , "ERROR_NO_SECURITY_ON_OBJECT" }, +{ 1351 , "ERROR_CANT_ACCESS_DOMAIN_INFO" }, +{ 1352 , "ERROR_INVALID_SERVER_STATE" }, +{ 1353 , "ERROR_INVALID_DOMAIN_STATE" }, +{ 1354 , "ERROR_INVALID_DOMAIN_ROLE" }, +{ 1355 , "ERROR_NO_SUCH_DOMAIN" }, +{ 1356 , "ERROR_DOMAIN_EXISTS" }, +{ 1357 , "ERROR_DOMAIN_LIMIT_EXCEEDED" }, +{ 1358 , "ERROR_INTERNAL_DB_CORRUPTION" }, +{ 1359 , "ERROR_INTERNAL_ERROR" }, +{ 1360 , "ERROR_GENERIC_NOT_MAPPED" }, +{ 1361 , "ERROR_BAD_DESCRIPTOR_FORMAT" }, +{ 1362 , "ERROR_NOT_LOGON_PROCESS" }, +{ 1363 , "ERROR_LOGON_SESSION_EXISTS" }, +{ 1364 , "ERROR_NO_SUCH_PACKAGE" }, +{ 1365 , "ERROR_BAD_LOGON_SESSION_STATE" }, +{ 1366 , "ERROR_LOGON_SESSION_COLLISION" }, +{ 1367 , "ERROR_INVALID_LOGON_TYPE" }, +{ 1368 , "ERROR_CANNOT_IMPERSONATE" }, +{ 1369 , "ERROR_RXACT_INVALID_STATE" }, +{ 1370 , "ERROR_RXACT_COMMIT_FAILURE" }, +{ 1371 , "ERROR_SPECIAL_ACCOUNT" }, +{ 1372 , "ERROR_SPECIAL_GROUP" }, +{ 1373 , "ERROR_SPECIAL_USER" }, +{ 1374 , "ERROR_MEMBERS_PRIMARY_GROUP" }, +{ 1375 , "ERROR_TOKEN_ALREADY_IN_USE" }, +{ 1376 , "ERROR_NO_SUCH_ALIAS" }, +{ 1377 , "ERROR_MEMBER_NOT_IN_ALIAS" }, +{ 1378 , "ERROR_MEMBER_IN_ALIAS" }, +{ 1379 , "ERROR_ALIAS_EXISTS" }, +{ 1380 , "ERROR_LOGON_NOT_GRANTED" }, +{ 1381 , "ERROR_TOO_MANY_SECRETS" }, +{ 1382 , "ERROR_SECRET_TOO_LONG" }, +{ 1383 , "ERROR_INTERNAL_DB_ERROR" }, +{ 1384 , "ERROR_TOO_MANY_CONTEXT_IDS" }, +{ 1385 , "ERROR_LOGON_TYPE_NOT_GRANTED" }, +{ 1386 , "ERROR_NT_CROSS_ENCRYPTION_REQUIRED" }, +{ 1387 , "ERROR_NO_SUCH_MEMBER" }, +{ 1388 , "ERROR_INVALID_MEMBER" }, +{ 1389 , "ERROR_TOO_MANY_SIDS" }, +{ 1390 , "ERROR_LM_CROSS_ENCRYPTION_REQUIRED" }, +{ 1391 , "ERROR_NO_INHERITANCE" }, +{ 1392 , "ERROR_FILE_CORRUPT" }, +{ 1393 , "ERROR_DISK_CORRUPT" }, +{ 1394 , "ERROR_NO_USER_SESSION_KEY" }, +{ 1395 , "ERROR_LICENSE_QUOTA_EXCEEDED" }, +{ 1400 , "ERROR_INVALID_WINDOW_HANDLE" }, +{ 1401 , "ERROR_INVALID_MENU_HANDLE" }, +{ 1402 , "ERROR_INVALID_CURSOR_HANDLE" }, +{ 1403 , "ERROR_INVALID_ACCEL_HANDLE" }, +{ 1404 , "ERROR_INVALID_HOOK_HANDLE" }, +{ 1405 , "ERROR_INVALID_DWP_HANDLE" }, +{ 1406 , "ERROR_TLW_WITH_WSCHILD" }, +{ 1407 , "ERROR_CANNOT_FIND_WND_CLASS" }, +{ 1408 , "ERROR_WINDOW_OF_OTHER_THREAD" }, +{ 1409 , "ERROR_HOTKEY_ALREADY_REGISTERED" }, +{ 1410 , "ERROR_CLASS_ALREADY_EXISTS" }, +{ 1411 , "ERROR_CLASS_DOES_NOT_EXIST" }, +{ 1412 , "ERROR_CLASS_HAS_WINDOWS" }, +{ 1413 , "ERROR_INVALID_INDEX" }, +{ 1414 , "ERROR_INVALID_ICON_HANDLE" }, +{ 1415 , "ERROR_PRIVATE_DIALOG_INDEX" }, +{ 1416 , "ERROR_LISTBOX_ID_NOT_FOUND" }, +{ 1417 , "ERROR_NO_WILDCARD_CHARACTERS" }, +{ 1418 , "ERROR_CLIPBOARD_NOT_OPEN" }, +{ 1419 , "ERROR_HOTKEY_NOT_REGISTERED" }, +{ 1420 , "ERROR_WINDOW_NOT_DIALOG" }, +{ 1421 , "ERROR_CONTROL_ID_NOT_FOUND" }, +{ 1422 , "ERROR_INVALID_COMBOBOX_MESSAGE" }, +{ 1423 , "ERROR_WINDOW_NOT_COMBOBOX" }, +{ 1424 , "ERROR_INVALID_EDIT_HEIGHT" }, +{ 1425 , "ERROR_DC_NOT_FOUND" }, +{ 1426 , "ERROR_INVALID_HOOK_FILTER" }, +{ 1427 , "ERROR_INVALID_FILTER_PROC" }, +{ 1428 , "ERROR_HOOK_NEEDS_HMOD" }, +{ 1429 , "ERROR_GLOBAL_ONLY_HOOK" }, +{ 1430 , "ERROR_JOURNAL_HOOK_SET" }, +{ 1431 , "ERROR_HOOK_NOT_INSTALLED" }, +{ 1432 , "ERROR_INVALID_LB_MESSAGE" }, +{ 1433 , "ERROR_SETCOUNT_ON_BAD_LB" }, +{ 1434 , "ERROR_LB_WITHOUT_TABSTOPS" }, +{ 1435 , "ERROR_DESTROY_OBJECT_OF_OTHER_THREAD" }, +{ 1436 , "ERROR_CHILD_WINDOW_MENU" }, +{ 1437 , "ERROR_NO_SYSTEM_MENU" }, +{ 1438 , "ERROR_INVALID_MSGBOX_STYLE" }, +{ 1439 , "ERROR_INVALID_SPI_VALUE" }, +{ 1440 , "ERROR_SCREEN_ALREADY_LOCKED" }, +{ 1441 , "ERROR_HWNDS_HAVE_DIFF_PARENT" }, +{ 1442 , "ERROR_NOT_CHILD_WINDOW" }, +{ 1443 , "ERROR_INVALID_GW_COMMAND" }, +{ 1444 , "ERROR_INVALID_THREAD_ID" }, +{ 1445 , "ERROR_NON_MDICHILD_WINDOW" }, +{ 1446 , "ERROR_POPUP_ALREADY_ACTIVE" }, +{ 1447 , "ERROR_NO_SCROLLBARS" }, +{ 1448 , "ERROR_INVALID_SCROLLBAR_RANGE" }, +{ 1449 , "ERROR_INVALID_SHOWWIN_COMMAND" }, +{ 1450 , "ERROR_NO_SYSTEM_RESOURCES" }, +{ 1451 , "ERROR_NONPAGED_SYSTEM_RESOURCES" }, +{ 1452 , "ERROR_PAGED_SYSTEM_RESOURCES" }, +{ 1453 , "ERROR_WORKING_SET_QUOTA" }, +{ 1454 , "ERROR_PAGEFILE_QUOTA" }, +{ 1455 , "ERROR_COMMITMENT_LIMIT" }, +{ 1456 , "ERROR_MENU_ITEM_NOT_FOUND" }, +{ 1500 , "ERROR_EVENTLOG_FILE_CORRUPT" }, +{ 1501 , "ERROR_EVENTLOG_CANT_START" }, +{ 1502 , "ERROR_LOG_FILE_FULL" }, +{ 1503 , "ERROR_EVENTLOG_FILE_CHANGED" }, +{ 1700 , "RPC_S_INVALID_STRING_BINDING" }, +{ 1701 , "RPC_S_WRONG_KIND_OF_BINDING" }, +{ 1702 , "RPC_S_INVALID_BINDING" }, +{ 1703 , "RPC_S_PROTSEQ_NOT_SUPPORTED" }, +{ 1704 , "RPC_S_INVALID_RPC_PROTSEQ" }, +{ 1705 , "RPC_S_INVALID_STRING_UUID" }, +{ 1706 , "RPC_S_INVALID_ENDPOINT_FORMAT" }, +{ 1707 , "RPC_S_INVALID_NET_ADDR" }, +{ 1708 , "RPC_S_NO_ENDPOINT_FOUND" }, +{ 1709 , "RPC_S_INVALID_TIMEOUT" }, +{ 1710 , "RPC_S_OBJECT_NOT_FOUND" }, +{ 1711 , "RPC_S_ALREADY_REGISTERED" }, +{ 1712 , "RPC_S_TYPE_ALREADY_REGISTERED" }, +{ 1713 , "RPC_S_ALREADY_LISTENING" }, +{ 1714 , "RPC_S_NO_PROTSEQS_REGISTERED" }, +{ 1715 , "RPC_S_NOT_LISTENING" }, +{ 1716 , "RPC_S_UNKNOWN_MGR_TYPE" }, +{ 1717 , "RPC_S_UNKNOWN_IF" }, +{ 1718 , "RPC_S_NO_BINDINGS" }, +{ 1719 , "RPC_S_NO_PROTSEQS" }, +{ 1720 , "RPC_S_CANT_CREATE_ENDPOINT" }, +{ 1721 , "RPC_S_OUT_OF_RESOURCES" }, +{ 1722 , "RPC_S_SERVER_UNAVAILABLE" }, +{ 1723 , "RPC_S_SERVER_TOO_BUSY" }, +{ 1724 , "RPC_S_INVALID_NETWORK_OPTIONS" }, +{ 1725 , "RPC_S_NO_CALL_ACTIVE" }, +{ 1726 , "RPC_S_CALL_FAILED" }, +{ 1727 , "RPC_S_CALL_FAILED_DNE" }, +{ 1728 , "RPC_S_PROTOCOL_ERROR" }, +{ 1730 , "RPC_S_UNSUPPORTED_TRANS_SYN" }, +{ 1732 , "RPC_S_UNSUPPORTED_TYPE" }, +{ 1733 , "RPC_S_INVALID_TAG" }, +{ 1734 , "RPC_S_INVALID_BOUND" }, +{ 1735 , "RPC_S_NO_ENTRY_NAME" }, +{ 1736 , "RPC_S_INVALID_NAME_SYNTAX" }, +{ 1737 , "RPC_S_UNSUPPORTED_NAME_SYNTAX" }, +{ 1739 , "RPC_S_UUID_NO_ADDRESS" }, +{ 1740 , "RPC_S_DUPLICATE_ENDPOINT" }, +{ 1741 , "RPC_S_UNKNOWN_AUTHN_TYPE" }, +{ 1742 , "RPC_S_MAX_CALLS_TOO_SMALL" }, +{ 1743 , "RPC_S_STRING_TOO_LONG" }, +{ 1744 , "RPC_S_PROTSEQ_NOT_FOUND" }, +{ 1745 , "RPC_S_PROCNUM_OUT_OF_RANGE" }, +{ 1746 , "RPC_S_BINDING_HAS_NO_AUTH" }, +{ 1747 , "RPC_S_UNKNOWN_AUTHN_SERVICE" }, +{ 1748 , "RPC_S_UNKNOWN_AUTHN_LEVEL" }, +{ 1749 , "RPC_S_INVALID_AUTH_IDENTITY" }, +{ 1750 , "RPC_S_UNKNOWN_AUTHZ_SERVICE" }, +{ 1751 , "EPT_S_INVALID_ENTRY" }, +{ 1752 , "EPT_S_CANT_PERFORM_OP" }, +{ 1753 , "EPT_S_NOT_REGISTERED" }, +{ 1754 , "RPC_S_NOTHING_TO_EXPORT" }, +{ 1755 , "RPC_S_INCOMPLETE_NAME" }, +{ 1756 , "RPC_S_INVALID_VERS_OPTION" }, +{ 1757 , "RPC_S_NO_MORE_MEMBERS" }, +{ 1758 , "RPC_S_NOT_ALL_OBJS_UNEXPORTED" }, +{ 1759 , "RPC_S_INTERFACE_NOT_FOUND" }, +{ 1760 , "RPC_S_ENTRY_ALREADY_EXISTS" }, +{ 1761 , "RPC_S_ENTRY_NOT_FOUND" }, +{ 1762 , "RPC_S_NAME_SERVICE_UNAVAILABLE" }, +{ 1763 , "RPC_S_INVALID_NAF_ID" }, +{ 1764 , "RPC_S_CANNOT_SUPPORT" }, +{ 1765 , "RPC_S_NO_CONTEXT_AVAILABLE" }, +{ 1766 , "RPC_S_INTERNAL_ERROR" }, +{ 1767 , "RPC_S_ZERO_DIVIDE" }, +{ 1768 , "RPC_S_ADDRESS_ERROR" }, +{ 1769 , "RPC_S_FP_DIV_ZERO" }, +{ 1770 , "RPC_S_FP_UNDERFLOW" }, +{ 1771 , "RPC_S_FP_OVERFLOW" }, +{ 1772 , "RPC_X_NO_MORE_ENTRIES" }, +{ 1773 , "RPC_X_SS_CHAR_TRANS_OPEN_FAIL" }, +{ 1774 , "RPC_X_SS_CHAR_TRANS_SHORT_FILE" }, +{ 1775 , "RPC_X_SS_IN_NULL_CONTEXT" }, +{ 1777 , "RPC_X_SS_CONTEXT_DAMAGED" }, +{ 1778 , "RPC_X_SS_HANDLES_MISMATCH" }, +{ 1779 , "RPC_X_SS_CANNOT_GET_CALL_HANDLE" }, +{ 1780 , "RPC_X_NULL_REF_POINTER" }, +{ 1781 , "RPC_X_ENUM_VALUE_OUT_OF_RANGE" }, +{ 1782 , "RPC_X_BYTE_COUNT_TOO_SMALL" }, +{ 1783 , "RPC_X_BAD_STUB_DATA" }, +{ 1784 , "ERROR_INVALID_USER_BUFFER" }, +{ 1785 , "ERROR_UNRECOGNIZED_MEDIA" }, +{ 1786 , "ERROR_NO_TRUST_LSA_SECRET" }, +{ 1787 , "ERROR_NO_TRUST_SAM_ACCOUNT" }, +{ 1788 , "ERROR_TRUSTED_DOMAIN_FAILURE" }, +{ 1789 , "ERROR_TRUSTED_RELATIONSHIP_FAILURE" }, +{ 1790 , "ERROR_TRUST_FAILURE" }, +{ 1791 , "RPC_S_CALL_IN_PROGRESS" }, +{ 1792 , "ERROR_NETLOGON_NOT_STARTED" }, +{ 1793 , "ERROR_ACCOUNT_EXPIRED" }, +{ 1794 , "ERROR_REDIRECTOR_HAS_OPEN_HANDLES" }, +{ 1795 , "ERROR_PRINTER_DRIVER_ALREADY_INSTALLED" }, +{ 1796 , "ERROR_UNKNOWN_PORT" }, +{ 1797 , "ERROR_UNKNOWN_PRINTER_DRIVER" }, +{ 1798 , "ERROR_UNKNOWN_PRINTPROCESSOR" }, +{ 1799 , "ERROR_INVALID_SEPARATOR_FILE" }, +{ 1800 , "ERROR_INVALID_PRIORITY" }, +{ 1801 , "ERROR_INVALID_PRINTER_NAME" }, +{ 1802 , "ERROR_PRINTER_ALREADY_EXISTS" }, +{ 1803 , "ERROR_INVALID_PRINTER_COMMAND" }, +{ 1804 , "ERROR_INVALID_DATATYPE" }, +{ 1805 , "ERROR_INVALID_ENVIRONMENT" }, +{ 1806 , "RPC_S_NO_MORE_BINDINGS" }, +{ 1807 , "ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" }, +{ 1808 , "ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT" }, +{ 1809 , "ERROR_NOLOGON_SERVER_TRUST_ACCOUNT" }, +{ 1810 , "ERROR_DOMAIN_TRUST_INCONSISTENT" }, +{ 1811 , "ERROR_SERVER_HAS_OPEN_HANDLES" }, +{ 1812 , "ERROR_RESOURCE_DATA_NOT_FOUND" }, +{ 1813 , "ERROR_RESOURCE_TYPE_NOT_FOUND" }, +{ 1814 , "ERROR_RESOURCE_NAME_NOT_FOUND" }, +{ 1815 , "ERROR_RESOURCE_LANG_NOT_FOUND" }, +{ 1816 , "ERROR_NOT_ENOUGH_QUOTA" }, +{ 1817 , "RPC_S_NO_INTERFACES" }, +{ 1818 , "RPC_S_CALL_CANCELLED" }, +{ 1819 , "RPC_S_BINDING_INCOMPLETE" }, +{ 1820 , "RPC_S_COMM_FAILURE" }, +{ 1821 , "RPC_S_UNSUPPORTED_AUTHN_LEVEL" }, +{ 1822 , "RPC_S_NO_PRINC_NAME" }, +{ 1823 , "RPC_S_NOT_RPC_ERROR" }, +{ 1824 , "RPC_S_UUID_LOCAL_ONLY" }, +{ 1825 , "RPC_S_SEC_PKG_ERROR" }, +{ 1826 , "RPC_S_NOT_CANCELLED" }, +{ 1827 , "RPC_X_INVALID_ES_ACTION" }, +{ 1828 , "RPC_X_WRONG_ES_VERSION" }, +{ 1829 , "RPC_X_WRONG_STUB_VERSION" }, +{ 1898 , "RPC_S_GROUP_MEMBER_NOT_FOUND" }, +{ 1899 , "EPT_S_CANT_CREATE" }, +{ 1900 , "RPC_S_INVALID_OBJECT" }, +{ 1901 , "ERROR_INVALID_TIME" }, +{ 1902 , "ERROR_INVALID_FORM_NAME" }, +{ 1903 , "ERROR_INVALID_FORM_SIZE" }, +{ 1904 , "ERROR_ALREADY_WAITING" }, +{ 1905 , "ERROR_PRINTER_DELETED" }, +{ 1906 , "ERROR_INVALID_PRINTER_STATE" }, +{ 1907 , "ERROR_PASSWORD_MUST_CHANGE" }, +{ 1908 , "ERROR_DOMAIN_CONTROLLER_NOT_FOUND" }, +{ 1909 , "ERROR_ACCOUNT_LOCKED_OUT" }, +{ 6118 , "ERROR_NO_BROWSER_SERVERS_FOUND" }, +{ 2000 , "ERROR_INVALID_PIXEL_FORMAT" }, +{ 2001 , "ERROR_BAD_DRIVER" }, +{ 2002 , "ERROR_INVALID_WINDOW_STYLE" }, +{ 2003 , "ERROR_METAFILE_NOT_SUPPORTED" }, +{ 2004 , "ERROR_TRANSFORM_NOT_SUPPORTED" }, +{ 2005 , "ERROR_CLIPPING_NOT_SUPPORTED" }, +{ 3000 , "ERROR_UNKNOWN_PRINT_MONITOR" }, +{ 3001 , "ERROR_PRINTER_DRIVER_IN_USE" }, +{ 3002 , "ERROR_SPOOL_FILE_NOT_FOUND" }, +{ 3003 , "ERROR_SPL_NO_STARTDOC" }, +{ 3004 , "ERROR_SPL_NO_ADDJOB" }, +{ 3005 , "ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED" }, +{ 3006 , "ERROR_PRINT_MONITOR_ALREADY_INSTALLED" }, +{ 4000 , "ERROR_WINS_INTERNAL" }, +{ 4001 , "ERROR_CAN_NOT_DEL_LOCAL_WINS" }, +{ 4002 , "ERROR_STATIC_INIT" }, +{ 4003 , "ERROR_INC_BACKUP" }, +{ 4004 , "ERROR_FULL_BACKUP" }, +{ 4005 , "ERROR_REC_NON_EXISTENT" }, +{ 4006 , "ERROR_RPL_NOT_ALLOWED" }, +{ 10004 , "WSAEINTR" }, +{ 10009 , "WSAEBADF" }, +{ 10013 , "WSAEACCES" }, +{ 10014 , "WSAEFAULT" }, +{ 10022 , "WSAEINVAL" }, +{ 10024 , "WSAEMFILE" }, +{ 10035 , "WSAEWOULDBLOCK" }, +{ 10036 , "WSAEINPROGRESS" }, +{ 10037 , "WSAEALREADY" }, +{ 10038 , "WSAENOTSOCK" }, +{ 10039 , "WSAEDESTADDRREQ" }, +{ 10040 , "WSAEMSGSIZE" }, +{ 10041 , "WSAEPROTOTYPE" }, +{ 10042 , "WSAENOPROTOOPT" }, +{ 10043 , "WSAEPROTONOSUPPORT" }, +{ 10044 , "WSAESOCKTNOSUPPORT" }, +{ 10045 , "WSAEOPNOTSUPP" }, +{ 10046 , "WSAEPFNOSUPPORT" }, +{ 10047 , "WSAEAFNOSUPPORT" }, +{ 10048 , "WSAEADDRINUSE" }, +{ 10049 , "WSAEADDRNOTAVAIL" }, +{ 10050 , "WSAENETDOWN" }, +{ 10051 , "WSAENETUNREACH" }, +{ 10052 , "WSAENETRESET" }, +{ 10053 , "WSAECONNABORTED" }, +{ 10054 , "WSAECONNRESET" }, +{ 10055 , "WSAENOBUFS" }, +{ 10056 , "WSAEISCONN" }, +{ 10057 , "WSAENOTCONN" }, +{ 10058 , "WSAESHUTDOWN" }, +{ 10059 , "WSAETOOMANYREFS" }, +{ 10060 , "WSAETIMEDOUT" }, +{ 10061 , "WSAECONNREFUSED" }, +{ 10062 , "WSAELOOP" }, +{ 10063 , "WSAENAMETOOLONG" }, +{ 10064 , "WSAEHOSTDOWN" }, +{ 10065 , "WSAEHOSTUNREACH" }, +{ 10066 , "WSAENOTEMPTY" }, +{ 10067 , "WSAEPROCLIM" }, +{ 10068 , "WSAEUSERS" }, +{ 10069 , "WSAEDQUOT" }, +{ 10070 , "WSAESTALE" }, +{ 10071 , "WSAEREMOTE" }, +{ 10101 , "WSAEDISCON" }, +{ 10091 , "WSASYSNOTREADY" }, +{ 10092 , "WSAVERNOTSUPPORTED" }, +{ 10093 , "WSANOTINITIALISED" }, +{ 11001 , "WSAHOST_NOT_FOUND" }, +{ 11002 , "WSATRY_AGAIN" }, +{ 11003 , "WSANO_RECOVERY" }, +{ 11004 , "WSANO_DATA" }, +{ 0, 0 /*NULL*/} +}; diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/objndx.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/objndx.h new file mode 100644 index 00000000000..ceb6d06b133 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/objndx.h @@ -0,0 +1,29 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +#ifndef __objndx_h +#define __objndx_h + +/* Define maximum length of object name strings */ +#define OBJNDXNAMLEN 16 + +/* Functions in objndx.c */ +extern void * objndx_create(int size, void (*freefunc)(void *)); +extern char * objndx_register(void * objndx, void * objptr, char * namebuf); +extern void * objndx_lookup(void * objndx, char * objname); +extern void * objndx_remove(void * objndx, char * objname); +extern void objndx_destroy(void * objndx); + +#endif /* __objndx_h */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/pblock.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/pblock.h new file mode 100644 index 00000000000..4dc1629fcd0 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/pblock.h @@ -0,0 +1,193 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * pblock.h: Header for Parameter Block handling functions + * + * + * A parameter block is a set of name=value pairs which are generally used + * as parameters, but can be anything. They are kept in a hash table for + * reasonable speed, but if you are doing any intensive modification or + * access of them you should probably make a local copy of each parameter + * while working. + * + * When creating a pblock, you specify the hash table size for that pblock. + * You should set this size larger if you know that many items will be in + * that pblock, and smaller if only a few will be used or if speed is not + * a concern. + * + * The hashing function is very simple right now, and only looks at the + * first character of name. + * + * Rob McCool + * + */ + +#ifndef PBLOCK_H +#define PBLOCK_H + +/* + * Requires that the macros MALLOC and STRDUP be set to "safe" versions that + * will exit if no memory is available. If not under MCC httpd, define + * them to be the real functions and play with fire, or make your own + * function. + */ + +#include "../netsite.h" + +#include <ctype.h> /* isspace */ +#include <stdio.h> /* sprintf */ +#include <string.h> /* strlen, strcmp */ + + +/* ------------------------------ Structures ------------------------------ */ + + +typedef struct { + char *name,*value; +} pb_param; + +struct pb_entry { + pb_param *param; + struct pb_entry *next; +}; + +typedef struct { + int hsize; + struct pb_entry **ht; +} pblock; + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * param_create creates a parameter with the given name and value. If name + * and value are non-NULL, they are copied and placed into the new pb_param + * struct. + */ + +pb_param *param_create(char *name, char *value); + +/* + * param_free frees a given parameter if it's non-NULL, and returns 1 if + * p was non-NULL, and 0 if p was NULL. + * + * Useful for error checking pblock_remove. + */ + +int param_free(pb_param *pp); + +/* + * pblock_create creates a new pblock with hash table size n. + * + * It returns the newly allocated pblock. + */ + +pblock *pblock_create(int n); + +/* + * pblock_free frees the given pblock and any entries inside it. + * + * If you want to save anything in a pblock, remove its entities with + * pblock_remove first and save the pointers you get. + */ + +void pblock_free(pblock *pb); + +/* + * pblock_find finds the entry with the given name in pblock pb. + * + * If it is successful, it returns the param block. If not, it returns NULL. + */ + +#define pblock_find(name, pb) (_pblock_fr(name,pb,0)) + +/* + * pblock_findval finds the entry with the given name in pblock pb, and + * returns its value, otherwise returns NULL. + */ + +char *pblock_findval(char *name, pblock *pb); + +/* + * pblock_remove behaves exactly like pblock_find, but removes the given + * entry from pb. + */ + +#define pblock_remove(name, pb) (_pblock_fr(name,pb,1)) + +/* + * pblock_nvinsert creates a new parameter with the given name and value + * and inserts it into pblock pb. The name and value in the parameter are + * also newly allocated. Returns the pb_param it allocated (in case you + * need it). + * + * pblock_nninsert inserts a numerical value. + */ + +pb_param *pblock_nvinsert(char *name, char *value, pblock *pb); +pb_param *pblock_nninsert(char *name, int value, pblock *pb); + +/* + * pblock_pinsert inserts a pb_param into a pblock. + */ + +void pblock_pinsert(pb_param *pp, pblock *pb); + +/* + * pblock_str2pblock scans the given string str for parameter pairs + * name=value, or name="value". Any \ must be followed by a literal + * character. If a string value is found, with no unescaped = signs, it + * will be added with the name 1, 2, 3, etc. depending on whether it was + * first, second, third, etc. in the stream (zero doesn't count). + * + * Returns the number of parameters added to the table, or -1 upon error. + */ + +int pblock_str2pblock(char *str, pblock *pb); + +/* + * pblock_pblock2str places all of the parameters in the given pblock + * into the given string (NULL if it needs creation). It will re-allocate + * more space for the string. Each parameter is separated by a space and of + * the form name="value" + */ + +char *pblock_pblock2str(pblock *pb, char *str); + +/* + * pblock_copy copies the entries in the given source pblock to the + * destination one. The entries are newly allocated so that the original + * pblock may be freed or the new one changed without affecting the other. + */ + +void pblock_copy(pblock *src, pblock *dst); + +/* + * pblock_pb2env copies the given pblock into the given environment, with + * one new env entry for each name/value pair in the pblock. + */ + +char **pblock_pb2env(pblock *pb, char **env); + + +/* --------------------------- Internal things ---------------------------- */ + + +pb_param *_pblock_fr(char *name, pblock *pb, int remove); + + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/sem.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/sem.h new file mode 100644 index 00000000000..00fec3bfe6d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/sem.h @@ -0,0 +1,70 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * sem.h: Attempt to provide multi-process semaphores across platforms + * + * Rob McCool + */ + + +#ifndef SEM_H +#define SEM_H + +#include "systems.h" + + +/* All of the implementations currently use int as the semaphore type */ +#ifdef SEM_WIN32 +typedef HANDLE SEMAPHORE; +#define SEM_ERROR 0 +/* That oughta hold them (I hope) */ +#define SEM_MAXVALUE 32767 + +#else /* ! SEM_WIN32 */ +typedef int SEMAPHORE; +#define SEM_ERROR -1 +#endif /* SEM_WIN32 */ + +/* + * sem_init creates a semaphore using the given name and unique + * identification number. filename should be a file accessible to the + * process. Returns SEM_ERROR on error. + */ + +SEMAPHORE sem_init(char *name, int number); + +/* + * sem_terminate de-allocates the given semaphore. + */ + +void sem_terminate(SEMAPHORE id); + +/* + * sem_grab attempts to gain exclusive access to the given semaphore. If + * it can't get it, the caller will block. Returns -1 on error. + */ + +int sem_grab(SEMAPHORE id); + +/* + * sem_release releases this process's exclusive control over the given + * semaphore. Returns -1 on error. + */ + +int sem_release(SEMAPHORE id); + + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/session.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/session.h new file mode 100644 index 00000000000..3104cb0ca65 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/session.h @@ -0,0 +1,85 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * session.h: Deals with virtual sessions + * + * A session is the time between when a client connects and when it + * disconnects. Several requests may be handled in one session. + * + * Rob McCool + */ + + +#ifndef SESSION_H +#define SESSION_H + + +#include "../netsite.h" /* MALLOC etc */ +#include "net.h" /* dns-related stuff */ +#include "buffer.h" /* netbuf */ + + +/* ------------------------------ Structures ------------------------------ */ + + + +#define SESSION_HASHSIZE 5 + + +typedef struct { + /* Client-specific information */ + pblock *client; + + SYS_NETFD csd; + netbuf *inbuf; + + struct in_addr iaddr; +} Session; + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * session_create creates a new request structure for the client with the + * given socket descriptor and sockaddr. + */ + +Session *session_create(SYS_NETFD csd, struct sockaddr_in *sac); + +/* + * session_free frees the given session + */ + +void session_free(Session *sn); + +/* + * session_dns returns the DNS hostname of the client of this session, + * and inserts it into the client pblock. Returns NULL if unavailable. + */ + +#define session_dns(sn) session_dns_lookup(sn, 0) + +/* + * session_maxdns looks up a hostname from an IP address, and then verifies + * that the host is really who they claim to be. + */ + +#define session_maxdns(sn) session_dns_lookup(sn, 1) + +char *session_dns_lookup(Session *sn, int verify); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/shexp.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/shexp.h new file mode 100644 index 00000000000..887f96ae81e --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/shexp.h @@ -0,0 +1,97 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * shexp.h: Defines and prototypes for shell exp. match routines + * + * + * This routine will match a string with a shell expression. The expressions + * accepted are based loosely on the expressions accepted by zsh. + * + * o * matches anything + * o ? matches one character + * o \ will escape a special character + * o $ matches the end of the string + * o [abc] matches one occurence of a, b, or c. The only character that needs + * to be escaped in this is ], all others are not special. + * o [a-z] matches any character between a and z + * o [^az] matches any character except a or z + * o ~ followed by another shell expression will remove any pattern + * matching the shell expression from the match list + * o (foo|bar) will match either the substring foo, or the substring bar. + * These can be shell expressions as well. + * + * The public interface to these routines is documented below. + * + * Rob McCool + * + */ + +#ifndef SHEXP_H +#define SHEXP_H + +/* + * Requires that the macro MALLOC be set to a "safe" malloc that will + * exit if no memory is available. If not under MCC httpd, define MALLOC + * to be the real malloc and play with fire, or make your own function. + */ + +#include "../netsite.h" + +#include <ctype.h> /* isalnum */ +#include <string.h> /* strlen */ + + + +/* --------------------------- Public routines ---------------------------- */ + + +/* + * shexp_valid takes a shell expression exp as input. It returns: + * + * NON_SXP if exp is a standard string + * INVALID_SXP if exp is a shell expression, but invalid + * VALID_SXP if exp is a valid shell expression + */ + +#define NON_SXP -1 +#define INVALID_SXP -2 +#define VALID_SXP 1 + +int shexp_valid(char *exp); + +/* + * shexp_match + * + * Takes a prevalidated shell expression exp, and a string str. + * + * Returns 0 on match and 1 on non-match. + */ + +int shexp_match(char *str, char *exp); + + +/* + * shexp_cmp + * + * Same as above, but validates the exp first. 0 on match, 1 on non-match, + * -1 on invalid exp. shexp_casecmp does the same thing but is case + * insensitive. + */ + +int shexp_cmp(char *str, char *exp); +int shexp_casecmp(char *str, char *exp); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/shmem.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/shmem.h new file mode 100644 index 00000000000..0692a051c78 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/shmem.h @@ -0,0 +1,84 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * shmem.h: Portable abstraction for memory shared among a server's workers + * + * Rob McCool + */ + + +#ifndef _SHMEM_H +#define _SHMEM_H + +#include "netsite.h" +#include "systems.h" + + +/* --------------------------- Data structures ---------------------------- */ + + +#if defined (SHMEM_UNIX_MMAP) || defined (SHMEM_WIN32_MMAP) +#include "file.h" /* SYS_FILE */ + +typedef struct { + void *data; /* the data */ +#ifdef SHMEM_WIN32_MMAP + HANDLE fdmap; +#endif /* SHMEM_WIN32_MMAP */ + int size; /* the maximum length of the data */ + + char *name; /* internal use: filename to unlink if exposed */ + SYS_FILE fd; /* internal use: file descriptor for region */ +} shmem_s; + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * shmem_alloc allocates a region of shared memory of the given size, using + * the given name to avoid conflicts between multiple regions within the + * program. The region will not be automatically grown if its boundaries + * are over-run, use shmem_realloc for that. + * + * If expose is non-zero and the underlying system supports it, the + * file used to create the shared region will be visible to other processes + * running on the system. + * + * name should be unique to the program which calls this routine, otherwise + * conflicts will arise. + * + * Returns a new shared memory region, with the data element being a + * pointer to the shared memory. This function must be called before any + * daemon workers are spawned, in order for the handle to the shared region + * to be inherited by the children. + * + * Because of the requirement that the region must be inherited by the + * children, the region cannot be re-allocated with a larger size when + * necessary. + */ +shmem_s *shmem_alloc(char *name, int size, int expose); + + +/* + * shmem_free de-allocates the specified region of shared memory. + */ +void shmem_free(shmem_s *region); + +#endif /* SHMEM_UNIX_MMAP || SHMEM_WIN32_MMAP */ + + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/systems.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/systems.h new file mode 100644 index 00000000000..193bc63c034 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/systems.h @@ -0,0 +1,222 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * systems.h: Lists of defines for systems + * + * This sets what general flavor the system is (UNIX, etc.), + * and defines what extra functions your particular system needs. + */ + + +#ifndef SYSTEMS_H +#define SYSTEMS_H + +#include <string.h> + + +#define DAEMON_ANY +#define DAEMON_LISTEN_SIZE 128 +#ifndef MCC_ADMSERV +#define DAEMON_STATS +#endif + +/* Linux is not currently supported */ +#ifdef linux + +#define FILE_UNIX +#undef FILE_STDIO +#undef DAEMON_UNIX_FORK +#undef DAEMON_UNIX_POOL +#define DAEMON_UNIX_MOBRULE +#undef DAEMON_STATS +#define BSD_FLOCK +#define BSD_RLIMIT +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS (MAP_FILE | MAP_PRIVATE) +#undef BSD_SIGNALS + +#undef NEED_CRYPT_PROTO +#undef AUTH_DBM +#define SEM_FLOCK + + +#define ZERO(ptr,len) memset(ptr,0,len) + +#elif defined(BSDI) + +#define FILE_UNIX +#define DAEMON_UNIX_MOBRULE +#define BSD_FLOCK +#define BSD_RLIMIT +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS (MAP_FILE | MAP_PRIVATE) +#define BSD_SIGNALS +#define BSD_TIME +#define BSD_MAIL +#undef NEED_CRYPT_PROTO +#define AUTH_DBM +#define SEM_FLOCK + +#define ZERO(ptr,len) memset(ptr,0,len) + +#elif defined(SOLARIS) + +#define FILE_UNIX +#undef FILE_STDIO +#define DAEMON_UNIX_MOBRULE +#define DAEMON_NEEDS_SEMAPHORE +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS MAP_PRIVATE +#undef BSD_SIGNALS +#define BSD_RLIMIT +#define NEED_CRYPT_H +#define AUTH_DBM +/* The Solaris routines return ENOSPC when too many semaphores are SEM_UNDO. */ +#define SEM_FLOCK +#define DLL_CAPABLE +#define DLL_DLOPEN + +#define ZERO(ptr,len) memset(ptr,0,len) + +#elif defined(SUNOS4) + +#define BSD_SIGNALS +#define BSD_TIME +#define BSD_MAIL +#define BSD_FLOCK +#define BSD_RLIMIT +#define FILE_UNIX +#undef FILE_STDIO +#define DAEMON_UNIX_MOBRULE +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS MAP_PRIVATE +#undef NEED_CRYPT_H +#define NEED_CRYPT_PROTO +#define AUTH_DBM +#define SEM_FLOCK +#define ZERO(ptr,len) memset(ptr,0,len) +#define DLL_CAPABLE +#define DLL_DLOPEN + +#elif defined(OSF1) + +#undef BSD_SIGNALS +#define BSD_TIME +#define BSD_FLOCK +#define BSD_RLIMIT +#define FILE_UNIX +#undef FILE_STDIO +#define DAEMON_UNIX_MOBRULE +#define DAEMON_NEEDS_SEMAPHORE +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS MAP_PRIVATE +#define AUTH_DBM +#define SEM_FLOCK +#define ZERO(ptr,len) memset(ptr,0,len) +#define DLL_CAPABLE +#define DLL_DLOPEN + +#elif defined(AIX) + +#define FILE_UNIX +#undef FILE_STDIO +#undef DAEMON_UNIX_FORK +#undef DAEMON_UNIX_POOL +#define DAEMON_UNIX_MOBRULE +#define DAEMON_NEEDS_SEMAPHORE +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS MAP_PRIVATE +#undef BSD_SIGNALS +#define BSD_RLIMIT +#undef NEED_CRYPT_H +#define AUTH_DBM +#define SEM_FLOCK +#define ZERO(ptr,len) memset(ptr,0,len) +#define DLL_CAPABLE +#define DLL_DLOPEN + +#elif defined(HPUX) + +#define FILE_UNIX +#undef FILE_STDIO +#define DAEMON_UNIX_MOBRULE +#define DAEMON_NEEDS_SEMAPHORE +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS MAP_PRIVATE +#undef BSD_SIGNALS +#undef BSD_RLIMIT +#undef NEED_CRYPT_H +#define AUTH_DBM +#define SEM_FLOCK +#define ZERO(ptr,len) memset(ptr,0,len) +#define DLL_CAPABLE +#define DLL_HPSHL + +#elif defined (IRIX) + +#define FILE_UNIX +#undef FILE_STDIO +#undef DAEMON_UNIX_FORK +#undef DAEMON_UNIX_POOL +#define DAEMON_UNIX_MOBRULE +#define DLL_CAPABLE +#define DLL_DLOPEN +#define NET_SOCKETS +#define FILE_UNIX_MMAP +#define FILE_MMAP_FLAGS MAP_PRIVATE +#undef BSD_SIGNALS +#define BSD_RLIMIT +#define NEED_CRYPT_H +#define AUTH_DBM +#define SEM_FLOCK +#define ZERO(ptr,len) memset(ptr,0,len) + +#else /* Windows NT */ + +#include <wtypes.h> +#include <winbase.h> + +typedef void* PASSWD; + +#define FILE_WIN32 +#define NET_SOCKETS +#define NET_WINSOCK +#define DAEMON_WIN32 +#undef AUTH_DBM +#define ZERO(ptr, len) ZeroMemory(ptr, len) +#define SEM_WIN32 +#define DLL_CAPABLE +#define DLL_WIN32 +#define NO_NODELOCK /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagh */ + +/* The stat call under NT doesn't define these macros */ +#define S_ISDIR(mode) ((mode&S_IFMT) == S_IFDIR) +#define S_ISREG(mode) ((mode&S_IFMT) == S_IFREG) + +#define strcasecmp util_strcasecmp +#define strncasecmp util_strncasecmp +int util_strcasecmp(const char *s1, const char *s2); +int util_strncasecmp(const char *s1, const char *s2, int n); +#endif /* Windows NT */ + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/systhr.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/systhr.h new file mode 100644 index 00000000000..e53cc385049 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/systhr.h @@ -0,0 +1,130 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * systhr.h: Abstracted threading mechanisms + * + * Rob McCool + */ + +#ifndef _SYSTHR_H +#define _SYSTHR_H + +#include "netsite.h" +#include "systems.h" + +#ifdef THREAD_ANY + +#ifdef USE_NSPR +#include <nspr/prthread.h> +#include <nspr/prglobal.h> + +typedef PRThread* SYS_THREAD; +#endif + +#ifdef THREAD_WIN32 +#include <nspr/prthread.h> +#include <nspr/prglobal.h> +#include <process.h> +typedef struct { + HANDLE hand; + DWORD id; +} sys_thread_s; +typedef sys_thread_s *SYS_THREAD; +#endif + +/* + * systhread_start creates a thread with the given priority, will allocate + * a stack of stksz bytes, and calls fn with arg as its argument. stksz + * of zero will allocate a default stack size. + * + * XXX Priorities are system dependent + */ + +SYS_THREAD systhread_start(int prio, int stksz, void (*fn)(void *), void *arg); + +/* + * systhread_current returns a pointer to the current thread. + */ +#ifdef USE_NSPR +#define systhread_current() PR_CurrentThread() +#elif defined(THREAD_WIN32) +#define systhread_current() GetCurrentThreadId() +#endif + +/* + * systhread_attach makes an existing thread an NSPR thread. Currently this + * is used only in NT. + */ + +SYS_THREAD systhread_attach(); + +/* + * systhread_terminate terminates the thread that is passed in. + */ +void systhread_terminate(SYS_THREAD thr); + + +/* + * systhread_sleep puts the calling thread to sleep for the given number + * of milliseconds. + */ +void systhread_sleep(int milliseconds); + +/* + * systhread_init initializes the threading system. name is a name for the + * program for debugging. + */ +void systhread_init(char *name); + +/* + * systhread_timerset starts or re-sets the interrupt timer for a thread + * system. This should be considered a suggestion as most systems don't allow + * the timer interval to be changed. + */ +#ifdef THREAD_NSPR_USER +#define systhread_timerset(usec) PR_StartEvents(usec) + +#elif defined(USE_NSPR) +#define systhread_timerset(usec) (void)(usec) + +#elif defined(THREAD_WIN32) +#define systhread_timerset(usec) (void)(usec) +#endif + + +/* + * newkey allocates a new integer id for thread-private data. Use this + * key to identify a variable which you want to appear differently + * between threads, and then use setdata to associate a value with this + * key for each thread. + */ +int systhread_newkey(void); + +/* + * Get data that has been previously associated with key in this thread. + * Returns NULL if setkey has not been called with this key by this + * thread previously, or the data that was previously used with setkey + * by this thread with this key. + */ +void *systhread_getdata(int key); + +/* + * Associate data with the given key number in this thread. + */ +void systhread_setdata(int key, void *data); + +#endif +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/util.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/util.h new file mode 100644 index 00000000000..f710ffc2530 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/base/util.h @@ -0,0 +1,205 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * util.h: A hodge podge of utility functions and standard functions which + * are unavailable on certain systems + * + * Rob McCool + */ + + +#ifndef HTTPD_UTIL_H +#define HTTPD_UTIL_H + +#include "buffer.h" /* filebuf for getline */ + +#include <time.h> /* struct tm */ + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * getline scans in buf until it finds a LF or CRLF, storing the string in + * l. It will terminate the string and return: + * + * 0 when done, with the scanned line (minus CR or LF) in l + * 1 upon EOF, with the scanned line (minus CR or LF) in l + * -1 on error with the error description in l (uses lineno for information) + */ + +int util_getline(filebuf *buf, int lineno, int maxlen, char *l); + + +/* + * can_exec returns 1 if you can execute the file described by finfo, and + * 0 if you can't. + */ + +#ifdef XP_UNIX +#include <sys/stat.h> +#include <sys/types.h> + +int util_can_exec(struct stat *finfo, uid_t uid, gid_t gid); + +#endif /* XP_UNIX */ +/* + * env_create creates a new environment with the given env, with n new + * entries, and places the current position that you should add your + * entries with at pos. + * + * If env is NULL, it will allocate a new one. If not, it will reallocate + * that one. + */ + +char **util_env_create(char **env, int n, int *pos); + +/* + * util_env_str allocates a string from the given name and value and + * returns it. It does not check for things like = signs in name. + */ + +char *util_env_str(char *name, char *value); + +/* + * env_replace replaces the occurrence of the given variable with the + * value you give. + */ + +void util_env_replace(char **env, char *name, char *value); + +/* + * util_env_free frees an environment. + */ + +void util_env_free(char **env); + +/* + * util_env_find looks through env for the named string. Returns the + * corresponding value if the named string is found, or NULL if not. + */ +char *util_env_find(char **env, char *name); + + +/* + * hostname gets the local hostname. Returns NULL if it can't find a FQDN. + * You are free to realloc or free this string. + */ + +char *util_hostname(void); + + +/* + * chdir2path changes the current directory to the one that the file + * path is in. path should point to a file. Caveat: path must be a writable + * string. It won't get modified permanently. + */ + +int util_chdir2path(char *path); + +/* + * is_mozilla checks if the given user-agent is mozilla, of at least + * the given major and minor revisions. These are strings to avoid + * ambiguities like 1.56 > 1.5 + */ + +int util_is_mozilla(char *ua, char *major, char *minor); + +/* + * is_url will return 1 if the given string seems to be a URL, or will + * return 0 otherwise. + * + * Because of stupid news URLs, this will return 1 if the string has + * all alphabetic characters up to the first colon and will not check for + * the double slash. + */ + +int util_is_url(char *url); + +/* + * util_later_than checks the date in the string ims, and if that date is + * later than or equal to the one in the tm struct lms, then it returns 1. + * + * Handles RFC 822, 850, and ctime formats. + */ + +int util_later_than(struct tm *lms, char *ims); + + +/* + * util_uri_is_evil returns 1 if a URL has ../ or // in it. + */ +int util_uri_is_evil(char *t); + +/* + * util_uri_parse gets rid of /../, /./, and //. + * + * Assumes that either the string starts with a /, or the string will + * not .. right off of its beginning. As such, ../foo.gif will + * not be changed, although /../foo.gif will become /foo.gif. + */ + +void util_uri_parse(char *uri); + +/* + * util_uri_unescape unescapes the given URI in place (% conversions only). + */ + +void util_uri_unescape(char *s); + +/* + * util_uri_escape escapes any nasty chars in s and copies the string into d. + * If d is NULL, it will allocate and return a properly sized string. + * Warning: does not check bounds on a given d. + * + * util_url_escape does the same thing but does it for a url, i.e. ?:+ is + * not escaped. + */ + +char *util_uri_escape(char *d, char *s); +char *util_url_escape(char *d, char *s); + +/* + * util_sh_escape places a \ in front of any shell-special characters. + * Returns a newly-allocated copy of the string. + */ + +char *util_sh_escape(char *s); + +/* + * util_itoa converts the given integer to a string into a. + */ + +int util_itoa(int i, char *a); + +/* + * util_vsprintf and util_sprintf are simplified clones of the System V + * vsprintf and sprintf routines. + * + * Returns the number of characters printed. Only handles %d and %s, + * does not handle any width or precision. + */ + +#include <stdarg.h> + +int util_vsprintf(char *s, register char *fmt, va_list args); +int util_sprintf(char *s, char *fmt, ...); + +/* These routines perform bounds checks. */ +int util_vsnprintf(char *s, int n, register char *fmt, va_list args); +int util_snprintf(char *s, int n, char *fmt, ...); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/conf.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/conf.h new file mode 100644 index 00000000000..fd20b2eeaf3 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/conf.h @@ -0,0 +1,155 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * conf.h: Deals with the server configuration file. + * + * Object configuration is an entirely different matter. This deals with + * things like what port the server runs on, how many children it spawns, + * and other server-related issues. Information related configuration is + * handled by the object conf. + * + * Rob McCool + */ + + +#ifndef CONF_H +#define CONF_H + +#ifdef XP_WIN32 +#include <nt/ntconf.h> +#else + +#include "netsite.h" +#include "frame/objset.h" +#include "base/daemon.h" /* daemon struct */ + +#include <pwd.h> /* struct passwd */ + +/* ------------------------------ Constants ------------------------------- */ + + +/* The longest line in the configuration file */ +#define CONF_MAXLEN 16384 + +#define LF 10 +#define CR 13 + + +#if defined(DAEMON_ANY) +#ifdef MCC_PROXY +#define DEFAULT_PORT 8080 +#else +#define DEFAULT_PORT 80 +#endif +#endif + +#if defined(DAEMON_UNIX_POOL) || defined(DAEMON_UNIX_MOBRULE) +#define DEFAULT_POOL_MAX 50 +#endif + + + +/* ------------------------------- Globals -------------------------------- */ + + +#ifndef CONF_C + +/* + * These server parameters are made global because they really don't + * belong anywhere else. + */ + +#if defined(DAEMON_ANY) + +#include <sys/types.h> + +/* What port we listen to */ +extern int port; + +/* What address to bind to */ +extern char *addr; + +/* User to run as */ +extern struct passwd *userpw; + +/* Directory to chroot to */ +extern char *chr; + +/* Where to log our pid to */ +extern char *pidfn; + +#if defined(DAEMON_UNIX_POOL) || defined(DAEMON_UNIX_MOBRULE) +/* The maximum number of processes to keep in the pool */ +extern int pool_max; +/* The minimum number of processes to keep in the pool */ +extern int pool_min; +/* The maximum number of requests each process should handle. -1=default */ +extern int pool_life; +#endif + +#ifdef NET_SSL +extern char *secure_keyfn; +extern char *secure_certfn; +extern char *secure_dongle; +extern int security_active; +extern int secure_auth; +extern int security_session_timeout; +#endif + +#endif + +/* The server's hostname as should be reported in self-ref URLs */ +extern char *server_hostname; + +/* The main object from which all are derived */ +extern char *root_object; + +/* The object set the administrator has asked us to load */ +extern httpd_objset *std_os; + +/* The main error log, where all errors are logged */ +extern char *master_error_log; + +/* The e-mail address of someone to mail upon catastrophic error */ +extern char *admin_email; + +#endif + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * conf_init reads the given configuration file and sets any non-default + * parameters to their given setting. + */ + +char *conf_init(char *cfn); + +/* + * conf_terminate frees any data the conf routines may be holding. + */ + +void conf_terminate(void); + + +/* + * conf_vars2daemon transfers these globals to a daemon structure + */ +void conf_vars2daemon(daemon_s *d); + +#endif +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/dnfilter.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/dnfilter.h new file mode 100644 index 00000000000..789c19c4138 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/dnfilter.h @@ -0,0 +1,44 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +#ifndef __dnfilter_h +#define __dnfilter_h + +/* Error codes */ +#define DNFERR_MAX (-1) /* maximum error code */ +#define DNFERR_MALLOC (-1) /* insufficient memory */ +#define DNFERR_FOPEN (-2) /* file open error */ +#define DNFERR_FILEIO (-3) /* file I/O error */ +#define DNFERR_DUPSPEC (-4) /* duplicate filter specification */ +#define DNFERR_INTERR (-5) /* internal error (bug) */ +#define DNFERR_SYNTAX (-6) /* syntax error in filter file */ +#define DNFERR_MIN (-6) /* minimum error code */ + +/* This is used to return error information from dns_filter_setup() */ +typedef struct DNSFilterErr_s DNSFilterErr_t; +struct DNSFilterErr_s { + int errNo; /* DNFERR_xxxx error code */ + int lineno; /* file line number, if applicable */ + char * filename; /* filename, if applicable */ + char * errstr; /* error text, if any */ +}; + +/* Data and functions in dnfilter.c */ +extern void * dnf_objndx; +extern void dns_filter_destroy(void * dnfptr); +extern int dns_filter_setup(pblock * client, DNSFilterErr_t * reterr); +extern int dns_filter_check(pblock * client, char * cdns); + +#endif /* __dnfilter_h */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/func.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/func.h new file mode 100644 index 00000000000..111ffd3a375 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/func.h @@ -0,0 +1,111 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * func.h: Handles the function hash table + * + * httpd uses a table of internal functions hashed by a name string such that + * users can reference specific functions from the configuration files. + * + * Any function referenced by configuration files will be passed a + * parameter, a Request structure. The functions do not return anything. + * + * Rob McCool + */ + +#ifndef FUNC_H +#define FUNC_H + + +#include "netsite.h" +#include "base/pblock.h" +#include "base/session.h" /* Session structure */ +#include "frame/req.h" /* Request structure */ + + +/* -------------------------- Structure and Type -------------------------- */ + + +/* + * FuncPtr is a pointer to our kind of functions + */ + +typedef int Func(pblock *, Session *, Request *); +typedef Func *FuncPtr; + +/* + * FuncStruct is a structure used in the static declaration of the + * functions. This static declaration is parsed into a hash table at + * startup. You should initialize the next entry to NULL. + */ + +struct FuncStruct { + char *name; + FuncPtr func; + struct FuncStruct *next; +}; + + +/* --------------------------- Hash definitions --------------------------- */ + + +/* + * This is a primitive hash function. Once more is known about the names of + * the functions, this will be optimized. + */ + +#define NUM_HASH 20 +#define FUNC_HASH(s) (s[0] % NUM_HASH) + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * func_init reads the static FuncStruct arrays and creates the global + * function table from them. + * + * func_init will only read from the static arrays defined in func.c. + */ + +void func_init(void); + +/* + * func_find returns a pointer to the function named name, or NULL if none + * exists. + */ + +FuncPtr func_find(char *name); + +/* + * func_exec will try to execute the function whose name is the "fn" entry + * in the given pblock. If name is not found, it will log a misconfig of + * missing fn parameter. If it can't find it, it will log that. In these + * cases it will return REQ_ABORTED. Otherwise, it will return what the + * function being executed returns. + */ + +int func_exec(pblock *pb, Session *sn, Request *rq); + +/* + * func_insert dynamically inserts a named function into the server's + * table of functions. Returns the FuncStruct it keeps in internal + * databases, because on server restart you are responsible for freeing + * (or not) its contents. + */ + +struct FuncStruct *func_insert(char *name, FuncPtr fn); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/http.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/http.h new file mode 100644 index 00000000000..8fa5d0bd608 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/http.h @@ -0,0 +1,171 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * http.h: Deals with HTTP-related issues + * + * Rob McCool + */ + + +#ifndef HTTP_H +#define HTTP_H + + +#include "netsite.h" +#include "base/session.h" +#include "base/pblock.h" + +#include "frame/req.h" /* REQ_MAX_LINE, Request structure */ + +/* ------------------------------ Constants ------------------------------- */ + + +#define HTTP_DATE_LEN 128 +#define HTTP_DATE_FMT "%A, %d-%b-%y %T GMT" + + +/* The maximum number of RFC-822 headers we'll allow */ +/* This would be smaller if a certain browser wasn't so damn stupid. */ +#define HTTP_MAX_HEADERS 200 + +/* Whether or not we should read the headers for if-modified-since */ +#define HTTP_DO_IMS +#define HTTP_ALWAYS_LOADHDRS + +/* HTTP status codes */ + +#define PROTOCOL_OK 200 +#define PROTOCOL_NO_RESPONSE 204 +#define PROTOCOL_REDIRECT 302 +#define PROTOCOL_NOT_MODIFIED 304 +#define PROTOCOL_BAD_REQUEST 400 +#define PROTOCOL_UNAUTHORIZED 401 +#define PROTOCOL_FORBIDDEN 403 +#define PROTOCOL_NOT_FOUND 404 +#define PROTOCOL_PROXY_UNAUTHORIZED 407 +#define PROTOCOL_SERVER_ERROR 500 +#define PROTOCOL_NOT_IMPLEMENTED 501 + + +#ifdef NET_SSL +#define HTTPS_PORT 443 +#define HTTPS_URL "https" +#endif +#define HTTP_PORT 80 +#define HTTP_URL "http" + +/* -------------------------- http_scan_headers --------------------------- */ + + +/* + * parses the first line of an HTTP request + */ + +#define protocol_parse_request http_parse_request +int http_parse_request(char *t, Request *rq, Session *sn); + +/* + * Scans HTTP headers from the given netbuf, and places them in headers. + * If netbuf is NULL, the session's inbuf is used. + * + * Folded lines are joined and the linefeed removed (but not the whitespace). + * If there are any repeat headers they are joined and the two field bodies + * separated by a comma and space. + * + * t should be a string of length REQ_MAX_LINE. This is a convenience to + * req.c so that we don't use too much runtime stack. + * + * Session is an optional parameter. Use NULL if you wish. It's used for + * error logs. + */ + +#define protocol_scan_headers http_scan_headers +int http_scan_headers(Session *sn, netbuf *buf, char *t, pblock *headers); + + +/* + * Starts the HTTP response. If HTTP/0.9, does nothing. If 1.0, sends header. + * If this returns REQ_NOACTION, the method was head and no body should be + * sent. Otherwise, it will return REQ_PROCEED. + */ + +#define protocol_start_response http_start_response +int http_start_response(Session *sn, Request *rq); + + +/* + * http_hdrs2env takes the entries from the given pblock and converts them + * to an environment. + * + * Each name entry will be made uppercase, prefixed with HTTP_ and any + * occurrence of - will be converted to _. + */ + +char **http_hdrs2env(pblock *pb); + +//FUZZ: disable check_for_NULL +/* + * http_status sets status to the code n, with reason string r. If r is + * NULL, the server will attempt to find one for the given status code. + * If it finds none, it will give "Because I felt like it." + */ +//FUZZ: enable check_for_NULL + +#define protocol_status http_status +void http_status(Session *sn, Request *rq, int n, char *r); + +/* + * http_set_finfo sets content-length and last-modified + */ + +#define protocol_set_finfo http_set_finfo +int http_set_finfo(Session *sn, Request *rq, struct stat *finfo); + + +/* + * Takes the given pblock and prints headers into the given buffer at + * position pos. Returns the buffer, reallocated if needed. Modifies pos. + */ + +char *http_dump822(pblock *pb, char *t, int *pos, int tsz); + +/* + * Finishes a request. For HTTP, this just closes the socket. + */ + +#define protocol_finish_request http_finish_request +void http_finish_request(Session *sn, Request *rq); + + +/* + * http_handle_session processes each request generated by Session + */ + +#define protocol_handle_session http_handle_session +void http_handle_session(Session *sn); + +/* + * http_uri2url takes the give URI prefix and URI suffix and creates a + * newly-allocated full URL from them of the form + * http://(server):(port)(prefix)(suffix) + * + * If you want either prefix or suffix to be skipped, use "" instead of NULL. + */ + +#define protocol_uri2url http_uri2url +char *http_uri2url(char *prefix, char *suffix); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/httpact.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/httpact.h new file mode 100644 index 00000000000..a1e1a971bb8 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/httpact.h @@ -0,0 +1,120 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * httpact.h: Defines the API characteristics for HTTP servers + * + * Rob McCool + */ + + +#ifndef HTTPACT_H +#define HTTPACT_H + +#include "frame/req.h" +#include "frame/object.h" + + +/* ------------------------------ Constants ------------------------------- */ + +#ifdef MCC_BATMAN +#define NUM_DIRECTIVES 5 +#else +#ifdef MCC_PROXY +#define NUM_DIRECTIVES 10 +#else +#define NUM_DIRECTIVES 7 +#endif +#endif + + +/* -------------------------- Generic Prototypes -------------------------- */ + + +/* + * directive_name2num will return the position of the abbreviated directive + * dir in the directive table. + * + * If dir does not exist in the table, it will return -1. + */ + +int directive_name2num(char *dir); + + +/* + * directive_num2name returns a string describing directive number num. + */ +const char *directive_num2name(int num); + + +/* + * servact_finderror looks through the request's object set to find a + * suitable error function to execute. Returns REQ_PROCEED if a function + * was found and executed successfully, REQ_NOACTION otherwise. + */ +int servact_finderror(Session *sn, Request *rq); + + +/* + * Read in and handle one request from the given session + */ +void servact_handle(Session *sn); + + +/* ----------------------- HTTP specific prototypes ----------------------- */ + + +int servact_handle_processed(Session *sn, Request *rq); + +/* + * Returns the translated path (filename) for the given uri, NULL otherwise. + * If authentication is required for the given uri, nothing is returned even + * if the current user has authenticated to that area. + */ +char *servact_translate_uri(char *uri, Session *sn); + + + +#ifdef MCC_PROXY + +/* ----------------------- proxy specific prototypes ---------------------- */ + +/* + * Resolves the given hostname, first trying to find a resolver + * function from obj.conf, and if that fails, just calls gethostbyname(). + * + */ +struct hostent *servact_gethostbyname(char *host, Session *sn, Request *rq); + + +/* + * Establishes a connection to the specified host and port using + * a Connect class function from obj.conf. Returns the sockect + * descriptor that is connected (and which should be SSL_Import()'ed + * by the caller). + * + * Returns -2 (REQ_NOACTION), if no such Connect class function exists. + * The caller should use the native connect mechanism in that case. + * + * Returns -1 (REQ_ABORT) on failure to connect. The caller should not + * attempt to use the native connect. + * + */ +int servact_connect(char *host, int port, Session *sn, Request *rq); + + +#endif /* ! MCC_PROXY */ + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/ipfilter.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/ipfilter.h new file mode 100644 index 00000000000..2aa32502d8f --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/ipfilter.h @@ -0,0 +1,48 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +#ifndef __ipfilter_h +#define __ipfilter_h + +/* Define error codes */ +#define IPFERR_MAX (-1) /* maximum error code value */ +#define IPFERR_MALLOC (-1) /* insufficient memory */ +#define IPFERR_FOPEN (-2) /* file open error */ +#define IPFERR_FILEIO (-3) /* file I/O error */ +#define IPFERR_DUPSPEC (-4) /* duplicate filter specification */ +#define IPFERR_INTERR (-5) /* internal error (bug) */ +#define IPFERR_SYNTAX (-6) /* syntax error in filter file */ +#define IPFERR_CNFLICT (-7) /* conflicting filter specification */ +#define IPFERR_MIN (-7) /* minimum error code value */ + +/* Define a scalar IP address value */ +typedef unsigned long IPAddr_t; + +/* Define structure for returning error information */ +typedef struct IPFilterErr_s IPFilterErr_t; +struct IPFilterErr_s { + int errNo; /* IPFERR_xxxx error code */ + int lineno; /* file line number, if applicable */ + char * filename; /* filename, if applicable */ + char * errstr; /* error text, if any */ +}; + +/* Data and functions in ipfilter.c */ +extern void * ipf_objndx; +extern void ip_filter_destroy(void * ipfptr); +extern int ip_filter_setup(pblock * client, IPFilterErr_t * reterr); +extern int ip_filter_check(pblock * client, IPAddr_t cip); + +#endif /* __ipfilter_h */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/log.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/log.h new file mode 100644 index 00000000000..1113ebe6867 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/log.h @@ -0,0 +1,51 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * log.h: Records transactions, reports errors to administrators, etc. + * + * Rob McCool + */ + + +#ifndef LOG_H +#define LOG_H + + +#include "netsite.h" +#include "base/session.h" /* Session structure */ +#include "frame/req.h" /* Request struct */ +#include "base/ereport.h" /* Error reporting, degrees */ + + +#define ERROR_CUTOFF 128 + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * log_error logs an error of the given degree from the function func + * and formats the arguments with the printf() style fmt. Returns whether the + * log was successful. Records the current date. + * + * sn and rq are optional parameters. If given, information about the client + * will be reported. + */ + +int log_error(int degree, char *func, Session *sn, Request *rq, + char *fmt, ...); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/object.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/object.h new file mode 100644 index 00000000000..45180c5b884 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/object.h @@ -0,0 +1,167 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * object.h: Handle httpd objects + * + * Manages information about a document from config. files. Called mainly + * by objset.c. + * + * This module does not assume anything about the directives being parsed. + * That is handled by objset.c. + * + * This module requires the pblock module from the base library. + * + * Rob McCool + * + */ + + +#ifndef OBJECT_H +#define OBJECT_H + + +#include "netsite.h" +#include "base/pblock.h" +#include "base/session.h" + + + + +/* ------------------------------ Constants ------------------------------- */ + + +/* The maximum directive length unabbreviated, plus one space */ +#define MAX_DNAME_LEN 11 +#define NUM_DIRECTIVES 7 + + +/* ------------------------------ Structures ------------------------------ */ + + + +/* + * Hierarchy of httpd_object + * + * An object contains dtables. + * + * Each dtable is a table of directives that were entered of a certain type. + * There is one dtable for each unique type of directive. + * + * Each dtable contains an array of directives, each of which is equivalent + * to one directive that occurred in a config. file. + * + * It is up to the caller to determine how many dtables will be allocated + * and to keep track of which of their directive types maps to which dtable + * number. + */ + + +/* + * directive is a structure containing the protection and parameters to an + * instance of a directive within an httpd_object. + * + * param is the parameters, client is the protection. + */ + +typedef struct { + pblock *param; + pblock *client; +} directive; + +/* + * dtable is a structure for creating tables of directives + */ + +typedef struct { + int ni; + directive *inst; +} dtable; + +/* + * The httpd_object structure. + * + * The name pblock array contains the names for this object, such as its + * virtual location, its physical location, or its identifier. + * + * tmpl contains any templates allocated to this object. + */ + +typedef struct { + pblock *name; + + int nd; + dtable *dt; +} httpd_object; + + + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * directive_name2num will return the position of the abbreviated directive + * dir in the directive table. + * + * If dir does not exist in the table, it will return -1. + */ + +int directive_name2num(char *dir); + + +/* + * directive_num2name returns a string describing directive number num. + */ + +const char *directive_num2name(int num); + + +/* + * object_create will create a new object and return a pointer to it. + * It will allocate space for nd directive types and set name accordingly. + */ + +httpd_object *object_create(int nd, pblock *name); + +/* + * object_free will free an object and any data associated with it. + */ + +void object_free(httpd_object *obj); + +/* + * object_add_directive will add a new directive to the dtable for + * the directive class at position dc. + */ + +void object_add_directive(int dc, pblock *p, pblock *c, httpd_object *obj); + + +/* + * object_findnext finds the object configured to follow the given object, + * and stores the variables in rq->vars. It returns REQ_PROCEED if more + * objects should be processed, or REQ_NOACTION if it did not find any + * further objects to process. If something bad happens, REQ_ABORTED is + * returned. + * + * Handles all DIRECTIVE_CONSTRUCT type directives such as NameTrans and + * AuthType. + */ + + +/* --------- Prototype moved to req.h because of interdependency ---------- */ + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/objset.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/objset.h new file mode 100644 index 00000000000..fe68c31eb04 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/objset.h @@ -0,0 +1,158 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * objset.h: Handles object sets + * + * Each object is produced by reading a config file of some form. See the + * server documentation for descriptions of the directives that are + * recognized, what they do, and how they are parsed. + * + * This module requires the pblock and buffer modules from the base library. + * + * Rob McCool + */ + + +#ifndef OBJSET_H +#define OBJSET_H + +#ifdef XP_WIN32 +#include <nt/ntobjset.h> +#else + + +#include "netsite.h" +#include "base/pblock.h" +#include "base/buffer.h" +#include "frame/object.h" + + + +/* ------------------------------ Constants ------------------------------- */ + + +/* + * The default number of objects to leave room for in an object set, + * and the number of new entries by which to increase the size when that + * room is filled. + */ + +#define OBJSET_INCSIZE 8 + +/* + * When parsing config. files, httpd will put a limit on how long + * the parameters to a directive can be (in characters). + * + * Currently set to 10 lines (80 chars/line). + */ + +#define MAX_DIRECTIVE_LEN 800 + +/* + * The size of the hash tables that store a directive's parameters + */ + +#define PARAMETER_HASH_SIZE 3 + + +/* ------------------------------ Structures ------------------------------ */ + + +/* + * httpd_objset is a container for a bunch of objects. obj is a + * NULL-terminated array of objects. pos points to the entry after the last + * one in the array. You should not mess with pos, but can read it to find + * the last entry. + */ + +typedef struct { + int pos; + httpd_object **obj; +} httpd_objset; + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * objset_scan_buffer will scan through buffer, looking for object + * configuration information, and adding them to the object set os if it + * finds any. If os is NULL it will allocate a new object set. + * + * If any error occurs (syntax error, premature EOF) this function will + * free os, print an error message into errstr, and return NULL. + * This is because a config. file error is viewed as a catastrophic error + * from which httpd should not try to recover. If httpd were to continue + * after an error, it would not behave as the admin. expected and he/she + * may not notice until it's too late. + * + * Upon EOF the file will not be closed. + */ + +httpd_objset *objset_scan_buffer(filebuf *buf, char *errstr, httpd_objset *os); + +/* + * objset_create creates a new object set and returns a pointer to it. + */ + +httpd_objset *objset_create(void); + +/* + * objset_free will free an object set and any associated objects. + */ + +void objset_free(httpd_objset *os); + +/* + * objset_free_setonly frees only the object set. + */ +void objset_free_setonly(httpd_objset *os); + +/* + * objset_new_object will add a new object to objset with the specified + * name. It returns a pointer to the new object (which may be anywhere in + * the objset). + */ + +httpd_object *objset_new_object(pblock *name, httpd_objset *os); + +/* + * objset_add_object will add the existing object to os. + */ + +void objset_add_object(httpd_object *obj, httpd_objset *os); + +/* + * objset_findbyname will find the object in objset having the given name, + * and return the object if found, and NULL otherwise. + * ign is a set of objects to ignore. + */ + +httpd_object *objset_findbyname(char *name, httpd_objset *ign, + httpd_objset *os); + +/* + * objset_findbyppath will find the object in objset having the given + * partial path entry. Returns object if found, NULL otherwise. + * ign is a set of objects to ignore. + */ + +httpd_object *objset_findbyppath(char *ppath, httpd_objset *ign, + httpd_objset *os); + + +#endif +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/protocol.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/protocol.h new file mode 100644 index 00000000000..d44705a60cc --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/protocol.h @@ -0,0 +1,27 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * protocol.h: Switch which protocol we're speaking. + * + * Currently only HTTP, but expected to include MTP in the future. + * + * Rob McCool + */ + + +#ifdef MCC_HTTPD +#include "http.h" +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/req.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/req.h new file mode 100644 index 00000000000..afe525150c6 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/req.h @@ -0,0 +1,216 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * req.h: Request-specific data structures and functions + * + * Rob McCool + */ + + +#ifndef REQ_H +#define REQ_H + + +#include "netsite.h" +#include "base/pblock.h" +#include "base/session.h" +#include "frame/objset.h" + +#include <sys/stat.h> + + + +/* ------------------------------ Constants ------------------------------- */ + + +#define REQ_HASHSIZE 10 +#define REQ_MAX_LINE 4096 + + +/* + * The REQ_ return codes. These codes are used to determine what the server + * should do after a particular module completes its task. + * + * Func type functions return these as do many internal functions. + */ + +/* The function performed its task, proceed with the request */ +#define REQ_PROCEED 0 +/* The entire request should be aborted: An error occurred */ +#define REQ_ABORTED -1 +/* The function performed no task, but proceed anyway. */ +#define REQ_NOACTION -2 +/* Tear down the session and exit */ +#define REQ_EXIT -3 + + + +/* ------------------------------ Structures ------------------------------ */ + + +typedef struct { + /* Server working variables */ + pblock *vars; + + /* The method, URI, and protocol revision of this request */ + pblock *reqpb; + /* Protocol specific headers */ + int loadhdrs; + pblock *headers; + + /* Server's response headers */ + pblock *srvhdrs; + + /* The object set constructed to fulfill this request */ + httpd_objset *os; + /* Array of objects that were created from .nsconfig files */ + httpd_objset *tmpos; + + /* The stat last returned by request_stat_path */ + char *statpath; + char *staterr; + struct stat *finfo; + +#ifdef MCC_PROXY + /* SOCKS request data */ + void *socks_rq; +#endif + +} Request; + + +/* ------------------------------ Prototypes ------------------------------ */ + + +/* + * request_create creates a new request structure. + */ + +Request *request_create(void); + +/* + * request_free destroys a request structure. + */ + +void request_free(Request *req); + + +/* + * Restarts a request for a given URI internally. If rq is non-NULL, the + * function will keep the old request's headers and protocol, but with a new + * URI and method of GET. If the previous method was HEAD, this is preserved. + * Any other method becomes GET. You may assume that if you give it a request + * structure that it will use the same structure. + * + * Once you have this new Request, you must then do what you want with + * it (e.g. send the object back, perform uri2path translation, etc.) + */ + +Request *request_restart_internal(char *uri, Request *rq); + + +/* + * request_translate_uri performs virtual to physical mapping on the given + * uri and returns either a path string or NULL depending on whether it was + * successful or not. + */ + +char *request_translate_uri(char *uri, Session *sn); + + +/* + * request_header finds the named header depending on the requesting + * protocol. If possible, it will not load headers until the first is + * requested. You have to watch out because this can return REQ_ABORTED. + */ + +int request_header(char *name, char **value, Session *sn, Request *rq); + +/* + * request_loadheaders just makes sure the headers have been loaded. + */ + +int request_loadheaders(Session *sn, Request *rq); + + +/* + * request_stat_path tries to stat path. If path is NULL, it will look in + * the vars pblock for "path". If the stat is successful, it returns the stat + * structure. If not, returns NULL and leaves a message in rq->staterr. If a + * previous call to this function was successful, and path is the same, the + * function will simply return the previously found value. + * + * User functions should not free this structure. + */ + +struct stat *request_stat_path(char *path, Request *rq); + + +/* + * Parses the URI parameter in rq->vars and finds out what objects it + * references (using NameTrans). Builds the request's object set. + */ + +int request_uri2path(Session *sn, Request *rq); + +/* + * Performs any path checks needed for this request. + */ + +int request_pathchecks(Session *sn, Request *rq); + +/* + * Does all the ObjectType directives for a request + */ + +int request_fileinfo(Session *sn, Request *rq); + + +/* + * request_handle_processed takes a Request structure with its reqpb + * block filled in and handles the request. + */ + +int request_handle_processed(Session *sn, Request *rq); + + +/* + * Complete a request by finding the service function and using it. Returns + * REQ_NOACTION if no matching function was found. + */ + +int request_service(Session *sn, Request *rq); + + +/* + * request_handle handles one request from the session's inbuf. + */ + +void request_handle(Session *sn); + +/* + * Moved here due to problems with interdependency. See object.h for + * description. + */ + +int object_findnext(Session *sn, Request *rq, httpd_object *obj); +int object_pathcheck(Session *sn, Request *rq, httpd_object *obj); +int object_findinfo(Session *sn, Request *rq, httpd_object *obj); +int object_findservice(Session *sn, Request *rq, httpd_object *obj); +int object_finderror(Session *sn, Request *rq, httpd_object *obj); +int object_findlogs(Session *sn, Request *rq, httpd_object *obj); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/servact.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/servact.h new file mode 100644 index 00000000000..9e6df32c6d4 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/frame/servact.h @@ -0,0 +1,26 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * servact.h: Define the server's actions, depending on what type of + * server it is. + * + * Rob McCool + */ + + +#if defined(MCC_HTTPD) || defined(MCC_PROXY) || defined(MCC_NEWS) +#include "httpact.h" +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/netsite.h b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/netsite.h new file mode 100644 index 00000000000..80f114d3fb5 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-includes/netsite.h @@ -0,0 +1,67 @@ +/* + * $Id$ + * + * Copyright (c) 1994, 1995. Netscape Communications Corporation. All + * rights reserved. + * + * Use of this software is governed by the terms of the license agreement for + * the Netscape Communications or Netscape Comemrce Server between the + * parties. + */ + + +/* ------------------------------------------------------------------------ */ + + +/* + * Standard defs for NetSite servers. + */ + + +#ifndef NETSITE_H +#define NETSITE_H + +#ifdef MCC_PROXY +#define MAGNUS_VERSION "1.1m" +#define MAGNUS_VERSION_STRING "Netscape-Proxy/1.1m" + +#elif defined(MCC_ADMSERV) +#define MAGNUS_VERSION "1.1" +#define MAGNUS_VERSION_STRING "Netscape-Administrator/1.1" + +#elif defined(MCC_HTTPD) +#define MAGNUS_VERSION "1.1" +#ifdef NET_SSL +#define MAGNUS_VERSION_STRING "Netscape-Commerce/1.12" +#else +#define MAGNUS_VERSION_STRING "Netscape-Communications/1.12" +#endif + +#elif defined(MCC_NEWS) +#define MAGNUS_VERSION_STRING "Netscape 1.1" +#endif + +/* Used in some places as a length limit on error messages */ +#define MAGNUS_ERROR_LEN 8192 + +/* Carraige return and line feed */ +#define CR 13 +#define LF 10 + +/* -------------------------- Memory allocation --------------------------- */ + + +/* Later change these to have catastrophic error handling */ + +#include <stdlib.h> + +#define MALLOC(sz) malloc(sz) +#define FREE(ptr) free((void *)ptr) +#define STRDUP(str) strdup(str) +#define REALLOC(ptr,sz) realloc(ptr,sz) + + +/* Not sure where to put this. */ +void magnus_atrestart(void (*fn)(void *), void *data); + +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-send.c b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-send.c new file mode 100644 index 00000000000..70e99d33a87 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/nsapi-send.c @@ -0,0 +1,88 @@ +/* $Id$ */ +/* + * Send random bits file + * Once this service function is installed, any file with the extension + * "dyn-send" will be serviced with this function. An optional query + * string may be passed to alter the amount of data in the response. + * + * For example: + * /file.dyn-send - returns a 10240 byte file + * /file.dyn-send?size=20 - returns a 20 byte file + * /file.dyn-send?size=1024 - returns a 1024 byte file + * etc. + * + * To install the service routine, compile it as per the makefile + * included with your Netscape server distribution (serverroot/nsapi/examples) + * and then add the following lines to your netscape server configuration: + * + * in magnus.conf + * Init fn=load-modules shlib=example.so funcs=nsapi-send + * + * in obj.conf + * Service method=(GET|HEAD) fn=nsapi-send type=magnus-internal/dyn-send + * + * in mime.types + * type=magnus-internal/dyn-send exts=dyn-send + * + * Mike Belshe + * mbelshe@netscape.com + * 11-5-95 + * + */ + +#ifndef WIN32 +#include <stdio.h> +#include <stdlib.h> +#include "base/pblock.h" +#include "base/session.h" +#include "frame/protocol.h" +#include "base/util.h" +#include "frame/http.h" +#else +#include <windows.h> +#define FILE_STDIO 1 +#endif +#include "frame/req.h" + +#define FILE_SIZE 10240 +#define HEADERS "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" + +#ifdef WIN32 +__declspec(dllexport) +#endif + +int nsapi_send(pblock *pb, Session *sn, Request *rq) +{ + char *query_string; + char buffer[sizeof(HEADERS) + 204800 + 1]; + int filesize; + unsigned int maxindex; + unsigned int index; + + /* Get the query string, if any; check to see if an alternate + * file size was specified. + */ + if ( !(query_string = pblock_findval("query", rq->reqpb)) ) + filesize = FILE_SIZE; + else { + filesize = atoi(&(query_string[5])); + } + + memcpy(&buffer, HEADERS, sizeof(HEADERS)-1); + + /* Generate the output */ + maxindex = sizeof(HEADERS) + filesize; + for (index=sizeof(HEADERS); index < (maxindex); index++) + /* generate random characters from A-Z */ +#ifdef IRIX + buffer[index] = rand_r() % 26 + 63; +#else + buffer[index] = rand() %26 + 63; +#endif + + /* Send the output */ + if (net_write(sn->csd, buffer, sizeof(HEADERS)-1+filesize, 0) == IO_ERROR) + return REQ_EXIT; + + return REQ_PROCEED; +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/parse_file_list.c b/ACE/apps/JAWS/clients/WebSTONE/src/parse_file_list.c new file mode 100644 index 00000000000..dd433adf79c --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/parse_file_list.c @@ -0,0 +1,290 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 <stdio.h> +#include <errno.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> + +#ifndef WIN32 +#include <netdb.h> +#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 <netinet/in.h> +#else +#include <windows.h> +#include <process.h> +#include <time.h> +#include <winsock.h> +#endif /* WIN32 */ + +#include <ctype.h> + +#include "sysdep.h" +#include "bench.h" + + +/* + * count_file_list() + * given a filename, return a guess at the number of pages + */ +int +count_file_list(const char *url_list_file) +{ + FILE *fp; + long int num_of_pages; + char a_line[BUFSIZ]; + char *textvalue; + int returnval; + + fp = fopen(url_list_file, "r"); + + if (fp == 0) + { + D_PRINTF( "Error %d opening filelist %s: %s\n", + errno, url_list_file, strerror(errno) );; + return(returnerr("Error %d opening filelist %s: %s\n", + errno, url_list_file, strerror(errno))); + } + else + { + num_of_pages = 0; + D_PRINTF( "Opened file, about to count\n" ); + /* + * parse through the file line-by-line + * strip out comments, but don't check for URL consistency + */ + while (fgets(a_line, BUFSIZ, fp) != 0) + { + textvalue = a_line; + /* check for comments */ + if (strchr(textvalue, '#') != 0) + { + /* throw out anything after any '#' */ + D_PRINTF( "Stripping comment from line: %s\n", textvalue ); + returnval = strcspn(textvalue, "#"); + D_PRINTF( "Found first # at %d\n", returnval ); + if (returnval == 0) + { + textvalue = 0; + } + } + /* is there more? */ + if (textvalue != 0) + { + num_of_pages++; + D_PRINTF( "Found %ld pages\n", num_of_pages ); + } + } + return(num_of_pages); + } + fclose(fp); +} /* end count_file_list() */ + +/* + * parse_file_list() + * given a filename, a pointer to a page list, and pointers to integers + * for the number of pages and the number of files, parse its contents. + */ +void +parse_file_list (const char *url_list_file, page_list_t *page_list, + long int *num_of_pages, long int *num_of_files) +{ + FILE *fp; + int filenum; + int returnval; + int loadnum; + char a_line[BUFSIZ]; + char tempbuf[BUFSIZ]; + char *textvalue; + int numfiles = 1, numpages = 0; + int maxpages = *num_of_pages; + page_list_t *pp; + + extern int haveproxyserver; + + fp = fopen(url_list_file, "r"); + + if (fp == 0) + { + errexit("Error %d opening filelist: %s\n", errno, strerror(errno)); + } + else + { + /* + * GRAB A LINE. FORMAT IS: URL WEIGHTINGFACTOR + * EXAMPLE: http://www/file.html 1 + */ + D_PRINTF( "File is open.\n" ); + while(fgets(a_line, BUFSIZ, fp) != 0) + { + textvalue = a_line; + /* check for comments */ + if (strchr(textvalue, '#') != 0) + { + /* throw out anything after a '#' */ + D_PRINTF( "Stripping comment from line: %s\n", textvalue ); + returnval = strcspn(textvalue, "#"); + D_PRINTF( "Found first # at %d\n", returnval ); + if (returnval == 0) + continue; + } + + if (numpages >= *num_of_pages) + errexit("Out of space in parse_file_list()\n"); + + pp = &page_list[numpages]; + + D_PRINTF( "Processing page %ld\n", numpages ); + loadnum = 0; + + if (textvalue != 0) { /* is there more? */ + /* check for weighting factor */ + D_PRINTF( "Setting page values from: %s\n", textvalue ); + returnval = sscanf(textvalue, "%s%d", tempbuf, &loadnum); + D_PRINTF( "Scan for weighting returns %d, %d\n", + returnval, loadnum ); + if (returnval == EOF || loadnum <= 0) + { + pp->load_num = 1; + } + else + { + pp->load_num = loadnum; + } + D_PRINTF( "Setting load=%d for line: %s\n", + pp->load_num, textvalue ); + + /* placeholder for grouping multiple files onto one page */ + pp->num_of_files = 1; + filenum = 0; + + textvalue = tempbuf; + D_PRINTF( "Line is now: %s\n", textvalue ); + + /* + * if we've got a proxy server, we'll assume that the + * remaining text is a valid URL, and stuff it into + * page_list[numpages].filename[filenum] + * Otherwise, we'll have to parse it out. + */ + + if (haveproxyserver) + { + pp->servername[filenum] = 0; + pp->port_number[filenum] = 0; + strcpy(pp->filename[filenum], textvalue); + } + else /* no proxy server, so we have to parse it out... */ + { + /* try http://server(:port)/file */ + D_PRINTF( "Trying http://server(:port)/filename\n" ); + returnval = sscanf(textvalue, "http://%[^/]%s", + tempbuf, + a_line); + /* check server string for :port */ + if (returnval != 0 && returnval != EOF) + { + D_PRINTF( "Setting filename %s\n", a_line ); + strcpy(pp->filename[filenum], + a_line); + + D_PRINTF( "Checking %s for :portnumber\n", tempbuf ); + returnval = sscanf(tempbuf, "%[^:]:%d", + a_line, + &pp->port_number[filenum]); + + if (returnval < 2) + { + pp->port_number[filenum] = 80; + } + if (returnval == EOF) + { + pp->servername[filenum] = 0; + } + else + { + D_PRINTF( "Port number %d, setting server %s\n", + pp->port_number[filenum], + a_line ); + + strcpy(pp->servername[filenum], a_line); + } + + D_PRINTF( "Server %s, port number %d\n", + pp->servername[filenum], + pp->port_number[filenum] ); + } + else /* no good - try straight filename */ + { + pp->port_number[filenum] = 80; + D_PRINTF( "Trying filename, returnval=%d\n", + returnval ); + pp->servername[filenum] = 0; + D_PRINTF( "Server %s, port number %d\n", + pp->servername[filenum], + pp->port_number[filenum] ); + returnval = sscanf(textvalue, "%s", a_line); + D_PRINTF( "Scan returned filename %s\n", a_line ); + + strcpy(pp->filename[filenum], a_line); + } /* end of parsing */ + } /* end if haveproxyserver */ + + D_PRINTF( "Done parsing line\n" ); + D_PRINTF( "Got server %s, port %d, file %s, returnval %d\n", + pp->servername[filenum], + pp->port_number[filenum], + pp->filename[filenum], + returnval ); + } /* end if textvalue not NULL */ + + numpages++; + } /* end while not EOF */ + if (numpages < 1) + { + returnerr("No files are specified by filelist\n"); + } + } /* end if file ok */ + fclose(fp); + D_PRINTF( "Returning %ld pages and %ld files\n", + numpages, numfiles ); + + *num_of_pages = numpages; + *num_of_files = numfiles; +} +/* end parse_file_list */ + +long int +load_percent(page_list_t *page_list, long int number_of_pages) +{ + int i; + long int index_number = 0; + + for (i = 0; i < number_of_pages; i++) + { + index_number += page_list[i].load_num; + } + + D_PRINTF( "load_percent returning %d\n", (index_number) ); + return(index_number); +} + diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/parse_file_list.h b/ACE/apps/JAWS/clients/WebSTONE/src/parse_file_list.h new file mode 100644 index 00000000000..715686228db --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/parse_file_list.h @@ -0,0 +1,20 @@ +/* $Id$ */ +/************************************************************************** + * * + * Copyright (C) 1995 Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs where * + * deveolped by SGI for public use. If anychanges are made to this code * + * please try to get the changes back to the author. Feel free to make * + * modfications and changes to the code and release it. * + * * + **************************************************************************/ +#ifndef __PARSE_FILE_LIST_H__ +#define __PARSE_FILE_LIST_H__ + +extern int count_file_list(const char *); + +extern void parse_file_list (char *, page_list_t *, + long int *, long int *); + +#endif /* !__PARSE_FILE_LIST_H__ */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/rexec.c b/ACE/apps/JAWS/clients/WebSTONE/src/rexec.c new file mode 100644 index 00000000000..acbf2253bf1 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/rexec.c @@ -0,0 +1,373 @@ +/* $Id$ */ +/* + * Copyright (c) 1994-1995 Ataman Software, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Ataman Software, Inc. + * 4. The name of Ataman Software, Inc. may not may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY ATAMAN SOFTWARE, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL ATAMAN SOFTWARE, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +static char copyright[] = + "Copyright (c) 1994-1995 Ataman Software, Inc. All rights reserved."; + + +#pragma warning(disable: 4699) +/* Includes for Win32 systems go here. */ +#define STRICT +#pragma warning(disable: 4201) +#include <windows.h> +#pragma warning(default: 4201) +#include <winsock.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <process.h> +#include <signal.h> +#include "sysdep.h" +#include "bench.h" + +#define RETVAL DWORD +#define IDENT HANDLE +#define STDINPUT hStdIn +#define STDOUTPUT hStdOut +#define STDERROR hStdErr +#define FILECOOKIE HANDLE + +static void PassOutputThread(SOCKET); +static void PassErrorThread(SOCKET); + +HANDLE hStdIn, hStdOut, hStdErr; + + + +/* +Think carefully before enabling the -p option. While it may be +convenient to have this option, it is for many (if not most) sites a +security hole. Remember that the '-p password' used on the command +line is visible on most Unix systems to any user that is allow to run +the 'ps' command (normally ALL users can run this command). While no +utility that comes by default with Windows NT at this time shows the +same information, it is unclear whether or not the information is +avaiable to all users. Certainly privileged users would be be able to +see this information on any system. + +If the security risk is acceptable at your site, you can enable the -p +option by uncommenting the #define below. +*/ +/* #define ALLOWDASH_P */ + +static void MyOpenService(const char *remote_host); +static BOOL Send(SOCKET, const char *, size_t); +static BOOL SendZString(const char *); +static BOOL GetErrString(char *, size_t); + +static IDENT PassInput(void); +static IDENT PassOutput(void); +static IDENT PassError(void); +static BOOL Close(FILECOOKIE); +static int Read(FILECOOKIE, char *, size_t); +static BOOL Write(FILECOOKIE, const char *, size_t); +static void Wait(IDENT, RETVAL *); + +static SOCKET sIO = INVALID_SOCKET; +static SOCKET sErr = INVALID_SOCKET; + +IDENT idIn = 0; +IDENT idOut, idErr; + +SOCKET rexec(const char **hostname, NETPORT port, char *username, char *password, + char *command, SOCKET *sockerr) +{ + + MyOpenService(*hostname); + + SendZString(username); + SendZString(password); + SendZString(command); + + if (!GetErrString(command, sizeof command)) { + errexit("Rexec: Remote aborted connection without initiating protocol: %s.\n", + neterrstr()); + } + + if (*command != '\0') { + char *p = command; + if (*p == '\001') { + p++; + } + errexit("Rexec: Remote aborted connection: %s\n", p); + } + + hStdIn = GetStdHandle(STD_INPUT_HANDLE); + hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + hStdErr = GetStdHandle(STD_ERROR_HANDLE); + + *sockerr = sErr; + return sIO; +} + + +static void MyOpenService(const char *remote_host) +{ + struct sockaddr_in server_addr, my_err_addr, junk_addr; + struct servent *sv; + static char portbuf[30]; + SOCKET sTmp; + int addr_len; + + if (remote_host[0] >= '0' && remote_host[0] <= '9') { + unsigned long addr; + + addr = inet_addr(remote_host); + if (addr == INADDR_NONE) { + returnerr("Invalid IP address %s\n", remote_host); + return; + } + server_addr.sin_addr.S_un.S_addr = addr; + } else { + struct hostent *hent; + + hent = gethostbyname(remote_host); + if (hent == 0) + { + D_PRINTF( "Can't get %s host entry\n", remote_host ); + D_PRINTF( "Gethostbyname failed: %d", WSAGetLastError() ); + errexit("Rexec: gethostbyname(%s) failed: %s\n", + remote_host, neterrstr()); + } + memcpy((char *)&server_addr.sin_addr, hent->h_addr, hent->h_length); +} + +#ifdef OMIT + hent = gethostbyname(remote_host); + if(!hent) { + errexit("Rexec: Lookup of server hostname failed: %s.\n", + neterrstr()); + } +#endif /* OMIT */ + + sv=getservbyname("exec", "tcp"); + if (!sv) { + errexit("Rexec: Lookup of port number for rexec service failed: %s.\n", + neterrstr()); + } + + server_addr.sin_family = PF_INET; + server_addr.sin_port = htons(sv->s_port); + + if((sIO=socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { + errexit("Rexec: I/O socket creation failed: %s.\n", + neterrstr()); + } + + if(connect(sIO, (struct sockaddr *)&server_addr, sizeof server_addr) == SOCKET_ERROR) { + errexit("Rexec: I/O socket connection failed: %s.\n", + neterrstr()); + } + + memset(&my_err_addr, '\0', sizeof my_err_addr); + my_err_addr.sin_addr.s_addr = htonl(INADDR_ANY); + my_err_addr.sin_family = AF_INET; + my_err_addr.sin_port = 0; + + if ((sTmp=socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { + errexit("Rexec: Error socket creation failed: error=%s.\n", + neterrstr()); + } + + if (bind(sTmp, (struct sockaddr *)&my_err_addr, sizeof my_err_addr) == SOCKET_ERROR) { + errexit("Rexec: Error socket bind failed: %s.\n", + neterrstr()); + (void) closesocket(sTmp); + } + + if (listen(sTmp, 1) == SOCKET_ERROR) { + errexit("Rexec: Error socket listen failed: %s.\n", + neterrstr()); + (void) closesocket(sTmp); + } + + addr_len = sizeof my_err_addr; + if (getsockname(sTmp, (struct sockaddr *)&my_err_addr, &addr_len) == SOCKET_ERROR) { + errexit("Rexec: Error socket bind failed: %s.\n", + neterrstr()); + (void) closesocket(sTmp); + } + + sprintf(portbuf, "%hu", ntohs(my_err_addr.sin_port)); + SendZString(portbuf); + + addr_len = sizeof junk_addr; + if ((sErr = accept(sTmp, (struct sockaddr *)&junk_addr, &addr_len)) + == INVALID_SOCKET) { + errexit("Rexec: Error socket accept failed: %s.\n", + neterrstr()); + (void) closesocket(sTmp); + } + + (void) closesocket(sTmp); +} + + + +static BOOL Send(SOCKET s, const char *buf, size_t nbuf) +{ + int cnt; + size_t sent = 0; + + while (sent < nbuf) { + cnt = send(s, &buf[sent], nbuf-sent, 0); + if (cnt == -1) { + return FALSE; + } + sent += cnt; + } + return TRUE; +} + + +static BOOL SendZString(const char *str) +{ + return Send(sIO, str, strlen(str)+1); +} + + +static BOOL GetErrString(char *str, size_t len) +{ + size_t pos = 0; + + while (pos < len) { + char ch; + if (recv(sIO, &ch, 1, 0) != 1) { + return FALSE; + } + str[pos++] = ch; + if (ch == '\0') { + return TRUE; + } + if (ch == '\n') { + return TRUE; + } + } + return FALSE; +} + + +static IDENT PassOutput() +{ + IDENT id; + id = (IDENT)_beginthread(PassOutputThread, 4096, (void *)sIO); + if ((long)id == -1) { + errexit("Rexec: Could not start output passing thread: error = %lu\n", GetLastError()); + } + return id; +} + +static void PassOutputThread(SOCKET sIO) +{ + RETVAL retval = 0; + int count; + char buf[4096]; + + while ((count=recv(sIO, buf, sizeof buf, 0)) > 0) { + if (!Write(STDOUTPUT, buf, count)) { + fprintf(stderr, "Error writing to standard output: error = %lu.\n", GetLastError()); + retval = 1; + break; + } + } + + _endthread(); +} + + +static IDENT PassError() +{ + IDENT id; + id = (IDENT)_beginthread(PassErrorThread, 4096, (void *)sErr); + if ((long)id == -1) { + errexit("Rexec: Could not start error passing thread: error = %lu\n", GetLastError()); + } + return id; +} + +static void PassErrorThread(SOCKET sErr) +{ + RETVAL retval = 0; + int count; + char buf[4096]; + + while ((count=recv(sErr, buf, sizeof buf, 0)) > 0) { + if (!Write(STDERROR, buf, count)) { + fprintf(stderr, "Error writing to standard error: error = %lu.\n", GetLastError()); + retval = 1; + break; + } + } + _endthread(); +} + +static BOOL Close(FILECOOKIE fc) +{ + return CloseHandle(fc); +} + +static int Read(FILECOOKIE fc, char *buf, size_t nbuf) +{ + DWORD cbRead; + if (!ReadFile(fc, buf, nbuf, &cbRead, 0)) { + return -1; + } + return (int)cbRead; +} + + +static BOOL Write(FILECOOKIE fc, const char *buf, size_t nbuf) +{ + DWORD cbWritten; + + if (!WriteFile(fc, buf, nbuf, &cbWritten, 0)) { + return FALSE; + } + if (cbWritten != nbuf) { + return FALSE; + } + return TRUE; +} + + +static void +Wait(IDENT id, RETVAL *prv) +{ + if (!WaitForSingleObject(id, INFINITE)) { + *prv = 2; + } else { + if (!GetExitCodeThread(id, prv)) { + *prv = 4; + } + } +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/statistics.c b/ACE/apps/JAWS/clients/WebSTONE/src/statistics.c new file mode 100644 index 00000000000..efc82c96e9a --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/statistics.c @@ -0,0 +1,49 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 <math.h> +#include <stdlib.h> +#include "sysdep.h" +#include "bench.h" + + +double +mean(const double sum, const int n) +{ + if (n) + { + return(sum / n); + } + else + { + return(0); + } +} + + +double +variance(const double sum, const double sumofsquares, const int n) +{ + double meanofsum; + + meanofsum = mean(sum, n); + + return (mean(sumofsquares,n) - (meanofsum * meanofsum)); +} + + +double +stddev(const double sum, const double sumofsquares, const int n) +{ + return(sqrt(fabs(variance(sum, sumofsquares, n)))); +} diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/statistics.h b/ACE/apps/JAWS/clients/WebSTONE/src/statistics.h new file mode 100644 index 00000000000..9f4bea75229 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/statistics.h @@ -0,0 +1,9 @@ +#ifndef _STATISTICS_H_ +#define _STATISTICS_H_ +/* $Id$ */ + +extern double mean(const double, const int); +extern double variance(const double, const double, const int); +extern double stddev(const double, const double, const int); + +#endif /* ! _STATISTICS_H_ */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/sysdep.c b/ACE/apps/JAWS/clients/WebSTONE/src/sysdep.c new file mode 100644 index 00000000000..0976cf1df66 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/sysdep.c @@ -0,0 +1,51 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 "sysdep.h" +/* strerror() */ +#ifndef HAVE_STRERROR +/* strerror is not available on SunOS 4.1.3 and others */ +extern int sys_nerr; +extern char *sys_errlist[]; +extern int errno; + +char *strerror(int errnum) +{ + + if (errnum<sys_nerr) + { + return(sys_errlist[errnum]); + } + + return(0); +} + +#endif /* strerror() */ + + +/* stub routines for NT */ + +#ifdef WIN32 +#include <winsock.h> +#include <process.h> + +int getpid(void) { + + return GetCurrentThreadId(); +} + +void sleep(int sec) { + + Sleep(sec*1000); +} +#endif /* WIN32 */ + diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/sysdep.h b/ACE/apps/JAWS/clients/WebSTONE/src/sysdep.h new file mode 100644 index 00000000000..6dcb23e4a18 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/sysdep.h @@ -0,0 +1,133 @@ +#ifndef __SYSDEP_H__ +#define __SYSDEP_H__ +/* $Id$ */ +/************************************************************************** + * * + * 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 config.h, output from autoconf */ +#ifdef HAVE_CONFIG_H +#ifndef __CONFIG_H__ +#define __CONFIG_H__ +#include "config.h" +#endif +#endif + +#ifdef WIN32 +#include <windows.h> +#include <winsock.h> +#endif /* WIN32 */ + +/* MAXHOSTNAMELEN is undefined on some systems */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +//FUZZ: disable check_for_NULL +/* SunOS doesn't define NULL */ +#ifndef NULL +#define NULL 0 +#endif +//FUZZ: enable check_for_NULL + +/* encapsulation of minor UNIX/WIN NT differences */ +#ifdef WIN32 +#define NETREAD(sock, buf, len) recv(sock, buf, len, 0) +#define NETWRITE(sock, buf, len) send(sock, buf, len, 0) +#define NETCLOSE(sock) closesocket(sock) +#define BADSOCKET(sock) ((sock) == INVALID_SOCKET) +#define BADSOCKET_ERRNO(sock) BADSOCKET(sock) +#define BADSOCKET_VALUE INVALID_SOCKET +#define S_ADDR S_un.S_addr + +#ifdef USE_TIMEZONE +#error NT gettimeofday() doesn't support USE_TIMEZONE (yet) +#else +#define GETTIMEOFDAY(timeval, tz) gettimeofday(timeval) +#endif /* USE_TIMEZONE */ + +typedef unsigned short NETPORT; +#define SRANDOM srand +#define RANDOM_R rand_r +#define RANDOM rand +#define THREAD __declspec ( thread ) +#define PROGPATH "c:\\webstone\\webclient" +#define FILENAME_SIZE 256 +#define HAVE_VPRINTF 1 + +#define SIGCHLD 0 /* dummy value */ +#define SIGALRM 0 /* dummy value */ +typedef int pid_t; +typedef unsigned short ushort; +#define MAXPATHLEN 512 + + + +#else /* not WIN32 */ +#define NETREAD(sock, buf, len) read(sock, buf, len) +#define NETWRITE(sock, buf, len) write(sock, buf, len) +#define NETCLOSE(sock) close(sock) +#define BADSOCKET(sock) ((sock) < 0) +#define BADSOCKET_ERRNO(sock) (BADSOCKET(sock) || errno) +#define BADSOCKET_VALUE (-1) +#define S_ADDR s_addr + +#ifdef USE_TIMEZONE +#define GETTIMEOFDAY(timeval,tz) gettimeofday(timeval, 0) +#else +#define GETTIMEOFDAY(timeval,tz) gettimeofday(timeval, tz) +#endif /* USE_TIMEZONE */ + +typedef unsigned short NETPORT; +#define SRANDOM srandom +#define RANDOM random +#define THREAD +#define PROGPATH "/tmp/webclient" /* "/usr/local/bin/webclient" */ +#define FILENAME_SIZE 1024 +#define HAVE_VPRINTF 1 + +typedef int SOCKET; +#define min(a,b) (((a) < (b)) ? a : b) +#define max(a,b) (((a) > (b)) ? a : b) +#endif /* WIN32 */ + + +/* function prototypes */ + +#ifdef WIN32 +int getopt(int argc, char ** argv, char *opts); +int getpid(void); +int gettimeofday(struct timeval *curTimeP); +int random_number(int max); +SOCKET rexec(const char **hostname, NETPORT port, char *username, char *password, + char *command, SOCKET *sockerr); +void sleep(int secs); + +#else +#ifdef NO_REXEC +extern int rexec(char **, int, char *, char *, char *, int *); +#endif +#endif /* WIN32 */ + + +#ifndef HAVE_STRERROR +/* strerror() is not available on SunOS 4.x and others */ +char *strerror(int errnum); + +#endif +/* strerror() */ + + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif + +/* !__SYSDEP_H__ */ +#endif diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/timefunc.c b/ACE/apps/JAWS/clients/WebSTONE/src/timefunc.c new file mode 100644 index 00000000000..fe38d821eac --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/timefunc.c @@ -0,0 +1,171 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 */ +#ifndef WIN32 +#include <netdb.h> +#include <sys/time.h> +#include <sys/param.h> +#else +#include <windows.h> +#include <winsock.h> +#include <time.h> +#endif /* WIN32 */ +#include <math.h> +#include <stdio.h> +#include "sysdep.h" +#include "bench.h" + +double +timevaldouble(struct timeval *tin) +{ + return ((double)tin->tv_sec + ((double)tin->tv_usec / USECINSEC)); +} + + +void +doubletimeval(const double tin, struct timeval *tout) +{ + tout->tv_sec = (long)floor(tin); + tout->tv_usec = (long)((tin - tout->tv_sec) * USECINSEC ); +} + + +void +addtime(struct timeval *OrigTime, struct timeval *NewTime) +{ + OrigTime->tv_usec += NewTime->tv_usec; + if(OrigTime->tv_usec >= USECINSEC) + { + /* + * NEED TO CARRY 1. + */ + OrigTime->tv_sec++; + OrigTime->tv_usec -= USECINSEC; + } + OrigTime->tv_sec += NewTime->tv_sec; +} + + +void +compdifftime(struct timeval *EndTime, struct timeval *StartTime, struct timeval *DiffTime) +{ + struct timeval endtime = *EndTime; + + if((endtime.tv_usec - StartTime->tv_usec) < 0) + { + /* + * NEED TO BORROW. + */ + endtime.tv_usec += USECINSEC; + endtime.tv_sec--; + } + DiffTime->tv_usec = endtime.tv_usec - StartTime->tv_usec; + DiffTime->tv_sec = endtime.tv_sec - StartTime->tv_sec; +} + + +void +mintime(struct timeval *CurrMinTime, struct timeval *CheckMinTime) +{ + if(CheckMinTime->tv_sec < CurrMinTime->tv_sec) + { + *CurrMinTime = *CheckMinTime; + return; + } + if(CheckMinTime->tv_sec == CurrMinTime->tv_sec) + { + if(CheckMinTime->tv_usec < CurrMinTime->tv_usec) + { + *CurrMinTime = *CheckMinTime; + return; + } + } +} + + +void +maxtime(struct timeval *CurrMaxTime, struct timeval *CheckMaxTime) +{ + if(CheckMaxTime->tv_sec > CurrMaxTime->tv_sec) + { + *CurrMaxTime = *CheckMaxTime; + return; + } + if(CheckMaxTime->tv_sec == CurrMaxTime->tv_sec) + { + if(CheckMaxTime->tv_usec > CurrMaxTime->tv_usec) + { + *CurrMaxTime = *CheckMaxTime; + return; + } + } +} + +void +avgtime(struct timeval *TotalTime, int NumTimes, struct timeval *AvgTime) +{ + double meantime; + + meantime = mean(timevaldouble(TotalTime), NumTimes); + + doubletimeval(meantime, AvgTime); +} + + +void +sqtime(struct timeval *Time, struct timeval *SqTime) +{ + double sec; + + sec = timevaldouble(Time); + sec *= sec; /* square */ + + doubletimeval(sec, SqTime); +} + + +void +variancetime(struct timeval *SumTime, double SumSquareTime, int NumTimes, struct timeval *VarianceTime) +{ + double result; + + result = variance(timevaldouble(SumTime), SumSquareTime, NumTimes); + + doubletimeval(result, VarianceTime); +} + + +void +stddevtime(struct timeval *SumTime, double SumSquareTime, + int NumTimes, struct timeval *StdDevTime) +{ + double result; + + result = stddev(timevaldouble(SumTime), SumSquareTime, NumTimes); + + doubletimeval(result, StdDevTime); +} + +double +thruputpersec(const double n, struct timeval *t) +{ + double tv; + + tv = timevaldouble(t); + if (tv != 0) + return n / timevaldouble(t); + else + return 0; +} + + diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/timefunc.h b/ACE/apps/JAWS/clients/WebSTONE/src/timefunc.h new file mode 100644 index 00000000000..884aeea82d9 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/timefunc.h @@ -0,0 +1,30 @@ +/* $Id$ */ +/************************************************************************** + * 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. * + * * + **************************************************************************/ + +#ifndef __TIMEFUNC_H__ +#define __TIMEFUNC_H__ + +extern double timevaldouble(struct timeval *); +extern void doubletimeval(const double, struct timeval *); + +extern void addtime(struct timeval *, struct timeval *); +extern void compdifftime(struct timeval *, struct timeval *, struct timeval *); +extern void mintime(struct timeval *, struct timeval *); +extern void maxtime(struct timeval *, struct timeval *); +extern void avgtime(struct timeval *, int, struct timeval *); +extern void variancetime(struct timeval *, double, int, struct timeval *); +extern void stddevtime(struct timeval *, double, int, struct timeval *); + +extern void sqtime(struct timeval *, struct timeval *); + +extern double thruputpersec(const double, struct timeval *); + +#endif /* !__TIMEFUNC_H__ */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/webclient.c b/ACE/apps/JAWS/clients/WebSTONE/src/webclient.c new file mode 100644 index 00000000000..42084842904 --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/webclient.c @@ -0,0 +1,1299 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 <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 == 0) + { + 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,":")) == 0) + { + /* + * 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] != 0) + && + *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, 0, 0, &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 +ACE_TMAIN(int argc, ACE_TCHAR *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(0, 0, 1, 0); + if(hSemaphore == 0) + { + 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,":")) == 0) + { + /* + * 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 (0, 0, ClientThread, 0, THR_BOUND, 0); + + /* switch(fork()) + { + case 0: + numclients = 1; + ClientThread(0); + 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(0, 0, 0) == 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, 0) == -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, 0); + + 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 == 0) + 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(×tat); + + 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, 0); +#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, ×tat, 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, ×tat, 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, 0); + + 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(×tat); + 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() */ diff --git a/ACE/apps/JAWS/clients/WebSTONE/src/webmaster.c b/ACE/apps/JAWS/clients/WebSTONE/src/webmaster.c new file mode 100644 index 00000000000..1bfbcc06b9d --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/src/webmaster.c @@ -0,0 +1,1420 @@ +/* $Id$ */ +/************************************************************************** + * * + * 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 ) +struct sockaddr_in *serveraddr; +{ + int sock,len; + + /* + * SET UP THE SOCKET WE ARE GOING TO USE TO SYNCHRONIZE WITH THE CLIENTS. + */ + D_PRINTF( "About to call sock %d %d\n", portnum, MAXCLIENTS ); + + sock = passivesock(0, "tcp", MAXCLIENTS); + + if (BADSOCKET(sock)) + { + errexit("Couldn't open socket %d: %s\n", sock, neterrstr()); + } + D_PRINTF( "The passivesock call succeeded\n" ); + + D_PRINTF( "calling getsockname\n" ); + + len = sizeof(struct sockaddr); + if(getsockname(sock, (struct sockaddr *)serveraddr, &len) < 0) + { + errexit("Could not get socket informaton\n"); + } + + return( sock ); +} + +/* + Function which generates a commandline for the webclients +*/ +void MakeCmdLine( commandline) +char *commandline; +{ + char tmpcommandline[NCCARGS]; + char hostname[MAXHOSTNAMELEN]; + char *webclient_path, *temp; + int cnt; + struct hostent *master_phe_tmp; /* temp. variable added by - Rajesh Shah*/ + + /* + * BUILD THE PORTIONS OF THE cmdline FOR EACH CLIENT THAT WE CAN BUILD NOW. + * WE WILL FILL IN THE NUMBER OF CLIENTS LATER WITH AN sprintf. + */ + D_PRINTF( "Calling gethostname\n" ); + + if(gethostname(hostname,MAXHOSTNAMELEN) != 0) + { + errexit("Could not retrieve local host name"); + } else { + /* convert hostname to address (to avoid DNS problems for webclients) */ + /* The following lines are add to copy the system + buffer (output of gethostbyname()) into user area. + This is because, there are very good chances that later + on system buffer might be overwritten by some calls and + still if your pointer is pointing to same addr. nothing + but only trouble and trouble! Infact this is what + happening when I tried to run webstone benchmark for more + then one clients. It used to over write the webmaster name + with the first client name and so remaining on client(s) + the webclient process(es) were invoked with wrong webmaster + name! This behaviour is observed Solaris 2.4 this bug + can be hit in any OS. - Rajesh Shah 5/18/96 */ + + /* master_phe = gethostbyname(hostname); */ + master_phe_tmp = gethostbyname(hostname); + master_phe = (struct hostent *)malloc(sizeof(struct hostent)); + HostEntCpy(master_phe, master_phe_tmp); + } + + /* set up executable pathname */ +#ifndef WIN32 + temp = getenv("TMPDIR"); + + if ( temp && *temp ) { + webclient_path = (char *)mymalloc( strlen(temp) + strlen("/webclient") + + 1); + strcpy(webclient_path, temp); + strcat(webclient_path, "/webclient"); + + } else +#else + temp = temp; +#endif /* WIN32 */ + webclient_path = PROGPATH; + + + D_PRINTF( "Path to webclient is: %s\n", webclient_path ); + + sprintf(commandline,"%s", webclient_path); + + if(haveproxyserver) + { + sprintf(tmpcommandline, " -P %s", proxyserver); + strcat(commandline, tmpcommandline); + } + if (debug) + { + strcat(commandline," -d"); + } + if (numloops != 0) + { + sprintf(tmpcommandline," -l %d", numloops); + strcat(commandline,tmpcommandline); + } + if (portnum) + { + sprintf(tmpcommandline," -p %d", portnum); + strcat(commandline,tmpcommandline); + } + if (redirect) + { + strcat(commandline," -r"); + } + if (savefile) + { + strcat(commandline," -s"); + } + if (uil_filelist_f) + { + strcat(commandline," -u "); + strcat(commandline,uil_filelist); + } + if (record_all_transactions) + { + strcat(commandline," -R"); + } + if (testtime != 0) + { + sprintf(tmpcommandline," -t %d", testtime); + strcat(commandline,tmpcommandline); + } + + /* + * SET UP A SPACE FOR THE NUMBER OF CLIENTS ON THE commandline. + */ + sprintf(tmpcommandline,"%s -n %%d -w %%s -c %%s:%%d", commandline); + strcpy(commandline,tmpcommandline); + + if (uil_filelist_f == 0) + { + cnt = 0; + while(cnt < number_of_pages) + { + /* + * PUT THE FILES AT THE END OF THE LIST. + */ + strcat(commandline," "); + strcat(commandline,filelist[cnt]); + cnt++; + } + } + puts(commandline); +} + +/* + rexec to the client hosts and start the webclients +*/ +int RexecClients( commandline, clienthostname, serveraddr) +char *commandline; +char clienthostname[MAXCLIENTS][MAXHOSTNAMELEN]; +struct sockaddr_in *serveraddr; + +{ + int tmpfd; + int numclients = 0; + char tmpcommandline[NCCARGS]; + struct servent *inetport; + int cnt; + char buffer[NCCARGS]; + char login[MAXUSERNAME]; + char password[MAXPASSWD]; + FILE *fp; + int returnval; + char *tmphostname; + + memset(buffer, 0, sizeof(buffer)); + + /* + * OPEN UP THE CONFIG FILE. FOR EACH LINE IN THE CONFIG FILE, CHECK + * ITS VALIDITY AND THEN rexec A COMMAND ON THE CLIENT. + */ + + if ((fp = fopen(configfile,"r")) == 0) + { + errexit("Could not open config file %s\n", configfile); + } + + if ((inetport = getservbyname("exec","tcp")) == 0) + { + errexit("Could not get service name for exec/tcp\n"); + } + D_PRINTF( "getservbyname returned %d\n", ntohs(inetport->s_port) ); + + cnt = 0; + + D_PRINTF( "rexec loop\n" ); + while(1) + { + char webserver2[MAXHOSTNAMELEN]; + char linebuf[150]; + int num; + char *primename; + + if (0 == fgets(linebuf, sizeof(linebuf), fp)) + break; + num = sscanf(linebuf,"%s %s %s %d %s",clienthostname[cnt],login,password, + &numclients, webserver2); + if (num < 4) + break; + if (servaddrin_config) { + if (num == 4) { + errexit("No webserver specified in config file for %s\n", clienthostname[cnt]); + } + strcpy(webserver, webserver2); + } + + if (numclients <= 0) + errexit("Number of clients must be >= 0\n"); + if (numclients > MAXPROCSPERNODE) + { + errexit("Number of clients per node can't exceed %d\n", MAXPROCSPERNODE); + } + totalnumclients += numclients; + + primename = pick_webmaster_IP_address(clienthostname[cnt], master_phe, network_mask); + if (primename == 0) { + errexit("Bad client address %s for Client %d\n", clienthostname[cnt], cnt); + } + + fprintf(stdout,"Client %d: %s \t# Processes: %d\n Webserver: %s\tWebmaster: %s:%d\n", + cnt, clienthostname[cnt], numclients, webserver, primename, + ntohs(serveraddr->sin_port)); + fflush(stdout); + sprintf(tmpcommandline, commandline, numclients, webserver, primename, + ntohs(serveraddr->sin_port)); + + fprintf(stderr, "tmpcommandline: %s\n", tmpcommandline); + + D_PRINTF( "%s rexec %s\n",&clienthostname[cnt],tmpcommandline ); + if (norexec) { + sleep(30); /* gives some time to start clients for debugging */ + } else { + + tmphostname = &(clienthostname[cnt][0]); + tmpfd = rexec(&tmphostname, inetport->s_port, login, password, + tmpcommandline, &sockErr[cnt]); + if((sockIO[cnt] = tmpfd) < 0) + { + errexit("Could not rexec: rexec to client %s, cmdline %s failed\n", + clienthostname[cnt],tmpcommandline); + } + } + + + returnval = NETREAD(tmpfd, buffer, OKSTRLEN); + D_PRINTF( "read returns %d, %s\n", returnval, buffer ); + + if (returnval <= 0 || memcmp(buffer, OKSTR, OKSTRLEN) != 0) + { + errexit("rexec to client %s, cmdline %s received error %s\n", + clienthostname[cnt],tmpcommandline, buffer); + } + + + cnt++; + if (cnt > MAXCLIENTS || cnt > FD_SETSIZE) + { + errexit("Number of Clients can't exceed %d\n", MAXCLIENTS); + } + } + + num_rexecs = cnt; + if (totalnumclients > MAXTOTALPROCS) + { + errexit("Total number of processes can't exceed %d\n", + MAXTOTALPROCS); + } + +#ifndef WIN32 + /* NOW WE NEED TO HANDLE THE OUTPUT FROM THE REXEC. + * TO DO THIS, WE FORK, THEN HAVE ONE PROCESS READ FROM TMPFD. + * THE OTHER PROCESS CONTINUES WITH THE PROGRAM + */ + D_PRINTF( "Forking webclient stderr/stdout processes\n" ); + switch (fork()) + { + case -1: /* ERROR */ + errexit("fork: %s\n", strerror(errno)); + case 0: /* CHILD */ + exit(echo_client(clienthostname[cnt], tmpfd)); + default: /* PARENT */ + break; + } +#else + /* start threads to echo stdout/stderr from clients */ + _beginthread(echo_client, 0, (void *)0); + _beginthread(echo_client, 0, (void *)1); +#endif /* WIN32 */ + + fprintf(stdout,"\n"); + fprintf(stdout,"\n"); + fclose(fp); + + return totalnumclients; +} + +void GetReady( fdset, totalnumclients, sock ) +fd_set *fdset; +int totalnumclients; +int sock; +{ + int cnt,len; + fd_set tmpfdset, leftfdset; + char buffer[NCCARGS]; + + /* + * NOW WE NEED TO ACCEPT ALL THE CONNECTIONS FROM THE CLIENTS, + * ACCEPT ALL THE READY MESSAGES + */ + + D_PRINTF( "Beginning accept loop\n" ); + for (cnt = 0; cnt < totalnumclients; cnt++) + { + D_PRINTF( "Client %d:\t", cnt ); + + { + fd_set readfds; + struct timeval timeout; + int rv; + + timeout.tv_sec = MAX_ACCEPT_SECS; + timeout.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + + /* if we're hung, quit */ + D_PRINTF("Before select() on listen() socket\n"); + if (!(rv = select(FD_SETSIZE, &readfds, 0, 0, &timeout))) { + fprintf(stdout, + "Listen timeout after %d seconds (%d clients so far)\n", + MAX_ACCEPT_SECS, cnt); + D_PRINTF("select() timed out after %d seconds\n", MAX_ACCEPT_SECS); + errexit("Webmaster terminating\n"); + } + } + + if(BADSOCKET(socknum[cnt] = accept(sock, 0, 0))) + { + /* + * ERROR accepting FROM THE CLIENTS. WE NEED TO ISSUE AN + * ABORT TO ALL. + */ + abort_clients(); + errexit("Error accepting from one of the clients: %s", neterrstr()); + } else + { + /* + * SET THE FD IN THE MASK + */ + FD_SET(socknum[cnt],fdset); + } + D_PRINTF( "on socket %d\n",socknum[cnt] ); + } + D_PRINTF( "\n" ); + + /* + * WAIT FOR A READY. + */ + sleep(1); + fprintf(stdout,"Waiting for READY from %d clients\n",totalnumclients); + fflush(stdout); + leftfdset = *fdset; +#ifndef WIN32 + while(memcmp(&leftfdset,&zerofdset,sizeof(fd_set))) + { + tmpfdset = leftfdset; + + if(select(FD_SETSIZE,&tmpfdset,NULL,NULL,NULL) < 0) + { + /* + * ERROR SELECTING. ABORT ALL. + */ + abort_clients(); + errexit("Error accepting from one of the clients: %s\n", + neterrstr()); + break; + } +#else + /* I don't see why a select is needed at all--all clients must respond + * and there is no synchronization/timing issue. + */ + tmpfdset = leftfdset; + { +#endif /* WIN32 */ + + for (cnt = 0; cnt < totalnumclients; cnt++) + { + /* + * SEE WHICH SOCKETS HAVE A INPUT ON THEM PENDING + * AND RECEIVE IT. + */ + if(!BADSOCKET(socknum[cnt]) && (FD_ISSET(socknum[cnt],&tmpfdset))) + { + /* + * GET THE READY FROM THIS GUY. + * DON'T FORGET TO CLEAR HIS BIT IN THE tmpfdset + */ + len = NETREAD(socknum[cnt],buffer,READYSTRLEN); + if(len != READYSTRLEN) + { + abort_clients(); + errexit("Error reading from client #%d\n", cnt); + } + if(memcmp(buffer, READYSTR, READYSTRLEN)) + { + abort_clients(); + fprintf(stdout,"Received bad READY string: len %d, value %s\n", + len,buffer); + } + FD_CLR(socknum[cnt],&leftfdset); + } + } + } + sleep(1); + fprintf(stdout,"All READYs received\n"); + fflush(stdout); +} + +/* + Start all the clients by sending them a GO signal + totalnumclients is the total number of clients + socknum is an int array with the filedescriptors for all the + client connections +*/ +void SendGo( totalnumclients, socknum) +int totalnumclients; +int *socknum; +{ + int cnt; + fprintf(stdout,"Sending GO to all clients\n"); + for(cnt = 0; cnt < totalnumclients; cnt++) + { + if(socknum[cnt] > 0) + { + /* + * SEND A GO + */ + if(NETWRITE(socknum[cnt], GOSTR, GOSTRLEN) != GOSTRLEN) + { + abort_clients(); + errexit("Error sending GO to client %d: %s\n", cnt, neterrstr()); + } + } + } +} + +/* + This function gathers statistics from all the clients +*/ + +void GetResults(fdset, page_stats, endtime, timestr, totalnumclients, + statarray) +fd_set *fdset; +page_stats_t **page_stats; +time_t *endtime; +char *timestr; +int totalnumclients; +stats_t statarray[MAXCLIENTS]; +{ + fd_set leftfdset,tmpfdset; + char *stats_as_text; + char *page_stats_as_text; + int returnval; + int cnt,i; + + + /* DOESN'T ACTUALLY PRINT UNTIL THE FIRST CLIENT REPORTS */ + fprintf(stdout,"Reading results "); + + /* + * COPY THE FILE DESCRIPTORS TO A TMP LIST, + * ALLOCATE MEMORY FOR STATS, PAGESTATS IN TEXT FORM + */ + leftfdset = *fdset; + stats_as_text = (char *)mymalloc(SIZEOF_STATSTEXT+1); + page_stats_as_text = (char *)mymalloc(SIZEOF_PAGESTATSTEXT+1); + + /* + * COPY THE FILE DESCRIPTORS TO A TMP LIST, + * PLUS A LIST OF REMAINING FDs + */ + leftfdset = *fdset; + /* + * LOOP UNTIL ALL CLIENTS HAVE REPORTED + * AND tmpfdset IS EMPTY + */ +#ifndef WIN32 + while(memcmp(&leftfdset,&zerofdset,sizeof(fd_set))) + { + tmpfdset = leftfdset; + sleep(1); + returnval = select(FD_SETSIZE,&tmpfdset,NULL,NULL,NULL); + D_PRINTF( "Call to select returned %d, errno %d\n", + returnval, errno ); + if(returnval < 0) + { + /* + * ERROR SELECTING. ABORT ALL. + */ + D_PRINTF( "select() error %s\n", neterrstr() ); + abort_clients(); + errexit("Error selecting from one of the clients\n"); + } +#else + /* I don't see why a select is needed at all */ + tmpfdset = leftfdset; + { +#endif /* WIN32 */ + for(cnt = 0; cnt < totalnumclients; cnt++) + { + /* + * SEE WHICH SOCKETS HAVE A INPUT ON THEM PENDING AND + * RECEIVE IT. + */ + + /* IS THIS A VALID SOCKET? IS IT READY TO READ? */ + if(!BADSOCKET(socknum[cnt]) && (FD_ISSET(socknum[cnt],&tmpfdset))) + { + int len; + + /* + * GET THE TIMING DATA FROM THIS GUY + * THEN REMOVE HIM FROM THE tmpfdset + */ + /* + * READ TIME STATS + * DOES READ() RETURN THE CORRECT LENGTH? + */ + D_PRINTF( "About to read timestats, count %d, errno %d\n", + cnt, errno ); + len = SIZEOF_STATSTEXTBASE + number_of_pages*SIZEOF_DOUBLETEXT; + returnval = recvdata(socknum[cnt], stats_as_text, + len); + D_PRINTF( "Read time stats %d\n", returnval ); + if (returnval != len) /* <= 0) */ + { + D_PRINTF( "Error reading timing stats: %s\n", + neterrstr() ); + fprintf(stderr, "Error reading timing stats: %s\nSocket number %d\n", + neterrstr(),socknum[cnt]); + abort_clients(); + errexit(""); + } /* end if */ + + /* convert text to stats */ + stats_as_text[returnval] = 0; /* add an end marker */ + statarray[cnt] = *text_to_stats(stats_as_text); + + fputc('.', stdout); /* PROGRESS MARKER */ + fflush(stdout); + + if(uil_filelist_f) /* READ PAGE STATS */ + { + for (i = 0; i < number_of_pages; i++) + { + D_PRINTF( "On page_stats[%d][%d]\n", cnt, i ); + returnval = recvdata(socknum[cnt], page_stats_as_text, + SIZEOF_PAGESTATSTEXT); + D_PRINTF( "Read page stats %d\n", returnval ); + + if (returnval != SIZEOF_PAGESTATSTEXT) /* <= 0) */ + { + D_PRINTF( "Error reading page_stats[%d][%d]: %s\n", + cnt, i, neterrstr() ); + fprintf(stderr, "Error reading page_stats[%d][%d]: %s\n", + cnt, i, neterrstr()); + abort_clients(); + errexit(""); + } + D_PRINTF( "Page stats: read %d bytes\n", + returnval ); + + page_stats_as_text[returnval] = 0; /* add an end marker */ + D_PRINTF("strlen(page_stats_as_text) = %d\n", + strlen(page_stats_as_text)); + page_stats[cnt][i] = + *text_to_page_stats(page_stats_as_text); + + } /* end for */ + } /* end if filelist */ + + FD_CLR(socknum[cnt],&leftfdset); + NETCLOSE(socknum[cnt]); + socknum[cnt] = BADSOCKET_VALUE; + } /* end if socknum */ + } /* end for cnt */ + } /* end while memcmp fd */ + + /* + * DONE READING RESULTS FROM CLIENTS + */ + + *endtime = time(0); + timestr = asctime(localtime(endtime)); + fprintf(stdout,"\nAll clients ended at %s\n",timestr); + fflush(stdout); + + /* FREE MEMORY ALLOCATED FOR CLIENT STATS, PAGESTATS AS TEXT */ + free(stats_as_text); + free(page_stats_as_text); + +} + +/* + Prints out all the results +*/ +void PrintResults( page_stats, endtime, timestr, totalnumclients, statarray, + page_stats_total) +page_stats_t **page_stats; +time_t endtime; +char *timestr; +int totalnumclients; +stats_t statarray[MAXCLIENTS]; +page_stats_t *page_stats_total; +{ + stats_t masterstat; + int cnt,i,j; + double thruput; + struct timeval dtime; + + /* + * PRINT EVERYTHING OUT + */ + stats_init(&masterstat); + for(cnt = 0; cnt < totalnumclients; cnt++) + { + if((statarray[cnt].rs.totalconnects > 0) && (dumpall)) + { + fprintf(stdout,"----------------------------------\n"); + /* fprintf(stdout,"Test for host: %s\n",statarray[cnt].hostname); */ + fprintf(stdout,"Total number of pages retrieved from server: %u\n", + statarray[cnt].totalpages); + + rqstat_fprint(stdout, &(statarray[cnt].rs)); + + thruput = thruputpersec((double)(statarray[cnt].rs.totalbytes), + &(statarray[cnt].rs.totalresponsetime)); + + fprintf(stdout, "Thruput average per connection: %.0f bytes/sec\n", + thruput); + } + if(statarray[cnt].rs.totalconnects > 0) + { + D_PRINTF( "Summing stats for %d, with %ld total connections\n", + cnt, statarray[cnt].rs.totalconnects ); + rqstat_sum(&masterstat.rs, &(statarray[cnt].rs)); + } + else + { + masterstat.rs.totalerrs += statarray[cnt].rs.totalerrs; + } + } + + for (i=0; i < totalnumclients; i++) + { + for (j=0; j < number_of_pages; j++) + { + D_PRINTF( "Summing page stats for %d, page %d, with %d connects\n", + i, j, statarray[i].page_numbers[j] ); + + if (statarray[i].page_numbers[j] != 0) + { + rqst_stats_t *pst_rs; + rqst_stats_t *ps_rs; + + pst_rs = &(page_stats_total[j].rs); + ps_rs = &(page_stats[i][j].rs); + + rqstat_sum(pst_rs, ps_rs); + + page_stats_total[j].totalpages += page_stats[i][j].totalpages; + masterstat.totalpages += page_stats[i][j].totalpages; + + /* yes, this is assignment, not sum */ + page_stats_total[j].page_size = page_stats[i][j].page_size; + + page_stats_total[j].page_valid = 1; + } + } + } + + /* print page statistics */ + if (verbose) { + for (i = 0; i < number_of_pages; i++) + { + if (page_stats_total[i].page_valid == 1) + { + page_stats_t *pst; + + pst = &(page_stats_total[i]); + + printf ("===============================================================================\n"); + printf ("Page # %d\n\n", i); + printf ("Total number of times page was hit %u\n", + pst->totalpages); + + rqstat_print(&(pst->rs)); + + printf ("Page size %u \n", pst->page_size); + printf ("===============================================================================\n\n"); + } + } + } + + fprintf(stdout,"===============================================================================\n"); + + /* + * Validate run. + */ + masterstat.total_num_of_files = statarray[0].total_num_of_files; + for (i=1; i < totalnumclients; i++) + { + if ((statarray[i].rs.totalconnects > 0) && + (statarray[i].total_num_of_files != masterstat.total_num_of_files)) + { + fprintf(stdout,"**********************************************************************\n"); + fprintf(stdout,"**** ERROR: number of files in each test configuration is not the same\n"); + fprintf(stdout,"**** ERROR: Check configuration file %s on each client\n", configfile); + fprintf(stdout,"**********************************************************************\n"); + break; + } + } + + + /* + * Print summary statistics + */ + fprintf(stdout, "WEBSTONE 2.0 results:\n"); + + fprintf(stdout, "Total number of clients: \t%d\n", totalnumclients); + testtime = sumedh_end.tv_sec - sumedh_start.tv_sec; + fprintf(stdout,"Test time: \t\t\t%d seconds\n", testtime); + + fprintf(stdout, "Server connection rate: \t%3.2f connections/sec\n", + (double)(masterstat.rs.totalconnects)/(testtime)); + + fprintf(stdout, "Server error rate: \t\t%4.4f err/sec\n", + (double)(masterstat.rs.totalerrs)/(testtime)); + + fprintf(stdout, "Server thruput: \t\t%2.2f Mbit/sec\n", + (double)(8*masterstat.rs.totalbytes)/(testtime*1024*1024)); + + fprintf(stdout, "Little's Load Factor: \t\t%3.2f \n", + (double)(masterstat.rs.totalresponsetime.tv_sec) + /(testtime)); + avgtime(&masterstat.rs.totalresponsetime, + masterstat.rs.totalconnects, &dtime); + + fprintf(stdout, "Average response time: \t\t%4.4f millisec\n", + (double)1000*(dtime.tv_sec + (double)dtime.tv_usec / 1000000)); + + fprintf(stdout, "Error Level:\t\t\t%4.4f %%\n", + (double)(100 * masterstat.rs.totalerrs)/(masterstat.rs.totalconnects)); + + /* so much for the key metrics */ + + thruput = 8 * thruputpersec((double)(masterstat.rs.totalbytes), + &(masterstat.rs.totalresponsetime)); + + fprintf(stdout, "Average client thruput: \t%4.4f Mbit/sec\n", + thruput/(1024*1024)); + + fprintf(stdout,"Sum of client response times:\t%u.%u sec\n", + masterstat.rs.totalresponsetime.tv_sec, + masterstat.rs.totalresponsetime.tv_usec); + + fprintf(stdout,"Total number of pages read:\t%u\n\n", + masterstat.totalpages); + + /* Remaining stats are the same as usual */ + + rqstat_fprint(stdout, &(masterstat.rs)); + fflush(stdout); + +} + +#ifdef WIN32 +/* close socket library */ +void sock_cleanup(void) { + + WSACleanup(); +} +#endif /* WIN32 */ + +void +main(const int argc, char *argv[]) +{ + + int sync_sock; + int i; + int j; + char buffer[NCCARGS]; + char commandline[NCCARGS]; + char *timestr; + time_t starttime; + time_t endtime; + fd_set fdset; + /* make the big arrays static to avoid stack overflow */ + static char clienthostname[MAXCLIENTS][MAXHOSTNAMELEN]; + static stats_t statarray[MAXCLIENTS]; + page_stats_t **page_stats; + page_stats_t *page_stats_total; + struct sockaddr_in serveraddr; + + +#ifdef WIN32 + WSADATA WSAData; + COORD dwSize; + + if ((WSAStartup(MAKEWORD(1,1), &WSAData)) != 0) { + errexit("Error in WSAStartup()\n"); + } + atexit(sock_cleanup); + + /* increase size of output window */ + dwSize.X = 80; + dwSize.Y = 500; + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), dwSize); +#endif /* WIN32 */ + + + /* Initalization of variables. */ + debugfile = stdout; + memset(buffer, 0, NCCARGS); + memset(webserver, 0, MAXHOSTNAMELEN); + memset(configfile, 0, MAXPATHLEN); + FD_ZERO(&zerofdset); + FD_ZERO(&fdset); + + for(i = 0; i < MAXCLIENTS; i++) + { + socknum[i] = BADSOCKET_VALUE; + statarray[i].rs.totalconnects = 0; + } + + signal(SIGINT, sig_int); + + ParseCmdLine( argc, argv); + + sync_sock = SetupSyncSocket( &serveraddr ); + + MakeCmdLine( commandline); + + totalnumclients = RexecClients( commandline, clienthostname, &serveraddr); + + /* Initalization of variables. */ + page_stats = + (page_stats_t **) + mymalloc(totalnumclients*sizeof(page_stats_t *)); + for (i=0; i < totalnumclients; i++) + { + page_stats[i] = (page_stats_t *) + mymalloc(number_of_pages*sizeof(page_stats_t)); + } + page_stats_total = + (page_stats_t *)mymalloc(number_of_pages*sizeof(page_stats_t)); + + for (i=0; i < totalnumclients; i++) { + stats_init(&(statarray[i])); + } + for (i=0; i < totalnumclients; i++) { + for (j=0; j < number_of_pages; j++) { + page_stats_init(&(page_stats[i][j])); + } + } + for (i=0; i < number_of_pages; i++) { + page_stats_init(&(page_stats_total[i])); + } + + for(i = 0; i < totalnumclients; i++) + { + socknum[i] = BADSOCKET_VALUE; + statarray[i].rs.totalconnects = 0; + } + + GetReady( &fdset, totalnumclients, sync_sock ); + NETCLOSE(sync_sock); + + /* + * START ALL OF THE CLIENTS BY SENDING THEM A GO SIGNAL. + */ + + + gettimeofday (&sumedh_start, 0); + SendGo( totalnumclients, socknum); + + /* + * WAIT FOR ALL OF THE CLIENTS TO COMPLETE. WE SHOULD GET A REPLY + * FOR EACH SOCKET WE HAVE OPEN. THE REPLY WILL BE THE TIMING + * INFORMATION WE USE. + */ + + starttime = time(0); + timestr = asctime(localtime(&starttime)); + fprintf(stdout,"All clients started at %s\n",timestr); + fprintf(stdout,"Waiting for clients completion\n"); + fflush(stdout); + + /* IF THIS IS A TIMED TEST, WE MIGHT AS WELL SNOOZE */ + if (testtime) { + sleep(testtime * 60); + } + + GetResults( &fdset, page_stats, &endtime, timestr, totalnumclients, + statarray); + + gettimeofday (&sumedh_end, 0); + PrintResults( page_stats, endtime, timestr, totalnumclients, statarray, + page_stats_total); + + /* free memory */ + for (i = 0; i < totalnumclients; i++) + { + free(page_stats[i]); + } + free(page_stats); + free(page_stats_total); + + exit(0); +} + +/* Added by Rajesh Shah 5/18/96 */ +void +HostEntCpy(struct hostent *dest, struct hostent *src) +{ + + dest->h_name = (char *)malloc(strlen(src->h_name)+1); + strcpy(dest->h_name, src->h_name); + printf("WebMaster name = %s\n", dest->h_name); + dest->h_aliases = src->h_aliases; + dest->h_addrtype = src->h_addrtype; + dest->h_length = src->h_length; + dest->h_addr_list = src->h_addr_list; +} + diff --git a/ACE/apps/JAWS/clients/WebSTONE/webstone b/ACE/apps/JAWS/clients/WebSTONE/webstone new file mode 100755 index 00000000000..026f0d664ad --- /dev/null +++ b/ACE/apps/JAWS/clients/WebSTONE/webstone @@ -0,0 +1,75 @@ +#!/bin/sh +# +# +WEBSTONEROOT=`pwd` ; export WEBSTONEROOT +[ -z "$EDITOR" ] && EDITOR="vi" + +case $1 in + '-gui') + bin/webstone-gui.pl + ;; + '-help') + echo + more README.FIRST + ;; + '-setup') + if (sh bin/gui-configure) + then + : + else + echo + echo "Some problems were found." + echo "Press RETURN to continue, or CTRL-C to abort." + read junk + fi + if (cd src ; ./configure ; make install) + then + echo + echo + echo "Press RETURN to continue" + read junk + $EDITOR conf/testbed + echo + echo "WebStone make complete." + echo "Type './webstone -genfiles' to create the fileset." + echo + else + echo + echo "WebStone make FAILED" + echo "Consult the file doc/FAQ-webstone.html for porting hints." + echo + fi + ;; + '-kill') + cd bin + ./killbench + ;; + '-nogui') + cd bin + ./runbench + ;; + '-genfiles') + cd bin + ./genfiles + echo + echo "If no errors occurred, type './webstone' to run the benchmark." + echo + ;; + '-silent') + cd bin + ./runbench > /dev/null 2>&1 & + ;; + '-tail') + LATEST=$WEBSTONEROOT/bin/runs/`ls -1 $WEBSTONEROOT/bin/runs | tail -1`/run + tail -f $LATEST + ;; + '-results') + bin/wscollect.pl $2 bin/runs + ;; + + *) + $WEBSTONEROOT/webstone -nogui + ;; +esac + +# end diff --git a/ACE/apps/JAWS/server/HTTP_Config.cpp b/ACE/apps/JAWS/server/HTTP_Config.cpp new file mode 100644 index 00000000000..11890037d3c --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Config.cpp @@ -0,0 +1,140 @@ +// $Id$ + +// HTTP_Config.cpp + +#include "ace/OS_NS_stdlib.h" +#include "HTTP_Config.h" + +ACE_RCSID(server, HTTP_Config, "$Id$") + +// static HTTP_Config_Info config_info; + +HTTP_Config_Info *HTTP_Config::instance_ = 0; + +HTTP_Config_Info * +HTTP_Config::instance (void) +{ + if (HTTP_Config::instance_ == 0) + { + HTTP_Config::instance_ = new HTTP_Config_Info; + + HTTP_Config::instance_->document_root (0); + HTTP_Config::instance_->cgi_path (0); + HTTP_Config::instance_->user_dir (0); + HTTP_Config::instance_->dir_index (0); + HTTP_Config::instance_->proxy_flag (0); + } + + return HTTP_Config::instance_; +} + +HTTP_Config_Info::HTTP_Config_Info (void) + : document_root_ (0), + cgi_path_ (0), + user_dir_ (0), + dir_index_ (0), + proxy_flag_ (0) +{ +} + +HTTP_Config_Info::~HTTP_Config_Info (void) +{ +} + +const char * +HTTP_Config_Info::document_root (void) const +{ + return this->document_root_; +} + +const char * +HTTP_Config_Info::cgi_path (void) const +{ + return this->cgi_path_; +} + +const char * +HTTP_Config_Info::user_dir (void) const +{ + return this->user_dir_; +} + +const char * +HTTP_Config_Info::dir_index (void) const +{ + return this->dir_index_; +} + +int +HTTP_Config_Info::proxy_flag (void) const +{ + return this->proxy_flag_; +} + +const char * +HTTP_Config_Info::document_root (const char *dr_string) +{ + if (dr_string) + this->document_root_ = dr_string; + else + { + this->document_root_ = ACE_OS::getenv ("JAWS_DOCUMENT_ROOT"); + if (!this->document_root_) + this->document_root_ = "."; + } + + return this->document_root_; +} + +const char * +HTTP_Config_Info::cgi_path (const char *cp_string) +{ + if (cp_string) + this->cgi_path_ = cp_string; + else + { + this->cgi_path_ = ACE_OS::getenv ("JAWS_CGI_PATH"); + + if (!this->cgi_path_) + this->cgi_path_ = "cgi-bin"; + } + + return this->cgi_path_; +} + +const char * +HTTP_Config_Info::user_dir (const char *ud_string) +{ + if (ud_string) + this->user_dir_ = ud_string; + else + { + this->user_dir_ = ACE_OS::getenv ("JAWS_USER_DIR"); + if (!this->user_dir_) + this->user_dir_ = ".www"; + } + + return this->user_dir_; +} + +const char * +HTTP_Config_Info::dir_index (const char *di_string) +{ + if (di_string) + this->dir_index_ = di_string; + else + { + this->dir_index_ = ACE_OS::getenv ("JAWS_DIR_INDEX"); + if (!this->dir_index_) + this->dir_index_ = "index.html"; + } + + return this->dir_index_; +} + +int +HTTP_Config_Info::proxy_flag (int pf) +{ + this->proxy_flag_ = pf; + return this->proxy_flag_; +} diff --git a/ACE/apps/JAWS/server/HTTP_Config.h b/ACE/apps/JAWS/server/HTTP_Config.h new file mode 100644 index 00000000000..a758efeedf9 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Config.h @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ + +//============================================================================= +/** + * @file HTTP_Config.h + * + * $Id$ + * + * @author James Hu + */ +//============================================================================= + + +// = Forward declaration. +class HTTP_Config_Info; + +/** + * @class HTTP_Config + * + * @brief Stores server configuration information. + * Someday, this will be hip and cool and be able to parse + * NCSA httpd style config files like Apache does. For now, + * I'm just going to hack in environment variable stuff. + * Designed around Singleton pattern. + */ +class HTTP_Config +{ +public: + /// Access the Singleton. + static HTTP_Config_Info *instance (void); + +private: + /// Store the Singleton. + static HTTP_Config_Info *instance_; +}; + +/** + * @class HTTP_Config_Info + * + * @brief This is where the information is really stored. + */ +class HTTP_Config_Info +{ +friend class HTTP_Config; +public: + HTTP_Config_Info (void); + ~HTTP_Config_Info (void); + + // Accessors to the information + + /// Where the root of the document tree begins. This prevents + /// clients from being able to examine your entire filesystem. + const char *document_root (void) const; + + /// A search path for CGI files. + const char *cgi_path (void) const; + + /// The directory which is appended to a home user directory, e.g., + /// ".www-docs" or "public_html". + const char *user_dir (void) const; + + /// What is the default index file for a directory, e.g., + /// "index.html". + const char *dir_index (void) const; + + /// Will the server support proxy requests? + int proxy_flag (void) const; + +private: + // = Accesors that can set the data + + const char *document_root (const char *dr_string); + const char *cgi_path (const char *cp_string); + const char *user_dir (const char *ud_string); + const char *dir_index (const char *di_string); + + int proxy_flag (int pf); + +private: + // = Data members + + /// The directory root from which documents will be fetched + const char *document_root_; + + /// The directories from which to expect CGI scripts + const char *cgi_path_; + + /// Name of the sub-directory where user Web pages are + const char *user_dir_; + + /// Name of the Web page to present in place of a directory listing + const char *dir_index_; + + /// Should we support proxy requests? Ignored for now. + int proxy_flag_; +}; diff --git a/ACE/apps/JAWS/server/HTTP_Handler.cpp b/ACE/apps/JAWS/server/HTTP_Handler.cpp new file mode 100644 index 00000000000..a4e4ad31b23 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Handler.cpp @@ -0,0 +1,314 @@ +// $Id$ + +// HTTP_Service.cpp -- simple implementation of the HTTP protocol + +#include "ace/Message_Block.h" +#include "ace/Filecache.h" + +#include "HTTP_Handler.h" +#include "HTTP_Helpers.h" +#include "IO.h" +#include "ace/OS_NS_sys_socket.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(server, HTTP_Handler, "$Id$") + +HTTP_Handler::HTTP_Handler (JAWS_IO &io, + HTTP_Handler_Factory &factory) + : factory_ (factory), + request_data_ (0), + handle_ (ACE_INVALID_HANDLE), + response_ (io, request_), + io_ (io) +{ + this->io_.handler (this); +} + +HTTP_Handler::~HTTP_Handler (void) +{ + this->request_data_->release (); + this->request_data_ = 0; +} + +void +HTTP_Handler::open (ACE_HANDLE handle, + ACE_Message_Block &initial_data) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) New connection \n")); + + int sockbufsize = HTTP_Handler::MAX_SOCKBUFSIZE; + int result = ACE_OS::setsockopt (handle, + SOL_SOCKET, + SO_RCVBUF, + (char *) &sockbufsize, + sizeof sockbufsize); + + if (result == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "SO_RCVBUF")); + + sockbufsize = HTTP_Handler::MAX_SOCKBUFSIZE; + + result = ACE_OS::setsockopt (handle, + SOL_SOCKET, + SO_SNDBUF, + (char *) &sockbufsize, + sizeof sockbufsize); + if (result == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "SO_SNDBUF")); + + this->handle_ = handle; + this->io_.handle (this->handle_); + + this->request_data_ = initial_data.duplicate (); + this->read_complete (initial_data); +} + +void +HTTP_Handler::read_complete (ACE_Message_Block &message_block) +{ + // This is actually a callback entry point. The JAWS_IO framework + // calls into this method after some data has been read in. + + switch (this->request_.parse_request (message_block)) + { + case 0: + do + { + int next_read_size + = HTTP_Handler::MAX_REQUEST_SIZE - message_block.length (); + + if (next_read_size == 0) + { + this->request_too_long (); + return; + } + + this->io_.read (message_block, next_read_size); + } + while (0); + break; + + default: + // this->request_.respond (); + this->response_.process_request (); + } +} + +void +HTTP_Handler::receive_file_complete (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) %s received successfully\n", + request_.uri ())); + + char buffer[BUFSIZ]; + int buflen = + ACE_OS::sprintf (buffer, + "%s %d %s\r\n", + this->request_.version (), + HTTP_Status_Code::STATUS_OK, + "Successful"); + + this->io_.send_confirmation_message (buffer, buflen); +} + +void +HTTP_Handler::receive_file_error (int result) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) %s error in receiving file\n", + request_.uri ())); + + char buffer[BUFSIZ]; + + int status_code; + switch (result) + { + case ACE_Filecache_Handle::ACE_ACCESS_FAILED: + case ACE_Filecache_Handle::ACE_WRITE_FAILED: + case ACE_Filecache_Handle::ACE_OPEN_FAILED: + status_code = HTTP_Status_Code::STATUS_NOT_FOUND; + break; + case ACE_Filecache_Handle::ACE_COPY_FAILED: + case ACE_Filecache_Handle::ACE_STAT_FAILED: + case ACE_Filecache_Handle::ACE_MEMMAP_FAILED: + status_code = HTTP_Status_Code::STATUS_FORBIDDEN; + break; + default: + status_code = HTTP_Status_Code::STATUS_INTERNAL_SERVER_ERROR; + break; + } + int buflen = + ACE_OS::sprintf (buffer, + "%s %d %s", + this->request_.version (), + status_code, + "Failed"); + + this->io_.send_confirmation_message (buffer, buflen); +} + +void +HTTP_Handler::confirmation_message_complete (void) +{ + this->done (); +} + +void +HTTP_Handler::error_message_complete (void) +{ + this->done (); +} + +void +HTTP_Handler::transmit_file_complete (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) %s transmitted successfully\n", + request_.uri ())); + + this->done (); +} + +void +HTTP_Handler::transmit_file_error (int result) +{ + ACE_DEBUG ((LM_DEBUG, + " (%t) %s error in transmitting file\n", + request_.uri ())); + + int status_code; + + switch (result) + { + case ACE_Filecache_Handle::ACE_ACCESS_FAILED: + case ACE_Filecache_Handle::ACE_WRITE_FAILED: + case ACE_Filecache_Handle::ACE_OPEN_FAILED: + status_code = HTTP_Status_Code::STATUS_NOT_FOUND; + break; + case ACE_Filecache_Handle::ACE_COPY_FAILED: + case ACE_Filecache_Handle::ACE_STAT_FAILED: + case ACE_Filecache_Handle::ACE_MEMMAP_FAILED: + status_code = HTTP_Status_Code::STATUS_FORBIDDEN; + break; + default: + status_code = HTTP_Status_Code::STATUS_INTERNAL_SERVER_ERROR; + break; + } + + this->response_.error_response (status_code, "error in transmitting file"); +} + +void +HTTP_Handler::read_error (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) error in reading request\n")); + this->done (); +} + +void +HTTP_Handler::write_error (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) %s error in writing response\n", + request_.uri ())); + + this->done (); +} + +void +HTTP_Handler::timeout (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) %s error in reading request\n", + request_.uri ())); + + this->response_. + error_response (HTTP_Status_Code::STATUS_INTERNAL_SERVER_ERROR, + "error in reading request"); +} + +void +HTTP_Handler::request_too_long (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) request too long\n")); + this->response_. + error_response (HTTP_Status_Code::STATUS_BAD_REQUEST, + "request too long"); +} + +void +HTTP_Handler::done (void) +{ + this->factory_.destroy_http_handler (*this, this->io_); +} + +HTTP_Handler_Factory::~HTTP_Handler_Factory (void) +{ +} + +HTTP_Handler * +Synch_HTTP_Handler_Factory::create_http_handler (void) +{ + JAWS_Synch_IO *io; + ACE_NEW_RETURN (io, JAWS_Synch_IO, 0); + HTTP_Handler *handler; + ACE_NEW_RETURN (handler, HTTP_Handler (*io, *this), 0); + + return handler; +} + +void +Synch_HTTP_Handler_Factory::destroy_http_handler (HTTP_Handler &handler, + JAWS_IO &io) +{ + delete &io; + delete &handler; +} + +//-------------SYNCH IO no Cache + +HTTP_Handler * +No_Cache_Synch_HTTP_Handler_Factory::create_http_handler (void) +{ + JAWS_Synch_IO_No_Cache *io = 0; + ACE_NEW_RETURN (io, JAWS_Synch_IO_No_Cache, 0); + HTTP_Handler *handler = 0; + ACE_NEW_RETURN (handler, HTTP_Handler (*io, *this), 0); + + return handler; +} + +void +No_Cache_Synch_HTTP_Handler_Factory::destroy_http_handler (HTTP_Handler &handler, + JAWS_IO &io) +{ + delete &io; + delete &handler; +} + +//---------------- + +// This only works on Win32 +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) +void +Asynch_HTTP_Handler_Factory::open (ACE_HANDLE handle, + ACE_Message_Block &mb) +{ + JAWS_Asynch_IO *io; + ACE_NEW (io, JAWS_Asynch_IO); + HTTP_Handler *handler; + ACE_NEW (handler, HTTP_Handler (*io, *this)); + handler->open (handle, mb); +} + +void +Asynch_HTTP_Handler_Factory::destroy_http_handler (HTTP_Handler &handler, + JAWS_IO &io) +{ + delete &handler; + delete &io; + delete this; +} + +HTTP_Handler * +Asynch_HTTP_Handler_Factory::create_http_handler (void) +{ + return 0; +} +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ diff --git a/ACE/apps/JAWS/server/HTTP_Handler.h b/ACE/apps/JAWS/server/HTTP_Handler.h new file mode 100644 index 00000000000..c4c44799535 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Handler.h @@ -0,0 +1,237 @@ +/* -*- c++ -*- */ + +//============================================================================= +/** + * @file HTTP_Handler.h + * + * $Id$ + * + * @author James Hu and Irfan Pyarali + */ +//============================================================================= + + +#ifndef HTTP_HANDLER_H +#define HTTP_HANDLER_H + +// = Forward declarations +class Message_Block; +class HTTP_Handler_Factory; + +#include "ace/Asynch_IO.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "HTTP_Request.h" +#include "HTTP_Response.h" +#include "IO.h" + +/** + * @class HTTP_Handler + * + * @brief This class is used to implement the HTTP protocol + * + * The HTTP_Handler class is a state based implementation of the + * HTTP protocol. Therefore, it can be used synchronously and + * asynchronously. It uses an abstract IO class to move between + * different HTTP protocol states. It is up to the IO class to + * decide on synchronous or asynchronous I/O. + */ +class HTTP_Handler : protected JAWS_IO_Handler +{ + // Friend I/O classes. Can call protected methods. + friend class JAWS_Synch_IO; + friend class JAWS_Synch_IO_No_Cache; + friend class JAWS_Asynch_IO; + + // Factories + friend class Asynch_HTTP_Handler_Factory; + friend class Synch_HTTP_Handler_Factory; + friend class No_Cache_Synch_HTTP_Handler_Factory; + +public: + /** + * The handler is initialized with a connection <handle> of a new + * client and any <initial_data> that came across. The + * <initial_data> block will be of MAX_REQUEST_SIZE and the number + * of bytes in <initial_data> can be found from + * <initial_data>.length () + */ + virtual void open (ACE_HANDLE handle, + ACE_Message_Block &initial_data); + +protected: + /// The constructor is passed the factory that created <this> and the + /// IO mechanism that the handler should use. + HTTP_Handler (JAWS_IO &io, + HTTP_Handler_Factory &factory); + + /// Destructor + virtual ~HTTP_Handler (void); + + /// This method is called by the framework when there is a timeout. + virtual void timeout (void); + + /** + * This is the termination state of the handler. After successful or + * unsuccessful completions, the handler will end up in this state + * (method). + */ + virtual void done (void); + + /// Request too long. + virtual void request_too_long (void); + + /// Reference to the creating factory. + HTTP_Handler_Factory &factory_; + +protected: + // = Completion methods inherited from <JAWS_IO_Handler>. + + virtual void read_complete (ACE_Message_Block &data); + virtual void read_error (void); + virtual void transmit_file_complete (void); + virtual void transmit_file_error (int result); + virtual void receive_file_complete (void); + virtual void receive_file_error (int result); + virtual void write_error (void); + virtual void confirmation_message_complete (void); + virtual void error_message_complete (void); + +public: + enum + { + MAX_SOCKBUFSIZE = 64 * 1024, + MAX_REQUEST_SIZE = 8192, + METHODSIZ = 10, + VERSIONSIZ = 10 + }; + +private: + /// This points to the request sent by the client + ACE_Message_Block *request_data_; + + /// I/O handle to the client + ACE_HANDLE handle_; + + HTTP_Request request_; + HTTP_Response response_; + + /// IO class used by the handler + JAWS_IO &io_; +}; + +/** + * @class HTTP_Handler_Factory + * + * @brief This class is used to create new HTTP handlers + * + * This is an abstract factory for creating new HTTP handlers. + */ +class HTTP_Handler_Factory +{ +public: + /// Destructor + virtual ~HTTP_Handler_Factory (void); + + /// This creates a new HTTP_Handler + virtual HTTP_Handler *create_http_handler (void) = 0; + + /** + * The HTTP handler will call this method from HTTP_Handler::done to + * tell the factory to reap up the handler as it is now done with + * the protocol + */ + virtual void destroy_http_handler (HTTP_Handler &handler, + JAWS_IO &io) = 0; +}; + +/** + * @class Synch_HTTP_Handler_Factory + * + * @brief This class is used to create new HTTP handlers that will use + * Synch IO + * + */ +class Synch_HTTP_Handler_Factory : public HTTP_Handler_Factory +{ +public: + /// This creates a new HTTP_Handler + HTTP_Handler *create_http_handler (void); + + /** + * The HTTP handler will call this method from HTTP_Handler::done to + * tell the factory to reap up the handler as it is now done with + * the protocol + */ + void destroy_http_handler (HTTP_Handler &handler, + JAWS_IO &io); +}; + +//--------------Added a factory for SYNCH IO without caching + +/** + * @class No_Cache_Synch_HTTP_Handler_Factory + * + * @brief This class is used to create new HTTP handlers that will use + * Synch IO without caching + * + */ +class No_Cache_Synch_HTTP_Handler_Factory : public HTTP_Handler_Factory +{ +public: + /// This creates a new HTTP_Handler + HTTP_Handler *create_http_handler (void); + + /** + * The HTTP handler will call this method from HTTP_Handler::done to + * tell the factory to reap up the handler as it is now done with + * the protocol + */ + void destroy_http_handler (HTTP_Handler &handler, + JAWS_IO &io); +}; + +//-------------- + +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) +/** + * @class Asynch_HTTP_Handler_Factory + * + * @brief This class is used to create new HTTP handlers that will use + * Asynchronous IO. This only works on Win32. + * + */ +class Asynch_HTTP_Handler_Factory : public HTTP_Handler_Factory, public ACE_Service_Handler +{ +public: + /** + * The HTTP handler will call this method from HTTP_Handler::done to + * tell the factory to reap up the handler as it is now done with + * the protocol + */ + void destroy_http_handler (HTTP_Handler &handler, + JAWS_IO &io); + + /** + * <open> is called by <ACE_Asynch_Acceptor> to initialize a new + * instance of ACE_Service_Handler that has been created after the a + * new connection is accepted. + * + * This will act as a creation point for new handlers. + */ + virtual void open (ACE_HANDLE handle, + ACE_Message_Block &message_block); + +private: + /** + * This method is private as users are not allowed to create new + * handlers. New handlers can only be created by the framework when + * new client connections arrive. + */ + HTTP_Handler *create_http_handler (void); +}; +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ +#endif /* HTTP_HANDLER_H */ diff --git a/ACE/apps/JAWS/server/HTTP_Helpers.cpp b/ACE/apps/JAWS/server/HTTP_Helpers.cpp new file mode 100644 index 00000000000..4bbaa6ee498 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Helpers.cpp @@ -0,0 +1,442 @@ +// $Id$ + +// HTTP_Helpers.cpp -- Helper utilities for both server and client + +#include "HTTP_Helpers.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" +#include "ace/Guard_T.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(server, HTTP_Helpers, "$Id$") + +// = Static initialization. +const char *const +HTTP_Helper::months_[12]= +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +char const *HTTP_Helper::alphabet_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char * HTTP_Helper::date_string_ = 0; +ACE_SYNCH_MUTEX HTTP_Helper::mutex_; + +ACE_SYNCH_MUTEX HTTP_Status_Code::lock_; +int HTTP_Status_Code::instance_ = 0; +const char *HTTP_Status_Code::Reason[HTTP_Status_Code::MAX_STATUS_CODE + 1]; + +time_t +HTTP_Helper::HTTP_mktime (const char *httpdate) +{ + char *buf; + + ACE_NEW_RETURN (buf, char[ACE_OS::strlen (httpdate) + 1], (time_t) -1); + + // Make spaces in the date be semi-colons so we can parse robustly + // with sscanf. + + const char *ptr1 = httpdate; + char *ptr2 = buf; + + do + { + if (*ptr1 == ' ') + *ptr2++ = ';'; + else + *ptr2++ = *ptr1; + } + while (*ptr1++ != '\0'); + + // In HTTP/1.0, there are three versions of an HTTP_date. + + // rfc1123-date = wkday "," SP dd month yyyy SP hh:mm:ss SP "GMT" + // rfc850-date = weekday "," SP dd-month-yy SP hh:mm:ss SP "GMT" + // asctime-date = wkday SP month dd SP hh:mm:ss SP yyyy + + // static const char rfc1123_date[] = "%3s,;%2d;%3s;%4d;%2d:%2d:%2d;GMT"; + // static const char rfc850_date[] = "%s,;%2d-%3s-%2d;%2d:%2d:%2d;GMT"; + // static const char asctime_date[] = "%3s;%3s;%2d;%2d:%2d:%2d;%4d"; + + // Should also support other versions (such as from NNTP and SMTP) + // for robustness, but it should be clear how to extend this. + + struct tm tms; + char month[4]; + char weekday[10]; + + if (::sscanf(buf, "%3s,;%2d;%3s;%4d;%2d:%2d:%2d;GMT", // RFC-1123 date format + weekday, + &tms.tm_mday, + month, + &tms.tm_year, + &tms.tm_hour, + &tms.tm_min, + &tms.tm_sec) == 7) + ; + else if (::sscanf(buf, "%s,;%2d-%3s-%2d;%2d:%2d:%2d;GMT", // RFC-850 date format + weekday, + &tms.tm_mday, month, &tms.tm_year, + &tms.tm_hour, &tms.tm_min, &tms.tm_sec) == 7) + { + weekday[3] = '\0'; + } + else if (::sscanf(buf, "%3s;%3s;%2d;%2d:%2d:%2d;%4d", // ASCTIME date format. + weekday, + month, &tms.tm_mday, + &tms.tm_hour, &tms.tm_min, &tms.tm_sec, + &tms.tm_year) == 7) + { + } + + delete [] buf; + + tms.tm_year = HTTP_Helper::fixyear (tms.tm_year); + tms.tm_mon = HTTP_Helper::HTTP_month (month); + + if (tms.tm_mon == -1) + return (time_t) -1; + + // mktime is a Standard C function. + { + +#if !defined (ACE_HAS_REENTRANT_LIBC) + ACE_MT (ACE_Guard<ACE_SYNCH_MUTEX> g (HTTP_Helper::mutex_)); +#endif /* NOT ACE_HAS_REENTRANT_LIBC */ + + return ACE_OS::mktime (&tms); + } +} + +const char * +HTTP_Helper::HTTP_date (void) +{ + if (HTTP_Helper::date_string_ == 0) + { + ACE_MT (ACE_Guard<ACE_SYNCH_MUTEX> m (HTTP_Helper::mutex_)); + + if (HTTP_Helper::date_string_ == 0) + { + // 40 bytes is all I need. + ACE_NEW_RETURN (HTTP_Helper::date_string_, char[40], 0); + + if (!HTTP_Helper::HTTP_date (HTTP_Helper::date_string_)) + { + delete [] HTTP_Helper::date_string_; + HTTP_Helper::date_string_ = 0; + } + } + } + + return HTTP_Helper::date_string_; +} + +const char * +HTTP_Helper::HTTP_date (char *s) +{ + // Return the date-string formatted per HTTP standards. Time must + // be in UTC, so using the 'strftime' call (which obeys the locale) + // isn't correct. + static const char* months[] = {"Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Oct","Nov","Dec"}; + static const char* days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; + + time_t tloc; + struct tm tms; + char * date_string = s; + + if (ACE_OS::time (&tloc) != (time_t) -1 + && ACE_OS::gmtime_r (&tloc, &tms) != 0) + { + ACE_OS::sprintf (date_string, + "%s, %2.2d %s %4.4d %2.2d:%2.2d:%2.2d GMT", + days[tms.tm_wday], tms.tm_mday, months[tms.tm_mon], + tms.tm_year + 1900, tms.tm_hour, tms.tm_min, tms.tm_sec); + } + else + date_string = 0; + + return date_string; +} + +int +HTTP_Helper::HTTP_month (const char *month) +{ + for (size_t i = 0; i < 12; i++) + if (ACE_OS::strcmp(month, HTTP_Helper::months_[i]) == 0) + return i; + + return -1; +} + +const char * +HTTP_Helper::HTTP_month (int month) +{ + if (month < 0 || month >= 12) + return 0; + + return HTTP_Helper::months_[month]; +} + +// Fix the path if it needs fixing/is fixable. + +char * +HTTP_Helper::HTTP_decode_string (char *path) +{ + // replace the percentcodes with the actual character + int i, j; + char percentcode[3]; + + for (i = j = 0; path[i] != '\0'; i++, j++) + { + if (path[i] == '%') + { + percentcode[0] = path[++i]; + percentcode[1] = path[++i]; + percentcode[2] = '\0'; + path[j] = (char) ACE_OS::strtol (percentcode, (char **) 0, 16); + } + else + path[j] = path[i]; + } + + path[j] = path[i]; + + return path; +} + +char * +HTTP_Helper::HTTP_decode_base64 (char *data) +{ + char inalphabet[256], decoder[256]; + + ACE_OS::memset (inalphabet, 0, sizeof (inalphabet)); + ACE_OS::memset (decoder, 0, sizeof (decoder)); + + for (int i = ACE_OS::strlen (HTTP_Helper::alphabet_) - 1; + i >= 0; + i--) + { + inalphabet[(unsigned int) HTTP_Helper::alphabet_[i]] = 1; + decoder[(unsigned int) HTTP_Helper::alphabet_[i]] = i; + } + + char *indata = data; + char *outdata = data; + + int bits = 0; + int c; + int char_count = 0; + int errors = 0; + + while ((c = *indata++) != '\0') + { + if (c == '=') + break; + if (c > 255 || ! inalphabet[c]) + continue; + bits += decoder[c]; + char_count++; + if (char_count == 4) + { + *outdata++ = (bits >> 16); + *outdata++ = ((bits >> 8) & 0xff); + *outdata++ = (bits & 0xff); + bits = 0; + char_count = 0; + } + else + bits <<= 6; + } + + if (c == '\0') + { + if (char_count) + { + ACE_DEBUG ((LM_DEBUG, + "base64 encoding incomplete: at least %d bits truncated\n", + ((4 - char_count) * 6))); + errors++; + } + } + else + { + // c == '=' + switch (char_count) + { + case 1: + ACE_DEBUG ((LM_DEBUG, + "base64 encoding incomplete: at least 2 bits missing\n")); + errors++; + break; + case 2: + *outdata++ = (bits >> 10); + break; + case 3: + *outdata++ = (bits >> 16); + *outdata++ = ((bits >> 8) & 0xff); + break; + } + } + *outdata = '\0'; + return errors ? 0 : data; +} + +char * +HTTP_Helper::HTTP_encode_base64 (char *data) +{ + char buf[BUFSIZ]; + int c; + int error; + int char_count = 0; + int bits = 0; + error = 0; + char *indata = data; + char *outdata = buf; + const unsigned char ASCII_MAX = ~0; + + while ((c = *indata++) != '\0') + { + if (c > (int)ASCII_MAX) + { + ACE_DEBUG ((LM_DEBUG, "encountered char > 255 (decimal %d)\n", c)); + error++; + break; + } + bits += c; + char_count++; + + if (char_count == 3) + { + *outdata++ = HTTP_Helper::alphabet_[bits >> 18]; + *outdata++ = HTTP_Helper::alphabet_[(bits >> 12) & 0x3f]; + *outdata++ = HTTP_Helper::alphabet_[(bits >> 6) & 0x3f]; + *outdata++ = HTTP_Helper::alphabet_[bits & 0x3f]; + bits = 0; + char_count = 0; + } + else + bits <<= 8; + } + + if (!error) + { + if (char_count != 0) + { + bits <<= 16 - (8 * char_count); + *outdata++ = HTTP_Helper::alphabet_[bits >> 18]; + *outdata++ = HTTP_Helper::alphabet_[(bits >> 12) & 0x3f]; + + if (char_count == 1) + { + *outdata++ = '='; + *outdata++ = '='; + } + else + { + *outdata++ = HTTP_Helper::alphabet_[(bits >> 6) & 0x3f]; + *outdata++ = '='; + } + } + *outdata = '\0'; + ACE_OS::strcpy (data, buf); + } + + return (error ? 0 : data); +} + +int +HTTP_Helper::fixyear (int year) +{ + // Fix the year 2000 problem + + if (year > 1000) + year -= 1900; + else if (year < 100) + { + struct tm tms; + time_t tloc; + + if (ACE_OS::time (&tloc) != (time_t) -1) + { + ACE_OS::gmtime_r (&tloc, &tms); + + if (tms.tm_year % 100 == year) + year = tms.tm_year; + + // The last two cases check boundary conditions, in case the + // year just changed at the moment we checked to see if we + // need to fix it. + if ((year+1) % 100 == tms.tm_year % 100) + year = tms.tm_year - 1; + + if (year == (tms.tm_year + 1) % 100) + year = tms.tm_year + 1; + + // What to do if none of the above? + } + } + + return year; +} + +const char ** +HTTP_Status_Code::instance (void) +{ + if (HTTP_Status_Code::instance_ == 0) + { + ACE_MT (ACE_Guard<ACE_SYNCH_MUTEX> g (lock_)); + + if (HTTP_Status_Code::instance_ == 0) + { + for (size_t i = 0; + i < HTTP_Status_Code::MAX_STATUS_CODE + 1; + i++) + { + switch (i) + { + case STATUS_OK: + HTTP_Status_Code::Reason[i] = "OK"; break; + case STATUS_CREATED: + HTTP_Status_Code::Reason[i] = "Created"; break; + case STATUS_ACCEPTED: + HTTP_Status_Code::Reason[i] = "Accepted"; break; + case STATUS_NO_CONTENT: + HTTP_Status_Code::Reason[i] = "No Content"; break; + case STATUS_MOVED_PERMANENTLY: + HTTP_Status_Code::Reason[i] = "Moved Permanently"; break; + case STATUS_MOVED_TEMPORARILY: + HTTP_Status_Code::Reason[i] = "Moved Temporarily"; break; + case STATUS_NOT_MODIFIED: + HTTP_Status_Code::Reason[i] = "Not Modified"; break; + case STATUS_BAD_REQUEST: + HTTP_Status_Code::Reason[i] = "Bad Request"; break; + case STATUS_UNAUTHORIZED: + HTTP_Status_Code::Reason[i] = "Unauthorized"; break; + case STATUS_FORBIDDEN: + HTTP_Status_Code::Reason[i] = "Forbidden"; break; + case STATUS_NOT_FOUND: + HTTP_Status_Code::Reason[i] = "Not Found"; break; + case STATUS_INTERNAL_SERVER_ERROR: + HTTP_Status_Code::Reason[i] = "Internal Server Error"; break; + case STATUS_NOT_IMPLEMENTED: + HTTP_Status_Code::Reason[i] = "Not Implemented"; break; + case STATUS_BAD_GATEWAY: + HTTP_Status_Code::Reason[i] = "Bad Gateway"; break; + case STATUS_SERVICE_UNAVAILABLE: + HTTP_Status_Code::Reason[i] = "Service Unavailable"; break; + default: + HTTP_Status_Code::Reason[i] = "Unknown"; + } + } + + HTTP_Status_Code::instance_ = 1; + } + + // GUARD released + } + + return HTTP_Status_Code::Reason; +} diff --git a/ACE/apps/JAWS/server/HTTP_Helpers.h b/ACE/apps/JAWS/server/HTTP_Helpers.h new file mode 100644 index 00000000000..0bbc837ff82 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Helpers.h @@ -0,0 +1,110 @@ +/* -*- c++ -*- */ + +//============================================================================= +/** + * @file HTTP_Helpers.h + * + * $Id$ + * + * @author James Hu + */ +//============================================================================= + + +#ifndef HTTP_HELPERS_H +#define HTTP_HELPERS_H + +#include "ace/Synch_Traits.h" +#include "ace/Thread_Mutex.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class HTTP_Helper + Static functions to enhance the lives of HTTP programmers everywhere. + */ +class HTTP_Helper +{ +public: + + // Convert and HTTP-date into a time_t + static time_t HTTP_mktime (const char *httpdate); + + // Create today's date + static const char *HTTP_date (void); + static const char *HTTP_date (char *s); + + // Month conversions (ascii <--> numeric) + static int HTTP_month (const char *month); + static const char *HTTP_month (int month); + + static char *HTTP_decode_string (char *path); + + // Encode/Decode base64 stuff (weak security model) + static char *HTTP_decode_base64 (char *data); + static char *HTTP_encode_base64 (char *data); + +private: + + static int fixyear (int year); + +private: + static const char *const months_[12]; + static char const *alphabet_; + + /// Use this sometimes (e.g. HTTP_date) + static char *date_string_; + static ACE_SYNCH_MUTEX mutex_; +}; + +// Design around the Singleton pattern + +/** + * @class HTTP_Status_Code + * + * @brief Go from numeric status codes to descriptive strings. + * + * Design around the Singleton pattern + */ +class HTTP_Status_Code +{ +public: + /// Singleton access point. + static const char **instance (void); + + enum STATUS_CODE + { + STATUS_OK = 200, + STATUS_CREATED = 201, + STATUS_ACCEPTED = 202, + STATUS_NO_CONTENT = 204, + STATUS_MOVED_PERMANENTLY = 301, + STATUS_MOVED_TEMPORARILY = 302, + STATUS_NOT_MODIFIED = 304, + STATUS_BAD_REQUEST = 400, + STATUS_UNAUTHORIZED = 401, + STATUS_FORBIDDEN = 403, + STATUS_NOT_FOUND = 404, + STATUS_INTERNAL_SERVER_ERROR = 500, + STATUS_NOT_IMPLEMENTED = 501, + STATUS_BAD_GATEWAY = 502, + STATUS_SERVICE_UNAVAILABLE = 503, + STATUS_INSUFFICIENT_DATA = 399 + }; + + enum + { + MAX_STATUS_CODE = 599 + }; + +private: + // Singleton pattern is afoot here. + static const char *Reason[MAX_STATUS_CODE + 1]; + static int instance_; + static ACE_SYNCH_MUTEX lock_; +}; + +#endif /* HTTP_HELPERS_H */ + diff --git a/ACE/apps/JAWS/server/HTTP_Request.cpp b/ACE/apps/JAWS/server/HTTP_Request.cpp new file mode 100644 index 00000000000..c2d4b7a3134 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Request.cpp @@ -0,0 +1,664 @@ +// $Id$ + +#include "ace/Message_Block.h" +#include "HTTP_Request.h" +#include "HTTP_Helpers.h" +#include "HTTP_Config.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_pwd.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(server, HTTP_Request, "$Id$") + +const char *const +HTTP_Request::static_header_strings_[HTTP_Request::NUM_HEADER_STRINGS] = +{ + "Date", + "Pragma", + "Authorization", + "From", + "If-Modified-Since", + "Referrer", + "User-Agent", + "Allow", + "Content-Encoding", + "Content-Length", + "Content-Type", + "Expires", + "Last-Modified" +}; + +const char *const +HTTP_Request::static_method_strings_[HTTP_Request::NUM_METHOD_STRINGS] = +{ + "GET", + "HEAD", + "POST", + "PUT" +}; + +// For reasons of efficiency, this class expects buffer to be +// null-terminated, and buflen does NOT include the \0. + +HTTP_Request::HTTP_Request (void) + : got_request_line_ (0), + method_ (0), + uri_ (0), + version_ (0), + path_ (0), + cgi_ (0), + cgi_env_ (0), + cgi_args_ (0), + query_string_ (0), + path_info_ (0), + header_strings_ (HTTP_Request::static_header_strings_), + method_strings_ (HTTP_Request::static_method_strings_) +{ + + for (size_t i = 0; + i < HTTP_Request::NUM_HEADER_STRINGS; + i++) + this->headers_.recognize (this->header_strings_[i]); +} + +HTTP_Request::~HTTP_Request (void) +{ + ACE_OS::free (this->method_); + ACE_OS::free (this->uri_); + ACE_OS::free (this->version_); + ACE_OS::free (this->path_); + ACE_OS::free (this->query_string_); + ACE_OS::free (this->path_info_); + + delete [] this->cgi_env_; +} + +int +HTTP_Request::parse_request (ACE_Message_Block &mb) +{ + mb.wr_ptr ()[0] = '\0'; + + // Note that RFC 822 does not mention the maximum length of a header + // line. So in theory, there is no maximum length. + + // In Apache, they assume that each header line should not exceed + // 8K. + + int result = this->headers_.complete_header_line (mb.rd_ptr ()); + + if (result != 0) + { + if (!this->got_request_line ()) + { + this->parse_request_line (mb.rd_ptr ()); + while (this->headers_.complete_header_line (mb.rd_ptr ()) > 0) + this->headers_.parse_header_line (mb.rd_ptr ()); + } + else if (result > 0) + do + this->headers_.parse_header_line (mb.rd_ptr ()); + while (this->headers_.complete_header_line (mb.rd_ptr ()) > 0); + } + + mb.wr_ptr (ACE_OS::strlen(mb.rd_ptr ()) - mb.length ()); + + if (this->headers_.end_of_headers () + || (this->got_request_line () && this->version () == 0)) + return this->init (mb.rd_ptr (), mb.length ()); + else + return 0; +} + +void +HTTP_Request::parse_request_line (char *const request_line) +{ + char *ptr = request_line; + char *buf = request_line; + int offset = 1; + + this->status_ = HTTP_Status_Code::STATUS_OK; + + ptr = ACE_OS::strchr (request_line, '\n'); + + if (ptr > request_line && ptr[-1] == '\r') + ptr--, offset++; + + if (ptr == request_line) + { + this->status_ = HTTP_Status_Code::STATUS_BAD_REQUEST; + return; + } + + *ptr = '\0'; + ptr += offset; + + char *lasts = 0; // for strtok_r + + // Get the request type. + this->got_request_line_ = 1; + + if (this->method (ACE_OS::strtok_r (buf, " \t", &lasts)) + && this->uri (ACE_OS::strtok_r (0, " \t", &lasts))) + { + this->type (this->method ()); + + if (this->version (ACE_OS::strtok_r (0, " \t", &lasts)) == 0 + && this->type () != HTTP_Request::GET) + this->status_ = HTTP_Status_Code::STATUS_NOT_IMPLEMENTED; + + if (this->path (this->uri ()) == 0) + this->status_ = HTTP_Status_Code::STATUS_NOT_FOUND; + } + + ACE_DEBUG ((LM_DEBUG, " (%t) request %s %s %s parsed\n", + (this->method () ? this->method () : "-"), + (this->uri () ? this->uri () : "="), + (this->version () ? this->version () : "HTTP/0.9"))); + + ACE_OS::memmove (buf, ptr, ACE_OS::strlen (ptr)+1); +} + +int +HTTP_Request::init (char *const buffer, + int buflen) +{ + // Initialize these every time. + content_length_ = -1; + + // Extract the data pointer. + data_ = buffer; + datalen_ = 0; + + // Set the datalen + if (data_ != 0) + datalen_ = buflen; + else + datalen_ = 0; + + ACE_DEBUG ((LM_DEBUG, " (%t) init has initialized\n")); + + return 1; +} + +const char * +HTTP_Request::method (void) const +{ + return this->method_; +} + +const char * +HTTP_Request::uri (void) const +{ + return this->uri_; +} + +const char * +HTTP_Request::version (void) const +{ + return this->version_; +} + +const char * +HTTP_Request::path (void) const +{ + return this->path_; +} + +int +HTTP_Request::cgi (void) const +{ + return this->cgi_; +} + +const char ** +HTTP_Request::cgi_env (void) const +{ + return (const char **)this->cgi_env_; +} + +const char * +HTTP_Request::cgi_args (void) const +{ + return this->cgi_args_; +} + +const char * +HTTP_Request::query_string (void) const +{ + return this->query_string_; +} + +const char * +HTTP_Request::path_info (void) const +{ + return this->path_info_; +} + +int +HTTP_Request::got_request_line (void) const +{ + return this->got_request_line_; +} + +int +HTTP_Request::type (void) const +{ + return type_; +} + +const Headers & +HTTP_Request::headers (void) const +{ + return this->headers_; +} + +const char * +HTTP_Request::header_strings (int index) const +{ + const char *hs = 0; + + if (0 <= index && index < NUM_HEADER_STRINGS) + hs = this->header_strings_[index]; + + return hs; +} + +const char * +HTTP_Request::header_values (int index) const +{ + const char *hs = 0; + const char *hv = 0; + + if (0 <= index && index < NUM_HEADER_STRINGS) + { + hs = this->header_strings_[index]; + hv = this->headers_[hs].value (); + } + + return hv; +} + +char * +HTTP_Request::data (void) +{ + return data_; +} + +int +HTTP_Request::data_length (void) +{ + return datalen_; +} + +int +HTTP_Request::content_length (void) +{ + if (this->content_length_ == -1) + { + const char * clv = this->headers_["Content-length"].value (); + this->content_length_ = (clv ? ACE_OS::atoi (clv) : 0); + } + + return this->content_length_; +} + +int +HTTP_Request::status (void) +{ + return this->status_; +} + +const char * +HTTP_Request::status_string (void) +{ + return HTTP_Status_Code::instance ()[this->status_]; +} + +void +HTTP_Request::dump (void) +{ + ACE_DEBUG ((LM_DEBUG, "%s command.\n" + "filename is %s," + " length of the file is %d," + " data string is %s," + " datalen is %d," + " status is %d, which is %s\n\n", + this->method () ? this->method () : "EMPTY", + this->uri () ? this->uri () : "EMPTY", + this->content_length (), + this->data () ? this->data () : "EMPTY", + this->data_length (), + this->status (), + this->status_string ())); +} + +const char * +HTTP_Request::method (const char *method_string) +{ + if (this->method_) + ACE_OS::free (this->method_); + + if (method_string == 0) + { + this->status_ = HTTP_Status_Code::STATUS_BAD_REQUEST; + this->method_ = 0; + } + else + this->method_ = ACE_OS::strdup (method_string); + + return this->method_; +} + +const char * +HTTP_Request::uri (char *uri_string) +{ + if (this->uri_) + ACE_OS::free (this->uri_); + + if (uri_string == 0) + { + this->status_ = HTTP_Status_Code::STATUS_BAD_REQUEST; + this->uri_ = 0; + } + else + { + this->uri_ = ACE_OS::strdup (uri_string); + this->cgi (this->uri_); + HTTP_Helper::HTTP_decode_string (this->uri_); + } + + return this->uri_; +} + +const char * +HTTP_Request::version (const char *version_string) +{ + if (this->version_) + ACE_OS::free (this->version_); + + if (version_string) + this->version_ = ACE_OS::strdup (version_string); + else + this->version_ = 0; + + return this->version_; +} + +int +HTTP_Request::type (const char *type_string) +{ + this->type_ = HTTP_Request::NO_TYPE; + + if (type_string == 0) + return this->type_; + + for (size_t i = 0; + i < HTTP_Request::NUM_METHOD_STRINGS; + i++) + + if (ACE_OS::strcmp (type_string, this->method_strings_[i]) == 0) + { + this->type_ = i; + break; + } + + if (this->type_ == HTTP_Request::NO_TYPE) + this->status_ = HTTP_Status_Code::STATUS_NOT_IMPLEMENTED; + + return this->type_; +} + +int +HTTP_Request::cgi (char *uri_string) +{ + this->cgi_ = 0; + this->cgi_env_ = 0; + this->cgi_args_ = 0; + + ACE_DEBUG ((LM_DEBUG, " (%t) HTTP_Request::cgi (%s)\n", uri_string)); + + if (uri_string == 0 || ACE_OS::strlen (uri_string) == 0) + return 0; + + // There are 2 cases where a file could be a CGI script + // + // (1) the file has a CGI extension. + // (2) the file resides in a CGI bin directory. + + char *extra_path_info = 0; + if (this->cgi_in_path (uri_string, extra_path_info) + || this->cgi_in_extension (uri_string, extra_path_info)) + { + cgi_args_and_env (extra_path_info); + + if (extra_path_info) + { + this->path_info_ = ACE_OS::strdup (extra_path_info); + HTTP_Helper::HTTP_decode_string (this->path_info_); + *extra_path_info = '\0'; + } + } + + return this->cgi_; +} + +int +HTTP_Request::cgi_in_path (char *uri_string, char *&extra_path_info) +{ + char *cgi_path; + + ACE_DEBUG ((LM_DEBUG, " (%t) HTTP_Request::cgi_in_path (%s)\n", + uri_string)); + + if (HTTP_Config::instance ()->cgi_path ()) + cgi_path = ACE_OS::strdup (HTTP_Config::instance ()->cgi_path ()); + else + cgi_path = ACE_OS::strdup (""); + + // error checking considered helpful! + if (cgi_path == 0) + return 0; + + char *lasts = 0; + char *cgi_path_next = ACE_OS::strtok_r (cgi_path, ":", &lasts); + + if (cgi_path_next) + do + { + int len = ACE_OS::strlen (cgi_path_next); + + // match path to cgi path + int in_cgi_path = 0; + + if (*cgi_path_next == '/') + { + // cgi path next points to an ``absolute'' path + extra_path_info = uri_string; + in_cgi_path = + (ACE_OS::strncmp (extra_path_info, cgi_path_next, len) == 0); + } + else + { + // cgi path next points to a ``relative'' path + extra_path_info = ACE_OS::strstr (uri_string, cgi_path_next); + in_cgi_path = (extra_path_info != 0); + } + + if (in_cgi_path) + { + if (extra_path_info[len] == '/') + { + this->cgi_ = 1; + extra_path_info += len; + + // move past the executable name + do + extra_path_info++; + while (*extra_path_info != '/' + && *extra_path_info != '?' + && *extra_path_info != '\0'); + + if (*extra_path_info == '\0') + extra_path_info = 0; + + break; + } + } + extra_path_info = 0; + + cgi_path_next = ACE_OS::strtok_r (0, ":", &lasts); + } + while (cgi_path_next); + + ACE_OS::free (cgi_path); + + return this->cgi_; +} + +int +HTTP_Request::cgi_in_extension (char *uri_string, char *&extra_path_info) +{ + extra_path_info = ACE_OS::strstr (uri_string, ".cgi"); + + ACE_DEBUG ((LM_DEBUG, " (%t) HTTP_Request::cgi_in_extension (%s)\n", + uri_string)); + + while (extra_path_info != 0) + { + extra_path_info += 4; + // skip past ``.cgi'' + + switch (*extra_path_info) + { + case '\0': + extra_path_info = 0; + break; + case '/': + case '?': + break; + default: + extra_path_info = ACE_OS::strstr (extra_path_info, ".cgi"); + continue; + } + this->cgi_ = 1; + break; + } + + return this->cgi_; +} + +void +HTTP_Request::cgi_args_and_env (char *&extra_path_info) +{ + char *cgi_question = 0; + + if (extra_path_info) + cgi_question = ACE_OS::strchr (extra_path_info, '?'); + + if (extra_path_info == cgi_question) + extra_path_info = 0; + + if (cgi_question) + { + *cgi_question++ = '\0'; + + if (*cgi_question != '\0') + { + // We need the ``original'' QUERY_STRING for the + // environment. We will substitute '+'s for spaces in the + // other copy. + + this->query_string_ = ACE_OS::strdup (cgi_question); + + char *ptr = cgi_question; + int count = 0; + do + if (*ptr == '+') + *ptr = ' '; + else if (*ptr == '&' || *ptr == '=') + count++; + while (*++ptr); + + count++; + + if (ACE_OS::strchr (cgi_question, '=')) + { + ACE_NEW (this->cgi_env_, char *[count+1]); + + int i = 0; + ptr = cgi_question; + do + { + this->cgi_env_ [i++] = ptr; + + while (*ptr++) + if (*ptr == '&' || *ptr == '=') + *ptr = '\0'; + + HTTP_Helper::HTTP_decode_string (this->cgi_env_[i-1]); + } + while (i < count); + + this->cgi_env_[count] = 0; + } + else + { + this->cgi_args_ = cgi_question; + HTTP_Helper::HTTP_decode_string (cgi_question); + } + } + } +} + +const char * +HTTP_Request::path (const char *uri_string) +{ + char const *file_name = uri_string; + char buf[MAXPATHLEN + 1]; + buf[0] = '\0'; + + if (file_name == 0) return 0; + + if (*file_name == '/') + { + file_name++; + if (*file_name == '~') + { + char *ptr = buf; + + while (*++file_name && *file_name != '/') + *ptr++ = *file_name; + + *ptr = '\0'; + + if (ptr == buf) + ACE_OS::strcpy (buf, ACE_OS::getenv ("HOME")); + else + { +#if !defined (ACE_WIN32) && !defined (VXWORKS) + char pw_buf[BUFSIZ]; + struct passwd pw_struct; + if (ACE_OS::getpwnam_r (buf, &pw_struct, pw_buf, sizeof (pw_buf)) + == 0) + return 0; + ACE_OS::strcpy (buf, pw_struct.pw_dir); +#endif /* NOT ACE_WIN32 AND NOT VXWORKS */ + } + + ACE_OS::strcat (buf, "/"); + ACE_OS::strcat (buf, HTTP_Config::instance ()->user_dir ()); + ACE_OS::strcat (buf, file_name); + } + else + { + // With a starting '/' but no '~' + ACE_OS::strcat (buf, HTTP_Config::instance ()->document_root ()); + ACE_OS::strcat (buf, file_name - 1); + } + } + + if (*buf != '\0') + this->path_ = ACE_OS::strdup (buf); + + return this->path_; +} diff --git a/ACE/apps/JAWS/server/HTTP_Request.h b/ACE/apps/JAWS/server/HTTP_Request.h new file mode 100644 index 00000000000..76a8e8739cf --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Request.h @@ -0,0 +1,200 @@ +/* -*- c++ -*- */ + +//============================================================================= +/** + * @file HTTP_Request.h + * + * $Id$ + * + * @author James Hu + */ +//============================================================================= + + +#ifndef HTTP_REQUEST_H +#define HTTP_REQUEST_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Parse_Headers.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_Message_Block; +ACE_END_VERSIONED_NAMESPACE_DECL + +/** + * @class HTTP_Request + * + * @brief This parses the client request of an HTTP transaction. + * + */ +class HTTP_Request +{ +public: + /// Default construction. + HTTP_Request (void); + + /// Destructor. + ~HTTP_Request (void); + + /// parse an incoming request + int parse_request (ACE_Message_Block &mb); + + /// the first line of a request is the request line, which is of the + /// form: METHOD URI VERSION. + void parse_request_line (char *const request_line); + + /// Initialize the request object. This will parse the buffer and + /// prepare for the accessors. + int init (char *const buffer, + int buflen); + +public: + // = The Accessors. + + /// HTTP request method + const char *method (void) const; + + /// HTTP request uri + const char *uri (void) const; + + /// HTTP request version + const char *version (void) const; + + /// The HTTP request uri translated into a server filename path + const char *path (void) const; + + /// TRUE of the request is a cgi request + int cgi (void) const; + + /// The arguments to the cgi request + const char *cgi_args (void) const; + + /// The environment variables passed to the CGI request + const char **cgi_env (void) const; + + /// The cgi request query string + const char *query_string (void) const; + + /// The cgi request path information + const char *path_info (void) const; + + /// The type of the HTTP request + int type (void) const; + + /// The headers that were parsed from the request + const Headers &headers (void) const; + + /// Header strings stored + const char *header_strings (int index) const; + + /// Values associated with the header strings + const char *header_values (int index) const; + + /// The buffer into which request data is read + char *data (void); + + /// The length of the request data + int data_length (void); + + /// The length of incoming content if any + int content_length (void); + + /// Current status of the incoming request + int status (void); + + /// A string describing the state of the incoming request + const char *status_string (void); + + /// Dump the state of the request. + void dump (void); + + enum + { + NO_TYPE = -1, + GET = 0, + HEAD, + POST, + PUT, + NUM_METHOD_STRINGS + }; + // Values for request type + + enum + { + DATE = 0, + PRAGMA, + AUTHORIZATION, + FROM, + IF_MODIFIED_SINCE, + REFERRER, + USER_AGENT, + ALLOW, + CONTENT_ENCODING, + CONTENT_LENGTH, + CONTENT_TYPE, + EXPIRES, + LAST_MODIFIED, + NUM_HEADER_STRINGS + }; + // Header strings + +private: + // = Private Accessors which can set values + const char *method (const char *method_string); + const char *uri (char *uri_string); + const char *version (const char *version_string); + const char *path (const char *uri_string); + + /// determine if the given URI is a CGI program. + int cgi (char *uri_string); + + /// determine if the given URI resides in a cgi-bin directory + int cgi_in_path (char *uri_string, char *&extra_path_info); + + /// determine if the given URI contains a cgi extension + int cgi_in_extension (char *uri_string, char *&extra_path_info); + + /// set the arguments and environment for the cgi program + void cgi_args_and_env (char *&extra_path_info); + + int type (const char *type_string); + +private: + int got_request_line (void) const; + +private: + int got_request_line_; + Headers headers_; + + char *method_; + char *uri_; + char *version_; + char *path_; + + int cgi_; + char **cgi_env_; + char *cgi_args_; + + char *query_string_; + char *path_info_; + + const char * const *const header_strings_; + static const char *const static_header_strings_[NUM_HEADER_STRINGS]; + + const char * const *const method_strings_; + static const char *const static_method_strings_[NUM_METHOD_STRINGS]; + + char *data_; + int datalen_; + int content_length_; + char *filename_; + int status_; + int type_; +}; + +#endif /* HTTP_REQUEST_H */ diff --git a/ACE/apps/JAWS/server/HTTP_Response.cpp b/ACE/apps/JAWS/server/HTTP_Response.cpp new file mode 100644 index 00000000000..9750a1a6482 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Response.cpp @@ -0,0 +1,388 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_ctype.h" +#include "ace/Process.h" +#include "ace/Mem_Map.h" +#include "ace/Log_Msg.h" + +#include "HTTP_Response.h" +#include "HTTP_Request.h" +#include "HTTP_Helpers.h" +#include "HTTP_Config.h" +#include "IO.h" + +ACE_RCSID(server, HTTP_Response, "$Id$") + +#if defined (ACE_JAWS_BASELINE) +static char * const EMPTY_HEADER = ""; +#else +static const char * const EMPTY_HEADER = ""; +#endif /* ACE_JAWS_BASELINE */ + +HTTP_Response::HTTP_Response (JAWS_IO &io, HTTP_Request &request) + : io_(io), request_(request) +{ +} + +HTTP_Response::HTTP_Response (HTTP_Request &request, JAWS_IO &io) + : io_(io), request_(request) +{ +} + +HTTP_Response::~HTTP_Response (void) +{ +#if defined (ACE_JAWS_BASELINE) + if (this->HTTP_HEADER != EMPTY_HEADER) + delete [] this->HTTP_HEADER; + // The [] is important. Without it, there was a huge memory leak! +#endif /* ACE_JAWS_BASELINE */ +} + +void +HTTP_Response::process_request(HTTP_Response &response) +{ + response.process_request(); +} + +void +HTTP_Response::process_request (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) processing request: %s\n", + this->request_.status_string ())); + + switch (this->request_.status ()) + { + case HTTP_Status_Code::STATUS_OK : + + if (this->request_.cgi ()) + { + this->cgi_response (); + } + else + { + this->normal_response (); + } + + break; + + default: + this->error_response (this->request_.status (), + this->request_.status_string ()); + } +} + +void +HTTP_Response::error_response (int status_code, const char *log_message) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) [%s %s %s] %s\n", + this->request_.method () ? this->request_.method () : "-", + this->request_.uri () ? this->request_.uri () : "-", + this->request_.version() ? this->request_.version () : "-", + log_message ? log_message : "-")); + + static char const error_header1[] = + "%s %d %s\r\n" + "Server: JAWS/1.0prebeta\r\n" + "Content-type: text/html\r\n" + "Content-length: %d\r\n" + "\r\n" + "%s" + ; + + static char const error_header2[] = + "%s %d %s\r\n" + "Server: JAWS/1.0prebeta\r\n" + "WWW-Authenticate: Basic realm=\"JAWS_authorization\"\r\n" + "Content-type: text/html\r\n" + "Content-length: %d\r\n" + "\r\n" + "%s" + ; + + static char const error_message[] = + "<html>\n" + "<head><title>Server error message</title></head>\n" + "<body>\n" + "<h1>Error %d: %s</h1>\n" + "The request could not be completed because:\n %s\n" + "</body>\n" + "</html>\n" + ; + + + char *buf; + char buf1[4 * BUFSIZ]; + char buf2[BUFSIZ]; + + int length; + const char *error_header = error_header1; + + if (status_code == HTTP_Status_Code::STATUS_UNAUTHORIZED) + error_header = error_header2; + + length = + ACE_OS::sprintf (buf2, error_message, + status_code, HTTP_Status_Code::instance ()[status_code], + log_message); + + if (this->request_.version () == 0 + || ACE_OS::strcmp ("HTTP/0.9", this->request_.version ()) == 0) + buf = buf2; + else + { + length = + ACE_OS::sprintf (buf1, error_header, + this->request_.version(), status_code, + HTTP_Status_Code::instance ()[status_code], + length, + buf2); + buf = buf1; + } + + this->io_.send_error_message (buf, length); +} + +void +HTTP_Response::normal_response (void) +{ + const char *hv = 0;; + + ACE_DEBUG ((LM_DEBUG, " (%t) %s request for %s [%s], version %s\n", + request_.method (), request_.uri (), request_.path (), + (request_.version () ? request_.version () : "HTTP/0.9"))); + + switch (this->request_.type ()) + { + case HTTP_Request::GET : + + this->build_headers (); + this->io_.transmit_file (this->request_.path (), + this->HTTP_HEADER, + this->HTTP_HEADER_LENGTH, + this->HTTP_TRAILER, + this->HTTP_TRAILER_LENGTH); + break; + + case HTTP_Request::HEAD : + this->build_headers (); + this->io_.send_confirmation_message (this->HTTP_HEADER, + this->HTTP_HEADER_LENGTH); + break; + + case HTTP_Request::POST : + // What to do here? + // Standard says this is implementation dependent. + // Examples: annotations, page updates, etc. + // This may be a good place to stick CORBA stuff, + // and mobile code. + this->error_response (HTTP_Status_Code::STATUS_NOT_IMPLEMENTED, + "Requested method is not implemented."); + break; + + case HTTP_Request::PUT : + // Only commit to this if we can authenticate it + + // if there is no Authentication: header on the incoming request, + // deny it + hv = this->request_.headers ()["Authorization"].value (); + if (hv == 0 || *hv == '\0') + this->error_response (HTTP_Status_Code::STATUS_UNAUTHORIZED, + "Unauthorized to use PUT method"); + else if (ACE_OS::strncmp (hv, "Basic ", 6) != 0) + // ``6'' is the length of the string "Basic " + this->error_response (HTTP_Status_Code::STATUS_UNAUTHORIZED, + "Unknown authorization method"); + else + { + ACE_Mem_Map mmapfile; + const char *hvv = hv + 6; + // Skip past the string "Basic " + char *buf = new char [ACE_OS::strlen (hv)]; + char *auth + = HTTP_Helper::HTTP_decode_base64 (ACE_OS::strcpy (buf, hvv)); + + if (mmapfile.map (ACE_TEXT ("jaws.auth")) != -1 + && auth != 0 + && ACE_OS::strstr((const char *) mmapfile.addr (), auth) != 0) + this->io_.receive_file (this->request_.path (), + this->request_.data (), + this->request_.data_length (), + this->request_.content_length ()); + else + this->error_response (HTTP_Status_Code::STATUS_UNAUTHORIZED, + "Invalid authorization attempt"); + delete [] buf; + } + break; + + default : + this->error_response (HTTP_Status_Code::STATUS_NOT_IMPLEMENTED, + "Requested method is not implemented."); + } +} + + +void +HTTP_Response::cgi_response (void) +{ + ACE_Process_Options cgi_options; + + if (this->request_.cgi_args ()) + cgi_options.command_line ("%s %s", + this->request_.path (), + this->request_.cgi_args ()); + else + cgi_options.command_line ("%s", this->request_.path ()); + + // Build environment variables + cgi_options.setenv ("SERVER_SOFTWARE", "%s", "JAWS/1.0"); + cgi_options.setenv ("SERVER_NAME", "%s", "localhost"); + cgi_options.setenv ("GATEWAY_INTERFACE", "%s", "CGI/1.1"); + + cgi_options.setenv ("SERVER_PROTOCOL", "%s", + this->request_.version () + ? this->request_.version () + : "HTTP/0.9"); + cgi_options.setenv ("SERVER_PORT", "%d", 5432); + + cgi_options.setenv ("REQUEST_METHOD", "%s", this->request_.method ()); + + if (this->request_.path_info ()) + { + cgi_options.setenv ("PATH_INFO", "%s", + this->request_.path_info ()); + cgi_options.setenv ("PATH_TRANSLATED", + "%s/%s", + HTTP_Config::instance ()->document_root (), + this->request_.path_info ()); + } + + cgi_options.setenv ("SCRIPT_NAME", + "%s", + this->request_.uri ()); + + if (this->request_.query_string ()) + cgi_options.setenv ("QUERY_STRING", + "%s", + this->request_.query_string ()); + + if (this->request_.cgi_env ()) + for (size_t i = 0; this->request_.cgi_env ()[i]; i += 2) + cgi_options.setenv (this->request_.cgi_env ()[i], + "%s", + this->request_.cgi_env ()[i+1]); + + char buf[BUFSIZ]; + char *p, *q; + ACE_OS::strcpy (buf, "HTTP_"); + p = q = buf + ACE_OS::strlen (buf); + + for (size_t i = 0; i < HTTP_Request::NUM_HEADER_STRINGS; i++) + { + int j = 0; + + for (char c; (c = this->request_.header_strings (i)[j++]) != '\0'; ) + if (ACE_OS::ace_isalpha (c)) + *q++ = ACE_OS::ace_toupper (c); + else if (c == '-') + *q++ = '_'; + else + *q++ = c; + + *q = '\0'; + + const char *hv = this->request_.header_values (i); + + if (hv && *hv) + cgi_options.setenv (buf, "%s", hv); + q = p; + } + + cgi_options.set_handles (this->io_.handle (), + this->io_.handle (), + this->io_.handle ()); + + this->build_headers (); + this->io_.send_confirmation_message (this->HTTP_HEADER, + this->HTTP_HEADER_LENGTH); + // ACE::send (this->io_.handle (), + // this->HTTP_HEADER, this->HTTP_HEADER_LENGTH); + + // Exec the CGI program. + ACE_Process cgi_process; + cgi_process.spawn (cgi_options); + // cgi_process.wait (); +} + +void +HTTP_Response::build_headers (void) +{ + // At this point, we should really determine the type of request + // this is, and build the appropriate header. + + // Let's assume this is HTML for now. Unless the request is CGI, + // then do not include content-* headers. + + if (this->request_.version () == 0 + || ACE_OS::strcmp ("HTTP/0.9", this->request_.version ()) == 0) + { + HTTP_HEADER = EMPTY_HEADER; + HTTP_HEADER_LENGTH = 0; + } + else + { +#if defined (ACE_JAWS_BASELINE) + HTTP_HEADER = new char[BUFSIZ * 4]; + + // We assume that at this point everything is OK + HTTP_HEADER_LENGTH = + ACE_OS::sprintf (HTTP_HEADER, "%s", "HTTP/1.0 200 OK\r\n"); + + char date_ptr [40]; + // 40 bytes is the maximum length needed to store the date + + if (HTTP_Helper::HTTP_date (date_ptr) != 0) + HTTP_HEADER_LENGTH += + ACE_OS::sprintf (HTTP_HEADER+HTTP_HEADER_LENGTH, + "Date: %s\r\n", date_ptr); + + if (! this->request_.cgi ()) { + HTTP_HEADER_LENGTH += + ACE_OS::sprintf (HTTP_HEADER+HTTP_HEADER_LENGTH, + "Content-type: %s\r\n", + "text/html"); + + struct stat file_stat; + // If possible, add the Content-length field to the header. + // @@ Note that using 'ACE_OS::stat' is a hack. Normally, a + // web browser will have a 'virtual' file system. In a VFS, + // 'stat' might not reference the correct location. + if ((this->request_.type () == HTTP_Request::GET) && + (ACE_OS::stat (this->request_.path (), &file_stat) == 0)) + { + HTTP_HEADER_LENGTH += + ACE_OS::sprintf (HTTP_HEADER+HTTP_HEADER_LENGTH, + "Content-length: %u\r\n", file_stat.st_size); + } + + // Complete header with empty line and adjust header length. + HTTP_HEADER[HTTP_HEADER_LENGTH++] = '\r'; + HTTP_HEADER[HTTP_HEADER_LENGTH++] = '\n'; + } +#else + if (! this->request_.cgi ()) + HTTP_HEADER = "HTTP/1.0 200 OK\r\n" + "Content-type: text/html\r\n\r\n"; + else + HTTP_HEADER = "HTTP/1.0 200 OK\r\n"; + + HTTP_HEADER_LENGTH = ACE_OS::strlen (HTTP_HEADER); + +#endif /* ACE_JAWS_BASELINE */ + } + + HTTP_TRAILER = ""; + HTTP_TRAILER_LENGTH = 0; +} diff --git a/ACE/apps/JAWS/server/HTTP_Response.h b/ACE/apps/JAWS/server/HTTP_Response.h new file mode 100644 index 00000000000..05a595a9fdf --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Response.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ + +//============================================================================= +/** + * @file HTTP_Response.h + * + * $Id$ + * + * @author James Hu + */ +//============================================================================= + + +#ifndef HTTP_RESPONSE_H +#define HTTP_RESPONSE_H + +class JAWS_IO; +class HTTP_Request; + +/** + * @class HTTP_Response + * + * @brief Abstraction for HTTP responses. + * + * Provides an encapsulation of responses to HTTP requests. + * For instance, given an HTTP GET request, it will produce + * header and body suitable for returning to the client who made + * the request. + */ +class HTTP_Response +{ +public: + HTTP_Response (JAWS_IO &io, + HTTP_Request &request); + HTTP_Response (HTTP_Request &request, JAWS_IO &io); + ~HTTP_Response (void); + + /// This is called by the handler to initiate a response. + void process_request (void); + + /// This returns an error response for cases where there is a problem + /// with the request, logging the log_message. + void error_response (int status, + const char *log_message); + +private: + + /// Called by process_request when the request is a normal request. + void normal_response (void); + + /// Called by process_request when the request is a cgi request. + void cgi_response (void); + +private: + + /// static version of process_request, just in case. + static void process_request (HTTP_Response &response); + + /// creates the appropriate header information for responses. + void build_headers (void); + +private: + /// The IO and Request objects associated with this re + JAWS_IO &io_; + HTTP_Request &request_; + +#if defined (ACE_JAWS_BASELINE) + char *HTTP_HEADER; +#else + const char *HTTP_HEADER; +#endif + /// HTTP Headers and trailers. + const char *HTTP_TRAILER; + int HTTP_HEADER_LENGTH; + int HTTP_TRAILER_LENGTH; +}; + +#endif /* HTTP_RESPONSE_H */ diff --git a/ACE/apps/JAWS/server/HTTP_Server.cpp b/ACE/apps/JAWS/server/HTTP_Server.cpp new file mode 100644 index 00000000000..dcaf1858cd4 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Server.cpp @@ -0,0 +1,431 @@ +// $Id$ + +#ifndef ACE_BUILD_SVC_DLL +#define ACE_BUILD_SVC_DLL +#endif /* ACE_BUILD_SVC_DLL */ + +#include "ace/OS_NS_string.h" +#include "ace/Get_Opt.h" +#include "ace/Asynch_Acceptor.h" +#include "ace/LOCK_SOCK_Acceptor.h" +#include "ace/Proactor.h" +#include "ace/Signal.h" +#include "ace/Auto_Ptr.h" + +#include "IO.h" +#include "HTTP_Server.h" + +ACE_RCSID(server, HTTP_Server, "$Id$") + +// class is overkill +class JAWS +{ +public: + enum + { + JAWS_POOL = 0, + JAWS_PER_REQUEST = 1 + }; + + enum + { + JAWS_SYNCH = 0, + JAWS_ASYNCH = 2 + }; +}; + +void +HTTP_Server::parse_args (int argc, ACE_TCHAR *argv[]) +{ + int c; + int thr_strategy = 0; + int io_strategy = 0; + const ACE_TCHAR *prog = argc > 0 ? argv[0] : ACE_TEXT ("HTTP_Server"); + + // Set some defaults + this->port_ = 0; + this->threads_ = 0; + this->backlog_ = 0; + this->throttle_ = 0; + this->caching_ = true; + + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:n:t:i:b:c:")); + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'p': + this->port_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'n': + this->threads_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 't': + // POOL -> thread pool + // PER_REQUEST -> thread per request + // THROTTLE -> thread per request with throttling + if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("POOL")) == 0) + thr_strategy = JAWS::JAWS_POOL; + else if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("PER_REQUEST")) == 0) + { + thr_strategy = JAWS::JAWS_PER_REQUEST; + this->throttle_ = 0; + } + else if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("THROTTLE")) == 0) + { + thr_strategy = JAWS::JAWS_PER_REQUEST; + this->throttle_ = 1; + } + break; + case 'f': + if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("THR_BOUND")) == 0) + { + // What happened here? + } + else if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("THR_DAEMON")) == 0) + { + } + else if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("THR_DETACHED")) == 0) + { + } + case 'i': + // SYNCH -> synchronous I/O + // ASYNCH -> asynchronous I/O + if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("SYNCH")) == 0) + io_strategy = JAWS::JAWS_SYNCH; + else if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("ASYNCH")) == 0) + io_strategy = JAWS::JAWS_ASYNCH; + break; + case 'b': + this->backlog_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'c': + if (ACE_OS::strcmp (get_opt.opt_arg (), ACE_TEXT ("NO_CACHE")) == 0) + this->caching_ = false; + else + this->caching_ = true; + break; + default: + break; + } + + // No magic numbers. + if (this->port_ <= 0) + this->port_ = 5432; + if (this->threads_ <= 0) + this->threads_ = 5; + // Don't use number of threads as default + if (this->backlog_ <= 0) + this->backlog_ = this->threads_; + + this->strategy_ = thr_strategy | io_strategy; + + ACE_UNUSED_ARG (prog); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("in HTTP_Server::init, %s port = %d, ") + ACE_TEXT ("number of threads = %d\n"), + prog, this->port_, this->threads_)); +} + +int +HTTP_Server::init (int argc, ACE_TCHAR *argv[]) + // Document this function +{ + // Ignore signals generated when a connection is broken unexpectedly. + ACE_Sig_Action sig ((ACE_SignalHandler) SIG_IGN, SIGPIPE); + ACE_UNUSED_ARG (sig); + + // Parse arguments which sets the initial state. + this->parse_args (argc, argv); + + //If the IO strategy is synchronous (SYNCH case), then choose a handler + //factory based on the desired caching scheme + HTTP_Handler_Factory *f = 0; + + if (this->strategy_ != (JAWS::JAWS_POOL | JAWS::JAWS_ASYNCH)) + if (this->caching_) + ACE_NEW_RETURN (f, Synch_HTTP_Handler_Factory (), -1); + else + ACE_NEW_RETURN (f, No_Cache_Synch_HTTP_Handler_Factory (), -1); + + //NOTE: At this point f better not be a NULL pointer, + //so please do not change the ACE_NEW_RETURN macros unless + //you know what you are doing + ACE_Auto_Ptr<HTTP_Handler_Factory> factory (f); + + + // Choose what concurrency strategy to run. + switch (this->strategy_) + { + case (JAWS::JAWS_POOL | JAWS::JAWS_ASYNCH) : + return this->asynch_thread_pool (); + + case (JAWS::JAWS_PER_REQUEST | JAWS::JAWS_SYNCH) : + return this->thread_per_request (*factory.get ()); + + case (JAWS::JAWS_POOL | JAWS::JAWS_SYNCH) : + default: + return this->synch_thread_pool (*factory.get ()); + } + + ACE_NOTREACHED (return 0); +} + +int +HTTP_Server::fini (void) +{ + this->tm_.close (); + return 0; +} + + +int +HTTP_Server::synch_thread_pool (HTTP_Handler_Factory &factory) +{ + // Main thread opens the acceptor + if (this->acceptor_.open (ACE_INET_Addr (this->port_), 1, + PF_INET, this->backlog_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("HTTP_Acceptor::open")), -1); + + // Create a pool of threads to handle incoming connections. + Synch_Thread_Pool_Task t (this->acceptor_, this->tm_, this->threads_, factory); + + this->tm_.wait (); + return 0; +} + +Synch_Thread_Pool_Task::Synch_Thread_Pool_Task (HTTP_Acceptor &acceptor, + ACE_Thread_Manager &tm, + int threads, + HTTP_Handler_Factory &factory) + : ACE_Task<ACE_NULL_SYNCH> (&tm), + acceptor_ (acceptor), + factory_ (factory) +{ + if (this->activate (THR_DETACHED | THR_NEW_LWP, threads) == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Synch_Thread_Pool_Task::open"))); +} + +int +Synch_Thread_Pool_Task::svc (void) +{ + // Creates a factory of HTTP_Handlers binding to synchronous I/O strategy + //Synch_HTTP_Handler_Factory factory; + + for (;;) + { + ACE_SOCK_Stream stream; + + // Lock in this accept. When it returns, we have a connection. + if (this->acceptor_.accept (stream) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT("%p\n"), + ACE_TEXT ("HTTP_Acceptor::accept")), -1); + + ACE_Message_Block *mb; + ACE_NEW_RETURN (mb, + ACE_Message_Block (HTTP_Handler::MAX_REQUEST_SIZE + 1), + -1); + + // Create an HTTP Handler to handle this request + HTTP_Handler *handler = this->factory_.create_http_handler (); + handler->open (stream.get_handle (), *mb); + // Handler is destroyed when the I/O puts the Handler into the + // done state. + + mb->release (); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" (%t) in Synch_Thread_Pool_Task::svc, recycling\n"))); + } + + ACE_NOTREACHED(return 0); +} + +int +HTTP_Server::thread_per_request (HTTP_Handler_Factory &factory) +{ + int grp_id = -1; + + // thread per request + // Main thread opens the acceptor + if (this->acceptor_.open (ACE_INET_Addr (this->port_), 1, + PF_INET, this->backlog_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("HTTP_Acceptor::open")), -1); + + ACE_SOCK_Stream stream; + + // When we are throttling, this is the amount of time to wait before + // checking for runnability again. + const ACE_Time_Value wait_time (0, 10); + + for (;;) + { + if (this->acceptor_.accept (stream) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("HTTP_Acceptor::accept")), -1); + + Thread_Per_Request_Task *t; + // Pass grp_id as a constructor param instead of into open. + ACE_NEW_RETURN (t, Thread_Per_Request_Task (stream.get_handle (), + this->tm_, + grp_id, + factory), + -1); + + + if (t->open () != 0) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Thread_Per_Request_Task::open")), + -1); + + // Throttling is not allowing too many threads to run away. + // Should really use some sort of condition variable here. + if (!this->throttle_) + continue; + + // This works because each task has only one thread. + while (this->tm_.num_tasks_in_group (grp_id) > this->threads_) + this->tm_.wait (&wait_time); + } + + ACE_NOTREACHED(return 0); +} + +Thread_Per_Request_Task::Thread_Per_Request_Task (ACE_HANDLE handle, + ACE_Thread_Manager &tm, + int &grp_id, + HTTP_Handler_Factory &factory) + : ACE_Task<ACE_NULL_SYNCH> (&tm), + handle_ (handle), + grp_id_ (grp_id), + factory_ (factory) +{ +} + + +// HEY! Add a method to the thread_manager to return total number of +// threads managed in all the tasks. + +int +Thread_Per_Request_Task::open (void *) +{ + int status = -1; + + if (this->grp_id_ == -1) + status = this->grp_id_ = this->activate (THR_DETACHED | THR_NEW_LWP); + else + status = this->activate (THR_DETACHED | THR_NEW_LWP, + 1, 0, -1, this->grp_id_, 0); + + if (status == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Thread_Per_Request_Task::open")), + -1); + return 0; +} + +int +Thread_Per_Request_Task::svc (void) +{ + ACE_Message_Block *mb; + ACE_NEW_RETURN (mb, ACE_Message_Block (HTTP_Handler::MAX_REQUEST_SIZE + 1), + -1); + //Synch_HTTP_Handler_Factory factory; + HTTP_Handler *handler = this->factory_.create_http_handler (); + handler->open (this->handle_, *mb); + mb->release (); + return 0; +} + +int +Thread_Per_Request_Task::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" (%t) Thread_Per_Request_Task::svc, dying\n"))); + delete this; + return 0; +} + +// Understanding the code below requires understanding of the +// WindowsNT asynchronous completion notification mechanism and the +// Proactor Pattern. + +// (1) The application submits an asynchronous I/O request to the +// operating system and a special handle with it (Asynchronous +// Completion Token). +// (2) The operating system commits to performing the I/O request, +// while application does its own thing. +// (3) Operating system finishes the I/O request and places ACT onto +// the I/O Completion Port, which is a queue of finished +// asynchronous requests. +// (4) The application eventually checks to see if the I/O request +// is done by checking the I/O Completion Port, and retrieves the +// ACT. + +int +HTTP_Server::asynch_thread_pool (void) +{ +// This only works on Win32 +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + // Create the appropriate acceptor for this concurrency strategy and + // an appropriate handler for this I/O strategy + ACE_Asynch_Acceptor<Asynch_HTTP_Handler_Factory> acceptor; + + // Tell the acceptor to listen on this->port_, which makes an + // asynchronous I/O request to the OS. + if (acceptor.open (ACE_INET_Addr (this->port_), + HTTP_Handler::MAX_REQUEST_SIZE + 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Asynch_Acceptor::open")), -1); + + // Create the thread pool. + // Register threads with the proactor and thread manager. + Asynch_Thread_Pool_Task t (*ACE_Proactor::instance (), + this->tm_); + + // The proactor threads are waiting on the I/O Completion Port. + + // Wait for the threads to finish. + return this->tm_.wait (); +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + return -1; +} + +// This only works on Win32 +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + +Asynch_Thread_Pool_Task::Asynch_Thread_Pool_Task (ACE_Proactor &proactor, + ACE_Thread_Manager &tm) + : ACE_Task<ACE_NULL_SYNCH> (&tm), + proactor_ (proactor) +{ + if (this->activate () == -1) + ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("Asynch_Thread_Pool_Task::open"))); +} + +int +Asynch_Thread_Pool_Task::svc (void) +{ + for (;;) + if (this->proactor_.handle_events () == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE_Proactor::handle_events")), + -1); + + return 0; +} + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + +// Define the factory function. +ACE_SVC_FACTORY_DEFINE (HTTP_Server) + +// Define the object that describes the service. +ACE_STATIC_SVC_DEFINE (HTTP_Server, ACE_TEXT ("HTTP_Server"), ACE_SVC_OBJ_T, + &ACE_SVC_NAME (HTTP_Server), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, 0) + diff --git a/ACE/apps/JAWS/server/HTTP_Server.h b/ACE/apps/JAWS/server/HTTP_Server.h new file mode 100644 index 00000000000..c7afbf729e0 --- /dev/null +++ b/ACE/apps/JAWS/server/HTTP_Server.h @@ -0,0 +1,160 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file HTTP_Server.h + * + * $Id$ + * + * @author James Hu + */ +//============================================================================= + + +#ifndef HTTP_SERVER_H +#define HTTP_SERVER_H + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Service_Config.h" +#include "ace/Service_Object.h" +#include "ace/Thread_Manager.h" +#include "ace/Acceptor.h" +#include "ace/LOCK_SOCK_Acceptor.h" +#include "ace/Task_T.h" +#include "ace/Asynch_IO.h" +#include "ace/svc_export.h" +#include "HTTP_Handler.h" +#include "ace/Synch_Traits.h" +#include "ace/Thread_Mutex.h" +#include "ace/Null_Mutex.h" +#include "ace/Global_Macros.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +// Forward declaration. +class ACE_Proactor; +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_HAS_THREAD_SAFE_ACCEPT) +typedef ACE_LOCK_SOCK_Acceptor<ACE_SYNCH_NULL_MUTEX> HTTP_SOCK_Acceptor; +#else +typedef ACE_LOCK_SOCK_Acceptor<ACE_SYNCH_MUTEX> HTTP_SOCK_Acceptor; +#endif /* ACE_HAS_THREAD_SAFE_ACCEPT */ + +typedef HTTP_SOCK_Acceptor HTTP_Acceptor; + +/** + * @class HTTP_Server + * + * @brief This server is used to create HTTP Handlers for the Web + * server + * + */ +class ACE_Svc_Export HTTP_Server : public ACE_Service_Object +{ +public: + /// Initialization + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Exit hooks + virtual int fini (void); + +protected: + /// Thread Per Request implementation + virtual int thread_per_request (HTTP_Handler_Factory &factory); + + /// Asynch Thread Pool implementation + virtual int asynch_thread_pool (void); + + /// Synch Thread Pool implementation + virtual int synch_thread_pool (HTTP_Handler_Factory &factory); + +private: + // James, comment these data members. + void parse_args (int argc, ACE_TCHAR **argv); + int port_; + int threads_; + int strategy_; + int backlog_; + int throttle_; + bool caching_; + ACE_Thread_Manager tm_; + HTTP_Acceptor acceptor_; +}; + +/** + * @class Synch_Thread_Pool_Task + * + * @brief Used to implement Synch Thread Pool + * + * Describe this and the others below. + * NOTE: this class was modified to make caching disabling possible + */ +class Synch_Thread_Pool_Task : public ACE_Task<ACE_NULL_SYNCH> +{ +public: + Synch_Thread_Pool_Task (HTTP_Acceptor &acceptor, + ACE_Thread_Manager &tm, + int threads, + HTTP_Handler_Factory &factory); + virtual int svc (void); + +private: + HTTP_Acceptor &acceptor_; + HTTP_Handler_Factory &factory_; +}; + +/** + * @class Thread_Per_Request_Task + * + * @brief Used to implement Thread Per Request. + * + * Spawns a new thread for every new incoming connection. The + * handle below is the socket stream of the incoming connection. + * NOTE: this class was modified to make caching disabling possible + */ +class Thread_Per_Request_Task : public ACE_Task<ACE_NULL_SYNCH> +{ +public: + Thread_Per_Request_Task (ACE_HANDLE handle, + ACE_Thread_Manager &tm, + int &grp_id, + HTTP_Handler_Factory &factory); + virtual int open (void *args = 0); + virtual int close (u_long); + virtual int svc (void); + +private: + ACE_HANDLE handle_; + int &grp_id_; + HTTP_Handler_Factory &factory_; +}; + +// This only works on Win32 +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) +/** + * @class Asynch_Thread_Pool_Task + * + * @brief Used to implement Asynch Thread Pool + * + * The proactor below utilizes WaitForMultipleObjects. + */ +class Asynch_Thread_Pool_Task : public ACE_Task<ACE_NULL_SYNCH> +{ +public: + Asynch_Thread_Pool_Task (ACE_Proactor &proactor, + ACE_Thread_Manager &tm); + virtual int svc (void); + +private: + ACE_Proactor &proactor_; +}; +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + +ACE_SVC_FACTORY_DECLARE (HTTP_Server) + +ACE_STATIC_SVC_DECLARE_EXPORT (ACE_Svc, HTTP_Server) + +#endif /* HTTP_SERVER_H */ diff --git a/ACE/apps/JAWS/server/IO.cpp b/ACE/apps/JAWS/server/IO.cpp new file mode 100644 index 00000000000..394a6a88f2a --- /dev/null +++ b/ACE/apps/JAWS/server/IO.cpp @@ -0,0 +1,563 @@ +// $Id$ + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_uio.h" +#include "ace/OS_NS_sys_socket.h" +#include "ace/Message_Block.h" +#include "ace/Min_Max.h" +#include "ace/SOCK_Stream.h" +#include "ace/Filecache.h" +#include "IO.h" +#include "HTTP_Helpers.h" + +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_sys_stat.h" +#include "ace/Auto_Ptr.h" +#include "ace/Basic_Types.h" + +ACE_RCSID (server, + IO, + "$Id$") + + +JAWS_IO::JAWS_IO (void) + : handler_ (0) +{ +} + +JAWS_IO::~JAWS_IO (void) +{ +} + +void +JAWS_IO::handler (JAWS_IO_Handler *handler) +{ + this->handler_ = handler; +} + +JAWS_IO_Handler::~JAWS_IO_Handler (void) +{ +} + +JAWS_Synch_IO::JAWS_Synch_IO (void) + : handle_ (ACE_INVALID_HANDLE) +{ +} + +JAWS_Synch_IO::~JAWS_Synch_IO (void) +{ + ACE_OS::closesocket (this->handle_); +} + +ACE_HANDLE +JAWS_Synch_IO::handle (void) const +{ + return this->handle_; +} + +void +JAWS_Synch_IO::handle (ACE_HANDLE handle) +{ + this->handle_ = handle; +} + +void +JAWS_Synch_IO::read (ACE_Message_Block &mb, + int size) +{ + ACE_SOCK_Stream stream; + stream.set_handle (this->handle_); + int result = stream.recv (mb.wr_ptr (), size); + + if (result <= 0) + this->handler_->read_error (); + else + { + mb.wr_ptr (result); + this->handler_->read_complete (mb); + } +} + +void +JAWS_Synch_IO::receive_file (const char *filename, + void *initial_data, + int initial_data_length, + int entire_length) +{ + ACE_Filecache_Handle handle (filename, entire_length); + + int result = handle.error (); + + if (result == ACE_Filecache_Handle::ACE_SUCCESS) + { + ACE_SOCK_Stream stream; + stream.set_handle (this->handle_); + + int bytes_to_memcpy = ACE_MIN (entire_length, initial_data_length); + ACE_OS::memcpy (handle.address (), initial_data, bytes_to_memcpy); + + int bytes_to_read = entire_length - bytes_to_memcpy; + + int bytes = stream.recv_n ((char *) handle.address () + initial_data_length, + bytes_to_read); + if (bytes == bytes_to_read) + this->handler_->receive_file_complete (); + else + result = -1; + } + + if (result != ACE_Filecache_Handle::ACE_SUCCESS) + this->handler_->receive_file_error (result); +} + +void +JAWS_Synch_IO::transmit_file (const char *filename, + const char *header, + int header_size, + const char *trailer, + int trailer_size) +{ + ACE_Filecache_Handle handle (filename); + + int result = handle.error (); + + if (result == ACE_Filecache_Handle::ACE_SUCCESS) + { +#if defined (ACE_JAWS_BASELINE) || defined (ACE_WIN32) + ACE_SOCK_Stream stream; + stream.set_handle (this->handle_); + + if ((stream.send_n (header, header_size) == header_size) + && (stream.send_n (handle.address (), handle.size ()) + == handle.size ()) + && (stream.send_n (trailer, trailer_size) == trailer_size)) + this->handler_->transmit_file_complete (); + else + result = -1; +#else + // Attempting to use writev + // Is this faster? + iovec iov[3]; + int iovcnt = 0; + if (header_size > 0) + { + iov[iovcnt].iov_base = const_cast<char*> (header); + iov[iovcnt].iov_len = header_size; + iovcnt++; + } + if (handle.size () > 0) + { + iov[iovcnt].iov_base = reinterpret_cast<char*> (handle.address ()); + iov[iovcnt].iov_len = handle.size (); + iovcnt++; + } + if (trailer_size > 0) + { + iov[iovcnt].iov_base = const_cast<char*> (trailer); + iov[iovcnt].iov_len = trailer_size; + iovcnt++; + } + if (ACE_OS::writev (this->handle_, iov, iovcnt) < 0) + result = -1; + else + this->handler_->transmit_file_complete (); +#endif /* ACE_JAWS_BASELINE */ + } + + if (result != ACE_Filecache_Handle::ACE_SUCCESS) + this->handler_->transmit_file_error (result); +} + +void +JAWS_Synch_IO::send_confirmation_message (const char *buffer, + int length) +{ + this->send_message (buffer, length); + this->handler_->confirmation_message_complete (); +} + +void +JAWS_Synch_IO::send_error_message (const char *buffer, + int length) +{ + this->send_message (buffer, length); + this->handler_->error_message_complete (); +} + +void +JAWS_Synch_IO::send_message (const char *buffer, + int length) +{ + ACE_SOCK_Stream stream; + stream.set_handle (this->handle_); + stream.send_n (buffer, length); +} + +// This only works on Win32 +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + +JAWS_Asynch_IO::JAWS_Asynch_IO (void) +{ +} + +JAWS_Asynch_IO::~JAWS_Asynch_IO (void) +{ + ACE_OS::closesocket (this->handle_); +} + +void +JAWS_Asynch_IO::read (ACE_Message_Block& mb, + int size) +{ + ACE_Asynch_Read_Stream ar; + + if (ar.open (*this, this->handle_) == -1 + || ar.read (mb, size) == -1) + this->handler_->read_error (); +} + +// This method will be called when an asynchronous read completes on a +// stream. + +void +JAWS_Asynch_IO::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result) +{ + // This callback is for this->receive_file() + if (result.act () != 0) + { + int code = 0; + if (result.success () && result.bytes_transferred () != 0) + { + if (result.message_block ().length () == result.message_block ().size ()) + code = ACE_Filecache_Handle::ACE_SUCCESS; + else + { + ACE_Asynch_Read_Stream ar; + if (ar.open (*this, this->handle_) == -1 + || ar.read (result.message_block (), + result.message_block ().size () - result.message_block ().length (), + result.act ()) == -1) + code = -1; + else + return; + } + } + else + code = -1; + + if (code == ACE_Filecache_Handle::ACE_SUCCESS) + this->handler_->receive_file_complete (); + else + this->handler_->receive_file_error (code); + + delete &result.message_block (); + delete (ACE_Filecache_Handle *) result.act (); + } + else + { + // This callback is for this->read() + if (result.success () + && result.bytes_transferred () != 0) + this->handler_->read_complete (result.message_block ()); + else + this->handler_->read_error (); + } +} + +void +JAWS_Asynch_IO::receive_file (const char *filename, + void *initial_data, + int initial_data_length, + int entire_length) +{ + ACE_Message_Block *mb = 0; + ACE_Filecache_Handle *handle; + + ACE_NEW (handle, ACE_Filecache_Handle (filename, entire_length, ACE_NOMAP)); + + int result = handle->error (); + + if (result == ACE_Filecache_Handle::ACE_SUCCESS) + { + ACE_OS::memcpy (handle->address (), + initial_data, + initial_data_length); + + int bytes_to_read = entire_length - initial_data_length; + + ACE_NEW (mb, ACE_Message_Block ((char *)handle->address () + + initial_data_length, bytes_to_read)); + + if (mb == 0) + { + errno = ENOMEM; + result = -1; + } + else + { + ACE_Asynch_Read_Stream ar; + + if (ar.open (*this, this->handle_) == -1 + || ar.read (*mb, mb->size () - mb->length (), handle) == -1) + result = -1; + } + } + + if (result != ACE_Filecache_Handle::ACE_SUCCESS) + { + this->handler_->receive_file_error (result); + delete mb; + delete handle; + } +} + +void +JAWS_Asynch_IO::transmit_file (const char *filename, + const char *header, + int header_size, + const char *trailer, + int trailer_size) +{ + ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer = 0; + ACE_Filecache_Handle *handle = new ACE_Filecache_Handle (filename, ACE_NOMAP); + + int result = handle->error (); + + if (result == ACE_Filecache_Handle::ACE_SUCCESS) + { + ACE_Message_Block header_mb (header, header_size); + ACE_Message_Block trailer_mb (trailer, trailer_size); + + header_and_trailer = new ACE_Asynch_Transmit_File::Header_And_Trailer + (&header_mb, header_size, &trailer_mb, trailer_size); + + ACE_Asynch_Transmit_File tf; + + if (tf.open (*this, this->handle_) == -1 + || tf.transmit_file (handle->handle (), // file handle + header_and_trailer, // header and trailer data + 0, // bytes_to_write + 0, // offset + 0, // offset_high + 0, // bytes_per_send + 0, // flags + handle // act + ) == -1) + result = -1; + } + + if (result != ACE_Filecache_Handle::ACE_SUCCESS) + { + this->handler_->transmit_file_error (result); + delete header_and_trailer; + delete handle; + } +} + + +// This method will be called when an asynchronous transmit file completes. +void +JAWS_Asynch_IO::handle_transmit_file (const ACE_Asynch_Transmit_File::Result &result) +{ + if (result.success ()) + this->handler_->transmit_file_complete (); + else + this->handler_->transmit_file_error (-1); + + delete result.header_and_trailer (); + delete (ACE_Filecache_Handle *) result.act (); +} + +void +JAWS_Asynch_IO::send_confirmation_message (const char *buffer, + int length) +{ + this->send_message (buffer, length, CONFORMATION); +} + +void +JAWS_Asynch_IO::send_error_message (const char *buffer, + int length) +{ + this->send_message (buffer, length, ERROR_MESSAGE); +} + +void +JAWS_Asynch_IO::send_message (const char *buffer, + int length, + int act) +{ + ACE_Message_Block *mb; + ACE_NEW (mb, ACE_Message_Block (buffer, length)); + + if (mb == 0) + { + this->handler_->error_message_complete (); + return; + } + + ACE_Asynch_Write_Stream aw; + if (aw.open (*this, this->handle_) == -1 + || aw.write (*mb, length, (void *) static_cast<intptr_t> (act)) == -1) + { + mb->release (); + + if (act == CONFORMATION) + this->handler_->confirmation_message_complete (); + else + this->handler_->error_message_complete (); + } +} + +void +JAWS_Asynch_IO::handle_write_stream (const ACE_Asynch_Write_Stream::Result &result) +{ + result.message_block ().release (); + + if (result.act () == (void *) CONFORMATION) + this->handler_->confirmation_message_complete (); + else + this->handler_->error_message_complete (); +} + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + +//-------------------Adding SYNCH IO no Caching + +JAWS_Synch_IO_No_Cache::JAWS_Synch_IO_No_Cache (void) + : handle_ (ACE_INVALID_HANDLE) +{ +} + +JAWS_Synch_IO_No_Cache::~JAWS_Synch_IO_No_Cache (void) +{ + ACE_OS::closesocket (this->handle_); +} + +ACE_HANDLE +JAWS_Synch_IO_No_Cache::handle (void) const +{ + return this->handle_; +} + +void +JAWS_Synch_IO_No_Cache::handle (ACE_HANDLE handle) +{ + this->handle_ = handle; +} + +void +JAWS_Synch_IO_No_Cache::read (ACE_Message_Block &mb, int size) +{ + ACE_SOCK_Stream stream; + stream.set_handle (this->handle_); + int result = stream.recv (mb.wr_ptr (), size); + + if (result <= 0) + this->handler_->read_error (); + else + { + mb.wr_ptr (result); + this->handler_->read_complete (mb); + } +} + +void +JAWS_Synch_IO_No_Cache::receive_file (const char *, + void *, + int, + int) +{ + //ugly hack to send HTTP_Status_Code::STATUS_FORBIDDEN + this->handler_->receive_file_error (5); +} + +void +JAWS_Synch_IO_No_Cache::transmit_file (const char *filename, + const char *header, + int header_size, + const char *trailer, + int trailer_size) +{ + int result = 0; + + // Can we access the file? + if (ACE_OS::access (filename, R_OK) == -1) + { + //ugly hack to send in HTTP_Status_Code::STATUS_NOT_FOUND + result = ACE_Filecache_Handle::ACE_ACCESS_FAILED; + this->handler_->transmit_file_error (result); + return; + } + + ACE_stat stat; + + // Can we stat the file? + if (ACE_OS::stat (filename, &stat) == -1) + { + //ugly hack to send HTTP_Status_Code::STATUS_FORBIDDEN + result = ACE_Filecache_Handle::ACE_STAT_FAILED; + this->handler_->transmit_file_error (result); + return; + } + + ACE_OFF_T size = stat.st_size; + + // Can we open the file? + ACE_HANDLE handle = ACE_OS::open (filename, O_RDONLY); + if (handle == ACE_INVALID_HANDLE) + { + //ugly hack to send HTTP_Status_Code::STATUS_FORBIDDEN + result = ACE_Filecache_Handle::ACE_OPEN_FAILED; + this->handler_->transmit_file_error (result); + return; + } + + char* f = new char[size]; + ACE_Auto_Basic_Array_Ptr<char> file (f); + + ACE_OS::read_n (handle, f, size); + + ACE_SOCK_Stream stream; + stream.set_handle (this->handle_); + + if ((stream.send_n (header, header_size) == header_size) + && (stream.send_n (f, size) == size) + && (stream.send_n (trailer, trailer_size) == trailer_size)) + { + this->handler_->transmit_file_complete (); + } + else + { + //ugly hack to default to HTTP_Status_Code::STATUS_INTERNAL_SERVER_ERROR + result = -1; + this->handler_->transmit_file_error (result); + } + + ACE_OS::close (handle); +} + +void +JAWS_Synch_IO_No_Cache::send_confirmation_message (const char *buffer, + int length) +{ + this->send_message (buffer, length); + this->handler_->confirmation_message_complete (); +} + +void +JAWS_Synch_IO_No_Cache::send_error_message (const char *buffer, int length) +{ + this->send_message (buffer, length); + this->handler_->error_message_complete (); +} + +void +JAWS_Synch_IO_No_Cache::send_message (const char *buffer, int length) +{ + ACE_SOCK_Stream stream; + stream.set_handle (this->handle_); + stream.send_n (buffer, length); +} + diff --git a/ACE/apps/JAWS/server/IO.h b/ACE/apps/JAWS/server/IO.h new file mode 100644 index 00000000000..0fd3035558e --- /dev/null +++ b/ACE/apps/JAWS/server/IO.h @@ -0,0 +1,293 @@ +/* -*- c++ -*- */ + +//============================================================================= +/** + * @file IO.h + * + * $Id$ + * + * @author James Hu + */ +//============================================================================= + + +#ifndef JAWS_IO_H +#define JAWS_IO_H + +#include "ace/ACE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Asynch_IO.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_Message_Block; +ACE_END_VERSIONED_NAMESPACE_DECL + +class JAWS_IO_Handler; + + +/** + * @class JAWS_IO + * + * @brief This class defines the abstract interface for an I/O class in + * the context of Web-likes servers + * + * An I/O class should have the following interface. Derived + * classes will define the exactly how the I/O will take place + * (Asynchronous, Synchronous, Reactive) + */ +class JAWS_IO +{ +public: + JAWS_IO (void); + virtual ~JAWS_IO (void); + void handler (JAWS_IO_Handler *handler); + + virtual void handle (ACE_HANDLE h) = 0; + virtual ACE_HANDLE handle (void) const = 0; + + // James, please add documentation here. + + /// read from the handle size bytes into the message block. + virtual void read (ACE_Message_Block& mb, int size) = 0; + + /// send header, filename, trailer to the handle. + virtual void transmit_file (const char *filename, + const char *header, + int header_size, + const char *trailer, + int trailer_size) = 0; + + /// read data from the handle and store in filename. + virtual void receive_file (const char *filename, + void *initial_data, + int initial_data_length, + int entire_length) = 0; + + /// send a confirmation message to the handle. + virtual void send_confirmation_message (const char *buffer, int length) = 0; + + /// send an error message to the handle. + virtual void send_error_message (const char *buffer, int length) = 0; + +protected: + JAWS_IO_Handler *handler_; +}; + +/** + * @class JAWS_IO_Handler + * + * @brief This class defines the abstract interface for an I/O handler class in + * the context of Web-likes servers + * + */ +class JAWS_IO_Handler +{ +public: + + /// Destructor. + virtual ~JAWS_IO_Handler (void); + + /// This method is called by the IO class when new client data shows + /// up. + virtual void read_complete (ACE_Message_Block &data) = 0; + + /// This method is called by the IO class when there was an error in + /// reading new data from the client. + virtual void read_error (void) = 0; + + /// This method is called by the IO class when the requested file has + /// been successfully transmitted to the client. + virtual void transmit_file_complete (void) = 0; + + /// This method is called by the IO class when there was an error in + /// transmitting the requested file to the client. + virtual void transmit_file_error (int result) = 0; + + /// This method is called by the IO class when the requested file has + /// been successfully received from the client. + virtual void receive_file_complete (void) = 0; + + /// This method is called by the IO class when there was an error in + /// receiving the requested file from the client. + virtual void receive_file_error (int result) = 0; + + /// This method is called by the IO class when there was an error in + /// writing data to the client. + virtual void write_error (void) = 0; + + /// This method is called by the IO class when the confirmation + /// message has been delivered to the client. + virtual void confirmation_message_complete (void) = 0; + + /// This method is called by the IO class when the error message has + /// been delivered to the client. + virtual void error_message_complete (void) = 0; + +}; + +/** + * @class JAWS_Synch_IO + * + * @brief This class defines the interface for a Synchronous I/O class. + * + */ +class JAWS_Synch_IO : public JAWS_IO +{ +public: + JAWS_Synch_IO (void); + + ~JAWS_Synch_IO (void); + + virtual void handle (ACE_HANDLE h); + virtual ACE_HANDLE handle (void) const; + + void read (ACE_Message_Block& mb, int size); + + void transmit_file (const char *filename, + const char *header, + int header_size, + const char *trailer, + int trailer_size); + + void receive_file (const char *filename, + void *initial_data, + int initial_data_length, + int entire_length); + + void send_confirmation_message (const char *buffer, + int length); + + void send_error_message (const char *buffer, + int length); + +protected: + virtual void send_message (const char *buffer, + int length); + + ACE_HANDLE handle_; +}; + +// This only works on Win32 +#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) + +/** + * @class JAWS_Asynch_IO + * + * @brief This class defines the interface for a Asynchronous I/O class. + * + */ +class JAWS_Asynch_IO : public JAWS_IO, public ACE_Handler +{ +public: + JAWS_Asynch_IO (void); + + ~JAWS_Asynch_IO (void); + + virtual void handle (ACE_HANDLE h) { ACE_Handler::handle (h); }; + virtual ACE_HANDLE handle (void) const { return ACE_Handler::handle (); }; + + void read (ACE_Message_Block& mb, int size); + + void transmit_file (const char *filename, + const char *header, + int header_size, + const char *trailer, + int trailer_size); + + void receive_file (const char *filename, + void *initial_data, + int initial_data_length, + int entire_length); + + void send_confirmation_message (const char *buffer, + int length); + + void send_error_message (const char *buffer, + int length); + +protected: + enum Message_Types + { + CONFORMATION, + ERROR_MESSAGE + }; + + virtual void send_message (const char *buffer, + int length, + int act); + + /// This method will be called when an asynchronous read completes on + /// a stream. + virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result); + + /// This method will be called when an asynchronous write completes + /// on a stream. + virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result); + + /// This method will be called when an asynchronous transmit file + /// completes. + virtual void handle_transmit_file (const ACE_Asynch_Transmit_File::Result &result); +}; + +#endif /* ACE_HAS_WIN32_OVERLAPPED_IO */ + + +//-------------------Adding SYNCH IO no Caching + +/** + * @class JAWS_Synch_IO_No_Cache + * + * @brief This class defines the interface for a Synchronous I/O class, + * however in this class we do not use any caching. + * + * Wondering how this is useful? + * The ACE_Filecache ACE_NOMAP option is broken and even if it were not, there + * are other use cases in which we want to avoid caching altogether. For example, + * we use JAWS in conjunction with the CIAO Repository Manager, however the two + * do not have any explicit knowledge of each other. Therefore if the RM tried + * to remove a package and its files from disk, its operation would [partially] + * fail if JAWS still holds some of the files in its cache. + */ +class JAWS_Synch_IO_No_Cache : public JAWS_IO +{ +public: + JAWS_Synch_IO_No_Cache (void); + + ~JAWS_Synch_IO_No_Cache (void); + + virtual void handle (ACE_HANDLE h); + virtual ACE_HANDLE handle (void) const; + + void read (ACE_Message_Block& mb, int size); + + void transmit_file (const char *filename, + const char *header, + int header_size, + const char *trailer, + int trailer_size); + + void receive_file (const char *filename, + void *initial_data, + int initial_data_length, + int entire_length); + + void send_confirmation_message (const char *buffer, + int length); + + void send_error_message (const char *buffer, + int length); + +protected: + virtual void send_message (const char *buffer, int length); + + ACE_HANDLE handle_; +}; + +//------------------- + +#endif /* JAWS_IO_H */ + diff --git a/ACE/apps/JAWS/server/JAWS_Concurrency.cpp b/ACE/apps/JAWS/server/JAWS_Concurrency.cpp new file mode 100644 index 00000000000..6398469625d --- /dev/null +++ b/ACE/apps/JAWS/server/JAWS_Concurrency.cpp @@ -0,0 +1,82 @@ +// $Id$ + +#include "JAWS_Concurrency.h" + +ACE_RCSID(server, JAWS_Concurrency, "$Id$") + +JAWS_Concurrency_Base::JAWS_Concurrency_Base (void) +{ +} + +int +JAWS_Concurrency_Base::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return this->putq (mb, tv); +} + +int +JAWS_Concurrency_Base::svc (void) +{ + int result = 0; + + for (;;) + { + ACE_Message_Block *mb = 0; + + // At this point we could set a timeout value so that the + // threading strategy can delete a thread if there is nothing to + // do. Carefully think how to implement it so you don't leave + // yourself with 0 threads. + + result = this->getq (mb); + if (result == -1 || mb == 0) + break; + + this->put_next (mb); + } + return 0; +} + +JAWS_Dispatch_Policy::JAWS_Dispatch_Policy (void) +{ +} + +JAWS_Dispatch_Policy::~JAWS_Dispatch_Policy (void) +{ +} + +JAWS_Dispatcher::JAWS_Dispatcher (JAWS_Dispatch_Policy *policy) + : policy_(policy) +{ +} + +JAWS_Thread_Pool_Task::JAWS_Thread_Pool_Task (long flags, + int nthreads, + int maxthreads) + : nthreads_ (nthreads), + maxthreads_ (maxthreads) +{ + if (this->activate (flags, nthreads) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "JAWS_Thread_Pool_Task::activate")); +} + +JAWS_Thread_Per_Task::JAWS_Thread_Per_Task (long flags, int maxthreads) + : flags_ (flags), + maxthreads_ (maxthreads) +{ +} + +int +JAWS_Thread_Per_Task::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + const int force_active = 1; + const int nthreads = 1; + + if (this->activate (this->flags_, nthreads, force_active) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "JAWS_Thread_Pool_Task::activate"), + -1); + + this->putq (mb, tv); + + return 0; +} diff --git a/ACE/apps/JAWS/server/JAWS_Concurrency.h b/ACE/apps/JAWS/server/JAWS_Concurrency.h new file mode 100644 index 00000000000..7096d1dbefa --- /dev/null +++ b/ACE/apps/JAWS/server/JAWS_Concurrency.h @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +// $Id$ + +#ifndef JAWS_CONCURRENCY_H +#define JAWS_CONCURRENCY_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Task.h" +#include "IO.h" + +class JAWS_Concurrency_Base : public ACE_Task<ACE_SYNCH> + // = TITLE + // Base class for different concurrency models + // + // = DESCRIPTION + // Provides a default implementaion of the virtual put() method + // which calls putq(), but can be overloaded to do something + // synchronously, such as call put_next(). + +{ +public: + JAWS_Concurrency_Base (void); + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0); + virtual int svc (void); +}; + +class JAWS_Dispatch_Policy + // = TITLE + // Policy mechanism for choosing different concurrency models. + // + // = DESCRIPTION + // Given some (unspecified) state, decides what the concurrency + // model should be. (For now, we always return the same model.) +{ +public: + JAWS_Dispatch_Policy (void); + virtual ~JAWS_Dispatch_Policy (void); + virtual JAWS_Concurrency_Base * update (void *state = 0) = 0; +}; + +class JAWS_Dispatcher + // = TITLE + // The class that is responsible to delivering events to the + // appropriate concurrency mechanism. + // + // = DESCRIPTION + // JAWS_IO_Handler calls into the dispatcher so that the completed + // IO can find a thread to take care of it. +{ +public: + JAWS_Dispatcher (JAWS_Dispatch_Policy *policy); + + int dispatch (JAWS_IO_Handler *ioh); + +private: + JAWS_Dispatch_Policy *policy_; +}; + +class JAWS_Thread_Pool_Task : public JAWS_Concurrency_Base + // = TITLE + // Used to implement Thread Pool Concurrency Strategy + // + // = DESCRIPTION + // This task is created to hold a pool of threads that receive + // requests through the message queue. +{ +public: + JAWS_Thread_Pool_Task (long flags = THR_NEW_LWP, + int nthreads = 5, + int maxthreads = 20); + +private: + int nthreads_; + int maxthreads_; +}; + +class JAWS_Thread_Per_Task : public JAWS_Concurrency_Base + // = TITLE + // Used to implement Thread Per Request Concurrency Strategy + // + // = DESCRIPTION + // As each new message arrives from the queue, a new thread is + // spawned to handle it. This is done by overloading put to call + // activate. +{ +public: + JAWS_Thread_Per_Task (long flags = THR_NEW_LWP, int maxthreads = 20); + + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0); + +private: + long flags_; + int maxthreads_; +}; + +#endif /* !defined (JAWS_CONCURRENCY_H) */ diff --git a/ACE/apps/JAWS/server/JAWS_Pipeline.cpp b/ACE/apps/JAWS/server/JAWS_Pipeline.cpp new file mode 100644 index 00000000000..f2ea3ecfbe9 --- /dev/null +++ b/ACE/apps/JAWS/server/JAWS_Pipeline.cpp @@ -0,0 +1,29 @@ +// $Id$ + +#include "JAWS_Pipeline.h" + +ACE_RCSID(server, JAWS_Pipeline, "$Id$") + +JAWS_Pipeline::JAWS_Pipeline (void) +{ +} + +int +JAWS_Pipeline::open (void *) +{ + // Simply call into the virtual svc() method. + if (this->svc () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "JAWS_Pipeline::svc"), + -1); + return 0; +} + +int +JAWS_Pipeline::close (u_long) +{ + return 0; +} + +#include "JAWS_Pipeline_Handler.cpp" diff --git a/ACE/apps/JAWS/server/JAWS_Pipeline.h b/ACE/apps/JAWS/server/JAWS_Pipeline.h new file mode 100644 index 00000000000..919c982977c --- /dev/null +++ b/ACE/apps/JAWS/server/JAWS_Pipeline.h @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +// $Id$ + +#ifndef JAWS_PIPELINE_H +#define JAWS_PIPELINE_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Service_Config.h" +#include "ace/Stream.h" +#include "ace/Module.h" +#include "ace/Task.h" + +typedef ACE_Stream<ACE_NULL_SYNCH> JAWS_Pipeline_Stream; +typedef ACE_Module<ACE_NULL_SYNCH> JAWS_Pipeline_Module; +typedef ACE_Task<ACE_NULL_SYNCH> JAWS_Pipeline_Task; + +class JAWS_Pipeline : public JAWS_Pipeline_Task + // = TITLE + // Methods that are common to pipeline components +{ +public: + JAWS_Pipeline (void); + // ACE_Task hooks + + virtual int open (void * = 0); + virtual int close (u_long = 0); +}; + +#include "JAWS_Pipeline_Handler.h" + +#endif /* !defined (JAWS_PIPELINE_H) */ diff --git a/ACE/apps/JAWS/server/JAWS_Pipeline_Handler.cpp b/ACE/apps/JAWS/server/JAWS_Pipeline_Handler.cpp new file mode 100644 index 00000000000..e67a99545bb --- /dev/null +++ b/ACE/apps/JAWS/server/JAWS_Pipeline_Handler.cpp @@ -0,0 +1,25 @@ +// $Id$ + +#ifndef JAWS_PIPELINE_HANDLER_CPP +#define JAWS_PIPELINE_HANDLER_CPP + +#include "JAWS_Pipeline_Handler.h" + +ACE_RCSID(server, JAWS_Pipeline_Handler, "$Id$") + +template <class TYPE> +JAWS_Pipeline_Handler<TYPE>::JAWS_Pipeline_Handler (void) +{ +} + +template <class TYPE> int +JAWS_Pipeline_Handler<TYPE>::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + TYPE *data = dynamic_cast<TYPE *> (mb->data_block ()); + + int status = this->handle_input (data, tv); + + return (status != -1) ? this->put_next (mb, tv) : -1; +} + +#endif /* !defined (JAWS_PIPELINE_HANDLER_CPP) */ diff --git a/ACE/apps/JAWS/server/JAWS_Pipeline_Handler.h b/ACE/apps/JAWS/server/JAWS_Pipeline_Handler.h new file mode 100644 index 00000000000..7e9becb6f5e --- /dev/null +++ b/ACE/apps/JAWS/server/JAWS_Pipeline_Handler.h @@ -0,0 +1,29 @@ +/* -*- c++ -*- */ +// $Id$ + +#ifndef JAWS_PIPELINE_HANDLER_H +#define JAWS_PIPELINE_HANDLER_H + +#include "JAWS_Pipeline.h" + +template <class TYPE> +class JAWS_Pipeline_Handler : public JAWS_Pipeline_Task + // = TITLE + // Methods that are common to pipeline components +{ +public: + JAWS_Pipeline_Handler (void); + // ACE_Task hooks + + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0); + // inherited from ACE_Task + + virtual int handle_put (TYPE *data, ACE_Time_Value *tv) = 0; + // Callback hook for specialized data processing +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "JAWS_Pipeline_Handler.cpp" +#endif + +#endif /* !defined (JAWS_PIPELINE_HANDLER_H) */ diff --git a/ACE/apps/JAWS/server/Makefile.am b/ACE/apps/JAWS/server/Makefile.am new file mode 100644 index 00000000000..206dce1d281 --- /dev/null +++ b/ACE/apps/JAWS/server/Makefile.am @@ -0,0 +1,96 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.JAWS.am + +if BUILD_ACE_FILECACHE +if !BUILD_ACE_FOR_TAO +if !BUILD_USES_WCHAR + +noinst_LTLIBRARIES = libJAWS.la + +libJAWS_la_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DACE_BUILD_SVC_DLL + +libJAWS_la_SOURCES = \ + HTTP_Config.cpp \ + HTTP_Handler.cpp \ + HTTP_Helpers.cpp \ + HTTP_Request.cpp \ + HTTP_Response.cpp \ + HTTP_Server.cpp \ + IO.cpp \ + JAWS_Concurrency.cpp \ + JAWS_Pipeline.cpp \ + Parse_Headers.cpp + +noinst_HEADERS = \ + HTTP_Config.h \ + HTTP_Handler.h \ + HTTP_Helpers.h \ + HTTP_Request.h \ + HTTP_Response.h \ + HTTP_Server.h \ + IO.h \ + JAWS_Concurrency.h \ + JAWS_Pipeline.h \ + Parse_Headers.h + +endif !BUILD_USES_WCHAR +endif !BUILD_ACE_FOR_TAO +endif BUILD_ACE_FILECACHE + +## Makefile.JAWS_server.am + +if BUILD_ACE_FILECACHE +if !BUILD_ACE_FOR_TAO +if !BUILD_USES_WCHAR + +noinst_PROGRAMS = main + +main_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +main_SOURCES = \ + main.cpp \ + HTTP_Config.h \ + HTTP_Handler.h \ + HTTP_Helpers.h \ + HTTP_Request.h \ + HTTP_Response.h \ + HTTP_Server.h \ + IO.h \ + JAWS_Concurrency.h \ + JAWS_Pipeline.h \ + JAWS_Pipeline_Handler.h \ + Parse_Headers.h + +main_LDADD = \ + libJAWS.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_USES_WCHAR +endif !BUILD_ACE_FOR_TAO +endif BUILD_ACE_FILECACHE + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/apps/JAWS/server/Parse_Headers.cpp b/ACE/apps/JAWS/server/Parse_Headers.cpp new file mode 100644 index 00000000000..12807305d1f --- /dev/null +++ b/ACE/apps/JAWS/server/Parse_Headers.cpp @@ -0,0 +1,362 @@ +// $Id$ + +#include "ace/Log_Msg.h" + +#include "Parse_Headers.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_strings.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_ctype.h" + +ACE_RCSID(server, Parse_Headers, "$Id$") + +// Implementation of class Headers + +Headers::Headers (void) : done_(0) +{ +} + +Headers::~Headers (void) +{ +} + +void +Headers::recognize (const char * const header) +{ + (void)this->map_[header]; +} + +void +Headers::parse_header_line (char * const header_line) +{ + char *ptr = header_line; + char *buf = header_line; + int offset = 1; + + ptr = ACE_OS::strchr (header_line, '\n'); + + if (ptr > header_line && ptr[-1] == '\r') + { + ptr--; + offset++; + } + + if (ptr == header_line) + { + this->done_ = 1; + return; + } + + *ptr = '\0'; + ptr += offset; + + char *value = 0; + char *header = ACE_OS::strtok_r (buf, ":", &value); + + ACE_DEBUG((LM_DEBUG, " (%t) Headers::parse_header_line [%s]\n", + header ? header : "<empty>")); + + if (header != 0 && this->map_.mapped (header)) + { + while (ACE_OS::ace_isspace (*value)) + value++; + + this->map_[header] = value; + + ACE_DEBUG((LM_DEBUG, " (%t) Headers::parse_header_line <%s>\n", + value ? value : "<empty>")); + } + + // Write back the unused portion of the input. + ACE_OS::memmove (header_line, ptr, ACE_OS::strlen(ptr) + 1); +} + +int +Headers::complete_header_line (char *const header_line) +{ + // Algorithm -- + // Scan for end of line marker. + // If the next character is linear white space, then unfold the header. + // Else, if the next character is printable, we have a complete header line. + // Else, presumably the next character is '\0', so the header is incomplete. + + // return -1 if end of line but not complete header line + // return 0 if no end of line marker + // return 1 if complete header line + + char *ptr = header_line; + int offset; + + if (!this->end_of_line (ptr, offset)) + return 0; + + if (ptr == header_line) + { + ACE_OS::memmove (ptr, ptr+offset, ACE_OS::strlen (ptr + offset) + 1); + this->done_ = 1; + ACE_DEBUG ((LM_DEBUG, " (%t) no more headers\n")); + return 0; + } + + do + { + switch (ptr[offset]) + { + case ' ': + case '\t': + ACE_OS::memmove (ptr, ptr+offset, ACE_OS::strlen (ptr + offset) + 1); + break; + + case '\n': + case '\r': + return 1; + + default: + if (ACE_OS::ace_isalpha (ptr[offset])) + return 1; + else + return -1; + } + } + while (this->end_of_line (ptr, offset) != 0); + + return 0; +} + +int +Headers::end_of_headers (void) const +{ + return this->done_; +} + +Headers_Map_Item & +Headers::operator[] (const char * const header) +{ + return this->map_[header]; +} + +const Headers_Map_Item & +Headers::operator[] (const char * const header) const +{ + return this->map_[header]; +} + +int +Headers::end_of_line (char *&line, int &offset) const +{ + char *old_line = line; + char *ptr = ACE_OS::strchr (old_line, '\n'); + + if (ptr == 0) + return 0; + + line = ptr; + offset = 1; + + if (line > old_line + && line[-1] == '\r') + { + line--; + offset = 2; + } + + return 1; +} + + +// Implementation of class Headers_Map + +Headers_Map::Headers_Map (void) + : num_headers_(0) +{ +} + +Headers_Map::~Headers_Map (void) +{ +} + +Headers_Map_Item::Headers_Map_Item (void) + : header_(0), + value_(0) +{ +} + +Headers_Map_Item::~Headers_Map_Item (void) +{ + ACE_OS::free ((void *) this->header_); + ACE_OS::free ((void *) this->value_); + this->header_ = this->value_ = 0; +} + +// Headers_Map_Item::operator const char * (void) const +// { +// return this->value_ == 0 ? this->no_value_ : this->value_; +// } + +Headers_Map_Item & +Headers_Map_Item::operator= (char * value) +{ + ACE_OS::free ((void *) this->value_); + this->value_ = ACE_OS::strdup (value); + return *this; +} + +Headers_Map_Item & +Headers_Map_Item::operator= (const char * value) +{ + ACE_OS::free ((void *) this->value_); + this->value_ = ACE_OS::strdup (value); + return *this; +} + +Headers_Map_Item & +Headers_Map_Item::operator= (const Headers_Map_Item & mi) +{ + ACE_OS::free ((void *) this->value_); + ACE_OS::free ((void *) this->header_); + this->header_ = ACE_OS::strdup (mi.header_); + this->value_ = (mi.value_ ? ACE_OS::strdup (mi.value_) : 0); + return *this; +} + +const char * +Headers_Map_Item::header (void) const +{ + return this->header_; +} + +const char * +Headers_Map_Item::value (void) const +{ + return this->value_; +} + +Headers_Map_Item & +Headers_Map::operator[] (const char * const header) +{ + Headers_Map_Item *item_ptr; + + item_ptr = this->find (header); + + if (item_ptr == 0) + item_ptr = this->place (header); + + return *item_ptr; +} + +const Headers_Map_Item & +Headers_Map::operator[] (const char * const header) const +{ + Headers_Map_Item *item_ptr; + Headers_Map *mutable_this = (Headers_Map *)this; + + item_ptr = this->find (header); + + if (item_ptr == 0) + item_ptr = mutable_this->place (header); + + return *item_ptr; +} + +int +Headers_Map::mapped (const char * const header) const +{ + int result = this->find (header) != 0; + + return result; +} + +Headers_Map_Item * +Headers_Map::find (const char * const header) const +{ + Headers_Map *const mutable_this = (Headers_Map *) this; + + mutable_this->garbage_.header_ = header; +#if 0 + Headers_Map_Item *mi_ptr = (Headers_Map_Item *) + ACE_OS::bsearch (&this->garbage_, + this->map_, + this->num_headers_, + sizeof (Headers_Map_Item), + Headers_Map::compare); +#else + int i = 0; + int j = this->num_headers_; + + while (i < j-1) + { + int k = (i+j)/2; + if (Headers_Map::compare (&this->garbage_, this->map_+k) < 0) + j = k; + else + i = k; + } + + Headers_Map_Item *mi_ptr = mutable_this->map_ + i; + if (Headers_Map::compare (&this->garbage_, mi_ptr) != 0) + mi_ptr = 0; +#endif + + mutable_this->garbage_.header_ = 0; + + return mi_ptr; +} + +Headers_Map_Item * +Headers_Map::place (const char *const header) +{ + this->garbage_.header_ = ACE_OS::strdup (header); + + int i = this->num_headers_++; + ACE_OS::free ((void *) this->map_[i].header_); + ACE_OS::free ((void *) this->map_[i].value_); + this->map_[i].header_ = 0; + this->map_[i].value_ = 0; + Headers_Map_Item temp_item; + + while (i > 0) + { + if (Headers_Map::compare (&this->garbage_, + &this->map_[i - 1]) > 0) + break; + + this->map_[i].header_ = this->map_[i - 1].header_; + this->map_[i].value_ = this->map_[i - 1].value_; + this->map_[i - 1].header_ = 0; + this->map_[i - 1].value_ = 0; + + i--; + } + + this->map_[i].header_ = this->garbage_.header_; + this->map_[i].value_ = this->garbage_.value_; + + this->garbage_.header_ = 0; + + return &this->map_[i]; +} + +int +Headers_Map::compare (const void *item1, + const void *item2) +{ + Headers_Map_Item *a, *b; + int result; + + a = (Headers_Map_Item *) item1; + b = (Headers_Map_Item *) item2; + + if (a->header_ == 0 || b->header_ == 0) + { + if (a->header_ == 0 && b->header_ == 0) + result = 0; + else if (a->header_ == 0) + result = 1; + else + result = -1; + } + else + result = ACE_OS::strcasecmp (a->header_, b->header_); + + return (result < 0) ? -1 : (result > 0); +} diff --git a/ACE/apps/JAWS/server/Parse_Headers.h b/ACE/apps/JAWS/server/Parse_Headers.h new file mode 100644 index 00000000000..8ba46a6b5ea --- /dev/null +++ b/ACE/apps/JAWS/server/Parse_Headers.h @@ -0,0 +1,124 @@ +/* -*- c++ -*- */ + +//============================================================================= +/** + * @file Parse_Headers.h + * + * $Id$ + * + * @author James Hu + */ +//============================================================================= + + +#ifndef PARSE_HEADERS_H +#define PARSE_HEADERS_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Headers_Map_Item +{ +friend class Headers_Map; +friend class Headers; + +private: + Headers_Map_Item (void); + ~Headers_Map_Item (void); + + // operator const char * (void) const; + Headers_Map_Item &operator= (char *); + Headers_Map_Item &operator= (const char *); + Headers_Map_Item &operator= (const Headers_Map_Item &); + +public: + const char *header (void) const; + const char *value (void) const; + +private: + const char *header_; + const char *value_; +}; + +/** + * @class Headers_Map + * + * @brief Map textual headings to header values (e.g. "Subject:" maps to + * "Re: My left foot" + */ +class Headers_Map +{ +public: + Headers_Map (void); + ~Headers_Map (void); + + Headers_Map_Item &operator[] (const char *const header); + const Headers_Map_Item &operator[] (const char *const header) const; + + enum + { + MAX_HEADERS = 100 + }; + + int mapped (const char *const header) const; + +private: + Headers_Map_Item *find (const char *const header) const; + Headers_Map_Item *place (const char *const header); + static int compare (const void *item1, const void *item2); + +private: + Headers_Map_Item map_[MAX_HEADERS]; + Headers_Map_Item garbage_; + + int num_headers_; +}; + +/** + * @class Headers + * + * @brief A general mechanism to parse headers of Internet text headers. + * + * Allow interesting headers to be inserted and later associated + * with values. This implementation assumes the parsing of headers + * will be done from ACE_Message_Blocks. + */ +class Headers +{ +public: + Headers (void); + ~Headers (void); + + void recognize (const char *const header); + + void parse_header_line (char *const header_line); + + /** + * -1 -> end of line but not complete header line + * 0 -> no end of line marker + * 1 -> complete header line + */ + int complete_header_line (char *const header_line); + + int end_of_headers (void) const; + + enum + { + MAX_HEADER_LINE_LENGTH = 8192 + }; + + Headers_Map_Item &operator[] (const char *const header); + const Headers_Map_Item &operator[] (const char *const header) const; + +private: + int end_of_line (char *&line, int &offset) const; + +private: + Headers_Map map_; + int done_; +}; + +#endif /* PARSE_HEADERS_H */ diff --git a/ACE/apps/JAWS/server/README b/ACE/apps/JAWS/server/README new file mode 100644 index 00000000000..27f0a0e3a8d --- /dev/null +++ b/ACE/apps/JAWS/server/README @@ -0,0 +1,228 @@ +# -*- text -*- +# Hey, Emacs! This is a TEXT file. + +-------------------------- +README for the JAWS server +-------------------------- + +This is the README file for the JAWS server. + +CONTENTS + +1. Compiling + a. UNIX + b. Windows NT 4.0 + +2. Executing + a. svc.conf parameters + b. General Info + +3. Limitations + +4. Acknowledgements + +5. New additions + +------------ +1. Compiling +------------ + +1a. Compiling under UNIX. + + Assuming that the environment variable ACE_ROOT is set +correctly, and that you are using GNU make, compiling should simply +involve: + + $ cd $ACE_ROOT/apps/JAWS/server + $ make clean + $ make depend + $ make + +This will produce an executable named ``main''. + +1b. Compiling under Windows NT 4.0. + + Assuming you are using a recent version of Microsoft +Visual C++, you can use the jaws.mdp file located in +$ACE_ROOT/apps/JAWS/server to build JAWS. + + +------------ +2. Executing +------------ + +2a. svc.conf parameters. + + To run JAWS, simply execute "main". It loads the HTTP server +from the file named in the ``svc.conf'' file. The ``svc.conf'' file +itself contains documentation about the load line. It supports the +following command-line arguments: + + -p port Start JAWS on the specified port. + -n num_threads Use num_threads as the maximum number of threads. + -f thr_flag Can be used multiple times to set thread + creation flags: + THR_BOUND -> bound threads + THR_DAEMON -> daemonized threads + THR_DETACHED -> detached threads + THR_NEW_LWP -> increase concurrency level + -t thr_strategy Use one of the following strategies: + POOL -> thread pool + PER_REQUEST -> thread-per-request + THROTTLE -> thread-per-request with throttling + -i io_strategy Use one of the following strategies: + SYNCH -> synchronous I/O + ASYNCH -> asynchronous I/O + -b backlog Backlog value for listen (). + +2b. General Information + + By default, JAWS will used port 5432 with 5 threads and apply +the synchronous thread pool strategy. Unless set, the default backlog +value is equal the value of the maximum number of threads. + + JAWS also responds to several environment variables. This is +a temporary feature which will be replaced by a more general +configuration file similar to NCSA httpd's. The environment variables +are: + JAWS_DOCUMENT_ROOT + This is the starting point the server will use to look + for files. + Default value: the current directory of the server. + + JAWS_CGI_PATH + This is intended to be a ``:'' delimited list of paths + (similar to your regular PATH environment variable) which + describes the possible locations for CGI binaries. + Default value: Any directory named ``cgi-bin''. + + JAWS_USER_DIR + This is the name of the subdirectory in a users home + directory which contains publicly available WWW documents. + Default value: ``.www''. + + JAWS_DIR_INDEX + The name of the file which is sent, if present, when the URL + leads to a directory. + Default value: ``index.html''. + + You may test the server by executing telnet, opening a +connection to the server machine on the server port. For instance: + + $ telnet machinename 5432 + Trying ###.###.###.###... + Connected to machinename.your.domain + Escape character is '^]'. + GET /main.cpp + // main.cpp + //... + + Note that if you use an HTTP/1.0 get request, then you have +to hit return twice before the file will be sent. E.g., + + $ telnet machinename 5432 + Trying ###.###.###.###... + Connected to machinename.your.domain + Escape character is '^]'. + GET /main.cpp HTTP/1.0 + + // main.cpp + //... + + Where applicable, JAWS will perform ``~'' expansion for home +directories of usernames. + + +----------- +3. Features +----------- + +(a) JAWS supports full HTTP/1.0 responses. + +(b) JAWS support CGI scripts on UNIX. + +(c) JAWS parses request headers. The mechanism can be used to parse + headers from a variety of text based protocols (e.g., SNMP and + NNTP). + +(d) Optimized filecaching. + +-------------- +4. Limitations +-------------- + +The following are TODO items for JAWS: + +status|task +------+----------------------- + | (a) JAWS will support HTTP/1.1 eventually, including + | persistent connections. + | + | (b) JAWS can be more aggressive with its threading strategies, + | such as: + | (*) parallelize HTTP protocol processing, similar to + | PHTTPD. + | (*) prioritize threads to give more important requests + | more execution time. + | (*) apply throttling, similar to THTTPD. + | + | (c) JAWS will support a general protocol content filtering + | mechanism which will be used to replace the existing CGI + | support implementation. + | + +Questions, comments, corrections, suggestions are welcome. Please +feel free to send me any such correspondence. + +James Hu <jxh@cs.wustl.edu> + +------------------- +4. Acknowledgements +------------------- + + My partners in crime for this endeavor include: + + Eastman-Kodak, Rochester N.Y. + and Object Technologies, Inc. For providing funding for this + research. + + Dr. Douglas Schmidt For being my advisor, and + convincing my sponsors to fund + me. + + Irfan Pyarali For porting JAWS to NT, and + for designing and implementing + the JAWS IO mechanism. + + Sumedh Mungee For writing the benchmark + client, and performing the + UNIX benchmarks. + + Tim Harrison For his comments, advice, and + help in designing the IO + mechanism used by JAWS. + +----------------------- +5. Additions +----------------------- + +The need arose to have JAWS not perform any file caching. We added this +functionality and provided a new cmd line option -c with params NO_CACHE/CACHE. + +This capability is to be used with the RepositoryManager in CIAO. + +In its current design the RepositoryManager (RM) need a collocated HTTP server. +When RM istalls packages, it unpacks them so that the separate files are accessible to +ZIP unaware entities like JAWS. JAWS is used to serve the libraries in the package to the +various deamons that might be interested in them, e.g. the NodeApplicationManager. + +The problem with using file caching reveals itself during the deletePackage operation of +the RM. When the RM attempts to delete a file which was previously accessed via JAWS a +is currently in the file cache the call fails and the file remains on the filesystem +indefinitely. If the file is cached with a ACE_NOMAP option is is not stored in a file +map and it is deleted upon server termination. The OS handles that. Althoguh this might +or might not be OK (depending on how it scales) there is an additional problem because +JAWS and the ACE_Filecache_Handle class used do not provide enough functionality to deal +with the ACE_NOMAP case. I believe that ACE_NOMAP option was probably never used. + +To overcome the above problems we added the no caching functionality in JAWS. diff --git a/ACE/apps/JAWS/server/jaws.auth b/ACE/apps/JAWS/server/jaws.auth new file mode 100644 index 00000000000..e3c51f7eac8 --- /dev/null +++ b/ACE/apps/JAWS/server/jaws.auth @@ -0,0 +1,2 @@ +jxh:nonsense +bill:no nonsense diff --git a/ACE/apps/JAWS/server/main.cpp b/ACE/apps/JAWS/server/main.cpp new file mode 100644 index 00000000000..dc9d8291549 --- /dev/null +++ b/ACE/apps/JAWS/server/main.cpp @@ -0,0 +1,57 @@ +// $Id$ + +#include "ace/Service_Config.h" +#include "ace/Reactor.h" +#include "ace/Filecache.h" + +#include "HTTP_Server.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_signal.h" + +ACE_RCSID(server, main, "$Id$") + +ACE_STATIC_SVC_REQUIRE(HTTP_Server) + +#ifdef ACE_HAS_SIG_C_FUNC +extern "C" +{ +#endif /* ACE_HAS_SIG_C_FUNC */ + + // call exit() so that static destructors get called +static void +handler (int) +{ + delete (ACE_Filecache *) ACE_Filecache::instance (); + ACE_OS::exit (0); +} + +#ifdef ACE_HAS_SIG_C_FUNC +} +#endif /* ACE_HAS_SIG_C_FUNC */ + +// This is the driver entry point into JAWS. It is possible to use +// JAWS as an ACE Service, as well. + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_Service_Config daemon; + + ACE_OS::signal (SIGCHLD, SIG_IGN); + + // SigAction not needed since the handler will shutdown the server. + ACE_OS::signal (SIGINT, (ACE_SignalHandler) handler); + ACE_OS::signal (SIGUSR2, (ACE_SignalHandler) handler); + + if (daemon.open (argc, argv, ACE_DEFAULT_LOGGER_KEY, 0) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + // The configured service creates threads, and the + // server won't exit until the threads die. + + // Run forever, performing the configured services until we receive + // a SIGINT. + + + return 0; +} diff --git a/ACE/apps/JAWS/server/server.mpc b/ACE/apps/JAWS/server/server.mpc new file mode 100644 index 00000000000..19e880d3530 --- /dev/null +++ b/ACE/apps/JAWS/server/server.mpc @@ -0,0 +1,36 @@ +// -*- MPC -*- +// $Id$ + +project(JAWS) : ace_output, acelib { + sharedname = JAWS + dynamicflags = ACE_BUILD_SVC_DLL + requires += ace_filecache + avoids += uses_wchar + avoids += ace_for_tao + + Source_Files { + HTTP_Server.cpp + HTTP_Config.cpp + HTTP_Handler.cpp + HTTP_Helpers.cpp + JAWS_Pipeline.cpp + JAWS_Concurrency.cpp + HTTP_Request.cpp + HTTP_Response.cpp + Parse_Headers.cpp + IO.cpp + } +} + +project(JAWS_server) : aceexe { + exename = main + after += JAWS + libs += JAWS + requires += ace_filecache + avoids += uses_wchar + avoids += ace_for_tao + + Source_Files { + main.cpp + } +} diff --git a/ACE/apps/JAWS/server/svc.conf b/ACE/apps/JAWS/server/svc.conf new file mode 100644 index 00000000000..fdba6ab9c76 --- /dev/null +++ b/ACE/apps/JAWS/server/svc.conf @@ -0,0 +1,49 @@ +# +# -p port number +# -n threads in the server +# -f thread activation flags +# = THR_BOUND +# = THR_DAEMON +# = THR_DETACHED +# = THR_NEW_LWP +# -t threading strategy +# = POOL -> thread pool +# = PER_REQUEST -> thread per request +# = THROTTLE -> thread per request with throttling +# -i I/O strategy +# = SYNCH +# = ASYNCH +# -b backlog value for listen () +# -c caching: NO_CACHE or CACHE +# +# +# Thread Pool, 20 unbound threads +# This is the baseline +static HTTP_Server "HTTP_Server -p 5432 -n 20 -i SYNCH -t POOL -b 50 -f THR_NEW_LWP" +# +# +# Start a baseline server without caching +#static HTTP_Server "HTTP_Server -p 5432 -n 20 -i SYNCH -t POOL -b 50 -f THR_NEW_LWP -c NO_CACHE" +# +# +# Thread Pool, 40 threads +#static HTTP_Server "HTTP_Server -p 5432 -n 40 -i SYNCH -t POOL -b 50 -f THR_NEW_LWP -f THR_BOUND" +# +# +# Thread-per-request, unlimited number of threads +#static HTTP_Server "HTTP_Server -p 5432 -i SYNCH -t PER_REQUEST -b 50 -f THR_NEW_LWP" +# +# +# Throttling, 40 threads +#static HTTP_Server "HTTP_Server -p 5432 -n 40 -i SYNCH -t THROTTLE -b 50 -f THR_NEW_LWP" +# + +# +# Example for using HTTP_Server as a dynamic service +# +# For NT. +#dynamic HTTP_Server Service_Object * ./jaws.exe:_make_HTTP_Server() "HTTP_Server -p 5432 -n 20 -i SYNCH -t POOL -b 50 -f THR_NEW_LWP" + +# +# For UNIX platforms. +#dynamic HTTP_Server Service_Object * ./main:_make_HTTP_Server() "HTTP_Server -p 5432 -n 20 -i SYNCH -t POOL -b 50 -f THR_NEW_LWP" diff --git a/ACE/apps/JAWS/server/test.cgi b/ACE/apps/JAWS/server/test.cgi new file mode 100755 index 00000000000..936afcf0d3c --- /dev/null +++ b/ACE/apps/JAWS/server/test.cgi @@ -0,0 +1,9 @@ +#!/bin/sh + +echo Content-type: text/plain +echo + +echo args -- $* +env +echo Done! +exit 0 diff --git a/ACE/apps/JAWS/stress_testing/README b/ACE/apps/JAWS/stress_testing/README new file mode 100644 index 00000000000..0969522d638 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/README @@ -0,0 +1,54 @@ +http_tester +----------- + +This is the http_tester suite, an ACE based HTTP benchmarking tool, +used to evaluate the performance of JAWS and other HTTP servers. + +Usage +----- + +To use the http_tester, you need to use a config file "infile", which +consists of a list of experiments, one on each line. http_tester logs +output data in the "outfile". + +Usage: http_tester infile outfile + +Experiments +----------- + +Each experiment consists of several space-delimited compulsory +fields, as follows: + +experiment_id (string) +total_number_of_requests (integer) +request_rate (float) +url1 (first URL) +p1 (probability of requesting the first URL) +url2 (second URL) +p2 (probability of requesting the second URL) +url3 (third URL) +p3 (probability of requesting the third URL) +TCP_NODELAY (boolean, 1 == TCP_NODELAY is set) +SOCKET_RECV_BUFSIZ (usually 65536) + +URLS must be of the form: + +http://www.cs.wustl.edu:8888/~sumedh/index.html + +(the port number is required, im making it optional in the next version). + +Please see the sample file "config", for an example. + +Output file +----------- + +The output file consists of the following space delimited fields: + +Experiment Id (string) +Average throughput of connection (float) +Average latency of connection (float) +Maximum number of active connections at any given time (int) + + +Sumedh Mungee +<sumedh@cs.wustl.edu> diff --git a/ACE/apps/JAWS/stress_testing/benchd.cpp b/ACE/apps/JAWS/stress_testing/benchd.cpp new file mode 100644 index 00000000000..f2cf497f2e6 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/benchd.cpp @@ -0,0 +1,241 @@ +// $Id$ + +// benchd: Adapted from the "ntalker" example. +// Sumedh Mungee + +#include "ace/Process.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram_Mcast.h" +#include "ace/Reactor.h" +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(stress_testing, benchd, "$Id$") + +#if defined (ACE_HAS_IP_MULTICAST) +// network interface to subscribe to +// this is hardware specific. +// use netstat (1M) to find whether your interface +// is le0 or ie0 + +// Maximum number of arguments supported for a request +static const int MAX_ARGS = 16; +// Name of the client benchmarking tool +static const char *TESTER = "http_tester"; +static int QUIET = 0; +static const char *INTERFACE = "le0"; +static const char *MCAST_ADDR = ACE_DEFAULT_MULTICAST_ADDR; +static const u_short UDP_PORT = ACE_DEFAULT_MULTICAST_PORT; +static const char *OUTPUT_FILE_NAME = "benchd.log"; +static ACE_HANDLE OUTPUT_FILE; + +// Handle both multicast and stdin events. + +class Handle_Events : public ACE_Event_Handler +{ +public: + Handle_Events (u_short udp_port, + const char *ip_addr, + const char *interface, + ACE_Reactor &reactor); + ~Handle_Events (void); + + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + +private: + int serve (char *buf); + ACE_SOCK_Dgram_Mcast mcast_; + ACE_Handle_Set handle_set_; +}; + +int +Handle_Events::handle_input (ACE_HANDLE h) +{ + char buf[BUFSIZ]; + + if (h == 0) + { + int readresult = ACE_OS::read (h, buf, BUFSIZ); + if (readresult > 0) + { + if (this->mcast_.send (buf, readresult) != readresult) + { + ACE_OS::perror ("send error"); + return -1; + } + return 0; + } + else if (readresult == -1) + ACE_OS::perror ("can't read from STDIN"); + + return -1; + } + else + { + ACE_INET_Addr remote_addr; + + // receive message from multicast group + int retcode = this->mcast_.recv (buf, sizeof buf, remote_addr); + + if (retcode != -1) + { + /* + cout << "received datagram from host " << remote_addr.get_host_name () + << " on port " << remote_addr.get_port_number () + << " bytes = " << retcode << endl; + */ + serve (buf); + return 0; + } + + ACE_OS::perror ("Something amiss."); + return -1; + } +} + +int +Handle_Events::handle_close (ACE_HANDLE h, ACE_Reactor_Mask) +{ + if (h == 0) + ACE_DEBUG ((LM_DEBUG, "STDIN_Events handle removed from reactor.\n")); + else + ACE_DEBUG ((LM_DEBUG, "Mcast_Events handle removed from reactor.\n")); + return 0; +} + +Handle_Events::~Handle_Events (void) +{ + // ACE_OS::exit on error (bogus)... + + if (this->mcast_.unsubscribe () == -1) + ACE_OS::perror ("unsubscribe fails"), ACE_OS::exit (1); +} + +Handle_Events::Handle_Events (u_short udp_port, + const char *ip_addr, + const char *interface, + ACE_Reactor &reactor) +{ + // Create multicast address to listen on. + + ACE_INET_Addr sockmc_addr (udp_port, ip_addr); + + // subscribe to multicast group. + + if (this->mcast_.subscribe (sockmc_addr, 1, interface) == -1) + ACE_OS::perror ("can't subscribe to multicast group"), ACE_OS::exit (1); + + // Disable loopbacks. + // if (this->mcast_.set_option (IP_MULTICAST_LOOP, 0) == -1 ) + // ACE_OS::perror (" can't disable loopbacks " ), ACE_OS::exit (1); + + if (!QUIET) { + this->handle_set_.set_bit (0); + } + this->handle_set_.set_bit (this->mcast_.get_handle ()); + + // Register callbacks with the ACE_Reactor. + if (reactor.register_handler (this->handle_set_, + this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_OS::perror ("can't register events"), ACE_OS::exit (1); +} + + +// This method handles multicast requests.. +// These requests are of the following form: +// command (arguments) + + +// currently only one is supported (and indeed needed :-)) http_tester +// arguments + +int +Handle_Events::serve (char *buf) +{ + ACE_ARGV arguments (buf); + + if (ACE_OS::strcmp (arguments[0], TESTER) == 0) + { + ACE_Process_Options po; + ACE_Process p; + + po.set_handles (ACE_INVALID_HANDLE, OUTPUT_FILE, OUTPUT_FILE); + po.command_line (arguments.argv ()); + + p.spawn (po); + return 0; + } + else + return -1; +} + +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "i:u:q"); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'q': + QUIET = 1; + case 'i': + INTERFACE = get_opt.opt_arg (); + break; + case 'u': + // Usage fallthrough. + default: + ACE_DEBUG ((LM_DEBUG, "%s -i interface\n", argv[0])); + ACE_OS::exit (1); + } +} + +static sig_atomic_t done = 0; + +// Signal handler. + +extern "C" void +handler (int) +{ + done = 1; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); + ACE_OS::signal (SIGCLD, SIG_IGN); + ACE_UNUSED_ARG (sa); + + parse_args (argc, argv); + + OUTPUT_FILE = ACE_OS::open (OUTPUT_FILE_NAME, O_CREAT | O_WRONLY, 0644); + if (OUTPUT_FILE == 0) + return 1; + + ACE_Reactor reactor; + Handle_Events handle_events (UDP_PORT, MCAST_ADDR, INTERFACE, reactor); + + // main loop + + while (!done) + reactor.handle_events (); + + ACE_OS::close (OUTPUT_FILE); + cout << "\nbenchd done.\n"; + return 0; +} +#else +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_ERROR ((LM_ERROR, "error: %s must be run on a platform that support IP multicast\n", + argv[0])); + return 0; +} +#endif /* ACE_HAS_IP_MULTICAST */ diff --git a/ACE/apps/JAWS/stress_testing/client.h b/ACE/apps/JAWS/stress_testing/client.h new file mode 100644 index 00000000000..58ef98c7bdf --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/client.h @@ -0,0 +1,8 @@ +// $Id$ + +#include "global.h" +#include "util.h" +#include "http.h" +#include "cp.h" +#include "stats.h" + diff --git a/ACE/apps/JAWS/stress_testing/config b/ACE/apps/JAWS/stress_testing/config new file mode 100644 index 00000000000..7e730eaef10 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/config @@ -0,0 +1,3 @@ +1.0 1 1 http://localhost:5432/IO.h 1 a 0 b 0 1 65536 +2.0 1 1 http://localhost:5432/IO.h 1 a 0 b 0 1 65536 + diff --git a/ACE/apps/JAWS/stress_testing/connection.cpp b/ACE/apps/JAWS/stress_testing/connection.cpp new file mode 100644 index 00000000000..c81ae2fba53 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/connection.cpp @@ -0,0 +1,100 @@ +// $Id$ + +#include "connection.h" + +ACE_RCSID(stress_testing, connection, "$Id$") + +// Make the connection to the WEB server + +int connection::connect(char *hostname_opt_port, int tcp_nodelay, int sockbufsiz) { + if(!hostname_opt_port) return 1; + + char *hostname_with_port; + // Check to see if portnumber is specified in the hostnameport + // If not, append :80 + if(!ACE_OS::strchr(hostname_opt_port,':')) { + hostname_with_port = new char[ACE_OS::strlen(hostname_opt_port) + 3]; + ACE_OS::sprintf(hostname_with_port, "%s:%d", hostname_opt_port, 80); + } + else { + hostname_with_port = hostname_opt_port; + } + + // Beyond this point, hostname_with_port is of the form hostname:port + + ACE_INET_Addr server_addr(hostname_with_port); + + // Connect to server + + ACE_SOCK_Connector con; + + if(con.connect(stream_, server_addr) == -1) { + ACE_OS::perror("ACE_SOCK_Connector::connect"); + return 1; + } + + + // tcp_nodelay processing. + + // turn off weird ack things + if(tcp_nodelay) { + struct protoent *p = ACE_OS::getprotobyname ("tcp"); + int one = 1; + + if (p && stream_.set_option (p->p_proto, + TCP_NODELAY, + (char *)& one, + sizeof (one))) + { + ACE_OS::perror("tcp_nodelay"); + return 1; + } + } + + if(sockbufsiz) + if (stream_.set_option (SOL_SOCKET, + SO_RCVBUF, + (char *) &sockbufsiz, + sizeof sockbufsiz) == -1) + { + ACE_OS::perror("socket_queue_size"); + return 1; + } + + return 0; +} + +int connection::read(void *buffer, size_t maxlen, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + return stream_.recv(buffer, maxlen); +} + +int connection::write(const void *buffer, size_t maxlen, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + return stream_.send(buffer, maxlen); +} + +int connection::write_n(const void *buffer, size_t len, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + if(stream_.send_n(buffer, len) == -1) + ACE_ERROR_RETURN((LM_ERROR, "Write failed for %s", buffer),1); + return 0; +} + +int connection::read_n(void *buffer, size_t maxlen, unsigned int timeout_seconds) { + ACE_UNUSED_ARG (timeout_seconds); + if(stream_.recv_n(buffer, maxlen) == -1) + ACE_ERROR_RETURN((LM_ERROR, "Read failed.."),1); + return 1; +} + +int connection::close(void) { + stream_.close_reader(); + stream_.close_writer(); + stream_.close(); + return 0; +} + +connection::~connection(void) { + this->close(); +} diff --git a/ACE/apps/JAWS/stress_testing/connection.h b/ACE/apps/JAWS/stress_testing/connection.h new file mode 100644 index 00000000000..db37ff07f35 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/connection.h @@ -0,0 +1,22 @@ +// $Id$ + +#include "global.h" + +#ifndef _D_connection +#define _D_connection +class connection { + +public: + int connect(char *hostname_opt_port, int tcp_nodelay, int sockbufsiz); + int read(void *buffer, size_t maxlen, unsigned int timeout_seconds = 60); + int write(const void *buffer, size_t maxlen, unsigned int timeout_seconds = 60); + int write_n(const void *buffer, size_t len, unsigned int timeout_seconds = 60); + int read_n(void *buffer, size_t maxlen, unsigned int timeout_seconds = 60); + int close(void); + ~connection(void); + +private: + ACE_SOCK_Stream stream_; + char sockbuf[66000]; +}; +#endif diff --git a/ACE/apps/JAWS/stress_testing/cp.cpp b/ACE/apps/JAWS/stress_testing/cp.cpp new file mode 100644 index 00000000000..4829735aaa8 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/cp.cpp @@ -0,0 +1,11 @@ +// $Id$ + +#include "cp.h" + +ACE_RCSID(stress_testing, cp, "$Id$") + +Client_Parameters::Client_Parameters(int i) { + + id = i; + +} diff --git a/ACE/apps/JAWS/stress_testing/cp.h b/ACE/apps/JAWS/stress_testing/cp.h new file mode 100644 index 00000000000..ad2e5ddf31b --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/cp.h @@ -0,0 +1,14 @@ +// $Id$ + +#include "util.h" +#include "stats.h" + +class Client_Parameters { +public: + Client_Parameters(int); + URL *url; + static Stats *stats; + static int tcp_nodelay; + static int sockbufsiz; + int id; +}; diff --git a/ACE/apps/JAWS/stress_testing/global.h b/ACE/apps/JAWS/stress_testing/global.h new file mode 100644 index 00000000000..0d916f2cc41 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/global.h @@ -0,0 +1,31 @@ +// $Id$ + +#include "ace/ACE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Connector.h" +#include "ace/Pipe.h" +#include "ace/SOCK_Stream.h" +#include "ace/INET_Addr.h" +#include "ace/Profile_Timer.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" + +// FUZZ: disable check_for_math_include +#include <math.h> + + + + + + + + + + + diff --git a/ACE/apps/JAWS/stress_testing/http.h b/ACE/apps/JAWS/stress_testing/http.h new file mode 100644 index 00000000000..efce9235e56 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/http.h @@ -0,0 +1,16 @@ +// $Id$ + +#include "global.h" + +#define CONTENT_ENCODING_HEADER "Content-encoding: " +#define CONTENT_TYPE_HEADER "Content-type: " +#define INCOMING_FILE_NAME "/tmp/sumedh.web.inc" +#define TEMPORARY_FILE_NAME "/tmp/sumedh.web.tmp" + +#define ENCODING_TAB "./encoding.tab" +#define CONTENT_TAB "./content.tab" + +int demime(void); +int decode(char *encoding); +int view(char *content); + diff --git a/ACE/apps/JAWS/stress_testing/http_tester.cpp b/ACE/apps/JAWS/stress_testing/http_tester.cpp new file mode 100644 index 00000000000..199bfa33e19 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/http_tester.cpp @@ -0,0 +1,172 @@ +// $Id$ + +#include "client.h" + +ACE_RCSID(stress_testing, http_tester, "$Id$") + +int Client_Parameters::tcp_nodelay; +int Client_Parameters::sockbufsiz; +Stats *Client_Parameters::stats; + +static void * +client_thread(void *data) +{ + Client_Parameters *cp = (Client_Parameters *) data; + float latency = 0, throughput; + URL *u = cp->url; + + // Check for presence of protocol, hostname and filename. + + if(!(u->get_protocol() && u->get_hostname() && u->get_filename())) { + cerr << "Invalid URL" << endl; + return 0; + } + + cp->stats->i_have_started(cp->id); + + // Attempt connection + connection webserver; + + if(webserver.connect(u->get_hostname(), cp->tcp_nodelay, cp->sockbufsiz)) return 0; + // Send the request now. + + + char request[BUFSIZ]; + + ACE_Profile_Timer throughput_timer, latency_timer; + throughput_timer.start(); + latency_timer.start(); + ACE_OS::sprintf(request,"GET /%s HTTP/1.0\r\n\r\n",u->get_filename()); + webserver.write_n(request, ACE_OS::strlen(request)) ; + + char buffer[BUFSIZ]; + ssize_t num_read = 0, total_read = 0; + unsigned int first_time = 1; + for(;;) { + num_read = webserver.read(buffer, sizeof buffer); + if(first_time) { + ACE_Profile_Timer::ACE_Elapsed_Time et; + latency_timer.stop(); + latency_timer.elapsed_time(et); + latency = et.real_time; + first_time = 0; + } + if(num_read <= 0) + break; + total_read += num_read; + } + cp->stats->i_am_done(cp->id); + ACE_Profile_Timer::ACE_Elapsed_Time et; + throughput_timer.stop(); + throughput_timer.elapsed_time(et); + throughput = (8 * total_read/et.real_time) / (1000 * 1000); //pow(10,6) ; + cp->stats->log(cp->id, throughput, latency); + webserver.close(); + return 0; +} + +int driver(char *id, int total_num, float requests_sec, char *url1, float p1, char *url2, float p2, char *url3, float p3, int tcp_nodelay, int sockbufsiz) { + + // construct the client parameters packet + + Client_Parameters::tcp_nodelay = tcp_nodelay; + Client_Parameters::sockbufsiz = sockbufsiz; + + Client_Parameters::stats = new Stats(total_num); + + int missed_deadlines = 0; + // sleep_time is in microseconds, and requests_sec is per second, hence the pow(10,6) + float sleep_time = (1/requests_sec) * (1000.0 * 1000.0); // pow(10,6); + float delta = 0; + ACE_OS::srand(ACE_OS::time(0)); + for(int i = 0; i < total_num; i++) { // i is used as a id for threads + ACE_Profile_Timer timer; + if(sleep_time < delta) + { + // cerr << "Requested rate is too high, sleep_time == " << sleep_time << ", and delta = " << delta << ", after " << i << " iterations! " << endl; + missed_deadlines++; + } + else + { + ACE_Time_Value tv(0, (long int) (sleep_time - delta)); + ACE_OS::sleep(tv); + timer.start(); + } + Client_Parameters *cp = new Client_Parameters(i); + + double r = ((double)ACE_OS::rand()/(double)RAND_MAX); + // cerr << " choosing between " << url1 << url2 << url3 << " with r == " << r; + if(r <= p1) cp->url = new URL(url1); + if( (r > p1) && (r <= (p1 + p2))) cp->url = new URL(url2); + if( (r > (p1 + p2)) && (r <= p1 + p2 + p3)) cp->url = new URL(url3); + // cerr << "The URL being requested is " << cp->url->get_filename() << endl; + + + (ACE_Thread_Manager::instance ())->spawn(client_thread, (void *) cp); + timer.stop(); + ACE_Profile_Timer::ACE_Elapsed_Time et; + timer.elapsed_time(et); + delta = ( (0.4 * fabs(et.real_time * (1000 * 1000))) + (0.6 * delta) ); // pow(10,6) + } + + // Join the other threads.. + (ACE_Thread_Manager::instance ())->wait(); + // Now output the data for this test + cout << id; + Client_Parameters::stats->output(); + cout << endl; + if (missed_deadlines != 0) + { + cout << "missed deadlines " << missed_deadlines << endl; + cout << "missed deadlines as a % of total requests: " << (float) missed_deadlines / total_num * 100 << endl; + } + return 0; +} + + +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + // This will set the global scale factor if the ACE_SCALE_FACTOR + // environment variable is set. + ACE_High_Res_Timer::get_env_global_scale_factor (); + + if(argc < 3) { + cerr << "Usage: " << argv[0] << " infile outfile " << endl; + cerr << "The input file contains lines, with the following fields: " << endl; + cerr << "experiment_id total_number_of_requests request_rate url1 p1 url2 p2 url3 p3 TCP_NODELAY SOCKET_RECV_BUFSIZ " << endl; + + return 1; + } + + FILE *fp = ACE_OS::fopen(argv[1],"r"); + if(fp == 0) { + ACE_POS::perror("fopen"); + return 2; + } + ACE_OS::close(1); + int fd = ACE_OS::open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(fd == -1) { + ACE_OS::perror("open"); + return 3; + } + + + int total_num, tcp, sock; + char *id = new char[BUFSIZ]; + float rate, p1, p2, p3; + char *url1 = new char[BUFSIZ]; + char *url2 = new char[BUFSIZ]; + char *url3 = new char[BUFSIZ]; + + + while(!feof(fp)) { + fscanf(fp,"%s %d %f %s %f %s %f %s %f %d %d\n", id, &total_num, &rate, url1, &p1, url2, &p2, url3, &p3, &tcp, &sock); + if (id[0] == '#') continue; + ACE_OS::fprintf(stderr,"----\n"); + ACE_OS::fprintf(stderr,"\tNow performing experiment:%s\n\tSending %d requests at %f requests/second\n", id, total_num, rate); + driver(id, total_num, rate, url1, p1, url2, p2, url3, p3, tcp, sock); + } + ACE_OS::fclose(fp); + ACE_OS::close(fd); + return 0; +} diff --git a/ACE/apps/JAWS/stress_testing/out b/ACE/apps/JAWS/stress_testing/out new file mode 100644 index 00000000000..c237b7f38bc --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/out @@ -0,0 +1,2 @@ +1.0 0.47895 0.00859167 1 +2.0 0.562603 0.00185976 1 diff --git a/ACE/apps/JAWS/stress_testing/stats.cpp b/ACE/apps/JAWS/stress_testing/stats.cpp new file mode 100644 index 00000000000..8d7df2ccf5f --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/stats.cpp @@ -0,0 +1,88 @@ +// $Id$ + +#include "stats.h" + +ACE_RCSID(stress_testing, stats, "$Id$") + +Stats::Stats(int size) { + throughput_ = new float[size]; + latency_ = new float[size]; + thread_count_ = size; + init_fini_ = new Init_Fini_t[2*size]; + for(int i = 0; i < size; i++) + throughput_[i] = latency_[i] = 0; +} + +void Stats::log(int id, float throughput, float latency) { + throughput_[id] = throughput; + latency_[id] = latency; +} + +// Unused for now. +void Stats::print(char *message) { + + ACE_UNUSED_ARG (message); + + // char time_buf[64]; + // long ltime; + // time(<ime); + + // ACE_OS::ctime_r(<ime, time_buf, sizeof time_buf); + + // if(ACE_OS::gettimeofday() == -1) { + // perror("gettimeofday"); + // } + // time_buf[strlen(time_buf)-1] = 0; + // printf("%010ld%09ld \t %s %s\n", tp.tv_sec, tp.tv_usec, time_buf, message); +} + + +int comp(const void *a, const void *b) { + + Init_Fini_t *A = (Init_Fini_t *)a; + Init_Fini_t *B = (Init_Fini_t *)b; + + return (A->timestamp < B->timestamp) ? -1 : (A->timestamp > B->timestamp); +} + + +void Stats::output() { + int i; + float tavg = 0, lavg = 0; + + ACE_OS::qsort(init_fini_, 2*thread_count_, sizeof(Init_Fini_t), comp); + + int max = 0,thread_peak = 0; + + for(i = 0; i < 2*thread_count_; i++) { + // cerr << " " << ((init_fini_[i].type == THREAD_START) ? "START": "END") << " " << init_fini_[i].timestamp.sec() << "." << init_fini_[i].timestamp.usec() << endl; + if(init_fini_[i].type == THREAD_START) { + if(++thread_peak > max) + max = thread_peak; + } + else thread_peak--; + } + for(i = 0; i < thread_count_; i++) { + tavg += throughput_[i]; + lavg += latency_[i]; + } + cout << " " << tavg/thread_count_ << " " << lavg/thread_count_ << " " << max; +} + + +void Stats::i_have_started(int id) { + + init_fini_[2*id].type = THREAD_START; + init_fini_[2*id].timestamp = ACE_OS::gettimeofday(); + +} + +void Stats::i_am_done(int id) { + + init_fini_[(2*id)+1].type = THREAD_END; + + init_fini_[(2*id)+1].timestamp = ACE_OS::gettimeofday(); + +} + + diff --git a/ACE/apps/JAWS/stress_testing/stats.h b/ACE/apps/JAWS/stress_testing/stats.h new file mode 100644 index 00000000000..b5ef4a4f4a0 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/stats.h @@ -0,0 +1,31 @@ +// $Id$ + +#include "global.h" + +#ifndef _D_Stats +#define _D_Stats + +#define THREAD_START 42 +#define THREAD_END 43 + +class Init_Fini_t { +public: + int type; // 0 is start, 1 is end + ACE_Time_Value timestamp; +}; + +class Stats { +public: + Stats(int); + void log(int, float, float); + void i_have_started(int); + void i_am_done(int); + void print (char *); + void output(); +private: + float *throughput_; + float *latency_; + Init_Fini_t *init_fini_; // Array (2n deep) to count peak no. of active threads + int thread_count_; +}; +#endif diff --git a/ACE/apps/JAWS/stress_testing/util.cpp b/ACE/apps/JAWS/stress_testing/util.cpp new file mode 100644 index 00000000000..495ba7c59e0 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/util.cpp @@ -0,0 +1,60 @@ +// $Id$ + +#include "util.h" + +ACE_RCSID(stress_testing, util, "$Id$") + +URL::URL(char *input_buf) { + + char *buffer = new char[BUFSIZ]; + + ACE_OS::strcpy(buffer,input_buf); + if(buffer == 0) + return; + + char *temp; + char *lasts; + + if((temp = ACE_OS::strtok_r(buffer,": ",&lasts))) { + protocol_ = (char *) ACE_OS::malloc(ACE_OS::strlen(temp) + 1); + ACE_OS::strcpy(protocol_, temp); + } + + if((temp = ACE_OS::strtok_r(0,"/",&lasts))) { + hostname_ = (char *) ACE_OS::malloc(ACE_OS::strlen(temp) + 1); + ACE_OS::strcpy(hostname_, temp); + } + if((temp = ACE_OS::strtok_r(0,"\0",&lasts))) { + filename_ = (char *) ACE_OS::malloc(ACE_OS::strlen(temp) + 1); + ACE_OS::strcpy(filename_, temp); + } + else { + filename_ = (char *) ACE_OS::malloc(ACE_OS::strlen(INDEX_NAME) + 1); + ACE_OS::strcpy(filename_,INDEX_NAME); + } +} + +char *URL::get_protocol(void) { + return protocol_; +} + +char *URL::get_hostname(void) { + return hostname_; +} + +char *URL::get_filename(void) { + return filename_; +} + + + + + +void cleanup(void) { + ACE_OS::unlink(TEMPORARY_FILE_NAME); + ACE_OS::unlink(INCOMING_FILE_NAME); +} + +void sigint(int) { + cleanup(); +} diff --git a/ACE/apps/JAWS/stress_testing/util.h b/ACE/apps/JAWS/stress_testing/util.h new file mode 100644 index 00000000000..875a8cd80e0 --- /dev/null +++ b/ACE/apps/JAWS/stress_testing/util.h @@ -0,0 +1,34 @@ +// $Id$ + +#include "connection.h" + +#ifndef _D_URL +#define _D_URL +class URL { + +public: + + URL(char *buffer); + + char *get_protocol(); + char *get_hostname(); + char *get_filename(); + +private: + char *protocol_; + char *hostname_; + char *filename_; +}; + +void cleanup(void); +void sigint(int); +int copier(connection in); + +#define INDEX_NAME "/index.html" +#define INCOMING_FILE_NAME "/tmp/sumedh.web.inc" +#define TEMPORARY_FILE_NAME "/tmp/sumedh.web.tmp" +#endif + + + + |