boa-0.94.14rc21/0000755000175000001440000000000010207232236013746 5ustar jnelsonusers00000000000000boa-0.94.14rc21/CHANGES0000644000175000001440000010305410207231613014742 0ustar jnelsonusers00000000000000** Changes from 0.94.13 to 0.94.14 * SUBSTANTIALLY UPDATE AUTOCONF SYSTEM - all of the autoconf stuff is now located in the top level directory, and creates the appropriate Makefiles for building the system and documentation. * add [optional, Linux-only] check for sendfile system call * add new state, IOSHUFFLE, which utilizes sendfile (or emulates it using the request's buffer, otherwise) * make the default socket size 32K. The client_stream_size stays constant at 8K, and the new 'buffer' size is 4K Note also that the new code uses the "default" socket buffer size it obtains with the first accept()ed socket. * use setjmp, instead of sigsetjmp (we dont mess with the signal mask so why bother! it's one less syscall) * explicitly set pending_requests to 0 in select.c when sigterm_flag has been set, and also when the server socket is *not* set despite checking for it. * make default behavior be to leave stderr alone, but tie it to cgilog otherwise * add initial vhost_root support * remove support for normalize_path * use --disable-sendfile to disable sendfile support sendfile support for files > 100K is default, now. It's significantly faster and easier than the alternative * add "Host" header support to CGI environment * umask ~0770 before exec * backport hash.c from 0.95 and use fnv1a hash (see CREDITS) * don't set stderr close-on-exec * make some minor for very useful optimizations in the read/write loop for CGIs * make some adjustments for Solaris and other platforms * add yyerror function definition to boa_lexer.l * tie stdout to the access_log, unless there is no access_log, in which case tie it to /dev/null * use sensible defaults for umask (077) and (027 for CGI) * add and document new parameters (CGILog and CGIumask) * vast improvements to the cgi-test.cgi program, by Jon Nelson and Landon Curt Noll. * next 3 items by Don Mahurin (patches modified somewhat): * pidfile patch * default mime_types patch * NCSA environment environment variables wrapped in #ifdef USE_NCSA_CGI_ENV * fix some escaping issues with the directory indexer (Ulf Harnhammar) * poll or select available at compile time * as of 0.94.14rc2 through 0.94.14rc3: * remove support for lex/yacc (backported from 0.95) * add conditional support for http/1.1 * as of 0.94.14rc4: * replace many #defines with enumerations * update specfile (thanks to Supreet Sethi via SourceForge) * support optional config file name argument * tentatively support Ranges * as of 0.94.14rc5 through 0.94.14rc7: * dummy install target and some cleanups for *BSD * update index_dir.c to be *really* safe WRT html and http escaping* * Note to self - please make that code less ugly * basic access (Allow/Deny) control * fix check-for-broken-setuid check in boa.c -- root *is* a legal user * as of 0.94.14rc9: * fix reversed argument passing in add_mime_type * disable-gunzip support * capitalization changes, etc.. to configure.in * use slightly newer AC_DEFINE 3-argument style in configure.in * add new member of struct, bytes_written, and use it to more accurately report the number of bytes actually written to the socket. * When sendfile(2) reports ECONNRESET treat it like EPIPE, which is to say silently shut it down and don't be noisy about logging it. * wrap sa_family_t typedef in #ifdef DONT_HAVE_SA_FAMILY_T to deal with non-POSIX (1g) systems (Cygwin?) * add req->bytes_written member variable, and use it instead of filepos * apply Peter Korsgaard's "configure --help" patch * apply Peter Korsgaard's "configure --disable-gunzip" patch * use newer 3-argument AC_DEFINE * update config.sub and config.guess * clean up and update configure.in somewhat * don't close stderr in terminal signal handlers * free range pool and server_name in (final) sigterm handler * refactor select and poll loops * as of 0.94.14rc10: * change to using PF_ prefix instead of AF_ prefix (PF_ is POSIX?) * fix copying too-much-memory (read-side, write-side was OK) in ascii_sockaddr. Also optimize slightly (note, may actually be a wee slower due to strlen check -- is there a way around this?) * fix a few shadow variable problems and improve select and poll loops * check for and use madvise (may or may not help) * update depends (the cause of SIGSEGs when ./configure was re-run to switch from select to poll, *without* running make clean) * always remove select.o and poll.o (and access.o) because these are the usual conditional files. * if we aren't using IPv6, define BOA_NI_MAXHOST to 20. 1025 is far too huge for a single IPv4 IP address in dotted-quad notation. * move access_init to earlier in the config reading * allow a MAX_FILE_MMAP value of 0 to mean "always mmap" * as of 0.94.14rc11: * fix 'HEAD' requests (bug introduced in rc6) * as of 0.94.14rc12: * *huge* patch to try to eliminate shadow variables, use unsigned ints instead of signed ints, and "const" where appropriate. * check for and use __func__, a C99 construct that is used in the DIE and WARN macros to also describe the name of the current function. * fix a very minor IPv6 issue, and include netdb.h in compat.h so that NI_MAXHOST is defined for IPv6 * when we can't mmap a file, fall back to IOSHUFFLE. If we couldn't mmap the file due to an error in mmap or madvise, report the error, otherwise it is safe to assume we simply ran out of hash table space. This was reported by Davide Pagnin * The following 2 changes borrowed from Hydra (which is itself based on Boa): * Some optimizations in HTTP header parsing. * Added DefaultCharset configuration directive. If given, the default character set will be appended to the Content-Type for all 'text' mime types. * update boa.texi with some missing configuration directives * as of 0.94.14rc13: * force select.c, poll.c, and access.c to always be included in dependency stuff fix use of HAVE_FUNC * if FD_SETSIZE is undefined, set MAX_FD to OPEN_MAX instead of arbitarily setting it to 2048. * improve the poll code slightly * give Boa more breathing room WRT MaxConnections and total current connections -- currently simply set at 20. * forcibly clear the server_s from the block_read_fdset when it won't be checked. * as of 0.94.14rc14: * fix more spelling errors (LRD) and remove use of const int * better sa_family_t detection on *BSD (Peter Pentchev) * as of 0.94.14rc15: * fix a potential NULL-pointer dereference when generating CGI environment variables *and* we are extremely low on memory * when unable to set new sockets to non-block or close-on-exec, don't just warn, also close it down and place on the free list. * use log_error_doc in some places instead of log_error_time * clean up logline parsing. This fixes a potential sigseg! * fix use of ACCEPT_ON #define in process_option_line * as of 0.94.14rc16: * be more stringent about verifying that all of the proper variables got allocated in create_common_env * when unable to add an environment to the CGI space, note what the key and values are to the error log. * use log_error_doc instead of log_error_time in some places * make sure to _exit if strdup fails in create_argv * DO NOT accept control characters in the http header stream * DO NOT accept control characters in the decoded URI * warn when the hash function is sent an NULL or empty value * warn when find_alias is sent a uri_len of 0. * clean up and fix some of the path construction code paths * add log_error_doc in some places * when checking for a user home dir, if the full URI is "/~" then log it and send back a bad request response * mild clean up of req_write_escape_html * refactor code so all hash functions start with hash * check for and complain about empty or NULL keys and values in the various hash function * change the maximum number of environment variables to 100 from 50 * as of 0.94.14rc17: * #define QUIET_DISCONNECT to silence read and write errors to client * when range requests are determined to be invalid, use log_error_doc * make log messages when URI contains invalid characters or doesn't start with a '/' less scary * if creating a temporary file, or setting it to close-on-exec fails, send_r_error * if key or value for an http header is invalid, log it. * be more strict with range parsing * handle 0-byte sendfile attempt better * as of 0.94.14rc18: * add log_error_mesg_fatal, which does log_error_mesg and then exits * fix malloc thinko in buffer code * use ULONG_MAX instead of -1 to describe unbounded ranges * log '-' instead of req->logline if req->logline is undefined * remove some superflous send_r_error statements. * fix a logic inversion regarding QUIET_DISCONNECT * move rate limit code very slightly, and force http version of 1.0 * move req->ka_count decrement out of sanitize_request * /always/ issue log_access in free_request * use BOA_FD_CLR to clear file descriptors out of the FD_SETs that they might be in. * disable keepalive when response status is 0 or >= 500 * update a comment regarding the 100 Continue response * use BOA_READ and BOA_WRITE macros in select.c * backport (but leave it commented out) USE_SETRLIMIT stuff for cgi's This (currently disabled) functionality enables the use of CGIRlimit{CPU,Data,Nice} configuration values for CGI execution. * backported DEBUG debugging and logging code allows run-time enabling of finer-grained debugging. Disable with --disable-verbose (worth about 4K of binary size) * split out usage and parsing commandline tasks into their own functions (usage and parse_commandline) * in poll.c, don't just check for BOA_READ, but handle all "error" conditions first, then check for /any/ revent. * force response code to 400 when client closes connection before request is fully read. * use code 408 to indicate timed-out response * use isalnum instead of isalpha to verify hostname as per Alan's suggestion * fix 2 copy-and-paste error messages in mmap_cache.c (error message was wrong) * add and use TIMED_OUT state for requests that time out. * reset signals (in child process) after forking for CGI * fix multipart range responses * as of 0.94.14rc19: * change many instances of log_error_mesg + send_r_error to boa_perror * set timezone right away at program startup * add new_clean_pathname from now-defunct 0.95 branch (unused via #if 0) * change common_cgi_env to be dynamically sized, using realloc. * add new keyword, CGIEnv, which takes 2 parameters and adds them as the key and value of another common environment variable for CGI. This item requires the previous change. * split modified_since into 2 routines: date_to_tm, which parses various date formats into a 'struct tm', and modified_since, which then just compares the struct tm to the items from a statbuf. * remove fake status codes R_413 and R_415, and manually set R_REQUEST_URI_TOO_LONG to 414 and R_INVALID_RANGE to 416 * move CRLF macro definition to defines.h * use CRLF macro everywhere * don't print content-length in print_partial_content_continue * remove extra CRLF in print_partial_content_done * *do* print content-length in 206 response's "primary" headers IFF There is only 1 range. * move CRLF in 206 *after* to the print_partial_content_continue * in 503, remove \r from the human-readable message. * #define and use CRLF macro, fix some tabs/spaces issues * in date_to_tm, use 70 not 50 as the cutoff date (makes sense, 1970) * adapt some code from Squid to return -1 in date_to_tm on invalid dates (seconds > 59, etc...) * implement ConcealServerIdentity * treat headers with blank content as non-error but do not parse them * as of 0.94.14rc20: * fix potential NULL-pointer dereference in hash_insert, introduced in 0.94.14rc16. * try to make SuSE-ready: rpm/{boa.init, boa.init-redhat, boa.init-suse, boa.spec} * use S_ISREG combined with access(2) rather than using the statbuf stuff to determine if a cgi is accessible * optionally #define EXIT_FAILURE and EXIT_SUCCESS, and use them everywhere. * mark a few variables and functions 'static' * use %u instead of %d when printing an unsigned int * mmap returns void * not char * * change access_node->type to an enum * make boa.h #include 'config.h' *first* * use -1 instead of ULONG_MAX (that way, if the datatype ever changes, we always get it's maximum) * fix bug in multiple non-contiguous range requests for files that use sendfile(2) * reduce some noise if a request in a keepalive chain is shut down without having read a single byte. * fix potential memory access bug in hashing * update config.sub and config.guess to the latest available * use CHANGES not ChangeLog * as of 0.94.14rc21: * shift from GNU Autoconf 2.58 to GNU Autoconf 2.59 * increase warning level in GCC_FLAGS another notch * skip superfluous unsigned qualifier for char in get_alias_hash_value * skip check for error in umask(), since it doesn't happen * reorder read_config_files() and create_common_env() * drop incorrect preprocessor usage in TIMEZONE macro * make very sure default_type is set * correct error message in index_dir for .gz files * make mmap_cache 64-bit clean * try to deal with signed file offsets when using sendfile() * clean up signed/unsigned char issues in read_header() * use socklen_t where appropriate in request.c * call range_pool_empty() in response to SIGHUP * add more const qualifiers * eliminate signed/unsigned comparison warnings: change ka_timeout to signed * spelling fixes * miscellaneous whitespace changes * update Copyright dates * drop webindex.pl ** Changes from 0.94.12 to 0.94.13 * Change many instances of log_error_mesg + exit to DIE macro * Change all instance of log_error_mesg (without exit) to WARN macro * do a much better job of checking return values from malloc and especially strdup. * check results of calling umask and getrlimit * server_s is no longer a global int * check results of fork via switch instead of if (fork()) * check for getopt.h and include it if found * remove unused #defines, and add WARN macro, and replace many calls to log_error_mesg(..) with WARN macro * fix bug in get_commonlog_time where time_offset calculation was the opposite of what it should be ('-' and '+' were swapped) * fix compatability bug with old and newer versions of flex/yacc * add check for AC_FUNC_MMAP to configure.in * fix really lame thinko in normalize_path, which would prepend the results of earlier calls to results from later calls * Add MaxConnections, a configuration directive which allows the user to specify the maximum number of connections that Boa will accept concurrently. * add SERVER_ADDR and REQUEST_URI to environment of CGI * handle SIGBUS during writes of data that has been memory mapped * minor optimization in select.c that prevents DEAD requests from being added to the block set * fix bug in CGI environment script_name - closes sf.net bug #576725 * make 'status' variable local to requests.c, not local to every file by forgetting to declare 'extern' in globals.h :-| * make getsockname non-fatal, and do it every time because we may need it for the CGI * some minor refactoring optimizations in hash.c * enlarge MMAP hash table to 1024 from 256, and enlarge other mmap-related hash table #defines appropriately (4x, or (x+1)*4-1) ** Changes from 0.94.11 to 0.94.12 * Renamed Changelog ChangeLog, and moved up to top-level directory * Next 3 items due in part or whole thanks to Liam Widdowson * when printf'ing a pid type, force to int, because it could be something else on other platforms. Should probably change it to a long, and use that. * backported chroot commandline support from 0.95 * backported support for strdup, strstr, alphasort, and scandir from 0.95 * Fixed src/Makefile.in -- it didn't remove index_dir.o * backport create_temporary_file from 0.95 (instead of using tmpnam) * Allow non-standard date format 31 September 2000 23:59:59 GMT Patch by Landon Curt Noll * Skip whitespace before HTTP/major.minor Adapted patch from Landon Curt Noll * open /dev/null first thing (affects chrooting) * properly handle sigalrm -- use sigalrm_flag and sigalrm_run instead of handling the signal in the signal handler * update manpage slightly * send 400 BAD Request when resource does not start with '/' * add grp.h to boa.h's includes -- remove from boa.c and config.c * removed duplicate header includes from boa.c, config.c, get.c, ip.c, request.c, response.c * factor out creating the server socket and dropping privs into create_server_socket and drop_privs * type all functions in boa.c (except main) as static * set umask after opening /dev/null * tie stdin/stdout to /dev/null before commandline parse * removed old, unused chroot code * move builds_needs_escape earlier in the startup * move fork later in the startup * type all c_set_* as static in config.c * don't bother trying to change uid/gid (or error if the requested uid/gid doesn't exist) if not UID 0 * return more appropriate error code when foo.html gives access denied, but foo.html.gz gives some other error (essentially report error associated with foo.html, not foo.html.gz) * send NOT Implemented when an unknown method is attempted * always attempt a 32k read right before close (stopgap until blackhole can be merged) * allow more than 1 space in logline between method, resource, and http version * don't use inline functions * update configure.in so that autoconf 2.50 doesn't complain (as much) * properly use VPATH and srcdir according to autoconf docs * change curly-braces to parentheses in Makefilein * use $^ instead of manually listing the dependencies in Makefile.in * remove tests section in Makefile.in * write tags not TAGS in Makefile.in * Add gethostbyname and inet_aton to function checks * Add code from 0.95 which checks for socket in -lsocket, inet_aton in -lresolv, and gethost{by}name in -lnsl * Also remove broken bc-based "how big is an unsigned int" checks: assume minimum of 32 bits and check in escape.c at runtime. * Added new file: README.chroot.solaris, based on a modified version by Liam Widdowson * Add check_struct_for.m4, which allows us to check a structure for a member (found at http://www.gnu.org/software/ac-archive/ authored by Wes Hardaker * Call "aclocal -I ." to rebuild aclocal.m4 * Using new check-struct-for-member autoconf macro, check for tm_gmtoff and tm_zone in struct tm -- useful in portability tests for localtime. * Also check sockaddr_in for structure sin_len so we can set it properly. * index_dir.c (which ends up in boa_indexer) can now be compiled with USE_LOCALTIME, and if so, it will report the local time using the timezone name. Otherwise it uses UTC time and UTC timezone designation. * fix buglet in mmap_cache.c which shows up when under heavy load by many different files. Found and squashed by Michal Kara * normalize paths on Aliases, log files, server root, dirmaker This makes sure that paths are 'absolute' * don't generate DOCUMENT_ROOT or SERVER_ROOT, CGIs have no business knowing that information * if CGI, chdir to the cgi's root path Bug found by Matt Callaway * remove ChrootPath and PidFile directives from the parser (they aren't used anyway) * keep track of maximum file descriptor in use to optimize call to select() * apply IPv6 patch from Jari Korva * optimize keep-alive copy data routine * try to use memcpy instead of strcpy/strcat in more places (alias.c) * update .depend file * use fcntl + GET_FL to get a file descriptor's flags, then add or remove only the bits we want to set. This prevents accidentally setting or unsettings bits we don't have anything to do with inadvertantly. (removed, at least temporarily. Show me a system where it is needed -- LRD) * make sure to call FD_ZERO when we handle a restart * in read.c, don't call boa_perror on read failure -- socket is dead or messed up anyway, no reason to try to write to it. * explicit .SUFFIXES in Makefile.in * boa.objdump target added * use @MAKE_SET@ (for when $(MAKE) != "make") * add -Wundef -Wwrite-strings -Wredundant-decls -Winline to GCC_FLAGS * change Paul Phillips' and Larry Doolittle's emails in source * add --disable-debug, --enable-profile, --with-dmalloc, and --with-efence * test for failed-but-return-was-successful setuid: http://www.securityfocus.com/bid/1322 * use _exit not exit in CGI child * always place new keepalive request on blocked list, we can't be sure of the state of the active list, and since enqueue places things at the *front* of the list, it doesn't do us much good to place the new request on the active list anyway. * update some Copyright statements for 2002 * When comparing the uri to an alias, only compare if the uri length is greater than or equal to the length of the alias * in init_script_alias, make sure to check for document_root before trying to use it * script_name is now just a copy of the request, rather than some complicated variation on the pathname * change the way the CGI environment is handled. Now, it is allocated at request allocation time, and exists throughout the life of the structure. * check memory allocations, etc.. when creating the static CGI environment and when making new CGI environment variables * wait until process_option_end to call unescape_uri, clean_pathname, and translate_uri * remove debian package information * move RedHat packaging information to contrib * remove tests -- they weren't usable anyway * add some new hash routines, and use djb2 (a variant on a hash algorithm popularized by Dan J. Bernstein) * a side-effect of the new hash routines is a bugfix, involving negative return values from hash routines. This has been fixed. * add a routine, show_hash_stats, which is called with other statistical output via sigalarm * remove some duplicate prototypes from config.c * make simple_itoa take an unsigned int * try to make NOBLOCK handling in compat.h compatible with Solaris * make sure to update current_time before calling signal handlers * alter primary loop to make sure that select gets called even when there are requests that are not blocking, and call fdset_update and process_requests (when appropriate) after signal handlers but before select to make sure that blocked requests are still handled by select after a sighup. (Thanks to Karl Olsen) * pull select loop into select.c * poll server socket once per active connection * add send_r_service_unavailable and use it when appropriate * state uptime in seconds at normal program termination * include sys/fcntl.h if it is found by configure * fix POST bug where a content-length < 0 would cause Boa to consume its full share of CPU until killed Bug report by Landon Curt Noll * add CGIPath configuration variable based upon a patch by Landon Curt Noll * add function boa_atoi, which wraps atoi, but does not accept negative values. Additionally, it checks to make sure the converted value and the original value are the same, avoiding issues like "124.3" -> "123" and "123abc" -=> "123". Either a value is an int or it isn't - no middle ground. * use boa_atoi to convert content-length from client. * add new #define - SINGLE_POST_LIMIT_DEFAULT, which defines (in bytes) the *default* single_post_limit. * single_post_limit is now in bytes. * when adding aliases, only "normalize" paths that start with "./" - this is a departure from previous behavior * add "?" to the list of characters that it is safe to leave unescaped * clean up Makefile.in of no-longer-pertinent comments * add send_r_bad_gateway and use it * tie stderr to either cgi_log_fd or devnullfd - either way make sure stderr is a valid filehandle before cgi execution * cgi_env is no longer allocated, it's part of the struct now * fix bug in CgiPath logic * when unable to allocate memory for an environment variable, log it * add clear_common_env, which de-allocates the cgi_common_env stuff [NEVER USE THIS outside of a terminal signal handler!] * don't be so wasteful of memory in normalize_path * adapted fix for alias expansion from Brieuc Jeunhomme ** Changes from 0.94.10.1 to 0.94.11 * use LIBS in Makefile.in (which propagates from autoconf) * properly free memory allocated by scandir in index_dir.c * rearrange some header files and includes * on reads and writes, don't check for -1, check for < 0 * include fix by William Meadows for escape.c which fixes segfaults due to improper allocation * above fix by William Meadows no longer needed; escape.c and escape.h rewritten by Larry Doolittle -- requires at least 32 bit words, but is correct (jdn's 1st attempt was faulty) ** Changes from 0.94.10 to 0.94.10.1 * Actually update the SERVER_VERSION in src/defines.h ** Changes from 0.94.9 to 0.94.10 * Fixes escaping rules * Fixes segfault when directory_index is undefined and directory needs to be generated * adds dummy signal handlers for SIGUSR1 and SIGUSR2 (Closes SF #425921) * Update documentation regarding mime.types (Closes Debian #69991) * Make sure documentation builds (Closes Debian #110818) ** Changes from 0.94.8.3 to 0.94.9 * src/Makefile.in updated to take CFLAGS, LIBS, and LDFLAGS from autoconf * Update escaping rules with latest RFC * unescape_uri skips fragments and also stop parsing at '?' * Don't accept fd over FD_SETSIZE in request.c:get_request * use backported documentation from 0.95 * make sure POST fd gets closed even on client cancel * use backported index_dir.c from 0.95 * support subdirectories in ScriptAlias directories * add SinglePostLimit (int, in Kilobytes) to config system * add CGIPath configuration to set the CGI's PATH variable. * check for ENOSPC on body write * use environment variable TMP (or "/tmp" if not available), and chdir there when boa exits. * add 1-time-only hack to make a 32kB read at the end of a request on POST or PUT * close unused file descriptors (/dev/null in boa.c, and the unused part of the pipes call in cgi.c) * made Makefile.in VPATH happy ** Changes from 0.94.8.2 to 0.94.8.3 * Move unescape_uri *before* clean_pathname to prevent encoding of / and .. in pathname * wrap execution of GUNZIP in cgi.c with #ifdef GUNZIP * stop parsing when fragment found in URL ('#') ** Changes from 0.94.8.1 to 0.94.8.2 * close pipes[1] in child and generate HTTP_REFERER environment variable in cgi.c * Minor changes to the Debian package ** Changes from 0.94.8 to 0.94.8.1 * Change umask call from (umask(0600)) to (umask(~0600)) ** Changes from 0.94.7 to 0.94.8 * Fix major thinko in temp file permissions * unlink temporary file immediately following creation * implement maximum # of active connections at 10 less than RLIMIT_NOFILE to avoid or eliminate crashes resulting from running out of file descriptors * Fix thinko in POST ** Changes from 0.94.6 to 0.94.7 * STDIN and STDOUT are now tied to /dev/null * sets PATH_MAX to 2048 if not defined (for Hurd) * core dumps (should never happen) would be located in /tmp * alter behavior when select gets a EBADF * add translation for the \" char -> " * remove use of sys_errlist. Use perror. * better makedist.sh (still a stupid program though) ** Changes from 0.94.5 to 0.94.6 * Removed doc++ commenting * Removed erroneous debugging statments * Move some stuff out of config.c (read_config_file) to boa.c * Altered some of fixup_server_root() * Bug fix in get.c re: automatic gunzip * Added some stubs for chroot code (*not* ready yet) ** Changes from 0.94.4 to 0.94.5 * Alteration of most of the comments and such for doc++ use * Fixed buffer overflow in alias.c * Fixed buffer underflow in util.c ** Changes from 0.94.3 to 0.94.4 * Better escaping of data to user, both for HTTP headers and HTML body * Proper escaping of output in CGI example perl scripts ** Changes from 0.94.0 to 0.94.2 * Fixed obnoxious pipeline bug * Fixed (sorta) a compilation/core bug for *BSD systems Original code by Thomas Neumann * Moved to GPLv2 * Changed manpage to section 8 * boa.sgml now references a .png file instead of evil .gif ** Changes from 0.93.19.2 to 0.94.0 * Added UseGMT to the configuration parser * util.c commonlog now logs in Apache-style commonlog time format * Remove SO_SNDBUF on-start message ** Changes from 0.93.19 to 0.93.19.2 * Changed to combined log (from NCSA access_log format) ala Drew Streib * Altered POST cgi code to handle bug in Netscape * SO_SNDBUF changes by Larry ** Changes from 0.93.17.2 to 0.93.19 (all 0.93.18.x changes inclusive) * Update of some copyright statements for 99 * Replacement of sprintf with strlen/memcpy or strcpy/strcat wherever possible * Significant rearrangement in alias.c, minor functional differences (some CGI environment variables handled differently) * Removal of die function. Replace with log_err_mesg and exit. * initial IPv6 stubs and support * Move #include "config.h" to top of boa.h where it will do some good * Stubs and functions for strstr and strdup * Seperation of buffer code into it's own file * Significant changes to cgi.c et al (cgi_header.c, etc...) * Speed patches by removal of "extra" calls to time(): Use global variable! * pipelining changes... it works now. * require content-length from clients (ala rfc1945) * alter body_read and body_write to work more efficiently with known content-length * move read(2) part to *after* parsing... * added support for additional header message in send_redirect_temp * change use of NO_ZERO_FILL_LENGTH to offsetof() use * Remove SO_REUSEADDR setting on each client socket, Paul Saab * Avoid SO_SNDBUF setting if possible * Large quantities of otherwise not-insignificant changes ** Changes from 0.93.17.2 to 0.93.17.3 * Put on-the-fly directories back in, stripped down from the 0.92 version * Fixed DocumentRoot, ServerAdmin and ServerName null-value handling in CGI environment generation * Fixed argument order in Script* directives (bug introduced in 0.93.17.2) * Got rid of MAX_CGI_VARS because it was not being used consistently, or for that matter, at all, really. * Added some more FASCIST_LOGGING to cgi.c * Minor mmap patch by LRD for request.c ** Changes from 0.93.17.1 to 0.93.17.2 * Added "Listen" directive for server bind address, as most recently suggested by David N. Welton * Put virtualhost feature in, was experimental in 0.92q ** Changes from 0.93.16.2 to 0.93.17.1 * New config file parser (supposed to be more maintainable) (LRD) * Support for "|command" and ":host:port" syntax for logfiles (untested) (LRD) ** Changes for the 0.93 version ** * Huge quantities of changes * keepalive Bugfix in 0.93.16.2 by Jon Nelson report by Craig Silverstein of Google fame. * patch for config.h by Craig Silverstein * fixed "Parent Directory" problem in boa_indexer for title "/" (Debian bug #36165) * More Craig Silverstein modifications, namely: ErrorLog (if omitted, print to stderr) DocumentRoot (if omitted, can only server user-dir files) DirectoryIndex (if omitted, always use DirectoryMaker) MimeTypes (if omitted, don't load -- users can use AddType instead) ** Changes from v0.92o to v0.92p ** * Documented misbehavior of CGI, SIGHUP, short aliases, stale dircache. * Documented how to patch signals.c for use on SunOS. * Closed file descriptor leak when redirecting a bare directory URL to one with an appended "/". * Closed potential file descriptor leak if errors encountered generating on-the-fly index. * Cleaned up include file handling to be simultaneously compatible with Linux, SunOS, HP-UX, and AIX. * Supress message body for codes 302, 400, 403, 404, 500, and 501 if incoming request is "HEAD". ** Changes from v0.91 to v0.92o ** (0.92o released 27 December, 1996) * Maintenance handover from Paul Phillips to Larry Doolittle * Changed (char)NULL to '\0' * Cleaned up signal handler prototypes in signals.c * Modified handling of CGI environment variable PATH_TRANSLATED, should now work the same as NCSA. * More conservative buffer size in add_cgi_env() * Build argv list for a CGI script according to spec * Speedup process_header_line, eliminate potential memory leak * Occasional spelling fixes and lint removal * Added REMOTE_PORT env var for CGI scripts, to allow easy ident lookups * Changed rfc822 time format * Log timeouts and broken connections * Fix mime suffix handling for filenames with multiple "."s * Initialize conn->time_last, fixes bug with rapid-fire connections * Performance tweak to req_write() * Changed http_version from float to char[8] * Rewrote on-the-fly directory generation; it works now * Added user configurable dircache directory in boa.conf * Fixed "simple" response bugs, including incorrect CGI handling * Keepalive (HTTP/1.1 draft) support, mostly by Jon Nelson * Close data_fd in 304 Not Modified flow of control * Switch socket flags to non-blocking before cgi handoff * Try to handle errno properly in the face of multiple errors * Close fd's of all other transactions before cgi handoff * Move real work for sighup and sigchld out of signal handler * Fix free(req->cgi_env) in request.c * Response message cleanup - better match to HTML-2.0 DTD * Experimental Virtual Host code from Russ Nelson * Expand buffer for escaped URI in init_get() * SIGTERM triggers lame duck mode until all pending transactions complete * Close and unlink temp file for POST in parent process ** Changes from v0.90 to v0.91 ** * Cleaned up main while loop * Optimized request line parsing * Added state machine for header reads -- necessary to deal wtih possibility of obtaining header data in multiple reads. This also allows interactive use of server. * Added 500/501 return codes for various conditions ** v0.90 ** * Initial release boa-0.94.14rc21/COPYING0000644000175000001440000004311007541627162015015 0ustar jnelsonusers00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 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. Copyright (C) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year 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. , 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. boa-0.94.14rc21/CREDITS0000644000175000001440000000427507617124055015010 0ustar jnelsonusers00000000000000Liam Widdowson Lots of improvement for Solaris support Wes Hardaker Michal Kara mmap_cache buglet fix Matt Callaway CGI chdir issue Jari Korva IPv6 patch William Meadows escape.c bug notification and (first) fix Thomas Neumann *BSD compilation/core bugfixes Paul Saab Remove SO_REUSEADDR setting on each client socket David N. Welton Added "Listen" directive for server bind address Craig Silverstein patches for config.h and config.c Russ Nelson Original, Experimental IP-based Virtual Host code Landon Curt Noll http://www.isthe.com/chongo Allow non-standard date format 31 September 2000 23:59:59 GMT Skip whitespace before HTTP/major.minor FNV1a hash in hash.c Brieuc Jeunhomme fix buglet in alias expansion the name-based virtualhost code patch send to us by Brieuc was *very* close to the one that had been developed in-house, so we merged them. Special thanks for *actually* writing DOCS!! Laurent Pelecq test for socket in -lnet for BeOS tests for herror and inet_addr Don Mahurin (dma) pidfile patch default mime_types patch NCSA environment environment variables wrapped in #ifdef USE_NCSA_CGI_ENV Ulf Harnhammar fixed a small escaping issue with the automatic directory index maker Fraser McCrossan dummy install target some prototype cleaning for *BSD sprintf -> snprintf for local redirection in get.c MJ Pomraning suggestions to update index_dir.c to make sure filenames are http and html safe. Peter Korsgaard basic access control disable-gunzip support capitalization changes, etc.. to configure.in Davide Pagnin notes regarding find_mmap misuse Peter Pentchev fixes to sa_family_t detection on *BSD Alan H. Teague general cleanups boa-0.94.14rc21/Makefile.in0000644000175000001440000000106707576177640016045 0ustar jnelsonusers00000000000000# $Id: Makefile.in,v 1.1.2.6 2002/12/12 21:29:04 jnelson Exp $ MAKE=@MAKE@ .PHONY: clean mrclean distclean boa docs all: boa boa: (cd src && $(MAKE) $(MFLAGS)) docs: (cd docs && $(MAKE) $(MFLAGS)) clean: -(cd src && $(MAKE) $(MFLAGS) clean) -(cd docs && $(MAKE) clean) distclean: mrclean mrclean: clean -(cd src && $(MAKE) $(MFLAGS) mrclean) -(cd docs && $(MAKE)$(MFLAGS) mrclean) rm -f config.status config.cache config.h config.log rm -f Makefile *~ # dummy target for install install: @echo Please read the documentation then install manually. boa-0.94.14rc21/README0000644000175000001440000000113607437566724014656 0ustar jnelsonusers00000000000000This is Boa, a high performance web server for Unix-alike computers, covered by the Gnu General Public License. This is version 0.94, released January 2000. It is well tested and appears to be of at least "gamma" quality. Boa was created in 1991 by Paul Phillips . It is now being maintained and enhanced by Larry Doolittle and Jon Nelson . For more information (including installation instructions) examine the file docs/boa.txt or docs/boa.dvi, point your web browser to docs/boa.html, or visit the Boa homepage at http://www.boa.org/ boa-0.94.14rc21/aclocal.m40000644000175000001440000001421607613060740015620 0ustar jnelsonusers00000000000000# aclocal.m4 generated automatically by aclocal 1.6.2 -*- Autoconf -*- # Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. dnl Many of the following macros courtesy of: dnl http://www.gnu.org/software/ac-archive/ dnl dnl The Following macros courtesy of: dnl Installed_Packages/check_gnu_make.html dnl dnl Copyrights are by the individual authors, as listed. dnl License: GPL dnl dnl CHECK_GNU_MAKE() dnl dnl This macro searches for a GNU version of make. If a match is found, the dnl makefile variable `ifGNUmake' is set to the empty string, otherwise it is dnl set to "#". This is useful for including a special features in a Makefile, dnl which cannot be handled by other versions of make. The variable dnl _cv_gnu_make_command is set to the command to invoke GNU make if it exists, dnl the empty string otherwise. dnl dnl Here is an example of its use: dnl dnl Makefile.in might contain: dnl dnl # A failsafe way of putting a dependency rule into a makefile dnl $(DEPEND): dnl $(CC) -MM $(srcdir)/*.c > $(DEPEND) dnl dnl @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND))) dnl @ifGNUmake@ include $(DEPEND) dnl @ifGNUmake@ endif dnl dnl Then configure.in would normally contain: dnl dnl CHECK_GNU_MAKE() dnl AC_OUTPUT(Makefile) dnl dnl Then perhaps to cause gnu make to override any other make, we could do dnl something like this (note that GNU make always looks for GNUmakefile first): dnl dnl if ! test x$_cv_gnu_make_command = x ; then dnl mv Makefile GNUmakefile dnl echo .DEFAULT: > Makefile ; dnl echo \ $_cv_gnu_make_command \$@ >> Makefile; dnl fi dnl dnl Then, if any (well almost any) other make is called, and GNU make also exists, dnl then the other make wraps the GNU make. dnl dnl John Darrington dnl 1.3 (2002/01/04) dnl dnl Modified 18 Sep 2002 by Jon Nelson AC_DEFUN([CHECK_GNU_MAKE], [ AC_CACHE_CHECK( for GNU make, _cv_gnu_make_command, [_cv_gnu_make_command='' dnl Search all the common names for GNU make for a in "$MAKE" make gmake gnumake ; do if test -z "$a" ; then continue ; fi if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ); then _cv_gnu_make_command=$a break; fi done if test "x$_cv_gnu_make_command" = "x"; then _cv_gnu_make_command="Not found" fi ]) dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise if test "$_cv_gnu_make_command" != "Not found"; then ifGNUmake=''; else ifGNUmake='#'; _cv_gnu_make_command=''; fi AC_SUBST(ifGNUmake) ]) dnl AC_CHECK_STRUCT_FOR(INCLUDES,STRUCT,MEMBER,DEFINE,[no]) dnl 1.1 (2000/09/19) dnl Wes Hardaker dnl ---------------------------------------------------------- AC_DEFUN([AC_CHECK_STRUCT_FOR],[ ac_safe_struct=`echo "$2" | sed 'y%./+-%__p_%'` ac_safe_member=`echo "$3" | sed 'y%./+-%__p_%'` ac_safe_all="ac_cv_struct_${ac_safe_struct}_has_${ac_safe_member}" changequote(, )dnl ac_uc_define=STRUCT_`echo "${ac_safe_struct}_HAS_${ac_safe_member}" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` changequote([, ])dnl AC_MSG_CHECKING([for $2.$3]) AC_CACHE_VAL($ac_safe_all, [ if test "x$4" = "x"; then defineit="= 0" elif test "x$4" = "xno"; then defineit="" else defineit="$4" fi AC_TRY_COMPILE([ $1 ],[ struct $2 testit; testit.$3 $defineit; ], eval "${ac_safe_all}=yes", eval "${ac_safe_all}=no" ) ]) if eval "test \"x$`echo ${ac_safe_all}`\" = \"xyes\""; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED($ac_uc_define) else AC_MSG_RESULT(no) fi ]) dnl @synopsis AC_C_VAR_FUNC dnl dnl This macro tests if the C complier supports the C9X standard dnl __func__ indentifier. dnl dnl The new C9X standard for the C language stipulates that the dnl identifier __func__ shall be implictly declared by the compiler dnl as if, immediately following the opening brace of each function dnl definition, the declaration dnl dnl static const char __func__[] = "function-name"; dnl dnl appeared, where function-name is the name of the function where dnl the __func__ identifier is used. dnl dnl @version $Id: aclocal.m4,v 1.1.2.5 2003/01/20 20:53:52 jnelson Exp $ dnl @author Christopher Currie AC_DEFUN([AC_C_VAR_FUNC], [AC_REQUIRE([AC_PROG_CC]) AC_CACHE_CHECK(whether $CC recognizes __func__, ac_cv_c_var_func, AC_TRY_COMPILE(, [int main() { char *s = __func__; }], AC_DEFINE(HAVE_FUNC,, [Define if the C complier supports __func__]) ac_cv_c_var_func=yes, ac_cv_c_var_func=no) ) ])dnl dnl Exports one of ac_cv_func_poll or ac_cv_func_select dnl Author - Jon Nelson dnl Copyright 2002 AC_DEFUN([POLL_OR_SELECT], [ AC_MSG_CHECKING(whether to use poll or select) AC_ARG_WITH(poll, [ --with-poll Use poll], [ if test "$withval" = "yes" ; then AC_MSG_RESULT(trying poll) ac_x=1 else AC_MSG_RESULT(trying select) ac_x=0 fi ], [ AC_MSG_RESULT(trying select) ac_x=0 ]) if test $ac_x = 1; then AC_CHECK_HEADERS(sys/poll.h) AC_CHECK_FUNCS(poll) if test "x$ac_cv_func_poll" = "x"; then AC_MSG_ERROR(We attempted to find poll but could not. Please try again with --without-poll) fi BOA_ASYNC_IO="poll" else AC_CHECK_HEADERS(sys/select.h) AC_CHECK_FUNCS(select) if test "x$ac_cv_func_select" = "x"; then AC_MSG_ERROR(We attempted to find select but could not. Please try again with --with-poll) fi BOA_ASYNC_IO="select" fi ] ) boa-0.94.14rc21/config.guess0000754000175000001440000012513110061741374016276 0ustar jnelsonusers00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2004-03-12' # 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. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # 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 build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) 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 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; amd64:OpenBSD:*:*) echo x86_64-unknown-openbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; cats:OpenBSD:*:*) echo arm-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pegasos:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mipseb-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit 0 ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit 0 ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit 0 ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha*:OpenVMS:*:*) echo alpha-hp-vms exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; *:OS400:*:*) echo powerpc-ibm-os400 exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit 0 ;; DRS?6000:UNIX_SV:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7 && exit 0 ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-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 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c \ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && exit 0 echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix 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:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${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*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 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:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | 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=${UNAME_VERSION}.${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 BSD 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/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then # avoid double evaluation of $set_cc_for_build test -n "$CC_FOR_BUILD" || eval $set_cc_for_build if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include 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_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 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 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi 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*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; *:UNICOS/mp:*:*) echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) # Determine whether the default compiler uses glibc. eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #if __GLIBC__ >= 2 LIBC=gnu #else LIBC= #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` # GNU/KFreeBSD systems have a "k" prefix to indicate we are using # FreeBSD's kernel, but not the complete OS. case ${LIBC} in gnu) kernel_only='k' ;; esac echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit 0 ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit 0 ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit 0 ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # 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. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-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 ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit 0 ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 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 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) case `uname -p` in *86) UNAME_PROCESSOR=i686 ;; powerpc) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit 0 ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` 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 eval $set_cc_for_build cat >$dummy.c < # include #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 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`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); 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-pc-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) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # 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_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 # 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 cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: boa-0.94.14rc21/config.sub0000754000175000001440000007467010061741374015754 0ustar jnelsonusers00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2004-03-12' # 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. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # 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 # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### 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 | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; 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. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # 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. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | msp430-* \ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; 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 | j90) basic_machine=j90-cray os=-unicos ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; 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 ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-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 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; 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 ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; 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 ;; necv70) basic_machine=v70-nec os=-sysv ;; 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 ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nv1) basic_machine=nv1-cray os=-unicosmp ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; 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 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-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/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; 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 ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; 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. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) 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 # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # 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[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -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*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; 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 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-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 ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) 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 ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: boa-0.94.14rc21/configure0000754000175000001440000076205310107202417015666 0ustar jnelsonusers00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="src/boa.c" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP ifGNUmake ALLSOURCES MAKE EGREP LIBOBJS SCANDIR ALPHASORT STRUTIL GUNZIP ACCESSCONTROL_SOURCE ASYNCIO_SOURCE LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. 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' 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 ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # 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_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$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 ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) 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 | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$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 | -n) 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_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } 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 "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # 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_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` 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 "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # 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 <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-profiling Compile and link profiling code --disable-gunzip Disable use of gunzip --enable-access-control Enable support for allow/deny rules --disable-debug Do not compile and link debugging code --disable-verbose Do not enable verbose/debug logging --disable-sendfile Disable the use of the sendfile(2) system call Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-dmalloc Link with the Dmalloc memory debugger/profiler --with-efence Link with the Electric Fence memory debugger --with-poll Use poll Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd "$ac_popdir" done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # 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 # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # 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 "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/config.h" 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 elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 echo "$as_me: error: cannot run $ac_config_sub" >&2;} { (exit 1); exit 1; }; } echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6 if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_build_alias=$build_alias test -z "$ac_cv_build_alias" && ac_cv_build_alias=`$ac_config_guess` test -z "$ac_cv_build_alias" && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6 build=$ac_cv_build build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6 if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_host_alias=$host_alias test -z "$ac_cv_host_alias" && ac_cv_host_alias=$ac_cv_build_alias ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6 host=$ac_cv_host host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl 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 "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking whether $CC recognizes __func__" >&5 echo $ECHO_N "checking whether $CC recognizes __func__... $ECHO_C" >&6 if test "${ac_cv_c_var_func+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int main() { char *s = __func__; } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_FUNC _ACEOF ac_cv_c_var_func=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_var_func=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_var_func" >&5 echo "${ECHO_T}$ac_cv_c_var_func" >&6 echo "$as_me:$LINENO: checking for GNU make" >&5 echo $ECHO_N "checking for GNU make... $ECHO_C" >&6 if test "${_cv_gnu_make_command+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else _cv_gnu_make_command='' for a in "$MAKE" make gmake gnumake ; do if test -z "$a" ; then continue ; fi if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ); then _cv_gnu_make_command=$a break; fi done if test "x$_cv_gnu_make_command" = "x"; then _cv_gnu_make_command="Not found" fi fi echo "$as_me:$LINENO: result: $_cv_gnu_make_command" >&5 echo "${ECHO_T}$_cv_gnu_make_command" >&6 if test "$_cv_gnu_make_command" != "Not found"; then ifGNUmake=''; else ifGNUmake='#'; _cv_gnu_make_command=''; fi if test "x$_cv_gnu_make_command" != "x"; then MAKE="$_cv_gnu_make_command" ALLSOURCES="\$^" else MAKE="make" ALLSOURCES="\$(.ALLSRC)" fi # AC_SEARCH_LIBS (function, search-libs, [action-if-found], [action-if-not-found], [other-libraries]) echo "$as_me:$LINENO: checking for library containing socket" >&5 echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6 if test "${ac_cv_search_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_socket=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); int main () { socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_socket="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_socket" = no; then for ac_lib in socket net; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); int main () { socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_socket="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5 echo "${ECHO_T}$ac_cv_search_socket" >&6 if test "$ac_cv_search_socket" != no; then test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS" fi echo "$as_me:$LINENO: checking for library containing inet_aton" >&5 echo $ECHO_N "checking for library containing inet_aton... $ECHO_C" >&6 if test "${ac_cv_search_inet_aton+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_inet_aton=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char inet_aton (); int main () { inet_aton (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_inet_aton="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_inet_aton" = no; then for ac_lib in resolv; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char inet_aton (); int main () { inet_aton (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_inet_aton="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_inet_aton" >&5 echo "${ECHO_T}$ac_cv_search_inet_aton" >&6 if test "$ac_cv_search_inet_aton" != no; then test "$ac_cv_search_inet_aton" = "none required" || LIBS="$ac_cv_search_inet_aton $LIBS" fi echo "$as_me:$LINENO: checking for library containing gethostname" >&5 echo $ECHO_N "checking for library containing gethostname... $ECHO_C" >&6 if test "${ac_cv_search_gethostname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_gethostname=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname (); int main () { gethostname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_gethostname="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_gethostname" = no; then for ac_lib in nsl; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname (); int main () { gethostname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_gethostname="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_gethostname" >&5 echo "${ECHO_T}$ac_cv_search_gethostname" >&6 if test "$ac_cv_search_gethostname" != no; then test "$ac_cv_search_gethostname" = "none required" || LIBS="$ac_cv_search_gethostname $LIBS" fi echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5 echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6 if test "${ac_cv_search_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_gethostbyname=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_gethostbyname="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_gethostbyname" = no; then for ac_lib in nsl; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_gethostbyname="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6 if test "$ac_cv_search_gethostbyname" != no; then test "$ac_cv_search_gethostbyname" = "none required" || LIBS="$ac_cv_search_gethostbyname $LIBS" fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_opendir=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_opendir" = no; then for ac_lib in dir; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6 if test "$ac_cv_search_opendir" != no; then test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" fi else echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_opendir=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_opendir" = no; then for ac_lib in x; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char opendir (); int main () { opendir (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_opendir="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6 if test "$ac_cv_search_opendir" != no; then test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" fi fi echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else 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 <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else 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 <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #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); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_sys_wait_h=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 if test $ac_cv_header_sys_wait_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_WAIT_H 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in fcntl.h sys/fcntl.h limits.h sys/time.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in getopt.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* 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; } #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6 if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6 if test "${ac_cv_type_uid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 echo "${ECHO_T}$ac_cv_type_uid_t" >&6 if test $ac_cv_type_uid_t = no; then cat >>confdefs.h <<\_ACEOF #define uid_t int _ACEOF cat >>confdefs.h <<\_ACEOF #define gid_t int _ACEOF fi echo "$as_me:$LINENO: checking for off_t" >&5 echo $ECHO_N "checking for off_t... $ECHO_C" >&6 if test "${ac_cv_type_off_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((off_t *) 0) return 0; if (sizeof (off_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_off_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_off_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 echo "${ECHO_T}$ac_cv_type_off_t" >&6 if test $ac_cv_type_off_t = yes; then : else cat >>confdefs.h <<_ACEOF #define off_t long _ACEOF fi echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((pid_t *) 0) return 0; if (sizeof (pid_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6 if test $ac_cv_type_pid_t = yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6 if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((size_t *) 0) return 0; if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned _ACEOF fi echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6 if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 if test "${ac_cv_struct_tm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct tm *tp; tp->tm_sec; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_struct_tm=sys/time.h fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 echo "${ECHO_T}$ac_cv_struct_tm" >&6 if test $ac_cv_struct_tm = sys/time.h; then cat >>confdefs.h <<\_ACEOF #define TM_IN_SYS_TIME 1 _ACEOF fi echo "$as_me:$LINENO: checking whether sa_family_t is defined" >&5 echo $ECHO_N "checking whether sa_family_t is defined... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { sa_family_t foo2; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 cat >>confdefs.h <<\_ACEOF #define DONT_HAVE_SA_FAMILY_T 1 _ACEOF fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: checking for working POSIX fnmatch" >&5 echo $ECHO_N "checking for working POSIX fnmatch... $ECHO_C" >&6 if test "${ac_cv_func_fnmatch_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Some versions of Solaris, SCO, and the GNU C Library # have a broken or incompatible fnmatch. # So we run a test program. If we are cross-compiling, take no chance. # Thanks to John Oleynick, Franc,ois Pinard, and Paul Eggert for this test. if test "$cross_compiling" = yes; then ac_cv_func_fnmatch_works=cross else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include # define y(a, b, c) (fnmatch (a, b, c) == 0) # define n(a, b, c) (fnmatch (a, b, c) == FNM_NOMATCH) int main () { exit (!(y ("a*", "abc", 0) && n ("d*/*1", "d/s/1", FNM_PATHNAME) && y ("a\\\\bc", "abc", 0) && n ("a\\\\bc", "abc", FNM_NOESCAPE) && y ("*x", ".x", 0) && n ("*x", ".x", FNM_PERIOD) && 1)); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_fnmatch_works=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_fnmatch_works=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_fnmatch_works" >&5 echo "${ECHO_T}$ac_cv_func_fnmatch_works" >&6 if test $ac_cv_func_fnmatch_works = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_FNMATCH 1 _ACEOF fi echo "$as_me:$LINENO: checking for working memcmp" >&5 echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6 if test "${ac_cv_func_memcmp_working+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_memcmp_working=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* Some versions of memcmp are not 8-bit clean. */ char c0 = 0x40, c1 = 0x80, c2 = 0x81; if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) exit (1); /* The Next x86 OpenStep bug shows up only when comparing 16 bytes or more and with at least one buffer not starting on a 4-byte boundary. William Lewis provided this test program. */ { char foo[21]; char bar[21]; int i; for (i = 0; i < 4; i++) { char *a = foo + i; char *b = bar + i; strcpy (a, "--------01111111"); strcpy (b, "--------10000000"); if (memcmp (a, b, 16) >= 0) exit (1); } exit (0); } ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_memcmp_working=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_memcmp_working=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6 test $ac_cv_func_memcmp_working = no && case $LIBOBJS in "memcmp.$ac_objext" | \ *" memcmp.$ac_objext" | \ "memcmp.$ac_objext "* | \ *" memcmp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;; esac for ac_header in stdlib.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getpagesize do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for working mmap" >&5 echo $ECHO_N "checking for working mmap... $ECHO_C" >&6 if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_mmap_fixed_mapped=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default /* malloc might have been renamed as rpl_malloc. */ #undef malloc /* Thanks to Mike Haertel and Jim Avera for this test. Here is a matrix of mmap possibilities: mmap private not fixed mmap private fixed at somewhere currently unmapped mmap private fixed at somewhere already mapped mmap shared not fixed mmap shared fixed at somewhere currently unmapped mmap shared fixed at somewhere already mapped For private mappings, we should verify that changes cannot be read() back from the file, nor mmap's back from the file at a different address. (There have been systems where private was not correctly implemented like the infamous i386 svr4.0, and systems where the VM page cache was not coherent with the file system buffer cache like early versions of FreeBSD and possibly contemporary NetBSD.) For shared mappings, we should conversely verify that changes get propagated back to all the places they're supposed to be. Grep wants private fixed already mapped. The main things grep needs to know about mmap are: * does it exist and is it safe to write into the mmap'd area * how to use it (BSD variants) */ #include #include #if !STDC_HEADERS && !HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ #if !HAVE_GETPAGESIZE /* Assume that all systems that can run configure have sys/param.h. */ # if !HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # if HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ int main () { char *data, *data2, *data3; int i, pagesize; int fd; pagesize = getpagesize (); /* First, make a file with some known garbage in it. */ data = (char *) malloc (pagesize); if (!data) exit (1); for (i = 0; i < pagesize; ++i) *(data + i) = rand (); umask (0); fd = creat ("conftest.mmap", 0600); if (fd < 0) exit (1); if (write (fd, data, pagesize) != pagesize) exit (1); close (fd); /* Next, try to mmap the file at a fixed address which already has something else allocated at it. If we can, also make sure that we see the same garbage. */ fd = open ("conftest.mmap", O_RDWR); if (fd < 0) exit (1); data2 = (char *) malloc (2 * pagesize); if (!data2) exit (1); data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) exit (1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) exit (1); /* Finally, make sure that changes to the mapped area do not percolate back to the file as seen by read(). (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = (char *) malloc (pagesize); if (!data3) exit (1); if (read (fd, data3, pagesize) != pagesize) exit (1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) exit (1); close (fd); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_mmap_fixed_mapped=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_mmap_fixed_mapped=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6 if test $ac_cv_func_mmap_fixed_mapped = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_MMAP 1 _ACEOF fi rm -f conftest.mmap echo "$as_me:$LINENO: checking for function prototypes" >&5 echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6 if test "$ac_cv_prog_cc_stdc" != no; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define PROTOTYPES 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define __PROTOTYPES 1 _ACEOF else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi echo "$as_me:$LINENO: checking whether setvbuf arguments are reversed" >&5 echo $ECHO_N "checking whether setvbuf arguments are reversed... $ECHO_C" >&6 if test "${ac_cv_func_setvbuf_reversed+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_func_setvbuf_reversed=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include # if PROTOTYPES int (setvbuf) (FILE *, int, char *, size_t); # endif int main () { char buf; return setvbuf (stdout, _IOLBF, &buf, 1); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include # if PROTOTYPES int (setvbuf) (FILE *, int, char *, size_t); # endif int main () { char buf; return setvbuf (stdout, &buf, _IOLBF, 1); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then # It compiles and links either way, so it must not be declared # with a prototype and most likely this is a K&R C compiler. # Try running it. if test "$cross_compiling" = yes; then : # Assume setvbuf is not reversed when cross-compiling. else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { /* This call has the arguments reversed. A reversed system may check and see that the address of buf is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ char buf; if (setvbuf (stdout, _IOLBF, &buf, 1) != 0) exit (1); putchar ('\r'); exit (0); /* Non-reversed systems SEGV here. */ ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_setvbuf_reversed=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) rm -f core *.core fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi ac_cv_func_setvbuf_reversed=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_setvbuf_reversed" >&5 echo "${ECHO_T}$ac_cv_func_setvbuf_reversed" >&6 if test $ac_cv_func_setvbuf_reversed = yes; then cat >>confdefs.h <<\_ACEOF #define SETVBUF_REVERSED 1 _ACEOF fi for ac_func in getcwd strdup strstr strcspn strtol do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in gethostname gethostbyname socket inet_aton herror inet_addr do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in scandir alphasort do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in madvise do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_safe_struct=`echo "tm" | sed 'y%./+-%__p_%'` ac_safe_member=`echo "tm_gmtoff" | sed 'y%./+-%__p_%'` ac_safe_all="ac_cv_struct_${ac_safe_struct}_has_${ac_safe_member}" ac_uc_define=STRUCT_`echo "${ac_safe_struct}_HAS_${ac_safe_member}" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` echo "$as_me:$LINENO: checking for tm.tm_gmtoff" >&5 echo $ECHO_N "checking for tm.tm_gmtoff... $ECHO_C" >&6 if eval "test \"\${$ac_safe_all+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x" = "x"; then defineit="= 0" elif test "x" = "xno"; then defineit="" else defineit="" fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif int main () { struct tm testit; testit.tm_gmtoff $defineit; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "${ac_safe_all}=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "${ac_safe_all}=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if eval "test \"x$`echo ${ac_safe_all}`\" = \"xyes\""; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<_ACEOF #define $ac_uc_define 1 _ACEOF else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$ac_cv_struct_tm_has_tm_gmtoff" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TM_GMTOFF 1 _ACEOF fi ac_safe_struct=`echo "tm" | sed 'y%./+-%__p_%'` ac_safe_member=`echo "tm_zone" | sed 'y%./+-%__p_%'` ac_safe_all="ac_cv_struct_${ac_safe_struct}_has_${ac_safe_member}" ac_uc_define=STRUCT_`echo "${ac_safe_struct}_HAS_${ac_safe_member}" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` echo "$as_me:$LINENO: checking for tm.tm_zone" >&5 echo $ECHO_N "checking for tm.tm_zone... $ECHO_C" >&6 if eval "test \"\${$ac_safe_all+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x" = "x"; then defineit="= 0" elif test "x" = "xno"; then defineit="" else defineit="" fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif int main () { struct tm testit; testit.tm_zone $defineit; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "${ac_safe_all}=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "${ac_safe_all}=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if eval "test \"x$`echo ${ac_safe_all}`\" = \"xyes\""; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<_ACEOF #define $ac_uc_define 1 _ACEOF else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$ac_cv_struct_tm_has_tm_zone" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_TM_ZONE 1 _ACEOF fi ac_safe_struct=`echo "sockaddr_in" | sed 'y%./+-%__p_%'` ac_safe_member=`echo "sin_len" | sed 'y%./+-%__p_%'` ac_safe_all="ac_cv_struct_${ac_safe_struct}_has_${ac_safe_member}" ac_uc_define=STRUCT_`echo "${ac_safe_struct}_HAS_${ac_safe_member}" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` echo "$as_me:$LINENO: checking for sockaddr_in.sin_len" >&5 echo $ECHO_N "checking for sockaddr_in.sin_len... $ECHO_C" >&6 if eval "test \"\${$ac_safe_all+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x" = "x"; then defineit="= 0" elif test "x" = "xno"; then defineit="" else defineit="" fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct sockaddr_in testit; testit.sin_len $defineit; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "${ac_safe_all}=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "${ac_safe_all}=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if eval "test \"x$`echo ${ac_safe_all}`\" = \"xyes\""; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<_ACEOF #define $ac_uc_define 1 _ACEOF else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$ac_cv_struct_sockaddr_in_has_sin_len" = "yes"; then cat >>confdefs.h <<\_ACEOF #define HAVE_SIN_LEN 1 _ACEOF fi if test $ac_cv_func_scandir = no; then # scandir not defined, add it SCANDIR="scandir.o" fi if test $ac_cv_func_alphasort = no; then # alphasort not defined, add it ALPHASORT="alphasort.o" fi if test $ac_cv_func_strdup = no -o $ac_cv_func_strstr = no; then # strdup or strstr not defined STRUTIL="strutil.o" fi if test -n "$GCC"; then test -n "$GCC" && CFLAGS="$CFLAGS -pipe" echo "$as_me:$LINENO: checking compile and link profiling code" >&5 echo $ECHO_N "checking compile and link profiling code... $ECHO_C" >&6 # Check whether --enable-profiling or --disable-profiling was given. if test "${enable_profiling+set}" = set; then enableval="$enable_profiling" if test "$enableval" = "yes" ; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 CFLAGS="$CFLAGS -pg" LDFLAGS="$LDFLAGS -g -pg" else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi; fi echo "$as_me:$LINENO: checking whether to enable gunzip support" >&5 echo $ECHO_N "checking whether to enable gunzip support... $ECHO_C" >&6 # Check whether --enable-gunzip or --disable-gunzip was given. if test "${enable_gunzip+set}" = set; then enableval="$enable_gunzip" if test "$enableval" = "yes" ; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 # Extract the first word of "gunzip", so it can be a program name with args. set dummy gunzip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_GUNZIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $GUNZIP in [\\/]* | ?:[\\/]*) ac_cv_path_GUNZIP="$GUNZIP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GUNZIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done ;; esac fi GUNZIP=$ac_cv_path_GUNZIP if test -n "$GUNZIP"; then echo "$as_me:$LINENO: result: $GUNZIP" >&5 echo "${ECHO_T}$GUNZIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi cat >>confdefs.h <<_ACEOF #define GUNZIP "$ac_cv_path_GUNZIP" _ACEOF else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 # Extract the first word of "gunzip", so it can be a program name with args. set dummy gunzip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_GUNZIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $GUNZIP in [\\/]* | ?:[\\/]*) ac_cv_path_GUNZIP="$GUNZIP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GUNZIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done ;; esac fi GUNZIP=$ac_cv_path_GUNZIP if test -n "$GUNZIP"; then echo "$as_me:$LINENO: result: $GUNZIP" >&5 echo "${ECHO_T}$GUNZIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi cat >>confdefs.h <<_ACEOF #define GUNZIP "$ac_cv_path_GUNZIP" _ACEOF fi; echo "$as_me:$LINENO: checking whether to enable access control support" >&5 echo $ECHO_N "checking whether to enable access control support... $ECHO_C" >&6 # Check whether --enable-access-control or --disable-access-control was given. if test "${enable_access_control+set}" = set; then enableval="$enable_access_control" if test "$enableval" = "yes" ; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 CFLAGS="$CFLAGS -DACCESS_CONTROL" ACCESSCONTROL_SOURCE="access.c" else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi; echo "$as_me:$LINENO: checking whether to compile and link debugging code" >&5 echo $ECHO_N "checking whether to compile and link debugging code... $ECHO_C" >&6 # Check whether --enable-debug or --disable-debug was given. if test "${enable_debug+set}" = set; then enableval="$enable_debug" if test "$enableval" = "yes" ; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 LDFLAGS="$LDFLAGS -g" test -n "$GCC" && CFLAGS="$CFLAGS -Wall" else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 LDFLAGS="$LDFLAGS -g" test -n "$GCC" && CFLAGS="$CFLAGS -Wall" fi; echo "$as_me:$LINENO: checking whether to disable verbose/debug logging" >&5 echo $ECHO_N "checking whether to disable verbose/debug logging... $ECHO_C" >&6 # Check whether --enable-verbose or --disable-verbose was given. if test "${enable_verbose+set}" = set; then enableval="$enable_verbose" if test "$enableval" = "yes" ; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else CFLAGS="$CFLAGS -DDISABLE_DEBUG" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 fi; echo "$as_me:$LINENO: checking whether to link with the Dmalloc memory debugger/profiler" >&5 echo $ECHO_N "checking whether to link with the Dmalloc memory debugger/profiler... $ECHO_C" >&6 # Check whether --with-dmalloc or --without-dmalloc was given. if test "${with_dmalloc+set}" = set; then withval="$with_dmalloc" if test "$withval" = "yes"; then echo "$as_me:$LINENO: result: trying" >&5 echo "${ECHO_T}trying" >&6 echo "$as_me:$LINENO: checking for dmalloc_shutdown in -ldmalloc" >&5 echo $ECHO_N "checking for dmalloc_shutdown in -ldmalloc... $ECHO_C" >&6 if test "${ac_cv_lib_dmalloc_dmalloc_shutdown+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldmalloc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dmalloc_shutdown (); int main () { dmalloc_shutdown (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dmalloc_dmalloc_shutdown=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dmalloc_dmalloc_shutdown=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dmalloc_dmalloc_shutdown" >&5 echo "${ECHO_T}$ac_cv_lib_dmalloc_dmalloc_shutdown" >&6 if test $ac_cv_lib_dmalloc_dmalloc_shutdown = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBDMALLOC 1 _ACEOF LIBS="-ldmalloc $LIBS" fi else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi; echo "$as_me:$LINENO: checking whether to link with the Electric Fence memory debugger" >&5 echo $ECHO_N "checking whether to link with the Electric Fence memory debugger... $ECHO_C" >&6 # Check whether --with-efence or --without-efence was given. if test "${with_efence+set}" = set; then withval="$with_efence" if test "$withval" = "yes"; then echo "$as_me:$LINENO: result: trying" >&5 echo "${ECHO_T}trying" >&6 echo "$as_me:$LINENO: checking for main in -lefence" >&5 echo $ECHO_N "checking for main in -lefence... $ECHO_C" >&6 if test "${ac_cv_lib_efence_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lefence $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_efence_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_efence_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_efence_main" >&5 echo "${ECHO_T}$ac_cv_lib_efence_main" >&6 if test $ac_cv_lib_efence_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBEFENCE 1 _ACEOF LIBS="-lefence $LIBS" fi else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi; case $host_os in *linux*) echo "$as_me:$LINENO: checking whether to enable the use of the sendfile(2) system call" >&5 echo $ECHO_N "checking whether to enable the use of the sendfile(2) system call... $ECHO_C" >&6 # Check whether --enable-sendfile or --disable-sendfile was given. if test "${enable_sendfile+set}" = set; then enableval="$enable_sendfile" if test "$enableval" = "no" ; then echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 for ac_header in sys/sendfile.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in sendfile do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done fi else echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 for ac_header in sys/sendfile.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in sendfile do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done fi; ;; *) ;; esac echo "$as_me:$LINENO: checking whether to use poll or select" >&5 echo $ECHO_N "checking whether to use poll or select... $ECHO_C" >&6 # Check whether --with-poll or --without-poll was given. if test "${with_poll+set}" = set; then withval="$with_poll" if test "$withval" = "yes" ; then echo "$as_me:$LINENO: result: trying poll" >&5 echo "${ECHO_T}trying poll" >&6 ac_x=1 else echo "$as_me:$LINENO: result: trying select" >&5 echo "${ECHO_T}trying select" >&6 ac_x=0 fi else echo "$as_me:$LINENO: result: trying select" >&5 echo "${ECHO_T}trying select" >&6 ac_x=0 fi; if test $ac_x = 1; then for ac_header in sys/poll.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in poll do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_poll" = "x"; then { { echo "$as_me:$LINENO: error: We attempted to find poll but could not. Please try again with --without-poll" >&5 echo "$as_me: error: We attempted to find poll but could not. Please try again with --without-poll" >&2;} { (exit 1); exit 1; }; } fi BOA_ASYNC_IO="poll" else for ac_header in sys/select.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in select do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* 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 char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_select" = "x"; then { { echo "$as_me:$LINENO: error: We attempted to find select but could not. Please try again with --with-poll" >&5 echo "$as_me: error: We attempted to find select but could not. Please try again with --with-poll" >&2;} { (exit 1); exit 1; }; } fi BOA_ASYNC_IO="select" fi if test "$BOA_ASYNC_IO" = "poll"; then ASYNCIO_SOURCE="poll.c" else ASYNCIO_SOURCE="select.c" fi # there are three scenarios # GNU make is installed as "make" # GNU make is installed as something else we detected # GNU make is not installed # Unfortunately, we can't deal with it one way or the other # Trying multiple AC_OUTPUT confuses autoconf, and using variables # *in* AC_OUTPUT is even worse. # *so*, make a default makefile that just forces make to call gmake # or whatever. ac_config_files="$ac_config_files Makefile src/Makefile docs/Makefile" cat >confcache <<\_ACEOF # 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, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # 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 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "docs/Makefile" ) CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@build@,$build,;t t s,@build_cpu@,$build_cpu,;t t s,@build_vendor@,$build_vendor,;t t s,@build_os@,$build_os,;t t s,@host@,$host,;t t s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@ifGNUmake@,$ifGNUmake,;t t s,@ALLSOURCES@,$ALLSOURCES,;t t s,@MAKE@,$MAKE,;t t s,@EGREP@,$EGREP,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@SCANDIR@,$SCANDIR,;t t s,@ALPHASORT@,$ALPHASORT,;t t s,@STRUTIL@,$STRUTIL,;t t s,@GUNZIP@,$GUNZIP,;t t s,@ACCESSCONTROL_SOURCE@,$ACCESSCONTROL_SOURCE,;t t s,@ASYNCIO_SOURCE@,$ASYNCIO_SOURCE,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_HEADER section. # # 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=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } # Do quote $f, to prevent DOS paths from being IFS'd. echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF # Transform confdefs.h into two sed scripts, `conftest.defines' and # `conftest.undefs', that substitutes the proper values into # config.h.in to produce config.h. The first handles `#define' # templates, and the second `#undef' templates. # 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.defines conftest.undefs # Using a here document instead of a string reduces the quoting nightmare. # Putting comments in sed scripts is not portable. # # `end' is used to avoid that the second main sed command (meant for # 0-ary CPP macros) applies to n-ary macro definitions. # See the Autoconf documentation for `clear'. cat >confdef2sed.sed <<\_ACEOF s/[\\&,]/\\&/g s,[\\$`],\\&,g t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times # the same #defines, which is useless. Nevertheless, we may not want to # sort them, since we want the *last* AC-DEFINE to be honored. uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs rm -f confdef2sed.sed # 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.undefs <<\_ACEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.defines >/dev/null do # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/defines.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines echo ' fi # grep' >>$CONFIG_STATUS echo >>$CONFIG_STATUS # Break up conftest.undefs because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #undef templates' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.undefs >/dev/null do # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/undefs.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail rm -f conftest.undefs mv conftest.tail conftest.undefs done rm -f conftest.undefs cat >>$CONFIG_STATUS <<\_ACEOF # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then echo "/* Generated by configure. */" >$tmp/config.h else echo "/* $ac_file. Generated by configure. */" >$tmp/config.h fi cat $tmp/in >>$tmp/config.h rm -f $tmp/in if test x"$ac_file" != x-; then if diff $ac_file $tmp/config.h >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } rm -f $ac_file mv $tmp/config.h $ac_file fi else cat $tmp/config.h rm -f $tmp/config.h fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi boa-0.94.14rc21/configure.in0000644000175000001440000001603607737713505016306 0ustar jnelsonusers00000000000000dnl $Id: configure.in,v 1.1.2.16 2003/10/05 04:00:05 jnelson Exp $ dnl Process this file with autoconf to produce a configure script. AC_INIT AC_CONFIG_SRCDIR([src/boa.c]) dnl Make config.h AC_CONFIG_HEADER(src/config.h) AC_CANONICAL_HOST dnl Checks for programs. AC_PROG_CC AC_PROG_CPP AC_C_VAR_FUNC CHECK_GNU_MAKE if test "x$_cv_gnu_make_command" != "x"; then MAKE="$_cv_gnu_make_command" ALLSOURCES="\$^" else MAKE="make" ALLSOURCES="\$(.ALLSRC)" fi AC_SUBST(ALLSOURCES) AC_SUBST(MAKE) dnl AC_MSG_RESULT($host) dnl i686-pc-linux-gnu dnl AC_MSG_RESULT($host_cpu) dnl i686 dnl AC_MSG_RESULT($host_vendor) dnl pc dnl AC_MSG_RESULT($host_os) dnl linux-gnu dnl i386-unknown-freebsd4.2 dnl Checks for libraries. # AC_SEARCH_LIBS (function, search-libs, [action-if-found], [action-if-not-found], [other-libraries]) AC_SEARCH_LIBS(socket, socket net) AC_SEARCH_LIBS(inet_aton, resolv) AC_SEARCH_LIBS(gethostname, nsl) AC_SEARCH_LIBS(gethostbyname, nsl) dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(fcntl.h sys/fcntl.h limits.h sys/time.h) AC_CHECK_HEADERS(getopt.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_UID_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM dnl AC_CHECK_TYPE(sa_family_t,unsigned short int) dnl AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) (includes, function-body, [action-if-found], [action-if-not-found]) AC_MSG_CHECKING(whether sa_family_t is defined) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[sa_family_t foo2;]])],[AC_MSG_RESULT(yes)],[ AC_MSG_RESULT(no) AC_DEFINE(DONT_HAVE_SA_FAMILY_T,1,[Define if sa_family_t is not defined]) ]) dnl Checks for library functions. AC_FUNC_FNMATCH AC_FUNC_MEMCMP AC_FUNC_MMAP AC_FUNC_SETVBUF_REVERSED AC_CHECK_FUNCS(getcwd strdup strstr strcspn strtol) AC_CHECK_FUNCS(gethostname gethostbyname socket inet_aton herror inet_addr) AC_CHECK_FUNCS(scandir alphasort) AC_CHECK_FUNCS(madvise) AC_CHECK_STRUCT_FOR([ #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif ],tm,tm_gmtoff) if test "$ac_cv_struct_tm_has_tm_gmtoff" = "yes"; then AC_DEFINE(HAVE_TM_GMTOFF,1,[Define if struct tm has a tm_gmtoff member]) fi AC_CHECK_STRUCT_FOR([ #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif ],tm,tm_zone) if test "$ac_cv_struct_tm_has_tm_zone" = "yes"; then AC_DEFINE(HAVE_TM_ZONE,1,[Define if struct tm has tm_zone member]) fi AC_CHECK_STRUCT_FOR([ #include #include ],sockaddr_in,sin_len) if test "$ac_cv_struct_sockaddr_in_has_sin_len" = "yes"; then AC_DEFINE(HAVE_SIN_LEN,1,[Define if struct sockaddr_in has sin_len member]) fi if test $ac_cv_func_scandir = no; then # scandir not defined, add it SCANDIR="scandir.o" AC_SUBST(SCANDIR) fi if test $ac_cv_func_alphasort = no; then # alphasort not defined, add it ALPHASORT="alphasort.o" AC_SUBST(ALPHASORT) fi if test $ac_cv_func_strdup = no -o $ac_cv_func_strstr = no; then # strdup or strstr not defined STRUTIL="strutil.o" AC_SUBST(STRUTIL) fi if test -n "$GCC"; then dnl if we are running gcc, use -pipe test -n "$GCC" && CFLAGS="$CFLAGS -pipe" AC_MSG_CHECKING(compile and link profiling code) AC_ARG_ENABLE(profiling, [ --enable-profiling Compile and link profiling code], [ if test "$enableval" = "yes" ; then AC_MSG_RESULT(yes) CFLAGS="$CFLAGS -pg" LDFLAGS="$LDFLAGS -g -pg" else AC_MSG_RESULT(no) fi ], [ AC_MSG_RESULT(no) ]) fi AC_MSG_CHECKING(whether to enable gunzip support) AC_ARG_ENABLE(gunzip, [ --disable-gunzip Disable use of gunzip], [ if test "$enableval" = "yes" ; then AC_MSG_RESULT(yes) AC_PATH_PROG(GUNZIP, gunzip) AC_DEFINE_UNQUOTED(GUNZIP, "$ac_cv_path_GUNZIP", [Define if gunzip can be found]) else AC_MSG_RESULT(no) fi ], [ AC_MSG_RESULT(yes) AC_PATH_PROG(GUNZIP, gunzip) AC_DEFINE_UNQUOTED(GUNZIP, "$ac_cv_path_GUNZIP", [Define if gunzip can be found]) ]) AC_MSG_CHECKING(whether to enable access control support) AC_ARG_ENABLE(access-control, [ --enable-access-control Enable support for allow/deny rules], [ if test "$enableval" = "yes" ; then AC_MSG_RESULT(yes) CFLAGS="$CFLAGS -DACCESS_CONTROL" ACCESSCONTROL_SOURCE="access.c" else AC_MSG_RESULT(no) fi ], [ AC_MSG_RESULT(no) ]) AC_SUBST(ACCESSCONTROL_SOURCE) AC_MSG_CHECKING(whether to compile and link debugging code) AC_ARG_ENABLE(debug, [ --disable-debug Do not compile and link debugging code], [ if test "$enableval" = "yes" ; then AC_MSG_RESULT(yes) LDFLAGS="$LDFLAGS -g" test -n "$GCC" && CFLAGS="$CFLAGS -Wall" else AC_MSG_RESULT(no) fi ], [ AC_MSG_RESULT(yes) LDFLAGS="$LDFLAGS -g" test -n "$GCC" && CFLAGS="$CFLAGS -Wall" ]) AC_MSG_CHECKING(whether to disable verbose/debug logging) AC_ARG_ENABLE(verbose, [ --disable-verbose Do not enable verbose/debug logging], [ if test "$enableval" = "yes" ; then AC_MSG_RESULT(yes) else CFLAGS="$CFLAGS -DDISABLE_DEBUG" AC_MSG_RESULT(no) fi ], [ AC_MSG_RESULT(yes) ]) AC_MSG_CHECKING(whether to link with the Dmalloc memory debugger/profiler) AC_ARG_WITH(dmalloc, [ --with-dmalloc Link with the Dmalloc memory debugger/profiler], [ if test "$withval" = "yes"; then AC_MSG_RESULT(trying) AC_CHECK_LIB(dmalloc, dmalloc_shutdown) else AC_MSG_RESULT(no) fi ], [ AC_MSG_RESULT(no) ]) AC_MSG_CHECKING(whether to link with the Electric Fence memory debugger) AC_ARG_WITH(efence, [ --with-efence Link with the Electric Fence memory debugger], [ if test "$withval" = "yes"; then AC_MSG_RESULT(trying) AC_CHECK_LIB(efence, main) else AC_MSG_RESULT(no) fi ], [ AC_MSG_RESULT(no) ]) case $host_os in *linux*) AC_MSG_CHECKING(whether to enable the use of the sendfile(2) system call) AC_ARG_ENABLE(sendfile, [ --disable-sendfile Disable the use of the sendfile(2) system call], [ if test "$enableval" = "no" ; then AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) AC_CHECK_HEADERS(sys/sendfile.h) AC_CHECK_FUNCS(sendfile) fi ], [ AC_MSG_RESULT(yes) AC_CHECK_HEADERS(sys/sendfile.h) AC_CHECK_FUNCS(sendfile) ]) ;; *) ;; esac POLL_OR_SELECT if test "$BOA_ASYNC_IO" = "poll"; then ASYNCIO_SOURCE="poll.c" else ASYNCIO_SOURCE="select.c" fi AC_SUBST(ASYNCIO_SOURCE) # there are three scenarios # GNU make is installed as "make" # GNU make is installed as something else we detected # GNU make is not installed # Unfortunately, we can't deal with it one way or the other # Trying multiple AC_OUTPUT confuses autoconf, and using variables # *in* AC_OUTPUT is even worse. # *so*, make a default makefile that just forces make to call gmake # or whatever. AC_CONFIG_FILES([Makefile src/Makefile docs/Makefile]) AC_OUTPUT boa-0.94.14rc21/contrib/0000755000175000001440000000000010207232236015406 5ustar jnelsonusers00000000000000boa-0.94.14rc21/contrib/README.chroot.solaris0000644000175000001440000001205007400223646021242 0ustar jnelsonusers00000000000000Boa chroot mini-HOWTO =================================================== by Liam Widdowson modified slightly by Jon Nelson The following is required to get Boa working in a chroot jail. Whilst this README is about Solaris specifically, the principals here will apply to other operating systems. The following assumptions are made: - Boa has been compiled and installed in /opt/boa - The chroot jail will be created in /var/www - A user and group 'www' have been created. Make sure you change the above directories to suit your system. Your boa.conf should look something like the following: ## begin config file Port 80 User www Group www # Note, these paths are used releative to the chroot jail. i.e /var/log is # really /var/www/var/log ErrorLog /var/log/error_log AccessLog /var/log/access_log DocumentRoot /var/www # You won't be able to access user home directories outside of the chroot # but you may replicate them into the chroot jail. You'll need a working # and valid /etc/passwd as well UserDir public_html DirectoryIndex index.html # this binary must exist in the chroot jail. Again, the path is relative. DirectoryMaker /usr/bin/boa_indexer KeepAliveMax 1000 KeepAliveTimeout 10 # this file must exist inside AND outside the chroot jail. MimeTypes /opt/boa/mime.types DefaultType text/plain ## end config file Once the configuration file is created, you must begin creating your chroot jail. A variety of libraries, timezone files, device files and other bits and pieces must be copied in order for this to work. Below is a ls -lR of what your jail should be at a minimum: .: total 10 drwxr-xr-x 2 root other 512 Jan 21 18:58 dev drwxr-xr-x 2 root other 512 Jan 21 19:20 etc drwxr-xr-x 3 root other 512 Jan 21 19:20 opt drwxr-xr-x 5 root other 512 Jan 21 19:08 usr drwxr-xr-x 4 root other 512 Jan 21 18:57 var ./dev: total 0 crw-rw-rw- 1 root other 13, 2 Jan 21 18:58 null crw-rw-rw- 1 root other 41, 0 Jan 21 18:58 udp ./etc: total 16 -r-xr-xr-x 1 root other 482 Jan 21 19:20 TIMEZONE -r--r--r-- 1 root other 74 Jan 21 19:20 hosts -rw-r--r-- 1 root other 1239 Jan 21 19:20 netconfig -rw-r--r-- 1 root other 1298 Jan 21 19:20 nsswitch.conf -r--r--r-- 1 root other 514 Jan 21 19:44 passwd -rw-r--r-- 1 root other 94 Jan 21 19:20 resolv.conf drwx------ 2 root other 512 Jan 21 19:20 boa ./boa: total 4 -rw-r--r-- 1 root other 1234 Jan 21 19:26 boa.conf ./opt: total 2 drwxr-xr-x 2 root other 512 Jan 21 19:26 boa ./opt/boa: total 20 -rw-r--r-- 1 root other 9964 Jan 21 19:26 mime.types ./usr: total 6 drwxr-xr-x 2 root other 512 Jan 21 19:21 bin drwxr-xr-x 2 root other 512 Jan 21 19:03 lib drwxr-xr-x 3 root other 512 Jan 21 19:08 share ./usr/bin: total 18 -rwxr-xr-x 1 root other 8944 Jan 21 19:23 boa_indexer ./usr/lib: total 5094 -rwxr-xr-x 1 root other 185020 Jan 21 19:03 ld.so.1 -rwxr-xr-x 1 root other 1126652 Jan 21 18:56 libc.so.1 -rwxr-xr-x 1 root other 4308 Jan 21 18:56 libdl.so.1 -rwxr-xr-x 1 root other 24968 Jan 21 18:56 libmp.so.2 -rwxr-xr-x 1 root other 883500 Jan 21 18:56 libnsl.so.1 -rwxr-xr-x 1 root other 265860 Jan 21 18:56 libresolv.so.2 -rwxr-xr-x 1 root other 70260 Jan 21 18:56 libsocket.so.1 ./usr/share: total 2 drwxr-xr-x 3 root other 512 Jan 21 19:08 lib ./usr/share/lib: total 2 drwxr-xr-x 3 root other 512 Jan 21 19:08 zoneinfo ./usr/share/lib/zoneinfo: total 2 drwxr-xr-x 2 root other 512 Jan 21 19:09 Australia ./usr/share/lib/zoneinfo/Australia: total 22 -rw-r--r-- 1 root other 785 Jan 21 19:09 ACT -rw-r--r-- 1 root other 785 Jan 21 19:09 Broken_Hill -rw-r--r-- 1 root other 663 Jan 21 19:09 LHI -rw-r--r-- 1 root other 785 Jan 21 19:09 NSW -rw-r--r-- 1 root other 104 Jan 21 19:09 North -rw-r--r-- 1 root other 160 Jan 21 19:09 Queensland -rw-r--r-- 1 root other 785 Jan 21 19:09 South -rw-r--r-- 1 root other 825 Jan 21 19:09 Tasmania -rw-r--r-- 1 root other 785 Jan 21 19:09 Victoria -rw-r--r-- 1 root other 150 Jan 21 19:09 West -rw-r--r-- 1 root other 785 Jan 21 19:09 Yancowinna ./var: total 4 drwxr-xr-x 2 www www 512 Jan 21 19:44 log drwxr-xr-x 2 root other 512 Jan 21 18:57 www ./var/log: total 4 -rw-r--r-- 1 root other 202 Jan 21 19:47 access_log -rw-r--r-- 1 root other 590 Jan 21 19:49 error_log ./var/www: total 0 Note, your boa binary should be kept outside of the chroot jail as they are not required. The commandline issued to boa requires "-r /var/www" which tells boa to chroot to /var/www before it does anything else, including reading its configuration file. That's all that's required. Start your new chrooting boa up and enjoy! boa-0.94.14rc21/contrib/rpm/0000755000175000001440000000000010207232236016204 5ustar jnelsonusers00000000000000boa-0.94.14rc21/contrib/rpm/boa.conf0000644000175000001440000001561407353774737017654 0ustar jnelsonusers00000000000000# Boa v0.94 configuration file # File format has not changed from 0.93 # File format has changed little from 0.92 # version changes are noted in the comments # # The Boa configuration file is parsed with a lex/yacc or flex/bison # generated parser. If it reports an error, the line number will be # provided; it should be easy to spot. The syntax of each of these # rules is very simple, and they can occur in any order. Where possible # these directives mimic those of NCSA httpd 1.3; I saw no reason to # introduce gratuitous differences. # $Id: boa.conf,v 1.2 2001/09/25 03:28:31 jnelson Exp $ # The "ServerRoot" is not in this configuration file. It can be compiled # into the server (see defines.h) or specified on the command line with # the -c option, for example: # # boa -c /usr/local/boa # Port: The port Boa runs on. The default port for http servers is 80. # If it is less than 1024, the server must be started as root. Port 80 # Listen: the Internet address to bind(2) to. If you leave it out, # it takes the behavior before 0.93.17.2, which is to bind to all # addresses (INADDR_ANY). You only get one "Listen" directive, # if you want service on multiple IP addresses, you have three choices: # 1. Run boa without a "Listen" directive # a. All addresses are treated the same; makes sense if the addresses # are localhost, ppp, and eth0. # b. Use the VirtualHost directive below to point requests to different # files. Should be good for a very large number of addresses (web # hosting clients). # 2. Run one copy of boa per IP address, each has its own configuration # with a "Listen" directive. No big deal up to a few tens of addresses. # Nice separation between clients. # The name you provide gets run through inet_aton(3), so you have to use dotted # quad notation. This configuration is too important to trust some DNS. #Listen 192.68.0.5 # User: The name or UID the server should run as. # Group: The group name or GID the server should run as. User nobody Group nobody # ServerAdmin: The email address where server problems should be sent. # Note: this is not currently used, except as an environment variable # for CGIs. #ServerAdmin root@localhost # ErrorLog: The location of the error log file. If this does not start # with /, it is considered relative to the server root. # Set to /dev/null if you don't want errors logged. # If unset, defaults to /dev/stderr ErrorLog /var/log/boa/error_log # Please NOTE: Sending the logs to a pipe ('|'), as shown below, # is somewhat experimental and might fail under heavy load. # "Usual libc implementations of printf will stall the whole # process if the receiving end of a pipe stops reading." #ErrorLog "|/usr/sbin/cronolog --symlink=/var/log/boa/error_log /var/log/boa/error-%Y%m%d.log" # AccessLog: The location of the access log file. If this does not # start with /, it is considered relative to the server root. # Comment out or set to /dev/null (less effective) to disable # Access logging. AccessLog /var/log/boa/access_log # Please NOTE: Sending the logs to a pipe ('|'), as shown below, # is somewhat experimental and might fail under heavy load. # "Usual libc implementations of printf will stall the whole # process if the receiving end of a pipe stops reading." #AccessLog "|/usr/sbin/cronolog --symlink=/var/log/boa/access_log /var/log/boa/access-%Y%m%d.log" # VerboseCGILogs: this is just a logical switch. # It simply notes the start and stop times of cgis in the error log # Comment out to disable. #VerboseCGILogs # ServerName: the name of this server that should be sent back to # clients if different than that returned by gethostname + gethostbyname #ServerName www.your.org.here # VirtualHost: a logical switch. # Comment out to disable. # Given DocumentRoot /var/www, requests on interface 'A' or IP 'IP-A' # become /var/www/IP-A. # Example: http://localhost/ becomes /var/www/127.0.0.1 # # Not used until version 0.93.17.2. This "feature" also breaks commonlog # output rules, it prepends the interface number to each access_log line. # You are expected to fix that problem with a postprocessing script. #VirtualHost # DocumentRoot: The root directory of the HTML documents. # Comment out to disable server non user files. DocumentRoot /home/httpd/html # UserDir: The name of the directory which is appended onto a user's home # directory if a ~user request is recieved. UserDir public_html # DirectoryIndex: Name of the file to use as a pre-written HTML # directory index. Please MAKE AND USE THESE FILES. On the # fly creation of directory indexes can be _slow_. # Comment out to always use DirectoryMaker DirectoryIndex index.html # DirectoryMaker: Name of program used to create a directory listing. # Comment out to disable directory listings. If both this and # DirectoryIndex are commented out, accessing a directory will give # an error (though accessing files in the directory are still ok). DirectoryMaker /usr/lib/boa/boa_indexer # DirectoryCache: If DirectoryIndex doesn't exist, and DirectoryMaker # has been commented out, the the on-the-fly indexing of Boa can be used # to generate indexes of directories. Be warned that the output is # extremely minimal and can cause delays when slow disks are used. # Note: The DirectoryCache must be writable by the same user/group that # Boa runs as. # DirectoryCache /var/spool/boa/dircache # KeepAliveMax: Number of KeepAlive requests to allow per connection # Comment out, or set to 0 to disable keepalive processing KeepAliveMax 1000 # KeepAliveTimeout: seconds to wait before keepalive connection times out KeepAliveTimeout 10 # MimeTypes: This is the file that is used to generate mime type pairs # and Content-Type fields for boa. # Set to /dev/null if you do not want to load a mime types file. # Do *not* comment out (better use AddType!) MimeTypes /etc/mime.types # DefaultType: MIME type used if the file extension is unknown, or there # is no file extension. DefaultType text/plain # AddType: adds types without editing mime.types # Example: AddType type extension [extension ...] # Uncomment the next line if you want .cgi files to execute from anywhere #AddType application/x-httpd-cgi cgi # Redirect, Alias, and ScriptAlias all have the same semantics -- they # match the beginning of a request and take appropriate action. Use # Redirect for other servers, Alias for the same server, and ScriptAlias # to enable directories for script execution. # Redirect allows you to tell clients about documents which used to exist in # your server's namespace, but do not anymore. This allows you to tell the # clients where to look for the relocated document. # Example: Redirect /bar http://elsewhere/feh/bar # Aliases: Aliases one path to another. # Example: Alias /path1/bar /path2/foo Alias /doc /usr/doc # ScriptAlias: Maps a virtual path to a directory for serving scripts # Example: ScriptAlias /htbin/ /www/htbin/ ScriptAlias /cgi-bin/ /home/httpd/cgi-bin/ boa-0.94.14rc21/contrib/rpm/boa.init-redhat0000644000175000001440000000141710056643263021112 0ustar jnelsonusers00000000000000#!/bin/sh # The following two lines enable chkconfig(1) to manipulate this script # chkconfig: 345 87 13 # description: Boa is a World Wide Web server. It is used to serve \ # HTML files and CGI. # processname: boa # config: /etc/boa/boa.conf # There is no pid file # Source function library. . /etc/rc.d/init.d/functions # See how we were called. case "$1" in start) echo -n "Starting boa: " daemon boa touch /var/lock/subsys/boa echo ;; stop) echo -n "Shutting down boa: " killproc boa echo rm -f /var/lock/subsys/boa rm -f /var/run/boa.pid ;; status) status boa ;; restart) $0 stop $0 start ;; reload) echo -n "Reloading boa: " killproc boa -HUP echo ;; *) echo "Usage: $0 {start|stop|restart|reload|status}" exit 1 esac exit 0 boa-0.94.14rc21/contrib/rpm/boa.init-suse0000644000175000001440000000563410056643263020627 0ustar jnelsonusers00000000000000#! /bin/sh # # Portions Copyright (c) 2003 SuSE Linux AG # Original Author: Peter Poeml # # Based on the init script for OpenVPN # ### BEGIN INIT INFO # Provides: boa # Required-Start: $local_fs $remote_fs $network # Required-Stop: $local_fs $remote_fs $network # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: Boa httpd # Description: Start Boa httpd ### END INIT INFO DAEMON="Boa" boa=/usr/sbin/boa #piddir=/var/run test -x $boa || exit 5 # Shell functions sourced from /etc/rc.status: # rc_check check and set local and overall rc status # rc_status check and set local and overall rc status # rc_status -v ditto but be verbose in local rc status # rc_status -v -r ditto and clear the local rc status # rc_failed set local and overall rc status to failed # rc_failed set local and overall rc status to # rc_reset clear local rc status (overall remains) # rc_exit exit appropriate to overall rc status . /etc/rc.status # First reset status of this service rc_reset # Return values acc. to LSB for all commands but status: # 0 - success # 1 - generic or unspecified error # 2 - invalid or excess argument(s) # 3 - unimplemented feature (e.g. "reload") # 4 - insufficient privilege # 5 - program is not installed # 6 - program is not configured # 7 - program is not running # # Note that starting an already running service, stopping # or restarting a not-running service as well as the restart # with force-reload (in case signalling is not supported) are # considered a success. shopt -s nullglob ret=true case "$1" in start) echo -n "Starting $DAEMON " $boa || ret=false # Remember status and be verbose $ret rc_status -v ;; stop) echo -n "Shutting down $DAEMON " ## Stop daemon with killproc(8) and if this fails ## set echo the echo return value. killproc -TERM $boa || ret=false # Remember status and be verbose $ret rc_status -v ;; try-restart) ## Do a restart only if the service was active before. ## Note: try-restart is now part of LSB (as of 1.9). ## RH has a similar command named condrestart. $0 status if test $? = 0; then $0 restart else rc_reset # Not running is not a failure. fi # Remember status and be quiet rc_status ;; restart) ## Stop the service and regardless of whether it was ## running or not, start it again. $0 stop sleep 3 $0 start # Remember status and be quiet rc_status ;; reload) killproc -HUP $boa || ret=false rc_status -v ;; reopen) killproc -USR1 $boa || ret=false rc_status -v ;; # status) # echo -n "Checking for $DAEMON: " # running=false # running=true # killproc -p $i -USR2 $boa || { rv=$?; ret=false; } # if $running; then # $ret # rc_status -v # echo Status written to /var/log/messages # else # rc_failed 3 # rc_status -v # fi # ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|reload|reopen}" exit 1 esac rc_exit boa-0.94.14rc21/contrib/rpm/boa.logrotate0000644000175000001440000000010607316001600020660 0ustar jnelsonusers00000000000000/var/log/boa/*_log { weekly compress copytruncate missingok } boa-0.94.14rc21/contrib/rpm/boa.spec0000644000175000001440000000604610061743555017640 0ustar jnelsonusers00000000000000%define is_suse %(test -e /etc/SuSE-release && echo 1 || echo 0) Summary: a single-tasking high performance http server Name: boa Version: 0.94.14rc20 Release: 1 Group: System Environment/Daemons Source: http://www.boa.org/boa-%{version}.tar.gz Copyright: GNU general public license Requires: /etc/mime.types %if is_suse Prereq: insserv %else Prereq: /sbin/chkconfig Provides: setup %endif Prereq: man, gzip Provides: webserver Buildroot: /usr/tmp/boa %description Boa is a single-tasking HTTP server. That means that unlike traditional web servers, it does not fork for each incoming connection, nor does it fork many copies of itself to handle multiple connections. It internally mul­ tiplexes all of the ongoing HTTP connections, and forks only for CGI programs (which must be separate processes.) Preliminary tests show Boa is more than twice as fast as Apache. Boa was created in 1991 by Paul Phillips . It is now being maintained and enhanced by Larry Doolittle and Jon Nelson . For more information (including installation instructions) examine the file docs/boa.txt or docs/boa.dvi, point your web browser to docs/boa.html, or visit the Boa homepage at http://www.boa.org/ %changelog * Thu Aug 6 2000 Jonathon D Nelson - revamp packaging based upon examples provided by Jules Stuifbergen and others %prep %setup -T -b 0 %build %configure make (cd docs && gzip -c boa.8 > boa.8.gz) (cd docs && make boa.html) %clean rm -rf $RPM_BUILD_ROOT %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr/sbin mkdir -p $RPM_BUILD_ROOT/home/httpd/{html,cgi-bin} mkdir -p $RPM_BUILD_ROOT/var/log/boa mkdir -p $RPM_BUILD_ROOT/usr/lib/boa mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man8 mkdir -p $RPM_BUILD_ROOT/etc/init.d mkdir -p $RPM_BUILD_ROOT/etc/boa install -m755 src/boa $RPM_BUILD_ROOT/usr/sbin/ install -m755 src/boa_indexer $RPM_BUILD_ROOT/usr/lib/boa/ install -m644 contrib/rpm/boa.conf $RPM_BUILD_ROOT/etc/boa/ %if is_suse install -m755 contrib/rpm/boa.init-suse $RPM_BUILD_ROOT/etc/init.d/boa %else install -m755 contrib/rpm/boa.init-redhat $RPM_BUILD_ROOT/etc/init.d/boa mkdir -p $RPM_BUILD_ROOT/etc/{boa,logrotate.d} install -m644 contrib/rpm/boa.logrotate $RPM_BUILD_ROOT/etc/logrotate.d/boa %endif mv docs/boa.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/ touch $RPM_BUILD_ROOT/var/log/boa/{error,access}_log %post %if is_suse /sbin/insserv --default /etc/init.d/boa %else /sbin/chkconfig boa reset %endif %preun /etc/init.d/boa stop %if is_suse /sbin/insserv --remove /etc/init.d/boa %else /sbin/chkconfig --del boa %endif %files %defattr(-,root,root) %dir /home/httpd/html %dir /home/httpd/cgi-bin %dir /var/log/boa %doc COPYING CREDITS CHANGES README docs/boa.html docs/boa_banner.png docs/boa.texi %doc /%{_mandir}/man8/* %dir /etc/boa %config /etc/boa/boa.conf %config /etc/init.d/boa %if is_suse %else %config /etc/logrotate.d/boa %endif %ghost %attr(600,nobody,nobody)/var/log/boa/error_log %ghost %attr(600,nobody,nobody)/var/log/boa/access_log /usr/sbin/boa /usr/lib/boa/boa_indexer boa-0.94.14rc21/docs/0000755000175000001440000000000010207232236014676 5ustar jnelsonusers00000000000000boa-0.94.14rc21/docs/.cvsignore0000644000175000001440000000005107614044316016702 0ustar jnelsonusers00000000000000Makefile *.xml *.html *.txt *.dvi *.info boa-0.94.14rc21/docs/Makefile.in0000644000175000001440000000153307542237232016756 0ustar jnelsonusers00000000000000# $Id: Makefile.in,v 1.1.2.3 2002/09/19 03:03:54 jnelson Exp $ srcdir = @srcdir@ VPATH = @srcdir@ all: boa.html boa.dvi boa.info boa.txt boa.info: boa.texi makeinfo --number-sections @ALLSOURCES@ boa.dvi: boa.texi texi2dvi --clean @ALLSOURCES@ boa.pdf: boa.texi texi2dvi --pdf --clean @ALLSOURCES@ boa.ps: boa.dvi dvips -o $@ @ALLSOURCES@ boa_toc.html: boa.texi texi2html -split_chapter -menu @ALLSOURCES@ boa.html: boa.texi makeinfo --html --number-sections --no-split -o - @ALLSOURCES@ | \ sed -e 's/Node:.*//' | sed -e 's/Next:.*//' | \ sed -e 's/Previous:.*//' | sed -e 's/Up:.*//' > $@ boa.txt: boa.texi makeinfo --no-headers --no-split -o $@ @ALLSOURCES@ clean: rm -f boa.{html,txt,dvi,ps,pdf,info} boa_*.html rm -f boa.{cp,fn,fns,ky,log,pg,toc,tp,vr,vrs,aux} *~ distclean: mrclean mrclean: clean rm -f Makefile boa-0.94.14rc21/docs/boa.80000644000175000001440000002103307617123136015540 0ustar jnelsonusers00000000000000.TH BOA 8 "Jan 22 2000" "Version 0.94" .SH NAME .B boa \- a single\-tasking high performance http server .SH SYNOPSIS .B boa .RB [ -c .IR server_root ] .RB [ -r .IR chroot ] .RB [ -d ] .SH DESCRIPTION Boa is a single-tasking HTTP server. That means that unlike traditional web servers, it does not fork for each incoming connection, nor does it fork many copies of itself to handle multiple connections. It internally multiplexes all of the ongoing HTTP connections, and forks only for CGI programs (which must be separate processes.) Preliminary tests show Boa is more than twice as fast as Apache. .PP The primary design goals of Boa are speed and security. Security, in the sense of "can't be subverted by a malicious user", not "fine grained access control and encrypted communications". Boa is not intended as a feature-packed server; if you want one of those, check out WN from John Franks. Modifications to Boa that improve its speed, security, robustness, and portability, are eagerly sought. Other features may be added if they can be achieved without hurting the primary goals. .SH OPTIONS .IP \fB-d\fR instruct Boa not to fork itself (non-daemonize). .IP "\fB-c \fIserver_root\fR" choose a server root overriding the default SERVER_ROOT #define in .I defines.h The server root must hold your local copy of the configuration file .IP "\fB-r \fIchroot\fR" instruct Boa where to chdir and chroot to. The chdir/chroot is done before the configuration file is read, or any log files are opened. .SH FILES .TP \fBboa.conf\fR \- the sole configuration file for Boa. The directives in this file are defined in the .B DIRECTIVES section. .TP \fBmime.types\fR \- the MimeTypes defines what Content-Type Boa will send in an HTTP/1.0 or better transaction. .SH DIRECTIVES The Boa configuration file is parsed with a lex/yacc or flex/bison generated parser. If it reports an error, the line number will be provided; it should be easy to spot. The syntax of each of these rules is very simple, and they can occur in any order. Where possible, these directives mimic those of NCSA httpd 1.3; We saw no reason to introduce gratuitous differences. .PP Note: the "ServerRoot" is not in this configuration file. It can be compiled into the server (see .I defines.h ) or specified on the command line with the .B -c option. The following directives are contained in the .I boa.conf file, and most, but not all, are required. .TP Port This is the port that Boa runs on. The default port for http servers is 80. If it is less than 1024, the server must be started as root. .TP User The name or UID the server should run as. For Boa to attempt this, the server must be started as root. .TP Group The group name or GID the server should run as. For Boa to attempt this, the server must be started as root. .TP ServerAdmin The email address where server problems should be sent. Note: this is not currently used. .TP PidFile Where to put the pid of the process. Comment out to write no pid file. Note: Because Boa drops privileges at startup, and the pid file is written by the UID/GID before doing so, Boa does not attempt removal of the pid file. .TP ErrorLog The location of the error log file. If this does not start with /, it is considered relative to the server root. Set to /dev/null if you don't want errors logged. .TP AccessLog The location of the access log file. If this does not start with /, it is considered relative to the server root. Comment out or set to /dev/null (less effective) to disable access logging. .TP VerboseCGILogs This is a logical switch and does not take any parameters. Comment out to disable. .TP CGILog The location of the CGI error log file. If this does not start with /, it is considered relative to the server root. If specified, this is the file that the stderr of CGIs is tied to, *instead* of to the ErrorLog. .TP CGIumask The CGIumask is set immediately before execution of the CGI. The default value is 027. The number must be interpretable unambiguously by the C function strtol. No base is specified, so one may use a hexadecimal, decimal, or octal number if it is prefixed accordingly. .TP ServerName The name of this server that should be sent back to clients if different than that returned by gethostname. .TP VirtualHost This is a logical switch and does not take any parameters. Comment out to disable. Given DocumentRoot /var/www, requests on interface 'A' or IP 'IP-A' become /var/www/IP-A. Example: http://localhost/ becomes /var/www/127.0.0.1 .TP VHostRoot The root location for all virtually hosted data Comment out to disable. Incompatible with 'Virtualhost' and 'DocumentRoot'!! Given VHostRoot /var/www, requests to host foo.bar.com, where foo.bar.com is ip a.b.c.d, become /var/www/a.b.c.d/foo.bar.com Hostnames are "cleaned", and must conform to the rules specified in rfc1034, which are be summarized here: Hostnames must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen. Hostnames must not exceed 63 characters in length. .TP DefaultVHost Define this in order to have a default hostname when the client does not specify one, if using VirtualHostName. If not specified, the word "default" will be used for compatibility with older clients. .TP DocumentRoot The root directory of the HTML documents. If this does not start with /, it is considered relative to the server root. .TP UserDir The name of the directory which is appended onto a user's home directory if a ~user request is received. .TP DirectoryIndex Name of the file to use as a pre-written HTML directory index. Please make and use these files. On the fly creation of directory indexes can be slow. .TP DirectoryMaker Name of the program used to generate on-the-fly directory listings. The program must take one or two command-line arguments, the first being the directory to index (absolute), and the second, which is optional, contains what Boa would have the "title" of the document be. Comment out if you don't want on the fly directory listings. If this does not start with /, it is considered relative to the server root. .TP KeepAliveMax Number of KeepAlive requests to allow per connection. Comment out, or set to 0 to disable keepalive processing. .TP KeepAliveTimeout Number of seconds to wait before keepalive connections time out. .TP MimeTypes The location of the .I mime.types file. If this does not start with /, it is considered relative to the server root. Set to /dev/null if you do not want to load a mime types file. Do *not* comment out (better use AddType!) .TP DefaultType MIME type used if the file extension is unknown, or there is no file extension. .TP AddType [extension...] Associates a MIME type with an extension or extensions. .TP Redirect, Alias, and ScriptAlias Redirect, Alias, and ScriptAlias all have the same semantics \-\- they match the beginning of a request and take appropriate action. Use Redirect for other servers, Alias for the same server, and ScriptAlias to enable directories for script execution. Redirect allows you to tell clients about documents which used to exist in your server's namespace, but do not anymore. This allows you tell the clients where to look for the relocated document. Alias aliases one path to another. Of course, symbolic links in the file system work fine too. ScriptAlias maps a virtual path to a directory for serving scripts. .PP Please see the included .I boa.conf for defaults and examples. .SH HISTORY Like the Linux kernel, even numbered versions are "stable", and odd numbered versions are "unstable", or rather, "development". Versions 0.91 and 0.91beta of Boa were released by Paul Phillips .PP Version 0.92 was released by Larry Doolittle on December 12, 1996. .PP Version 0.93 was the development version of 0.94. .PP Version 0.94 was released 22 Jan 2000. .SH BUGS There are probably bugs, but we are not aware of any at this time. .SH AUTHOR Boa was created by Paul Phillips . It is now being maintained and enhanced by Larry Doolittle and Jon Nelson . .PP Linux is the development platform at the moment, other OS's are known to work. If you'd like to contribute to this effort, contact Larry or Jon via e-mail. .SH LICENSE This program is distributed under the GNU General Public License, as noted in each source file. boa-0.94.14rc21/docs/boa.texi0000644000175000001440000007423407617123136016355 0ustar jnelsonusers00000000000000\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename boa.info @settitle The Boa HTTP Daemon @set UPDATED Last Updated: 10 Jan 2003 @set COPYPHRASE Copyright @copyright{} 1996-2003 Jon Nelson and Larry Doolittle @set VERSION $Revision: 1.5.2.10 $ @paragraphindent asis @iftex @parindent 0pt @end iftex @c @setchapternewpage odd @c %**end of header @iftex @titlepage @title The Boa HTTP Daemon @c @sp 2 @end iftex @ifinfo This file documents Boa, an HTTP daemon for UN*X like machines. @end ifinfo @html

The Boa HTTP Daemon

@end html @ifinfo @dircategory Networking @direntry * Boa: (boa). The Boa Webserver @end direntry @end ifinfo @comment node-name, next, previous, up @node Top, Introduction, , (dir) Welcome to the documentation for Boa, a high performance HTTP Server for UN*X-alike computers, covered by the @uref{Gnu_License,GNU General Public License}. The on-line, updated copy of this documentation lives at @uref{http://www.boa.org/,http://www.boa.org/} @sp 1 @center @value{COPYPHRASE} @center @value{UPDATED}, @value{VERSION} @iftex @end titlepage @contents @end iftex @menu * Introduction:: * Installation and Usage:: * Limits and Design Philosophy:: * Appendix:: -- Detailed Node Listing -- Installation * Files Used by Boa:: * Compile-Time and Command-Line Options:: * boa.conf Directives:: * Security:: Limits and Design Philosophy * Limits:: * Differences between Boa and other web servers:: * Unexpected Behavior:: Appendix * License:: * Acknowledgments:: * Reference Documents:: * Other HTTP Servers:: * Benchmarks:: * Tools:: * Authors:: @end menu @comment node-name, next, previous, up @node Introduction, Installation and Usage,top,top @chapter Introduction Boa is a single-tasking HTTP server. That means that unlike traditional web servers, it does not fork for each incoming connection, nor does it fork many copies of itself to handle multiple connections. It internally multiplexes all of the ongoing HTTP connections, and forks only for CGI programs (which must be separate processes), automatic directory generation, and automatic file gunzipping. Preliminary tests show Boa is capable of handling several thousand hits per second on a 300 MHz Pentium and dozens of hits per second on a lowly 20 MHz 386/SX. The primary design goals of Boa are speed and security. Security, in the sense of @emph{can't be subverted by a malicious user,} not @emph{fine grained access control and encrypted communications}. Boa is not intended as a feature-packed server; if you want one of those, check out WN (@uref{http://hopf.math.nwu.edu/}) from John Franks. Modifications to Boa that improve its speed, security, robustness, and portability, are eagerly sought. Other features may be added if they can be achieved without hurting the primary goals. Boa was created in 1991 by Paul Phillips (@email{psp@@well.com}). It is now being maintained and enhanced by Larry Doolittle (@email{ldoolitt@@boa.org}) and Jon Nelson (@email{jnelson@@boa.org}). Please see the acknowledgment section for further details. GNU/Linux is the development platform at the moment, other OS's are known to work. If you'd like to contribute to this effort, contact Larry or Jon via e-mail. @comment node-name, next, previous, up @node Installation and Usage, Limits and Design Philosophy, Introduction,top @chapter Installation and Usage Boa is currently being developed and tested on GNU/Linux/i386. The code is straightforward (more so than most other servers), so it should run easily on most modern Unix-alike platforms. Recent versions of Boa worked fine on FreeBSD, SunOS 4.1.4, GNU/Linux-SPARC, and HP-UX 9.0. Pre-1.2.0 GNU/Linux kernels may not work because of deficient mmap() implementations. @menu * Installation:: * Files Used by Boa:: * Compile-Time and Command-Line Options:: * Security:: @end menu @comment node-name, next, previous, up @node Installation,Files Used by Boa,,Installation and Usage @section Installation @enumerate @item Unpack @enumerate @item Choose, and cd into, a convenient directory for the package. @item @kbd{tar -xvzf boa-0.94.tar.gz}, or for those of you with an archaic (non-GNU) tar; @kbd{gzip -cd boa-0.94.tar.gz | tar -xvf -} @item Read the documentation. Really. @end enumerate @item Build @enumerate @item (optional) Change the default SERVER_ROOT by setting the #define at the top of src/defines.h @item Type @kbd{./configure} @item If the configure step was successful, type @kbd{make} @item Report any errors to the maintainers for resolution, or strike out on your own. @end enumerate @item Configure @enumerate @item Choose a server root. For a standard installation, /etc/boa is often used. @item Locate the sample configuration file in @emph{examples/boa.conf}, and copy it to the server root (/etc/boa/boa.conf) @item Choose a user and server port under which Boa can run. The traditional port is 80, and user @t{nobody} (create if you need to) is often a good selection for security purposes. If you don't have (or choose not to use) root privileges, you can not use port numbers less than 1024, nor can you switch user id. @item Choose locations for log files, CGI programs (if any), and the base of your URL tree. Make sure to create any leading directories. If you use the ones provided by the, make sure to create /var/log/boa/ @item Set the location of the @t{mime.types} file. @item Edit @emph{boa.conf} according to your choices above (this file documents itself). Read through this file to see what other features you can configure. @end enumerate @item Start @itemize @item Start Boa. If you didn't build the right SERVER_ROOT into the binary, you can specify it on the command line with the -c option (command line takes precedence). @example Example: ./boa -c /usr/local/boa @end example @end itemize @item Test @itemize @item At this point the server should run and serve documents. If not, check the error_log file for clues. @end itemize @item Install @itemize @item Copy the binary to a safe place, and put the invocation into your system startup scripts. Use the same -c option you used in your initial tests. @end itemize @end enumerate @comment node-name, next, previous, up @node Files Used by Boa, Compile-Time and Command-Line Options, Installation,Installation and Usage @section Files Used by Boa @ftable @file @item boa.conf This file is the sole configuration file for Boa. The directives in this file are defined in the DIRECTIVES section. @item mime.types The MimeTypes defines what Content-Type Boa will send in an HTTP/1.0 or better transaction. Set to /dev/null if you do not want to load a mime types file. Do *not* comment out (better use AddType!) @end ftable @comment node-name, next, previous, up @node Compile-Time and Command-Line Options, boa.conf Directives, Files Used by Boa,Installation and Usage @section Compile-Time and Command-Line Options @table @var @item SERVER_ROOT @itemx -c The default server root as #defined by @var{SERVER_ROOT} in @file{defines.h} can be overridden on the command line using the @option{-c} option. The server root must hold your local copy of the configuration file @file{boa.conf}. @example Example: /usr/sbin/boa -c /etc/boa @end example @end table @comment node-name, next, previous, up @node boa.conf Directives, Security, Compile-Time and Command-Line Options, (top) @section boa.conf Directives The Boa configuration file is parsed with a custom parser. If it reports an error, the line number will be provided; it should be easy to spot. The syntax of each of these rules is very simple, and they can occur in any order. Where possible, these directives mimic those of NCSA httpd 1.3; I (Paul Phillips) saw no reason to introduce gratuitous differences. Note: the "ServerRoot" is not in this configuration file. It can be compiled into the server (see @file{defines.h}) or specified on the command line with the @command{-c} option. The following directives are contained in the @file{boa.conf} file, and most, but not all, are required. @table @option @item Port This is the port that Boa runs on. The default port for http servers is 80. If it is less than 1024, the server must be started as root. @item Listen The Internet address to bind(2) to, in quadded-octet form (numbers). If you leave it out, it binds to all addresses (INADDR_ANY). The name you provide gets run through inet_aton(3), so you have to use dotted quad notation. This configuration is too important to trust some DNS. You only get one "Listen" directive, if you want service on multiple IP addresses, you have three choices: @enumerate @item Run boa without a "Listen" directive: @itemize @bullet @item All addresses are treated the same; makes sense if the addresses are localhost, ppp, and eth0. @item Use the VirtualHost directive below to point requests to different files. Should be good for a very large number of addresses (web hosting clients). @end itemize @item Run one copy of boa per IP address: @itemize @bullet @item Each instance has its own configuration with its own "Listen" directive. No big deal up to a few tens of addresses. Nice separation between clients. @end itemize @end enumerate @item BackLog BackLog sets the value sent to listen(2). The default value is whatever SO_MAXCONN is defined to. @item User The name or UID the server should run as. For Boa to attempt this, the server must be started as root. @item Group The group name or GID the server should run as. For Boa to attempt this, the server must be started as root. @item ServerAdmin The email address where server problems should be sent. Note: this is not currently used. @item ServerRoot This parameter is analogous to the '-c' command line option -- it sets a default server root. The server root is where Boa expects to find boa.conf, and from which all relative alias paths are constructed. @item UseLocaltime Tell Boa to output time in the local time zone instead of GMT (UTC). @item ErrorLog The location of the error log file. If this does not start with /, it is considered relative to the server root. Set to /dev/null if you don't want errors logged. @item AccessLog The location of the access log file. If this does not start with /, it is considered relative to the server root. Comment out or set to /dev/null (less effective) to disable access logging. @item CGILog The location of the CGI error log file. If this does not start with /, it is considered relative to the server root. If specified, this is the file that the stderr of CGIs is tied to, *instead* of to the ErrorLog. @item VerboseCGILogs This is a logical switch and does not take any parameters. Comment out to disable. All it does is switch on or off logging of when CGIs are launched and when the children return. @item ServerName The name of this server that should be sent back to clients if different than that returned by gethostname. @item VirtualHost This is a logical switch and does not take any parameters. Comment out to disable. Given DocumentRoot /var/www, requests on interface `A' or IP `IP-A' become /var/www/IP-A. Example: http://localhost/ becomes /var/www/127.0.0.1 @item VHostRoot The root location for all virtually hosted data. Comment out to disable. Incompatible with 'Virtualhost' and 'DocumentRoot'!! Given VHostRoot /var/www, requests to host foo.bar.com, where foo.bar.com is ip a.b.c.d, become /var/www/a.b.c.d/foo.bar.com Hostnames are "cleaned", and must conform to the rules specified in rfc1034, which are be summarized here: Hostnames must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen. Hostnames must not exceed 63 characters in length. @item DefaultVHost Define this in order to have a default hostname when the client does not specify one, if using VirtualHostName. If not specified, the word "default" will be used for compatibility with older clients. @item DocumentRoot The root directory of the HTML documents. If this does not start with /, it is considered relative to the server root. @item UserDir The name of the directory which is appended onto a user's home directory if a ~user request is received. @item DirectoryIndex Name of the file to use as a pre-written HTML directory index. Please make and use these files. On the fly creation of directory indexes can be slow. @item DirectoryMaker Name of the program used to generate on-the-fly directory listings. The program must take one or two command-line arguments, the first being the directory to index (absolute), and the second, which is optional, should be the "title" of the document be. Comment out if you don't want on the fly directory listings. If this does not start with /, it is considered relative to the server root. @item DirectoryCache DirectoryCache: If DirectoryIndex doesn't exist, and DirectoryMaker has been commented out, the the on-the-fly indexing of Boa can be used to generate indexes of directories. Be warned that the output is extremely minimal and can cause delays when slow disks are used. Note: The DirectoryCache must be writable by the same user/group that Boa runs as. @item PidFile Where to put the pid of the process. Comment out to write no pid file. Note: Because Boa drops privileges at startup, and the pid file is written by the UID/GID before doing so, Boa does not attempt removal of the pid file. @item KeepAliveMax Number of KeepAlive requests to allow per connection. Comment out, or set to 0 to disable keepalive processing. @item KeepAliveTimeout Number of seconds to wait before keepalive connections time out. @item MimeTypes The location of the mime.types file. If this does not start with /, it is considered relative to the server root. Comment out to avoid loading mime.types (better use AddType!) @item DefaultType MIME type used if the file extension is unknown, or there is no file extension. @item DefaultCharset If set, the default character set will be appended to the Content-Type for all 'text' mime types. @item AddType extension... Associates a MIME type with an extension or extensions. @item Redirect, Alias, and ScriptAlias Redirect, Alias, and ScriptAlias all have the same semantics -- they match the beginning of a request and take appropriate action. Use Redirect for other servers, Alias for the same server, and ScriptAlias to enable directories for script execution. @item Redirect allows you to tell clients about documents which used to exist in your server's namespace, but do not anymore. This allows you tell the clients where to look for the relocated document. @item Alias aliases one path to another. Of course, symbolic links in the file system work fine too. @item ScriptAlias maps a virtual path to a directory for serving scripts. @item SinglePostLimit If defined, the maximum number of bytes that a client may send in a POST request. The default is 1024*1024 bytes, or 1 megabyte. @item CGIPath CGIPath sets the string that is used for the 'PATH' environment variable for CGIs. The default is defined in defines.h. @item CGIumask The CGIumask is set immediately before execution of the CGI. The default value is 027. The number must be interpretable unambiguously by the C function strtol. No base is specified, so one may use a hexadecimal, decimal, or octal number if it is prefixed accordingly. @item MaxConnections MaxConnections defines the maximum number of concurrent connections that Boa will handle. Once Boa reaches this limit, it stops accepting connections until the number of active connections goes down. The default is the maximum number of available file descriptors. @item Allow, Deny Only supported if Boa is compiled with --enable-access-control. Allow and Deny allows pattern based access control using shell wildcards. The string the matching is performed on is the absolute filesystem filename. The Allow, Deny directives are processed in order until the first match is found, and are processed using fnmatch. @item Deny Disallow files matching @item Allow Allow files matching @end table @comment node-name, next, previous, up @node Security, , boa.conf Directives, Installation and Usage @section Security Boa has been designed to use the existing file system security. In @file{boa.conf}, the directives @emph{user} and @emph{group} determine who Boa will run as, if launched by root. By default, the user/group is nobody/nogroup. This allows quite a bit of flexibility. For example, if you want to disallow access to otherwise accessible directories or files, simply make them inaccessible to nobody/nogroup. If the user that Boa runs as is "boa" and the groups that "boa" belongs to include "web-stuff" then files/directories accessible by users with group "web-stuff" will also be accessible to Boa. The February 2000 hoo-rah from @uref{http://www.cert.org/advisories/CA-2000-02.html,CERT advisory CA-2000-02} has little to do with Boa. As of version 0.94.4, Boa's escaping rules have been cleaned up a little, but they weren't that bad before. The example CGI programs have been updated to show what effort is needed there. If you write, maintain, or use CGI programs under Boa (or any other server) it's worth your while to read and understand this advisory. The real problem, however, boils down to browser and web page designers emphasizing frills over content and security. The market leading browsers assume (incorrectly) that all web pages are trustworthy. @comment node-name, next, previous, up @node Limits and Design Philosophy,Appendix, Installation and Usage,top @chapter Limits and Design Philosophy There are many issues that become more difficult to resolve in a single tasking web server than in the normal forking model. Here is a partial list -- there are probably others that haven't been encountered yet. @menu * Limits:: * Differences between Boa and other web servers:: * Unexpected Behavior:: @end menu @comment node-name, next, previous, up @node Limits,Differences between Boa and other web servers,,Limits and Design Philosophy @section Limits @itemize @bullet @item Slow file systems The file systems being served should be much faster than the network connection to the HTTP requests, or performance will suffer. For instance, if a document is served from a CD-ROM, the whole server (including all other currently incomplete data transfers) will stall while the CD-ROM spins up. This is a consequence of the fact that Boa mmap()'s each file being served, and lets the kernel read and cache pages as best it knows how. When the files come from a local disk (the faster the better), this is no problem, and in fact delivers nearly ideal performance under heavy load. Avoid serving documents from NFS and CD-ROM unless you have even slower inbound net connections (e.g., POTS SLIP). @item DNS lookups Writing a nonblocking gethostbyaddr is a difficult and not very enjoyable task. Paul Phillips experimented with several methods, including a separate logging process, before removing hostname lookups entirely. There is a companion program with Boa @file{util/resolver.pl} that will postprocess the logfiles and replace IP addresses with hostnames, which is much faster no matter what sort of server you run. @item Identd lookups Same difficulties as hostname lookups; not included. Boa provides a REMOTE_PORT environment variable, in addition to REMOTE_ADDR, so that a CGI program can do its own ident. See the end of @t{examples/cgi-test.cgi}. @item Password file lookups via NIS If users are allowed to serve HTML from their home directories, password file lookups can potentially block the process. To lessen the impact, each user's home directory is cached by Boa so it need only be looked up once. @item Running out of file descriptors Since a file descriptor is needed for every ongoing connection (two for non-nph CGIs, directories, and automatic gunzipping of files), it is possible though highly improbable to run out of file descriptors. The symptoms of this conditions may vary with your particular Unix variant, but you will probably see log entries giving an error message for @t{accept}. Try to build your kernel to give an adequate number for your usage - GNU/Linux provides 256 out of the box, more than enough for most people. @end itemize @comment node-name, next, previous, up @node Differences between Boa and other web servers,Unexpected Behavior,Limits,Limits and Design Philosophy @section Differences between Boa and other web servers In the pursuit of speed and simplicity, some aspects of Boa differ from the popular web servers. In no particular order: @itemize @bullet @item @var{REMOTE_HOST} environment variable not set for CGI programs The @var{REMOTE_HOST} environment variable is not set for CGI programs, for reasons already described. This is easily worked around because the IP address is provided in the @var{REMOTE_ADDR} variable, so (if the CGI program actually cares) gethostbyaddr or a variant can be used. @item There are no server side includes (@acronym{SSI}) in Boa We don't like them, and they are too slow to parse. We will consider more efficient alternatives. @item There are no access control features Boa will follow symbolic links, and serve any file that it can read. The expectation is that you will configure Boa to run as user "nobody", and only files configured world readable will come out. If Boa is compiled with --enable-access-control, access control is supported using the Allow, Deny directives. @item No chroot option There is no option to run chrooted. If anybody wants this, and is willing to try out experimental code, contact the maintainers. @end itemize @comment node-name, next, previous, up @node Unexpected Behavior,,Differences between Boa and other web servers,Limits and Design Philosophy @section Unexpected Behavior @itemize @bullet @item SIGHUP handling Like any good server, Boa traps SIGHUP and rereads @file{boa.conf}. However, under normal circumstances, it has already given away permissions, so many items listed in @file{boa.conf} can not take effect. No attempt is made to change uid, gid, log files, or server port. All other configuration changes should take place smoothly. @item Relative URL handling Not all browsers handle relative URLs correctly. Boa will not cover up for this browser bug, and will typically report 404 Not Found for URL's containing odd combinations of "../" 's. Note: As of version 0.95.0 (unreleased) the URL parser has been rewritten and *does* correctly handle relative URLs. @end itemize @comment node-name, next, previous, up @node Appendix,,Limits and Design Philosophy,top @appendix Appendix @menu * License:: * Acknowledgments:: * Reference Documents:: * Other HTTP Servers:: * Benchmarks:: * Tools:: * Authors:: @end menu @comment node-name, next, previous, up @node License,Acknowledgments,,Appendix @section License This program is distributed under the @uref{http://www.gnu.org/copyleft/gpl.html,GNU General Public License}. as noted in each source file: @* @smallexample /* * Boa, an http server * Copyright (C) 1995 Paul Phillips * * 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 1, 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. * */ @end smallexample @comment node-name, next, previous, up @node Acknowledgments,Reference Documents,License,Appendix @section Acknowledgments Paul Phillips wrote the first versions of Boa, up to and including version 0.91. Version 0.92 of Boa was officially released December 1996 by Larry Doolittle. Version 0.93 was the development version of 0.94, which was released in February 2000. The Boa Webserver is currently (Feb 2000) maintained and enhanced by Larry Doolittle (@email{ldoolitt@@boa.org}) and Jon Nelson (@email{jnelson@@boa.org}). We would like to thank Russ Nelson (@email{nelson@@crynwr.com}) for hosting the @uref{http://www.boa.org/,web site}. We would also like to thank Paul Phillips for writing code that is worth maintaining and supporting. Many people have contributed to Boa, but instead of listing them here, their names and specific contributions have been listed in the @file{CREDITS} file. Paul Phillips records his acknowledgments as follows: @quotation Thanks to everyone in the WWW community, in general a great bunch of people. Special thanks to Clem Taylor (@email{}), who provided invaluable feedback on many of my ideas, and offered good ones of his own. Also thanks to John Franks, author of wn, for writing what I believe is the best webserver out there. @end quotation @comment node-name, next, previous, up @node Reference Documents,Other HTTP Servers,Acknowledgments,Appendix @section Reference Documents Links to documents relevant to @uref{http://www.boa.org/,Boa} development and usage. Incomplete, we're still working on this. NCSA has a decent @uref{http://hoohoo.ncsa.uiuc.edu/docs/Library.html,page} along these lines, too. Also see Yahoo's List @* @uref{http://www.yahoo.com/Computers_and_Internet/Software/Internet/World_Wide_Web/Servers/} @itemize @item W3O HTTP page @* @uref{http://www.w3.org/pub/WWW/Protocols/} @item RFC 1945 HTTP-1.0 (informational) @* @uref{http://ds.internic.net/rfc/rfc1945.txt} @item IETF Working Group Draft 07 of HTTP-1.1 @* @uref{http://www.w3.org/pub/WWW/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-07.txt} @item HTTP: A protocol for networked information @* @uref{http://www.w3.org/pub/WWW/Protocols/HTTP/HTTP2.html} @item The Common Gateway Interface (CGI) @* @uref{http://hoohoo.ncsa.uiuc.edu/cgi/overview.html} @item RFC 1738 URL syntax and semantics @* @uref{http://ds.internic.net/rfc/rfc1738.txt} @item RFC 1808 Relative URL syntax and semantics @* @uref{http://ds.internic.net/rfc/rfc1808.txt} @end itemize @comment node-name, next, previous, up @node Other HTTP Servers,Benchmarks,Reference Documents,Appendix @section Other HTTP Servers For Unix-alike platforms, with published source code. @itemize @item tiny/turbo/throttling httpd very similar to Boa, with a throttling feature @* @uref{http://www.acme.com/software/thttpd/} @item Roxen: based on ulpc interpreter, non-forking (interpreter implements threading), GPL'd @* @uref{http://www.roxen.com/} @item WN: featureful, GPL'd @* @uref{http://hopf.math.nwu.edu/} @item Apache: fast, PD @* @uref{http://www.apache.org/} @item NCSA: standard, legal status? @* @uref{http://hoohoo.ncsa.uiuc.edu/} @item CERN: standard, PD, supports proxy @* @uref{http://www.w3.org/pub/WWW/Daemon/Status.html} @item xs-httpd 2.0: small, fast, pseudo-GPL'd @* @uref{http://www.stack.nl/~sven/xs-httpd/} @item bozohttpd.tar.gz sources, in perl @* @uref{ftp://ftp.eterna.com.au/bozo/bsf/attware/bozohttpd.tar.gz} @item Squid is actually an "Internet Object Cache" @* @uref{http://squid.nlanr.net/Squid/} @end itemize Also worth mentioning is Zeus. It is commercial, with a free demo, so it doesn't belong on the list above. Zeus seems to be based on technology similar to Boa and thttpd, but with more bells and whistles. @* @uref{http://www.zeus.co.uk/products/server/} @comment node-name, next, previous, up @node Benchmarks,Tools,Other HTTP Servers,Appendix @section Benchmarks @itemize @item ZeusBench (broken link) @* @uref{http://www.zeus.co.uk/products/server/intro/bench2/zeusbench.shtml} @item WebBench (binary-ware) @* @uref{http://web1.zdnet.com/zdbop/webbench/webbench.html} @item WebStone @* @uref{http://www.mindcraft.com/benchmarks/webstone/} @item SpecWeb96 @* @uref{http://www.specbench.org/osg/web96/} @end itemize @comment node-name, next, previous, up @node Tools,Authors,Benchmarks,Appendix @section Tools @itemize @item Analog logfile analyzer @* @uref{http://www.statslab.cam.ac.uk/~sret1/analog/} @item wwwstat logfile analyzer @* @uref{http://www.ics.uci.edu/pub/websoft/wwwstat/} @item gwstat wwwstat postprocessor @* @uref{http://dis.cs.umass.edu/stats/gwstat.html} @item The Webalizer logfile analyzer @* @uref{http://www.usagl.net/webalizer/} @item cgiwrap @* @uref{http://www.umr.edu/~cgiwrap/} @item suEXEC (Boa would need to be ..umm.. "adjusted" to support this) @* @uref{http://www.apache.org/docs/suexec.html} @end itemize Note: References last checked: 06 October 1997 @comment node-name, next, previous, up @node Authors,,Tools,Appendix @section Authors @itemize @item Conversion from linuxdoc SGML to texinfo by Jon Nelson @item Conversion to linuxdoc SGML by Jon Nelson @item Original HTML documentation by Larry Doolittle @item @value{COPYPHRASE} @end itemize @c variable @c @printindex vr @c concept @c @printindex cp @c function @c @printindex fn @c key @c @printindex ky @c program @c @printindex pg @c data type @c @printindex tp @bye boa-0.94.14rc21/docs/boa_banner.png0000644000175000001440000001304007044710677017507 0ustar jnelsonusers00000000000000‰PNG  IHDRdŸ–EPLTE!)19BJRZcks{„Œ”œ¥­µ½ÆÎÖÞçï÷ÿ{„Œ”œ¥­µÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ†½ÉÜbKGDˆH-IDATxÚí]‹v£ºe,`H¡ç„ò&\ÈíôÿÿðbÉÆ²1I“IÛ¥«žÚÖ–,ËÔùÏ0Œãéùú ¯xçþr §ÓûûûŸç둯4 |Oä£xÊcä´£(X©žò—å}H^ö±¢,§Mêºy¾þÊ«ÇqH“d¿?HÓ´O¹¯Tþ¼¿ŸN €tO¹“4Uññ‘¿e‡Ói@& C3 ¥Èñ)·–®iªª(‹â 9k!* ODn+]×6M=±PQäÒB¬>ÄHÿ”[ȤÏ) Yv8Œ×YÈ/2ŸDaœ­}݆8ô÷VåM¤C@꺮ʲÈß.õ!ƒÃeŽí®±öñ™}ƒñѺ¼‰t½j!—ú.fºðwúíæ÷¹Dvì·þ´[ߺEùh]Þæn e)²Õ‡ mߨíÂÎà÷}™®o’°“?Z•·JY×XHëMª˜Öj¦Íp¶¶Ñ>¨‹²&_צKdgHD£,Ê–î ³Ÿ :e§¾É‡Ô¬o&ݱ‚âºÔÎß+êOÉéÝéÍžqû¤Ù3wè¦Æ! §÷"49!M„„íYáûpkbØÛc< g[¹Ã:˜‚pït‹îÑxØ(k“…¼3]&\ûÜáÝô)Ê÷u§Òí8¯°o¢éï k‡ìÓÓÄý@̵Ï%pÃ`è;¶…—úhˆ)Û,aå}msùÍìœÍâ'÷ M.äjÊú»‹j |ûÂA…¿qgS Õ2ÅNgdßüûºï|Ž#8æñ ÉnDZcÈÄiMRt,ØFˆFU[n2ÝŽˆã¼<UÊzÙH€j”€´.7€FE]¤4Ø®@ƒ:Mg\›†ã5‹øü™®a€e9%bàªø¬O»‘ø¡€¬QÖ˶(‹i9èÙꩇÊÞê¨]ÊgKØ f*8.ú‚o6ËZ “5æ{….Ú‰nTñu­{è:|"Yÿ8ù$e1þpRf!Gæ«'ΊÖÎ{|ëpCêñøÁ¤‰‘o6_ Ç+™Y~_¢yZ£ŒŸ)±ßç €q TZ0¸<ÏQ¨ï r'pS•„¡F€fIr¸%»àªÊ¯ñ">}¶àƲ@M‚O8‰ˆ¹ØÐ«©ñ—±ÔIEä‘€X)ëlØ‹Å9ñ®5rÐÔă« ]KvÑc©…T†ï³/ȵ”ÁídeÇÚÅwГa”á9ê` M¢Ýq] û×ò2WÑl9\„Å$³*Û Ëg8û¸ÜàÓ 1u&nÿ8ùeUìòwmw¬F!"z‚¨–t[0 ؉ø‚Σ^Œ_§!"“³+åŽ;\%Ȧñ åØéº8àlv²§²‚s.›rZôH@>e!ì`tç¨EдÏìãCƒšwOÅv "ˆ“Æé.‡·šµÛqÂë°á¾…:~ßíLë(Û“ê6“å´ïeHf–hýþ¨j¸ìÔ€Ñ ­%ÂÛ?q¥N=5 $Ÿ œœ*Õªª°Ë»¬3OVæÙáèÉ•zæ-e=4+ö9ÊêxC¯ª£+h eìk"uÈT(í´ÔY«ÆÄ!£eû–ä-£t”\ªÛœó*‰œ=Ú]ù\”…ˆôø²IÊ#§Ô¹,ÌßÝfàL<„q«#r—9„Íòéô;ŸÂ=sšŒ÷;æüÝ z`u£DF`ïÿ÷Uðøt.kÄj 0Y²O©.a„@ ¯97…´·²¨ÉÒ£Ãáljø4ò¢+ò! BÞ77ïûÙ\Ö\˜Õ[!ic®ÿ¢& n3/[K0ä¼r W`_VÉ"‘¿KìýËǬ™q 2éâV”u¾æ¤+ÊâRõÞj¾ˆŒÃ×FÒW6èˆË4‚©è~«I¶R³S¶"Hˆj!×QÖ?p“»`ßv'â•M@¢ÌvDÕ­$pJôŽÁô––”Å0õ¬^¶s× Õ-…z™öˆ»ž¯‡`E£‹ ?â–ýÄå ÃiÍ (aYÒÀ’~”sç®…TI/Q>¿–²°îƒQæ‰bøÃÈè·Cªn ì¬è· äŒjHoƒ’ºùIß|³OGŒ‚”¾ ¤³œ'þs¥¼q ‘ÁÃVñ»—›)e¶LäÐ* WFYÿB¿e€ÔÿEù ¨ºý„€ÔÐuB´ì½;¤“e!ƒ†ZÛŸ9Õ4YrÔáex­)|¾ËòÅ|$Iõ®•7K ‘q/ž-‚ ÀmüZ¹‹6¹2ÊÂò6ÓË®?Š%jÕ-dÄ,Âk.¿’n‡¡·¥ní¢SÞ©Áë hÅÔ'Iªwm2¦%¬&Sð´xÎ:C¸-ÓÓm‘&¤ ¨“ü×RSGÀ ^Ç!½ê–òoèmîDÍÜ›N˜rÓÚp‹˜Sˆ´®¡íÈJU@¨Þ0V¸÷¹„ÝKâ'4ïõ6!ÝýL]9ÆärPŒ©“‹£,P¸«:ù:ˆ†ÿ•ëÔŸsk„ºãÄ&ºs·l“ZQWëùÌ8÷[¾­X´MÚ"ÃÑc›U¥YN±^AÙå‰î QÃŒ+) úú? ¸ÑãÑC}ЪÛ×qÀoìXÛîFÚÑ|o¹ÖAE5|*°E èÚ5'|bY²`0’’<7]U¯z4ƒ±<ö•”†5mÑfpDòÊõ‡C¶ß•¤˜U‘óÈ0 ý5޹O'mpAÐò5Õð£¸{¾D%ŸÒ„èÕæq‰áþ‚ŒOÎÕ–õ.¡MÕU4³½2ÊŸî%þ+tÌôxÄÒݲ–U·¿Á¿ ƒô>2‚ðá0oíf¦ˆHiÈ ¶Õr’ŠjÅÆ!1­- ]ª Ñ@rÐlà †4'©;Íl¯¤¬W~éñÆ-„M.+U·XÞQ }:jÕ‰Ëî_oCÄ4i5¨IÉ!‰Ú`,‹¯ptófYMz§uÎ\ï³´>áÌZâÔu É”Ür˜r¼ÖCñk£¬ßvÝbpu<31×O«nÊuZƒ¾;eª¹Â¥‚¤Ýв§ökvƒàbeÊõ­Œ&ʲ†J´³2«¬²š½TR·ÊUÁAvˆõJÊ«g ËCV*3†Ý|)´êvúŠ£VëÞ¾Ð⻞µåzñIm² Zcú^7Ø|C”±fËö01 Q–ÕÐâÞBëÄgÖ/*`’kJVê$ùFã¸{×eÝzÆ‘Ùé’Hª×:Ц½tD:ñ9ŸNÎA¬NñÚ4ñO~·"‡èÒb_⬠Ûv ÙŠd¯ôw‰¡áEže$y³º¬¿Hsqñ5é‹Öíè¨C·s3/äÂ#Ð2†å,I~étøÍ(+¾Œ¯”¾h_‡Cg±d–y“…P¶¾“$H [Ñú±¿eûæÂ=ήÔBhÇÕ:c!${)@§A´á’‰Ié…Á?½.‹(Ëš¢£dÒïÏ<”`ÉXt¦Ñ0¥Q™>ü饤gVêÌBç¢F{ØKv99«)OkáØnWýþ5±Üº"t×ê»Ú½Ñ>7%j †™_šF^ VoWýþ%±¯Ô‘BIDôéµ’ùõ]…Јװ™ñ]^Õ§,ÌÚR'ú4q?¶¬$ÙuX~dSÒÌ—a}ÈϦ,ÒWm[Jê3éë²h$žôÓÙ®DÄË ëvQÖׄЎeœNËáÈCðHI𖚬ٴè¸$µîaÈÖß²˜Ç“¬`… é _“f2ÒfF½Ú>Ì¡QQBå„]´j”Üú6<èªhÛÊD.´:bÞ†2Øö0u“{Q¹FÀJ5§¯ö½×¨·$²ïÓ\\Tìo_ Z¨‡5Š: $fˆ‰˜k¦[cýM‹éQ¯¶øgÕBne±Ðƒ–Ö1?'œýT¦ü* TŒÊ" 0Ê4µÝ¼$óSËèö´PšUV‹þ¥ÔІÔC“ÊùRí’nBÃZ=@Ó®ù[SÖn¶ÖL·áã}…ækÀ‡ùÀ¦}«5µ™'}™Í>D†>Ã>šëšá]\]=¨C¯Õ«ö¡˜-e%¥â‘?¡à×hù€—ûP蟗^C$žqóì°z¡ñ)ØÏ¢ FḬ̈=Ø *¤ºe•¸!!EׂÛT鈖´fXùR1â”ø bšˆê¾;rÅÅ}¢,Îݰ¤¾ž/±›kW§C0Äž¤·åÃõ# x?,ØÞü|1õq½Ú`¢5:÷ ¹•Ž(}§€®õÑÝZ­W¬Êak­£ I@Þ‡²f«÷ðiÉXïØÑ1Fz[–e¥ìa›^Ó©ýê¸g]dXëjÔ›f#4§âüÔZJ² 3ÕS¸Ñ¤Ï¿¡WÇ=ŽºÌêNQ¡f0F¸.¨Šƒ‡™å!àQ†ÞÞ9‚]IeoCŸü¾[5”.«yýN«âas÷Z÷^Žã;í<¸±:QÈð^¹¬“ +Aaþ^Ô]ÌÝÞ/Líyõ­}‡Åg^²ùYB×Ù*ÖU¸Ö‡j8+ä¨Wöº§&¢.t¸ eA,7/ÌI™!¿\aº=>‡WoC¸™Í¶_å³ym”­hxñ¹ÿCÓZ±fYFó”M„MµçsÝ…²øÊ°o$ìõ¹ÊåQ vÑæÅˆ½ˆ“ØÛ8Ú_6›¾‹ É6MAÎO—ÒöO-–5è»(O¦&´pˆw‰²|1ÜšìHøôYè?Äiƒe;˜ÛŽvkkÑÈRÈÂwóë²Ãå‰ê¼h<ÞÝN¬ë\‹u~˧¹Ý…²ä´ çö‡¤¿Ù…òM:o _æmnWܲ¡1ßêmÏ™ÜGXxÆRlãæá¹üfúnyGw¡¬ùÁ'´ŒRú„&4˜Êu»E{Ö#É‚ýŒÿÃf—{DY-Ð+&¦`Ì”P!ÆMCQ²¡Ù~Ù†ÀÍË‘<5 ø?䦔Uø2Ä`OöÂt~šH¥q+¼<·•xUD1ÌÏ»¦¬¿È(‹­Þ“i•àÒæ6D>>ò?O¹“\`!åßOï‡ÉçL?O¹§Èÿ§¾ ÈŸá)UlÿO}œ°Úïá×Sþ¦˜I£IBÃëùsóŸj~BÕ©ï½§| a€¬?~ë)ÿÄI#ˆ'ÐÆCtEXtSoftware@(#)ImageMagick 4.2.8 99/08/01 cristy@mystic.es.dupont.com‘º!¸*tEXtSignature6b04f98b834bd3b8b0d23752ae4e54afÕª> tEXtPage400x100+0+0©‘Ú‹IEND®B`‚boa-0.94.14rc21/examples/0000755000175000001440000000000010207232236015564 5ustar jnelsonusers00000000000000boa-0.94.14rc21/examples/boa.conf0000644000175000001440000002222107617123136017204 0ustar jnelsonusers00000000000000# Boa v0.94 configuration file # File format has not changed from 0.93 # File format has changed little from 0.92 # version changes are noted in the comments # # The Boa configuration file is parsed with a custom parser. If it # reports an error, the line number will be provided; it should be easy # to spot. The syntax of each of these rules is very simple, and they # can occur in any order. Where possible these directives mimic those # of NCSA httpd 1.3; I saw no reason to introduce gratuitous # differences. # $Id: boa.conf,v 1.3.2.6 2003/02/02 05:02:22 jnelson Exp $ # The "ServerRoot" is not in this configuration file. It can be # compiled into the server (see defines.h) or specified on the command # line with the -c option, for example: # # boa -c /usr/local/boa # Port: The port Boa runs on. The default port for http servers is 80. # If it is less than 1024, the server must be started as root. Port 80 # Listen: the Internet address to bind(2) to. If you leave it out, # it takes the behavior before 0.93.17.2, which is to bind to all # addresses (INADDR_ANY). You only get one "Listen" directive, # if you want service on multiple IP addresses, you have three choices: # 1. Run boa without a "Listen" directive # a. All addresses are treated the same; makes sense if the addresses # are localhost, ppp, and eth0. # b. Use the VirtualHost directive below to point requests to different # files. Should be good for a very large number of addresses (web # hosting clients). # 2. Run one copy of boa per IP address, each has its own configuration # with a "Listen" directive. No big deal up to a few tens of addresses. # Nice separation between clients. # The name you provide gets run through inet_aton(3), so you have to use dotted # quad notation. This configuration is too important to trust some DNS. #Listen 192.68.0.5 # User: The name or UID the server should run as. # Group: The group name or GID the server should run as. User nobody Group nogroup # ServerAdmin: The email address where server problems should be sent. # Note: this is not currently used, except as an environment variable # for CGIs. #ServerAdmin root@localhost # PidFile: where to put the pid of the process. # Comment out to write no pid file. # Note: Because Boa drops privileges at startup, and the # pid file is written by the UID/GID before doing so, Boa # does not attempt removal of the pid file. # PidFile /var/run/boa.pid # ErrorLog: The location of the error log file. If this does not start # with /, it is considered relative to the server root. # Set to /dev/null if you don't want errors logged. # If unset, defaults to /dev/stderr # Please NOTE: Sending the logs to a pipe ('|'), as shown below, # is somewhat experimental and might fail under heavy load. # "Usual libc implementations of printf will stall the whole # process if the receiving end of a pipe stops reading." #ErrorLog "|/usr/sbin/cronolog --symlink=/var/log/boa/error_log /var/log/boa/error-%Y%m%d.log" ErrorLog /var/log/boa/error_log # AccessLog: The location of the access log file. If this does not # start with /, it is considered relative to the server root. # Comment out or set to /dev/null (less effective) to disable. # Useful to set to /dev/stdout for use with daemontools. # Access logging. # Please NOTE: Sending the logs to a pipe ('|'), as shown below, # is somewhat experimental and might fail under heavy load. # "Usual libc implementations of printf will stall the whole # process if the receiving end of a pipe stops reading." #AccessLog "|/usr/sbin/cronolog --symlink=/var/log/boa/access_log /var/log/boa/access-%Y%m%d.log" AccessLog /var/log/boa/access_log # CGILog /var/log/boa/cgi_log # CGILog: The location of the CGI stderr log file. If this does not # start with /, it is considered relative to the server root. # The log file would contain any contents send to /dev/stderr # by the CGI. If this is commented out, it defaults to whatever # ErrorLog points. Set to /dev/null to disable CGI stderr logging. # Please NOTE: Sending the logs to a pipe ('|'), as shown below, # is somewhat experimental and might fail under heavy load. # "Usual libc implementations of printf will stall the whole # process if the receiving end of a pipe stops reading." #CGILog "|/usr/sbin/cronolog --symlink=/var/log/boa/cgi_log /var/log/boa/cgi-%Y%m%d.log" # CGIumask 027 (no mask for user, read-only for group, and nothing for user) # CGIumask 027 # The CGIumask is set immediately before execution of the CGI. # UseLocaltime: Logical switch. Uncomment to use localtime # instead of UTC time #UseLocaltime # VerboseCGILogs: this is just a logical switch. # It simply notes the start and stop times of cgis in the error log # Comment out to disable. #VerboseCGILogs # ServerName: the name of this server that should be sent back to # clients if different than that returned by gethostname + gethostbyname #ServerName www.your.org.here # VirtualHost: a logical switch. # Comment out to disable. # Given DocumentRoot /var/www, requests on interface 'A' or IP 'IP-A' # become /var/www/IP-A. # Example: http://localhost/ becomes /var/www/127.0.0.1 # # Not used until version 0.93.17.2. This "feature" also breaks commonlog # output rules, it prepends the interface number to each access_log line. # You are expected to fix that problem with a postprocessing script. #VirtualHost # VHostRoot: the root location for all virtually hosted data # Comment out to disable. # Incompatible with 'Virtualhost' and 'DocumentRoot'!! # Given VHostRoot /var/www, requests to host foo.bar.com, # where foo.bar.com is ip a.b.c.d, # become /var/www/a.b.c.d/foo.bar.com # Hostnames are "cleaned", and must conform to the rules # specified in rfc1034, which are be summarized here: # # Hostnames must start with a letter, end with a letter or digit, # and have as interior characters only letters, digits, and hyphen. # Hostnames must not exceed 63 characters in length. #VHostRoot /var/www # DefaultVHost # Define this in order to have a default hostname when the client does not # specify one, if using VirtualHostName. If not specified, the word # "default" will be used for compatibility with older clients. #DefaultVHost foo.bar.com # DocumentRoot: The root directory of the HTML documents. # Comment out to disable server non user files. DocumentRoot /var/www # UserDir: The name of the directory which is appended onto a user's home # directory if a ~user request is received. UserDir public_html # DirectoryIndex: Name of the file to use as a pre-written HTML # directory index. Please MAKE AND USE THESE FILES. On the # fly creation of directory indexes can be _slow_. # Comment out to always use DirectoryMaker DirectoryIndex index.html # DirectoryMaker: Name of program used to create a directory listing. # Comment out to disable directory listings. If both this and # DirectoryIndex are commented out, accessing a directory will give # an error (though accessing files in the directory are still ok). DirectoryMaker /usr/lib/boa/boa_indexer # DirectoryCache: If DirectoryIndex doesn't exist, and DirectoryMaker # has been commented out, the the on-the-fly indexing of Boa can be used # to generate indexes of directories. Be warned that the output is # extremely minimal and can cause delays when slow disks are used. # Note: The DirectoryCache must be writable by the same user/group that # Boa runs as. # DirectoryCache /var/spool/boa/dircache # KeepAliveMax: Number of KeepAlive requests to allow per connection # Comment out, or set to 0 to disable keepalive processing KeepAliveMax 1000 # KeepAliveTimeout: seconds to wait before keepalive connection times out KeepAliveTimeout 10 # MimeTypes: This is the file that is used to generate mime type pairs # and Content-Type fields for boa. # Set to /dev/null if you do not want to load a mime types file. # Do *not* comment out (better use AddType!) MimeTypes /etc/mime.types # DefaultType: MIME type used if the file extension is unknown, or there # is no file extension. DefaultType text/plain # CGIPath: The value of the $PATH environment variable given to CGI progs. CGIPath /bin:/usr/bin:/usr/local/bin # SinglePostLimit: The maximum allowable number of bytes in # a single POST. Default is normally 1MB. # AddType: adds types without editing mime.types # Example: AddType type extension [extension ...] # Uncomment the next line if you want .cgi files to execute from anywhere #AddType application/x-httpd-cgi cgi # Redirect, Alias, and ScriptAlias all have the same semantics -- they # match the beginning of a request and take appropriate action. Use # Redirect for other servers, Alias for the same server, and ScriptAlias # to enable directories for script execution. # Redirect allows you to tell clients about documents which used to exist in # your server's namespace, but do not anymore. This allows you to tell the # clients where to look for the relocated document. # Example: Redirect /bar http://elsewhere/feh/bar # Aliases: Aliases one path to another. # Example: Alias /path1/bar /path2/foo Alias /doc /usr/doc # ScriptAlias: Maps a virtual path to a directory for serving scripts # Example: ScriptAlias /htbin/ /www/htbin/ ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ boa-0.94.14rc21/examples/cgi-test.cgi0000754000175000001440000001151407551423624020006 0ustar jnelsonusers00000000000000#! /usr/bin/perl -wT # Remember that CGI programs have to close out the HTTP header # (with a pair of newlines), after giving the Content-type: # and any other relevant or available header information. # Unlike CGI programs running under Apache, CGI programs under Boa # should understand some simple HTTP options. The header (and the # double-newline) should not be printed if the incoming request was # in HTTP/0.9. Also, we should stop after the header if # REQUEST_METHOD == "HEAD". Under Apache, nph- programs also have # to worry about such stuff. # Feb 3, 2000 -- updated to support POST, and avoid passing # Malicious HTML Tags as described in CERT's CA-2000-02 advisory. # # 20 Aug 2002 -- Big internal changes, to support much more # than just a printout of the environment. Now the CGI can # do various, GET, isindex, and POST requests, and respond # to them as well. # 26 Sep 2002 -- Additional security paranoia by Landon Curt Noll # http://www.isthe.com/chongo/index.html # paranoia # delete $ENV{IFS}; delete $ENV{CDPATH}; delete $ENV{ENV}; delete $ENV{BASH_ENV}; #$ENV{PATH} = "/bin:/usr/bin"; $SIG{ALRM} = sub { die "\n

timeout on stdin

\n"; }; alarm(3); # initial setup # use strict; use POSIX qw(strftime getegid); # Print Content-type, if allowed # if (defined $ENV{"SERVER_PROTOCOL"} && $ENV{"SERVER_PROTOCOL"} !~ m{HTTP/0.9}i) { print "Content-type: text/html; charset=ISO-8859-1\r\n\r\n"; } # Nothing to do if just a HEAD request # if (defined $ENV{"REQUEST_METHOD"} && $ENV{"REQUEST_METHOD"} =~ /^HEAD$/i) { exit 0; } # Initial HTML lines # print "Boa CGI test\n"; print "

Boa CGI test

\n\n"; print "Date: ", strftime("%a %b %e %H:%M:%S %Y\n", localtime); print "

\n"; # Main form code # if (defined $ENV{"REQUEST_METHOD"}) { print "Method: $ENV{\"REQUEST_METHOD\"}\n"; } else { print "Method: <>\n"; } print "

\n"; print "\n"; print ""; print ""; print "\n"; print ""; print "
Basic GET Form:
"; print "
\n\ \ \ \
"; print "
Basic POST Form:
"; print "
\n\ \ \ \
"; print "
Sample ISINDEX form:
\n"; if (defined $ENV{"SCRIPT_NAME"}) { print "$ENV{\"SCRIPT_NAME\"}?param1+param2+param3\n"; } else { print "undefined SCRIPT_NAME\n"; } print "
\n"; if (defined $ENV{"QUERY_STRING"}) { print "

Query String: $ENV{\"QUERY_STRING\"}\n"; } else { print "

Query String: undefined QUERY_STRING\n"; } # Print the arguments # print "

\nArguments:\n

    \n"; if ($#ARGV >= 0) { while ($a=shift(@ARGV)) { $a=~s/&/&/g; $a=~s//>/g; print "
  1. $a\n"; } } print "
\n"; # Print environment list # print "

\nEnvironment:\n

    \n"; foreach my $i (keys %ENV) { $a=$ENV{$i}; $a=~s/&/&/g; $a=~s//>/g; $i=~s/&/&/g; $i=~s//>/g; print "
  • $i = $a\n"; } print "
\n"; # Print posted data, if any # my $line_cnt = 0; my $line; if (defined $ENV{REQUEST_METHOD} && $ENV{REQUEST_METHOD} =~ /POST/i) { print "Input stream:

\n"; while (defined($line = )) { if (++$line_cnt > 100) { print "

... ignoring the rest of the input data

"; last; } $line =~ s/&/&/g; $line =~ s//>/g; print "

" if $line_cnt == 1;
        print "$line";
    }
    print "
" if $line_cnt > 0; print "
\n"; } else { print "No input stream: (not POST)

\n"; } # Print a little additional server information # print "uid: $> gid: ", getegid(), "\n

\n"; # Disabled use of this call due to DoS attack potential # #if (defined $ENV{"QUERY_STRING"} && defined $ENV{"REMOTE_PORT"} && # $ENV{"QUERY_STRING"} =~ /ident/i && $ENV{"REMOTE_PORT"} =~ /^\s*$/) { # ## Uses idlookup-1.2 from Peter Eriksson ## ftp://coast.cs.purdue.edu/pub/tools/unix/ident/tools/idlookup-1.2.tar.gz ## Could use modification to timeout and trap stderr messages # my $a="idlookup ". # $ENV{"REMOTE_ADDR"}." ".$ENV{"REMOTE_PORT"}." ".$ENV{"SERVER_PORT"}; # my $b=qx/$a/; # print "ident output:

\n$b
\n"; #} # End of HTML # print "\nBoa http server\n"; print "\n"; # All done! :-) # exit 0; boa-0.94.14rc21/examples/nph-test.cgi0000754000175000001440000000334307047204400020017 0ustar jnelsonusers00000000000000#!/usr/bin/perl # Remember that CGI programs have to close out the HTTP header # (with a pair of newlines), after giving the Content-type: # and any other relevant or available header information. # This test program always reports success (200 OK), and # correctly uses SERVER_PROTOCOL and REQUEST_METHOD to decide # whether or not to send the headers and content. # Feb 3, 2000 -- updated to support POST, and avoid passing # Malicious HTML Tags as described in CERT's CA-2000-02 advisory. $now=`date`; chomp($now); if ($ENV{"SERVER_PROTOCOL"} ne "HTTP/0.9") { print "HTTP/1.0 200 OK\r\nDate: $now\r\n"; print "Connection: close\r\n"; print "Content-type: text/html; charset=ISO-8859-1\r\n\r\n"; } exit 0 if ($ENV{"REQUEST_METHOD"} eq "HEAD"); print "Boa nph-CGI test\n"; print "

Boa nph-CGI test

\n\n"; print "Date: $now\n"; print "

\n\n

    \n"; foreach (keys %ENV) { $a= $ENV{$_}; $a=~s/&/&/g; $a=~s//>/g; print "
  • $_ == $a\n"; } print "
\n"; if ($ENV{REQUEST_METHOD} eq "POST") { print "Input stream:

\n";
    while () {
	s/&/&/g;
	s//>/g;
        print "$_";
    }
    print "

\n"; } print "id: ", `id`, "\n

\n"; if ($ENV{"QUERY_STRING"}=~/ident/ && $ENV{"REMOTE_PORT"} ne "") { # Uses idlookup-1.2 from Peter Eriksson # ftp://coast.cs.purdue.edu/pub/tools/unix/ident/tools/idlookup-1.2.tar.gz # Could use modification to timeout and trap stderr messages $a="idlookup ". $ENV{"REMOTE_ADDR"}." ".$ENV{"REMOTE_PORT"}." ".$ENV{"SERVER_PORT"}; $b=qx/$a/; print "ident output:

\n$b
\n"; } print "\nBoa http server\n"; print "\n"; exit 0; boa-0.94.14rc21/examples/resolver.pl0000754000175000001440000000107006767076707020013 0ustar jnelsonusers00000000000000#!/usr/bin/perl # IP address resolver for Boa # If you want an "in place" change to the log file, # change the first line to #!/usr/local/bin/perl -i.bak # Otherwise, send the output of this program wherever you want: # resolver.pl access_log >access_log_resolved $AF_INET = 2; while(<>) { next unless (($ip, $rest) = /([\d\.]+) (.*)/o); if(!$hosts{$ip}) { $packed_ip = pack('C4', split(/\./, $ip)); $host = (gethostbyaddr($packed_ip, $AF_INET))[0]; $hosts{$ip} = ($host ? $host : $ip); } print "$hosts{$ip} $rest\n"; } boa-0.94.14rc21/extra_macros.m40000644000175000001440000001301407613060740016704 0ustar jnelsonusers00000000000000dnl Many of the following macros courtesy of: dnl http://www.gnu.org/software/ac-archive/ dnl dnl The Following macros courtesy of: dnl Installed_Packages/check_gnu_make.html dnl dnl Copyrights are by the individual authors, as listed. dnl License: GPL dnl dnl CHECK_GNU_MAKE() dnl dnl This macro searches for a GNU version of make. If a match is found, the dnl makefile variable `ifGNUmake' is set to the empty string, otherwise it is dnl set to "#". This is useful for including a special features in a Makefile, dnl which cannot be handled by other versions of make. The variable dnl _cv_gnu_make_command is set to the command to invoke GNU make if it exists, dnl the empty string otherwise. dnl dnl Here is an example of its use: dnl dnl Makefile.in might contain: dnl dnl # A failsafe way of putting a dependency rule into a makefile dnl $(DEPEND): dnl $(CC) -MM $(srcdir)/*.c > $(DEPEND) dnl dnl @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND))) dnl @ifGNUmake@ include $(DEPEND) dnl @ifGNUmake@ endif dnl dnl Then configure.in would normally contain: dnl dnl CHECK_GNU_MAKE() dnl AC_OUTPUT(Makefile) dnl dnl Then perhaps to cause gnu make to override any other make, we could do dnl something like this (note that GNU make always looks for GNUmakefile first): dnl dnl if ! test x$_cv_gnu_make_command = x ; then dnl mv Makefile GNUmakefile dnl echo .DEFAULT: > Makefile ; dnl echo \ $_cv_gnu_make_command \$@ >> Makefile; dnl fi dnl dnl Then, if any (well almost any) other make is called, and GNU make also exists, dnl then the other make wraps the GNU make. dnl dnl John Darrington dnl 1.3 (2002/01/04) dnl dnl Modified 18 Sep 2002 by Jon Nelson AC_DEFUN([CHECK_GNU_MAKE], [ AC_CACHE_CHECK( for GNU make, _cv_gnu_make_command, [_cv_gnu_make_command='' dnl Search all the common names for GNU make for a in "$MAKE" make gmake gnumake ; do if test -z "$a" ; then continue ; fi if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ); then _cv_gnu_make_command=$a break; fi done if test "x$_cv_gnu_make_command" = "x"; then _cv_gnu_make_command="Not found" fi ]) dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise if test "$_cv_gnu_make_command" != "Not found"; then ifGNUmake=''; else ifGNUmake='#'; _cv_gnu_make_command=''; fi AC_SUBST(ifGNUmake) ]) dnl AC_CHECK_STRUCT_FOR(INCLUDES,STRUCT,MEMBER,DEFINE,[no]) dnl 1.1 (2000/09/19) dnl Wes Hardaker dnl ---------------------------------------------------------- AC_DEFUN([AC_CHECK_STRUCT_FOR],[ ac_safe_struct=`echo "$2" | sed 'y%./+-%__p_%'` ac_safe_member=`echo "$3" | sed 'y%./+-%__p_%'` ac_safe_all="ac_cv_struct_${ac_safe_struct}_has_${ac_safe_member}" changequote(, )dnl ac_uc_define=STRUCT_`echo "${ac_safe_struct}_HAS_${ac_safe_member}" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` changequote([, ])dnl AC_MSG_CHECKING([for $2.$3]) AC_CACHE_VAL($ac_safe_all, [ if test "x$4" = "x"; then defineit="= 0" elif test "x$4" = "xno"; then defineit="" else defineit="$4" fi AC_TRY_COMPILE([ $1 ],[ struct $2 testit; testit.$3 $defineit; ], eval "${ac_safe_all}=yes", eval "${ac_safe_all}=no" ) ]) if eval "test \"x$`echo ${ac_safe_all}`\" = \"xyes\""; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED($ac_uc_define) else AC_MSG_RESULT(no) fi ]) dnl @synopsis AC_C_VAR_FUNC dnl dnl This macro tests if the C complier supports the C9X standard dnl __func__ indentifier. dnl dnl The new C9X standard for the C language stipulates that the dnl identifier __func__ shall be implictly declared by the compiler dnl as if, immediately following the opening brace of each function dnl definition, the declaration dnl dnl static const char __func__[] = "function-name"; dnl dnl appeared, where function-name is the name of the function where dnl the __func__ identifier is used. dnl dnl @author Christopher Currie AC_DEFUN([AC_C_VAR_FUNC], [AC_REQUIRE([AC_PROG_CC]) AC_CACHE_CHECK(whether $CC recognizes __func__, ac_cv_c_var_func, AC_TRY_COMPILE(, [int main() { char *s = __func__; }], AC_DEFINE(HAVE_FUNC,, [Define if the C complier supports __func__]) ac_cv_c_var_func=yes, ac_cv_c_var_func=no) ) ])dnl dnl Exports one of ac_cv_func_poll or ac_cv_func_select dnl Author - Jon Nelson dnl Copyright 2002 AC_DEFUN([POLL_OR_SELECT], [ AC_MSG_CHECKING(whether to use poll or select) AC_ARG_WITH(poll, [ --with-poll Use poll], [ if test "$withval" = "yes" ; then AC_MSG_RESULT(trying poll) ac_x=1 else AC_MSG_RESULT(trying select) ac_x=0 fi ], [ AC_MSG_RESULT(trying select) ac_x=0 ]) if test $ac_x = 1; then AC_CHECK_HEADERS(sys/poll.h) AC_CHECK_FUNCS(poll) if test "x$ac_cv_func_poll" = "x"; then AC_MSG_ERROR(We attempted to find poll but could not. Please try again with --without-poll) fi BOA_ASYNC_IO="poll" else AC_CHECK_HEADERS(sys/select.h) AC_CHECK_FUNCS(select) if test "x$ac_cv_func_select" = "x"; then AC_MSG_ERROR(We attempted to find select but could not. Please try again with --with-poll) fi BOA_ASYNC_IO="select" fi ] ) boa-0.94.14rc21/extras/0000755000175000001440000000000010207232236015254 5ustar jnelsonusers00000000000000boa-0.94.14rc21/extras/alphasort.c0000644000175000001440000000023607437602764017440 0ustar jnelsonusers00000000000000#include #include "compat.h" int alphasort(const struct dirent **a, const struct dirent **b) { return (strcmp((*a)->d_name, (*b)->d_name)); } boa-0.94.14rc21/extras/scandir.c0000644000175000001440000000460007437602764017065 0ustar jnelsonusers00000000000000/* -*- Mode: C; c-file-style: "gnu" -*- */ /* Copyright (c) 2000 Petter Reinholdtsen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * scandir.c -- if scandir() is missing, make a replacement */ #include #include #include #include #include "compat.h" /* * XXX This is a simple hack version which doesn't sort the data, and * just passes all unsorted. */ int scandir(const char *dir, struct dirent ***namelist, int (*select) (const struct dirent *), int (*compar) (const struct dirent **, const struct dirent **)) { DIR *d = opendir(dir); struct dirent *current; struct dirent **names; int count = 0; int pos = 0; int result = -1; if (NULL == d) return -1; while (NULL != readdir(d)) count++; names = malloc(sizeof (struct dirent *) * count); closedir(d); d = opendir(dir); if (NULL == d) return -1; while (NULL != (current = readdir(d))) { if (NULL == select || select(current)) { struct dirent *copyentry = malloc(current->d_reclen); memcpy(copyentry, current, current->d_reclen); names[pos] = copyentry; pos++; } } result = closedir(d); if (pos != count) names = realloc(names, sizeof (struct dirent *) * pos); *namelist = names; return pos; } boa-0.94.14rc21/extras/strutil.c0000644000175000001440000000142407371654706017151 0ustar jnelsonusers00000000000000/* * Name: strstr and strdup * * These are the standard library utilities. We define them here for * systems that don't have them. */ #ifndef HAVE_STRSTR char *strstr(char *s1, char *s2) { /* from libiberty */ char *p; int len = strlen(s2); if (*s2 == '\0') /* everything matches empty string */ return s1; for (p = s1; (p = strchr(p, *s2)) != NULL; p = strchr(p + 1, *s2)) { if (strncmp(p, s2, len) == 0) return (p); } return NULL; } #endif #ifndef HAVE_STRDUP char *strdup(char *s) { char *retval; retval = (char *) malloc(strlen(s) + 1); if (retval == NULL) { perror("boa: out of memory in strdup"); exit(1); } return strcpy(retval, s); } #endif boa-0.94.14rc21/install-sh0000754000175000001440000001572207757713046016003 0ustar jnelsonusers00000000000000#!/bin/sh # # install - install a program, script, or datafile # # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # 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. It can only install one file at a time, a restriction # shared with many OS's install programs. # 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}" transformbasename="" 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 "$0: no input file specified" >&2 exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d "$dst" ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog 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" ] || [ -d "$src" ] then : else echo "$0: $src does not exist" >&2 exit 1 fi if [ x"$dst" = x ] then echo "$0: no destination specified" >&2 exit 1 else : 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 : 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 : fi pathcomp=$pathcomp/ done fi if [ x"$dir_arg" != x ] then $doit $instcmd "$dst" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; 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 : fi # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # 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 :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && # Now remove or move aside any old file at destination location. We try this # two ways since rm can't unlink itself on some systems and the destination # file might be busy for other reasons. In this case, the final cleanup # might fail but the new file should still install successfully. { if [ -f "$dstdir/$dstfile" ] then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } boa-0.94.14rc21/src/0000755000175000001440000000000010207232236014535 5ustar jnelsonusers00000000000000boa-0.94.14rc21/src/.depend0000644000175000001440000000336610020545337016007 0ustar jnelsonusers00000000000000alias.o: alias.c boa.h compat.h config.h defines.h globals.h escape.h boa.o: boa.c boa.h compat.h config.h defines.h globals.h escape.h buffer.o: buffer.c boa.h compat.h config.h defines.h globals.h escape.h cgi.o: cgi.c boa.h compat.h config.h defines.h globals.h escape.h cgi_header.o: cgi_header.c boa.h compat.h config.h defines.h globals.h \ escape.h config.o: config.c boa.h compat.h config.h defines.h globals.h escape.h \ access.h escape.o: escape.c boa.h compat.h config.h defines.h globals.h escape.h get.o: get.c boa.h compat.h config.h defines.h globals.h escape.h \ access.h hash.o: hash.c boa.h compat.h config.h defines.h globals.h escape.h ip.o: ip.c boa.h compat.h config.h defines.h globals.h escape.h log.o: log.c boa.h compat.h config.h defines.h globals.h escape.h mmap_cache.o: mmap_cache.c boa.h compat.h config.h defines.h globals.h \ escape.h pipe.o: pipe.c boa.h compat.h config.h defines.h globals.h escape.h queue.o: queue.c boa.h compat.h config.h defines.h globals.h escape.h range.o: range.c boa.h compat.h config.h defines.h globals.h escape.h read.o: read.c boa.h compat.h config.h defines.h globals.h escape.h request.o: request.c boa.h compat.h config.h defines.h globals.h escape.h response.o: response.c boa.h compat.h config.h defines.h globals.h \ escape.h signals.o: signals.c boa.h compat.h config.h defines.h globals.h escape.h util.o: util.c boa.h compat.h config.h defines.h globals.h escape.h sublog.o: sublog.c compat.h config.h select.o: select.c boa.h compat.h config.h defines.h globals.h escape.h select.o: select.c boa.h compat.h config.h defines.h globals.h escape.h poll.o: poll.c boa.h compat.h config.h defines.h globals.h escape.h access.o: access.c boa.h compat.h config.h defines.h globals.h escape.h \ access.h boa-0.94.14rc21/src/Makefile.in0000644000175000001440000000344510206520320016601 0ustar jnelsonusers00000000000000# $Id: Makefile.in,v 1.59.2.15 2005/02/22 03:02:40 jnelson Exp $ .SUFFIXES: .SUFFIXES: .o .c .PHONY: clean mrclean distclean all dist@ifGNUmake@ depend # The following gcc warning switches are too noisy to be useful checking # Boa for lint: # -Wtraditional -Wconversion -Wredundant-decls -Wunreachable-code # The following gcc warning switches should generate no warnings: GCC_FLAGS = -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wcast-qual \ -Wshadow -Waggregate-return -Wmissing-prototypes -Wnested-externs \ -Wall -W -Wno-unused -Winline -Wwrite-strings -Wundef -pedantic srcdir = @srcdir@ VPATH = @srcdir@:@srcdir@/../extras LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ -I@srcdir@ -I. @ifGNUmake@DEPEND = .depend CC = @CC@ CPP = @CPP@ SOURCES = alias.c boa.c buffer.c cgi.c cgi_header.c config.c escape.c \ get.c hash.c ip.c log.c mmap_cache.c pipe.c queue.c range.c \ read.c request.c response.c signals.c util.c sublog.c \ @ASYNCIO_SOURCE@ @ACCESSCONTROL_SOURCE@ OBJS = $(SOURCES:.c=.o) timestamp.o @STRUTIL@ all: boa boa_indexer boa: $(OBJS) $(CC) -o $@ @ALLSOURCES@ $(LDFLAGS) $(LIBS) boa_indexer: index_dir.o escape.o @SCANDIR@ @ALPHASORT@ @STRUTIL@ $(CC) -o $@ @ALLSOURCES@ $(LDFLAGS) $(LIBS) clean: rm -f $(OBJS) boa core *~ boa_indexer index_dir.o rm -f @SCANDIR@ @ALPHASORT@ @STRUTIL@ poll.o select.o access.o distclean: mrclean mrclean: clean rm -f config.status config.cache config.h Makefile config.log # timestamp timestamp.o: $(SOURCES) # depend stuff @ifGNUmake@depend: $(SOURCES) @ifGNUmake@ $(CPP) $(CPPFLAGS) -MM @ALLSOURCES@ select.c poll.c access.c > $(DEPEND) @ifGNUmake@-include $(DEPEND) # tags tags: $(SOURCES) ctags -o tags @ALLSOURCES@ *.h # object dump boa.objdump: boa objdump --disassemble-all --source boa > $@ boa-0.94.14rc21/src/access.c0000644000175000001440000000460210206636621016151 0ustar jnelsonusers00000000000000/* * Boa, an http server * This file Copyright (C) 2002 Peter Korsgaard * Some changes Copyright (C) 2003-2004 Jon Nelson * * 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 1, 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. */ /* $Id: access.c,v 1.1.2.6 2005/02/22 14:11:29 jnelson Exp $ */ #include #include #include #include "boa.h" #include "access.h" struct access_node { char *pattern; enum access_type type; }; static int n_access; static struct access_node *nodes = NULL; static void access_shutdown(void); static void access_shutdown(void) { int i; if (nodes) { for (i = 0; i < n_access; i++) { if (nodes[i].pattern) { free(nodes[i].pattern); } else { WARN("Not freeing NULL access pattern!"); } } free(nodes); } nodes = NULL; n_access = 0; } void access_init(void) { if (n_access || nodes) { access_shutdown(); } } void access_add(const char *pattern, enum access_type type) { nodes = realloc(nodes, (n_access + 1) * sizeof (struct access_node)); if (!nodes) { DIE("realloc of nodes failed!"); } nodes[n_access].type = type; nodes[n_access].pattern = strdup(pattern); if (!nodes[n_access].pattern) { DIE("strdup of pattern failed!"); } ++n_access; } /* access_add */ enum access_type access_allow(const char *file) { int i; /* find first match in allow / deny rules */ for (i = 0; i < n_access; i++) { if (fnmatch(nodes[i].pattern, file, 0) == 0) { return nodes[i].type; } } /* default to allow */ return ACCESS_ALLOW; } /* access_allow */ boa-0.94.14rc21/src/access.h0000644000175000001440000000224010206636621016152 0ustar jnelsonusers00000000000000/* * Boa, an http server * This file Copyright (C) 2002 Peter Korsgaard * Some changes (C) 2004 Jon Nelson * * 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 1, 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. * */ /* $Id: access.h,v 1.1.2.4 2005/02/22 14:11:29 jnelson Exp $ */ #ifndef _ACCESS_H #define _ACCESS_H enum access_type { ACCESS_DENY, ACCESS_ALLOW }; void access_init(void); void access_add(const char *pattern, enum access_type); enum access_type access_allow(const char *file); #endif /* _ACCESS_H */ boa-0.94.14rc21/src/alias.c0000644000175000001440000005501610206636621016006 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996 Russ Nelson * Copyright (C) 1996-2005 Larry Doolittle * Copyright (C) 1996-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: alias.c,v 1.70.2.20 2005/02/22 14:11:29 jnelson Exp $ */ #include "boa.h" struct alias { char *fakename; /* URI path to file */ char *realname; /* Actual path to file */ enum ALIAS type; /* ALIAS, SCRIPTALIAS, REDIRECT */ unsigned int fake_len; /* strlen of fakename */ unsigned int real_len; /* strlen of realname */ struct alias *next; }; typedef struct alias alias; static alias *alias_hashtable[ALIAS_HASHTABLE_SIZE]; static alias *find_alias(char *uri, unsigned int urilen); static int init_script_alias(request * req, alias * current1, unsigned int uri_len); static unsigned int get_alias_hash_value(const char *file); /* * Name: get_alias_hash_value * * Description: adds the ASCII values of the file letters * and mods by the hashtable size to get the hash value * Note: stops at first '/' (or '\0') */ static unsigned int get_alias_hash_value(const char *file) { unsigned int hash = 0; unsigned int i = 0; char c; if (file == NULL) { WARN("file sent to get_alias_hash_value is NULL"); return 0; } else if (file[0] == '\0') { WARN("file sent to get_alias_hash_value is empty"); return 0; } hash = (unsigned int) file[i++]; while ((c = file[i++]) && c != '/') hash += (unsigned int) c; return hash % ALIAS_HASHTABLE_SIZE; } /* * Name: add_alias * * Description: add an Alias, Redirect, or ScriptAlias to the * alias hash table. */ void add_alias(const char *fakename, const char *realname, enum ALIAS type) { unsigned int hash; alias *old, *new; unsigned int fakelen, reallen; /* sanity checking */ if (fakename == NULL || realname == NULL) { DIE("NULL values sent to add_alias"); } fakelen = strlen(fakename); reallen = strlen(realname); if (fakelen == 0 || reallen == 0) { DIE("empty values sent to add_alias"); } hash = get_alias_hash_value(fakename); DEBUG(DEBUG_ALIAS) { log_error_time(); fprintf(stderr, "%s:%d - Going to add alias: \"%s\" -=> \"%s\" (hash: %u)\n", __FILE__, __LINE__, fakename, realname, hash); } old = alias_hashtable[hash]; if (old) { while (old->next) { if (!strcmp(fakename, old->fakename)) /* don't add twice */ return; old = old->next; } } new = (alias *) malloc(sizeof (alias)); if (!new) { DIE("out of memory adding alias to hash"); } if (old) old->next = new; else alias_hashtable[hash] = new; new->fakename = strdup(fakename); if (!new->fakename) { DIE("failed strdup"); } new->fake_len = fakelen; /* check for "here" */ new->realname = strdup(realname); if (!new->realname) { DIE("strdup of realname failed"); } new->real_len = reallen; new->type = type; new->next = NULL; DEBUG(DEBUG_ALIAS) { log_error_time(); fprintf(stderr, "%s:%d - ADDED alias: \"%s\" -=> \"%s\" hash: %u\n", __FILE__, __LINE__, fakename, realname, hash); } } /* * Name: find_alias * * Description: Locates uri in the alias hashtable if it exists. * * Returns: * * alias structure or NULL if not found */ static alias *find_alias(char *uri, unsigned int urilen) { alias *current; unsigned int hash; /* Find ScriptAlias, Alias, or Redirect */ if (urilen == 0) { WARN("uri len is 0!"); urilen = strlen(uri); } hash = get_alias_hash_value(uri); DEBUG(DEBUG_ALIAS) { log_error_time(); fprintf(stderr, "%s:%d - looking for \"%s\" (hash=%u,len=%u)...\n", __FILE__, __LINE__, uri, hash, urilen); } current = alias_hashtable[hash]; while (current) { DEBUG(DEBUG_ALIAS) { log_error_time(); fprintf(stderr, "%s:%d - comparing \"%s\" (request) to \"%s\" (alias): ", __FILE__, __LINE__, uri, current->fakename); } /* current->fake_len must always be: * shorter or equal to the uri */ /* * when performing matches: * If the virtual part of the URL ends in '/', and * we get a match, stop there. * Otherwise, we require '/' or '\0' at the end of the URL. * We only check if the virtual path does *not* end in '/' */ if (current->fake_len <= urilen && !memcmp(uri, current->fakename, current->fake_len) && (current->fakename[current->fake_len - 1] == '/' || (current->fakename[current->fake_len - 1] != '/' && (uri[current->fake_len] == '\0' || uri[current->fake_len] == '/')))) { DEBUG(DEBUG_ALIAS) { fprintf(stderr, "Got it! (%s)\n", current->realname); } return current; } else { DEBUG(DEBUG_ALIAS) { fprintf(stderr, "Don't Got it!\n"); } } current = current->next; } return current; } /* * Name: translate_uri * * Description: Parse a request's virtual path. * Sets query_string, pathname directly. * Also sets path_info, path_translated, and script_name via * init_script_alias * * Note: NPH in user dir is currently broken * * Note -- this should be broken up. * * Return values: * 0: failure, close it down * 1: success, continue */ int translate_uri(request * req) { static char buffer[MAX_HEADER_LENGTH + 1]; alias *current; char *p; unsigned int uri_len; if (req->request_uri[0] != '/') { send_r_bad_request(req); return 0; } uri_len = strlen(req->request_uri); current = find_alias(req->request_uri, uri_len); if (current) { if (current->type == SCRIPTALIAS) /* Script */ return init_script_alias(req, current, uri_len); /* not a script alias, therefore begin filling in data */ if (current->real_len + uri_len - current->fake_len + 1 > sizeof(buffer)) { log_error_doc(req); fputs("uri too long!\n", stderr); send_r_bad_request(req); return 0; } memcpy(buffer, current->realname, current->real_len); memcpy(buffer + current->real_len, req->request_uri + current->fake_len, uri_len - current->fake_len + 1); if (current->type == REDIRECT) { /* Redirect */ if (req->method == M_POST) { /* POST to non-script */ /* it's not a cgi, but we try to POST??? */ log_error_doc(req); fputs("POST to non-script is disallowed.\n", stderr); send_r_bad_request(req); return 0; /* not a script alias, therefore begin filling in data */ } send_r_moved_temp(req, buffer, ""); return 0; } else { /* Alias */ req->pathname = strdup(buffer); if (!req->pathname) { boa_perror(req, "unable to strdup buffer onto req->pathname"); return 0; } return 1; } } /* The reason why this is *not* an 'else if' is that, after aliasing, we still have to check for '~' expansion */ if (user_dir && req->request_uri[1] == '~') { char *user_homedir; char *req_urip; if (req->request_uri[2] == '\0') { log_error_doc(req); fputs("Empty user-dir in URI\n", stderr); send_r_bad_request(req); return 0; } req_urip = req->request_uri + 2; /* since we have uri_len which is from strlen(req->request_uri) */ p = memchr(req_urip, '/', uri_len - 2); if (p) *p = '\0'; user_homedir = get_home_dir(req_urip); if (p) /* have to restore request_uri in case of error */ *p = '/'; if (!user_homedir) { /*no such user */ send_r_not_found(req); return 0; } else { unsigned int l1 = strlen(user_homedir); unsigned int l2 = strlen(user_dir); unsigned int l3 = (p ? strlen(p) : 0); /* we need l1 + '/' + l2 + l3 + '\0' */ if (l1 + 1 + l2 + l3 + 1 > sizeof(buffer)) { log_error_doc(req); fputs("uri too long!\n", stderr); send_r_bad_request(req); return 0; } memcpy(buffer, user_homedir, l1); buffer[l1] = '/'; /* copy the NUL in case 'p' is NULL */ memcpy(buffer + l1 + 1, user_dir, l2 + 1); if (p) memcpy(buffer + l1 + 1 + l2, p, l3 + 1); } } else if (vhost_root) { /* no aliasing, no userdir... */ unsigned int l1, l2, l3, l4, l5; char *ap = NULL; /* form * vhost_root + '/' + ip + '/' + host + '/' + htdocs + '/' + resource */ l1 = strlen(vhost_root); l2 = strlen(req->local_ip_addr); ap = req->host; l3 = strlen(ap); l4 = strlen("htdocs"); l5 = strlen(req->request_uri); if (l1 + 1 + l2 + 1 + l3 + 1 + l4 + l5 + 1 > sizeof(buffer)) { log_error_doc(req); fputs("uri too long!\n", stderr); send_r_bad_request(req); return 0; } memcpy(buffer, vhost_root, l1); buffer[l1] = '/'; memcpy(buffer + l1 + 1, req->local_ip_addr, l2); buffer[l1 + 1 + l2] = '/'; memcpy(buffer + l1 + 1 + l2 + 1, ap, l3); buffer[l1 + 1 + l2 + 1 + l3] = '/'; memcpy(buffer + l1 + 1 + l2 + 1 + l3 + 1, "htdocs", l4); /* request_uri starts with '/' */ memcpy(buffer + l1 + 1 + l2 + 1 + l3 + 1 + l4, req->request_uri, l5 + 1); } else if (document_root) { /* no aliasing, no userdir... */ unsigned int l1, l2, l3; l1 = strlen(document_root); l2 = strlen(req->request_uri); if (virtualhost) l3 = strlen(req->local_ip_addr); else l3 = 0; if (l1 + 1 + l2 + l3 + 1 > sizeof(buffer)) { log_error_doc(req); fputs("uri too long!\n", stderr); send_r_bad_request(req); return 0; } /* the 'l2 + 1' is there so we copy the '\0' as well */ memcpy(buffer, document_root, l1); if (virtualhost) { buffer[l1] = '/'; memcpy(buffer + l1 + 1, req->local_ip_addr, l3); memcpy(buffer + l1 + 1 + l3, req->request_uri, l2 + 1); } else memcpy(buffer + l1, req->request_uri, l2 + 1); } else { /* not aliased. not userdir. not part of document_root. BAIL */ send_r_not_found(req); return 0; } /* if here, * o it may be aliased but it's not a redirect or a script... * o it may be a homedir * o it may be a document_root resource (with or without virtual host) */ req->pathname = strdup(buffer); if (!req->pathname) { boa_perror(req, "Could not strdup buffer for req->pathname!"); return 0; } #ifdef FASCIST_LOGGING log_error_time(); fprintf(stderr, "%s:%d - buffer is: \"%s\"\n", __FILE__, __LINE__, buffer); log_error_time(); fprintf(stderr, "%s:%d - compare \"%s\" and \"%s\": %d\n", __FILE__, __LINE__, get_mime_type(buffer), CGI_MIME_TYPE, strcmp(CGI_MIME_TYPE, get_mime_type(buffer))); #endif /* below we support cgis outside of a ScriptAlias */ if (strcmp(CGI_MIME_TYPE, get_mime_type(req->pathname)) == 0) { /* cgi */ /* FIXME */ /* script_name could end up as /cgi-bin/bob/extra_path */ req->script_name = strdup(req->request_uri); if (!req->script_name) { boa_perror(req, "Could not strdup req->request_uri for req->script_name."); return 0; } if (req->http_version == HTTP09) req->cgi_type = NPH; else req->cgi_type = CGI; return 1; } else if (req->method == M_POST) { /* POST to non-script */ /* it's not a cgi, but we try to POST??? */ log_error_doc(req); fputs("POST to non-script disallowed.\n", stderr); send_r_bad_request(req); return 0; } else /* we are done!! */ return 1; } /* * Name: init_script_alias * * Description: Performs full parsing on a ScriptAlias request * Sets path_info and script_name * * Return values: * * 0: failure, shut down * 1: success, continue */ static int init_script_alias(request * req, alias * current1, unsigned int uri_len) { static char pathname[MAX_HEADER_LENGTH + 1]; struct stat statbuf; int i = 0; char c; int err; /* copies the "real" path + the non-alias portion of the uri to pathname. */ if (vhost_root) { /* vhost_root + IP + host + / + cgi-bin + resource */ unsigned int l1, l2, l3; char *ap; l1 = strlen(vhost_root); l2 = strlen(req->local_ip_addr); ap = req->host; l3 = strlen(ap); if (l1 + 1 + l2 + 1 + l3 + 1 + current1->real_len + (uri_len - current1->fake_len) + 1 > sizeof(pathname)) { log_error_doc(req); fputs("uri too long!\n", stderr); send_r_bad_request(req); return 0; } memcpy(pathname, vhost_root, l1); pathname[l1] = '/'; memcpy(pathname + l1 + 1, req->local_ip_addr, l2); pathname[l1 + 1 + l2] = '/'; memcpy(pathname + l1 + 1 + l2 + 1, ap, l3); pathname[l1 + 1 + l2 + 1 + l3] = '/'; memcpy(pathname + l1 + 1 + l2 + 1 + l3 + 1, current1->realname, current1->real_len); memcpy(pathname + l1 + 1 + l2 + 1 + l3 + 1 + current1->real_len, &req->request_uri[current1->fake_len], uri_len - current1->fake_len + 1); /* the +1 copies the NUL */ } else { if (current1->real_len + uri_len - current1->fake_len + 1 > sizeof(pathname)) { log_error_doc(req); fputs("uri too long!\n", stderr); send_r_bad_request(req); return 0; } memcpy(pathname, current1->realname, current1->real_len); memcpy(pathname + current1->real_len, &req->request_uri[current1->fake_len], uri_len - current1->fake_len + 1); /* the +1 copies the NUL */ } #ifdef FASCIST_LOGGING log_error_time(); fprintf(stderr, "%s:%d - pathname in init_script_alias is: \"%s\" (\"%s\")\n", __FILE__, __LINE__, pathname, pathname + current1->real_len); #endif if (strncmp("nph-", pathname + current1->real_len, 4) == 0 || (req->http_version == HTTP09)) req->cgi_type = NPH; else req->cgi_type = CGI; /* start at the beginning of the actual uri... (in /cgi-bin/bob, start at the 'b' in bob */ i = current1->real_len; c = '\0'; /* go to first and successive '/' and keep checking * if it is a full pathname * on success (stat (not lstat) of file is a *regular file*) */ do { c = pathname[++i]; if (c == '/') { pathname[i] = '\0'; err = stat(pathname, &statbuf); if (err == -1) { send_r_not_found(req); return 0; } /* is it a dir? */ if (!S_ISDIR(statbuf.st_mode)) { /* check access */ /* the file must be readable+executable by at least * u,g,or o */ if (!S_ISREG(statbuf.st_mode) || access(pathname, R_OK|X_OK)) { send_r_forbidden(req); return 0; } pathname[i] = '/'; /* stop here */ break; } /* if here, it's a dir (or it points to one!) */ pathname[i] = '/'; } } while (c != '\0'); req->script_name = strdup(req->request_uri); if (!req->script_name) { boa_perror(req, "unable to strdup req->request_uri for req->script_name"); return 0; } if (c == '\0') { err = stat(pathname, &statbuf); if (err == -1) { send_r_not_found(req); return 0; } /* is it a dir? */ if (!S_ISDIR(statbuf.st_mode)) { /* check access */ /* the file must be readable+executable by at least * u,g,or o */ if (!S_ISREG(statbuf.st_mode) || access(pathname, R_OK|X_OK)) { send_r_forbidden(req); return 0; } /* stop here */ } else { send_r_forbidden(req); return 0; } } /* we have path_info if c == '/'... still have to check for query */ else if (c == '/') { unsigned int hash; alias *current; int path_len; req->path_info = strdup(pathname + i); if (!req->path_info) { boa_perror(req, "unable to strdup pathname + index for req->path_info"); return 0; } pathname[i] = '\0'; /* strip path_info from path */ path_len = strlen(req->path_info); /* we need to fix script_name here */ /* index points into pathname, which is * realname/cginame/foo * and index points to the '/foo' part */ req->script_name[strlen(req->script_name) - path_len] = '\0'; /* zap off the /foo part */ /* now, we have to re-alias the extra path info.... this sucks. */ hash = get_alias_hash_value(req->path_info); current = alias_hashtable[hash]; while (current && !req->path_translated) { if (!strncmp(req->path_info, current->fakename, current->fake_len)) { static char buffer[MAX_HEADER_LENGTH + 1]; if (current->real_len + path_len - current->fake_len + 1 > sizeof(buffer)) { log_error_doc(req); fputs("uri too long!\n", stderr); send_r_bad_request(req); return 0; } memcpy(buffer, current->realname, current->real_len); /* strcpy(buffer + current->real_len, &req->path_info[current->fake_len]); */ memcpy(buffer + current->real_len, req->path_info + current->fake_len, path_len - current->fake_len + 1); /* +1 for NUL */ req->path_translated = strdup(buffer); if (!req->path_translated) { boa_perror(req, "unable to strdup buffer for req->path_translated"); return 0; } } current = current->next; } /* no alias... try userdir */ if (!req->path_translated && user_dir && req->path_info[1] == '~') { char *user_homedir; char *p; p = strchr(pathname + i + 1, '/'); if (p) *p = '\0'; user_homedir = get_home_dir(pathname + i + 2); if (p) *p = '/'; if (!user_homedir) { /* no such user */ send_r_not_found(req); return 0; } { unsigned int l1 = strlen(user_homedir); unsigned int l2 = strlen(user_dir); unsigned int l3 = 0; if (p) l3 = strlen(p); req->path_translated = malloc(l1 + 1 + l2 + l3 + 1); if (req->path_translated == NULL) { boa_perror(req, "unable to malloc memory for req->path_translated"); return 0; } memcpy(req->path_translated, user_homedir, l1); req->path_translated[l1] = '/'; memcpy(req->path_translated + l1 + 1, user_dir, l2 + 1); /* copy the NUL just in case */ if (p) memcpy(req->path_translated + l1 + 1 + l2, p, l3 + 1); } } else if (!req->path_translated && document_root) { /* no userdir, no aliasing... try document root */ unsigned int l1, l2; l1 = strlen(document_root); l2 = path_len; req->path_translated = malloc(l1 + l2 + 1); if (req->path_translated == NULL) { boa_perror(req, "unable to malloc memory for req->path_translated"); return 0; } memcpy(req->path_translated, document_root, l1); memcpy(req->path_translated + l1, req->path_info, l2 + 1); } } req->pathname = strdup(pathname); if (!req->pathname) { boa_perror(req, "unable to strdup pathname for req->pathname"); return 0; } return 1; } /* * Empties the alias hashtable, deallocating any allocated memory. */ void dump_alias(void) { int i; alias *temp; for (i = 0; i < ALIAS_HASHTABLE_SIZE; ++i) { /* these limits OK? */ if (alias_hashtable[i]) { temp = alias_hashtable[i]; while (temp) { alias *temp_next; if (temp->fakename) free(temp->fakename); if (temp->realname) free(temp->realname); temp_next = temp->next; free(temp); temp = temp_next; } alias_hashtable[i] = NULL; } } } boa-0.94.14rc21/src/boa.c0000644000175000001440000002001610206636621015446 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Some changes Copyright (C) 1996 Charles F. Randall * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1996-2005 Jon Nelson * * 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 1, 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. * */ /* $Id: boa.c,v 1.99.2.26 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" /* globals */ int backlog = SO_MAXCONN; time_t start_time; int debug_level = 0; int sighup_flag = 0; /* 1 => signal has happened, needs attention */ int sigchld_flag = 0; /* 1 => signal has happened, needs attention */ int sigalrm_flag = 0; /* 1 => signal has happened, needs attention */ int sigterm_flag = 0; /* lame duck mode */ time_t current_time; int pending_requests = 0; extern const char *config_file_name; /* static to boa.c */ static void usage(const char *programname); static void parse_commandline(int argc, char *argv[]); static void fixup_server_root(void); static int create_server_socket(void); static void drop_privs(void); static int sock_opt = 1; static int do_fork = 1; int main(int argc, char *argv[]) { int server_s; /* boa socket */ pid_t pid; /* set umask to u+rw, u-x, go-rwx */ /* according to the man page, umask always succeeds */ umask(077); /* but first, update timestamp, because log_error_time uses it */ (void) time(¤t_time); /* set timezone right away */ tzset(); { int devnullfd = -1; devnullfd = open("/dev/null", 0); /* make STDIN point to /dev/null */ if (devnullfd == -1) { DIE("can't open /dev/null"); } if (dup2(devnullfd, STDIN_FILENO) == -1) { DIE("can't dup2 /dev/null to STDIN_FILENO"); } (void) close(devnullfd); } parse_commandline(argc, argv); fixup_server_root(); read_config_files(); create_common_env(); open_logs(); server_s = create_server_socket(); init_signals(); build_needs_escape(); /* background ourself */ if (do_fork) { pid = fork(); } else { pid = getpid(); } switch (pid) { case -1: /* error */ perror("fork/getpid"); exit(EXIT_FAILURE); case 0: /* child, success */ break; default: /* parent, success */ if (pid_file != NULL) { FILE *PID_FILE = fopen(pid_file, "w"); if (PID_FILE != NULL) { fprintf(PID_FILE, "%d", pid); fclose(PID_FILE); } else { perror("fopen pid file"); } } if (do_fork) exit(EXIT_SUCCESS); break; } drop_privs(); /* main loop */ timestamp(); status.requests = 0; status.errors = 0; start_time = current_time; loop(server_s); return 0; } static void usage(const char *programname) { fprintf(stderr, "Usage: %s [-c serverroot] [-d] [-f configfile] [-r chroot]%s\n", programname, #ifndef DISABLE_DEBUG " [-l debug_level]" #else "" #endif ); #ifndef DISABLE_DEBUG print_debug_usage(); #endif exit(EXIT_FAILURE); } static void parse_commandline(int argc, char *argv[]) { int c; /* command line arg */ while ((c = getopt(argc, argv, "c:dl:f:r:")) != -1) { switch (c) { case 'c': if (server_root) free(server_root); server_root = strdup(optarg); if (!server_root) { perror("strdup (for server_root)"); exit(EXIT_FAILURE); } break; case 'd': do_fork = 0; break; case 'f': config_file_name = optarg; break; case 'r': if (chdir(optarg) == -1) { log_error_time(); perror("chdir (to chroot)"); exit(EXIT_FAILURE); } if (chroot(optarg) == -1) { log_error_time(); perror("chroot"); exit(EXIT_FAILURE); } if (chdir("/") == -1) { log_error_time(); perror("chdir (after chroot)"); exit(EXIT_FAILURE); } break; #ifndef DISABLE_DEBUG case 'l': parse_debug(optarg); break; #endif default: usage(argv[0]); exit(EXIT_FAILURE); } } } static int create_server_socket(void) { int server_s; server_s = socket(SERVER_PF, SOCK_STREAM, IPPROTO_TCP); if (server_s == -1) { DIE("unable to create socket"); } /* server socket is nonblocking */ if (set_nonblock_fd(server_s) == -1) { DIE("fcntl: unable to set server socket to nonblocking"); } /* close server socket on exec so CGIs can't write to it */ if (fcntl(server_s, F_SETFD, 1) == -1) { DIE("can't set close-on-exec on server socket!"); } /* reuse socket addr */ if ((setsockopt(server_s, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_opt, sizeof (sock_opt))) == -1) { DIE("setsockopt"); } /* Internet family-specific code encapsulated in bind_server() */ if (bind_server(server_s, server_ip, server_port) == -1) { DIE("unable to bind"); } /* listen: large number just in case your kernel is nicely tweaked */ if (listen(server_s, backlog) == -1) { DIE("unable to listen"); } return server_s; } static void drop_privs(void) { /* give away our privs if we can */ if (getuid() == 0) { struct passwd *passwdbuf; passwdbuf = getpwuid(server_uid); if (passwdbuf == NULL) { DIE("getpwuid"); } if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) { DIE("initgroups"); } if (setgid(server_gid) == -1) { DIE("setgid"); } if (setuid(server_uid) == -1) { DIE("setuid"); } /* test for failed-but-return-was-successful setuid * http://www.securityportal.com/list-archive/bugtraq/2000/Jun/0101.html */ if (server_uid != 0 && setuid(0) != -1) { DIE("icky Linux kernel bug!"); } } else { if (server_gid || server_uid) { log_error_time(); fprintf(stderr, "Warning: " "Not running as root: no attempt to change" " to uid %u gid %u\n", server_uid, server_gid); } server_gid = getgid(); server_uid = getuid(); } } /* * Name: fixup_server_root * * Description: Makes sure the server root is valid. * */ static void fixup_server_root() { if (!server_root) { #ifdef SERVER_ROOT server_root = strdup(SERVER_ROOT); if (!server_root) { perror("strdup (SERVER_ROOT)"); exit(EXIT_FAILURE); } #else fputs("boa: don't know where server root is. Please #define " "SERVER_ROOT in boa.h\n" "and recompile, or use the -c command line option to " "specify it.\n", stderr); exit(EXIT_FAILURE); #endif } if (chdir(server_root) == -1) { fprintf(stderr, "Could not chdir to \"%s\": aborting\n", server_root); exit(EXIT_FAILURE); } } boa-0.94.14rc21/src/boa.h0000644000175000001440000001642010206636621015457 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1997-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: boa.h,v 1.63.2.27 2005/02/22 14:11:29 jnelson Exp $*/ #ifndef _BOA_H #define _BOA_H #include "config.h" #include #include /* malloc, free, etc. */ #include /* stdin, stdout, stderr */ #include /* strdup */ #include #include /* localtime, time */ #include #include #include #include #include /* OPEN_MAX */ #include #include #include #include /* socket, bind, accept */ #include /* socket, bind, accept, setsockopt, */ #include /* open */ #include "compat.h" /* oh what fun is porting */ #include "defines.h" #include "globals.h" /* alias */ void add_alias(const char *fakename, const char *realname, enum ALIAS type); int translate_uri(request * req); void dump_alias(void); /* config */ void read_config_files(void); /* escape */ #include "escape.h" /* get */ int init_get(request * req); int process_get(request * req); int get_dir(request * req, struct stat *statbuf); /* hash */ unsigned get_mime_hash_value(const char *extension); char *get_mime_type(const char *filename); char *get_home_dir(const char *name); void dump_mime(void); void dump_passwd(void); void hash_show_stats(void); void add_mime_type(const char *extension, const char *type); /* log */ void open_logs(void); void log_access(request * req); void log_error_doc(request * req); void boa_perror(request * req, const char *message); void log_error_time(void); void log_error(const char *mesg); #ifdef HAVE_FUNC void log_error_mesg(const char *file, int line, const char *func, const char *mesg); void log_error_mesg_fatal(const char *file, int line, const char *func, const char *mesg); #else void log_error_mesg(const char *file, int line, const char *mesg); void log_error_mesg_fatal(const char *file, int line, const char *mesg); #endif /* queue */ void block_request(request * req); void ready_request(request * req); void dequeue(request ** head, request * req); void enqueue(request ** head, request * req); /* read */ int read_header(request * req); int read_body(request * req); int write_body(request * req); /* request */ request *new_request(void); void get_request(int); void process_requests(int server_s); int process_header_end(request * req); int process_header_line(request * req); int process_logline(request * req); int process_option_line(request * req); void add_accept_header(request * req, const char *mime_type); void free_requests(void); /* response */ const char *http_ver_string(enum HTTP_VERSION ver); void print_ka_phrase(request * req); void print_content_type(request * req); void print_content_length(request * req); void print_last_modified(request * req); void print_http_headers(request * req); void print_content_range(request * req); void print_partial_content_continue(request * req); void print_partial_content_done(request * req); int complete_response(request *req); void send_r_continue(request * req); /* 100 */ void send_r_request_ok(request * req); /* 200 */ void send_r_no_content(request * req); /* 204 */ void send_r_partial_content(request * req); /* 206 */ void send_r_moved_perm(request * req, const char *url); /* 301 */ void send_r_moved_temp(request * req, const char *url, const char *more_hdr); /* 302 */ void send_r_not_modified(request * req); /* 304 */ void send_r_bad_request(request * req); /* 400 */ void send_r_unauthorized(request * req, const char *name); /* 401 */ void send_r_forbidden(request * req); /* 403 */ void send_r_not_found(request * req); /* 404 */ void send_r_length_required(request * req); /* 411 */ void send_r_precondition_failed(request * req); /* 412 */ void send_r_request_uri_too_long(request * req); /* 414 */ void send_r_invalid_range(request * req); /* 416 */ void send_r_error(request * req); /* 500 */ void send_r_not_implemented(request * req); /* 501 */ void send_r_bad_gateway(request * req); /* 502 */ void send_r_service_unavailable(request * req); /* 503 */ void send_r_bad_version(request * req, const char * version); /* 505 */ /* cgi */ void create_common_env(void); void add_to_common_env(char *key, char *value); void clear_common_env(void); int add_cgi_env(request * req, const char *key, const char *value, int http_prefix); int init_cgi(request * req); /* signals */ void init_signals(void); void reset_signals(void); void sighup_run(void); void sigchld_run(void); void sigalrm_run(void); void sigterm_stage1_run(void); void sigterm_stage2_run(void); /* util.c */ void clean_pathname(char *pathname); char *get_commonlog_time(void); void rfc822_time_buf(char *buf, time_t s); char *simple_itoa(unsigned int i); int boa_atoi(const char *s); int month2int(const char *month); int modified_since(time_t * mtime, const char *if_modified_since); int unescape_uri(char *uri, char **query_string); int create_temporary_file(short want_unlink, char *storage, unsigned int size); int real_set_block_fd(int fd); int real_set_nonblock_fd(int fd); char *to_upper(char *str); void strlower(char *s); int check_host(const char *r); #ifndef DISABLE_DEBUG void parse_debug(char *foo); void print_debug_usage(void); #endif /* buffer */ int req_write(request * req, const char *msg); void reset_output_buffer(request * req); int req_write_escape_http(request * req, const char *msg); int req_write_escape_html(request * req, const char *msg); int req_flush(request * req); char *escape_uri(const char *uri); char *escape_string(const char *inp, char *buf); /* timestamp */ void timestamp(void); /* mmap_cache */ struct mmap_entry *find_mmap(int data_fd, struct stat *s); void release_mmap(struct mmap_entry *e); /* sublog */ int open_gen_fd(char *spec); int process_cgi_header(request * req); /* pipe */ int read_from_pipe(request * req); int write_from_pipe(request * req); int io_shuffle(request * req); #ifdef HAVE_SENDFILE #include int io_shuffle_sendfile(request * req); #endif /* ip */ int bind_server(int sock, char *ip, unsigned int port); char *ascii_sockaddr(struct SOCKADDR *s, char *dest, unsigned int len); int net_port(struct SOCKADDR *s); /* select or poll */ void loop(int server_s); /* range.c */ void ranges_reset(request * req); Range *range_pool_pop(void); void range_pool_empty(void); void range_pool_push(Range * r); int ranges_fixup(request * req); int range_parse(request * req, const char *str); #endif boa-0.94.14rc21/src/buffer.c0000644000175000001440000002101410206636621016155 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1999-2004 Jon Nelson * Copyright (C) 1999-2000 Larry Doolittle * 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 1, 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. * */ /* $Id: buffer.c,v 1.10.2.14 2005/02/22 14:11:29 jnelson Exp $ */ #include "boa.h" #include "escape.h" /* * Name: req_write * * Description: Buffers data before sending to client. * Returns: -1 for error, otherwise how much is stored */ int req_write(request * req, const char *msg) { unsigned int msg_len; msg_len = strlen(msg); if (!msg_len || req->status > DONE) return req->buffer_end; if (req->buffer_end + msg_len > BUFFER_SIZE) { log_error_doc(req); fprintf(stderr, "There is not enough room in the buffer to" " copy %u bytes (%d available). Shutting down connection.\n", msg_len, BUFFER_SIZE - req->buffer_end); #ifdef FASCIST_LOGGING *(req->buffer + req->buffer_end) = '\0'; fprintf(stderr, "The request looks like this:\n%s\n", req->buffer); #endif req->status = DEAD; return -1; } memcpy(req->buffer + req->buffer_end, msg, msg_len); req->buffer_end += msg_len; return req->buffer_end; } void reset_output_buffer(request * req) { req->buffer_end = 0; } /* * Name: req_write_escape_http * Description: Buffers and "escapes" data before sending to client. * as above, but translates as it copies, into a form suitably * encoded for URLs in HTTP headers. * Returns: -1 for error, otherwise how much is stored */ int req_write_escape_http(request * req, const char *msg) { char c, *dest; const char *inp; int left; inp = msg; dest = req->buffer + req->buffer_end; /* 3 is a guard band, since we don't check the destination pointer * in the middle of a transfer of up to 3 bytes */ left = BUFFER_SIZE - req->buffer_end; while ((c = *inp++) && left >= 3) { if (needs_escape((unsigned int) c)) { *dest++ = '%'; *dest++ = INT_TO_HEX((c >> 4) & 0xf); *dest++ = INT_TO_HEX(c & 0xf); left -= 3; } else { *dest++ = c; left--; } } --inp; req->buffer_end = dest - req->buffer; #ifdef TESTING if (left < 0) { log_error_time(); /* don't use log_error_doc here */ fprintf(stderr, "Overflowed buffer space!\n"); chdir("/tmp"); abort(); } #endif if (*inp != '\0') { log_error_doc(req); fprintf(stderr, "Ran out of Buffer space! [req_write_escape_http]\n"); req->status = DEAD; return -1; } return req->buffer_end; } /* * Name: req_write_escape_html * Description: Buffers and "escapes" data before sending to client. * as above, but translates as it copies, into a form suitably * encoded for HTML bodies. * Returns: -1 for error, otherwise how much is stored */ int req_write_escape_html(request * req, const char *msg) { char c, *dest; const char *inp; int left; inp = msg; dest = req->buffer + req->buffer_end; /* 6 is a guard band, since we don't check the destination pointer * in the middle of a transfer of up to 6 bytes */ left = BUFFER_SIZE - req->buffer_end; while ((c = *inp++) && left >= 6) { switch (c) { case '>': *dest++ = '&'; *dest++ = 'g'; *dest++ = 't'; *dest++ = ';'; left -= 4; break; case '<': *dest++ = '&'; *dest++ = 'l'; *dest++ = 't'; *dest++ = ';'; left -= 4; break; case '&': *dest++ = '&'; *dest++ = 'a'; *dest++ = 'm'; *dest++ = 'p'; *dest++ = ';'; left -= 5; break; case '\"': *dest++ = '&'; *dest++ = 'q'; *dest++ = 'u'; *dest++ = 'o'; *dest++ = 't'; *dest++ = ';'; left -= 6; break; default: *dest++ = c; left--; } } --inp; req->buffer_end = dest - req->buffer; #ifdef TESTING if (left < 0) { log_error_time(); /* don't use log_error_doc here */ fprintf(stderr, "Overflowed buffer space! [req_write_escape_html]\n"); chdir("/tmp"); abort(); } #endif if (*inp != '\0') { log_error_doc(req); fprintf(stderr, "Ran out of Buffer space (%d chars left)! " "[req_write_escape_html]\n", left); req->status = DEAD; return -1; } return req->buffer_end; } /* * Name: flush_req * * Description: Sends any backlogged buffer to client. * * Returns: -2 for error, -1 for blocked, otherwise how much is stored */ int req_flush(request * req) { unsigned bytes_to_write; bytes_to_write = req->buffer_end - req->buffer_start; if (req->status > DONE) return -2; if (bytes_to_write) { int bytes_written; bytes_written = write(req->fd, req->buffer + req->buffer_start, bytes_to_write); if (bytes_written < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else { req->buffer_start = req->buffer_end = 0; /* OK to disable if your logs get too big */ #ifdef QUIET_DISCONNECT if (errno != ECONNRESET && errno != EPIPE) #endif { log_error_doc(req); perror("buffer flush"); } req->status = DEAD; req->buffer_end = 0; return -2; } } #ifdef FASCIST_LOGGING log_error_time(); fprintf(stderr, "%s:%d - Wrote \"", __FILE__, __LINE__); fwrite(req->buffer + req->buffer_start, sizeof (char), bytes_written, stderr); fprintf(stderr, "\" (%d bytes)\n", bytes_written); #endif req->buffer_start += bytes_written; } if (req->buffer_start == req->buffer_end) req->buffer_start = req->buffer_end = 0; return req->buffer_end; /* successful */ } /* * Name: escape_string * * Description: escapes the string inp. Uses variable buf. If buf is * NULL when the program starts, it will attempt to dynamically allocate * the space that it needs, otherwise it will assume that the user * has already allocated enough space for the variable buf, which * could be up to 3 times the size of inp. If the routine dynamically * allocates the space, the user is responsible for freeing it afterwords * Returns: NULL on error, pointer to string otherwise. * Note: this function doesn't really belong here, I plopped it here to * work around a "bug" in escape.h (it defines a global, so can't be * used in multiple source files). Actually, this routine shouldn't * exist anywhere, it's only usage is in get.c's handling of on-the-fly * directory generation, which would be better configured to use a combination * of req_write_escape_http and req_write_escape_html. That would involve * more work than I'm willing to put in right now, though, so here we are. */ char *escape_string(const char *inp, char *buf) { int max; char *ix; unsigned char c; max = strlen(inp) * 3; if (buf == NULL && max) buf = malloc(sizeof (char) * (max + 1)); if (buf == NULL) { log_error_time(); perror("malloc"); return NULL; } ix = buf; while ((c = *inp++) && max > 0) { if (needs_escape((unsigned int) c)) { *ix++ = '%'; *ix++ = INT_TO_HEX((c >> 4) & 0xf); *ix++ = INT_TO_HEX(c & 0xf); } else *ix++ = c; } *ix = '\0'; return buf; } boa-0.94.14rc21/src/cgi.c0000644000175000001440000005244210206636621015457 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Some changes Copyright (C) 1996 Charles F. Randall * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1997-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: cgi.c,v 1.83.2.28 2005/02/22 14:11:29 jnelson Exp $ */ #include "boa.h" static char *env_gen_extra(const char *key, const char *value, unsigned int extra); static void create_argv(request * req, char **aargv); static int complete_env(request * req); int verbose_cgi_logs = 0; /* The +1 is for the the NULL in complete_env */ static char **common_cgi_env = NULL; short common_cgi_env_count = 0; /* * Name: create_common_env * * Description: Set up the environment variables that are common to * all CGI scripts */ void create_common_env(void) { int i; common_cgi_env = calloc((COMMON_CGI_COUNT + 1),sizeof(char *)); common_cgi_env_count = 0; if (common_cgi_env == NULL) { DIE("unable to allocate memory for common_cgi_env"); } /* NOTE NOTE NOTE: If you (the reader) someday modify this chunk of code to handle more "common" CGI environment variables, then bump the value COMMON_CGI_COUNT in defines.h UP Also, in the case of document_root and server_admin, two variables that may or may not be defined depending on the way the server is configured, we check for null values and use an empty string to denote a NULL value to the environment, as per the specification. The quote for which follows: "In all cases, a missing environment variable is equivalent to a zero-length (NULL) value, and vice versa." */ common_cgi_env[common_cgi_env_count++] = env_gen_extra("PATH", ((cgi_path != NULL) ? cgi_path : DEFAULT_PATH), 0); common_cgi_env[common_cgi_env_count++] = env_gen_extra("SERVER_SOFTWARE", SERVER_VERSION, 0); common_cgi_env[common_cgi_env_count++] = env_gen_extra("SERVER_NAME", server_name, 0); common_cgi_env[common_cgi_env_count++] = env_gen_extra("GATEWAY_INTERFACE", CGI_VERSION, 0); common_cgi_env[common_cgi_env_count++] = env_gen_extra("SERVER_PORT", simple_itoa(server_port), 0); /* NCSA and APACHE added -- not in CGI spec */ #ifdef USE_NCSA_CGI_ENV common_cgi_env[common_cgi_env_count++] = env_gen_extra("DOCUMENT_ROOT", document_root, 0); /* NCSA added */ common_cgi_env[common_cgi_env_count++] = env_gen_extra("SERVER_ROOT", server_root, 0); #endif /* APACHE added */ common_cgi_env[common_cgi_env_count++] = env_gen_extra("SERVER_ADMIN", server_admin, 0); common_cgi_env[common_cgi_env_count] = NULL; /* Sanity checking -- make *sure* the memory got allocated */ if (common_cgi_env_count != COMMON_CGI_COUNT) { log_error_time(); fprintf(stderr, "COMMON_CGI_COUNT not high enough.\n"); exit(EXIT_FAILURE); } for (i = 0; i < common_cgi_env_count; ++i) { if (common_cgi_env[i] == NULL) { log_error_time(); fprintf(stderr, "Unable to allocate a component of common_cgi_env - out of memory.\n"); exit(EXIT_FAILURE); } } } void add_to_common_env(char *key, char *value) { common_cgi_env = realloc(common_cgi_env, (common_cgi_env_count + 2) * (sizeof(char *))); if (common_cgi_env== NULL) { DIE("Unable to allocate memory for common CGI environment variable."); } common_cgi_env[common_cgi_env_count] = env_gen_extra(key,value, 0); if (common_cgi_env[common_cgi_env_count] == NULL) { /* errors already reported */ DIE("memory allocation failure in add_to_common_env"); } common_cgi_env[++common_cgi_env_count] = NULL; /* I find it hard to believe that somebody would actually * make 90+ *common* CGI variables, but it's always better * to be safe. */ if (common_cgi_env_count > CGI_ENV_MAX) { DIE("far too many common CGI environment variables added."); } } void clear_common_env(void) { int i; for (i = 0; i <= COMMON_CGI_COUNT; ++i) { if (common_cgi_env[i] != NULL) { free(common_cgi_env[i]); common_cgi_env[i] = NULL; } } } /* * Name: env_gen_extra * (and via a not-so-tricky #define, env_gen) * This routine calls malloc: please free the memory when you are done */ static char *env_gen_extra(const char *key, const char *value, unsigned int extra) { char *result; unsigned int key_len, value_len; if (value == NULL) /* ServerAdmin may not be defined, eg */ value = ""; key_len = strlen(key); value_len = strlen(value); /* leave room for '=' sign and null terminator */ result = malloc(extra + key_len + value_len + 2); if (result) { memcpy(result + extra, key, key_len); *(result + extra + key_len) = '='; memcpy(result + extra + key_len + 1, value, value_len); *(result + extra + key_len + value_len + 1) = '\0'; } else { log_error_time(); perror("malloc"); log_error_time(); fprintf(stderr, "tried to allocate (key=value) extra=%u: %s=%s\n", extra, key, value); } return result; } /* * Name: add_cgi_env * * Description: adds a variable to CGI's environment * Used for HTTP_ headers */ int add_cgi_env(request * req, const char *key, const char *value, int http_prefix) { char *p; unsigned int prefix_len; if (http_prefix) { prefix_len = 5; } else { prefix_len = 0; } if (req->cgi_env_index < CGI_ENV_MAX) { p = env_gen_extra(key, value, prefix_len); if (!p) { log_error_doc(req); fprintf(stderr, "Unable to generate additional CGI environment " "variable -- ran out of memory!\n"); return 0; } if (prefix_len) memcpy(p, "HTTP_", 5); req->cgi_env[req->cgi_env_index++] = p; return 1; } log_error_doc(req); fprintf(stderr, "Unable to generate additional CGI Environment " "variable \"%s%s=%s\" -- not enough space!\n", (prefix_len ? "HTTP_" : ""), key, value); return 0; } #define my_add_cgi_env(req, key, value) { \ int ok = add_cgi_env(req, key, value, 0); \ if (!ok) return 0; \ } /* * Name: complete_env * * Description: adds the known client header env variables * and terminates the environment array */ static int complete_env(request * req) { int i; for (i = 0; common_cgi_env[i]; i++) req->cgi_env[i] = common_cgi_env[i]; { const char *w; switch (req->method) { case M_POST: w = "POST"; break; case M_HEAD: w = "HEAD"; break; case M_GET: w = "GET"; break; default: w = "UNKNOWN"; break; } my_add_cgi_env(req, "REQUEST_METHOD", w); } if (req->header_host) my_add_cgi_env(req, "HTTP_HOST", req->header_host); my_add_cgi_env(req, "SERVER_ADDR", req->local_ip_addr); my_add_cgi_env(req, "SERVER_PROTOCOL", http_ver_string(req->http_version)); my_add_cgi_env(req, "REQUEST_URI", req->request_uri); if (req->path_info) my_add_cgi_env(req, "PATH_INFO", req->path_info); if (req->path_translated) /* while path_translated depends on path_info, * there are cases when path_translated might * not exist when path_info does */ my_add_cgi_env(req, "PATH_TRANSLATED", req->path_translated); my_add_cgi_env(req, "SCRIPT_NAME", req->script_name); if (req->query_string) my_add_cgi_env(req, "QUERY_STRING", req->query_string); my_add_cgi_env(req, "REMOTE_ADDR", req->remote_ip_addr); my_add_cgi_env(req, "REMOTE_PORT", simple_itoa(req->remote_port)); if (req->method == M_POST) { if (req->content_type) { my_add_cgi_env(req, "CONTENT_TYPE", req->content_type); } else { my_add_cgi_env(req, "CONTENT_TYPE", default_type); } if (req->content_length) { my_add_cgi_env(req, "CONTENT_LENGTH", req->content_length); } } #ifdef ACCEPT_ON if (req->accept[0]) my_add_cgi_env(req, "HTTP_ACCEPT", req->accept); #endif if (req->cgi_env_index < CGI_ENV_MAX + 1) { req->cgi_env[req->cgi_env_index] = NULL; /* terminate */ return 1; } log_error_doc(req); fprintf(stderr, "Not enough space in CGI environment for remainder" " of variables.\n"); return 0; } /* * Name: make_args_cgi * * Build argv list for a CGI script according to spec * */ static void create_argv(request * req, char **aargv) { char *p, *q, *r; int aargc; q = req->query_string; aargv[0] = req->pathname; /* here, we handle a special "indexed" query string. * Taken from the CGI/1.1 SPEC: * This is identified by a GET or HEAD request with a query string * with no *unencoded* '=' in it. * For such a request, I'm supposed to parse the search string * into words, according to the following rules: search-string = search-word *( "+" search-word ) search-word = 1*schar schar = xunreserved | escaped | xreserved xunreserved = alpha | digit | xsafe | extra xsafe = "$" | "-" | "_" | "." xreserved = ";" | "/" | "?" | ":" | "@" | "&" After parsing, each word is URL-decoded, optionally encoded in a system defined manner, and then the argument list is set to the list of words. Thus, schar is alpha|digit|"$"|"-"|"_"|"."|";"|"/"|"?"|":"|"@"|"&" As of this writing, escape.pl escapes the following chars: "-", "_", ".", "!", "~", "*", "'", "(", ")", "0".."9", "A".."Z", "a".."z", ";", "/", "?", ":", "@", "&", "=", "+", "\$", "," Which therefore means "=", "+", "~", "!", "*", "'", "(", ")", "," are *not* escaped and should be? Wait, we don't do any escaping, and nor should we. According to the RFC draft, we unescape and then re-escape in a "system defined manner" (here: none). The CGI/1.1 draft (03, latest is 1999???) is very unclear here. I am using the latest published RFC, 2396, for what does and does not need escaping. Since boa builds the argument list and does not call /bin/sh, (boa uses execve for CGI) */ if (q && !strchr(q, '=')) { /* we have an 'index' style */ q = strdup(q); if (!q) { log_error_doc(req); fputs("unable to strdup 'q' in create_argv!\n", stderr); _exit(EXIT_FAILURE); } for (aargc = 1; q && (aargc < CGI_ARGC_MAX);) { r = q; /* for an index-style CGI, + is used to separate arguments * an escaped '+' is of no concern to us */ if ((p = strchr(q, '+'))) { *p = '\0'; q = p + 1; } else { q = NULL; } if (unescape_uri(r, NULL)) { /* printf("parameter %d: %s\n",aargc,r); */ aargv[aargc++] = r; } } aargv[aargc] = NULL; } else { aargv[1] = NULL; } } /* * Name: init_cgi * * Description: Called for GET/POST requests that refer to ScriptAlias * directories or application/x-httpd-cgi files. Ties stdout to socket, * stdin to data if POST, and execs CGI. * stderr remains tied to our log file; is this good? * * Returns: * 0 - error or NPH, either way the socket is closed * 1 - success */ int init_cgi(request * req) { int child_pid; int pipes[2]; int use_pipes = 0; SQUASH_KA(req); if (req->cgi_type) { if (complete_env(req) == 0) { return 0; } } DEBUG(DEBUG_CGI_ENV) { int i; for (i = 0; i < req->cgi_env_index; ++i) log_error_time(); fprintf(stderr, "%s - environment variable for cgi: \"%s\"\n", __FILE__, req->cgi_env[i]); } /* we want to use pipes whenever it's a CGI or directory */ /* otherwise (NPH, gunzip) we want no pipes */ if (req->cgi_type == CGI || (!req->cgi_type && (req->pathname[strlen(req->pathname) - 1] == '/'))) { use_pipes = 1; if (pipe(pipes) == -1) { log_error_doc(req); perror("pipe"); return 0; } /* set the read end of the socket to non-blocking */ if (set_nonblock_fd(pipes[0]) == -1) { log_error_doc(req); perror("cgi-fcntl"); close(pipes[0]); close(pipes[1]); return 0; } } child_pid = fork(); switch (child_pid) { case -1: /* fork unsuccessful */ /* FIXME: There is a problem here. send_r_error (called by * boa_perror) would work for NPH and CGI, but not for GUNZIP. * Fix that. */ boa_perror(req, "fork failed"); if (use_pipes) { close(pipes[0]); close(pipes[1]); } return 0; break; case 0: /* child */ reset_signals(); if (req->cgi_type == CGI || req->cgi_type == NPH) { char *c; unsigned int l; char *newpath, *oldpath; c = strrchr(req->pathname, '/'); if (!c) { /* there will always be a '.' */ log_error_doc(req); fprintf(stderr, "unable to find '/' in req->pathname: \"%s\"\n", req->pathname); if (use_pipes) close(pipes[1]); _exit(EXIT_FAILURE); } *c = '\0'; if (chdir(req->pathname) != 0) { int saved_errno = errno; log_error_doc(req); fprintf(stderr, "Could not chdir to \"%s\":", req->pathname); errno = saved_errno; perror("chdir"); if (use_pipes) close(pipes[1]); _exit(EXIT_FAILURE); } oldpath = req->pathname; req->pathname = ++c; l = strlen(req->pathname) + 3; /* prefix './' */ newpath = malloc(sizeof (char) * l); if (!newpath) { /* there will always be a '.' */ log_error_doc(req); perror("unable to malloc for newpath"); if (use_pipes) close(pipes[1]); _exit(EXIT_FAILURE); } newpath[0] = '.'; newpath[1] = '/'; memcpy(&newpath[2], req->pathname, l - 2); /* includes the trailing '\0' */ free(oldpath); req->pathname = newpath; } if (use_pipes) { /* close the 'read' end of the pipes[] */ close(pipes[0]); /* tie CGI's STDOUT to our write end of pipe */ if (dup2(pipes[1], STDOUT_FILENO) == -1) { log_error_doc(req); perror("dup2 - pipes"); _exit(EXIT_FAILURE); } close(pipes[1]); } else { /* tie stdout to socket */ if (dup2(req->fd, STDOUT_FILENO) == -1) { log_error_doc(req); perror("dup2 - fd"); _exit(EXIT_FAILURE); } close(req->fd); } /* Switch socket flags back to blocking */ if (set_block_fd(STDOUT_FILENO) == -1) { log_error_doc(req); perror("cgi-fcntl"); _exit(EXIT_FAILURE); } /* tie post_data_fd to POST stdin */ if (req->method == M_POST) { /* tie stdin to file */ lseek(req->post_data_fd, SEEK_SET, 0); dup2(req->post_data_fd, STDIN_FILENO); close(req->post_data_fd); } #ifdef USE_SETRLIMIT /* setrlimit stuff. * This is neat! * RLIMIT_STACK max stack size * RLIMIT_CORE max core file size * RLIMIT_RSS max resident set size * RLIMIT_NPROC max number of processes * RLIMIT_NOFILE max number of open files * RLIMIT_MEMLOCK max locked-in-memory address space * RLIMIT_AS address space (virtual memory) limit * * RLIMIT_CPU CPU time in seconds * RLIMIT_DATA max data size * * Currently, we only limit the CPU time and the DATA segment * We also "nice" the process. * * This section of code adapted from patches sent in by Steve Thompson * (no email available) */ { struct rlimit rl; int retval; if (cgi_rlimit_cpu) { rl.rlim_cur = rl.rlim_max = cgi_rlimit_cpu; retval = setrlimit(RLIMIT_CPU, &rl); if (retval == -1) { log_error_time(); fprintf(stderr, "setrlimit(RLIMIT_CPU,%d): %s\n", rlimit_cpu, strerror(errno)); _exit(EXIT_FAILURE); } } if (cgi_limit_data) { rl.rlim_cur = rl.rlim_max = cgi_rlimit_data; retval = setrlimit(RLIMIT_DATA, &rl); if (retval == -1) { log_error_time(); fprintf(stderr, "setrlimit(RLIMIT_DATA,%d): %s\n", rlimit_data, strerror(errno)); _exit(EXIT_FAILURE); } } if (cgi_nice) { retval = nice(cgi_nice); if (retval == -1) { log_error_time(); perror("nice"); _exit(EXIT_FAILURE); } } } #endif umask(cgi_umask); /* change umask *again* u=rwx,g=rxw,o= */ /* * tie STDERR to cgi_log_fd * cgi_log_fd will automatically close, close-on-exec rocks! * if we don't tie STDERR (current log_error) to cgi_log_fd, * then we ought to tie it to /dev/null * FIXME: we currently don't tie it to /dev/null, we leave it * tied to whatever 'error_log' points to. This means CGIs can * scribble on the error_log, probably a bad thing. */ if (cgi_log_fd) { dup2(cgi_log_fd, STDERR_FILENO); } if (req->cgi_type) { char *aargv[CGI_ARGC_MAX + 1]; create_argv(req, aargv); execve(req->pathname, aargv, req->cgi_env); } else { if (req->pathname[strlen(req->pathname) - 1] == '/') execl(dirmaker, dirmaker, req->pathname, req->request_uri, (void *) NULL); #ifdef GUNZIP else execl(GUNZIP, GUNZIP, "--stdout", "--decompress", req->pathname, (void *) NULL); #endif } /* execve failed */ log_error_doc(req); fprintf(stderr, "Unable to execve/execl pathname: \"%s\"", req->pathname); perror(""); _exit(EXIT_FAILURE); break; default: /* parent */ /* if here, fork was successful */ if (verbose_cgi_logs) { log_error_time(); fprintf(stderr, "Forked child \"%s\" pid %d\n", req->pathname, child_pid); } if (req->method == M_POST) { close(req->post_data_fd); /* child closed it too */ req->post_data_fd = 0; } /* NPH, GUNZIP, etc... all go straight to the fd */ if (!use_pipes) return 0; close(pipes[1]); req->data_fd = pipes[0]; req->status = PIPE_READ; if (req->cgi_type == CGI) { req->cgi_status = CGI_PARSE; /* got to parse cgi header */ /* for cgi_header... I get half the buffer! */ req->header_line = req->header_end = (req->buffer + BUFFER_SIZE / 2); } else { req->cgi_status = CGI_BUFFER; /* I get all the buffer! */ req->header_line = req->header_end = req->buffer; } /* reset req->filepos for logging (it's used in pipe.c) */ /* still don't know why req->filesize might be reset though */ req->filepos = 0; break; } return 1; } boa-0.94.14rc21/src/cgi_header.c0000644000175000001440000001335210206636621016764 0ustar jnelsonusers00000000000000/* * Boa, an http server * cgi_header.c - cgi header parsing and control * Copyright (C) 1997-2003 Jon Nelson * * 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 1, 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. * */ #include "boa.h" /* process_cgi_header * returns 0 -=> error or HEAD, close down. * returns 1 -=> done processing * leaves req->cgi_status as WRITE */ /* The server MUST also resolve any conflicts between header fields returned by the script and header fields that it would otherwise send itself. ... At least one CGI-Field MUST be supplied, but no CGI field name may be used more than once in a response. If a body is supplied, then a "Content-type" header field MUST be supplied by the script, otherwise the script MUST send a "Location" or "Status" header field. If a Location CGI-Field is returned, then the script MUST NOT supply any HTTP-Fields. */ /* TODO: We still need to cycle through the data before the end of the headers, line-by-line, and check for any problems with the CGI outputting overriding http responses, etc... */ int process_cgi_header(request * req) { char *buf; char *c; if (req->cgi_status != CGI_DONE) req->cgi_status = CGI_BUFFER; buf = req->header_line; c = strstr(buf, "\n\r\n"); if (c == NULL) { c = strstr(buf, "\n\n"); if (c == NULL) { log_error_doc(req); fputs("cgi_header: unable to find LFLF\n", stderr); #ifdef FASCIST_LOGGING log_error_time(); fprintf(stderr, "\"%s\"\n", buf); #endif send_r_bad_gateway(req); return 0; } } if (req->http_version == HTTP09) { if (*(c + 1) == '\r') req->header_line = c + 2; else req->header_line = c + 1; return 1; } if (!strncasecmp(buf, "Status: ", 8)) { req->header_line--; memcpy(req->header_line, "HTTP/1.0 ", 9); } else if (!strncasecmp(buf, "Location: ", 10)) { /* got a location header */ #ifdef FASCIST_LOGGING log_error_time(); fprintf(stderr, "%s:%d - found Location header \"%s\"\n", __FILE__, __LINE__, buf + 10); #endif if (buf[10] == '/') { /* virtual path */ log_error_doc(req); fprintf(stderr, "server does not support internal redirection: " "\"%s\"\n", buf + 10); send_r_bad_request(req); /* * We (I, Jon) have declined to support absolute-path parsing * because I see it as a major security hole. * Location: /etc/passwd or Location: /etc/shadow is not funny. * * Also, the below code is borked. * request_uri could contain /cgi-bin/bob/extra_path */ /* strcpy(req->request_uri, buf + 10); return internal_redirect(req); */ } else { /* URL */ char *c2; c2 = strchr(buf + 10, '\n'); /* c2 cannot ever equal NULL here because we already have found one */ --c2; while (*c2 == '\r') --c2; ++c2; /* c2 now points to a '\r' or the '\n' */ *c2++ = '\0'; /* end header */ /* first next header, or is at req->header_end */ while ((*c2 == '\n' || *c2 == '\r') && c2 < req->header_end) ++c2; if (c2 == req->header_end) send_r_moved_temp(req, buf + 10, ""); else send_r_moved_temp(req, buf + 10, c2); } req->status = DONE; return 1; } else { /* not location and not status */ char *dest; unsigned int howmuch; send_r_request_ok(req); /* does not terminate */ /* got to do special things because a) we have a single buffer divided into 2 pieces b) we need to merge those pieces Easiest way is to memmove the cgi data backward until it touches the buffered data, then reset the cgi data pointers */ dest = req->buffer + req->buffer_end; if (req->method == M_HEAD) { if (*(c + 1) == '\r') req->header_end = c + 2; else req->header_end = c + 1; req->cgi_status = CGI_DONE; } howmuch = req->header_end - req->header_line; if (dest + howmuch > req->buffer + BUFFER_SIZE) { /* big problem */ log_error_doc(req); fprintf(stderr, "Too much data to move! Aborting! %s %d\n", __FILE__, __LINE__); /* reset buffer pointers because we already called send_r_request_ok... */ req->buffer_start = req->buffer_end = 0; send_r_error(req); return 0; } memmove(dest, req->header_line, howmuch); req->buffer_end += howmuch; req->header_line = req->buffer + req->buffer_end; req->header_end = req->header_line; req_flush(req); if (req->method == M_HEAD) return 0; } return 1; } boa-0.94.14rc21/src/compat.h0000644000175000001440000000724410206636621016205 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1999 Larry Doolittle * Copyright (C) 1999-2005 Jon Nelson * * 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 1, 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. * */ /* $Id: compat.h,v 1.18.2.12 2005/02/22 14:11:29 jnelson Exp $*/ #ifndef _COMPAT_H #define _COMPAT_H #include "config.h" #ifdef HAVE_POLL #include #else #include #endif /* HAVE_POLL */ #ifdef TIME_WITH_SYS_TIME #include #endif #ifdef HAVE_SYS_FCNTL_H #include #endif #ifndef OPEN_MAX #define OPEN_MAX 256 #endif #ifdef FD_SETSIZE #define MAX_FD FD_SETSIZE #else #define MAX_FD OPEN_MAX #endif /* FD_SETSIZE */ #include #ifndef SO_MAXCONN #define SO_MAXCONN 250 #endif #ifndef PATH_MAX #define PATH_MAX 2048 #endif /* Wild guess time, probably better done with configure */ #ifdef O_NONBLOCK #define NOBLOCK O_NONBLOCK /* Linux */ #else /* O_NONBLOCK */ #ifdef O_NDELAY #define NOBLOCK O_NDELAY /* Sun */ #else /* O_NDELAY */ #error "Can't find a way to #define NOBLOCK" #endif /* O_NDELAY */ #endif /* O_NONBLOCK */ #ifndef MAP_FILE #define MAP_OPTIONS MAP_PRIVATE /* Sun */ #else #define MAP_OPTIONS MAP_FILE|MAP_PRIVATE /* Linux */ #endif #include #ifdef INET6 /* #define S_FAMILY __s_family */ #define SOCKADDR sockaddr_storage #define SERVER_PF PF_INET6 #define S_FAMILY sin6_family #ifndef NI_MAXHOST #error NI_MAXHOST undefined!! #endif /* ifndef NI_MAXHOST */ #define BOA_NI_MAXHOST NI_MAXHOST #else /* ifdef INET6 */ #define SOCKADDR sockaddr_in #define SERVER_PF PF_INET #define S_FAMILY sin_family #define BOA_NI_MAXHOST 20 #endif /* ifdef INET6 */ #if HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif /* below here, functions are provided in extras */ #ifndef HAVE_SCANDIR int scandir(const char *dir, struct dirent ***namelist, int (*select) (const struct dirent *), int (*compar) (const struct dirent **, const struct dirent **)); #endif #ifndef HAVE_ALPHASORT int alphasort(const struct dirent **a, const struct dirent **b); #endif #ifndef HAVE_STRSTR char *strstr(char *s1, char *s2); #endif #ifndef HAVE_STRDUP char *strdup(char *s); #endif #ifdef HAVE_TM_GMTOFF #define TIMEZONE_OFFSET(foo) foo->tm_gmtoff #else #define TIMEZONE_OFFSET(foo) timezone #endif #ifdef HAVE_TM_ZONE #define TIMEZONE(foo) foo->tm_zone #else #define TIMEZONE(foo) *tzname #endif #ifdef HAVE_LIBDMALLOC #define DMALLOC_FUNC_CHECK #include #endif #ifdef HAVE_GETOPT_H #include #endif #ifdef DONT_HAVE_SA_FAMILY_T /* POSIX.1g specifies this type name for the `sa_family' member. */ typedef unsigned short int sa_family_t; #endif #endif boa-0.94.14rc21/src/config.c0000644000175000001440000003723610206636621016166 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1999-2005 Larry Doolittle * Copyright (C) 2000-2005 Jon Nelson * * 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 1, 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. * */ /* $Id: config.c,v 1.31.2.30 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" #include "access.h" #include const char *config_file_name; unsigned int server_port; uid_t server_uid; gid_t server_gid; char *server_root; char *server_name; char *server_admin; char *server_ip; int virtualhost; char *vhost_root; const char *default_vhost; unsigned max_connections; char *document_root; char *user_dir; char *directory_index; char *default_type; char *default_charset; char *dirmaker; char *cachedir; const char *tempdir; unsigned int cgi_umask = 027; char *pid_file; char *cgi_path; int single_post_limit = SINGLE_POST_LIMIT_DEFAULT; int conceal_server_identity = 0; int ka_timeout; unsigned int default_timeout; unsigned int ka_max; /* These came from log.c */ char *error_log_name; char *access_log_name; char *cgi_log_name; int use_localtime; #ifdef USE_SETRLIMIT extern int cgi_rlimit_cpu; /* boa.c */ extern int cgi_rlimit_data; /* boa.c */ extern int cgi_nice; /* boa.c */ #endif /* These are new */ static void c_add_cgi_env(char *v1, char *v2, void *table_ptr); static void c_set_user(char *v1, char *v2, void *t); static void c_set_group(char *v1, char *v2, void *t); static void c_set_string(char *v1, char *v2, void *t); static void c_set_int(char *v1, char *v2, void *t); static void c_set_unity(char *v1, char *v2, void *t); static void c_add_mime_types_file(char *v1, char *v2, void *t); static void c_add_mime_type(char *v1, char *v2, void *t); static void c_add_alias(char *v1, char *v2, void *t); static void c_add_access(char *v1, char *v2, void *t); struct ccommand { const char *name; const int type; void (*action) (char *, char *, void *); void *object; }; typedef struct ccommand Command; static void apply_command(Command * p, char *args); static void trim(char *s); static void parse(FILE * f); /* Fakery to keep the value passed to action() a void *, see usage in table and c_add_alias() below */ static enum ALIAS script_number = SCRIPTALIAS; static enum ALIAS redirect_number = REDIRECT; static enum ALIAS alias_number = ALIAS; static int access_allow_number = ACCESS_ALLOW; static int access_deny_number = ACCESS_DENY; static uid_t current_uid = 0; /* Help keep the table below compact */ #define STMT_NO_ARGS 1 #define STMT_ONE_ARG 2 #define STMT_TWO_ARGS 3 #define S0A STMT_NO_ARGS #define S1A STMT_ONE_ARG #define S2A STMT_TWO_ARGS /* function prototype */ Command *lookup_keyword(char *c); struct ccommand clist[] = { {"Port", S1A, c_set_int, &server_port}, {"Listen", S1A, c_set_string, &server_ip}, {"BackLog", S1A, c_set_int, &backlog}, {"User", S1A, c_set_user, NULL}, {"Group", S1A, c_set_group, NULL}, {"ServerAdmin", S1A, c_set_string, &server_admin}, {"ServerRoot", S1A, c_set_string, &server_root}, {"UseLocaltime", S0A, c_set_unity, &use_localtime}, {"ErrorLog", S1A, c_set_string, &error_log_name}, {"AccessLog", S1A, c_set_string, &access_log_name}, {"CgiLog", S1A, c_set_string, &cgi_log_name}, /* compatibility with CGILog */ {"CGILog", S1A, c_set_string, &cgi_log_name}, {"VerboseCGILogs", S0A, c_set_unity, &verbose_cgi_logs}, {"ServerName", S1A, c_set_string, &server_name}, {"VirtualHost", S0A, c_set_unity, &virtualhost}, {"VHostRoot", S1A, c_set_string, &vhost_root}, {"DefaultVHost", S1A, c_set_string, &default_vhost}, {"DocumentRoot", S1A, c_set_string, &document_root}, {"UserDir", S1A, c_set_string, &user_dir}, {"DirectoryIndex", S1A, c_set_string, &directory_index}, {"DirectoryMaker", S1A, c_set_string, &dirmaker}, {"DirectoryCache", S1A, c_set_string, &cachedir}, {"PidFile", S1A, c_set_string, &pid_file}, {"KeepAliveMax", S1A, c_set_int, &ka_max}, {"KeepAliveTimeout", S1A, c_set_int, &ka_timeout}, {"MimeTypes", S1A, c_add_mime_types_file, NULL}, {"DefaultType", S1A, c_set_string, &default_type}, {"DefaultCharset", S1A, c_set_string, &default_charset}, {"AddType", S2A, c_add_mime_type, NULL}, {"ScriptAlias", S2A, c_add_alias, &script_number}, {"Redirect", S2A, c_add_alias, &redirect_number}, {"Alias", S2A, c_add_alias, &alias_number}, {"SinglePostLimit", S1A, c_set_int, &single_post_limit}, {"CGIPath", S1A, c_set_string, &cgi_path}, {"CGIumask", S1A, c_set_int, &cgi_umask}, {"MaxConnections", S1A, c_set_int, &max_connections}, {"ConcealServerIdentity", S0A, c_set_unity, &conceal_server_identity}, {"Allow", S1A, c_add_access, &access_allow_number}, {"Deny", S1A, c_add_access, &access_deny_number}, #ifdef USE_SETRLIMIT {"CGIRlimitCpu", S2A, c_set_int, &cgi_rlimit_cpu}, {"CGIRlimitData", S2A, c_set_int, &cgi_rlimit_data}, {"CGINice", S2A, c_set_int, &cgi_nice}, #endif {"CGIEnv", S2A, c_add_cgi_env, NULL}, }; static void c_add_cgi_env(char *v1, char *v2, void *t) { add_to_common_env(v1, v2); } static void c_set_user(char *v1, char *v2, void *t) { struct passwd *passwdbuf; char *endptr; int i; DEBUG(DEBUG_CONFIG) { log_error_time(); printf("User %s = ", v1); } i = strtol(v1, &endptr, 0); if (*v1 != '\0' && *endptr == '\0') { server_uid = i; } else { passwdbuf = getpwnam(v1); if (!passwdbuf) { log_error_time(); fprintf(stderr, "No such user: %s\n", v1); if (current_uid) return; exit(EXIT_FAILURE); } server_uid = passwdbuf->pw_uid; } DEBUG(DEBUG_CONFIG) { printf("%d\n", server_uid); } } static void c_set_group(char *v1, char *v2, void *t) { struct group *groupbuf; char *endptr; int i; DEBUG(DEBUG_CONFIG) { log_error_time(); printf("Group %s = ", v1); } i = strtol(v1, &endptr, 0); if (*v1 != '\0' && *endptr == '\0') { server_gid = i; } else { groupbuf = getgrnam(v1); if (!groupbuf) { log_error_time(); fprintf(stderr, "No such group: %s\n", v1); if (current_uid) return; exit(EXIT_FAILURE); } server_gid = groupbuf->gr_gid; } DEBUG(DEBUG_CONFIG) { printf("%d\n", server_gid); } } static void c_set_string(char *v1, char *v2, void *t) { DEBUG(DEBUG_CONFIG) { log_error_time(); printf("Setting pointer %p to string %s ..", t, v1); } if (t) { if (*(char **) t != NULL) free(*(char **) t); *(char **) t = strdup(v1); if (!*(char **) t) { DIE("Unable to strdup in c_set_string"); } DEBUG(DEBUG_CONFIG) { printf("done.\n"); } } else { DEBUG(DEBUG_CONFIG) { printf("skipped.\n"); } } } static void c_set_int(char *v1, char *v2, void *t) { char *endptr; int i; DEBUG(DEBUG_CONFIG) { log_error_time(); printf("Setting pointer %p to integer string %s ..", t, v1); } if (t) { i = strtol(v1, &endptr, 0); /* Automatic base 10/16/8 switching */ if (*v1 != '\0' && *endptr == '\0') { *(int *) t = i; DEBUG(DEBUG_CONFIG) { printf(" Integer converted as %d, done\n", i); } } else { /* XXX should tell line number to user */ fprintf(stderr, "Error: %s found where integer expected\n", v1); } } else { DEBUG(DEBUG_CONFIG) { printf("skipped.\n"); } } } static void c_set_unity(char *v1, char *v2, void *t) { DEBUG(DEBUG_CONFIG) { log_error_time(); printf("Setting pointer %p to unity\n", t); } if (t) *(int *) t = 1; } static void c_add_mime_type(char *v1, char *v2, void *t) { add_mime_type(v2, v1); } static void c_add_mime_types_file(char *v1, char *v2, void *t) { /* v1 is the file */ FILE *f; char buf[256], *p; char *type, *extension, *c2; int len; f = fopen(v1, "r"); if (f == NULL) DIE("Can't open mime-types file"); while (fgets(buf, 255, f) != NULL) { if (buf[0] == '\0' || buf[0] == '#' || buf[0] == '\n') continue; c2 = strchr(buf, '\n'); if (c2) *c2 = '\0'; len = strcspn(buf, "\t "); if (!len) { DEBUG(DEBUG_CONFIG) { log_error_time(); fprintf(stderr, "Improperly formatted mime-type: \"%s\"\n", buf); } continue; } buf[len] = '\0'; type = buf; for (p = buf + len + 1; *p; ++p) { if (isalnum(*p)) break; } for (len = strcspn(p, "\t "); len; len = strcspn(p, "\t ")) { p[len] = '\0'; extension = p; add_mime_type(extension, type); /* blah blah */ for (p = p + len + 1; *p; ++p) { if (isalnum(*p)) break; } } } fclose(f); } static void c_add_alias(char *v1, char *v2, void *t) { DEBUG(DEBUG_CONFIG) { log_error_time(); printf("Calling add_alias with args \"%s\", \"%s\", and %d\n", v1, v2, *(int *) t); } add_alias(v1, v2, *(enum ALIAS *) t); } static void c_add_access(char *v1, char *v2, void *t) { #ifdef ACCESS_CONTROL access_add(v1, *(int *) t); #else log_error_time(); fprintf(stderr, "This version of Boa doesn't support access controls.\n" "Please recompile with --enable-access-control.\n"); #endif /* ACCESS_CONTROL */ } struct ccommand *lookup_keyword(char *c) { struct ccommand *p; DEBUG(DEBUG_CONFIG) { log_error_time(); printf("Checking string '%s' against keyword list\n", c); } for (p = clist; p < clist + (sizeof (clist) / sizeof (struct ccommand)); p++) { if (strcasecmp(c, p->name) == 0) return p; } return NULL; } static void apply_command(Command * p, char *args) { char *second; switch (p->type) { case STMT_NO_ARGS: (p->action) (NULL, NULL, p->object); break; case STMT_ONE_ARG: (p->action) (args, NULL, p->object); break; case STMT_TWO_ARGS: /* FIXME: if no 2nd arg exists, we use NULL. Desirable? */ while (isspace(*args)) ++args; if (*args == '\0') { log_error_time(); fprintf(stderr, "expected at least 1 arg! (%s)\n", p->name); exit(EXIT_FAILURE); } second = args; while (!isspace(*second)) ++second; if (*second == '\0') { /* nuthin but spaces */ second = NULL; } else { *second = '\0'; ++second; while (isspace(*second)) ++second; if (*second == '\0') { second = NULL; } } (p->action) (args, second, p->object); break; default: exit(EXIT_FAILURE); } } static void trim(char *s) { char *c = s + strlen(s) - 1; while (isspace(*c) && c > s) { *c = '\0'; --c; } } static void parse(FILE * f) { char buf[1025], *c; Command *p; int line = 0; current_uid = getuid(); while (fgets(buf, 1024, f) != NULL) { ++line; if (buf[0] == '\0' || buf[0] == '#' || buf[0] == '\n') continue; /* kill the linefeed and any trailing whitespace */ trim(buf); if (buf[0] == '\0') continue; /* look for multiple arguments */ c = buf; while (!isspace(*c)) ++c; if (*c == '\0') { /* no args */ c = NULL; } else { /* one or more args */ *c = '\0'; ++c; } p = lookup_keyword(buf); if (!p) { log_error_time(); fprintf(stderr, "Line %d: Did not find keyword \"%s\"\n", line, buf); exit(EXIT_FAILURE); } else { DEBUG(DEBUG_CONFIG) { log_error_time(); fprintf(stderr, "Found keyword %s in \"%s\" (%s)!\n", p->name, buf, c); } apply_command(p, c); } } } /* * Name: read_config_files * * Description: Reads config files, then makes sure that * all required variables were set properly. */ void read_config_files(void) { FILE *config; current_uid = getuid(); if (!config_file_name) { config_file_name = DEFAULT_CONFIG_FILE; } #ifdef ACCESS_CONTROL access_init(); #endif /* ACCESS_CONTROL */ config = fopen(config_file_name, "r"); if (!config) { fputs("Could not open boa.conf for reading.\n", stderr); exit(EXIT_FAILURE); } parse(config); fclose(config); if (!server_name) { struct hostent *he; char temp_name[100]; if (gethostname(temp_name, 100) == -1) { perror("gethostname:"); exit(EXIT_FAILURE); } he = gethostbyname(temp_name); if (he == NULL) { perror("gethostbyname:"); exit(EXIT_FAILURE); } server_name = strdup(he->h_name); if (server_name == NULL) { perror("strdup:"); exit(EXIT_FAILURE); } } tempdir = getenv("TMP"); if (tempdir == NULL) tempdir = "/tmp"; if (single_post_limit < 0) { fprintf(stderr, "Invalid value for single_post_limit: %d\n", single_post_limit); exit(EXIT_FAILURE); } if (vhost_root && virtualhost) { fprintf(stderr, "Both VHostRoot and VirtualHost were enabled, and " "they are mutually exclusive.\n"); exit(EXIT_FAILURE); } if (vhost_root && document_root) { fprintf(stderr, "Both VHostRoot and DocumentRoot were enabled, and " "they are mutually exclusive.\n"); exit(EXIT_FAILURE); } if (!default_vhost) { default_vhost = DEFAULT_VHOST; } #ifdef USE_SETRLIMIT if (cgi_rlimit_cpu < 0) cgi_rlimit_cpu = 0; if (cgi_rlimit_data < 0) cgi_rlimit_data = 0; if (cgi_nice < 0) cgi_nice = 0; #endif if (max_connections < 1) { struct rlimit rl; int c; /* has not been set explicitly */ c = getrlimit(RLIMIT_NOFILE, &rl); if (c < 0) { DIE("getrlimit"); } max_connections = rl.rlim_cur; } if (max_connections > FD_SETSIZE - 20) max_connections = FD_SETSIZE - 20; if (ka_timeout < 0) ka_timeout=0; /* not worth a message */ /* save some time */ default_timeout = (ka_timeout ? ka_timeout : REQUEST_TIMEOUT); #ifdef HAVE_POLL default_timeout *= 1000; #endif if (default_type == NULL) { DIE("DefaultType *must* be set!"); } } boa-0.94.14rc21/src/config.h.in0000644000175000001440000001271207737711106016577 0ustar jnelsonusers00000000000000/* src/config.h.in. Generated from configure.in by autoheader. */ /* Define if sa_family_t is not defined */ #undef DONT_HAVE_SA_FAMILY_T /* Define if gunzip can be found */ #undef GUNZIP /* Define to 1 if you have the `alphasort' function. */ #undef HAVE_ALPHASORT /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if your system has a working POSIX `fnmatch' function. */ #undef HAVE_FNMATCH /* Define if the C complier supports __func__ */ #undef HAVE_FUNC /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD /* Define to 1 if you have the `gethostbyname' function. */ #undef HAVE_GETHOSTBYNAME /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE /* Define to 1 if you have the `herror' function. */ #undef HAVE_HERROR /* Define to 1 if you have the `inet_addr' function. */ #undef HAVE_INET_ADDR /* Define to 1 if you have the `inet_aton' function. */ #undef HAVE_INET_ATON /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `dmalloc' library (-ldmalloc). */ #undef HAVE_LIBDMALLOC /* Define to 1 if you have the `efence' library (-lefence). */ #undef HAVE_LIBEFENCE /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the `madvise' function. */ #undef HAVE_MADVISE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if you have the `scandir' function. */ #undef HAVE_SCANDIR /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `sendfile' function. */ #undef HAVE_SENDFILE /* Define if struct sockaddr_in has sin_len member */ #undef HAVE_SIN_LEN /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcspn' function. */ #undef HAVE_STRCSPN /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FCNTL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SENDFILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define if struct tm has a tm_gmtoff member */ #undef HAVE_TM_GMTOFF /* Define if struct tm has tm_zone member */ #undef HAVE_TM_ZONE /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if the C compiler supports function prototypes. */ #undef PROTOTYPES /* Define to 1 if the `setvbuf' function takes the buffering type as its second argument and the buffer pointer as the third, as on System V before release 3. */ #undef SETVBUF_REVERSED /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Define like PROTOTYPES; this can be used by system headers. */ #undef __PROTOTYPES /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `int' if doesn't define. */ #undef gid_t /* Define to `long' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define to `unsigned' if does not define. */ #undef size_t /* Define to `int' if doesn't define. */ #undef uid_t boa-0.94.14rc21/src/defines.h0000644000175000001440000001342610206636621016336 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1997-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: defines.h,v 1.107.2.42 2005/02/22 14:11:29 jnelson Exp $*/ #ifndef _DEFINES_H #define _DEFINES_H /***** Change this, or use -c on the command line to specify it *****/ #ifndef SERVER_ROOT #define SERVER_ROOT "/etc/boa" #endif /* Uncomment the following #define if you don't want your logs * filled with messages about client disconnects, etc... */ /* #define QUIET_DISCONNECT 1 */ /***** Change this via the CGIPath configuration value in boa.conf *****/ #define DEFAULT_PATH "/bin:/usr/bin:/usr/local/bin" /***** Change this via the DefaultVHost configuration directive in boa.conf *****/ #define DEFAULT_VHOST "default" #define DEFAULT_CONFIG_FILE "boa.conf" /* locate me in the server root */ /***** Change this via the SinglePostLimit configuration value in boa.conf *****/ #define SINGLE_POST_LIMIT_DEFAULT 1024 * 1024 /* 1 MB */ /***** Various stuff that you may want to tweak, but probably shouldn't *****/ #define SOCKETBUF_SIZE 32768 #define CLIENT_STREAM_SIZE 8192 #define BUFFER_SIZE 4096 #define MAX_HEADER_LENGTH 1024 #define MIME_HASHTABLE_SIZE 47 #define ALIAS_HASHTABLE_SIZE 17 #define PASSWD_HASHTABLE_SIZE 47 #define REQUEST_TIMEOUT 60 #define MIME_TYPES_DEFAULT "/etc/mime.types" #define CGI_MIME_TYPE "application/x-httpd-cgi" /***** CHANGE ANYTHING BELOW THIS LINE AT YOUR OWN PERIL *****/ /***** You will probably introduce buffer overruns unless you know what you are doing *****/ #define MAX_FILE_LENGTH NAME_MAX #define MAX_PATH_LENGTH PATH_MAX #ifdef ACCEPT_ON #define MAX_ACCEPT_LENGTH MAX_HEADER_LENGTH #else #define MAX_ACCEPT_LENGTH 0 #endif #ifndef SERVER_VERSION #define SERVER_VERSION "Boa/0.94.14rc21" #endif #define CGI_VERSION "CGI/1.1" #ifdef USE_NCSA_CGI_ENV #define COMMON_CGI_COUNT 8 #else #define COMMON_CGI_COUNT 6 #endif #define CGI_ENV_MAX 100 #define CGI_ARGC_MAX 128 #define SERVER_METHOD "http" /*********** MMAP_LIST CONSTANTS ************************/ #define MMAP_LIST_SIZE 256 #define MMAP_LIST_MASK 255 #define MMAP_LIST_USE_MAX 128 #define MAX_FILE_MMAP 100 * 1024 /* 100K */ /*************** POLL / SELECT MACROS *******************/ #ifdef HAVE_POLL #define BOA_READ (POLLIN|POLLPRI|POLLHUP) #define BOA_WRITE (POLLOUT|POLLHUP) #define BOA_FD_SET(req, thefd,where) { struct pollfd *my_pfd = &pfds[pfd_len]; req->pollfd_id = pfd_len++; my_pfd->fd = thefd; my_pfd->events = where; } #define BOA_FD_CLR(req, fd, where) /* this doesn't do anything? */ #else /* SELECT */ #define BOA_READ (&block_read_fdset) #define BOA_WRITE (&block_write_fdset) #define BOA_FD_SET(req, fd, where) { FD_SET(fd, where); if (fd > max_fd) max_fd = fd; } #define BOA_FD_CLR(req, fd, where) { FD_CLR(fd, where); } #endif /******** MACROS TO CHANGE BLOCK/NON-BLOCK **************/ /* If and when everyone has a modern gcc or other near-C99 compiler, * change these to static inline functions. Also note that since * we never fuss with O_APPEND append or O_ASYNC, we shouldn't have * to perform an extra system call to F_GETFL first. */ #ifdef BOA_USE_GETFL #define set_block_fd(fd) real_set_block_fd(fd) #define set_nonblock_fd(fd) real_set_nonblock_fd(fd) #else #define set_block_fd(fd) fcntl(fd, F_SETFL, 0) #define set_nonblock_fd(fd) fcntl(fd, F_SETFL, NOBLOCK) #endif /********************* DEBUG STUFF ***********************/ extern int debug_level; #ifdef DISABLE_DEBUG #define real_debug_level 0 #else #define real_debug_level debug_level #endif #define DEBUG(foo) if (real_debug_level & foo) #define DEBUG_ALIAS (1<<0) #define DEBUG_CGI_OUTPUT (1<<1) #define DEBUG_CGI_INPUT (1<<2) #define DEBUG_CGI_ENV (1<<3) #define DEBUG_HEADER_READ (1<<4) #define DEBUG_PIPELINE (1<<5) #define DEBUG_PLUGIN_ERRORS (1<<6) #define DEBUG_RANGE (1<<7) #define DEBUG_CONFIG (1<<8) #define DEBUG_BUFFER_IO (1<<9) #define DEBUG_BODY_READ (1<<10) #define DEBUG_MMAP_CACHE (1<<11) #define DEBUG_REQUEST (1<<12) #define DEBUG_HASH (1<<13) /***************** USEFUL MACROS ************************/ #define CRLF "\r\n" #define SQUASH_KA(req) (req->keepalive=KA_STOPPED) #ifdef HAVE_FUNC #define WARN(mesg) log_error_mesg(__FILE__, __LINE__, __func__, mesg) #define DIE(mesg) log_error_mesg_fatal(__FILE__, __LINE__, __func__, mesg) #else #define WARN(mesg) log_error_mesg(__FILE__, __LINE__, mesg) #define DIE(mesg) log_error_mesg_fatal(__FILE__, __LINE__, mesg) #endif #define INT_TO_HEX(x) (((x)>9)?(('a'-10)+(x)):('0'+(x))) #define HEX_TO_DECIMAL(char1, char2) \ (((char1 >= 'A') ? (((char1 & 0xdf) - 'A') + 10) : (char1 - '0')) * 16) + \ (((char2 >= 'A') ? (((char2 & 0xdf) - 'A') + 10) : (char2 - '0'))) #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #endif #ifndef EXIT_FAILURE #define EXIT_FAILURE 1 #endif #endif boa-0.94.14rc21/src/escape.c0000644000175000001440000000546610057761106016162 0ustar jnelsonusers00000000000000/* * Boa, an http server * escape.c * Copyright (C) 2001 Jon Nelson * Based on escape.pl, Copyright (C) 1996 Larry Doolittle * Copyright (C) 2001 Larry Doolittle * * 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 1, 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. * */ /* $Id: escape.c,v 1.7.2.2 2004/06/04 02:45:26 jnelson Exp $ */ /* unreserved = alnum | mark alnum = "0".."9" | "A".."Z" | "a".."z" mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" noescape = unreserved | ":" | "@" | "&" | "=" | "+" | "$" | "," | "/" */ #ifdef TEST #include #include #else #include "boa.h" #endif #include "escape.h" unsigned long _needs_escape[(NEEDS_ESCAPE_BITS + NEEDS_ESCAPE_WORD_LENGTH - 1) / NEEDS_ESCAPE_WORD_LENGTH]; void build_needs_escape(void) { unsigned int a, b; const unsigned char special[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "-_.!~*'():@&=+$,/?"; /* 21 Mar 2002 - jnelson - confirm with Apache 1.3.23 that '?' * is safe to leave unescaped. */ unsigned short i, j; b = 1; for (a = 0; b != 0; a++) b = b << 1; /* I found $a bit positions available in an unsigned long. */ if (a < NEEDS_ESCAPE_WORD_LENGTH) { fprintf(stderr, "NEEDS_ESCAPE_SHIFT configuration error -- " "%d should be <= log2(%d)\n", NEEDS_ESCAPE_SHIFT, a); exit(EXIT_FAILURE); } else if (a >= 2 * NEEDS_ESCAPE_WORD_LENGTH) { /* needs_escape_shift configuration suboptimal */ } else { /* Ahh, just right! */ ; } memset(_needs_escape, ~0, sizeof (_needs_escape)); for (i = 0; i < sizeof (special) - 1; ++i) { j = special[i]; if (j >= NEEDS_ESCAPE_BITS) { /* warning: character $j will be needlessly escaped. */ } else { _needs_escape[NEEDS_ESCAPE_INDEX(j)] &= ~NEEDS_ESCAPE_MASK(j); } } } #ifdef TEST int main(void) { int i; build_needs_escape(); for (i = 0; i <= NEEDS_ESCAPE_BITS; ++i) { if (needs_escape(i)) { fprintf(stdout, "%3d needs escape.\n", i); } } return (0); } #endif boa-0.94.14rc21/src/escape.h0000644000175000001440000000350107556524727016173 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 2001 Jon Nelson * Copyright (C) 2001 Larry Doolittle * 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 1, 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. * */ /* $Id: escape.h,v 1.18.2.1 2002/10/26 14:42:31 jnelson Exp $ */ #include "config.h" /* Highest character number that can possibly be passed through un-escaped */ #define NEEDS_ESCAPE_BITS 128 #ifndef NEEDS_ESCAPE_SHIFT #define NEEDS_ESCAPE_SHIFT 5 /* 1 << 5 is 32 bits */ #endif #define NEEDS_ESCAPE_WORD_LENGTH (1<>NEEDS_ESCAPE_SHIFT) /* Assume variable shift is fast, otherwise this could be a table lookup */ #define NEEDS_ESCAPE_MASK(c) (1<<((c)&(NEEDS_ESCAPE_WORD_LENGTH - 1))) /* Newer compilers could use an inline function. * This macro works great, as long as you pass unsigned int or unsigned char. */ #define needs_escape(c) ((c)>=NEEDS_ESCAPE_BITS || _needs_escape[NEEDS_ESCAPE_INDEX(c)]&NEEDS_ESCAPE_MASK(c)) extern unsigned long _needs_escape[(NEEDS_ESCAPE_BITS + NEEDS_ESCAPE_WORD_LENGTH - 1) / NEEDS_ESCAPE_WORD_LENGTH]; void build_needs_escape(void); boa-0.94.14rc21/src/get.c0000644000175000001440000005557110206636621015502 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996,99 Larry Doolittle * Copyright (C) 1996-2002 Jon Nelson * * 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 1, 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. * */ /* $Id: get.c,v 1.76.2.35 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" #include "access.h" #define STR(s) __STR(s) #define __STR(s) #s /* I think that permanent redirections (301) are supposed * to be absolute URIs, but they can be troublesome. * change to 1 to allow much simpler redirections. */ /* #define ALLOW_LOCAL_REDIRECT */ /* local prototypes */ static int get_cachedir_file(request * req, struct stat *statbuf); static int index_directory(request * req, char *dest_filename); /* * Name: init_get * Description: Initializes a non-script GET or HEAD request. * * Return values: * 0: finished or error, request will be freed * 1: successfully initialized, added to ready queue */ int init_get(request * req) { int data_fd, saved_errno; struct stat statbuf; volatile unsigned int bytes_free; data_fd = open(req->pathname, O_RDONLY); saved_errno = errno; /* might not get used */ #ifdef GUNZIP if (data_fd == -1 && errno == ENOENT) { /* cannot open */ /* it's either a gunzipped file or a directory */ char gzip_pathname[MAX_PATH_LENGTH]; unsigned int len; len = strlen(req->pathname); if (len + 4 > sizeof(gzip_pathname)) { log_error_doc(req); fprintf(stderr, "Pathname + .gz too long! (%s)\n", req->pathname); send_r_bad_request(req); return 0; } memcpy(gzip_pathname, req->pathname, len); memcpy(gzip_pathname + len, ".gz", 3); gzip_pathname[len + 3] = '\0'; data_fd = open(gzip_pathname, O_RDONLY); if (data_fd != -1) { close(data_fd); req->response_status = R_REQUEST_OK; if (req->pathname) free(req->pathname); req->pathname = strdup(gzip_pathname); if (!req->pathname) { boa_perror(req, "strdup req->pathname for gzipped filename " __FILE__ ":" STR(__LINE__)); return 0; } if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 200 OK-GUNZIP" CRLF); print_http_headers(req); print_content_type(req); print_last_modified(req); req_write(req, CRLF); req_flush(req); } if (req->method == M_HEAD) return 0; return init_cgi(req); } } #endif if (data_fd == -1) { log_error_doc(req); errno = saved_errno; perror("document open"); if (saved_errno == ENOENT) send_r_not_found(req); else if (saved_errno == EACCES) send_r_forbidden(req); else send_r_bad_request(req); return 0; } #ifdef ACCESS_CONTROL if (!access_allow(req->pathname)) { send_r_forbidden(req); return 0; } #endif fstat(data_fd, &statbuf); if (S_ISDIR(statbuf.st_mode)) { /* directory */ close(data_fd); /* close dir */ if (req->pathname[strlen(req->pathname) - 1] != '/') { char buffer[3 * MAX_PATH_LENGTH + 128]; unsigned int len; #ifdef ALLOW_LOCAL_REDIRECT len = strlen(req->request_uri); if (len + 2 > sizeof(buffer)) { send_r_error(req); return 0; } memcpy(buffer, req->request_uri, len); buffer[len] = '/'; buffer[len+1] = '\0'; #else char *host = server_name; unsigned int l2; char *port = NULL; const char *prefix = "http://"; static unsigned int l3 = 0; static unsigned int l4 = 0; if (l4 == 0) { l4 = strlen(prefix); } len = strlen(req->request_uri); if (!port && server_port != 80) { port = strdup(simple_itoa(server_port)); if (port == NULL) { errno = ENOMEM; boa_perror(req, "Unable to perform simple_itoa conversion on server port!"); return 0; } l3 = strlen(port); } /* l3 and l4 are done */ if (req->host) { /* only shows up in vhost mode */ /* what about the port? (in vhost_mode?) */ /* we don't currently report ports that differ * from out "bound" (listening) port, so we don't care */ host = req->host; } l2 = strlen(host); if (server_port != 80) { if (l4 + l2 + 1 + l3 + len + 1 > sizeof(buffer)) { errno = ENOMEM; boa_perror(req, "buffer not large enough for directory redirect"); return 0; } memcpy(buffer, prefix, l4); memcpy(buffer + l4, host, l2); buffer[l4 + l2] = ':'; memcpy(buffer + l4 + l2 + 1, port, l3); memcpy(buffer + l4 + l2 + 1 + l3, req->request_uri, len); buffer[l4 + l2 + 1 + l3 + len] = '/'; buffer[l4 + l2 + 1 + l3 + len + 1] = '\0'; } else { if (l4 + l2 + len + 1 > sizeof(buffer)) { errno = ENOMEM; boa_perror(req, "buffer not large enough for directory redirect"); return 0; } memcpy(buffer, prefix, l4); memcpy(buffer + l4, host, l2); memcpy(buffer + l4 + l2, req->request_uri, len); buffer[l4 + l2 + len] = '/'; buffer[l4 + l2 + len + 1] = '\0'; } #endif /* ALLOW LOCAL REDIRECT */ send_r_moved_perm(req, buffer); return 0; } data_fd = get_dir(req, &statbuf); /* updates statbuf */ if (data_fd < 0) /* couldn't do it */ return 0; /* errors reported by get_dir */ else if (data_fd == 0 || data_fd == 1) return data_fd; /* else, data_fd contains the fd of the file... */ } if (!S_ISREG(statbuf.st_mode)) { /* regular file */ log_error_doc(req); fprintf(stderr, "Resulting file is not a regular file.\n"); send_r_bad_request(req); close(data_fd); return 0; } /* If-UnModified-Since asks * is the file newer than date located in time_cval * yes -> return 412 * no -> return 200 * * If-Modified-Since asks * is the file date less than or same as the date located in time_cval * yes -> return 304 * no -> return 200 * * If-Unmodified-Since overrides If-Modified-Since */ /* if (req->headers[H_IF_UNMODIFIED_SINCE] && modified_since(&(statbuf.st_mtime), req->headers[H_IF_UNMODIFIED_SINCE])) { send_r_precondition_failed(req); return 0; } else */ if (req->if_modified_since && !modified_since(&(statbuf.st_mtime), req->if_modified_since)) { send_r_not_modified(req); close(data_fd); return 0; } req->filesize = statbuf.st_size; req->last_modified = statbuf.st_mtime; /* ignore if-range without range */ if (req->header_ifrange && !req->ranges) req->header_ifrange = NULL; /* we don't support it yet */ req->header_ifrange = NULL; /* parse ranges now */ /* we have to wait until req->filesize exists to fix them up */ /* fixup handles handles communicating with the client */ /* ranges_fixup logs as appropriate, and sends * send_r_invalid_range on error. */ if (req->filesize == 0) { if (req->http_version < HTTP11) { send_r_request_ok(req); close(data_fd); return 0; } send_r_no_content(req); close(data_fd); return 0; } if (req->ranges && !ranges_fixup(req)) { close(data_fd); return 0; } /* if no range has been set, use default range */ #if 0 DEBUG(DEBUG_RANGE) { log_error_time(); fprintf(stderr, "if-range: %s\time_cval: %d\tmtime: %d\n", req->header_ifrange, req->time_cval, statbuf->st_mtime); } #endif /* If the entity tag given in the If-Range header matches the current entity tag for the entity, then the server should provide the specified sub-range of the entity using a 206 (Partial content) response. If the entity tag does not match, then the server should return the entire entity using a 200 (OK) response. */ /* IF we have range data *and* no if-range or if-range matches... */ #ifdef MAX_FILE_MMAP if (req->filesize > MAX_FILE_MMAP) { req->data_fd = data_fd; req->status = IOSHUFFLE; } else #endif { /* NOTE: I (Jon Nelson) tried performing a read(2) * into the output buffer provided the file data would * fit, before mmapping, and if successful, writing that * and stopping there -- all to avoid the cost * of a mmap. Oddly, it was *slower* in benchmarks. */ req->mmap_entry_var = find_mmap(data_fd, &statbuf); if (req->mmap_entry_var == NULL) { req->data_fd = data_fd; req->status = IOSHUFFLE; } else { req->data_mem = req->mmap_entry_var->mmap; close(data_fd); /* close data file */ } } if (!req->ranges) { req->ranges = range_pool_pop(); req->ranges->start = 0; req->ranges->stop = -1; if (!ranges_fixup(req)) { return 0; } send_r_request_ok(req); } else { /* FIXME: support if-range header here, by the following logic: * if !req->header_ifrange || st_mtime > header_ifrange, * send_r_partial_content * else * reset-ranges, etc... */ if (!req->header_ifrange) { send_r_partial_content(req); } else { /* either no if-range or the if-range does not match */ ranges_reset(req); req->ranges = range_pool_pop(); req->ranges->start = 0; req->ranges->stop = -1; if (!ranges_fixup(req)) { return 0; } send_r_request_ok(req); } } if (req->method == M_HEAD) { return complete_response(req); } bytes_free = 0; if (req->data_mem) { /* things can really go tilt if req->buffer_end > BUFFER_SIZE, * but basically that can't happen */ /* We lose statbuf here, so make sure response has been sent */ bytes_free = BUFFER_SIZE - req->buffer_end; /* 256 bytes for the **trailing** headers */ /* bytes is now how much the buffer can hold * after the headers */ } if (req->data_mem && bytes_free > 256) { unsigned int want; Range *r; r = req->ranges; want = (r->stop - r->start) + 1; if (bytes_free > want) bytes_free = want; else { /* bytes_free <= want */ ; } if (setjmp(env) == 0) { handle_sigbus = 1; memcpy(req->buffer + req->buffer_end, req->data_mem + r->start, bytes_free); handle_sigbus = 0; /* OK, SIGBUS **after** this point is very bad! */ } else { /* sigbus! */ log_error_doc(req); reset_output_buffer(req); send_r_error(req); log_error("Got SIGBUS in memcpy\n"); return 0; } req->buffer_end += bytes_free; req->bytes_written += bytes_free; r->start += bytes_free; if (bytes_free == want) { /* this will fit due to the 256 extra bytes_free */ return complete_response(req); } } /* We lose statbuf here, so make sure response has been sent */ return 1; } /* * Name: process_get * Description: Writes a chunk of data to the socket. * * Return values: * -1: request blocked, move to blocked queue * 0: EOF or error, close it down * 1: successful write, recycle in ready queue */ int process_get(request * req) { int bytes_written; volatile unsigned int bytes_to_write; if (req->method == M_HEAD) { return complete_response(req); } bytes_to_write = (req->ranges->stop - req->ranges->start) + 1; if (bytes_to_write > system_bufsize) bytes_to_write = system_bufsize; if (setjmp(env) == 0) { handle_sigbus = 1; bytes_written = write(req->fd, req->data_mem + req->ranges->start, bytes_to_write); handle_sigbus = 0; /* OK, SIGBUS **after** this point is very bad! */ } else { /* sigbus! */ req->status = DEAD; log_error_doc(req); fprintf(stderr, "%sGot SIGBUS in write(2)!\n", get_commonlog_time()); /* sending an error here is inappropriate * if we are here, the file is mmapped, and thus, * a content-length has been sent. If we send fewer bytes * the client knows there has been a problem. * We run the risk of accidentally sending the right number * of bytes (or a few too many) and the client * won't be the wiser. */ return 0; } if (bytes_written < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else { #ifdef QUIET_DISCONNECT if (errno != EPIPE) { #else if (1) { #endif log_error_doc(req); /* Can generate lots of log entries, */ perror("write"); /* OK to disable if your logs get too big */ } req->status = DEAD; return 0; } } req->bytes_written += bytes_written; req->ranges->start += bytes_written; if ((req->ranges->stop + 1 - req->ranges->start) == 0) { return complete_response(req); } return 1; /* more to do */ } /* * Name: get_dir * Description: Called from process_get if the request is a directory. * statbuf must describe directory on input, since we may need its * device, inode, and mtime. * statbuf is updated, since we may need to check mtimes of a cache. * returns: * -1 error * 0 cgi (either gunzip or auto-generated) * >0 file descriptor of file */ int get_dir(request * req, struct stat *statbuf) { char pathname_with_index[MAX_PATH_LENGTH]; int data_fd; if (directory_index) { /* look for index.html first?? */ unsigned int l1, l2; l1 = strlen(req->pathname); l2 = strlen(directory_index); #ifdef GUNZIP if (l1 + l2 + 3 + 1 > sizeof(pathname_with_index)) { /* for .gz */ #else if (l1 + l2 + 1 > sizeof(pathname_with_index)) { #endif errno = ENOMEM; boa_perror(req, "pathname_with_index not large enough for pathname + index"); return -1; } memcpy(pathname_with_index, req->pathname, l1); /* doesn't copy NUL */ memcpy(pathname_with_index + l1, directory_index, l2 + 1); /* does */ data_fd = open(pathname_with_index, O_RDONLY); if (data_fd != -1) { /* user's index file */ /* We have to assume that directory_index will fit, because * if it doesn't, well, that's a huge configuration problem. * this is only the 'index.html' pathname for mime type */ memcpy(req->request_uri, directory_index, l2 + 1); /* for mimetype */ fstat(data_fd, statbuf); return data_fd; } if (errno == EACCES) { send_r_forbidden(req); return -1; } else if (errno != ENOENT) { /* if there is an error *other* than EACCES or ENOENT */ send_r_not_found(req); return -1; } #ifdef GUNZIP /* if we are here, trying index.html didn't work * try index.html.gz */ strcat(pathname_with_index, ".gz"); data_fd = open(pathname_with_index, O_RDONLY); if (data_fd != -1) { /* user's index file */ close(data_fd); req->response_status = R_REQUEST_OK; SQUASH_KA(req); if (req->pathname) free(req->pathname); req->pathname = strdup(pathname_with_index); if (!req->pathname) { boa_perror(req, "strdup of pathname_with_index for .gz files " __FILE__ ":" STR(__LINE__)); return 0; } if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 200 OK-GUNZIP" CRLF); print_http_headers(req); print_last_modified(req); req_write(req, "Content-Type: "); req_write(req, get_mime_type(directory_index)); req_write(req, CRLF CRLF); req_flush(req); } if (req->method == M_HEAD) return 0; return init_cgi(req); } #endif } /* only here if index.html, index.html.gz don't exist */ if (dirmaker != NULL) { /* don't look for index.html... maybe automake? */ req->response_status = R_REQUEST_OK; SQUASH_KA(req); /* the indexer should take care of all headers */ if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 200 OK" CRLF); print_http_headers(req); print_last_modified(req); req_write(req, "Content-Type: text/html" CRLF CRLF); req_flush(req); } if (req->method == M_HEAD) return 0; return init_cgi(req); /* in this case, 0 means success */ } else if (cachedir) { return get_cachedir_file(req, statbuf); } else { /* neither index.html nor autogenerate are allowed */ send_r_forbidden(req); return -1; /* nothing worked */ } } static int get_cachedir_file(request * req, struct stat *statbuf) { char pathname_with_index[MAX_PATH_LENGTH]; int data_fd; time_t real_dir_mtime; real_dir_mtime = statbuf->st_mtime; /* the sizeof() doesn't need a -1 because snprintf will * include the NUL when calculating if the size is enough */ snprintf(pathname_with_index, sizeof(pathname_with_index), "%s/dir.%d.%ld", cachedir, (int) statbuf->st_dev, statbuf->st_ino); data_fd = open(pathname_with_index, O_RDONLY); if (data_fd != -1) { /* index cache */ fstat(data_fd, statbuf); if (statbuf->st_mtime > real_dir_mtime) { statbuf->st_mtime = real_dir_mtime; /* lie */ strcpy(req->request_uri, directory_index); /* for mimetype */ return data_fd; } close(data_fd); unlink(pathname_with_index); /* cache is stale, delete it */ } if (index_directory(req, pathname_with_index) == -1) return -1; data_fd = open(pathname_with_index, O_RDONLY); /* Last chance */ if (data_fd != -1) { strcpy(req->request_uri, directory_index); /* for mimetype */ fstat(data_fd, statbuf); statbuf->st_mtime = real_dir_mtime; /* lie */ return data_fd; } boa_perror(req, "re-opening dircache"); return -1; /* Nothing worked. */ } /* * Name: index_directory * Description: Called from get_cachedir_file if a directory html * has to be generated on the fly * returns -1 for problem, else 0 * This version is the fastest, ugliest, and most accurate yet. * It solves the "stale size or type" problem by not ever giving * the size or type. This also speeds it up since no per-file * stat() is required. */ static int index_directory(request * req, char *dest_filename) { DIR *request_dir; FILE *fdstream; struct dirent *dirbuf; int bytes = 0; char *escname = NULL; if (chdir(req->pathname) == -1) { if (errno == EACCES || errno == EPERM) { send_r_forbidden(req); } else { log_error_doc(req); perror("chdir"); send_r_bad_request(req); } return -1; } request_dir = opendir("."); if (request_dir == NULL) { int errno_save = errno; send_r_error(req); log_error_doc(req); fprintf(stderr, "opendir failed on directory \"%s\": ", req->pathname); errno = errno_save; perror("opendir"); return -1; } fdstream = fopen(dest_filename, "w"); if (fdstream == NULL) { boa_perror(req, "dircache fopen"); closedir(request_dir); return -1; } bytes += fprintf(fdstream, "\nIndex of %s\n\n\n", req->request_uri); bytes += fprintf(fdstream, "\n\n

Index of %s

\n\n
\n",
                     req->request_uri);

    while ((dirbuf = readdir(request_dir))) {
        if (!strcmp(dirbuf->d_name, "."))
            continue;

        if (!strcmp(dirbuf->d_name, "..")) {
            bytes += fprintf(fdstream,
                             " [DIR] Parent Directory\n");
            continue;
        }

        /* FIXME: ought to use (as-yet unwritten) html_escape_string */
        escname = escape_string(dirbuf->d_name, NULL);
        if (escname != NULL) {
            bytes += fprintf(fdstream, " %s\n",
                             escname, dirbuf->d_name);
            free(escname);
            escname = NULL;
        }
    }
    closedir(request_dir);
    bytes += fprintf(fdstream, "
\n\n\n\n"); fclose(fdstream); chdir(server_root); req->filesize = bytes; /* for logging transfer size */ return 0; /* success */ } boa-0.94.14rc21/src/globals.h0000644000175000001440000002136710206636621016347 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-2005 Larry Doolittle * Copyright (C) 1997-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: globals.h,v 1.65.2.29 2005/02/22 14:11:29 jnelson Exp $*/ #ifndef _GLOBALS_H #define _GLOBALS_H /********************** METHODS **********************/ enum HTTP_METHOD { M_GET = 1, M_HEAD, M_PUT, M_POST, M_DELETE, M_LINK, M_UNLINK, M_MOVE, M_TRACE }; /******************* HTTP VERSIONS *******************/ enum HTTP_VERSION { HTTP09=1, HTTP10, HTTP11 }; /************** REQUEST STATUS (req->status) ***************/ enum REQ_STATUS { READ_HEADER, ONE_CR, ONE_LF, TWO_CR, BODY_READ, BODY_WRITE, WRITE, PIPE_READ, PIPE_WRITE, IOSHUFFLE, DONE, TIMED_OUT, DEAD }; /******************* RESPONSE CODES ******************/ enum RESPONSE_CODE { R_CONTINUE = 100, R_REQUEST_OK = 200, R_CREATED, R_ACCEPTED, R_PROVISIONAL, R_NO_CONTENT, R_205, R_PARTIAL_CONTENT, R_MULTIPLE = 300, R_MOVED_PERM, R_MOVED_TEMP, R_303, R_NOT_MODIFIED, R_BAD_REQUEST = 400, R_UNAUTHORIZED, R_PAYMENT, R_FORBIDDEN, R_NOT_FOUND, R_METHOD_NA, /* method not allowed */ R_NON_ACC, /* non acceptable */ R_PROXY, /* proxy auth required */ R_REQUEST_TO, /* request timeout */ R_CONFLICT, R_GONE, R_LENGTH_REQUIRED, R_PRECONDITION_FAILED, R_REQUEST_URI_TOO_LONG = 414, R_INVALID_RANGE = 416, R_ERROR = 500, R_NOT_IMP, R_BAD_GATEWAY, R_SERVICE_UNAV, R_GATEWAY_TO, /* gateway timeout */ R_BAD_VERSION }; /************* ALIAS TYPES (aliasp->type) ***************/ enum ALIAS { ALIAS, SCRIPTALIAS, REDIRECT }; /*********** KEEPALIVE CONSTANTS (req->keepalive) *******/ enum KA_STATUS { KA_INACTIVE, KA_ACTIVE, KA_STOPPED }; /********* CGI STATUS CONSTANTS (req->cgi_status) *******/ enum CGI_STATUS { CGI_PARSE, CGI_BUFFER, CGI_DONE }; /************** CGI TYPE (req->is_cgi) ******************/ enum CGI_TYPE { NPH = 1, CGI }; /**************** STRUCTURES ****************************/ struct range { unsigned long start; unsigned long stop; struct range *next; }; typedef struct range Range; struct mmap_entry { dev_t dev; ino_t ino; char *mmap; int use_count; off_t len; }; struct request { /* pending requests */ enum REQ_STATUS status; enum KA_STATUS keepalive; /* keepalive status */ enum HTTP_VERSION http_version; enum HTTP_METHOD method; /* M_GET, M_POST, etc. */ enum RESPONSE_CODE response_status; /* R_NOT_FOUND, etc.. */ enum CGI_TYPE cgi_type; enum CGI_STATUS cgi_status; /* should pollfd_id be zeroable or no ? */ #ifdef HAVE_POLL int pollfd_id; #endif char *pathname; /* pathname of requested file */ Range *ranges; /* our Ranges */ int numranges; int data_fd; /* fd of data */ unsigned long filesize; /* filesize */ unsigned long filepos; /* position in file */ unsigned long bytes_written; /* total bytes written (sans header) */ char *data_mem; /* mmapped/malloced char array */ char *logline; /* line to log file */ char *header_line; /* beginning of un or incompletely processed header line */ char *header_end; /* last known end of header, or end of processed data */ int parse_pos; /* how much have we parsed */ int buffer_start; /* where the buffer starts */ int buffer_end; /* where the buffer ends */ char *if_modified_since; /* If-Modified-Since */ time_t last_modified; /* Last-modified: */ /* CGI vars */ int cgi_env_index; /* index into array */ /* Agent and referer for logfiles */ char *header_host; char *header_user_agent; char *header_referer; char *header_ifrange; char *host; /* what we end up using for 'host', no matter the contents of header_host */ int post_data_fd; /* fd for post data tmpfile */ char *path_info; /* env variable */ char *path_translated; /* env variable */ char *script_name; /* env variable */ char *query_string; /* env variable */ char *content_type; /* env variable */ char *content_length; /* env variable */ struct mmap_entry *mmap_entry_var; /* everything **above** this line is zeroed in sanitize_request */ /* this may include 'fd' */ /* in sanitize_request with the 'new' parameter set to 1, * kacount is set to ka_max and client_stream_pos is also zeroed. * Also, time_last is set to 'NOW' */ int fd; /* client's socket fd */ time_t time_last; /* time of last succ. op. */ char local_ip_addr[BOA_NI_MAXHOST]; /* for virtualhost */ char remote_ip_addr[BOA_NI_MAXHOST]; /* after inet_ntoa */ unsigned int remote_port; /* could be used for ident */ unsigned int kacount; /* keepalive count */ int client_stream_pos; /* how much have we read... */ /* everything below this line is kept regardless */ char buffer[BUFFER_SIZE + 1]; /* generic I/O buffer */ char request_uri[MAX_HEADER_LENGTH + 1]; /* uri */ char client_stream[CLIENT_STREAM_SIZE]; /* data from client - fit or be hosed */ char *cgi_env[CGI_ENV_MAX + 4]; /* CGI environment */ #ifdef ACCEPT_ON char accept[MAX_ACCEPT_LENGTH]; /* Accept: fields */ #endif struct request *next; /* next */ struct request *prev; /* previous */ }; typedef struct request request; struct status { long requests; long errors; }; extern struct status status; extern char *optarg; /* For getopt */ extern request *request_ready; /* first in ready list */ extern request *request_block; /* first in blocked list */ extern request *request_free; /* first in free list */ #ifdef HAVE_POLL extern struct pollfd *pfds; extern unsigned int pfd_len; #else extern fd_set block_read_fdset; /* fds blocked on read */ extern fd_set block_write_fdset; /* fds blocked on write */ extern int max_fd; #endif /* global server variables */ extern char *access_log_name; extern char *error_log_name; extern char *cgi_log_name; extern int cgi_log_fd; extern int use_localtime; extern unsigned int server_port; extern uid_t server_uid; extern gid_t server_gid; extern char *server_admin; extern char *server_root; extern char *server_name; extern char *server_ip; extern char *document_root; extern char *user_dir; extern char *directory_index; extern char *default_type; extern char *default_charset; extern char *dirmaker; extern char *mime_types; extern char *pid_file; extern char *cachedir; extern const char *tempdir; extern char *cgi_path; extern short common_cgi_env_count; extern int single_post_limit; extern int conceal_server_identity; extern int ka_timeout; extern int unsigned default_timeout; extern int unsigned ka_max; extern int sighup_flag; extern int sigchld_flag; extern int sigalrm_flag; extern int sigterm_flag; extern time_t start_time; extern int pending_requests; extern unsigned max_connections; extern int verbose_cgi_logs; extern int backlog; extern time_t current_time; extern int virtualhost; extern char *vhost_root; extern const char *default_vhost; extern unsigned total_connections; extern unsigned int system_bufsize; /* Default size of SNDBUF given by system */ extern sigjmp_buf env; extern int handle_sigbus; extern unsigned int cgi_umask; #endif boa-0.94.14rc21/src/hash.c0000644000175000001440000003003210206636621015627 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1997-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: hash.c,v 1.14.4.15 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" #ifndef MAX_HASH_LENGTH #define MAX_HASH_LENGTH 4 #endif /* * There are two hash tables used, each with a key/value pair * stored in a hash_struct. They are: * * mime_hashtable: * key = file extension * value = mime type * * passwd_hashtable: * key = username * value = home directory * */ struct _hash_struct_ { char *key; char *value; struct _hash_struct_ *next; }; typedef struct _hash_struct_ hash_struct; static hash_struct *mime_hashtable[MIME_HASHTABLE_SIZE]; static hash_struct *passwd_hashtable[PASSWD_HASHTABLE_SIZE]; void add_mime_type(const char *extension, const char *type); static unsigned get_homedir_hash_value(const char *name); #ifdef WANT_ICKY_HASH static unsigned four_char_hash(const char *buf); #define _boa_hash four_char_hash #else #ifdef WANT_SDBM_HASH static unsigned sdbm_hash(const char *str); #define _boa_hash sdbm_hash #else #ifdef WANT_DJB2_HASH static unsigned djb2_hash(const char *str); #define _boa_hash djb2_hash #else static unsigned fnv1a_hash(const char *str); #define _boa_hash fnv1a_hash #endif #endif #endif static unsigned boa_hash(const char *str) { if (str == NULL || str[0] == '\0') { log_error_time(); fprintf(stderr, "Attempt to hash NULL or empty string! [boa_hash]!\n"); return 0; } return _boa_hash(str); } #ifdef WANT_ICKY_HASH static unsigned four_char_hash(const char *buf) { unsigned int hash = (buf[0] + (buf[1] ? buf[1] : 241 + (buf[2] ? buf[2] : 251 + (buf[3] ? buf[3] : 257)))); DEBUG(DEBUG_HASH) { log_error_time(); fprintf(stderr, "four_char_hash(%s) = %u\n", buf, hash); } return hash; } /* The next two hashes taken from * http://www.cs.yorku.ca/~oz/hash.html * * In my (admittedly) very brief testing, djb2_hash performed * very slightly better than sdbm_hash. */ #else #ifdef WANT_SDBM_HASH static unsigned sdbm_hash(const char *str) { unsigned hash = 0; int c; short count = MAX_HASH_LENGTH; DEBUG(DEBUG_HASH) { log_error_time(); fprintf(stderr, "sdbm_hash(%s) = ", str); } while ((c = *str++) && count--) hash = c + (hash << 6) + (hash << 16) - hash; DEBUG(DEBUG_HASH) { fprintf(stderr, "%u\n", hash); } return hash; } #else #ifdef WANT_DJB2_HASH static unsigned djb2_hash(const char *str) { unsigned hash = 5381; int c; short count = MAX_HASH_LENGTH; DEBUG(DEBUG_HASH) { log_error_time(); fprintf(stderr, "djb2_hash(%s) = ", str); } while ((c = *(str++)) && count--) hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ DEBUG(DEBUG_HASH) { fprintf(stderr, "%u\n", hash); } return hash; } #else /* * magic 32 bit FNV1a hash constants * * See: http://www.isthe.com/chongo/tech/comp/fnv/index.html */ #define OFFSET_BASIS 2166136261U #define FNV_PRIME 16777619U /* * * hash.c:152: warning: width of integer constant may change on other systems with -traditional */ static unsigned fnv1a_hash(const char *str) { unsigned int hash = OFFSET_BASIS; short count = MAX_HASH_LENGTH; /* * compute FNV1a hash of the first file component */ do { hash ^= *str++; hash *= FNV_PRIME; } while (*str != '\0' && count--); return hash; } #endif #endif #endif /* * Name: hash_insert * Description: Adds a key/value pair to the provided hashtable */ static hash_struct *hash_insert(hash_struct * table[], const unsigned int hash, const char *key, const char *value) { hash_struct *current, *trailer; if (!key) { log_error_time(); fprintf(stderr, "Yipes! Null value sent as key! [hash_insert]!\n"); return NULL; } else if (key[0] == '\0') { log_error_time(); fprintf(stderr, "Attempt to hash NULL or empty key! [hash_insert]!\n"); return NULL; } if (!value) { log_error_time(); fprintf(stderr, "Yipes! Null value sent as value! [hash_insert]!\n"); return NULL; } else if (value[0] == '\0') { log_error_time(); fprintf(stderr, "Attempt to hash NULL or empty value! [hash_insert]!\n"); return NULL; } /* should we bother to check table, hash, and key for NULL/0 ? */ DEBUG(DEBUG_HASH) { fprintf(stderr, "Adding key \"%s\" for value \"%s\" (hash=%u)\n", key, value, hash); } current = table[hash]; while (current) { if (!strcmp(current->key, key)) return current; /* don't add extension twice */ if (current->next) current = current->next; else break; } /* not found */ trailer = (hash_struct *) malloc(sizeof (hash_struct)); if (trailer == NULL) { WARN("unable to allocate memory for hash_insert"); return NULL; } trailer->key = strdup(key); trailer->value = strdup(value); trailer->next = NULL; if (trailer->key == NULL || trailer->value == NULL) { int errno_save = errno; if (trailer->key) free(trailer->key); if (trailer->value) free(trailer->value); free(trailer); trailer = NULL; errno = errno_save; WARN("allocated key or value is NULL"); return NULL; } /* successfully allocated and built new hash structure */ if (!current) { /* no entries for this hash value */ table[hash] = trailer; } else { current->next = trailer; } return trailer; } static hash_struct *hash_find(hash_struct * table[], const char *key, const unsigned int hash) { hash_struct *current; current = table[hash]; if (!key) { log_error_time(); fprintf(stderr, "Yipes! Null value sent as key! [hash_find]!\n"); return NULL; } else if (key[0] == '\0') { log_error_time(); fprintf(stderr, "Attempt to locate empty string in hash! [hash_find]!\n"); return NULL; } while (current) { if (!strcmp(current->key, key)) /* hit */ return current; current = current->next; } return NULL; } static void hash_clear(hash_struct * table[], int size) { int i; hash_struct *temp; for (i = 0; i < size; ++i) { /* these limits OK? */ temp = table[i]; while (temp) { hash_struct *temp_next; temp_next = temp->next; free(temp->key); free(temp->value); free(temp); temp = temp_next; } table[i] = NULL; } } void hash_show_stats(void) { int i; hash_struct *temp; int total = 0; int count; for (i = 0; i < MIME_HASHTABLE_SIZE; ++i) { /* these limits OK? */ if (mime_hashtable[i]) { count = 0; temp = mime_hashtable[i]; while (temp) { temp = temp->next; ++count; } #ifdef NOISY_SIGALRM log_error_time(); fprintf(stderr, "mime_hashtable[%d] has %d entries\n", i, count); #endif total += count; } } log_error_time(); fprintf(stderr, "mime_hashtable has %d total entries\n", total); total = 0; for (i = 0; i < PASSWD_HASHTABLE_SIZE; ++i) { /* these limits OK? */ if (passwd_hashtable[i]) { temp = passwd_hashtable[i]; count = 0; while (temp) { temp = temp->next; ++count; } #ifdef NOISY_SIGALRM log_error_time(); fprintf(stderr, "passwd_hashtable[%d] has %d entries\n", i, count); #endif total += count; } } log_error_time(); fprintf(stderr, "passwd_hashtable has %d total entries\n", total); } /*******************************************************************/ /*******************************************************************/ /******* Generic Hash Functions Above, Specific Below **************/ /*******************************************************************/ /*******************************************************************/ /* * Name: add_mime_type * Description: Adds a key/value pair to the mime_hashtable */ void add_mime_type(const char *extension, const char *type) { unsigned int hash; hash = get_mime_hash_value(extension); if (hash_insert(mime_hashtable, hash, extension, type) == NULL) DIE("Failed to hash_insert mime type."); } /* * Name: get_mime_hash_value * * Description: adds the ASCII values of the file extension letters * and mods by the hashtable size to get the hash value */ unsigned get_mime_hash_value(const char *extension) { return boa_hash(extension) % MIME_HASHTABLE_SIZE; } /* * Name: get_mime_type * * Description: Returns the mime type for a supplied filename. * Returns default type if not found. */ char *get_mime_type(const char *filename) { char *extension; hash_struct *current; unsigned int hash; if (filename == NULL) { log_error_time(); fprintf(stderr, "Attempt to hash NULL string! [get_mime_type]\n"); return default_type; } else if (filename[0] == '\0') { log_error_time(); fprintf(stderr, "Attempt to hash empty string! [get_mime_type]\n"); return default_type; } extension = strrchr(filename, '.'); /* remember, extension points to the *last* '.' in the filename, * which may be NULL or look like: * foo.bar * foo. (in which case extension[1] == '\0') */ /* extension[0] *can't* be NIL */ if (!extension || extension[1] == '\0') return default_type; /* make sure we hash on the 'bar' not the '.bar' */ ++extension; hash = get_mime_hash_value(extension); current = hash_find(mime_hashtable, extension, hash); return (current ? current->value : default_type); } /* * Name: get_homedir_hash_value * * Description: adds the ASCII values of the username letters * and mods by the hashtable size to get the hash value */ static unsigned get_homedir_hash_value(const char *name) { return boa_hash(name) % PASSWD_HASHTABLE_SIZE; } /* * Name: get_home_dir * * Description: Returns a point to the supplied user's home directory. * Adds to the hashtable if it's not already present. * */ char *get_home_dir(const char *name) { hash_struct *current; unsigned int hash; hash = get_homedir_hash_value(name); current = hash_find(passwd_hashtable, name, hash); if (!current) { /* not found */ struct passwd *passwdbuf; passwdbuf = getpwnam(name); if (!passwdbuf) /* does not exist */ return NULL; current = hash_insert(passwd_hashtable, hash, name, passwdbuf->pw_dir); } return (current ? current->value : NULL); } void dump_mime(void) { hash_clear(mime_hashtable, MIME_HASHTABLE_SIZE); } void dump_passwd(void) { hash_clear(passwd_hashtable, PASSWD_HASHTABLE_SIZE); } boa-0.94.14rc21/src/index_dir.c0000644000175000001440000002557710206520110016654 0ustar jnelsonusers00000000000000/* * Copyright (C) 1997-2005 Jon Nelson * * 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 1, 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. * */ /* $Id: index_dir.c,v 1.32.2.7 2005/02/22 03:00:24 jnelson Exp $*/ #include #include #include /* for PATH_MAX */ #include #include #include #include #include #include "compat.h" #define MAX_FILE_LENGTH MAXNAMLEN #define MAX_PATH_LENGTH PATH_MAX #define INT_TO_HEX(x) \ ((((x)-10)>=0)?('A'+((x)-10)):('0'+(x))) #include "escape.h" char *html_escape_string(const char *inp, char *dest, const unsigned int len); char *http_escape_string(const char *inp, char *buf, const unsigned int len); int select_files(const struct dirent *d); int index_directory(char *dir, char *title); void send_error(int error); /* * Name: html_escape_string */ char *html_escape_string(const char *inp, char *dest, const unsigned int len) { int max; char *buf; unsigned char c; max = len * 6; if (dest == NULL && max) dest = malloc(sizeof (unsigned char) * (max + 1)); if (dest == NULL) return NULL; buf = dest; while ((c = *inp++)) { switch (c) { case '>': *dest++ = '&'; *dest++ = 'g'; *dest++ = 't'; *dest++ = ';'; break; case '<': *dest++ = '&'; *dest++ = 'l'; *dest++ = 't'; *dest++ = ';'; break; case '&': *dest++ = '&'; *dest++ = 'a'; *dest++ = 'm'; *dest++ = 'p'; *dest++ = ';'; break; case '\"': *dest++ = '&'; *dest++ = 'q'; *dest++ = 'u'; *dest++ = 'o'; *dest++ = 't'; *dest++ = ';'; break; default: *dest++ = c; } } *dest = '\0'; return buf; } /* * Name: escape_string * * Description: escapes the string inp. Uses variable buf. If buf is * NULL when the program starts, it will attempt to dynamically allocate * the space that it needs, otherwise it will assume that the user * has already allocated enough space for the variable buf, which * could be up to 3 times the size of inp. If the routine dynamically * allocates the space, the user is responsible for freeing it afterwords * Returns: NULL on error, pointer to string otherwise. */ char *http_escape_string(const char *inp, char *buf, const unsigned int len) { int max; char *index_c; unsigned char c; int found_a_colon = 0; max = len * 3; if (buf == NULL && max) buf = malloc(sizeof (unsigned char) * (max + 1)); if (buf == NULL) return NULL; index_c = buf; while ((c = *inp++)) { if (c == ':' && !found_a_colon && index_c > buf) { found_a_colon = 1; memmove(buf + 2, buf, (index_c - buf)); *buf = '.'; *(buf + 1) = '/'; index_c += 2; *index_c++ = ':'; } else if (needs_escape((unsigned int) c) || c == '?') { *index_c++ = '%'; *index_c++ = INT_TO_HEX((c >> 4) & 0xf); *index_c++ = INT_TO_HEX(c & 0xf); } else *index_c++ = c; } *index_c = '\0'; return buf; } void send_error(int error) { const char *the_error; switch (error) { case 1: the_error = "Not enough arguments were passed to the indexer."; break; case 2: the_error = "The Directory Sorter ran out of Memory"; break; case 3: the_error = "The was a problem changing to the appropriate directory."; break; case 4: the_error = "There was an error escaping a string."; case 5: the_error = "Too many arguments were passed to the indexer."; break; case 6: the_error = "No files in this directory."; break; default: the_error = "An unknown error occurred producing the directory."; break; } printf("\n\n\n%s\n\n" "\n%s\n\n\n", the_error, the_error); } int select_files(const struct dirent *dirbuf) { if (dirbuf->d_name[0] == '.') return 0; else return 1; } /* * Name: index_directory * Description: Called from get_dir_mapping if a directory html * has to be generated on the fly * If no_slash is true, prepend slashes to hrefs * returns -1 for problem, else 0 */ int index_directory(char *dir, char *title) { struct dirent *dirbuf; int numdir; struct dirent **array; struct stat statbuf; char http_filename[MAX_FILE_LENGTH * 3]; char html_filename[MAX_FILE_LENGTH * 6]; char escaped_filename[MAX_FILE_LENGTH * 18]; /* *both* http and html escape */ int i; if (chdir(dir) == -1) { send_error(3); return -1; } numdir = scandir(".", &array, select_files, alphasort); if (numdir == -1) { send_error(2); return -1; } else if (numdir == -2) { send_error(6); return -1; } if (html_escape_string(title, html_filename, strlen(title)) == NULL) { send_error(4); return -1; } printf("\n" "\nIndex of %s\n\n\n" "\n" "

Index of %s

\n" "\n%s", html_filename, html_filename, (strcmp(title, "/") == 0 ? "" : "" "\n")); for (i = 0; i < numdir; ++i) { dirbuf = array[i]; if (stat(dirbuf->d_name, &statbuf) == -1) continue; if (!S_ISDIR(statbuf.st_mode)) continue; if (html_escape_string(dirbuf->d_name, html_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } if (http_escape_string(dirbuf->d_name, http_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } if (html_escape_string(http_filename, escaped_filename, strlen(http_filename)) == NULL) { send_error(4); return -1; } printf("" "" "" "" "\n", escaped_filename, html_filename, ctime(&statbuf.st_mtime), (long) statbuf.st_size); } printf ("\n\n"); for (i = 0; i < numdir; ++i) { int len; dirbuf = array[i]; if (stat(dirbuf->d_name, &statbuf) == -1) continue; if (S_ISDIR(statbuf.st_mode)) continue; if (html_escape_string(dirbuf->d_name, html_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } if (http_escape_string(dirbuf->d_name, http_filename, NAMLEN(dirbuf)) == NULL) { send_error(4); return -1; } len = strlen(http_filename); #ifdef GUNZIP if (len > 3 && !memcmp(http_filename + len - 3, ".gz", 3)) { http_filename[len - 3] = '\0'; html_filename[strlen(html_filename) - 3] = '\0'; if (html_escape_string(http_filename, escaped_filename, strlen(http_filename)) == NULL) { send_error(4); return -1; } printf("" "" "" "" "\n", escaped_filename, html_filename, http_filename, ctime(&statbuf.st_mtime), (long) statbuf.st_size); } else { #endif if (html_escape_string(http_filename, escaped_filename, strlen(http_filename)) == NULL) { send_error(4); return -1; } printf("" "" "" "" "\n", escaped_filename, html_filename, ctime(&statbuf.st_mtime), (long) statbuf.st_size); #ifdef GUNZIP } #endif } /* hey -- even though this is a one-shot deal, we should * still free memory we ought to free * You never know -- this code might get used elsewhere! */ for (i = 0; i < numdir; ++i) { free(array[i]); array[i] = NULL; } free(array); array = NULL; return 0; /* success */ } int main(int argc, char *argv[]) { time_t timep; struct tm *timeptr; char *now; if (argc < 3) { send_error(1); return -1; } else if (argc > 3) { send_error(5); return -1; } build_needs_escape(); if (argv[2] == NULL) index_directory(argv[1], argv[1]); else index_directory(argv[1], argv[2]); time(&timep); #ifdef USE_LOCALTIME timeptr = localtime(&timep); #else timeptr = gmtime(&timep); #endif now = strdup(asctime(timeptr)); now[strlen(now) - 1] = '\0'; #ifdef USE_LOCALTIME printf("

Directories

Parent Directory
%s/%s%ld bytes
 

Files

%s " "(.gz)%s%ld bytes
%s%s%ld bytes
\n
\nIndex generated %s %s\n" "\n" "\n\n", now, TIMEZONE(timeptr)); #else printf("\n
\nIndex generated %s UTC\n" "\n" "\n\n", now); #endif return 0; } boa-0.94.14rc21/src/ip.c0000644000175000001440000001061110206636621015315 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1999 Larry Doolittle * Copyright (C) 2000-2003 Jon Nelson * * 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 1, 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. * * Encapsulation of ipv4 and ipv6 stuff, try to get rid of the ifdef's elsewhere in the code. The IPv6 code here is based on contributions from Martin Hinner and Arkadiusz Miskiewicz . This incarnation of that code is untested. The original IPv4 code is based on original Boa code from Paul Phillips . A goal is to compile in as many families as are supported, and make the final choice at runtime. globals.h: #ifdef INET6 char remote_ip_addr[BOA_NI_MAXHOST]; #else char remote_ip_addr[20]; after inet_ntoa #endif None of this code interacts with the rest of Boa except through the parameter lists and return values. Consider making these functions __inline__ and using this as a .h file */ #include "boa.h" #include /* inet_ntoa */ /* Binds to the existing server_s, based on the configuration string in server_ip. IPv6 version doesn't pay attention to server_ip yet. */ int bind_server(int sock, char *ip, unsigned int port) { #ifdef INET6 struct sockaddr_in6 server_sockaddr; server_sockaddr.sin6_family = PF_INET6; memcpy(&server_sockaddr.sin6_addr, &in6addr_any, sizeof (in6addr_any)); server_sockaddr.sin6_port = htons(server_port); #else struct sockaddr_in server_sockaddr; memset(&server_sockaddr, 0, sizeof server_sockaddr); #ifdef HAVE_SIN_LEN /* uncomment for BSDs */ server_sockaddr.sin_len = sizeof server_sockaddr; #endif server_sockaddr.sin_family = PF_INET; if (ip != NULL) { #ifdef HAVE_INET_ATON inet_aton(ip, &server_sockaddr.sin_addr); #elif defined HAVE_INET_ADDR server_sockaddr.sin_addr.s_addr = inet_addr(ip); #else #error "Neither inet_aton nor inet_addr exist!" #endif } else { server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); } server_sockaddr.sin_port = htons(port); #endif return bind(sock, (struct sockaddr *) &server_sockaddr, sizeof (server_sockaddr)); } char *ascii_sockaddr(struct SOCKADDR *s, char *dest, unsigned int len) { #ifdef INET6 if (getnameinfo((struct sockaddr *) s, sizeof (struct SOCKADDR), dest, len, NULL, 0, NI_NUMERICHOST)) { fprintf(stderr, "[IPv6] getnameinfo failed\n"); *dest = '\0'; } #ifdef WHEN_DOES_THIS_APPLY #error Dont use memmove if ((s->__ss_family == PF_INET6) && IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) { #error The following two lines are broken memmove(dest, dest + 7, BOA_NI_MAXHOST); dest[BOA_NI_MAXHOST] = '\0'; } #endif /* ifdef WHEN_DOES_THIS_APPLY */ #else /* ifdef INET6 */ unsigned int newlen; char *buf; /* memmove(dest, inet_ntoa(s->sin_addr), len); */ buf = inet_ntoa(s->sin_addr); newlen = strlen(buf); /* we need newlen + 1 byte to be <= len, thus * newlen <= len - 1 is good * and newlen > len -1 is bad thus * newlen + 1 > len ==== newlen >= len */ if (newlen + 1 > len) { /* too many bytes incl. the NUL */ return NULL; } memcpy(dest, buf, newlen); dest[newlen] = '\0'; #endif /* ifdef INET6 */ return dest; } int net_port(struct SOCKADDR *s) { int p = -1; #ifdef INET6 char serv[NI_MAXSERV]; if (getnameinfo((struct sockaddr *) s, sizeof (struct SOCKADDR), NULL, 0, serv, sizeof (serv), NI_NUMERICSERV)) { fprintf(stderr, "[IPv6] getnameinfo failed\n"); } else { p = atoi(serv); } #else p = ntohs(s->sin_port); #endif return p; } boa-0.94.14rc21/src/log.c0000644000175000001440000001747010206636621015500 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1999-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: log.c,v 1.36.2.27 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" int cgi_log_fd; /* * Name: open_logs * * Description: Opens access log, error log, and if specified, CGI log * Ties stderr to error log, except during CGI execution, at which * time CGI log is the stderr for CGIs. * * Access log is line buffered, error log is not buffered. * */ void open_logs(void) { int access_log; /* if error_log_name is set, dup2 stderr to it */ /* otherwise, leave stderr alone */ /* we don't want to tie stderr to /dev/null */ if (error_log_name) { int error_log; /* open the log file */ error_log = open_gen_fd(error_log_name); if (error_log < 0) { DIE("unable to open error log"); } /* redirect stderr to error_log */ if (dup2(error_log, STDERR_FILENO) == -1) { DIE("unable to dup2 the error log"); } close(error_log); } if (access_log_name) { access_log = open_gen_fd(access_log_name); } else { access_log = open("/dev/null", 0); } if (access_log < 0) { DIE("unable to open access log"); } if (dup2(access_log, STDOUT_FILENO) == -1) { DIE("can't dup2 /dev/null to STDOUT_FILENO"); } if (fcntl(access_log, F_SETFD, 1) == -1) { DIE("unable to set close-on-exec flag for access_log"); } close(access_log); if (cgi_log_name) { cgi_log_fd = open_gen_fd(cgi_log_name); if (cgi_log_fd == -1) { WARN("open cgi_log"); free(cgi_log_name); cgi_log_name = NULL; cgi_log_fd = 0; } else { if (fcntl(cgi_log_fd, F_SETFD, 1) == -1) { WARN("unable to set close-on-exec flag for cgi_log"); free(cgi_log_name); cgi_log_name = NULL; close(cgi_log_fd); cgi_log_fd = 0; } } } #ifdef SETVBUF_REVERSED setvbuf(stderr, _IONBF, (char *) NULL, 0); setvbuf(stdout, _IOLBF, (char *) NULL, 0); #else setvbuf(stderr, (char *) NULL, _IONBF, 0); setvbuf(stdout, (char *) NULL, _IOLBF, 0); #endif } /* * Name: log_access * * Description: Writes log data to access_log. */ /* NOTES on the commonlog format: * Taken from notes on the NetBuddy program * http://www.computer-dynamics.com/commonlog.html remotehost remotehost rfc931 authuser [date] "request" status bytes remotehost - IP of the client rfc931 - remote name of the user (always '-') authuser - username entered for authentication - almost always '-' [date] - the date in [08/Nov/1997:01:05:03 -0600] (with brackets) format "request" - literal request from the client (boa may clean this up, replacing control-characters with '_' perhaps - NOTE: not done) status - http status code bytes - number of bytes transferred boa appends: referer user-agent and may prepend (depending on configuration): virtualhost - the name or IP (depending on whether name-based virtualhosting is enabled) of the host the client accessed */ void log_access(request * req) { if (!access_log_name) return; if (virtualhost) { printf("%s ", req->local_ip_addr); } else if (vhost_root) { printf("%s ", (req->host ? req->host : "(null)")); } printf("%s - - %s\"%s\" %d %ld \"%s\" \"%s\"\n", req->remote_ip_addr, get_commonlog_time(), req->logline ? req->logline : "-", req->response_status, req->bytes_written, (req->header_referer ? req->header_referer : "-"), (req->header_user_agent ? req->header_user_agent : "-")); } /* * Name: log_error_doc * * Description: Logs the current time and transaction identification * to the stderr (the error log): * should always be followed by an fprintf to stderr * * Example output: [08/Nov/1997:01:05:03 -0600] request from 192.228.331.232 "GET /~joeblow/dir/ HTTP/1.0" ("/usr/user1/joeblow/public_html/dir/"): write: Broken pipe Apache uses: [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] client denied by server configuration: /export/home/live/ap/htdocs/test */ void log_error_doc(request * req) { int errno_save = errno; if (virtualhost) { fprintf(stderr, "%s ", req->local_ip_addr); } else if (vhost_root) { fprintf(stderr, "%s ", (req->host ? req->host : "(null)")); } if (vhost_root) { fprintf(stderr, "%s - - %srequest [%s] \"%s\" (\"%s\"): ", req->remote_ip_addr, get_commonlog_time(), (req->header_host ? req->header_host : "(null)"), (req->logline ? req->logline : "(null)"), (req->pathname ? req->pathname : "(null)")); } else { fprintf(stderr, "%s - - %srequest \"%s\" (\"%s\"): ", req->remote_ip_addr, get_commonlog_time(), (req->logline ? req->logline : "(null)"), (req->pathname ? req->pathname : "(null)")); } errno = errno_save; } /* * Name: boa_perror * * Description: logs an error to user and error file both * */ void boa_perror(request * req, const char *message) { log_error_doc(req); perror(message); /* don't need to save errno because log_error_doc does */ send_r_error(req); } /* * Name: log_error_time * * Description: Logs the current time to the stderr (the error log): * should always be followed by an fprintf to stderr */ void log_error_time(void) { int errno_save = errno; fputs(get_commonlog_time(), stderr); errno = errno_save; } /* * Name: log_error * * Description: performs a log_error_time and writes a message to stderr * */ void log_error(const char *mesg) { fprintf(stderr, "%s%s", get_commonlog_time(), mesg); } /* * Name: log_error_mesg * * Description: performs a log_error_time, writes the file and lineno * to stderr (saving errno), and then a perror with message * */ #ifdef HAVE_FUNC void log_error_mesg(const char *file, int line, const char *func, const char *mesg) { int errno_save = errno; fprintf(stderr, "%s%s:%d (%s) - ", get_commonlog_time(), file, line, func); errno = errno_save; perror(mesg); errno = errno_save; } void log_error_mesg_fatal(const char *file, int line, const char *func, const char *mesg) { int errno_save = errno; fprintf(stderr, "%s%s:%d (%s) - ", get_commonlog_time(), file, line, func); errno = errno_save; perror(mesg); exit(EXIT_FAILURE); } #else void log_error_mesg(const char *file, int line, const char *mesg) { int errno_save = errno; fprintf(stderr, "%s%s:%d - ", get_commonlog_time(), file, line); errno = errno_save; perror(mesg); errno = errno_save; } void log_error_mesg_fatal(const char *file, int line, const char *mesg) { int errno_save = errno; fprintf(stderr, "%s%s:%d - ", get_commonlog_time(), file, line); errno = errno_save; perror(mesg); exit(EXIT_FAILURE); } #endif boa-0.94.14rc21/src/mmap_cache.c0000644000175000001440000001313510206636621016766 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1999-2005 Larry Doolittle * Copyright (C) 2000-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: mmap_cache.c,v 1.9.2.9 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" static int mmap_list_entries_used = 0; static int mmap_list_total_requests = 0; static int mmap_list_hash_bounces = 0; #define MMAP_LIST_NEXT(i) (((i)+1)&MMAP_LIST_MASK) #define MMAP_LIST_HASH(dev,ino,size) ((ino)&MMAP_LIST_MASK) /* define local table variable */ static struct mmap_entry mmap_list[MMAP_LIST_SIZE]; struct mmap_entry *find_mmap(int data_fd, struct stat *s) { void *m; int i, start; mmap_list_total_requests++; i = start = MMAP_LIST_HASH(s->st_dev, s->st_ino, s->st_size); for (; mmap_list[i].use_count;) { if (mmap_list[i].dev == s->st_dev && mmap_list[i].ino == s->st_ino && mmap_list[i].len == s->st_size) { mmap_list[i].use_count++; DEBUG(DEBUG_MMAP_CACHE) { fprintf(stderr, "Old mmap_list entry %d use_count now %d (hash was %d)\n", i, mmap_list[i].use_count, start); } return mmap_list + i; } mmap_list_hash_bounces++; i = MMAP_LIST_NEXT(i); if (i == start) { /* didn't find an entry that matches our dev/inode/size. There might be an entry that matches later in the table, but that _should_ be rare. The worst case is that we needlessly mmap() a file that is already mmap'd, but we did that all the time before this code was written, so it shouldn't be _too_ bad. */ /* we've looped, and found neither a free one nor a * match. Thus, there is no room for a new entry. */ /* WARN("mmap hash table is full. Consider enlarging."); */ return NULL; } } /* Enforce a size limit here */ /* Disallow more entries than MMAP_LIST_USE_MAX, despite * having found an available slot. */ if (mmap_list_entries_used > MMAP_LIST_USE_MAX) { /* WARN("Too many entries in mmap hash table."); */ return NULL; } m = mmap(0, s->st_size, PROT_READ, MAP_OPTIONS, data_fd, 0); if ((long) m == -1) { int saved_errno = errno; log_error_time(); fprintf(stderr, "Unable to mmap file: "); errno = saved_errno; perror("mmap"); return NULL; } #ifdef HAVE_MADVISE { int mret; mret = madvise(m, s->st_size, MADV_SEQUENTIAL); if (mret == -1) { int saved_errno = errno; log_error_time(); fprintf(stderr, "Unable to madvise file: "); errno = saved_errno; perror("madvise"); munmap(m, s->st_size); return NULL; } } #endif DEBUG(DEBUG_MMAP_CACHE) { fprintf(stderr, "New mmap_list entry %d (hash was %d)\n", i, start); } mmap_list_entries_used++; mmap_list[i].dev = s->st_dev; mmap_list[i].ino = s->st_ino; mmap_list[i].len = s->st_size; mmap_list[i].mmap = m; mmap_list[i].use_count = 1; return mmap_list + i; } void release_mmap(struct mmap_entry *e) { if (!e) return; if (!e->use_count) { DEBUG(DEBUG_MMAP_CACHE) { fprintf(stderr, "mmap_list(%p)->use_count already zero!\n", (void *) e); } return; } if (!--(e->use_count)) { munmap(e->mmap, e->len); mmap_list_entries_used--; } } #if 0 static struct mmap_entry *find_named_mmap(char *fname) { int data_fd; struct stat statbuf; struct mmap_entry *e; data_fd = open(fname, O_RDONLY); if (data_fd == -1) { perror(fname); return NULL; } fstat(data_fd, &statbuf); if (S_ISDIR(statbuf.st_mode)) { #ifdef DEBUG fprintf(stderr, "%s is a directory\n", fname); #endif return NULL; } e = find_mmap(data_fd, &statbuf); close(data_fd); return e; } #endif /* int main(int argc, char *argv[]) { #define MAXTEST 2048 struct mmap_entry *mlist[MAXTEST]; char name[1024], *s; int i, tests=0; while (fgets(name,sizeof(name),stdin) && tests < MAXTEST) { if (name[0]=='-') { i=atoi(name+1); release_mmap(mlist[i]); mlist[i]=NULL; } else { if ((s=strchr(name,'\n'))) *s='\0'; mlist[tests] = find_named_mmap(name); if (mlist[tests]) tests++; else fprintf(stderr, "find_named_mmap(%s) failed\n",name); } } fprintf(stderr, "mmap_list entries_used=%d ",mmap_list_entries_used); fprintf(stderr, "total_requests=%d ",mmap_list_total_requests); fprintf(stderr, "hash_bounces=%d\n",mmap_list_hash_bounces); for (i=0; i * Copyright (C) 1997-2004 Jon Nelson * Copyright (C) 1997-2005 Larry Doolittle * * 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 1, 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. * */ /* $Id: pipe.c,v 1.39.2.16 2005/02/22 14:13:03 jnelson Exp $*/ #include "boa.h" /* * Name: read_from_pipe * Description: Reads data from a pipe * * Return values: * -1: request blocked, move to blocked queue * 0: EOF or error, close it down * 1: successful read, recycle in ready queue */ int read_from_pipe(request * req) { int bytes_read; /* signed */ unsigned int bytes_to_read; /* unsigned */ bytes_to_read = BUFFER_SIZE - (req->header_end - req->buffer - 1); if (bytes_to_read == 0) { /* buffer full */ if (req->cgi_status == CGI_PARSE) { /* got+parsed header */ req->cgi_status = CGI_BUFFER; *req->header_end = '\0'; /* points to end of read data */ /* Could the above statement overwrite data??? No, because req->header_end points to where new data should begin, not where old data is. */ return process_cgi_header(req); /* cgi_status will change */ } req->status = PIPE_WRITE; return 1; } bytes_read = read(req->data_fd, req->header_end, bytes_to_read); #ifdef FASCIST_LOGGING if (bytes_read > 0) { *(req->header_end + bytes_read) = '\0'; fprintf(stderr, "pipe.c - read %d bytes: \"%s\"\n", bytes_read, req->header_end); } else fprintf(stderr, "pipe.c - read %d bytes\n", bytes_read); fprintf(stderr, "status, cgi_status: %d, %d\n", req->status, req->cgi_status); #endif if (bytes_read == -1) { if (errno == EINTR) return 1; else if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else { req->status = DEAD; log_error_doc(req); perror("pipe read"); return 0; } } *(req->header_end + bytes_read) = '\0'; if (bytes_read == 0) { /* eof, write rest of buffer */ req->status = PIPE_WRITE; if (req->cgi_status == CGI_PARSE) { /* hasn't processed header yet */ req->cgi_status = CGI_DONE; *req->header_end = '\0'; /* points to end of read data */ return process_cgi_header(req); /* cgi_status will change */ } req->cgi_status = CGI_DONE; return 1; } req->header_end += bytes_read; if (req->cgi_status != CGI_PARSE) return write_from_pipe(req); /* why not try and flush the buffer now? */ else { char *c, *buf; buf = req->header_line; c = strstr(buf, "\n\r\n"); if (c == NULL) { c = strstr(buf, "\n\n"); if (c == NULL) { return 1; } } req->cgi_status = CGI_DONE; *req->header_end = '\0'; /* points to end of read data */ return process_cgi_header(req); /* cgi_status will change */ } return 1; } /* * Name: write_from_pipe * Description: Writes data previously read from a pipe * * Return values: * -1: request blocked, move to blocked queue * 0: EOF or error, close it down * 1: successful write, recycle in ready queue */ int write_from_pipe(request * req) { int bytes_written; size_t bytes_to_write = req->header_end - req->header_line; if (bytes_to_write == 0) { if (req->cgi_status == CGI_DONE) return 0; req->status = PIPE_READ; req->header_end = req->header_line = req->buffer; return 1; } bytes_written = write(req->fd, req->header_line, bytes_to_write); if (bytes_written == -1) { if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else if (errno == EINTR) return 1; else { req->status = DEAD; log_error_doc(req); perror("pipe write"); return 0; } } req->header_line += bytes_written; req->bytes_written += bytes_written; /* if there won't be anything to write next time, switch state */ if ((unsigned) bytes_written == bytes_to_write) { req->status = PIPE_READ; req->header_end = req->header_line = req->buffer; } return 1; } #ifdef HAVE_SENDFILE int io_shuffle_sendfile(request * req) { int bytes_written; size_t bytes_to_write; off_t sendfile_offset; if (req->method == M_HEAD) { return complete_response(req); } /* XXX trouble if range is exactly 4G on a 32-bit machine? */ bytes_to_write = (req->ranges->stop - req->ranges->start) + 1; if (bytes_to_write > system_bufsize) bytes_to_write = system_bufsize; retrysendfile: if (bytes_to_write == 0) { /* shouldn't get here, but... */ bytes_written = 0; } else { /* arg 3 of sendfile should have type "off_t *" * struct range element start has type "unsigned long" * Where POSIX got the idea that an offset into a file * should be signed, I'll never know. */ sendfile_offset = req->ranges->start; if (sendfile_offset < 0) { req->status = DEAD; log_error_doc(req); fprintf(stderr, "impossible offset (%lu) requested of sendfile\n", req->ranges->start); return 0; } bytes_written = sendfile(req->fd, req->data_fd, &sendfile_offset, bytes_to_write); if (sendfile_offset < 0) { req->status = DEAD; log_error_doc(req); fprintf(stderr, "bad craziness in sendfile offset, returned %ld\n", (long) sendfile_offset); return 0; } req->ranges->start = sendfile_offset; if (bytes_written < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { return -1; /* request blocked at the pipe level, but keep going */ } else if (errno == EINTR) { goto retrysendfile; } else { req->status = DEAD; #ifdef QUIET_DISCONNECT if (0) #else if (errno != EPIPE && errno != ECONNRESET) #endif { log_error_doc(req); perror("sendfile write"); } } return 0; } else if (bytes_written == 0) { /* not sure how to handle this. * For now, treat it like it is blocked. */ return -1; }/* bytes_written */ } /* bytes_to_write */ /* sendfile automatically updates req->ranges->start * don't touch! * req->ranges->start += bytes_written; */ req->bytes_written += bytes_written; if (req->ranges->stop + 1 <= req->ranges->start) { return complete_response(req); } return 1; } #endif /* always try to read unless data_fs is 0 (and there is space) * then try to write * * Return values: * -1: request blocked, move to blocked queue * 0: EOF or error, close it down * 1: successful read, recycle in ready queue */ int io_shuffle(request * req) { int bytes_to_read; int bytes_written, bytes_to_write; if (req->method == M_HEAD) { return complete_response(req); } /* FIXME: This function doesn't take into account req->filesize * when *reading* into the buffer. Grr. * June 09, 2004: jdn, I don't think it's a problem anymore, * because the ranges are verified against the filesize, * and we cap bytes_to_read at bytes_to_write. */ bytes_to_read = BUFFER_SIZE - req->buffer_end - 256; bytes_to_write = (req->ranges->stop - req->ranges->start) + 1; if (bytes_to_read > bytes_to_write) bytes_to_read = bytes_to_write; if (bytes_to_read > 0 && req->data_fd) { int bytes_read; off_t temp; temp = lseek(req->data_fd, req->ranges->start, SEEK_SET); if (temp < 0) { req->status = DEAD; log_error_doc(req); perror("ioshuffle lseek"); return 0; } restartread: bytes_read = read(req->data_fd, req->buffer + req->buffer_end, bytes_to_read); if (bytes_read == -1) { if (errno == EINTR) goto restartread; else if (errno == EWOULDBLOCK || errno == EAGAIN) { /* not a fatal error, don't worry about it */ /* buffer is empty, we're blocking on read! */ if (req->buffer_end - req->buffer_start == 0) return -1; } else { req->status = DEAD; log_error_doc(req); perror("ioshuffle read"); return 0; } } else if (bytes_read == 0) { /* eof, write rest of buffer */ close(req->data_fd); req->data_fd = 0; } else { req->buffer_end += bytes_read; req->ranges->start += bytes_read; if ((req->ranges->stop + 1 - req->ranges->start) == 0) { return complete_response(req); } } } bytes_to_write = req->buffer_end - req->buffer_start; if (bytes_to_write == 0) { if (req->data_fd == 0) return 0; /* done */ req->buffer_end = req->buffer_start = 0; return 1; } restartwrite: bytes_written = write(req->fd, req->buffer + req->buffer_start, bytes_to_write); if (bytes_written == -1) { if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else if (errno == EINTR) goto restartwrite; else { req->status = DEAD; log_error_doc(req); perror("ioshuffle write"); return 0; } } else if (bytes_written == 0) { } req->buffer_start += bytes_written; req->bytes_written += bytes_written; if (bytes_to_write == bytes_written) { req->buffer_end = req->buffer_start = 0; } return 1; } boa-0.94.14rc21/src/poll.c0000644000175000001440000001567010206636621015665 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Some changes Copyright (C) 1996 Charles F. Randall * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1996-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: poll.c,v 1.2.2.18 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" void update_blocked(struct pollfd pfd1[]); struct pollfd *pfds; unsigned int pfd_len; void loop(int server_s) { struct pollfd pfd1[2][MAX_FD]; short which = 0, other = 1, temp; int server_pfd, watch_server; pfds = pfd1[which]; pfd_len = server_pfd = 0; watch_server = 1; while (1) { int timeout; time(¤t_time); if (sighup_flag) sighup_run(); if (sigchld_flag) sigchld_run(); if (sigalrm_flag) sigalrm_run(); if (sigterm_flag) { if (sigterm_flag == 1) { sigterm_stage1_run(); close(server_s); server_s = -1; /* remove server_pfd */ { unsigned int i, j; for(i = 0, j = 0;i < pfd_len;++i) { if (i == (unsigned) server_pfd) continue; pfd1[other][j].fd = pfd1[which][j].fd; pfd1[other][j].events = pfd1[which][j].events; ++j; } pfd_len = j; pfds = pfd1[other]; temp = other; other = which; which = temp; } watch_server = 0; } if (sigterm_flag == 2 && !request_ready && !request_block) { sigterm_stage2_run(); } } else { if (total_connections < max_connections) { server_pfd = pfd_len++; pfds[server_pfd].fd = server_s; pfds[server_pfd].events = BOA_READ; watch_server = 1; } else { watch_server = 0; } } /* If there are any requests ready, the timeout is 0. * If not, and there are any requests blocking, the * timeout is ka_timeout ? ka_timeout * 1000, otherwise * REQUEST_TIMEOUT * 1000. * -1 means forever */ pending_requests = 0; if (pfd_len) { timeout = (request_ready ? 0 : (request_block ? default_timeout : -1)); if (poll(pfds, pfd_len, timeout) == -1) { if (errno == EINTR) continue; /* while(1) */ } if (!sigterm_flag && watch_server) { /* */ if (pfds[server_pfd].revents & (POLLNVAL|POLLERR)) { /* problem with the server socket, unexpected */ log_error("server pfd revent contains " "POLLNVAL or POLLERR! Exiting."); exit(EXIT_FAILURE); } else if (pfds[server_pfd].revents & BOA_READ) { pending_requests = 1; } } time(¤t_time); /* if pfd_len is 0, we didn't poll, so the current time * should be up-to-date, and we *won't* be accepting anyway */ } /* go through blocked and unblock them if possible */ /* also resets pfd_len and pfd to known blocked */ pfd_len = 0; if (request_block) { update_blocked(pfd1[other]); } /* swap pfd */ pfds = pfd1[other]; temp = other; other = which; which = temp; /* process any active requests */ process_requests(server_s); } } /* * Name: update_blocked * * Description: iterate through the blocked requests, checking whether * that file descriptor has been set by select. Update the fd_set to * reflect current status. * * Here, we need to do some things: * - keepalive timeouts simply close * (this is special:: a keepalive timeout is a timeout where * keepalive is active but nothing has been read yet) * - regular timeouts close + error * - stuff in buffer and fd ready? write it out * - fd ready for other actions? do them */ void update_blocked(struct pollfd pfd1[]) { request *current, *next = NULL; time_t time_since; int revents; time(¤t_time); for (current = request_block; current; current = next) { time_since = current_time - current->time_last; next = current->next; // FIXME:: the first below has the chance of leaking memory! // (setting status to DEAD not DONE....) /* hmm, what if we are in "the middle" of a request and not * just waiting for a new one... perhaps check to see if anything * has been read via header position, etc... */ revents = pfds[current->pollfd_id].revents; if (revents & (POLLNVAL|POLLERR)) { /* socket returned error */ log_error_time(); fprintf(stderr, "Socket %d returned " "POLLNVAL|POLLERR (%s%s) ", current->fd, revents & POLLNVAL ? "POLLNVAL ":"", revents & POLLERR ? "POLLERR ":""); current->status = DEAD; } else if (time_since > REQUEST_TIMEOUT) { log_error_doc(current); fputs("connection timed out\n", stderr); current->status = TIMED_OUT; /* connection timed out */ } else if (current->kacount < ka_max && /* we *are* in a keepalive */ (time_since >= ka_timeout) && /* ka timeout has passed */ !current->logline) { /* haven't read anything yet */ log_error_doc(current); fputs("connection timed out\n", stderr); current->status = TIMED_OUT; /* connection timed out */ } else if (revents == 0) { /* still blocked */ pfd1[pfd_len].fd = pfds[current->pollfd_id].fd; pfd1[pfd_len].events = pfds[current->pollfd_id].events; current->pollfd_id = pfd_len++; continue; } ready_request(current); } } boa-0.94.14rc21/src/queue.c0000644000175000001440000000723110206636621016035 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1997-2002 Jon Nelson * * 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 1, 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. * */ /* $Id: queue.c,v 1.21.2.4 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" request *request_ready = NULL; /* ready list head */ request *request_block = NULL; /* blocked list head */ request *request_free = NULL; /* free list head */ /* * Name: block_request * * Description: Moves a request from the ready queue to the blocked queue */ void block_request(request * req) { dequeue(&request_ready, req); enqueue(&request_block, req); if (req->buffer_end) { BOA_FD_SET(req, req->fd, BOA_WRITE); } else { switch (req->status) { case IOSHUFFLE: #ifndef HAVE_SENDFILE if (req->buffer_end - req->buffer_start == 0) { BOA_FD_SET(req, req->data_fd, BOA_READ); break; } #endif case WRITE: case PIPE_WRITE: case DONE: BOA_FD_SET(req, req->fd, BOA_WRITE); break; case PIPE_READ: BOA_FD_SET(req, req->data_fd, BOA_READ); break; case BODY_WRITE: BOA_FD_SET(req, req->post_data_fd, BOA_WRITE); break; default: BOA_FD_SET(req, req->fd, BOA_READ); break; } } } /* * Name: ready_request * * Description: Moves a request from the blocked queue to the ready queue */ void ready_request(request * req) { dequeue(&request_block, req); enqueue(&request_ready, req); if (req->buffer_end) { BOA_FD_CLR(req, req->fd, BOA_WRITE); } else { switch (req->status) { case IOSHUFFLE: #ifndef HAVE_SENDFILE if (req->buffer_end - req->buffer_start == 0) { BOA_FD_CLR(req, req->data_fd, BOA_READ); break; } #endif case WRITE: case PIPE_WRITE: case DONE: BOA_FD_CLR(req, req->fd, BOA_WRITE); break; case PIPE_READ: BOA_FD_CLR(req, req->data_fd, BOA_READ); break; case BODY_WRITE: BOA_FD_CLR(req, req->post_data_fd, BOA_WRITE); break; default: BOA_FD_CLR(req, req->fd, BOA_READ); } } } /* * Name: dequeue * * Description: Removes a request from its current queue */ void dequeue(request ** head, request * req) { if (*head == req) *head = req->next; if (req->prev) req->prev->next = req->next; if (req->next) req->next->prev = req->prev; req->next = NULL; req->prev = NULL; } /* * Name: enqueue * * Description: Adds a request to the head of a queue */ void enqueue(request ** head, request * req) { if (*head) (*head)->prev = req; /* previous head's prev is us */ req->next = *head; /* our next is previous head */ req->prev = NULL; /* first in list */ *head = req; /* now we are head */ } boa-0.94.14rc21/src/range.c0000644000175000001440000002700510206636621016006 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 2000 Larry Doolittle * Copyright (C) 2000-2004 Jon Nelson * * 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, 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. * * range.c to test, build with * gcc -Wall -DSTANDALONE_TEST -DFASCIST_LOGGING range.c -o range * and test with * echo "bytes=0-10,15-9000,33-,-44,50-,30-50" | ./range 10000 * Parses client header information according to RFC2616, section 14.35.1 */ #include "boa.h" static void range_abort(request * req); static void range_add(request * req, unsigned long start, unsigned long stop); static Range *range_pool = NULL; void ranges_reset(request * req) { Range *r = req->ranges; while (r) { Range *bob; bob = r->next; range_pool_push(r); r = bob; } req->ranges = NULL; } Range *range_pool_pop(void) { Range *r; r = range_pool; if (r != NULL) range_pool = range_pool->next; else { /* have to make new range and return that */ r = malloc(sizeof (Range)); if (r == NULL) DIE("ran out of memory for new Range..."); } r->start = 0; r->stop = 0; r->next = NULL; return r; } void range_pool_empty(void) { while (range_pool != NULL) { Range *r = range_pool_pop(); free(r); } } void range_pool_push(Range * r) { r->next = range_pool; /* whether or not range_pool is NULL */ range_pool = r; } static void range_abort(request * req) { /* free all ranges starting with head */ ranges_reset(req); /* flag that we had an error, so no future ranges will be accepted */ req->ranges = range_pool_pop(); req->ranges->stop = -1; } static void range_add(request * req, unsigned long start, unsigned long stop) { Range *prev; Range *r = range_pool_pop(); DEBUG(DEBUG_RANGE) { fprintf(stderr, "range.c, range_add: got: %lu-%lu\n", start, stop); } for(prev = req->ranges;prev;prev = prev->next) { if (prev->next == NULL) break; } if (prev) { prev->next = r; } else { req->ranges = r; } r->start = start; r->stop = stop; req->numranges++; } /* parse_range converts the range string to a binary form _before_ * we know the size of the file. ranges_fixup touches up that * binary form _after_ we have req->filesize to work with. */ int ranges_fixup(request * req) { /* loop through the ranges */ Range *prev, *r; /* a -1 start means -xx * a -1 stop means xx- */ prev = NULL; r = req->ranges; req->ranges = NULL; if (req->filesize == 0) { Range *temp; while(r) { temp = r; r = r->next; range_pool_push(temp); } } while(r) { /* possible situations: * 1) start == -1 :: valid (so far) * 2) stop == -1 :: valid (so far) * 3) both are -1 :: impossible * 4) start <= stop :: valid * 5) start > stop && start != -1 :: invalid */ DEBUG(DEBUG_RANGE) { fprintf(stderr, "range.c: ranges_fixup: %lu-%lu\n", r->start, r->stop); } /* no stop range specified or stop is too big. * RFC says it gets req->filesize - 1 */ if (r->stop == (unsigned) -1 || r->stop >= req->filesize) { /* r->start is *not* -1 */ r->stop = req->filesize - 1; } /* no start range specified. * (such as -499 == last *500* bytes * thus, bytes (filesize - 499) through (filesize - 1) * assuming a 600 byte file: * -=> 600 - 499 = 100 through 599. * assuming a 6 byte file, and last 4 bytes: * -=> 6 - 4 = 2 through 6 - 1 = 5 * RFC says it gets filesize - stop. * Stop is already valid from a filesize point of view. */ if ((long) r->start == -1) { /* last N bytes of the entity body. * r->stop contains is N * due to the above test we are guaranteed * that r->stop is < req->filesize * we have to reset r->stop here, though */ r->start = req->filesize - r->stop; r->stop = req->filesize - 1; } /* start may only be <= stop. * in the case that start is == stop, * we write 1 byte. * in the case that start is < stop, * we're OK so long as start > 0 */ /* since start <= stop and stop < filesize, * start < filesize */ if ((long) r->start < 0 || r->start > r->stop) { Range *temp; temp = r; if (prev) prev->next = r->next; r = r->next; range_pool_push(temp); DEBUG(DEBUG_RANGE) { fprintf(stderr, "start or end of range is invalid. skipping.\n"); } continue; } /* r->stop and r->start are now both guaranteed < req->filesize */ /* r->stop and r->start may be the same, however */ DEBUG(DEBUG_RANGE) { fprintf(stderr, "ending with start: %lu\tstop: %lu\n", r->start, r->stop); } if (prev == NULL) req->ranges = r; prev = r; r = r->next; } if (req->ranges == NULL) { /* bad range */ send_r_invalid_range(req); return 0; } DEBUG(DEBUG_RANGE) { fprintf(stderr, "ranges_fixup returning 1\n"); } return 1; } /* * Name: parse_range * Description: Takes a char* string and extracts Range information from it. * Expects a null-terminated string in a format similar to the following: * "bytes=0-10,15-20000,33-,-44,50-,50-30" * Does not modify the input string. * Returns: 0 on error, 1 on success * Individual ranges are recorded using add_range. "-1" is used * as a marker for "not given" (as with 33- and -44 above). */ int range_parse(request * req, const char *str) { const char *initial_str = str; #ifdef FASCIST_LOGGING fprintf(stderr, "parsing: %s\n", str); #endif /* technically, this should be bytes (whitespace) = .... */ if (strncasecmp(str, "bytes=", 6)) { /* error. Doesn't start with 'bytes=' */ log_error_doc(req); log_error_time(); fprintf(stderr, "range \"%s\" doesn't start with \"bytes=\"\n", str); return 0; } /* the only stuff in a Range field is * whitespace, digits, ',' and '-' */ str += 6; { /* States */ #define initial 0 #define startnum 1 #define gap1 2 #define gap2 3 #define stopnum 4 int mode = initial; /* Character codes */ #define digit 0 #define white 1 #define comma 2 #define hyphen 3 #define null 4 #define other 5 int ccode; unsigned long start = 0, stop = 0; #define ACTMASK1 (0xE0) #define PB (0x20) /* Push Beginning */ #define PE (0x40) /* Push End */ #define DB (0x60) /* Disable Beginning */ #define DE (0x80) /* Disable End */ #define ACTMASK2 (0x18) #define AR (0x10) /* Abort Range */ #define SR (0x18) /* Submit Range */ #define STATEMASK (0x07) int stable[] = { /* digit white comma hyphen null other */ PB + startnum, 0 + initial, 0 + initial, DB + gap2, 0, AR, /* IN - initial */ PB + startnum, 0 + gap1, AR, 0 + gap2, AR, AR, /* startnum */ AR, 0 + gap1, AR, 0 + gap2, AR, AR, /* gap1 */ PE + stopnum, 0 + gap2, DE + SR + initial, AR, DE + SR, AR, /* gap2 */ PE + stopnum, SR + initial, SR + initial, AR, SR, AR }; /* stopnum */ int c; int fcode; for (;;) { c = *str++; /* There's probably a better way to code this character * code lookup, but this will do for now. Cache pollution * is more important than raw speed. */ switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ccode = digit; break; case ' ': case '\f': case '\n': case '\r': case '\t': case '\v': ccode = white; break; /* whitespace not actually legal */ case ',': ccode = comma; break; case '-': ccode = hyphen; break; case '\0': ccode = null; break; default: ccode = other; } fcode = stable[mode * 6 + ccode]; if ((fcode & ACTMASK1) == PB) start = start * 10 + (c - '0'); else if ((fcode & ACTMASK1) == DB) start = -1; else if ((fcode & ACTMASK1) == PE) stop = stop * 10 + (c - '0'); else if ((fcode & ACTMASK1) == DE) stop = -1; if ((fcode & ACTMASK2) == AR) { log_error_doc(req); log_error_time(); fprintf(stderr, "Invalid range request \"%s\".\n", initial_str); range_abort(req); return 0; } else if ((fcode & ACTMASK2) == SR) { if ((start == stop) && (start == (unsigned) -1)) { /* neither was specified, or they were very big. */ log_error_doc(req); log_error_time(); fprintf(stderr, "Invalid range request (neither start nor stop were specified).\n"); range_abort(req); return 0; } range_add(req, start, stop); start = 0; stop = 0; } if (ccode == null) return 1; mode = fcode & STATEMASK; } } return 1; } #ifdef STANDALONE_TEST void send_r_invalid_range(request * req) { fprintf(stderr, "send_r_invalid_range\n"); } void log_error_mesg(char *file, int line, char *mesg, int die) { fprintf(stderr, "%s:%d %s %d\n", file, line, mesg, die); } int main(int argc, char *argv[]) { request req; int c, fake_size = 10000; char buff[1024], *p; req.ranges = NULL; if (argc >= 2) fake_size = simple_itoa(argv[1]); while (fgets(buff, 1024, stdin)) { p = buff + strlen(buff) - 1; if (p >= buff && *p == '\n') *p = '\0'; req.filesize = -666; c = parse_range(&req, buff); printf("parse_range returned %d\n", c); req.filesize = fake_size; c = ranges_fixup(&req); printf("ranges_fixup returned %d\n", c); reset_ranges(&req); } return 0; } #endif boa-0.94.14rc21/src/read.c0000644000175000001440000003364710207122103015620 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-2005 Larry Doolittle * Copyright (C) 1997-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: read.c,v 1.49.2.14 2005/02/23 15:41:55 jnelson Exp $*/ #include "boa.h" /* * Name: read_header * Description: Reads data from a request socket. Manages the current * status via a state machine. Changes status from READ_HEADER to * READ_BODY or WRITE as necessary. * * Return values: * -1: request blocked, move to blocked queue * 0: request done, close it down * 1: more to do, leave on ready list */ int read_header(request * req) { int bytes; char *check, *buffer; unsigned char uc; check = req->client_stream + req->parse_pos; buffer = req->client_stream; bytes = req->client_stream_pos; DEBUG(DEBUG_HEADER_READ) { if (check < (buffer + bytes)) { buffer[bytes] = '\0'; log_error_time(); fprintf(stderr, "%s:%d - Parsing headers (\"%s\")\n", __FILE__, __LINE__, check); } } while (check < (buffer + bytes)) { /* check for illegal characters here * Anything except CR, LF, and US-ASCII - control is legal * We accept tab but don't do anything special with it. */ uc = *check; if (uc != '\r' && uc != '\n' && uc != '\t' && (uc < 32 || uc > 127)) { log_error_doc(req); fprintf(stderr, "Illegal character (%d) in stream.\n", (unsigned int) uc); send_r_bad_request(req); return 0; } switch (req->status) { case READ_HEADER: if (uc == '\r') { req->status = ONE_CR; req->header_end = check; } else if (uc == '\n') { req->status = ONE_LF; req->header_end = check; } break; case ONE_CR: if (uc == '\n') req->status = ONE_LF; else if (uc != '\r') req->status = READ_HEADER; break; case ONE_LF: /* if here, we've found the end (for sure) of a header */ if (uc == '\r') /* could be end o headers */ req->status = TWO_CR; else if (uc == '\n') req->status = BODY_READ; else req->status = READ_HEADER; break; case TWO_CR: if (uc == '\n') req->status = BODY_READ; else if (uc != '\r') req->status = READ_HEADER; break; default: break; } #ifdef VERY_FASCIST_LOGGING log_error_time(); fprintf(stderr, "status, check (unsigned): %d, %d\n", req->status, uc); #endif req->parse_pos++; /* update parse position */ check++; if (req->status == ONE_LF) { *req->header_end = '\0'; if (req->header_end - req->header_line >= MAX_HEADER_LENGTH) { log_error_doc(req); fprintf(stderr, "Header too long at %lu bytes: \"%s\"\n", (unsigned long) (req->header_end - req->header_line), req->header_line); send_r_bad_request(req); return 0; } /* terminate string that begins at req->header_line */ if (req->logline) { if (process_option_line(req) == 0) { /* errors already logged */ return 0; } } else { if (process_logline(req) == 0) /* errors already logged */ return 0; if (req->http_version == HTTP09) return process_header_end(req); } /* set header_line to point to beginning of new header */ req->header_line = check; } else if (req->status == BODY_READ) { #ifdef VERY_FASCIST_LOGGING int retval; log_error_time(); fprintf(stderr, "%s:%d -- got to body read.\n", __FILE__, __LINE__); retval = process_header_end(req); #else int retval = process_header_end(req); #endif /* process_header_end inits non-POST CGIs */ if (retval && req->method == M_POST) { /* for body_{read,write}, set header_line to start of data, and header_end to end of data */ req->header_line = check; req->header_end = req->client_stream + req->client_stream_pos; req->status = BODY_WRITE; /* so write it */ /* have to write first, or read will be confused * because of the special case where the * filesize is less than we have already read. */ /* As quoted from RFC1945: A valid Content-Length is required on all HTTP/1.0 POST requests. An HTTP/1.0 server should respond with a 400 (bad request) message if it cannot determine the length of the request message's content. */ if (req->content_length) { int content_length; content_length = boa_atoi(req->content_length); /* Is a content-length of 0 legal? */ if (content_length < 0) { log_error_doc(req); fprintf(stderr, "Invalid Content-Length [%s] on POST!\n", req->content_length); send_r_bad_request(req); return 0; } if (single_post_limit && content_length > single_post_limit) { log_error_doc(req); fprintf(stderr, "Content-Length [%d] > SinglePostLimit [%d] on POST!\n", content_length, single_post_limit); send_r_bad_request(req); return 0; } req->filesize = content_length; req->filepos = 0; if ((unsigned) (req->header_end - req->header_line) > req->filesize) { req->header_end = req->header_line + req->filesize; } } else { log_error_doc(req); fprintf(stderr, "Unknown Content-Length POST!\n"); send_r_bad_request(req); return 0; } } /* either process_header_end failed or req->method != POST */ return retval; /* 0 - close it done, 1 - keep on ready */ } /* req->status == BODY_READ */ } /* done processing available buffer */ #ifdef VERY_FASCIST_LOGGING log_error_time(); fprintf(stderr, "%s:%d - Done processing buffer. Status: %d\n", __FILE__, __LINE__, req->status); #endif if (req->status < BODY_READ) { /* only reached if request is split across more than one packet */ unsigned int buf_bytes_left; buf_bytes_left = CLIENT_STREAM_SIZE - req->client_stream_pos; if (buf_bytes_left < 1 || buf_bytes_left > CLIENT_STREAM_SIZE) { log_error_doc(req); fputs("No space left in client stream buffer, closing\n", stderr); req->response_status = 400; req->status = DEAD; return 0; } bytes = read(req->fd, buffer + req->client_stream_pos, buf_bytes_left); if (bytes < 0) { if (errno == EINTR) return 1; else if (errno == EAGAIN || errno == EWOULDBLOCK) /* request blocked */ return -1; log_error_doc(req); perror("header read"); /* don't need to save errno because log_error_doc does */ req->response_status = 400; return 0; } else if (bytes == 0) { if (req->kacount < ka_max && !req->logline && req->client_stream_pos == 0) { /* A keepalive request wherein we've read * nothing. * Ignore. */ ; } else { #ifndef QUIET_DISCONNECT log_error_doc(req); fputs("client unexpectedly closed connection.\n", stderr); #endif } req->response_status = 400; return 0; } /* bytes is positive */ req->client_stream_pos += bytes; DEBUG(DEBUG_HEADER_READ) { log_error_time(); req->client_stream[req->client_stream_pos] = '\0'; fprintf(stderr, "%s:%d -- We read %d bytes: \"%s\"\n", __FILE__, __LINE__, bytes, #ifdef VERY_FASCIST_LOGGING2 req->client_stream + req->client_stream_pos - bytes #else "" #endif ); } return 1; } return 1; } /* * Name: read_body * Description: Reads body from a request socket for POST CGI * * Return values: * * -1: request blocked, move to blocked queue * 0: request done, close it down * 1: more to do, leave on ready list * As quoted from RFC1945: A valid Content-Length is required on all HTTP/1.0 POST requests. An HTTP/1.0 server should respond with a 400 (bad request) message if it cannot determine the length of the request message's content. */ int read_body(request * req) { int bytes_read; unsigned int bytes_to_read, bytes_free; bytes_free = BUFFER_SIZE - (req->header_end - req->header_line); bytes_to_read = req->filesize - req->filepos; if (bytes_to_read > bytes_free) bytes_to_read = bytes_free; if (bytes_to_read <= 0) { req->status = BODY_WRITE; /* go write it */ return 1; } bytes_read = read(req->fd, req->header_end, bytes_to_read); if (bytes_read == -1) { if (errno == EWOULDBLOCK || errno == EAGAIN) { return -1; } else { boa_perror(req, "read body"); req->response_status = 400; return 0; } } else if (bytes_read == 0) { /* this is an error. premature end of body! */ log_error_doc(req); fprintf(stderr, "%s:%d - Premature end of body!!\n", __FILE__, __LINE__); send_r_bad_request(req); return 0; } req->status = BODY_WRITE; #ifdef FASCIST_LOGGING1 log_error_time(); fprintf(stderr, "%s:%d - read %d bytes.\n", __FILE__, __LINE__, bytes_to_read); #endif req->header_end += bytes_read; return 1; } /* * Name: write_body * Description: Writes a chunk of data to a file * * Return values: * -1: request blocked, move to blocked queue * 0: EOF or error, close it down * 1: successful write, recycle in ready queue */ int write_body(request * req) { int bytes_written; unsigned int bytes_to_write = req->header_end - req->header_line; if (req->filepos + bytes_to_write > req->filesize) bytes_to_write = req->filesize - req->filepos; if (bytes_to_write == 0) { /* nothing left in buffer to write */ req->header_line = req->header_end = req->buffer; if (req->filepos >= req->filesize) return init_cgi(req); /* if here, we can safely assume that there is more to read */ req->status = BODY_READ; return 1; } bytes_written = write(req->post_data_fd, req->header_line, bytes_to_write); if (bytes_written < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else if (errno == EINTR) return 1; else if (errno == ENOSPC) { /* 20010520 - Alfred Fluckiger */ /* No test was originally done in this case, which might */ /* lead to a "no space left on device" error. */ boa_perror(req, "write body"); /* OK to disable if your logs get too big */ return 0; } else { boa_perror(req, "write body"); /* OK to disable if your logs get too big */ return 0; } } DEBUG(DEBUG_HEADER_READ) { log_error_time(); fprintf(stderr, "%s:%d - wrote %d bytes of CGI body. %ld of %ld\n", __FILE__, __LINE__, bytes_written, req->filepos, req->filesize); } req->filepos += bytes_written; req->header_line += bytes_written; DEBUG(DEBUG_CGI_INPUT) { log_error_time(); { char c = req->header_line[bytes_written]; req->header_line[bytes_written] = '\0'; fprintf(stderr, "%s:%d - wrote %d bytes (%s). %lu of %lu\n", __FILE__, __LINE__, bytes_written, req->header_line, req->filepos, req->filesize); req->header_line[bytes_written] = c; } } return 1; /* more to do */ } boa-0.94.14rc21/src/request.c0000644000175000001440000007325610206636621016413 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-2005 Larry Doolittle * Copyright (C) 1996-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: request.c,v 1.112.2.51 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" #include /* for offsetof */ #define TUNE_SNDBUF /* #define USE_TCPNODELAY #define NO_RATE_LIMIT #define DIE_ON_ERROR_TUNING_SNDBUF */ unsigned total_connections = 0; unsigned int system_bufsize = 0; /* Default size of SNDBUF given by system */ struct status status; static unsigned int sockbufsize = SOCKETBUF_SIZE; /* function prototypes located in this file only */ static void free_request(request * req); static void sanitize_request(request * req, int make_new_request); /* * Name: new_request * Description: Obtains a request struct off the free list, or if the * free list is empty, allocates memory * * Return value: pointer to initialized request */ request *new_request(void) { request *req; if (request_free) { req = request_free; /* first on free list */ dequeue(&request_free, request_free); /* dequeue the head */ } else { req = (request *) malloc(sizeof (request)); if (!req) { log_error_time(); perror("malloc for new request"); return NULL; } } sanitize_request(req, 1); return req; } /* * Name: get_request * * Description: Polls the server socket for a request. If one exists, * does some basic initialization and adds it to the ready queue;. */ void get_request(int server_sock) { int fd; /* socket */ struct SOCKADDR remote_addr; /* address */ struct SOCKADDR salocal; unsigned int remote_addrlen = sizeof (struct SOCKADDR); request *conn; /* connection */ socklen_t len; #ifndef INET6 remote_addr.S_FAMILY = (sa_family_t) 0xdead; #endif fd = accept(server_sock, (struct sockaddr *) &remote_addr, &remote_addrlen); if (fd == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { /* abnormal error */ WARN("accept"); } else { /* no requests */ } pending_requests = 0; return; } if (fd >= FD_SETSIZE) { log_error("Got fd >= FD_SETSIZE."); close(fd); return; } #ifdef DEBUGNONINET /* This shows up due to race conditions in some Linux kernels when the client closes the socket sometime between the select() and accept() syscalls. Code and description by Larry Doolittle */ if (remote_addr.sin_family != PF_INET) { struct sockaddr *bogus = (struct sockaddr *) &remote_addr; char *ap, ablock[44]; int i; close(fd); log_error_time(); for (ap = ablock, i = 0; i < remote_addrlen && i < 14; i++) { *ap++ = ' '; *ap++ = INT_TO_HEX((bogus->sa_data[i] >> 4) & 0x0f); *ap++ = INT_TO_HEX(bogus->sa_data[i] & 0x0f); } *ap = '\0'; fprintf(stderr, "non-INET connection attempt: socket %d, " "sa_family = %hu, sa_data[%d] = %s\n", fd, bogus->sa_family, remote_addrlen, ablock); return; } #endif /* XXX Either delete this, or document why it's needed */ /* Pointed out 3-Oct-1999 by Paul Saab */ #ifdef REUSE_EACH_CLIENT_CONNECTION_SOCKET if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_opt, sizeof (sock_opt))) == -1) { DIE("setsockopt: unable to set SO_REUSEADDR"); } #endif len = sizeof (salocal); if (getsockname(fd, (struct sockaddr *) &salocal, &len) != 0) { WARN("getsockname"); close(fd); return; } conn = new_request(); if (!conn) { close(fd); return; } conn->fd = fd; conn->status = READ_HEADER; conn->header_line = conn->client_stream; conn->time_last = current_time; conn->kacount = ka_max; if (ascii_sockaddr (&salocal, conn->local_ip_addr, sizeof (conn->local_ip_addr)) == NULL) { WARN("ascii_sockaddr failed"); close(fd); enqueue(&request_free, conn); return; } /* nonblocking socket */ if (set_nonblock_fd(conn->fd) == -1) { WARN("fcntl: unable to set new socket to non-block"); close(fd); enqueue(&request_free, conn); return; } /* set close on exec to true */ if (fcntl(conn->fd, F_SETFD, 1) == -1) { WARN("fctnl: unable to set close-on-exec for new socket"); close(fd); enqueue(&request_free, conn); return; } #ifdef TUNE_SNDBUF /* Increase buffer size if we have to. * Only ask the system the buffer size on the first request, * and assume all subsequent sockets have the same size. */ if (system_bufsize == 0) { len = sizeof (system_bufsize); if (getsockopt (conn->fd, SOL_SOCKET, SO_SNDBUF, &system_bufsize, &len) == 0 && len == sizeof (system_bufsize)) { ; } else { WARN("getsockopt(SNDBUF)"); system_bufsize = 1; } } if (system_bufsize < sockbufsize) { if (setsockopt (conn->fd, SOL_SOCKET, SO_SNDBUF, (void *) &sockbufsize, sizeof (sockbufsize)) == -1) { WARN("setsockopt: unable to set socket buffer size"); #ifdef DIE_ON_ERROR_TUNING_SNDBUF exit(errno); #endif /* DIE_ON_ERROR_TUNING_SNDBUF */ } } #endif /* TUNE_SNDBUF */ /* for log file and possible use by CGI programs */ if (ascii_sockaddr (&remote_addr, conn->remote_ip_addr, sizeof (conn->remote_ip_addr)) == NULL) { WARN("ascii_sockaddr failed"); close(fd); enqueue(&request_free, conn); return; } /* for possible use by CGI programs */ conn->remote_port = net_port(&remote_addr); status.requests++; #ifdef USE_TCPNODELAY /* Thanks to Jef Poskanzer for this tweak */ { int one = 1; if (setsockopt(conn->fd, IPPROTO_TCP, TCP_NODELAY, (void *) &one, sizeof (one)) == -1) { DIE("setsockopt: unable to set TCP_NODELAY"); } } #endif total_connections++; /* gotta have some breathing room */ if (total_connections > max_connections) { pending_requests = 0; #ifndef NO_RATE_LIMIT /* have to fake an http version */ conn->http_version = HTTP10; conn->method = M_GET; send_r_service_unavailable(conn); conn->status = DONE; #endif /* NO_RATE_LIMIT */ } enqueue(&request_ready, conn); } static void sanitize_request(request * req, int new_req) { static unsigned int bytes_to_zero = offsetof(request, fd); if (new_req) { req->kacount = ka_max; req->time_last = current_time; req->client_stream_pos = 0; } else { unsigned int bytes_to_move = req->client_stream_pos - req->parse_pos; if (bytes_to_move) { memmove(req->client_stream, req->client_stream + req->parse_pos, bytes_to_move); } req->client_stream_pos = bytes_to_move; } /* bzero */ /* we want to clear a middle part of the request: */ DEBUG(DEBUG_REQUEST) { log_error_time(); fprintf(stderr, "req: %p, offset: %u\n", (void *) req, bytes_to_zero); } memset(req, 0, bytes_to_zero); req->status = READ_HEADER; req->header_line = req->client_stream; } /* * Name: free_request * * Description: Deallocates memory for a finished request and closes * down socket. */ static void free_request(request * req) { int i; /* free_request should *never* get called by anything but process_requests */ if (req->buffer_end && req->status < TIMED_OUT) { /* WARN("request sent to free_request before DONE."); */ req->status = DONE; /* THIS IS THE SAME CODE EXECUTED BY THE 'DONE' SECTION * of process_requests. It must be exactly the same! */ i = req_flush(req); /* * retval can be -2=error, -1=blocked, or bytes left */ if (i == -2) { /* error */ req->status = DEAD; } else if (i > 0) { return; } } /* put request on the free list */ dequeue(&request_ready, req); /* dequeue from ready or block list */ /* set response status to 408 if the client has timed out */ if (req->status == TIMED_OUT && req->response_status == 0) req->response_status = 408; if (req->kacount < ka_max && !req->logline && req->client_stream_pos == 0) { /* A keepalive request wherein we've read * nothing. * Ignore. */ ; } else { log_access(req); } if (req->mmap_entry_var) release_mmap(req->mmap_entry_var); else if (req->data_mem) munmap(req->data_mem, req->filesize); if (req->data_fd) { close(req->data_fd); BOA_FD_CLR(req, req->data_fd, BOA_READ); } if (req->post_data_fd) { close(req->post_data_fd); BOA_FD_CLR(req, req->post_data_fd, BOA_WRITE); } if (req->response_status >= 400) status.errors++; for (i = common_cgi_env_count; i < req->cgi_env_index; ++i) { if (req->cgi_env[i]) { free(req->cgi_env[i]); } else { log_error_time(); fprintf(stderr, "Warning: CGI Environment contains NULL value" "(index %d of %d).\n", i, req->cgi_env_index); } } if (req->pathname) free(req->pathname); if (req->path_info) free(req->path_info); if (req->path_translated) free(req->path_translated); if (req->script_name) free(req->script_name); if (req->host) free(req->host); if (req->ranges) ranges_reset(req); if (req->status < TIMED_OUT && (req->keepalive == KA_ACTIVE) && (req->response_status < 500 && req->response_status != 0) && req->kacount > 0) { sanitize_request(req, 0); --(req->kacount); status.requests++; enqueue(&request_block, req); BOA_FD_SET(req, req->fd, BOA_READ); BOA_FD_CLR(req, req->fd, BOA_WRITE); return; } /* While debugging some weird errors, Jon Nelson learned that some versions of Netscape Navigator break the HTTP specification. Some research on the issue brought up: http://www.apache.org/docs/misc/known_client_problems.html As quoted here: " Trailing CRLF on POSTs This is a legacy issue. The CERN webserver required POST data to have an extra CRLF following it. Thus many clients send an extra CRLF that is not included in the Content-Length of the request. Apache works around this problem by eating any empty lines which appear before a request. " Boa will (for now) hack around this stupid bug in Netscape (and Internet Exploder) by reading up to 32k after the connection is all but closed. This should eliminate any remaining spurious crlf sent by the client. Building bugs *into* software to be compatible is just plain wrong */ if (req->method == M_POST) { char buf[32768]; read(req->fd, buf, sizeof(buf)); } close(req->fd); BOA_FD_CLR(req, req->fd, BOA_READ); BOA_FD_CLR(req, req->fd, BOA_WRITE); total_connections--; enqueue(&request_free, req); return; } /* * Name: process_requests * * Description: Iterates through the ready queue, passing each request * to the appropriate handler for processing. It monitors the * return value from handler functions, all of which return -1 * to indicate a block, 0 on completion and 1 to remain on the * ready list for more processing. */ void process_requests(int server_sock) { int retval = 0; request *current, *trailer; if (pending_requests) { get_request(server_sock); #ifdef ORIGINAL_BEHAVIOR pending_requests = 0; #endif } current = request_ready; while (current) { time(¤t_time); retval = 1; /* emulate "success" in case we don't have to flush */ if (current->buffer_end && /* there is data in the buffer */ current->status < TIMED_OUT) { retval = req_flush(current); /* * retval can be -2=error, -1=blocked, or bytes left */ if (retval == -2) { /* error */ current->status = DEAD; retval = 0; } else if (retval >= 0) { /* notice the >= which is different from below? Here, we may just be flushing headers. We don't want to return 0 because we are not DONE or DEAD */ retval = 1; } } if (retval == 1) { switch (current->status) { case READ_HEADER: case ONE_CR: case ONE_LF: case TWO_CR: retval = read_header(current); break; case BODY_READ: retval = read_body(current); break; case BODY_WRITE: retval = write_body(current); break; case WRITE: retval = process_get(current); break; case PIPE_READ: retval = read_from_pipe(current); break; case PIPE_WRITE: retval = write_from_pipe(current); break; case IOSHUFFLE: #ifdef HAVE_SENDFILE retval = io_shuffle_sendfile(current); #else retval = io_shuffle(current); #endif break; case DONE: /* a non-status that will terminate the request */ retval = req_flush(current); /* * retval can be -2=error, -1=blocked, or bytes left */ if (retval == -2) { /* error */ current->status = DEAD; retval = 0; } else if (retval > 0) { retval = 1; } break; case TIMED_OUT: case DEAD: retval = 0; current->buffer_end = 0; SQUASH_KA(current); break; default: retval = 0; fprintf(stderr, "Unknown status (%d), " "closing!\n", current->status); current->status = DEAD; break; } } if (sigterm_flag) SQUASH_KA(current); /* we put this here instead of after the switch so that * if we are on the last request, and get_request is successful, * current->next is valid! */ if (pending_requests) get_request(server_sock); switch (retval) { case -1: /* request blocked */ trailer = current; current = current->next; block_request(trailer); break; case 0: /* request complete */ current->time_last = current_time; trailer = current; current = current->next; free_request(trailer); break; case 1: /* more to do */ current->time_last = current_time; current = current->next; break; default: log_error_doc(current); fprintf(stderr, "Unknown retval in process.c - " "Status: %d, retval: %d\n", current->status, retval); current->status = DEAD; current = current->next; break; } } } /* * Name: process_logline * * Description: This is called with the first req->header_line received * by a request, called "logline" because it is logged to a file. * It is parsed to determine request type and method, then passed to * translate_uri for further parsing. Also sets up CGI environment if * needed. */ int process_logline(request * req) { char *stop, *stop2; req->logline = req->client_stream; if (strlen(req->logline) < 5) { /* minimum length req'd. */ log_error_doc(req); fprintf(stderr, "Request too short: \"%s\"\n", req->logline); send_r_bad_request(req); return 0; } if (!memcmp(req->logline, "GET ", 4)) req->method = M_GET; else if (!memcmp(req->logline, "HEAD ", 5)) /* head is just get w/no body */ req->method = M_HEAD; else if (!memcmp(req->logline, "POST ", 5)) req->method = M_POST; else { log_error_doc(req); fprintf(stderr, "malformed request: \"%s\"\n", req->logline); send_r_not_implemented(req); return 0; } req->http_version = HTTP10; /* Guaranteed to find ' ' since we matched a method above */ stop = req->logline + 3; if (*stop != ' ') ++stop; /* scan to start of non-whitespace */ while (*(++stop) == ' '); stop2 = stop; /* scan to end of non-whitespace */ while (*stop2 != '\0' && *stop2 != ' ') ++stop2; if (stop2 - stop > MAX_HEADER_LENGTH) { log_error_doc(req); fprintf(stderr, "URI too long %d: \"%s\"\n", MAX_HEADER_LENGTH, req->logline); send_r_bad_request(req); return 0; } /* check for absolute URL */ if (!memcmp(stop, SERVER_METHOD, strlen(SERVER_METHOD)) && !memcmp(stop + strlen(SERVER_METHOD), "://", 3)) { char *host; /* we have an absolute URL */ /* advance STOP until first '/' after host */ stop += strlen(SERVER_METHOD) + 3; host = stop; /* if *host is '/' there is no host in the URI * if *host is ' ' there is corruption in the URI * if *host is '\0' there is nothing after http:// */ if (*host == '/' || *host == ' ' || *host == '\0') { /* nothing *at all* after http:// */ /* no host in absolute URI */ log_error_doc(req); /* we don't need to log req->logline, because log_error_doc does */ fprintf(stderr, "bogus absolute URI\n"); send_r_bad_request(req); return 0; } /* OK. The 'host' is at least 1 char long. * advance to '/', or end of host+url (' ' or ''\0') */ while(*stop != '\0' && *stop != '/' && *stop != ' ') ++stop; if (*stop != '/') { /* *stop is '\0' or ' ' */ /* host is valid, but there is no URL. */ log_error_doc(req); fprintf(stderr, "no URL in absolute URI: \"%s\"\n", req->logline); send_r_bad_request(req); return 0; } /* we have http://X/ where X is not ' ' or '/' (or '\0') */ /* since stop2 stops on '\0' and ' ', it *must* be after stop */ /* still, a safety check (belts and suspenders) */ if (stop2 < stop) { /* Corruption in absolute URI */ /* This prevents a DoS attack from format string attacks */ log_error_doc(req); fprintf(stderr, "Error: corruption in absolute URI:" "\"%s\". This should not happen.\n", req->logline); send_r_bad_request(req); return 0; } /* copy the URI */ memcpy(req->request_uri, stop, stop2 - stop); /* place a NIL in the file spot to terminate host */ *stop = '\0'; /* place host */ /* according to RFC2616 -- 1. If Request-URI is an absoluteURI, the host is part of the Request-URI. Any Host header field value in the request MUST be ignored. Since we ignore any Host header if req->host is already set, well, we rock! */ req->header_host = host; /* this includes the port! (if any) */ } else { /* copy the URI */ memcpy(req->request_uri, stop, stop2 - stop); } req->request_uri[stop2 - stop] = '\0'; /* METHOD URL\0 */ if (*stop2 == '\0') req->http_version = HTTP09; else if (*stop2 == ' ') { /* if found, we should get an HTTP/x.x */ unsigned int p1, p2; /* scan to end of whitespace */ ++stop2; while (*stop2 == ' ' && *stop2 != '\0') ++stop2; if (*stop2 == '\0') { req->http_version = HTTP09; } else { /* scan in HTTP/major.minor */ if (sscanf(stop2, "HTTP/%u.%u", &p1, &p2) == 2) { /* HTTP/{0.9,1.0,1.1} */ if (p1 == 0 && p2 == 9) { req->http_version = HTTP09; } else if (p1 == 1 && p2 == 0) { req->http_version = HTTP10; } else if (p1 == 1 && p2 == 1) { req->http_version = HTTP11; req->keepalive = KA_ACTIVE; /* enable keepalive */ /* Disable send_r_continue because some clients * *still* don't work with it, Python 2.2 being one * see bug 227361 at the sourceforge web site. * fixed in revision 1.52 of httplib.py, dated * 2002-06-28 (perhaps Python 2.3 will * contain the fix.) * * Also, send_r_continue should *only* be * used if the expect header was sent. */ /* send_r_continue(req); */ } else { goto BAD_VERSION; } } else { goto BAD_VERSION; } } } if (req->method == M_HEAD && req->http_version == HTTP09) { log_error("method is HEAD but version is HTTP/0.9"); send_r_bad_request(req); return 0; } req->cgi_env_index = common_cgi_env_count; return 1; BAD_VERSION: log_error_doc(req); fprintf(stderr, "bogus HTTP version: \"%s\"\n", stop2); send_r_bad_request(req); return 0; } /* * Name: process_header_end * * Description: takes a request and performs some final checking before * init_cgi or init_get * Returns 0 for error or NPH, or 1 for success */ int process_header_end(request * req) { if (!req->logline) { log_error_doc(req); fputs("No logline in process_header_end\n", stderr); send_r_error(req); return 0; } /* Percent-decode request */ if (unescape_uri(req->request_uri, &(req->query_string)) == 0) { log_error_doc(req); fputs("URI contains bogus characters\n", stderr); send_r_bad_request(req); return 0; } /* clean pathname */ clean_pathname(req->request_uri); if (req->request_uri[0] != '/') { log_error("URI does not begin with '/'\n"); send_r_bad_request(req); return 0; } if (vhost_root) { char *c; if (!req->header_host) { req->host = strdup(default_vhost); } else { req->host = strdup(req->header_host); } if (!req->host) { log_error_doc(req); fputs("unable to strdup default_vhost/req->header_host\n", stderr); send_r_error(req); return 0; } strlower(req->host); /* check for port, and remove * we essentially ignore the port, because we cannot * as yet report a different port than the one we are * listening on */ c = strchr(req->host, ':'); if (c) *c = '\0'; if (check_host(req->host) < 1) { log_error_doc(req); fputs("host invalid!\n", stderr); send_r_bad_request(req); return 0; } } if (translate_uri(req) == 0) { /* unescape, parse uri */ /* errors already logged */ SQUASH_KA(req); return 0; /* failure, close down */ } if (req->method == M_POST) { req->post_data_fd = create_temporary_file(1, NULL, 0); if (req->post_data_fd == 0) { /* errors already logged */ send_r_error(req); return 0; } if (fcntl(req->post_data_fd, F_SETFD, 1) == -1) { boa_perror(req, "unable to set close-on-exec for req->post_data_fd!"); close(req->post_data_fd); req->post_data_fd = 0; return 0; } return 1; /* success */ } if (req->cgi_type) { return init_cgi(req); } req->status = WRITE; return init_get(req); /* get and head */ } /* * Name: process_option_line * * Description: Parses the contents of req->header_line and takes * appropriate action. */ int process_option_line(request * req) { char c, *value, *line = req->header_line; /* Start by aggressively hacking the in-place copy of the header line */ #ifdef FASCIST_LOGGING log_error_time(); fprintf(stderr, "%s:%d - Parsing \"%s\"\n", __FILE__, __LINE__, line); #endif value = strchr(line, ':'); if (value == NULL) { log_error_doc(req); fprintf(stderr, "header \"%s\" does not contain ':'\n", line); return 0; } *value++ = '\0'; /* overwrite the : */ to_upper(line); /* header types are case-insensitive */ /* the code below *does* catch '\0' due to the c = *value test */ while ((c = *value) && (c == ' ' || c == '\t')) value++; /* if c == '\0' there was no 'value' for the key */ if (c == '\0') { /* return now to bypass any parsing or assignment */ return 1; } switch (line[0]) { case 'A': if (!memcmp(line, "ACCEPT", 7)) { #ifdef ACCEPT_ON add_accept_header(req, value); #endif return 1; } break; case 'C': if (!memcmp(line, "CONTENT_TYPE", 13) && !req->content_type) { req->content_type = value; return 1; } else if (!memcmp(line, "CONTENT_LENGTH", 15) && !req->content_length) { req->content_length = value; return 1; } else if (!memcmp(line, "CONNECTION", 11) && ka_max && req->keepalive != KA_STOPPED) { req->keepalive = (!strncasecmp(value, "Keep-Alive", 10) ? KA_ACTIVE : KA_STOPPED); return 1; } break; case 'H': if (!memcmp(line, "HOST", 5) && !req->header_host) { req->header_host = value; /* may be complete garbage! */ return 1; } break; case 'I': if (!memcmp(line, "IF_MODIFIED_SINCE", 18) && !req->if_modified_since) { req->if_modified_since = value; return 1; } break; case 'R': /* Need agent and referer for logs */ if (!memcmp(line, "REFERER", 8)) { req->header_referer = value; if (!add_cgi_env(req, "REFERER", value, 1)) { /* errors already logged */ return 0; } } else if (!memcmp(line, "RANGE", 6)) { if (req->ranges && req->ranges->stop == INT_MAX) { /* there was an error parsing, ignore */ return 1; } else if (!range_parse(req, value)) { /* unable to parse range */ send_r_invalid_range(req); return 0; } /* req->ranges */ } break; case 'U': if (!memcmp(line, "USER_AGENT", 11)) { req->header_user_agent = value; if (!add_cgi_env(req, "USER_AGENT", value, 1)) { /* errors already logged */ return 0; } return 1; } break; default: /* no default */ break; } /* switch */ return add_cgi_env(req, line, value, 1); } #ifdef ACCEPT_ON /* * Name: add_accept_header * Description: Adds a mime_type to a requests accept char buffer * silently ignore any that don't fit - * shouldn't happen because of relative buffer sizes */ void add_accept_header(request * req, const char *mime_type) { int l = strlen(req->accept); int l2 = strlen(mime_type); if ((l + l2 + 2) >= MAX_HEADER_LENGTH) return; if (req->accept[0] == '\0') { memcpy(req->accept, mime_type, l2 + 1); } else { req->accept[l] = ','; req->accept[l + 1] = ' '; memcpy(req->accept + l + 2, mime_type, l2 + 1); /* the +1 is for the '\0' */ } } #endif void free_requests(void) { request *ptr, *next; ptr = request_free; while (ptr != NULL) { next = ptr->next; free(ptr); ptr = next; } request_free = NULL; } boa-0.94.14rc21/src/response.c0000644000175000001440000004637210206636621016560 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1996-2004 Jon Nelson * * 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 1, 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. * */ /* $Id: response.c,v 1.41.2.17 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" #define HTML "text/html; charset=ISO-8859-1" const char *http_ver_string(enum HTTP_VERSION ver) { switch(ver) { case HTTP09: return "HTTP/0.9"; break; case HTTP10: return "HTTP/1.0"; break; case HTTP11: return "HTTP/1.1"; break; default: return "HTTP/1.0"; } return NULL; } void print_content_type(request * req) { char * mime_type = get_mime_type(req->request_uri); if (mime_type != NULL) { req_write(req, "Content-Type: "); req_write(req, mime_type); if (default_charset != NULL && strncasecmp( mime_type, "text", 4)==0) { /* add default charset */ req_write( req, "; charset="); req_write( req, default_charset); } req_write(req, CRLF); } } void print_content_length(request * req) { req_write(req, "Content-Length: "); req_write(req, simple_itoa(req->filesize)); req_write(req, CRLF); } void print_last_modified(request * req) { static char lm[] = "Last-Modified: " " " CRLF; rfc822_time_buf(lm + 15, req->last_modified); req_write(req, lm); } void print_ka_phrase(request * req) { if (req->kacount > 0 && req->keepalive == KA_ACTIVE && req->response_status < 500) { /* FIXME: Should we only print one or the other if we are HTTP * version between 1.0 (incl.) and 1.1 (not incl.) ? */ req_write(req, "Connection: Keep-Alive" CRLF "Keep-Alive: timeout="); req_write(req, simple_itoa(ka_timeout)); req_write(req, ", max="); req_write(req, simple_itoa(req->kacount)); req_write(req, CRLF); } else req_write(req, "Connection: close" CRLF); } void print_http_headers(request * req) { static char date_header[] = "Date: " " " CRLF; static char server_header[] = "Server: " SERVER_VERSION CRLF; rfc822_time_buf(date_header + 6, 0); req_write(req, date_header); if (!conceal_server_identity) req_write(req, server_header); req_write(req, "Accept-Ranges: bytes" CRLF); print_ka_phrase(req); } void print_content_range(request * req) { req_write(req, "Content-Range: bytes "); req_write(req, simple_itoa(req->ranges->start)); req_write(req, "-"); req_write(req, simple_itoa(req->ranges->stop)); req_write(req, "/"); req_write(req, simple_itoa(req->filesize)); req_write(req, CRLF); } void print_partial_content_continue(request * req) { static char msg[] = CRLF "--THIS_STRING_SEPARATES" CRLF; if (req->numranges > 1) { req_write(req, msg); } print_content_type(req); print_content_range(req); } void print_partial_content_done(request * req) { static char msg[] = CRLF "--THIS_STRING_SEPARATES--" CRLF; req_write(req, msg); } /* The routines above are only called by the routines below. * The rest of Boa only enters through the routines below. */ int complete_response(request *req) { Range *r; /* we only want to push off the one range */ r = req->ranges; req->ranges = req->ranges->next; range_pool_push(r); /* successfully flushed */ if (req->response_status == R_PARTIAL_CONTENT && req->numranges > 1) { if (req->ranges != NULL) { print_partial_content_continue(req); req_write(req, CRLF); } else { print_partial_content_done(req); req->status = DONE; req_flush(req); } } else { req->status = DONE; return 0; } return 1; } /* R_CONTINUE: 100 */ void send_r_continue(request * req) { static char msg[] = " 100 Continue" CRLF CRLF; /* shouldn't need this */ if (req->http_version != HTTP11) return; req->response_status = R_CONTINUE; req_write(req, http_ver_string(req->http_version)); req_write(req, msg); } /* R_REQUEST_OK: 200 */ void send_r_request_ok(request * req) { req->response_status = R_REQUEST_OK; if (req->http_version == HTTP09) return; req_write(req, http_ver_string(req->http_version)); req_write(req, " 200 OK" CRLF); print_http_headers(req); if (!req->cgi_type) { print_content_length(req); print_last_modified(req); print_content_type(req); req_write(req, CRLF); } } /* R_NO_CONTENT: 204 */ void send_r_no_content(request * req) { static char msg[] = " 204 NO CONTENT" CRLF; req->response_status = R_NO_CONTENT; if (req->http_version == HTTP09) return; req_write(req, http_ver_string(req->http_version)); req_write(req, msg); print_http_headers(req); /* FIXME: Why is this here? */ if (!req->cgi_type) { req_write(req, CRLF); } } /* R_PARTIAL_CONTENT: 206 */ void send_r_partial_content(request * req) { static char msg[] = " 206 Partial Content" CRLF; static char msg2[] = "Content-Type: multipart/byteranges; " "boundary=THIS_STRING_SEPARATES" CRLF; req->response_status = R_PARTIAL_CONTENT; #if 0 if (req->http_version != HTTP11) { log_error("can't do partial content if not HTTP/1.1!!"); send_r_request_ok(req); return; } #endif req_write(req, http_ver_string(req->http_version)); req_write(req, msg); print_http_headers(req); print_last_modified(req); if (req->numranges > 1) { req_write(req, msg2); req_write(req, CRLF); } else { req_write(req, "Content-Length: "); req_write(req, simple_itoa(req->ranges->stop - req->ranges->start + 1)); req_write(req, CRLF); } print_partial_content_continue(req); req_write(req, CRLF); } /* R_MOVED_PERM: 301 */ void send_r_moved_perm(request * req, const char *url) { SQUASH_KA(req); req->response_status = R_MOVED_PERM; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 301 Moved Permanently" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF); req_write(req, "Location: "); req_write_escape_http(req, url); req_write(req, CRLF CRLF); } if (req->method != M_HEAD) { req_write(req, "301 Moved Permanently\n" "\n

301 Moved

The document has moved\n" "here.\n\n"); } req_flush(req); } /* R_MOVED_TEMP: 302 */ void send_r_moved_temp(request * req, const char *url, const char *more_hdr) { SQUASH_KA(req); req->response_status = R_MOVED_TEMP; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 302 Moved Temporarily" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF); req_write(req, "Location: "); req_write_escape_http(req, url); req_write(req, CRLF); req_write(req, more_hdr); req_write(req, CRLF CRLF); } if (req->method != M_HEAD) { req_write(req, "302 Moved Temporarily\n" "\n

302 Moved

The document has moved\n" "here.\n\n"); } req_flush(req); } /* R_NOT_MODIFIED: 304 */ void send_r_not_modified(request * req) { SQUASH_KA(req); req->response_status = R_NOT_MODIFIED; req_write(req, http_ver_string(req->http_version)); req_write(req, " 304 Not Modified" CRLF); print_http_headers(req); print_content_type(req); req_write(req, CRLF); req_flush(req); } /* R_BAD_REQUEST: 400 */ void send_r_bad_request(request * req) { SQUASH_KA(req); req->response_status = R_BAD_REQUEST; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 400 Bad Request" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) req_write(req, "400 Bad Request\n" "

400 Bad Request

\nYour client has issued " "a malformed or illegal request.\n\n"); req_flush(req); } /* R_UNAUTHORIZED: 401 */ void send_r_unauthorized(request * req, const char *realm_name) { SQUASH_KA(req); req->response_status = R_UNAUTHORIZED; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 401 Unauthorized" CRLF); print_http_headers(req); req_write(req, "WWW-Authenticate: Basic realm=\""); req_write(req, realm_name); req_write(req, CRLF); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, "401 Unauthorized\n" "

401 Unauthorized

\nYour client does not " "have permission to get URL "); req_write_escape_html(req, req->request_uri); req_write(req, " from this server.\n\n"); } req_flush(req); } /* R_FORBIDDEN: 403 */ void send_r_forbidden(request * req) { SQUASH_KA(req); req->response_status = R_FORBIDDEN; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 403 Forbidden" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, "403 Forbidden\n" "

403 Forbidden

\nYour client does not " "have permission to get URL "); req_write_escape_html(req, req->request_uri); req_write(req, " from this server.\n\n"); } req_flush(req); } /* R_NOT_FOUND: 404 */ void send_r_not_found(request * req) { SQUASH_KA(req); req->response_status = R_NOT_FOUND; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 404 Not Found" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, "404 Not Found\n" "

404 Not Found

\nThe requested URL "); req_write_escape_html(req, req->request_uri); req_write(req, " was not found on this server.\n\n"); } req_flush(req); } /* R_LENGTH_REQUIRED: 411 */ /* FIXME: incomplete */ void send_r_length_required(request * req) { SQUASH_KA(req); req->response_status = R_LENGTH_REQUIRED; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 411 Length Required" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF); print_last_modified(req); print_content_type(req); req_write(req, CRLF); } if (req->method != M_HEAD) { req_write(req, "411 Length Required\n" "

411 Length Required

\nThe requested URL "); req_write_escape_html(req, req->request_uri); req_write(req, " requires that a valid Content-Length header be " "sent with it.\n\n"); } req_flush(req); } /* R_PRECONDITION_FAILED: 412 */ void send_r_precondition_failed(request * req) { SQUASH_KA(req); req->response_status = R_PRECONDITION_FAILED; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 412 Precondition Failed" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, "412 Precondition Failed\n" "

412 Precondition Failed

\n\n"); } req_flush(req); } /* R_BAD_REQUEST_URI_TOO_LONG: 414 */ void send_r_request_uri_too_long(request * req) { char body[] = "414 Request URI Too Long\n" "

414 Request URI Too Long

\nYour client has issued " "a malformed or illegal request.\n\n"; static unsigned int len = 0; req->response_status = R_REQUEST_URI_TOO_LONG; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 414 Request URI Too Long" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF); req_write(req, "Content-Length: "); if (!len) len = strlen(body); req_write(req, simple_itoa(len)); req_write(req, CRLF CRLF); } if (req->method != M_HEAD) req_write(req, body); req_flush(req); } /* R_INVALID_RANGE: 416 */ void send_r_invalid_range(request * req) { static char body[] = "416 Invalid Range\n" "

416 Invalid Range

\n\n"; static unsigned int body_len = 0; SQUASH_KA(req); req->response_status = R_INVALID_RANGE; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 416 Invalid Range" CRLF); print_http_headers(req); if (!body_len) body_len = strlen(body); req_write(req, "Content-Length: "); req_write(req, simple_itoa(body_len)); req_write(req, CRLF "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, body); } req_flush(req); } /* R_ERROR: 500 */ void send_r_error(request * req) { SQUASH_KA(req); req->response_status = R_ERROR; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 500 Server Error" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, "500 Server Error\n" "

500 Server Error

\nThe server encountered " "an internal error and could not complete your request.\n" "\n"); } req_flush(req); } /* R_NOT_IMP: 501 */ void send_r_not_implemented(request * req) { SQUASH_KA(req); req->response_status = R_NOT_IMP; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 501 Not Implemented" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } /* we always write the body, because we don't *KNOW* * what the method is. */ req_write(req, "501 Not Implemented\n" "

501 Not Implemented

\nPOST to non-script " "is not supported in Boa.\n\n"); req_flush(req); } /* R_BAD_GATEWAY: 502 */ void send_r_bad_gateway(request * req) { SQUASH_KA(req); req->response_status = R_BAD_GATEWAY; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 502 Bad Gateway" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, "502 Bad Gateway\n" "

502 Bad Gateway

\nThe CGI was " "not CGI/1.1 compliant.\n" "\n"); } req_flush(req); } /* R_SERVICE_UNAVAILABLE: 503 */ void send_r_service_unavailable(request * req) { /* 503 */ static char body[] = "503 Service Unavailable\n" "

503 Service Unavailable

\n" "There are too many connections in use right now.\n" "Please try again later.\n" "\n"; static unsigned int _body_len; static char *body_len; if (!_body_len) _body_len = strlen(body); if (!body_len) body_len = strdup(simple_itoa(_body_len)); if (!body_len) { log_error_time(); perror("strdup of _body_len from simple_itoa"); } SQUASH_KA(req); req->response_status = R_SERVICE_UNAV; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 503 Service Unavailable" CRLF); print_http_headers(req); if (body_len) { req_write(req, "Content-Length: "); req_write(req, body_len); req_write(req, CRLF); } req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, body); } req_flush(req); } /* R_NOT_IMP: 505 */ void send_r_bad_version(request * req, const char *version) { SQUASH_KA(req); req->response_status = R_BAD_VERSION; if (req->http_version != HTTP09) { req_write(req, http_ver_string(req->http_version)); req_write(req, " 505 HTTP Version Not Supported" CRLF); print_http_headers(req); req_write(req, "Content-Type: " HTML CRLF CRLF); /* terminate header */ } if (req->method != M_HEAD) { req_write(req, "505 HTTP Version Not Supported\n" "

505 HTTP Version Not Supported

\nHTTP versions " "other than 0.9 and 1.0 " "are not supported in Boa.\n

Version encountered: "); req_write(req, version); req_write(req, "

\n"); } req_flush(req); } boa-0.94.14rc21/src/select.c0000644000175000001440000001773710206636621016204 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Some changes Copyright (C) 1996 Charles F. Randall * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1996-2003 Jon Nelson * * 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 1, 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. * */ /* $Id: select.c,v 1.1.2.17 2005/02/22 14:11:29 jnelson Exp $*/ /* algorithm: * handle any signals * if we still want to accept new connections, add the server to the * list. * if there are any blocked requests or the we are still accepting new * connections, determine appropriate timeout and select, then move * blocked requests back into the active list. * handle active connections * repeat */ #include "boa.h" static void fdset_update(void); fd_set block_read_fdset; fd_set block_write_fdset; int max_fd = 0; void loop(int server_s) { FD_ZERO(BOA_READ); FD_ZERO(BOA_WRITE); max_fd = -1; while (1) { /* handle signals here */ if (sighup_flag) sighup_run(); if (sigchld_flag) sigchld_run(); if (sigalrm_flag) sigalrm_run(); if (sigterm_flag) { /* sigterm_flag: * 1. caught, unprocessed. * 2. caught, stage 1 processed */ if (sigterm_flag == 1) { sigterm_stage1_run(); BOA_FD_CLR(req, server_s, BOA_READ); close(server_s); /* make sure the server isn't in the block list */ server_s = -1; } if (sigterm_flag == 2 && !request_ready && !request_block) { sigterm_stage2_run(); /* terminal */ } } else { if (total_connections > max_connections) { /* FIXME: for poll we don't subtract 20. why? */ BOA_FD_CLR(req, server_s, BOA_READ); } else { BOA_FD_SET(req, server_s, BOA_READ); /* server always set */ } } pending_requests = 0; /* max_fd is > 0 when something is blocked */ if (max_fd) { struct timeval req_timeout; /* timeval for select */ req_timeout.tv_sec = (request_ready ? 0 : default_timeout); req_timeout.tv_usec = 0l; /* reset timeout */ if (select(max_fd + 1, BOA_READ, BOA_WRITE, NULL, (request_ready || request_block ? &req_timeout : NULL)) == -1) { /* what is the appropriate thing to do here on EBADF */ if (errno == EINTR) continue; /* while(1) */ else if (errno != EBADF) { DIE("select"); } } /* FIXME: optimize for when select returns 0 (timeout). * Thus avoiding many operations in fdset_update * and others. */ if (!sigterm_flag && FD_ISSET(server_s, BOA_READ)) { pending_requests = 1; } time(¤t_time); /* for "new" requests if we've been in * select too long */ /* if we skip this section (for example, if max_fd == 0), * then we aren't listening anyway, so we can't accept * new conns. Don't worry about it. */ } /* reset max_fd */ max_fd = -1; if (request_block) { /* move selected req's from request_block to request_ready */ fdset_update(); } /* any blocked req's move from request_ready to request_block */ if (pending_requests || request_ready) { process_requests(server_s); } } } /* * Name: fdset_update * * Description: iterate through the blocked requests, checking whether * that file descriptor has been set by select. Update the fd_set to * reflect current status. * * Here, we need to do some things: * - keepalive timeouts simply close * (this is special:: a keepalive timeout is a timeout where keepalive is active but nothing has been read yet) * - regular timeouts close + error * - stuff in buffer and fd ready? write it out * - fd ready for other actions? do them */ static void fdset_update(void) { request *current, *next; time(¤t_time); for (current = request_block; current; current = next) { time_t time_since = current_time - current->time_last; next = current->next; /* hmm, what if we are in "the middle" of a request and not * just waiting for a new one... perhaps check to see if anything * has been read via header position, etc... */ if (current->kacount < ka_max && /* we *are* in a keepalive */ (time_since >= ka_timeout) && /* ka timeout */ !current->logline) { /* haven't read anything yet */ log_error_doc(current); fputs("connection timed out\n", stderr); current->status = TIMED_OUT; /* connection timed out */ } else if (time_since > REQUEST_TIMEOUT) { log_error_doc(current); fputs("connection timed out\n", stderr); current->status = TIMED_OUT; /* connection timed out */ } if (current->buffer_end && /* there is data to write */ current->status < DONE) { if (FD_ISSET(current->fd, BOA_WRITE)) ready_request(current); else { BOA_FD_SET(current, current->fd, BOA_WRITE); } } else { switch (current->status) { case IOSHUFFLE: #ifndef HAVE_SENDFILE if (current->buffer_end - current->buffer_start == 0) { if (FD_ISSET(current->data_fd, BOA_READ)) ready_request(current); break; } #endif case WRITE: case PIPE_WRITE: if (FD_ISSET(current->fd, BOA_WRITE)) ready_request(current); else { BOA_FD_SET(current, current->fd, BOA_WRITE); } break; case BODY_WRITE: if (FD_ISSET(current->post_data_fd, BOA_WRITE)) ready_request(current); else { BOA_FD_SET(current, current->post_data_fd, BOA_WRITE); } break; case PIPE_READ: if (FD_ISSET(current->data_fd, BOA_READ)) ready_request(current); else { BOA_FD_SET(current, current->data_fd, BOA_READ); } break; case DONE: if (FD_ISSET(current->fd, BOA_WRITE)) ready_request(current); else { BOA_FD_SET(current, current->fd, BOA_WRITE); } break; case TIMED_OUT: case DEAD: ready_request(current); break; default: if (FD_ISSET(current->fd, BOA_READ)) ready_request(current); else { BOA_FD_SET(current, current->fd, BOA_READ); } break; } } current = next; } } boa-0.94.14rc21/src/signals.c0000644000175000001440000001420410206636621016347 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1996-2005 Jon Nelson * Some changes Copyright (C) 1997 Alain Magloire * * 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 1, 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. * */ /* $Id: signals.c,v 1.37.2.14 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" #ifdef HAVE_SYS_WAIT_H #include /* wait */ #endif #include /* signal */ sigjmp_buf env; int handle_sigbus; void sigsegv(int); void sigbus(int); void sigterm(int); void sighup(int); void sigint(int); void sigchld(int); void sigalrm(int); /* * Name: init_signals * Description: Sets up signal handlers for all our friends. */ void init_signals(void) { struct sigaction sa; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGSEGV); sigaddset(&sa.sa_mask, SIGBUS); sigaddset(&sa.sa_mask, SIGTERM); sigaddset(&sa.sa_mask, SIGHUP); sigaddset(&sa.sa_mask, SIGINT); sigaddset(&sa.sa_mask, SIGPIPE); sigaddset(&sa.sa_mask, SIGCHLD); sigaddset(&sa.sa_mask, SIGALRM); sigaddset(&sa.sa_mask, SIGUSR1); sigaddset(&sa.sa_mask, SIGUSR2); sa.sa_handler = sigsegv; sigaction(SIGSEGV, &sa, NULL); sa.sa_handler = sigbus; sigaction(SIGBUS, &sa, NULL); sa.sa_handler = sigterm; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = sighup; sigaction(SIGHUP, &sa, NULL); sa.sa_handler = sigint; sigaction(SIGINT, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sigchld; sigaction(SIGCHLD, &sa, NULL); sa.sa_handler = sigalrm; sigaction(SIGALRM, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGUSR1, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGUSR2, &sa, NULL); } void reset_signals(void) { struct sigaction sa; sa.sa_flags = 0; sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGSEGV); sigaddset(&sa.sa_mask, SIGBUS); sigaddset(&sa.sa_mask, SIGTERM); sigaddset(&sa.sa_mask, SIGHUP); sigaddset(&sa.sa_mask, SIGINT); sigaddset(&sa.sa_mask, SIGPIPE); sigaddset(&sa.sa_mask, SIGCHLD); sigaddset(&sa.sa_mask, SIGALRM); sigaddset(&sa.sa_mask, SIGUSR1); sigaddset(&sa.sa_mask, SIGUSR2); sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); sigaction(SIGALRM, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); } void sigsegv(int dummy) { time(¤t_time); log_error_time(); fprintf(stderr, "caught SIGSEGV, dumping core in %s\n", tempdir); chdir(tempdir); abort(); } extern sigjmp_buf env; extern int handle_sigbus; void sigbus(int dummy) { if (handle_sigbus) { longjmp(env, dummy); } time(¤t_time); log_error_time(); fprintf(stderr, "caught SIGBUS, dumping core in %s\n", tempdir); chdir(tempdir); abort(); } void sigterm(int dummy) { if (!sigterm_flag) sigterm_flag = 1; } void sigterm_stage1_run(void) { /* lame duck mode */ time(¤t_time); log_error_time(); fputs("caught SIGTERM, starting shutdown\n", stderr); sigterm_flag = 2; } void sigterm_stage2_run(void) { /* lame duck mode */ log_error_time(); fprintf(stderr, "exiting Boa normally (uptime %d seconds)\n", (int) (current_time - start_time)); chdir(tempdir); clear_common_env(); dump_mime(); dump_passwd(); dump_alias(); free_requests(); range_pool_empty(); free(server_root); free(server_name); server_root = NULL; exit(EXIT_SUCCESS); } void sighup(int dummy) { sighup_flag = 1; } void sighup_run(void) { sighup_flag = 0; time(¤t_time); log_error_time(); fputs("caught SIGHUP, restarting\n", stderr); /* Philosophy change for 0.92: don't close and attempt reopen of logfiles, * since usual permission structure prevents such reopening. */ /* why ? */ /* FD_ZERO(&block_read_fdset); FD_ZERO(&block_write_fdset); */ /* clear_common_env(); NEVER DO THIS */ dump_mime(); dump_passwd(); dump_alias(); free_requests(); range_pool_empty(); log_error_time(); fputs("re-reading configuration files\n", stderr); read_config_files(); log_error_time(); fputs("successful restart\n", stderr); } void sigint(int dummy) { time(¤t_time); log_error_time(); fputs("caught SIGINT: shutting down\n", stderr); chdir(tempdir); exit(EXIT_FAILURE); } void sigchld(int dummy) { sigchld_flag = 1; } void sigchld_run(void) { int child_status; pid_t pid; sigchld_flag = 0; while ((pid = waitpid(-1, &child_status, WNOHANG)) > 0) if (verbose_cgi_logs) { time(¤t_time); log_error_time(); fprintf(stderr, "reaping child %d: status %d\n", (int) pid, child_status); } return; } void sigalrm(int dummy) { sigalrm_flag = 1; } void sigalrm_run(void) { time(¤t_time); log_error_time(); fprintf(stderr, "%ld requests, %ld errors\n", status.requests, status.errors); hash_show_stats(); sigalrm_flag = 0; } boa-0.94.14rc21/src/sublog.c0000644000175000001440000000744210206636621016210 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1999 Larry Doolittle * Copyright (C) 2000-2005 Jon Nelson * * 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 1, 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. * */ /* $Id: sublog.c,v 1.6.2.6 2005/02/22 14:11:29 jnelson Exp $*/ #include #include #include #include #include #include #include #include #include #include #include #include #include "compat.h" int open_pipe_fd(const char *command); int open_net_fd(const char *spec); int open_gen_fd(const char *spec); /* Like popen, but gives fd instead of FILE * */ int open_pipe_fd(const char *command) { int pipe_fds[2]; int pid; /* "man pipe" says "filedes[0] is for reading, * filedes[1] is for writing. */ if (pipe(pipe_fds) == -1) return -1; pid = fork(); if (pid == 0) { /* child */ close(pipe_fds[1]); if (pipe_fds[0] != 0) { dup2(pipe_fds[0], 0); close(pipe_fds[0]); } execl("/bin/sh", "sh", "-c", command, (char *) 0); exit(EXIT_FAILURE); } close(pipe_fds[0]); if (pid < 0) { close(pipe_fds[1]); return -1; } return pipe_fds[1]; } int open_net_fd(const char *spec) { char *p; int fd, port; struct sockaddr_in sa; struct hostent *he; p = strchr(spec, ':'); if (!p) return -1; *p++ = '\0'; port = strtol(p, NULL, 10); /* printf("Host %s, port %d\n",spec,port); */ sa.sin_family = PF_INET; sa.sin_port = htons(port); he = gethostbyname(spec); if (!he) { #ifdef HAVE_HERROR herror("open_net_fd"); #endif return -1; } memcpy(&sa.sin_addr, he->h_addr, he->h_length); /* printf("using ip %s\n",inet_ntoa(sa.sin_addr)); */ fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) return fd; if (connect(fd, (struct sockaddr *) &sa, sizeof (sa)) < 0) return -1; return fd; } int open_gen_fd(const char *spec) { int fd; if (*spec == '|') { fd = open_pipe_fd(spec + 1); } else if (*spec == ':') { fd = open_net_fd(spec + 1); } else { fd = open(spec, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP); } return fd; } #ifdef STANDALONE_TEST int main(int argc, char *argv[]) { char buff[1024]; int fd, nr, nw; if (argc < 2) { fprintf(stderr, "usage: %s output-filename\n" " %s |output-command\n" " %s :host:port\n", argv[0], argv[0], argv[0]); return 1; } fd = open_gen_fd(argv[1]); if (fd < 0) { perror("open_gen_fd"); exit(EXIT_FAILURE); } while ((nr = read(0, buff, sizeof (buff))) != 0) { if (nr < 0) { if (errno == EINTR) continue; perror("read"); exit(EXIT_FAILURE); } nw = write(fd, buff, nr); if (nw < 0) { perror("write"); exit(EXIT_FAILURE); } } return 0; } #endif boa-0.94.14rc21/src/timestamp.c0000644000175000001440000000226710206636621016720 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1998-2002 Jon Nelson * * 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 1, 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. * */ /* $Id: timestamp.c,v 1.9.2.1 2005/02/22 14:11:29 jnelson Exp $*/ #include "boa.h" void timestamp(void) { log_error_time(); fprintf(stderr, "boa: server version %s\n", SERVER_VERSION); log_error_time(); fprintf(stderr, "boa: server built " __DATE__ " at " __TIME__ ".\n"); log_error_time(); fprintf(stderr, "boa: starting server pid=%d, port %d\n", (int) getpid(), server_port); } boa-0.94.14rc21/src/util.c0000644000175000001440000004726410206636621015700 0ustar jnelsonusers00000000000000/* * Boa, an http server * Copyright (C) 1995 Paul Phillips * Some changes Copyright (C) 1996 Charles F. Randall * Copyright (C) 1996-1999 Larry Doolittle * Copyright (C) 1996-2005 Jon Nelson * * 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 1, 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. * */ /* $Id: util.c,v 1.61.2.22 2005/02/22 14:11:29 jnelson Exp $ */ #include "boa.h" static int date_to_tm(struct tm *file_gmt, const char *cmtime); /* Don't need or want the trailing nul for these character arrays */ static const char month_tab[48] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec "; static const char day_tab[28] = "Sun,Mon,Tue,Wed,Thu,Fri,Sat,"; /* * Name: clean_pathname * * Description: Replaces unsafe/incorrect instances of: * //[...] with / * /./ with / * /../ with / (technically not what we want, but browsers should deal * with this, not servers) */ void clean_pathname(char *pathname) { char *cleanpath, c; cleanpath = pathname; while ((c = *pathname++)) { if (c == '/') { while (1) { if (*pathname == '/') pathname++; else if (*pathname == '.' && *(pathname + 1) == '/') pathname += 2; else if (*pathname == '.' && *(pathname + 1) == '.' && *(pathname + 2) == '/') { pathname += 3; } else break; } c = '/'; } *cleanpath++ = c; } *cleanpath = '\0'; } #if 0 char *new_clean_pathname(char *pathname) { static char *segment[50]; int seg_count = 0; char *a, *cleanpath, c; a = pathname; segment[seg_count] = pathname; cleanpath = pathname; while ((c = *pathname++)) { if (c == '/') { /* /?? */ while (1) { /* everything in this loop gets eliminated */ if (*pathname == '/') /* // */ pathname++; else if (*pathname == '.') { /* /. */ if (*(pathname + 1) == '/') /* /./ */ pathname += 2; else if (*(pathname + 1) == '\0') /* /.$ */ pathname += 1; else if (*(pathname + 1) == '.') { /* /.. */ if (*(pathname + 2) == '/') /* /../ */ pathname += 3; else if (*(pathname + 1) == '\0') /* /..$ */ pathname += 2; /* cleanpath goes *back* one */ if (seg_count) cleanpath = segment[--seg_count]; else { *a = '\0'; return a; } } else { /* /.blah */ break; } } else { /* we have /something */ break; } } if (seg_count > 49) { /* we can store in spots 0...49 */ *a = '\0'; return a; } *cleanpath = '/'; segment[seg_count++] = cleanpath++; } else *cleanpath++ = c; } *cleanpath = '\0'; return a; } #endif /* * Name: get_commonlog_time * * Description: Returns the current time in common log format in a static * char buffer. * * commonlog time is exactly 25 characters long * because this is only used in logging, we add " [" before and "] " after * making 29 characters * "[27/Feb/1998:20:20:04 +0000] " * * Contrast with rfc822 time: * "Sun, 06 Nov 1994 08:49:37 GMT" * * Altered 10 Jan 2000 by Jon Nelson ala Drew Streib for non UTC logging * */ char *get_commonlog_time(void) { struct tm *t; char *p; unsigned int a; static char buf[30]; int time_offset; if (use_localtime) { t = localtime(¤t_time); time_offset = TIMEZONE_OFFSET(t); } else { t = gmtime(¤t_time); time_offset = 0; } p = buf + 29; *p-- = '\0'; *p-- = ' '; *p-- = ']'; a = abs(time_offset / 60); *p-- = '0' + a % 10; a /= 10; *p-- = '0' + a % 6; a /= 6; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = (time_offset >= 0) ? '+' : '-'; *p-- = ' '; a = t->tm_sec; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ':'; a = t->tm_min; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ':'; a = t->tm_hour; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ':'; a = 1900 + t->tm_year; while (a) { *p-- = '0' + a % 10; a /= 10; } /* p points to an unused spot */ *p-- = '/'; p -= 2; memcpy(p--, month_tab + 4 * (t->tm_mon), 3); *p-- = '/'; a = t->tm_mday; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p = '['; return p; /* should be same as returning buf */ } /* * Name: month2int * * Description: Turns a three letter month into a 0-11 int * * Note: This function is from wn-v1.07 -- it's clever and fast */ int month2int(const char *monthname) { switch (*monthname) { case 'A': return (*++monthname == 'p' ? 3 : 7); case 'D': return (11); case 'F': return (1); case 'J': if (*++monthname == 'a') return 0; return (*++monthname == 'n' ? 5 : 6); case 'M': return (*(monthname + 2) == 'r' ? 2 : 4); case 'N': return (10); case 'O': return (9); case 'S': return (8); default: return (-1); } } /* * Name: date_to_seconds * Description: * Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format 31 September 2000 23:59:59 GMT ; non-standard * RETURN VALUES: * -1 for error, 0 for success */ static int date_to_tm(struct tm *parsed_gmt, const char *cmtime) { char monthname[10 + 1]; const char *cmtime_start = cmtime; int day, year, hour, minute, second; /* we don't use the weekday portion, so skip over it */ while (*cmtime != ' ' && *cmtime != '\0') ++cmtime; if (*cmtime != ' ') return -1; /* the pre-space in the third scanf skips whitespace for the string */ if (sscanf(cmtime, "%d %3s %d %d:%d:%d GMT", /* RFC 1123 */ &day, monthname, &year, &hour, &minute, &second) == 6) { } else if (sscanf(cmtime, "%d-%3s-%d %d:%d:%d GMT", /* RFC 1036 */ &day, monthname, &year, &hour, &minute, &second) == 6) { } else if (sscanf(cmtime, "%3s %d %d:%d:%d %d", /* asctime() format */ monthname, &day, &hour, &minute, &second, &year) == 6) { /* * allow this non-standard date format: 31 September 2000 23:59:59 GMT * NOTE: Use 'cmtime_start' instead of 'cmtime' here, because the date *starts* * with the day, versus a throwaway item */ } else if (sscanf(cmtime_start, "%d %10s %d %d:%d:%d GMT", &day, monthname, &year, &hour, &minute, &second) == 6) { } else { log_error_time(); fprintf(stderr, "Error in %s, line %d: Unable to sscanf \"%s\"\n", __FILE__, __LINE__, cmtime); return -1; /* error */ } if (year < 70) year += 100; if (year > 1900) year -= 1900; parsed_gmt->tm_sec = second; parsed_gmt->tm_min = minute; parsed_gmt->tm_hour = hour; parsed_gmt->tm_mday = day; parsed_gmt->tm_mon = month2int(monthname); parsed_gmt->tm_year = year; parsed_gmt->tm_wday = 0; parsed_gmt->tm_yday = 0; parsed_gmt->tm_isdst = 0; if (parsed_gmt->tm_mon == -1) { log_error_time(); fprintf(stderr, "Invalid month name: \"%s\"\n", monthname); return -1; } /* adapted from Squid 2.5 */ if (parsed_gmt->tm_sec < 0 || parsed_gmt->tm_sec > 59) return -1; if (parsed_gmt->tm_min < 0 || parsed_gmt->tm_min > 59) return -1; if (parsed_gmt->tm_hour < 0 || parsed_gmt->tm_hour > 23) return -1; if (parsed_gmt->tm_mday < 1 || parsed_gmt->tm_mday > 31) return -1; if (parsed_gmt->tm_mon < 0 || parsed_gmt->tm_mon > 11) return -1; if (parsed_gmt->tm_year < 70 || parsed_gmt->tm_year > 120) return -1; return 0; } /* * Name: modified_since * Description: Decides whether a file's mtime is newer than the * If-Modified-Since header of a request. * * RETURN VALUES: * 0: File has not been modified since specified time. * >0: File has been (and value is the converted_time) * -1: Error! */ int modified_since(time_t * mtime, const char *if_modified_since) { struct tm *file_gmt; struct tm parsed_gmt; int comp; if (date_to_tm(&parsed_gmt, if_modified_since) != 0) { return -1; } file_gmt = gmtime(mtime); /* Go through from years to seconds -- if they are ever unequal, we know which one is newer and can return */ if ((comp = file_gmt->tm_year - parsed_gmt.tm_year)) return (comp > 0); if ((comp = file_gmt->tm_mon - parsed_gmt.tm_mon)) return (comp > 0); if ((comp = file_gmt->tm_mday - parsed_gmt.tm_mday)) return (comp > 0); if ((comp = file_gmt->tm_hour - parsed_gmt.tm_hour)) return (comp > 0); if ((comp = file_gmt->tm_min - parsed_gmt.tm_min)) return (comp > 0); if ((comp = file_gmt->tm_sec - parsed_gmt.tm_sec)) return (comp > 0); /* this person must really be into the latest/greatest */ return 0; } /* * Name: to_upper * * Description: Turns a string into all upper case (for HTTP_ header forming) * AND changes - into _ */ char *to_upper(char *str) { char *start = str; while (*str) { if (*str == '-') *str = '_'; else *str = toupper(*str); str++; } return start; } /* * Name: unescape_uri * * Description: Decodes a uri, changing %xx encodings with the actual * character. The query_string should already be gone. * * Return values: * 1: success * 0: illegal string */ int unescape_uri(char *uri, char **query_string) { char c, d; char *uri_old; uri_old = uri; while ((c = *uri_old)) { if (c == '%') { uri_old++; if ((c = *uri_old++) && (d = *uri_old++)) { *uri = HEX_TO_DECIMAL(c, d); if (*uri < 32 || *uri > 126) { /* control chars in URI */ *uri = '\0'; return 0; } } else { *uri = '\0'; return 0; } ++uri; } else if (c == '?') { /* query string */ if (query_string) *query_string = ++uri_old; /* stop here */ *uri = '\0'; return (1); } else if (c == '#') { /* fragment */ /* legal part of URL, but we do *not* care. * However, we still have to look for the query string */ if (query_string) { ++uri_old; while ((c = *uri_old)) { if (c == '?') { *query_string = ++uri_old; break; } ++uri_old; } } break; } else { *uri++ = c; uri_old++; } } *uri = '\0'; return 1; } /* rfc822 (1123) time is exactly 29 characters long * "Sun, 06 Nov 1994 08:49:37 GMT" */ void rfc822_time_buf(char *buf, time_t s) { struct tm *t; char *p; unsigned int a; if (!s) { t = gmtime(¤t_time); } else t = gmtime(&s); p = buf + 28; /* p points to the last char in the buf */ p -= 3; /* p points to where the ' ' will go */ memcpy(p--, " GMT", 4); a = t->tm_sec; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ':'; a = t->tm_min; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ':'; a = t->tm_hour; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ' '; a = 1900 + t->tm_year; while (a) { *p-- = '0' + a % 10; a /= 10; } /* p points to an unused spot to where the space will go */ p -= 3; /* p points to where the first char of the month will go */ memcpy(p--, month_tab + 4 * (t->tm_mon), 4); *p-- = ' '; a = t->tm_mday; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ' '; p -= 3; memcpy(p, day_tab + t->tm_wday * 4, 4); } char *simple_itoa(unsigned int i) { /* 21 digits plus null terminator, good for 64-bit or smaller ints * for bigger ints, use a bigger buffer! * * 4294967295 is, incidentally, MAX_UINT (on 32bit systems at this time) * and is 10 bytes long */ static char local[22]; char *p = &local[21]; *p = '\0'; do { *--p = '0' + i % 10; i /= 10; } while (i != 0); return p; } /* I don't "do" negative conversions * Therefore, -1 indicates error */ int boa_atoi(const char *s) { int retval; char *reconv; if (!isdigit(*s)) return -1; retval = atoi(s); if (retval < 0) return -1; reconv = simple_itoa((unsigned int) retval); if (memcmp(s, reconv, strlen(s)) != 0) { return -1; } return retval; } int create_temporary_file(short want_unlink, char *storage, unsigned int size) { static char boa_tempfile[MAX_PATH_LENGTH + 1]; int fd; snprintf(boa_tempfile, MAX_PATH_LENGTH, "%s/boa-temp.XXXXXX", tempdir); /* open temp file */ fd = mkstemp(boa_tempfile); if (fd == -1) { log_error_time(); perror("mkstemp"); return 0; } if (storage != NULL) { unsigned int len = strlen(boa_tempfile); if (len < size) { memcpy(storage, boa_tempfile, len + 1); } else { close(fd); fd = 0; log_error_time(); fprintf(stderr, "not enough memory for memcpy in storage\n"); want_unlink = 1; } } if (want_unlink) { if (unlink(boa_tempfile) == -1) { close(fd); fd = 0; log_error_time(); fprintf(stderr, "unlink temp file\n"); } } return (fd); } int real_set_block_fd(int fd) { int flags; flags = fcntl(fd, F_GETFL); if (flags == -1) return -1; flags &= ~NOBLOCK; flags = fcntl(fd, F_SETFL, flags); return flags; } int real_set_nonblock_fd(int fd) { int flags; flags = fcntl(fd, F_GETFL); if (flags == -1) return -1; flags |= NOBLOCK; flags = fcntl(fd, F_SETFL, flags); return flags; } /* Quoting from rfc1034: ::= | " " ::=