*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/timestamp.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1998 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                
           1 -> void timestamp(void)
                {
           1 ->     log_error_time();
           1 ->     fprintf(stderr, "boa: server version %s\n", SERVER_VERSION);
           1 ->     log_error_time();
           1 ->     fprintf(stderr, "boa: server built " __DATE__ " at " __TIME__ ".\n");
           1 ->     log_error_time();
           1 ->     fprintf(stderr, "boa: starting server pid=%d, port %d\n",
           1 ->             (int) getpid(), server_port);
                }


Top 10 Lines:

     Line      Count

       25          1

Execution Summary:

        8   Executable lines in this file
        8   Lines executed
   100.00   Percent of the file executed

        1   Total number of line executions
     0.12   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/escape.cyc:
                /*
                 *  Boa, an http server
                 *  escape.c
                 *  Copyright (C) 2001 Jon Nelson <jnelson@boa.org>
                 *  Based on escape.pl, Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Copyright (C) 2001 Larry Doolittle <ldoolitt@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $ */
                
                /*
                 unreserved = alnum | mark
                 alnum = "0".."9" | "A".."Z" | "a".."z"
                 mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
                 noescape = unreserved | ":" | "@" | "&" | "=" | "+" | "$" | "," | "/"
                 */
                
                #ifdef TEST
                #include <stdio.h>
                #include <stdlib.h>
                #else
                #include "boa.h"
                #endif
                
                #include "escape.h"
                
                unsigned long _needs_escape[(NEEDS_ESCAPE_BITS+NEEDS_ESCAPE_WORD_LENGTH-1)/NEEDS_ESCAPE_WORD_LENGTH] = { for i < ((NEEDS_ESCAPE_BITS+NEEDS_ESCAPE_WORD_LENGTH-1)/NEEDS_ESCAPE_WORD_LENGTH) : 0 };
                
           1 -> void build_needs_escape(void)
                {
                    unsigned int a, b;
           1 ->     const 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;
                
           1 ->     b = 1;
           1 ->     for (a=0; b!=0; a++) b=b<<1;
                    /* I found $a bit positions available in an unsigned long. */
           1 ->     if (a < NEEDS_ESCAPE_WORD_LENGTH) {
           1 ->         fprintf(stderr,
                                "NEEDS_ESCAPE_SHIFT configuration error -- "\
                                "%d should be <= log2(%d)\n",
                                NEEDS_ESCAPE_SHIFT, a);
           1 ->         exit(1);
                    } else if (a >= 2*NEEDS_ESCAPE_WORD_LENGTH) {
                        /* needs_escape_shift configuration suboptimal */
                    } else {
                        /* Ahh, just right! */;
                    }
                    // memset(_needs_escape, ~0, sizeof(_needs_escape));
           1 ->     for(i = 0; i < sizeof(special) - 1; ++i) {
           1 ->         j=special[i];
           1 ->         if (j>=NEEDS_ESCAPE_BITS) {
                            /* warning: character $j will be needlessly escaped. */
                        } else {
           1 ->             _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
                


Top 10 Lines:

     Line      Count

       44          1

Execution Summary:

       11   Executable lines in this file
       11   Lines executed
   100.00   Percent of the file executed

        1   Total number of line executions
     0.09   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/queue.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1997 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba 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
                 */
                
          40 -> void block_request(request *`H req)
                {
          40 ->     dequeue(&request_ready, req);
          40 ->     enqueue(&request_block, req);
                
          40 ->     if (req->buffer_end) {
          40 ->         BOA_FD_SET(req->fd, &block_write_fdset);
                    } else {
          40 ->         switch (req->status) {
                        case WRITE:
                        case PIPE_WRITE:
                        case DONE:
          40 ->             BOA_FD_SET(req->fd, &block_write_fdset);
          40 ->             break;
                        case PIPE_READ:
          40 ->             BOA_FD_SET(req->data_fd, &block_read_fdset);
          40 ->             break;
                        case BODY_WRITE:
          40 ->             BOA_FD_SET(req->post_data_fd, &block_write_fdset);
          40 ->             break;
                        default:
          40 ->             BOA_FD_SET(req->fd, &block_read_fdset);
          40 ->             break;
                        }
                    }
                }
                
                /*
                 * Name: ready_request
                 *
                 * Description: Moves a request from the blocked queue to the ready queue
                 */
                
         300 -> void ready_request(request *`H req)
                {
         300 ->     dequeue(&request_block, req);
         300 ->     enqueue(&request_ready, req);
                
         300 ->     if (req->buffer_end) {
         300 ->         FD_CLR(req->fd, &block_write_fdset);
                    } else {
         300 ->         switch (req->status) {
                        case WRITE:
                        case PIPE_WRITE:
                        case DONE:
         300 ->             FD_CLR(req->fd, &block_write_fdset);
         300 ->             break;
                        case PIPE_READ:
         300 ->             FD_CLR(req->data_fd, &block_read_fdset);
         300 ->             break;
                        case BODY_WRITE:
         300 ->             FD_CLR(req->post_data_fd, &block_write_fdset);
         300 ->             break;
                        default:
         300 ->             FD_CLR(req->fd, &block_read_fdset);
                        }
                    }
                }
                
                
                /*
                 * Name: dequeue
                 *
                 * Description: Removes a request from its current queue
                 */
                
         898 -> void dequeue(request ** head, request * req)
                {
         898 ->     if (*head == req)
         898 ->         *head = req->next;
                
         898 ->     if (req->prev)
         898 ->         req->prev->next = req->next;
         898 ->     if (req->next)
         898 ->         req->next->prev = req->prev;
                
         898 ->     req->next = NULL;
         898 ->     req->prev = NULL;
                }
                
                /*
                 * Name: enqueue
                 *
                 * Description: Adds a request to the head of a queue
                 */
                
         900 -> void enqueue(request *`H* head, request *`H req)
                {
         900 ->     if (*head)
         900 ->         (*head)->prev = req;    /* previous head's prev is us */
                
         900 ->     req->next = *head;          /* our next is previous head */
         900 ->     req->prev = NULL;           /* first in list */
                
         900 ->     *head = req;                /* now we are head */
                }


Top 10 Lines:

     Line      Count

      122        900
      102        898
       69        300
       36         40

Execution Summary:

       42   Executable lines in this file
       42   Lines executed
   100.00   Percent of the file executed

     2138   Total number of line executions
    50.90   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/cycport.cyc:
                #include <string.h>
                
                using Core; // for Invalid_argument
                
        7710 -> int my_memcmp(const char ? @nozeroterm s1, const char ? @nozeroterm s2, size_t n)
                {
        7710 ->   if (s1 == NULL || s2 == NULL)
        7710 ->     throw new Invalid_argument("memcmp");
                  else {
        7710 ->     if (numelts(s1) < n || numelts(s2) < n) {
        7710 ->       if (numelts(s1) == numelts(s2))
        7710 ->         return memcmp(s1, s2, numelts(s1));
                      else {
        7710 ->         int minlen = ((numelts(s1) > numelts(s2)) ? numelts(s2) : numelts(s1));
        7710 ->         int retval = memcmp(s1, s2, minlen);
        7710 ->         if (retval != 0)
        7710 ->           return retval;
                        else
        7710 ->           throw new Invalid_argument("memcmp");
                      }
                    }
                    else
        7710 ->         return memcmp(s1, s2, n);
                  }
                }


Top 10 Lines:

     Line      Count

        5       7710

Execution Summary:

       12   Executable lines in this file
       12   Lines executed
   100.00   Percent of the file executed

     7710   Total number of line executions
   642.50   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/ip.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1999 Larry Doolittle <ldoolitt@boa.org>
                 *
                 *  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 bsed on contributions from Martin Hinner <martin@tdp.cz>
                  and Arkadiusz Miskiewicz <misiek@misiek.eu.org>.  This incarnation of that
                  code is untested.  The original IPv4 code is based on original Boa code
                  from Paul Phillips <paulp@go2net.com>.
                
                  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[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 <arpa/inet.h>          /* 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.  */
           1 -> int bind_server(int server_s, char *server_ip)
                {
                #ifdef INET6
                    struct sockaddr_in6 server_sockaddr;
                    server_sockaddr.sin6_family = AF_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
           1 ->     server_sockaddr.sin_family = AF_INET;
           1 ->     if (server_ip != NULL) {
           1 ->         inet_aton(server_ip, &server_sockaddr.sin_addr);
                    } else {
           1 ->         server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
                    }
           1 ->     server_sockaddr.sin_port = htons(server_port);
                #endif
                
           1 ->     return bind(server_s, &server_sockaddr,
                                sizeof (server_sockaddr));
                }
                
          40 -> char *`r ascii_sockaddr(struct SOCKADDR *s, char ?`r dest, 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
                    if ((s->__ss_family == AF_INET6) &&
                        IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
                        memmove(dest, dest+7, NI_MAXHOST);
                    }
                #endif
                #else
          40 ->     memmove(dest, inet_ntoa(s->sin_addr), numelts(inet_ntoa(s->sin_addr)));
                #endif
          40 ->     return dest;
                }
                
          20 -> int net_port(struct SOCKADDR *s)
                {
          20 ->     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
          20 ->     p = ntohs(s->sin_port);
                #endif
          20 ->     return p;
                }


Top 10 Lines:

     Line      Count

       76         40
       97         20
       50          1

Execution Summary:

       14   Executable lines in this file
       14   Lines executed
   100.00   Percent of the file executed

       61   Total number of line executions
     4.36   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/alias.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996 Russ Nelson <nelson@crynwr.com>
                 *  Some changes Copyright (C) 1996-2002 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $ */
                
                #include "boa.h"
                
                static uri_alias *alias_hashtable[ALIAS_HASHTABLE_SIZE];
                
                int get_alias_hash_value(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')
                 */
                
         270 -> int get_alias_hash_value(char *file)
                {
         270 ->     unsigned int hash = 0;
         270 ->     unsigned int index = 0;
                    unsigned char c;
                
         270 ->     hash = file[index++];
         270 ->     while ((c = file[index++]) && c != '/')
         270 ->         hash += (unsigned int) c;
                
         270 ->     return hash % ALIAS_HASHTABLE_SIZE;
                }
                
                /*
                 * Name: add_alias
                 *
                 * Description: add an Alias, Redirect, or ScriptAlias to the
                 * alias hash table.
                 */
                
       ##### -> void add_alias(char *fakename, char *realname, int type)
                {
                    int hash;
                    uri_alias *old_alias, *new_alias;
                    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);
                
       ##### ->     old_alias = alias_hashtable[hash];
                
       ##### ->     if (old_alias) {
       ##### ->         while (old_alias->next) {
       ##### ->             if (!strcmp(fakename, old_alias->fakename)) /* don't add twice */
       ##### ->                 return;
       ##### ->             old_alias = old_alias->next;
                        }
                    }
                
       ##### ->     new_alias = (uri_alias *) malloc(sizeof (uri_alias)); new_alias->fakename = NULL; new_alias->realname = NULL; new_alias->next = NULL;
       ##### ->     if (!new_alias) {
       ##### ->         DIE("out of memory adding alias to hash");
                    }
                
       ##### ->     if (old_alias)
       ##### ->         old_alias->next = new_alias;
                    else
       ##### ->         alias_hashtable[hash] = new_alias;
                
       ##### ->     new_alias->fakename = strdup(fakename);
       ##### ->     if (!new_alias->fakename) {
       ##### ->         DIE("failed strdup");
                    }
       ##### ->     new_alias->fake_len = fakelen;
                    /* check for "here" */
       ##### ->     if (realname[0] == '.' && realname[1] == '/') {
       ##### ->         new_alias->realname = normalize_path(realname+2);
       ##### ->         if (!new_alias->realname) {
                            /* superfluous - normalize_path checks for NULL return values. */
       ##### ->             DIE("normalize_path returned NULL");
                        }
       ##### ->         reallen = strlen(new_alias->realname);
                    } else {
       ##### ->         new_alias->realname = strdup(realname);
       ##### ->         if (!new_alias->realname) {
       ##### ->             DIE("strdup of realname failed");
                        }
                    }
       ##### ->     new_alias->real_len = reallen;
                
       ##### ->     new_alias->type = type;
       ##### ->     new_alias->next = NULL;
                }
                
                /*
                 * Name: find_alias
                 *
                 * Description: Locates uri in the alias hashtable if it exists.
                 *
                 * Returns:
                 *
                 * alias structure or NULL if not found
                 */
                
         270 -> uri_alias *find_alias(char *uri, int urilen)
                {
                    uri_alias *current;
                    int hash;
                
                    /* Find ScriptAlias, Alias, or Redirect */
                
         270 ->     if (urilen == 0)
         270 ->         urilen = strlen(uri);
         270 ->     hash = get_alias_hash_value(uri);
                
         270 ->     current = alias_hashtable[hash];
         270 ->     while (current) {
                #ifdef FASCIST_LOGGING
                        fprintf(stderr,
                                "%s:%d - comparing \"%s\" (request) to \"%s\" (alias): ",
                                __FILE__, __LINE__, uri, current->fakename);
                #endif
                        /* 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 '/'
                         */
         270 ->         if (current->fake_len <= urilen &&
         270 ->             !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] == '/')))) {
                #ifdef FASCIST_LOGGING
                                fprintf(stderr, "Got it!\n");
                #endif
         270 ->                 return current;
                        }
                #ifdef FASCIST_LOGGING
                        else
                            fprintf(stderr, "Don't Got it!\n");
                #endif
         270 ->         current = current->next;
                    }
         270 ->     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
                 */
                
         270 -> int translate_uri(request * req)
                {
                    static char buffer[MAX_HEADER_LENGTH + 1] @zeroterm;
         270 ->     char *req_urip;
                    uri_alias *current;
                    char ?@nozeroterm p;
                    int uri_len;
                
         270 ->     req_urip = req->request_uri;
         270 ->     if (req_urip[0] != '/') {
         270 ->         send_r_bad_request(req);
         270 ->         return 0;
                    }
                
         270 ->     uri_len = strlen(req->request_uri);
                
         270 ->     current = find_alias(req->request_uri, uri_len);
         270 ->     if (current) {
                
         270 ->         if (current->type == SCRIPTALIAS) /* Script */
         270 ->             return init_script_alias(req, current, uri_len);
                
                        /* not a script alias, therefore begin filling in data */
                
                        {
                            int len;
         270 ->             len = current->real_len;
         270 ->             len += uri_len - current->fake_len;
         270 ->             if (len > MAX_HEADER_LENGTH) {
         270 ->                 log_error_doc(req);
         270 ->                 fputs("uri too long!\n", stderr);
         270 ->                 send_r_bad_request(req);
         270 ->                 return 0;
                            }
         270 ->             memcpy(buffer, current->realname, current->real_len);
         270 ->             memcpy(buffer + current->real_len,
                                   req->request_uri + current->fake_len,
                                   uri_len - current->fake_len + 1);
                        }
                
         270 ->         if (current->type == REDIRECT) { /* Redirect */
         270 ->             if (req->method == M_POST) { /* POST to non-script */
                                /* it's not a cgi, but we try to POST??? */
         270 ->                 send_r_bad_request(req);
         270 ->                 return 0;       /* not a script alias, therefore begin filling in data */
                            }
         270 ->             send_r_moved_temp(req, buffer, "");
         270 ->             return 0;
                        } else {                /* Alias */
         270 ->             req->pathname = strdup(buffer);
         270 ->             if (!req->pathname) {
         270 ->                 send_r_error(req);
         270 ->                 WARN("unable to strdup buffer onto req->pathname");
         270 ->                 return 0;
                            }
         270 ->             return 1;
                        }
                    }
                
                    /*
                       The reason why this is *not* an 'else if' is that,
                       after aliasing, we still have to check for '~' expansion
                     */
                
         270 ->     if (user_dir && req->request_uri[1] == '~') {
                        char *user_homedir;
                
         270 ->         req_urip = req->request_uri + 2;
                
                        /* since we have uri_len which is from strlen(req->request_uri) */
         270 ->         p = mmemchr(req_urip, '/', uri_len - 2);
         270 ->         if (p)
         270 ->             *p = '\0';
                
         270 ->         user_homedir = get_home_dir(req_urip);
         270 ->         if (p)                  /* have to restore request_uri in case of error */
         270 ->             *p = '/';
                
         270 ->         if (!user_homedir) {    /*no such user */
         270 ->             send_r_not_found(req);
         270 ->             return 0;
                        }
                        {
         270 ->             int l1 = strlen(user_homedir);
         270 ->             int l2 = strlen(user_dir);
         270 ->             int l3 = (p ? strlen(p) : 0);
                
         270 ->             if (l1 + l2 + l3 + 1 > MAX_HEADER_LENGTH) {
         270 ->                 log_error_doc(req);
         270 ->                 fputs("uri too long!\n", stderr);
         270 ->                 send_r_bad_request(req);
         270 ->                 return 0;
                            }
                
         270 ->             memcpy(buffer, user_homedir, l1);
         270 ->             buffer[l1] = '/';
         270 ->             memcpy(buffer + l1 + 1, user_dir, l2 + 1);
         270 ->             if (p)
         270 ->                 memcpy(buffer + l1 + 1 + l2, p, l3 + 1);
                        }
         270 ->     } else if (document_root) {
                        /* no aliasing, no userdir... */
                        int l1, l2, l3;
                
         270 ->         l1 = strlen(document_root);
         270 ->         l2 = strlen(req->request_uri);
         270 ->         if (virtualhost)
         270 ->             l3 = strlen(req->local_ip_addr);
                        else
         270 ->             l3 = 0;
                
         270 ->         if (l1 + l2 + l3 + 1 > MAX_HEADER_LENGTH) {
         270 ->             log_error_doc(req);
         270 ->             fputs("uri too long!\n", stderr);
         270 ->             send_r_bad_request(req);
         270 ->             return 0;
                        }
                
                        /* the 'l2 + 1' is there so we copy the '\0' as well */
         270 ->         memcpy(buffer, document_root, l1);
         270 ->         if (virtualhost) {
         270 ->             buffer[l1] = '/';
         270 ->             memcpy(buffer + l1 + 1, req->local_ip_addr, l3);
         270 ->             memcpy(buffer + l1 + 1 + l3, req->request_uri, l2 + 1);
                        } else
         270 ->             memcpy(buffer + l1, req->request_uri, l2 + 1);
                    } else {
                        /* not aliased.  not userdir.  not part of document_root.  BAIL */
         270 ->         send_r_not_found(req);
         270 ->         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)
                     */
                
         270 ->     req->pathname = strdup(buffer);
         270 ->     if (!req->pathname) {
         270 ->         WARN("Could not strdup buffer for req->pathname!");
         270 ->         send_r_error(req);
         270 ->         return 0;
                    }
                
                    /* below we support cgis outside of a ScriptAlias */
         270 ->     if (strcmp(CGI_MIME_TYPE, get_mime_type(buffer)) == 0) { /* cgi */
                #ifdef FASCIST_LOGGING
                        log_error_time();
                        fprintf(stderr, "%s:%d - buffer is: \"%s\"\n",
                                __FILE__, __LINE__, buffer);
                #endif
                        /* FIXME */
                        /* script_name could end up as /cgi-bin/bob/extra_path */
         270 ->         req->script_name = strdup(req->request_uri);
         270 ->         if (!req->script_name) {
         270 ->             WARN("Could not strdup req->request_uri for req->script_name");
         270 ->             send_r_error(req);
         270 ->             return 0;
                        }
         270 ->         if (req->simple)
         270 ->             req->is_cgi = NPH;
                        else
         270 ->             req->is_cgi = CGI;
         270 ->         return 1;
         270 ->     } else if (req->method == M_POST) { /* POST to non-script */
                        /* it's not a cgi, but we try to POST??? */
         270 ->         send_r_bad_request(req);
         270 ->         return 0;
                    } else                      /* we are done!! */
         270 ->         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
                 */
                
       ##### -> int init_script_alias(request * req, uri_alias * current1, int uri_len)
                {
                    static char pathname[MAX_HEADER_LENGTH + 1] @zeroterm;
       ##### ->     struct stat statbuf;
                    static char buffer[MAX_HEADER_LENGTH + 1] @zeroterm;
                
       ##### ->     int index = 0;
                    char c;
                    int err;
                
                    /* copies the "real" path + the non-alias portion of the
                       uri to pathname.
                     */
                
       ##### ->     if (uri_len - current1->fake_len + current1->real_len >
                        MAX_HEADER_LENGTH) {
       ##### ->         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->simple) req->is_cgi = NPH;
                    else
       ##### ->         req->is_cgi = CGI;
                
                
                    /* start at the beginning of the actual uri...
                     (in /cgi-bin/bob, start at the 'b' in bob */
       ##### ->     index = current1->real_len;
                
                    /* 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[++index];
       ##### ->         if (c == '/') {
       ##### ->             pathname[index] = '\0';
       ##### ->             err = stat(pathname, &statbuf);
       ##### ->             pathname[index] = '/';
       ##### ->             if (err == -1) {
       ##### ->                 send_r_not_found(req);
       ##### ->                 return 0;
                            }
                
                            /* is it a dir? */
       ##### ->             if (!S_ISDIR(statbuf.st_mode)) {
                                /* check access */
       ##### ->                 if (!(statbuf.st_mode &
                                      (S_IFREG | /* regular file */
                                       (S_IRUSR | S_IXUSR) |    /* u+rx */
                                       (S_IRGRP | S_IXGRP) |    /* g+rx */
                                       (S_IROTH | S_IXOTH)))) { /* o+rx */
       ##### ->                     send_r_forbidden(req);
       ##### ->                     return 0;
                                }
                                /* stop here */
       ##### ->                 break;
                            }
                        }
                    } while (c != '\0');
                
       ##### ->     req->script_name = strdup(req->request_uri);
       ##### ->     if (!req->script_name) {
       ##### ->         send_r_error(req);
       ##### ->         WARN("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 */
       ##### ->             if (!(statbuf.st_mode &
                                  (S_IFREG | /* regular file */
                                   (S_IRUSR | S_IXUSR) |    /* u+rx */
                                   (S_IRGRP | S_IXGRP) |    /* g+rx */
                                   (S_IROTH | S_IXOTH)))) { /* o+rx */
       ##### ->                 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 == '/') {
                        int hash;
                        uri_alias *current;
                        int path_len;
                
       ##### ->         req->path_info = strdup(pathname + index);
       ##### ->         if (!req->path_info) {
       ##### ->             send_r_error(req);
       ##### ->             WARN("unable to strdup pathname + index for req->path_info");
       ##### ->             return 0;
                        }
       ##### ->         pathname[index] = '\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)) {
                
       ##### ->                 if (current->real_len +
                                    path_len - current->fake_len > MAX_HEADER_LENGTH) {
       ##### ->                     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]);
       ##### ->                 req->path_translated = strdup(buffer);
       ##### ->                 if (!req->path_translated) {
       ##### ->                     send_r_error(req);
       ##### ->                     WARN("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 = mstrchr(pathname + index + 1, '/');
       ##### ->             if (p)
       ##### ->                 *p = '\0';
                
       ##### ->             user_homedir = get_home_dir(pathname + index + 2);
       ##### ->             if (p)
       ##### ->                 *p = '/';
                
       ##### ->             if (!user_homedir) { /* no such user */
       ##### ->                 send_r_not_found(req);
       ##### ->                 return 0;
                            }
                            {
       ##### ->                 int l1 = strlen(user_homedir);
       ##### ->                 int l2 = strlen(user_dir);
                                int l3;
       ##### ->                 if (p)
       ##### ->                     l3 = strlen(p);
                                else
       ##### ->                     l3 = 0;
                
       ##### ->                 req->path_translated = malloc(l1 + l2 + l3 + 2);
       ##### ->                 if (req->path_translated == NULL) {
       ##### ->                     send_r_error(req);
       ##### ->                     WARN("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);
       ##### ->                 if (p)
       ##### ->                     memcpy(req->path_translated + l1 + 1 + l2, p, l3 + 1);
                            }
                        }
       ##### ->         if (!req->path_translated && document_root) {
                            /* no userdir, no aliasing... try document root */
                            int l1, l2;
       ##### ->             l1 = strlen(document_root);
       ##### ->             l2 = path_len;
                
       ##### ->             req->path_translated = malloc(l1 + l2 + 1);
       ##### ->             if (req->path_translated == NULL) {
       ##### ->                 send_r_error(req);
       ##### ->                 WARN("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) {
       ##### ->         send_r_error(req);
       ##### ->         WARN("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;
                    uri_alias *temp;
                
       ##### ->     for (i = 0; i < ALIAS_HASHTABLE_SIZE; ++i) { /* these limits OK? */
       ##### ->         if (alias_hashtable[i]) {
       ##### ->             temp = alias_hashtable[i];
       ##### ->             while (temp) {
                                uri_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;
                        }
                    }
                }


Top 10 Lines:

     Line      Count

       40        270
      134        270
      199        270

Execution Summary:

      271   Executable lines in this file
      271   Lines executed
   100.00   Percent of the file executed

      810   Total number of line executions
     2.99   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/response.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996-99 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                
                #define HTML "text/html; charset=ISO-8859-1"
                #define CRLF "\r\n"
                
         260 -> void print_content_type(request * req)
                {
         260 ->     req_write(req, "Content-Type: ");
         260 ->     req_write(req, get_mime_type(req->request_uri));
         260 ->     req_write(req, "\r\n");
                }
                
         260 -> void print_content_length(request * req)
                {
         260 ->     req_write(req, "Content-Length: ");
         260 ->     req_write(req, simple_itoa(req->filesize));
         260 ->     req_write(req, "\r\n");
                }
                
         260 -> void print_last_modified(request * req)
                {
                    static char lm[]@zeroterm = "Last-Modified: "
                        "                             " "\r\n";
         260 ->     rfc822_time_buf(lm + 15, req->last_modified);
         260 ->     req_write(req, lm);
                }
                
         270 -> void print_ka_phrase(request * req)
                {
         270 ->     if (req->kacount > 0 &&
                        req->keepalive == KA_ACTIVE && req->response_status < 500) {
         270 ->         req_write(req, "Connection: Keep-Alive\r\nKeep-Alive: timeout=");
         270 ->         req_write(req, simple_itoa(ka_timeout));
         270 ->         req_write(req, ", max=");
         270 ->         req_write(req, simple_itoa(req->kacount));
         270 ->         req_write(req, "\r\n");
                    } else
         270 ->         req_write(req, "Connection: close\r\n");
                }
                
         270 -> void print_http_headers(request * req)
                {
                    static char stuff[]@zeroterm = "Date: "
                        "                             "
                        "\r\nServer: " SERVER_VERSION "\r\n";
                
         270 ->     rfc822_time_buf(stuff + 6, 0);
         270 ->     req_write(req, stuff);
         270 ->     print_ka_phrase(req);
                }
                
                /* The routines above are only called by the routines below.
                 * The rest of Boa only enters through the routines below.
                 */
                
                /* R_REQUEST_OK: 200 */
         260 -> void send_r_request_ok(request * req)
                {
         260 ->     req->response_status = R_REQUEST_OK;
         260 ->     if (req->simple)
         260 ->         return;
                
         260 ->     req_write(req, "HTTP/1.0 200 OK\r\n");
         260 ->     print_http_headers(req);
                
         260 ->     if (!req->is_cgi) {
         260 ->         print_content_length(req);
         260 ->         print_last_modified(req);
         260 ->         print_content_type(req);
         260 ->         req_write(req, "\r\n");
                    }
                }
                
                /* R_MOVED_PERM: 301 */
       ##### -> void send_r_moved_perm(request * req, char *url)
                {
       ##### ->     SQUASH_KA(req);
       ##### ->     req->response_status = R_MOVED_PERM;
       ##### ->     if (!req->simple) {
       ##### ->         req_write(req, "HTTP/1.0 301 Moved Permanently\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n");
                
       ##### ->         req_write(req, "Location: ");
       ##### ->         req_write_escape_http(req, url);
       ##### ->         req_write(req, "\r\n\r\n");
                    }
       ##### ->     if (req->method != M_HEAD) {
       ##### ->         req_write(req,
                                  "<HTML><HEAD><TITLE>301 Moved Permanently</TITLE></HEAD>\n"
                                  "<BODY>\n<H1>301 Moved</H1>The document has moved\n"
                                  "<A HREF=\"");
       ##### ->         req_write_escape_html(req, url);
       ##### ->         req_write(req, "\">here</A>.\n</BODY></HTML>\n");
                    }
       ##### ->     req_flush(req);
                }
                
                /* R_MOVED_TEMP: 302 */
       ##### -> void send_r_moved_temp(request * req, char *url, const char *more_hdr)
                {
       ##### ->     SQUASH_KA(req);
       ##### ->     req->response_status = R_MOVED_TEMP;
       ##### ->     if (!req->simple) {
       ##### ->         req_write(req, "HTTP/1.0 302 Moved Temporarily\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n");
                
       ##### ->         req_write(req, "Location: ");
       ##### ->         req_write_escape_http(req, url);
       ##### ->         req_write(req, "\r\n");
       ##### ->         req_write(req, more_hdr);
       ##### ->         req_write(req, "\r\n\r\n");
                    }
       ##### ->     if (req->method != M_HEAD) {
       ##### ->         req_write(req,
                                  "<HTML><HEAD><TITLE>302 Moved Temporarily</TITLE></HEAD>\n"
                                  "<BODY>\n<H1>302 Moved</H1>The document has moved\n"
                                  "<A HREF=\"");
       ##### ->         req_write_escape_html(req, url);
       ##### ->         req_write(req, "\">here</A>.\n</BODY></HTML>\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/1.0 304 Not Modified\r\n");
       ##### ->     print_http_headers(req);
       ##### ->     print_content_type(req);
       ##### ->     req_write(req, "\r\n");
       ##### ->     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->simple) {
       ##### ->         req_write(req, "HTTP/1.0 400 Bad Request\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* terminate header */
                    }
       ##### ->     if (req->method != M_HEAD)
       ##### ->         req_write(req,
                                  "<HTML><HEAD><TITLE>400 Bad Request</TITLE></HEAD>\n"
                                  "<BODY><H1>400 Bad Request</H1>\nYour client has issued "
                                  "a malformed or illegal request.\n</BODY></HTML>\n");
       ##### ->     req_flush(req);
                }
                
                /* R_UNAUTHORIZED: 401 */
       ##### -> void send_r_unauthorized(request * req, char *realm_name)
                {
       ##### ->     SQUASH_KA(req);
       ##### ->     req->response_status = R_UNAUTHORIZED;
       ##### ->     if (!req->simple) {
       ##### ->         req_write(req, "HTTP/1.0 401 Unauthorized\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "WWW-Authenticate: Basic realm=\"");
       ##### ->         req_write(req, realm_name);
       ##### ->         req_write(req, "\"\r\n");
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* terminate header */
                    }
       ##### ->     if (req->method != M_HEAD) {
       ##### ->         req_write(req,
                                  "<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\n"
                                  "<BODY><H1>401 Unauthorized</H1>\nYour client does not "
                                  "have permission to get URL ");
       ##### ->         req_write_escape_html(req, req->request_uri);
       ##### ->         req_write(req, " from this server.\n</BODY></HTML>\n");
                    }
       ##### ->     req_flush(req);
                }
                
                /* R_FORBIDDEN: 403 */
       ##### -> void send_r_forbidden(request * req)
                {
       ##### ->     SQUASH_KA(req);
       ##### ->     req->response_status = R_FORBIDDEN;
       ##### ->     if (!req->simple) {
       ##### ->         req_write(req, "HTTP/1.0 403 Forbidden\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* terminate header */
                    }
       ##### ->     if (req->method != M_HEAD) {
       ##### ->         req_write(req, "<HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD>\n"
                                  "<BODY><H1>403 Forbidden</H1>\nYour client does not "
                                  "have permission to get URL ");
       ##### ->         req_write_escape_html(req, req->request_uri);
       ##### ->         req_write(req, " from this server.\n</BODY></HTML>\n");
                    }
       ##### ->     req_flush(req);
                }
                
                /* R_NOT_FOUND: 404 */
          10 -> void send_r_not_found(request * req)
                {
          10 ->     SQUASH_KA(req);
          10 ->     req->response_status = R_NOT_FOUND;
          10 ->     if (!req->simple) {
          10 ->         req_write(req, "HTTP/1.0 404 Not Found\r\n");
          10 ->         print_http_headers(req);
          10 ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* terminate header */
                    }
          10 ->     if (req->method != M_HEAD) {
          10 ->         req_write(req, "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n"
                                  "<BODY><H1>404 Not Found</H1>\nThe requested URL ");
          10 ->         req_write_escape_html(req, req->request_uri);
          10 ->         req_write(req, " was not found on this server.\n</BODY></HTML>\n");
                    }
          10 ->     req_flush(req);
                }
                
                /* R_ERROR: 500 */
       ##### -> void send_r_error(request * req)
                {
       ##### ->     SQUASH_KA(req);
       ##### ->     req->response_status = R_ERROR;
       ##### ->     if (!req->simple) {
       ##### ->         req_write(req, "HTTP/1.0 500 Server Error\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* terminate header */
                    }
       ##### ->     if (req->method != M_HEAD) {
       ##### ->         req_write(req,
                                  "<HTML><HEAD><TITLE>500 Server Error</TITLE></HEAD>\n"
                                  "<BODY><H1>500 Server Error</H1>\nThe server encountered "
                                  "an internal error and could not complete your request.\n"
                                  "</BODY></HTML>\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->simple) {
       ##### ->         req_write(req, "HTTP/1.0 501 Not Implemented\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* terminate header */
                    }
       ##### ->     if (req->method != M_HEAD) {
       ##### ->         req_write(req,
                                  "<HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD>\n"
                                  "<BODY><H1>501 Not Implemented</H1>\nPOST to non-script "
                                  "is not supported in Boa.\n</BODY></HTML>\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->simple) {
       ##### ->         req_write(req, "HTTP/1.0 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,
                                  "<HTML><HEAD><TITLE>502 Bad Gateway</TITLE></HEAD>\n"
                                  "<BODY><H1>502 Bad Gateway</H1>\nThe CGI was "
                                  "not CGI/1.1 compliant.\n" "</BODY></HTML>\n");
                    }
       ##### ->     req_flush(req);
                }
                
                /* R_SERVICE_UNAVAILABLE: 503 */
       ##### -> void send_r_service_unavailable(request * req) /* 503 */
                {
                    static char body[]@zeroterm =
                        "<HTML><HEAD><TITLE>503 Service Unavailable</TITLE></HEAD>\n"
                        "<BODY><H1>503 Service Unavailable</H1>\n"
                        "There are too many connections in use right now.\r\n"
                        "Please try again later.\r\n</BODY></HTML>\n";
                    static int _body_len;
                    static char *body_len = NULL;
                
       ##### ->     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->simple) {
       ##### ->         req_write(req, "HTTP/1.0 503 Service Unavailable\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         if (body_len) {
       ##### ->             req_write(req, "Content-Length: ");
       ##### ->             req_write(req, body_len);
       ##### ->             req_write(req, "\r\n");
                        }
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* 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)
                {
       ##### ->     SQUASH_KA(req);
       ##### ->     req->response_status = R_BAD_VERSION;
       ##### ->     if (!req->simple) {
       ##### ->         req_write(req, "HTTP/1.0 505 HTTP Version Not Supported\r\n");
       ##### ->         print_http_headers(req);
       ##### ->         req_write(req, "Content-Type: " HTML "\r\n\r\n"); /* terminate header */
                    }
       ##### ->     if (req->method != M_HEAD) {
       ##### ->         req_write(req,
                                  "<HTML><HEAD><TITLE>505 HTTP Version Not Supported</TITLE></HEAD>\n"
                                  "<BODY><H1>505 HTTP Version Not Supported</H1>\nHTTP versions "
                                  "other than 0.9 and 1.0 "
                                  "are not supported in Boa.\n<p><p>Version encountered: ");
       ##### ->         req_write(req, req->http_version);
       ##### ->         req_write(req, "<p><p></BODY></HTML>\n");
                    }
       ##### ->     req_flush(req);
                }


Top 10 Lines:

     Line      Count

       52        270
       65        270
       30        260
       37        260
       44        260
       81        260
      225         10

Execution Summary:

      186   Executable lines in this file
      186   Lines executed
   100.00   Percent of the file executed

     1590   Total number of line executions
     8.55   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/get.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996,99 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996-2002 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                
                /* local prototypes */
                int get_cachedir_file(request * req, struct stat *statbuf);
                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
                 */
                
         270 -> int init_get(request *`H req)
                {
                    int data_fd, saved_errno;
                    struct stat statbuf;
                    volatile int bytes;
                
         270 ->     data_fd = open(req->pathname, O_RDONLY);
         270 ->     saved_errno = errno; /* might not get used */
                
                #ifdef GUNZIP
         270 ->     if (data_fd == -1 && errno == ENOENT) {
                        /* cannot open */
                        /* it's either a gunzipped file or a directory */
                        char gzip_pathname[MAX_PATH_LENGTH + 1] @zeroterm;
         270 ->         int len;
                
         270 ->         len = strlen(req->pathname);
                
         270 ->         memcpy(gzip_pathname, req->pathname, len);
         270 ->         memcpy(gzip_pathname + len, ".gz", 3);
         270 ->         gzip_pathname[len + 3] = '\0';
         270 ->         data_fd = open(gzip_pathname, O_RDONLY);
         270 ->         if (data_fd != -1) {
         270 ->             close(data_fd);
                
         270 ->             req->response_status = R_REQUEST_OK;
         270 ->             if (req->pathname)
         270 ->                 free(req->pathname);
         270 ->             req->pathname = strdup(gzip_pathname);
         270 ->             if (!req->pathname) {
         270 ->                 log_error_time();
         270 ->                 perror("strdup");
         270 ->                 send_r_error(req);
         270 ->                 return 0;
                            }
         270 ->             if (!req->simple) {
         270 ->                 req_write(req, "HTTP/1.0 200 OK-GUNZIP\r\n");
         270 ->                 print_http_headers(req);
         270 ->                 print_content_type(req);
         270 ->                 print_last_modified(req);
         270 ->                 req_write(req, "\r\n");
         270 ->                 req_flush(req);
                            }
         270 ->             if (req->method == M_HEAD)
         270 ->                 return 0;
                
         270 ->             return init_cgi(req);
                        }
                    }
                #endif
                
         270 ->     if (data_fd == -1) {
         270 ->         log_error_doc(req);
         270 ->         errno = saved_errno;
         270 ->         perror("document open");
                
         270 ->         if (saved_errno == ENOENT)
         270 ->             send_r_not_found(req);
         270 ->         else if (saved_errno == EACCES)
         270 ->             send_r_forbidden(req);
                        else
         270 ->             send_r_bad_request(req);
         270 ->         return 0;
                    }
                
         270 ->     fstat(data_fd, &statbuf);
                
         270 ->     if (S_ISDIR(statbuf.st_mode)) { /* directory */
         270 ->         close(data_fd);         /* close dir */
                
         270 ->         if (req->pathname[strlen(req->pathname) - 1] != '/') {
                            char buffer[3 * MAX_PATH_LENGTH + 128] @zeroterm;
                
         270 ->             if (server_port != 80)
         270 ->                 sprintf(buffer, "http://%s:%d%s/", server_name,
                                        server_port, req->request_uri);
                            else
         270 ->                 sprintf(buffer, "http://%s%s/", server_name,
                                        req->request_uri);
         270 ->             send_r_moved_perm(req, buffer);
         270 ->             return 0;
                        }
         270 ->         data_fd = get_dir(req, &statbuf); /* updates statbuf */
                
         270 ->         if (data_fd == -1)      /* couldn't do it */
         270 ->             return 0;           /* errors reported by get_dir */
         270 ->         else if (data_fd <= 1)
                            /* data_fd == 0 -> close it down, 1 -> continue */
         270 ->             return data_fd;
                        /* else, data_fd contains the fd of the file... */
                    }
         270 ->     if (req->if_modified_since &&
                        !modified_since(&(statbuf.st_mtime), req->if_modified_since)) {
         270 ->         send_r_not_modified(req);
         270 ->         close(data_fd);
         270 ->         return 0;
                    }
         270 ->     req->filesize = statbuf.st_size;
         270 ->     req->last_modified = statbuf.st_mtime;
                
         270 ->     if (req->method == M_HEAD || req->filesize == 0) {
         270 ->         send_r_request_ok(req);
         270 ->         close(data_fd);
         270 ->         return 0;
                    }
                
         270 ->     if (req->filesize > MAX_FILE_MMAP) {
         270 ->         send_r_request_ok(req); /* All's well */
         270 ->         req->status = PIPE_READ;
         270 ->         req->cgi_status = CGI_BUFFER;
         270 ->         req->data_fd = data_fd;
         270 ->         req_flush(req);         /* this should *always* complete due to
                                                   the size of the I/O buffers */
         270 ->         req->header_line = req->header_end = req->buffer;
         270 ->         return 1;
                    }
                
         270 ->     if (req->filesize == 0) {  /* done */
         270 ->         send_r_request_ok(req);     /* All's well *so far* */
         270 ->         close(data_fd);
         270 ->         return 1;
                    }
                
                    /* 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.
                     */
         270 ->     req->mmap_entry_var = find_mmap(data_fd, &statbuf);
         270 ->     if (req->mmap_entry_var == NULL) {
         270 ->         req->buffer_end = 0;
         270 ->         if (errno == ENOENT)
         270 ->             send_r_not_found(req);
         270 ->         else if (errno == EACCES)
         270 ->             send_r_forbidden(req);
                        else
         270 ->             send_r_bad_request(req);
         270 ->         close(data_fd);
         270 ->         return 0;
                    }
         270 ->     req->data_mem = req->mmap_entry_var->mmap;
         270 ->     close(data_fd);             /* close data file */
                
         270 ->     if ((long) ((const char *@nozeroterm) req->data_mem) == -1) {
         270 ->         boa_perror(req, "mmap");
         270 ->         return 0;
                    }
                
         270 ->     send_r_request_ok(req);     /* All's well */
                
         270 ->     bytes = BUFFER_SIZE - req->buffer_end;
                
                    /* bytes is now how much the buffer can hold
                     * after the headers
                     */
                
         270 ->     if (bytes > 0) {
         270 ->         if (bytes > req->filesize)
         270 ->             bytes = req->filesize;
                
                /*         if (sigsetjmp(env, 1) == 0) { */
         270 ->             handle_sigbus = 1;
         270 ->             memcpy(req->buffer + req->buffer_end, req->data_mem, bytes);
         270 ->             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); */
                /*             fprintf(stderr, "%sGot SIGBUS in memcpy!\n", get_commonlog_time()); */
                /*             return 0; */
                /*         } */
         270 ->         req->buffer_end += bytes;
         270 ->         req->filepos += bytes;
         270 ->         if (req->filesize == req->filepos) {
         270 ->             req_flush(req);
         270 ->             req->status = DONE;
                        }
                    }
                
                    /* We lose statbuf here, so make sure response has been sent */
         270 ->     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
                 */
                
         350 -> int process_get(request * req)
                {
                    int bytes_written;
                    volatile int bytes_to_write;
                
         350 ->     bytes_to_write = req->filesize - req->filepos;
         350 ->     if (bytes_to_write > SOCKETBUF_SIZE)
         350 ->         bytes_to_write = SOCKETBUF_SIZE;
                
                
                /*     if (sigsetjmp(env, 1) == 0) { */
         350 ->         handle_sigbus = 1;
         350 ->         bytes_written = write(req->fd, req->data_mem + req->filepos,
                                              bytes_to_write);
         350 ->         handle_sigbus = 0;
                        /* OK, SIGBUS **after** this point is very bad! */
                /*     } else { */
                /*         /\* sigbus! *\/ */
                /*         log_error_doc(req); */
                /*         /\* 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. */
                /*          *\/ */
                /*         req->status = DEAD; */
                /*         fprintf(stderr, "%sGot SIGBUS in write(2)!\n", get_commonlog_time()); */
                /*         return 0; */
                /*     } */
                
         350 ->     if (bytes_written < 0) {
         350 ->         if (errno == EWOULDBLOCK || errno == EAGAIN)
         350 ->             return -1;
                        /* request blocked at the pipe level, but keep going */
                        else {
         350 ->             if (errno != EPIPE) {
         350 ->                 log_error_doc(req);
                                /* Can generate lots of log entries, */
         350 ->                 perror("write");
                                /* OK to disable if your logs get too big */
                            }
         350 ->             req->status = DEAD;
         350 ->             return 0;
                        }
                    }
         350 ->     req->filepos += bytes_written;
                
         350 ->     if (req->filepos == req->filesize) { /* EOF */
         350 ->         return 0;
                    } else
         350 ->         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
                 */
                
          10 -> int get_dir(request *`H req, struct stat *statbuf)
                {
                
                    char pathname_with_index[MAX_PATH_LENGTH + 1] @zeroterm;
          10 ->     int data_fd;
                
          10 ->     if (directory_index) {      /* look for index.html first?? */
          10 ->         strcpy(pathname_with_index, req->pathname);
          10 ->         strcat(pathname_with_index, directory_index);
                        /*
                           sprintf(pathname_with_index, "%s%s", req->pathname, directory_index);
                         */
                
          10 ->         data_fd = open(pathname_with_index, O_RDONLY);
                
          10 ->         if (data_fd != -1) {    /* user's index file */
          10 ->             strcpy(req->request_uri, directory_index); /* for mimetype */
          10 ->             fstat(data_fd, statbuf);
          10 ->             return data_fd;
                        }
          10 ->         if (errno == EACCES) {
          10 ->             send_r_forbidden(req);
          10 ->             return -1;
          10 ->         } else if (errno != ENOENT) {
                            /* if there is an error *other* than EACCES or ENOENT */
          10 ->             send_r_not_found(req);
          10 ->             return -1;
                        }
                
                #ifdef GUNZIP
                        /* if we are here, trying index.html didn't work
                         * try index.html.gz
                         */
          10 ->         strcat(pathname_with_index, ".gz");
          10 ->         data_fd = open(pathname_with_index, O_RDONLY);
          10 ->         if (data_fd != -1) {    /* user's index file */
          10 ->             close(data_fd);
                
          10 ->             req->response_status = R_REQUEST_OK;
          10 ->             SQUASH_KA(req);
          10 ->             if (req->pathname)
          10 ->                 free(req->pathname);
          10 ->             req->pathname = strdup(pathname_with_index);
          10 ->             if (!req->pathname) {
          10 ->                 log_error_time();
          10 ->                 perror("strdup");
          10 ->                 send_r_error(req);
          10 ->                 return 0;
                            }
          10 ->             if (!req->simple) {
          10 ->                 req_write(req, "HTTP/1.0 200 OK-GUNZIP\r\n");
          10 ->                 print_http_headers(req);
          10 ->                 print_last_modified(req);
          10 ->                 req_write(req, "Content-Type: ");
          10 ->                 req_write(req, get_mime_type(directory_index));
          10 ->                 req_write(req, "\r\n\r\n");
          10 ->                 req_flush(req);
                            }
          10 ->             if (req->method == M_HEAD)
          10 ->                 return 0;
          10 ->             return init_cgi(req);
                        }
                #endif
                    }
                
                    /* only here if index.html, index.html.gz don't exist */
          10 ->     if (dirmaker != NULL) {     /* don't look for index.html... maybe automake? */
          10 ->         req->response_status = R_REQUEST_OK;
          10 ->         SQUASH_KA(req);
                
                        /* the indexer should take care of all headers */
          10 ->         if (!req->simple) {
          10 ->             req_write(req, "HTTP/1.0 200 OK\r\n");
          10 ->             print_http_headers(req);
          10 ->             print_last_modified(req);
          10 ->             req_write(req, "Content-Type: text/html\r\n\r\n");
          10 ->             req_flush(req);
                        }
          10 ->         if (req->method == M_HEAD)
          10 ->             return 0;
                
          10 ->         return init_cgi(req);
                        /* in this case, 0 means success */
          10 ->     } else if (cachedir) {
          10 ->         return get_cachedir_file(req, statbuf);
                    } else {                    /* neither index.html nor autogenerate are allowed */
          10 ->         send_r_forbidden(req);
          10 ->         return -1;              /* nothing worked */
                    }
                }
                
       ##### -> int get_cachedir_file(request * req, struct stat *statbuf)
                {
                
                    char pathname_with_index[MAX_PATH_LENGTH + 1] @zeroterm;
       ##### ->     int data_fd;
                    time_t real_dir_mtime;
                
       ##### ->     real_dir_mtime = statbuf->st_mtime;
       ##### ->     sprintf(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.
                 */
                
       ##### -> 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_time();
       ##### ->         fprintf(stderr, "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,
                                     "<HTML><HEAD>\n<TITLE>Index of %s</TITLE>\n</HEAD>\n\n",
                                     req->request_uri);
       ##### ->     bytes += fprintf(fdstream, "<BODY>\n\n<H2>Index of %s</H2>\n\n<PRE>\n",
                                     req->request_uri);
                
       ##### ->     while ((dirbuf = readdir(request_dir))) {
       ##### ->         if (!strcmp(dirbuf->d_name, "."))
       ##### ->             continue;
                
       ##### ->         if (!strcmp(dirbuf->d_name, "..")) {
       ##### ->             bytes += fprintf(fdstream,
                                             " [DIR] <A HREF=\"../\">Parent Directory</A>\n");
       ##### ->             continue;
                        }
                
       ##### ->         if ((escname = escape_string(dirbuf->d_name, NULL)) != NULL) {
       ##### ->             bytes += fprintf(fdstream, " <A HREF=\"%s\">%s</A>\n",
       ##### ->                              strdup(escname), dirbuf->d_name);
       ##### ->             free(escname);
       ##### ->             escname = NULL;
                        }
                    }
       ##### ->     closedir(request_dir);
       ##### ->     bytes += fprintf(fdstream, "</PRE>\n\n</BODY>\n</HTML>\n");
                
       ##### ->     fclose(fdstream);
                
       ##### ->     chdir(server_root);
                
       ##### ->     req->filesize = bytes;      /* for logging transfer size */
       ##### ->     return 0;                   /* success */
                }


Top 10 Lines:

     Line      Count

      236        350
       40        270
      303         10

Execution Summary:

      248   Executable lines in this file
      248   Lines executed
   100.00   Percent of the file executed

      630   Total number of line executions
     2.54   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/pipe.cyc:
                
                /*
                 *  Boa, an http server
                 *  Based on code Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1997-99 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba 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
                 */
                
         480 -> int read_from_pipe(request *`H req)
                {
         480 ->     int bytes_read, bytes_to_read =
                        BUFFER_SIZE - ((char *)req->header_end - req->buffer);
                
         480 ->     if (bytes_to_read == 0) {   /* buffer full */
         480 ->         if (req->cgi_status == CGI_PARSE) { /* got+parsed header */
         480 ->             req->cgi_status = CGI_BUFFER;
         480 ->             *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.
                             */
         480 ->             return process_cgi_header(req); /* cgi_status will change */
                        }
         480 ->         req->status = PIPE_WRITE;
         480 ->         return 1;
                    }
                
         480 ->     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
                
         480 ->     if (bytes_read == -1) {
         480 ->         if (errno == EINTR)
         480 ->             return 1;
         480 ->         else if (errno == EWOULDBLOCK || errno == EAGAIN)
         480 ->             return -1;          /* request blocked at the pipe level, but keep going */
                        else {
         480 -> 	    req->status = DEAD;
         480 ->             log_error_doc(req);
         480 ->             perror("pipe read");
         480 ->             return 0;
                        }
         480 ->     } else if (bytes_read == 0) { /* eof, write rest of buffer */
         480 ->         req->status = PIPE_WRITE;
         480 ->         if (req->cgi_status == CGI_PARSE) { /* hasn't processed header yet */
         480 ->             req->cgi_status = CGI_DONE;
         480 ->             *req->header_end = '\0'; /* points to end of read data */
         480 ->             return process_cgi_header(req); /* cgi_status will change */
                        }
         480 ->         req->cgi_status = CGI_DONE;
         480 ->         return 1;
                    }
         480 ->     req->header_end = req->header_end + bytes_read;
         480 ->     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
                 */
                
         490 -> int write_from_pipe(request *`H req)
                {
         490 ->     int bytes_written, bytes_to_write = req->header_end - req->header_line;
                
         490 ->     if (bytes_to_write == 0) {
         490 ->         if (req->cgi_status == CGI_DONE)
         490 ->             return 0;
                
         490 ->         req->status = PIPE_READ;
         490 ->         req->header_end = req->header_line = req->buffer;
         490 ->         return 1;
                    }
                
         490 ->     bytes_written = write(req->fd, req->header_line, bytes_to_write);
                
         490 ->     if (bytes_written == -1) {
         490 ->         if (errno == EWOULDBLOCK || errno == EAGAIN)
         490 ->             return -1;          /* request blocked at the pipe level, but keep going */
         490 ->         else if (errno == EINTR)
         490 ->             return 1;
                        else {
         490 ->             req->status = DEAD;
         490 ->             send_r_error(req);  /* maybe superfluous */
         490 ->             log_error_doc(req);
         490 ->             perror("pipe write");
         490 ->             return 0;
                        }
                    }
                
         490 ->     req->header_line = req->header_line + bytes_written;
         490 ->     req->filepos += bytes_written;
                
         490 ->     return 1;
                }


Top 10 Lines:

     Line      Count

      103        490
       37        480

Execution Summary:

       51   Executable lines in this file
       51   Lines executed
   100.00   Percent of the file executed

      970   Total number of line executions
    19.02   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/boa_grammar.y:
                %{
                
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <psp@well.com>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include <string.h>
                #include <stdio.h>
                #include <stdlib.h>
                #include <unistd.h>
                /* #include "boa.h" */
                #include "parse.h"
                
                /* void yyerror(string_t msg); */
                
                /* yydebug = 1; */
                
                #ifdef DEBUG
                #define DBG(x) x
                #else
                #define DBG(x)
                #endif
                
                char *arg1hold;
                char mime_type[256] @zeroterm;            /* global to inherit */
                
                %}
                
                %union <`r> {
                    sval(char *`r);
                    ival(int);
                    cval(struct ccommand @`r);
                };
                %token STMT_NO_ARGS STMT_ONE_ARG STMT_TWO_ARGS MIMETYPE STRING INTEGER
                /* boa.conf tokens */
                %type <struct ccommand @`r> STMT_NO_ARGS STMT_ONE_ARG STMT_TWO_ARGS
                
          11 -> /* mime.type tokens */
                %type <char *`r> MIMETYPE
          11 -> %type <char *`r> STRING
         613 -> %type <int> INTEGER
         613 -> 
         613 -> %start ConfigFiles
         613 -> 
         613 -> %%
         613 -> 
         613 -> ConfigFiles:		BoaConfigStmts MimeTypeStmts
       ##### -> 	;
       ##### -> 
                BoaConfigStmts:		BoaConfigStmts BoaConfigStmt
       ##### -> 	|		/* empty */
                	;
       ##### -> 
                BoaConfigStmt:		
                			StmtNoArgs
                	|		StmtOneArg
                	|		StmtTwoArgs
                	;
                
                StmtNoArgs:		STMT_NO_ARGS
       ##### -> 		{ let &ccommand{<`a> my_name, my_type, my_action, my_object} = $1; if (my_action) {
                			DBG(printf("StmtNoArgs: %s\n",my_name);)
       ##### -> 			my_action(NULL,NULL,my_object);
                		 }
                		}
       ##### -> 	;
                
       ##### -> StmtOneArg:		STMT_ONE_ARG STRING
       ##### -> 		{ let &ccommand{<`a> my_name, my_type, my_action, my_object} = $1; if (my_action) {
                			DBG(printf("StmtOneArg: %s %s\n",my_name,$2);)
       ##### -> 			my_action($2,NULL,my_object);
                		 }
                		}
       ##### -> 	;
                
       ##### -> StmtTwoArgs:		STMT_TWO_ARGS STRING
       ##### -> 		{ arg1hold = strdup($2); }
       ##### -> 			 STRING
       ##### -> 		{ let &ccommand{<`a> my_name, my_type, my_action, my_object} = $1; if (my_action) {
       ##### -> 			DBG(printf("StmtTwoArgs: '%s' '%s' '%s'\n",
                			            my_name,arg1hold,$4);)
       ##### -> 			my_action($4,arg1hold,my_object);
                		  }
       ##### -> 		  free(arg1hold);
                		}
       ##### -> 	;
                
       ##### -> 
                /******************* mime.types **********************/
                
                MimeTypeStmts:		MimeTypeStmts MimeTypeStmt
                	|		/* empty */
                	;
                
                MimeTypeStmt:		MIMETYPE 
       ##### -> 		{ strcpy(mime_type, $1); }
       ##### -> 			ExtensionList
                	;
       ##### -> 
                ExtensionList:		ExtensionList Extension
                	|		/* empty */
                	;
                
                Extension:		STRING
       ##### -> 		{ add_mime_type($1, mime_type); }
                	;
                
                %%
                


Top 10 Lines:

     Line      Count

       59        613
       56         11

Execution Summary:

       33   Executable lines in this file
       33   Lines executed
   100.00   Percent of the file executed

      624   Total number of line executions
    18.91   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/util.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996,97 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996 Charles F. Randall <crandall@goldsys.com>
                 *  Some changes Copyright (C) 1996-99 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $ */
                
                #include "boa.h"
                
                #define HEX_TO_DECIMAL(char1, char2)	\
                    (((char1 >= 'A') ? (((char1 & 0xdf) - 'A') + 10) : (char1 - '0')) * 16) + \
                    (((char2 >= 'A') ? (((char2 & 0xdf) - 'A') + 10) : (char2 - '0')))
                
                const char month_tab[49] =
                    "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";
                const char day_tab[] = "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)
                 */
                
         270 -> void clean_pathname(char ?pathname)
                {
                    char ?cleanpath, c;
                
         270 ->     cleanpath = pathname;
         270 ->     while ((c = *pathname++)) {
         270 ->         if (c == '/') {
                            while (1) {
         270 ->                 if (*pathname == '/')
         270 ->                     pathname++;
         270 ->                 else if (*pathname == '.' && *(pathname + 1) == '/')
         270 ->                     pathname = pathname + 2;
         270 ->                 else if (*pathname == '.' && *(pathname + 1) == '.' &&
                                         *(pathname + 2) == '/') {
         270 ->                     pathname = pathname + 3;
                                } else
                                    break;
                            }
         270 ->             c = '/';
                        }
         270 ->         *cleanpath++ = c;
                    }
                
         270 ->     *cleanpath = '\0';
                }
                
                /*
                 * 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] "
                 *
                 * Constrast 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
                 *
                 */
                
          15 -> char *get_commonlog_time(void)
                {
                    struct tm *t;
                    char ?p;
                    unsigned int a;
                    static char buf[30]@zeroterm;
          15 ->     int time_offset;
                
          15 ->     if (use_localtime) {
          15 ->         t = localtime(&current_time);
          15 ->         time_offset = TIMEZONE_OFFSET(t);
                    } else {
          15 ->         t = gmtime(&current_time);
          15 ->         time_offset = 0;
                    }
                
          15 ->     p = buf + 29;
          15 ->     *p-- = '\0';
          15 ->     *p-- = ' ';
          15 ->     *p-- = ']';
          15 ->     a = abs(time_offset / 60);
          15 ->     *p-- = '0' + a % 10;
          15 ->     a /= 10;
          15 ->     *p-- = '0' + a % 6;
          15 ->     a /= 6;
          15 ->     *p-- = '0' + a % 10;
          15 ->     *p-- = '0' + a / 10;
          15 ->     *p-- = (time_offset >= 0) ? '+' : '-';
          15 ->     *p-- = ' ';
                
          15 ->     a = t->tm_sec;
          15 ->     *p-- = '0' + a % 10;
          15 ->     *p-- = '0' + a / 10;
          15 ->     *p-- = ':';
          15 ->     a = t->tm_min;
          15 ->     *p-- = '0' + a % 10;
          15 ->     *p-- = '0' + a / 10;
          15 ->     *p-- = ':';
          15 ->     a = t->tm_hour;
          15 ->     *p-- = '0' + a % 10;
          15 ->     *p-- = '0' + a / 10;
          15 ->     *p-- = ':';
          15 ->     a = 1900 + t->tm_year;
          15 ->     while (a) {
          15 ->         *p-- = '0' + a % 10;
          15 ->         a /= 10;
                    }
                    /* p points to an unused spot */
          15 ->     *p-- = '/';
          15 ->     p -= 2;
          15 ->     memcpy(p--, month_tab + 4 * (t->tm_mon), 3);
          15 ->     *p-- = '/';
          15 ->     a = t->tm_mday;
          15 ->     *p-- = '0' + a % 10;
          15 ->     *p-- = '0' + a / 10;
          15 ->     *p = '[';
          15 ->     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(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: modified_since
                 * Description: Decides whether a file's mtime is newer than the
                 * If-Modified-Since header of a request.
                 *
                
                 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:
                 *  0: File has not been modified since specified time.
                 *  1: File has been.
                 * -1: Error!
                 */
                
       ##### -> int modified_since(time_t * mtime, char *if_modified_since)
                {
                    struct tm *file_gmt;
                    char *ims_info;
                    char monthname[10 + 1]@zeroterm;
       ##### ->     int day, month, year, hour, minute, second;
                    int comp;
                
       ##### ->     ims_info = if_modified_since;
       ##### ->     while (*ims_info != ' ' && *ims_info != '\0')
       ##### ->         ++ims_info;
       ##### ->     if (*ims_info != ' ')
       ##### ->         return -1;
                
                    /* the pre-space in the third scanf skips whitespace for the string */
       ##### ->     if (sscanf(ims_info, "%d %3s %d %d:%d:%d GMT", /* RFC 1123 */
                               &day, monthname, &year, &hour, &minute, &second) == 6);
       ##### ->     else if (sscanf(ims_info, "%d-%3s-%d %d:%d:%d GMT", /* RFC 1036 */
                                    &day, monthname, &year, &hour, &minute, &second) == 6)
       ##### ->         year += 1900;
       ##### ->     else if (sscanf(ims_info, " %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 if_modified_since here, because the date *starts*
                     *       with the day, versus a throwaway item
                     */
       ##### ->     else if (sscanf(if_modified_since, "%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__, ims_info);
       ##### ->         return -1;              /* error */
                    }
                
       ##### ->     file_gmt = gmtime(mtime);
       ##### ->     month = month2int(monthname);
                
                    /* Go through from years to seconds -- if they are ever unequal,
                     we know which one is newer and can return */
                
       ##### ->     if ((comp = 1900 + file_gmt->tm_year - year))
       ##### ->         return (comp > 0);
       ##### ->     if ((comp = file_gmt->tm_mon - month))
       ##### ->         return (comp > 0);
       ##### ->     if ((comp = file_gmt->tm_mday - day))
       ##### ->         return (comp > 0);
       ##### ->     if ((comp = file_gmt->tm_hour - hour))
       ##### ->         return (comp > 0);
       ##### ->     if ((comp = file_gmt->tm_min - minute))
       ##### ->         return (comp > 0);
       ##### ->     if ((comp = file_gmt->tm_sec - second))
       ##### ->         return (comp > 0);
                
       ##### ->     return 0;                   /* this person must really be into the latest/greatest */
                }
                
                
                /*
                 * Name: to_upper
                 *
                 * Description: Turns a string into all upper case (for HTTP_ header forming)
                 * AND changes - into _
                 */
                
        1330 -> char *`r to_upper(char *`r str)
                {
        1330 ->     char *start = str;
                
        1330 ->     while (*str) {
        1330 ->         if (*str == '-')
        1330 ->             *str = '_';
                        else
        1330 ->             *str = toupper(*str);
                
        1330 ->         str++;
                    }
                
        1330 ->     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
                 */
                
         270 -> int unescape_uri(char *`r uri, char *`r* query_string)
                {
                    char c, d;
                    char *uri_old;
                
         270 ->     uri_old = uri;
                
         270 ->     while ((c = *uri_old)) {
         270 ->         if (c == '%') {
         270 ->             uri_old++;
         270 ->             if ((c = *uri_old++) && (d = *uri_old++))
         270 ->                 *uri++ = HEX_TO_DECIMAL(c, d);
                            else
         270 ->                 return 0;       /* NULL in chars to be decoded */
         270 ->         } else if (c == '?') { /* query string */
         270 ->             if (query_string)
         270 ->                 *query_string = ++uri_old;
                            /* stop here */
         270 ->             *uri = '\0';
         270 ->             return(1);
                            break;
         270 ->         } else if (c == '#') { /* fragment */
                            /* legal part of URL, but we do *not* care.
                             * However, we still have to look for the query string */
         270 ->             if (query_string) {
         270 ->                 ++uri_old;
         270 ->                 while((c = *uri_old)) {
         270 ->                     if (c == '?') {
         270 ->                         *query_string = ++uri_old;
         270 ->                         break;
                                    }
         270 ->                     ++uri_old;
                                }
                            }
                            break;
                        } else {
         270 ->             *uri++ = c;
         270 ->             uri_old++;
                        }
                    }
                
         270 ->     *uri = '\0';
         270 ->     return 1;
                }
                
                /* rfc822 (1123) time is exactly 29 characters long
                 * "Sun, 06 Nov 1994 08:49:37 GMT"
                 */
                
         530 -> void rfc822_time_buf(char *buf, time_t s)
                {
                    struct tm *t;
                    char ?p;
                    unsigned int a;
                
         530 ->     if (!s) {
         530 ->         t = gmtime(&current_time);
                    } else
         530 ->         t = gmtime(&s);
                
         530 ->     p = buf + 28;
                    /* p points to the last char in the buf */
                
         530 ->     p -= 3;
                    /* p points to where the ' ' will go */
         530 ->     memcpy(p--, " GMT", 4);
                
         530 ->     a = t->tm_sec;
         530 ->     *p-- = '0' + a % 10;
         530 ->     *p-- = '0' + a / 10;
         530 ->     *p-- = ':';
         530 ->     a = t->tm_min;
         530 ->     *p-- = '0' + a % 10;
         530 ->     *p-- = '0' + a / 10;
         530 ->     *p-- = ':';
         530 ->     a = t->tm_hour;
         530 ->     *p-- = '0' + a % 10;
         530 ->     *p-- = '0' + a / 10;
         530 ->     *p-- = ' ';
         530 ->     a = 1900 + t->tm_year;
         530 ->     while (a) {
         530 ->         *p-- = '0' + a % 10;
         530 ->         a /= 10;
                    }
                    /* p points to an unused spot to where the space will go */
         530 ->     p -= 3;
                    /* p points to where the first char of the month will go */
         530 ->     memcpy(p--, month_tab + 4 * (t->tm_mon), 4);
         530 ->     *p-- = ' ';
         530 ->     a = t->tm_mday;
         530 ->     *p-- = '0' + a % 10;
         530 ->     *p-- = '0' + a / 10;
         530 ->     *p-- = ' ';
         530 ->     p -= 3;
         530 ->     memcpy(p, day_tab + t->tm_wday * 4, 4);
                }
                
         781 -> 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] @zeroterm;
         781 ->     char ?p = &local[21];
         781 ->     *p-- = '\0';
                    do {
         781 ->         *p-- = '0' + i % 10;
         781 ->         i /= 10;
                    } while (i > 0);
         781 ->     return p + 1;
                }
                
                /* I don't "do" negative conversions
                 * Therefore, -1 indicates error
                 */
                
       ##### -> int boa_atoi(char *s)
                {
                    int retval;
                    char *reconv;
                
       ##### ->     if (!isdigit(*s))
       ##### ->         return -1;
                
       ##### ->     retval = atoi(s);
       ##### ->     if (retval < 0)
       ##### ->         return -1;
                
       ##### ->     reconv = simple_itoa(retval);
       ##### ->     if (memcmp(s,reconv,strlen(s)) != 0) {
       ##### ->         return -1;
                    }
       ##### ->     return retval;
                }
                
       ##### -> int create_temporary_file(short want_unlink, char *storage, int size)
                {
                    static char boa_tempfile[MAX_PATH_LENGTH + 1] @zeroterm;
       ##### ->     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) {
       ##### ->         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);
                }
                
                /*
                 * Name: normalize_path
                 *
                 * Description: Makes sure relative paths are made absolute
                 *
                 */
                
                #define DIRBUF_SIZE MAX_PATH_LENGTH * 2 + 1
           2 -> char * normalize_path(char *path)
                {
                    char dirbuf[DIRBUF_SIZE] @zeroterm;
           2 ->     int len1, len2;
                    char *endpath;
                
           2 ->     if (path[0] == '/') {
           2 ->         endpath = strdup(path);
                    } else {
                
                #ifndef HAVE_GETCWD
                        perror("boa: getcwd() not defined. Aborting.");
                        exit(1);
                #endif
           2 ->         if (getcwd(dirbuf, DIRBUF_SIZE) == NULL) {
           2 ->             if (errno == ERANGE)
           2 ->                 perror
                                    ("boa: getcwd() failed - unable to get working directory. "
                                     "Aborting.");
           2 ->             else if (errno == EACCES)
           2 ->                 perror("boa: getcwd() failed - No read access in current "
                                       "directory. Aborting.");
                            else
           2 ->                 perror("boa: getcwd() failed - unknown error. Aborting.");
           2 ->             exit(1);
                        }
                
                        /* OK, now the hard part. */
           2 ->         len1 = strlen(dirbuf);
           2 ->         len2 = strlen(path);
           2 ->         if (len1 + len2 > MAX_PATH_LENGTH * 2) {
           2 ->             perror("boa: eek. unable to normalize pathname");
           2 ->             exit(1);
                        }
           2 ->         if (strcmp(path,".") != 0) {
           2 ->             memcpy(dirbuf + len1, "/", 1);
           2 ->             memcpy(dirbuf + len1 + 1, path, len2 + 1);
                        }
                        /* fprintf(stderr, "boa: normalize gets \"%s\"\n", dirbuf); */
                
           2 ->         endpath = strdup(dirbuf);
                    }
                
           2 ->     if (endpath == NULL) {
           2 ->         fprintf(stderr,
                                "boa: Cannot strdup path. Aborting.\n");
           2 ->         exit(1);
                    }
           2 ->     return endpath;
                }
                
       ##### -> int real_set_block_fd(int fd)
                {
                    int flags;
                
       ##### ->     flags = fcntl(fd, F_GETFL);
       ##### ->     if (flags == -1)
       ##### ->         return -1;
                
       ##### ->     flags &= ~O_NONBLOCK;
       ##### ->     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 |= O_NONBLOCK;
       ##### ->     flags = fcntl(fd, F_SETFL, flags);
       ##### ->     return flags;
                }


Top 10 Lines:

     Line      Count

      265       1330
      389        781
      341        530
       46        270
      292        270
       90         15
      480          2

Execution Summary:

      244   Executable lines in this file
      244   Lines executed
   100.00   Percent of the file executed

     3198   Total number of line executions
    13.11   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/boa_lexer.l:
                %{
                
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <psp@well.com>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "y.tab.h"
                #include <stdlib.h>
                #include <unistd.h>
                #include "parse.h"
                #define YY_SKIP_YYWRAP
                #define MAX_STR_CONST 1024
                #define qspush(c) \
                	if (string_buf_ptr < string_buf+MAX_STR_CONST) \
                		*string_buf_ptr++ = c; \
                	else \
                		yyerror("quoted string overflow");
                int yyerror(const char * msg); int yywrap();
                char *mime_types = NULL;
                
                static int file = 0;
                int lineno = 1;
                struct ccommand *k; 
                char string_buf[MAX_STR_CONST] @zeroterm;
                char *string_buf_ptr;
                %}
                
                %s MIME
                /* Quoted string handling (almost) straight out of
                   the flex 2.5 man page, April 1995 */
                %x STR
                
                %%
                
                [ \t]+		;
                #.*		;
                
       ##### -> <MIME>[^ \t\n]+\/[^ \t\n]+	{ yylval.sval = yytext; return MIMETYPE; }
                
                [^ \"\t\n]+	{ /* XXX could use better checks that we are in a state to
                		   * accept keywords; this version matches original behavior */
       ##### -> 		  if ((YYSTATE==INITIAL) && (k=lookup_keyword(yytext))) {
       ##### -> 		      yylval.cval=k;
       ##### -> 		      return (k->type);
       ##### -> 		  } else { yylval.sval = yytext; return STRING; }
                                }
                
                \"	{
       ##### -> 	string_buf_ptr = string_buf;
       ##### -> 	BEGIN(STR);
                	}
       ##### -> 
                <STR>{
                \"	{ /* saw closing quote - all done */
       ##### -> 	BEGIN(INITIAL);
       ##### -> 	*string_buf_ptr = '\0';
                	/* return string constant token type and value to parser */
       ##### -> 	yylval.sval = string_buf; return STRING;
                	}
                
                \n	{
                	/* error - unterminated string constant */
                	/* generate error message */
       ##### -> 	yyerror("unterminated string constant");
                	}
       ##### -> 
                \\[0-7]{1,3}  {
                	/* octal escape sequence */
                	int result;
                
       ##### -> 	(void) sscanf( yytext + 1, "%o", &result );
                
                	if ( result > 0xff )
                		{ /* error, constant is out-of-bounds */ }
                
       ##### -> 	qspush(result);
                	}
       ##### -> 
                \\[0-9]+  {
                	/* generate error - bad escape sequence; something
                	 * like '\48' or '\0777777'
                	 */
       ##### -> 	yyerror("bad escape sequence");
                	}
       ##### -> 
       ##### -> \\n	qspush('\n');
       ##### -> \\t	qspush('\t');
       ##### -> \\r	qspush('\r');
       ##### -> \\b	qspush('\b');
       ##### -> \\f	qspush('\f');
       ##### -> 
       ##### -> \\(.|\n)  *string_buf_ptr++ = yytext[1];
       ##### -> 
                [^\\\n\"]+  {
       ##### -> 	char *yptr = yytext;
       ##### -> 	while ( *yptr )
       ##### -> 		qspush(*yptr++);
                	}
                }
                	/* End of <STR> dependence */
       ##### -> \n		{ lineno++; }
       ##### -> %%
       ##### -> 
                /* In yywrap we track which file we are on.
                 * 1: close boa.conf, open mime.types
                 * 2: return 1;
                 */
                
           2 -> int yywrap()
                {
           2 ->     fclose(yyin);
           2 ->     file++; 
                
           2 ->     switch(file) {
                      case 1:
           2 -> 	yyin = fopen(mime_types, "r");
           2 -> 	if(!yyin) {
           2 -> 	    fprintf(stderr, "Could not open mime.types file, \"%s\", "
                	    	"for reading\n", mime_types);
           2 -> 	    exit(1);
                	}
           2 -> 	BEGIN MIME;
           2 -> 	return 0;
                      default:
           2 -> 	BEGIN INITIAL;
           2 -> 	file = 0;		/* in case we reread config files */
           2 -> 	return 1;
                    }
                }
                
       ##### -> int yyerror(const char * msg)
                {
       ##### ->     fprintf(stderr, "Error on line %d of %s: %s\n", lineno, 
       ##### ->       (file == 0 ? "boa.conf" : "mime.types"), msg);
       ##### ->     return 1;
                }
                


Top 10 Lines:

     Line      Count

      127          2

Execution Summary:

       49   Executable lines in this file
       49   Lines executed
   100.00   Percent of the file executed

        2   Total number of line executions
     0.04   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/log.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1999 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                
                FILE *access_log;
                
                char *error_log_name;
                char *access_log_name;
                char *cgi_log_name;
                int cgi_log_fd;
                
                FILE *fopen_gen_fd(char *spec, const char *mode);
                
       ##### -> FILE *fopen_gen_fd(char *spec, const char *mode)
                {
                    int fd;
       ##### ->     if (!spec || *spec == '\0')
       ##### ->         return NULL;
       ##### ->     fd = open_gen_fd(spec);
       ##### ->     if (fd == -1)
       ##### ->         return NULL;
       ##### ->     return fdopen(fd, mode);
                }
                
                /*
                 * 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.
                 *
                 */
                
           1 -> void open_logs(void)
                {
                    int error_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 */
           1 ->     if (error_log_name) {
                        /* open the log file */
           1 ->         if (!(error_log = open_gen_fd(error_log_name))) {
           1 ->             DIE("unable to open error log");
                        }
                
                        /* redirect stderr to error_log */
           1 ->         if (dup2(error_log, STDERR_FILENO) == -1) {
           1 ->             DIE("unable to dup2 the error log");
                        }
           1 ->         close(error_log);
                    }
                
                    /* set the close-on-exec to true */
           1 ->     if (fcntl(STDERR_FILENO, F_SETFD, 1) == -1) {
           1 ->         DIE("unable to fcntl the error log");
                    }
                
           1 ->     if (access_log_name) {
                        /* Used the "a" flag with fopen, but fopen_gen_fd builds that in
                         * implicitly when used as a file, and "a" is incompatible with
                         * pipes and network sockets. */
           1 ->         if (!(access_log = fopen_gen_fd(access_log_name, "w"))) {
           1 ->             int errno_save = errno;
           1 ->             fprintf(stderr, "Cannot open %s for logging: ",
                                    access_log_name);
           1 ->             errno = errno_save;
           1 ->             perror("logfile open");
           1 ->             exit(errno);
                        }
                        /* line buffer the access log */
                #ifdef SETVBUF_REVERSED
                        setvbuf(access_log, _IOLBF, (char *) NULL, 0);
                #else
           1 ->         setvbuf(access_log, (char *) NULL, _IOLBF, 0);
                #endif
                    } else
           1 ->         access_log = NULL;
                
           1 ->     if (cgi_log_name) {
           1 ->         cgi_log_fd = open_gen_fd(cgi_log_name);
           1 ->         if (cgi_log_fd == -1) {
           1 ->             WARN("open cgi_log");
           1 ->             free(cgi_log_name);
           1 ->             cgi_log_name = NULL;
           1 ->             cgi_log_fd = 0;
                        } else {
           1 ->             if (fcntl(cgi_log_fd, F_SETFD, 1) == -1) {
           1 ->                 WARN("unable to set close-on-exec flag for cgi_log");
           1 ->                 close(cgi_log_fd);
           1 ->                 cgi_log_fd = 0;
           1 ->                 free(cgi_log_name);
           1 ->                 cgi_log_name = NULL;
                            }
                        }
                    }
                }
                
                /*
                 * Name: close_access_log
                 *
                 * Description: closes access_log file
                 */
       ##### -> void close_access_log(void)
                {
       ##### ->     if (access_log)
       ##### ->         fclose(access_log);
                }
                
                /*
                 * Name: log_access
                 *
                 * Description: Writes log data to access_log.
                 */
                
         270 -> void log_access(request * req)
                {   static char dash[]@zeroterm = "-";
         270 ->     if (access_log) {
         270 ->         if (virtualhost)
         270 ->             fprintf(access_log, "%s ", req->local_ip_addr);
         270 ->         fprintf(access_log, "%s - - %s\"%s\" %d %ld \"%s\" \"%s\"\n",
                                req->remote_ip_addr,
         270 ->                 get_commonlog_time(),
                                req->logline,
                                req->response_status,
                                req->filepos,
         270 ->                 (req->header_referer ? req->header_referer : dash),
         270 ->                 (req->header_user_agent ? req->header_user_agent : dash));
                
                    }
                }
                
                /*
                 * 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
                 *
                 * This function used to be implemented with a big fprintf, but not
                 * all fprintf's are reliable in the face of null string pointers
                 * (SunOS, in particular).  As long as I had to add the checks for
                 * null pointers, I changed from fprintf to fputs.
                 *
                 * 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
                 */
                
          10 -> void log_error_doc(request * req)
                {   static char null_string[]@zeroterm = "(null)";
          10 ->     int errno_save = errno;
                
          10 ->     fprintf(stderr, "%srequest from %s \"%s\" (\"%s\"): ",
          10 ->             get_commonlog_time(),
                            req->remote_ip_addr,
          10 ->             (req->logline != NULL ?
                             req->logline : null_string),
          10 ->             (req->pathname != NULL ? req->pathname : null_string));
                
          10 ->     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
                 */
                
           5 -> void log_error_time()
                {
           5 ->     int errno_save = errno;
           5 ->     fputs(get_commonlog_time(), stderr);
           5 ->     errno = errno_save;
                }
                
                /*
                 * 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
                 *
                 */
                
       ##### -> 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;
                }


Top 10 Lines:

     Line      Count

      140        270
      173         10
      207          5
       58          1

Execution Summary:

       70   Executable lines in this file
       70   Lines executed
   100.00   Percent of the file executed

      286   Total number of line executions
     4.09   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/buffer.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1999 Jon Nelson <jnelson@boa.org>
                
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $ */
                
                #include "boa.h"
                #include "escape.h"
                
                #define INT_TO_HEX(x) \
                    ((((x)-10)>=0)?('A'+((x)-10)):('0'+(x)))
                
                /*
                 * Name: req_write
                 *
                 * Description: Buffers data before sending to client.
                 * Returns: -1 for error, otherwise how much is stored
                 */
                
        3960 -> int req_write(request * req, const char *msg)
                {
                    int msg_len;
                
        3960 ->     msg_len = strlen(msg);
                
        3960 ->     if (!msg_len || req->status == DEAD)
        3960 ->         return req->buffer_end;
                
        3960 ->     if (req->buffer_end + msg_len > BUFFER_SIZE) {
        3960 ->         log_error_time();
        3960 ->         fprintf(stderr, "Ran out of Buffer space!\n");
        3960 ->         req->status = DEAD;
        3960 ->         return -1;
                    }
        3960 ->     memcpy(req->buffer + req->buffer_end, msg, msg_len);
        3960 ->     req->buffer_end += msg_len;
        3960 ->     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, char *msg)
                {
                    char c, *inp, *dest;
                    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 - 3;
       ##### ->     while ((c = *inp++) && left > 0) {
       ##### ->         if (needs_escape((unsigned int) c)) {
       ##### ->             *dest++ = '%';
       ##### ->             *dest++ = INT_TO_HEX(c >> 4);
       ##### ->             *dest++ = INT_TO_HEX(c & 15);
       ##### ->             left -= 3;
                        } else {
       ##### ->             *dest++ = c;
       ##### ->             left--;
                        }
                    }
       ##### ->     req->buffer_end = dest - req->buffer;
       ##### ->     if (left == 0) {
       ##### ->         log_error_time();
       ##### ->         fprintf(stderr, "Ran out of Buffer space!\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
                 */
          10 -> int req_write_escape_html(request * req, char *msg)
                {
                    char c, ?inp, ?dest;
                    int left;
          10 ->     inp = msg;
          10 ->     dest = req->buffer + req->buffer_end;
                    /* 5 is a guard band, since we don't check the destination pointer
                     * in the middle of a transfer of up to 5 bytes */
          10 ->     left = BUFFER_SIZE - req->buffer_end - 5;
          10 ->     while ((c = *inp++) && left > 0) {
          10 ->         switch (c) {
                        case '>':
          10 ->             *dest++ = '&';
          10 ->             *dest++ = 'g';
          10 ->             *dest++ = 't';
          10 ->             *dest++ = ';';
          10 ->             left -= 4;
          10 ->             break;
                        case '<':
          10 ->             *dest++ = '&';
          10 ->             *dest++ = 'l';
          10 ->             *dest++ = 't';
          10 ->             *dest++ = ';';
          10 ->             left -= 4;
          10 ->             break;
                        case '&':
          10 ->             *dest++ = '&';
          10 ->             *dest++ = 'a';
          10 ->             *dest++ = 'm';
          10 ->             *dest++ = 'p';
          10 ->             *dest++ = ';';
          10 ->             left -= 5;
          10 ->             break;
                        case '\"':
          10 ->             *dest++ = '&';
          10 ->             *dest++ = 'q';
          10 ->             *dest++ = 'u';
          10 ->             *dest++ = 'o';
          10 ->             *dest++ = 't';
          10 ->             *dest++ = ';';
          10 ->             left -= 6;
          10 ->             break;
                        default:
          10 ->             *dest++ = c;
          10 ->             left--;
                        }
                    }
          10 ->     req->buffer_end = dest - req->buffer;
          10 ->     if (left == 0) {
          10 ->         log_error_time();
          10 ->         fprintf(stderr, "Ran out of Buffer space!\n");
          10 ->         req->status = DEAD;
          10 ->         return -1;
                    }
          10 ->     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
                 */
                
         400 -> int req_flush(request * req)
                {
                    int bytes_to_write;
                
         400 ->     bytes_to_write = req->buffer_end - req->buffer_start;
         400 ->     if (req->status == DEAD)
         400 ->         return -2;
                
         400 ->     if (bytes_to_write) {
                        int bytes_written;
                
         400 ->         bytes_written = write(req->fd, req->buffer + req->buffer_start,
                                              bytes_to_write);
                
         400 ->         if (bytes_written < 0) {
         400 ->             if (errno == EWOULDBLOCK || errno == EAGAIN)
         400 ->                 return -1;      /* request blocked at the pipe level, but keep going */
                            else {
         400 ->                 req->buffer_start = req->buffer_end = 0;
         400 ->                 if (errno != EPIPE)
         400 ->                     perror("buffer flush"); /* OK to disable if your logs get too big */
         400 ->                 req->status = DEAD;
         400 ->                 req->buffer_end = 0;
         400 ->                 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
         400 ->         req->buffer_start += bytes_written;
                    }
         400 ->     if (req->buffer_start == req->buffer_end)
         400 ->         req->buffer_start = req->buffer_end = 0;
         400 ->     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 *`r escape_string(char ?@nozeroterm inp, char *`r buf)
                {
                    int max;
                    char *index;
                    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;
                    }
                
       ##### ->     index = buf;
       ##### ->     while ((c = *inp++) && max > 0) {
       ##### ->         if (needs_escape((unsigned int) c)) {
       ##### ->             *index++ = '%';
       ##### ->             *index++ = INT_TO_HEX(c >> 4);
       ##### ->             *index++ = INT_TO_HEX(c & 15);
                        } else
       ##### ->             *index++ = c;
                    }
       ##### ->     *index = '\0';
       ##### ->     return buf;
                }


Top 10 Lines:

     Line      Count

       37       3960
      172        400
      106         10

Execution Summary:

      111   Executable lines in this file
      111   Lines executed
   100.00   Percent of the file executed

     4370   Total number of line executions
    39.37   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/signals.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996-99 Jon Nelson <jnelson@boa.org>
                 *  Some changes Copyright (C) 1997 Alain Magloire <alain.magloire@rcsm.ee.mcgill.ca>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                #ifdef HAVE_SYS_WAIT_H
                #include <sys/wait.h>           /* wait */
                #endif
                #include <signal.h>             /* 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.
                 */
                
           1 -> void init_signals(void)
                {
           1 ->     struct sigaction sa = fresh_sigaction();
                
           1 ->     sa.sa_flags = 0;
                
           1 ->     sigemptyset(&sa.sa_mask);
           1 ->     sigaddset(&sa.sa_mask, SIGSEGV);
           1 ->     sigaddset(&sa.sa_mask, SIGBUS);
           1 ->     sigaddset(&sa.sa_mask, SIGTERM);
           1 ->     sigaddset(&sa.sa_mask, SIGHUP);
           1 ->     sigaddset(&sa.sa_mask, SIGINT);
           1 ->     sigaddset(&sa.sa_mask, SIGPIPE);
           1 ->     sigaddset(&sa.sa_mask, SIGCHLD);
           1 ->     sigaddset(&sa.sa_mask, SIGALRM);
           1 ->     sigaddset(&sa.sa_mask, SIGUSR1);
           1 ->     sigaddset(&sa.sa_mask, SIGUSR2);
                
           1 ->     sa.sa_handler = sigsegv;
           1 ->     sigaction(SIGSEGV, &sa, NULL);
                
           1 ->     sa.sa_handler = sigbus;
           1 ->     sigaction(SIGBUS, &sa, NULL);
                
           1 ->     sa.sa_handler = sigterm;
           1 ->     sigaction(SIGTERM, &sa, NULL);
                
           1 ->     sa.sa_handler = sighup;
           1 ->     sigaction(SIGHUP, &sa, NULL);
                
           1 ->     sa.sa_handler = sigint;
           1 ->     sigaction(SIGINT, &sa, NULL);
                
           1 ->     sa.sa_handler = SIG_IGN;
           1 ->     sigaction(SIGPIPE, &sa, NULL);
                
           1 ->     sa.sa_handler = sigchld;
           1 ->     sigaction(SIGCHLD, &sa, NULL);
                
           1 ->     sa.sa_handler = sigalrm;
           1 ->     sigaction(SIGALRM, &sa, NULL);
                
           1 ->     sa.sa_handler = SIG_IGN;
           1 ->     sigaction(SIGUSR1, &sa, NULL);
                
           1 ->     sa.sa_handler = SIG_IGN;
           1 ->     sigaction(SIGUSR2, &sa, NULL);
                }
                
       ##### -> void sigsegv(int dummy)
                {
       ##### ->     time(&current_time);
       ##### ->     log_error_time();
       ##### ->     fprintf(stderr, "caught SIGSEGV, dumping core in %s\n", tempdir);
       ##### ->     fclose(stderr);
       ##### ->     chdir(tempdir);
       ##### ->     abort();
                }
                
                //extern sigjmp_buf env;
                extern int handle_sigbus;
                
       ##### -> void sigbus(int dummy)
                {
                    if (handle_sigbus) {
                /*         longjmp(env, dummy); */
                    }
       ##### ->     time(&current_time);
       ##### ->     log_error_time();
       ##### ->     fprintf(stderr, "caught SIGBUS, dumping core in %s\n", tempdir);
       ##### ->     fclose(stderr);
       ##### ->     chdir(tempdir);
       ##### ->     abort();
                }
                
       ##### -> void sigterm(int dummy)
                {
       ##### ->     sigterm_flag = 1;
                }
                
       ##### -> void sigterm_stage1_run(int server_s) /* lame duck mode */
                {
       ##### ->     time(&current_time);
       ##### ->     log_error_time();
       ##### ->     fputs("caught SIGTERM, starting shutdown\n", stderr);
       ##### ->     FD_CLR(server_s, &block_read_fdset);
       ##### ->     close(server_s);
       ##### ->     sigterm_flag = 2;
                }
                
       ##### -> void sigterm_stage2_run() /* 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();
       ##### ->     exit(0);
                }
                
                
       ##### -> void sighup(int dummy)
                {
       ##### ->     sighup_flag = 1;
                }
                
       ##### -> void sighup_run(void)
                {
       ##### ->     sighup_flag = 0;
       ##### ->     time(&current_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.
                     */
                
       ##### ->     FD_ZERO(&block_read_fdset);
       ##### ->     FD_ZERO(&block_write_fdset);
                    /* clear_common_env(); NEVER DO THIS */
       ##### ->     dump_mime();
       ##### ->     dump_passwd();
       ##### ->     dump_alias();
       ##### ->     free_requests();
                
       ##### ->     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(&current_time);
       ##### ->     log_error_time();
       ##### ->     fputs("caught SIGINT: shutting down\n", stderr);
       ##### ->     fclose(stderr);
       ##### ->     chdir(tempdir);
       ##### ->     exit(1);
                }
                
       ##### -> void sigchld(int dummy)
                {
       ##### ->     sigchld_flag = 1;
                }
                
       ##### -> void sigchld_run(void)
                {
                    int status;
                    pid_t pid;
                
       ##### ->     sigchld_flag = 0;
                
       ##### ->     while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
       ##### ->         if (verbose_cgi_logs) {
       ##### ->             time(&current_time);
       ##### ->             log_error_time();
       ##### ->             fprintf(stderr, "reaping child %d: status %d\n", (int) pid, status);
                        }
       ##### ->     return;
                }
                
       ##### -> void sigalrm(int dummy)
                {
       ##### ->     sigalrm_flag = 1;
                }
                
       ##### -> void sigalrm_run(void)
                {
       ##### ->     time(&current_time);
       ##### ->     log_error_time();
       ##### ->     fprintf(stderr, "%ld requests, %ld errors\n",
                            status.requests, status.errors);
       ##### ->     show_hash_stats();
       ##### ->     sigalrm_flag = 0;
                }


Top 10 Lines:

     Line      Count

       48          1

Execution Summary:

      110   Executable lines in this file
      110   Lines executed
   100.00   Percent of the file executed

        1   Total number of line executions
     0.01   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/read.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996,97 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1997,99 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba 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
                 */
                
         570 -> int read_header(request *`H req)
                {
                    int bytes, buf_bytes_left;
                    char *check, ?buffer;
                
         570 ->     check = req->client_stream + req->parse_pos;
         570 ->     buffer = req->client_stream;
         570 ->     bytes = req->client_stream_pos;
                
                #ifdef VERY_FASCIST_LOGGING
                    if (check < (buffer + bytes)) {
                        buffer[bytes] = '\0';
                        log_error_time();
                        fprintf(stderr, "%s:%d - Parsing headers (\"%s\")\n",
                                __FILE__, __LINE__, check);
                    }
                #endif
         570 ->     while (check < (buffer + bytes)) {
         570 ->         switch (req->status) {
                        case READ_HEADER:
         570 ->             if (*check == '\r') {
         570 ->                 req->status = ONE_CR;
         570 ->                 req->header_end = check;
         570 ->             } else if (*check == '\n') {
         570 ->                 req->status = ONE_LF;
         570 ->                 req->header_end = check;
                            }
         570 ->             break;
                
                        case ONE_CR:
         570 ->             if (*check == '\n')
         570 ->                 req->status = ONE_LF;
         570 ->             else if (*check != '\r')
         570 ->                 req->status = READ_HEADER;
         570 ->             break;
                
                        case ONE_LF:
                            /* if here, we've found the end (for sure) of a header */
         570 ->             if (*check == '\r') /* could be end o headers */
         570 ->                 req->status = TWO_CR;
         570 ->             else if (*check == '\n')
         570 ->                 req->status = BODY_READ;
                            else
         570 ->                 req->status = READ_HEADER;
         570 ->             break;
                
                        case TWO_CR:
         570 ->             if (*check == '\n')
         570 ->                 req->status = BODY_READ;
         570 ->             else if (*check != '\r')
         570 ->                 req->status = READ_HEADER;
                            break;
                
                        default:
                            break;
                        }
                
                #ifdef VERY_FASCIST_LOGGING
                        log_error_time();
                        fprintf(stderr, "status, check: %d, %d\n", req->status, *check);
                #endif
                
         570 ->         req->parse_pos++;       /* update parse position */
         570 ->         check++;
                
         570 ->         if (req->status == ONE_LF) {
         570 ->             *req->header_end = '\0';
                
                            /* terminate string that begins at req->header_line */
                
         570 ->             if (req->logline) {
         570 ->                 if (process_option_line(req) == 0) {
         570 ->                     return 0;
                                }
                            } else {
         570 ->                 if (process_logline(req) == 0)
         570 ->                     return 0;
         570 ->                 if (req->simple)
         570 ->                     return process_header_end(req);
                            }
                            /* set header_line to point to beginning of new header */
         570 ->             req->header_line = check;
         570 ->         } 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
         570 ->             int retval = process_header_end(req);
                #endif
                            /* process_header_end inits non-POST cgi's */
                
         570 ->             if (retval && req->method == M_POST) {
                                /* for body_{read,write}, set header_line to start of data,
                                   and header_end to end of data */
         570 ->                 req->header_line = check;
         570 ->                 req->header_end =
         570 ->                     req->client_stream + req->client_stream_pos;
                
         570 ->                 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.
                
                                 */
                
         570 ->                 if (req->content_length) {
                                    int content_length;
                
         570 ->                     content_length = boa_atoi(req->content_length);
                                    /* Is a content-length of 0 legal? */
         570 ->                     if (content_length <= 0) {
         570 ->                         log_error_time();
         570 ->                         fprintf(stderr, "Invalid Content-Length [%s] on POST!\n",
                                                req->content_length);
         570 ->                         send_r_bad_request(req);
         570 ->                         return 0;
                                    }
         570 ->                     if (single_post_limit && content_length > single_post_limit) {
         570 ->                         log_error_time();
         570 ->                         fprintf(stderr, "Content-Length [%d] > SinglePostLimit [%d] on POST!\n",
                                                content_length, single_post_limit);
         570 ->                         send_r_bad_request(req);
         570 ->                         return 0;
                                    }
         570 ->                     req->filesize = content_length;
         570 ->                     req->filepos = 0;
         570 ->                     if (req->header_end - req->header_line > req->filesize) {
         570 ->                         req->header_end = req->header_line + req->filesize;
                                    }
                                } else {
         570 ->                     log_error_time();
         570 ->                     fprintf(stderr, "Unknown Content-Length POST!\n");
         570 ->                     send_r_bad_request(req);
         570 ->                     return 0;
                                }
                            }                   /* either process_header_end failed or req->method != POST */
         570 ->             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
                
         570 ->     if (req->status < BODY_READ) {
                        /* only reached if request is split across more than one packet */
                
         570 ->         buf_bytes_left = CLIENT_STREAM_SIZE - req->client_stream_pos;
         570 ->         if (buf_bytes_left < 1) {
         570 ->             log_error_time();
         570 ->             fputs("buffer overrun - read.c, read_header - closing\n",
                                  stderr);
         570 ->             req->status = DEAD;
         570 ->             return 0;
                        }
                
         570 ->         bytes = read(req->fd, buffer + req->client_stream_pos, buf_bytes_left);
                
         570 ->         if (bytes < 0) {
         570 ->             if (errno == EINTR)
         570 ->                 return 1;
         570 ->             if (errno == EAGAIN || errno == EWOULDBLOCK) /* request blocked */
         570 ->                 return -1;
                            /*
                               else if (errno == EBADF || errno == EPIPE) {
                
                               req->status = DEAD;
                               return 0;
                               */
         570 ->             log_error_doc(req);
         570 ->             perror("header read");            /* don't need to save errno because log_error_doc does */
         570 ->             return 0;
         570 ->         } else if (bytes == 0) {
                            /*
                               log_error_time();
                               fputs("unexpected end of headers\n", stderr);
                             */
         570 ->             return 0;
                        }
                
                        /* bytes is positive */
         570 ->         req->client_stream_pos += bytes;
                
                #ifdef FASCIST_LOGGING1
                        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
                #endif
                
         570 ->         return 1;
                    }
         570 ->     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, 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) {
                            /*
                               req->status = BODY_WRITE;
                               return 1;
                             */
       ##### ->             return -1;
                        } else {
       ##### ->             boa_perror(req, "read body");
       ##### ->             return 0;
                        }
       ##### ->     } else if (bytes_read == 0) {
                        /* this is an error.  premature end of body! */
       ##### ->         log_error_time();
       ##### ->         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 = 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 *`H req)
                {
       ##### ->     int bytes_written, 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 == -1) {
       ##### ->         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;
                        }
                    }
                #ifdef FASCIST_LOGGING
                    log_error_time();
                    fprintf(stderr, "%s:%d - wrote %d bytes. %ld of %ld\n",
                            __FILE__, __LINE__,
                            bytes_written, req->filepos, req->filesize);
                #endif
                
       ##### ->     req->filepos += bytes_written;
       ##### ->     req->header_line = req->header_line + bytes_written;
                
       ##### ->     return 1;                   /* more to do */
                }


Top 10 Lines:

     Line      Count

       39        570

Execution Summary:

      135   Executable lines in this file
      135   Lines executed
   100.00   Percent of the file executed

      570   Total number of line executions
     4.22   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/mmap_cache.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1999 Larry Doolittle <ldoolitt@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                
                int mmap_list_entries_used = 0;
                int mmap_list_total_requests = 0;
                int mmap_list_hash_bounces = 0;
                
                /* define local table variable */
                static struct mmap_entry mmap_list[MMAP_LIST_SIZE];
                
         250 -> struct mmap_entry *find_mmap(int data_fd, struct stat *s)
                {
                    const char ?@nozeroterm m;
                    int i, start;
         250 ->     mmap_list_total_requests++;
         250 ->     i = start = MMAP_LIST_HASH(s->st_dev, s->st_ino, s->st_size);
         250 ->     for (; mmap_list[i].use_count;) {
         250 ->         if (mmap_list[i].dev == s->st_dev &&
                            mmap_list[i].ino == s->st_ino &&
                            mmap_list[i].len == s->st_size) {
         250 ->             mmap_list[i].use_count++;
                #ifdef DEBUG
                            fprintf(stderr,
                                    "Old mmap_list entry %d use_count now %d (hash was %d)\n",
                                    i, mmap_list[i].use_count, start);
                #endif
         250 ->             return mmap_list + i;
                        }
         250 ->         mmap_list_hash_bounces++;
         250 ->         i = MMAP_LIST_NEXT(i);
                        /* Shouldn't happen, because of size limit enforcement below */
         250 ->         if (i == start)
         250 ->             return NULL;
                    }
                    /* 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.
                     */
                
                    /* Enforce a size limit here */
         250 ->     if (mmap_list_entries_used > MMAP_LIST_USE_MAX)
         250 ->         return NULL;
                
         250 ->     m = mmap(0, s->st_size, PROT_READ, MAP_OPTIONS, data_fd, 0);
                
         250 ->     if ((int) ((const char*@nozeroterm) m) == -1) {
                        /* boa_perror(req,"mmap"); */
         250 ->         return NULL;
                    }
                #ifdef DEBUG
                    fprintf(stderr, "New mmap_list entry %d (hash was %d)\n", i, h);
                #endif
         250 ->     mmap_list_entries_used++;
         250 ->     mmap_list[i].dev = s->st_dev;
         250 ->     mmap_list[i].ino = s->st_ino;
         250 ->     mmap_list[i].len = s->st_size;
         250 ->     mmap_list[i].mmap = m;
         250 ->     mmap_list[i].use_count = 1;
         250 ->     return mmap_list + i;
                }
                
         250 -> void release_mmap(struct mmap_entry *e)
                {
         250 ->     if (!e)
         250 ->         return;
         250 ->     if (!e->use_count) {
                #ifdef DEBUG
                        fprintf(stderr, "mmap_list(%p)->use_count already zero!\n", e);
                #endif
         250 ->         return;
                    }
         250 ->     if (!--(e->use_count)) {
         250 ->         munmap(e->mmap, e->len);
         250 ->         mmap_list_entries_used--;
                    }
                }
                
       ##### -> 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;
                }
                
                /*
                 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<tests; i++) release_mmap(mlist[i]);
                 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);
                
                */


Top 10 Lines:

     Line      Count

       32        250
       86        250

Execution Summary:

       42   Executable lines in this file
       42   Lines executed
   100.00   Percent of the file executed

      500   Total number of line executions
    11.90   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/select.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996 Charles F. Randall <crandall@goldsys.com>
                 *  Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996-2002 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                
                static void fdset_update(void);
                fd_set block_read_fdset;
                fd_set block_write_fdset;
                static struct timeval req_timeout;     /* timeval for select */
                
           1 -> void select_loop(int server_s)
                {
           1 ->     FD_ZERO(&block_read_fdset);
           1 ->     FD_ZERO(&block_write_fdset);
                    /* set server_s and req_timeout */
           1 ->     req_timeout.tv_sec = (ka_timeout ? ka_timeout : REQUEST_TIMEOUT);
           1 ->     req_timeout.tv_usec = 0l;   /* reset timeout */
                
                    /* preset max_fd */
           1 ->     max_fd = -1;
                
                    while (1) {
           1 ->         if (sighup_flag)
           1 ->             sighup_run();
           1 ->         if (sigchld_flag)
           1 ->             sigchld_run();
           1 ->         if (sigalrm_flag)
           1 ->             sigalrm_run();
                
           1 ->         if (sigterm_flag) {
           1 ->             if (sigterm_flag == 1)
           1 ->                 sigterm_stage1_run(server_s);
           1 ->             if (sigterm_flag == 2 && !request_ready && !request_block) {
           1 ->                 sigterm_stage2_run();
                            }
                        }
                
                        /* reset max_fd */
           1 ->         max_fd = -1;
                
           1 ->         if (request_block)
                            /* move selected req's from request_block to request_ready */
           1 ->             fdset_update();
                
                        /* any blocked req's move from request_ready to request_block */
           1 ->         process_requests(server_s);
                
           1 ->         if (!sigterm_flag && total_connections < (max_connections - 10)) {
           1 ->             BOA_FD_SET(server_s, &block_read_fdset); /* server always set */
                        }
                
           1 ->         req_timeout.tv_sec = (request_ready ? 0 :
                                              (ka_timeout ? ka_timeout : REQUEST_TIMEOUT));
           1 ->         req_timeout.tv_usec = 0l;   /* reset timeout */
                
           1 ->         if (select(max_fd + 1, &block_read_fdset,
                                   &block_write_fdset, NULL,
                                   (request_ready || request_block ? &req_timeout : NULL)) == -1) {
                            /* what is the appropriate thing to do here on EBADF */
           1 ->             if (errno == EINTR)
           1 ->                 continue;   /* while(1) */
           1 ->             else if (errno != EBADF) {
           1 ->                 DIE("select");
                            }
                        }
                
           1 ->         time(&current_time);
           1 ->         if (FD_ISSET(server_s, &block_read_fdset))
           1 ->             pending_requests = 1;
                    }
                }
                
                /*
                 * 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
                 */
                
         300 -> static void fdset_update(void)
                {
                    request *current, *next;
                
         300 ->     for(current = request_block;current;current = next) {
         300 ->         time_t time_since = current_time - current->time_last;
         300 ->         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... */
         300 ->         if (current->kacount < ka_max && /* we *are* in a keepalive */
                            (time_since >= ka_timeout) && /* ka timeout */
                            !current->logline)  /* haven't read anything yet */
         300 ->             current->status = DEAD; /* connection keepalive timed out */
         300 ->         else if (time_since > REQUEST_TIMEOUT) {
         300 ->             log_error_doc(current);
         300 ->             fputs("connection timed out\n", stderr);
         300 ->             current->status = DEAD;
                        }
         300 ->         if (current->buffer_end && current->status < DEAD) {
         300 ->             if (FD_ISSET(current->fd, &block_write_fdset))
         300 ->                 ready_request(current);
                            else {
         300 ->                 BOA_FD_SET(current->fd, &block_write_fdset);
                            }
                        } else {
         300 ->             switch (current->status) {
                            case WRITE:
                            case PIPE_WRITE:
         300 ->                 if (FD_ISSET(current->fd, &block_write_fdset))
         300 ->                     ready_request(current);
                                else {
         300 ->                     BOA_FD_SET(current->fd, &block_write_fdset);
                                }
         300 ->                 break;
                            case BODY_WRITE:
         300 ->                 if (FD_ISSET(current->post_data_fd, &block_write_fdset))
         300 ->                     ready_request(current);
                                else {
         300 ->                     BOA_FD_SET(current->post_data_fd, &block_write_fdset);
                                }
         300 ->                 break;
                            case PIPE_READ:
         300 ->                 if (FD_ISSET(current->data_fd, &block_read_fdset))
         300 ->                     ready_request(current);
                                else {
         300 ->                     BOA_FD_SET(current->data_fd, &block_read_fdset);
                                }
         300 ->                 break;
                            case DONE:
         300 ->                 if (FD_ISSET(current->fd, &block_write_fdset))
         300 ->                     ready_request(current);
                                else {
         300 ->                     BOA_FD_SET(current->fd, &block_write_fdset);
                                }
         300 ->                 break;
                            case DEAD:
         300 ->                 ready_request(current);
         300 ->                 break;
                            default:
         300 ->                 if (FD_ISSET(current->fd, &block_read_fdset))
         300 ->                     ready_request(current);
                                else {
         300 ->                     BOA_FD_SET(current->fd, &block_read_fdset);
                                }
                                break;
                            }
                        }
         300 ->         current = next;
                    }
                }
                


Top 10 Lines:

     Line      Count

      111        300
       33          1

Execution Summary:

       70   Executable lines in this file
       70   Lines executed
   100.00   Percent of the file executed

      301   Total number of line executions
     4.30   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/request.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996,97 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996-2002 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                #include <stddef.h> /* for offsetof */
                
                int total_connections;
                struct status status;
                
                static int sockbufsize = SOCKETBUF_SIZE;
                
                /* function prototypes located in this file only */
                static void free_request(request ** list_head_addr, request *`H req);
                
                /*
                 * 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
                 */
                
         280 -> request *new_request(void)
                {
                    request *req;
                
         280 ->     if (request_free) {
         280 ->         req = request_free;     /* first on free list */
         280 ->         dequeue(&request_free, request_free); /* dequeue the head */
                    } else {
         280 ->         req = (request *) calloc(1, sizeof (request));
         280 ->         if (!req) {
         280 ->             log_error_time();
         280 ->             perror("malloc for new request");
         280 ->             return NULL;
                        }
                    }
                
                    // memset(req, 0, offsetof(request, buffer) + 1);
         280 ->     req->fd = 0;
         280 ->     req->status = 0;
         280 ->     req->time_last = 0;
         280 ->     req->pathname = NULL;
         280 ->     req->simple = 0;
         280 ->     req->keepalive = 0;
         280 ->     req->kacount = 0;
         280 ->     req->data_fd = 0;
         280 ->     req->filesize = 0;
         280 ->     req->filepos = 0;
         280 ->     req->data_mem = NULL;
         280 ->     req->method = 0;
         280 ->     req->logline = NULL;
         280 ->     req->header_line = NULL;
         280 ->     req->header_end = NULL;
         280 ->     req->parse_pos = 0;
         280 ->     req->client_stream_pos = 0;
         280 ->     req->buffer_start = 0;
         280 ->     req->buffer_end = 0;
         280 ->     req->http_version = NULL;
         280 ->     req->response_status = 0;
         280 ->     req->if_modified_since = NULL;
         280 ->     req->last_modified = 0;
         280 ->     bzero(req->local_ip_addr, (NI_MAXHOST - 1));
         280 ->     req->remote_port = 0;
         280 ->     bzero(req->remote_ip_addr, (NI_MAXHOST - 1));
         280 ->     req->is_cgi = 0;
         280 ->     req->cgi_status = 0;
         280 ->     req->cgi_env_index = 0;
         280 ->     req->header_user_agent = NULL;
         280 ->     req->header_referer = NULL;
         280 ->     req->post_data_fd = 0;
         280 ->     req->path_info = NULL;
         280 ->     req->path_translated = NULL;
         280 ->     req->script_name = NULL;
         280 ->     req->query_string = NULL;
         280 ->     req->content_type = NULL;
         280 ->     req->content_length = NULL;
         280 ->     req->mmap_entry_var = NULL;
         280 ->     req->next = NULL;
         280 ->     req->prev = NULL;
                
         280 ->     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;.
                 */
                
          40 -> void get_request(int server_s)
                {
                    int fd;                     /* socket */
                    struct SOCKADDR remote_addr; /* address */
                    struct SOCKADDR salocal;
          40 ->     int remote_addrlen = sizeof (struct SOCKADDR);
                    request *conn;              /* connection */
                    size_t len;
                    static int system_bufsize = 0; /* Default size of SNDBUF given by system */
                
          40 ->     remote_addr.S_FAMILY = 0xdead;
          40 ->     fd = accept(server_s, &remote_addr,
                                &remote_addrlen);
                
          40 ->     if (fd == -1) {
          40 ->         if (errno != EAGAIN && errno != EWOULDBLOCK)
                            /* abnormal error */
          40 ->             WARN("accept");
                        else
                            /* no requests */
          40 ->             pending_requests = 0;
          40 ->         return;
                    }
          40 ->     if (fd >= FD_SETSIZE) {
          40 ->         WARN("Got fd >= FD_SETSIZE.");
          40 ->         close(fd);
          40 -> 	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 <ldoolitt@boa.org>
                     */
                #define HEX(x) (((x)>9)?(('a'-10)+(x)):('0'+(x)))
                    if (remote_addr.sin_family != AF_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++ = HEX((bogus->sa_data[i] >> 4) & 0x0f);
                            *ap++ = 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 <paul@mu.org> */
                #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
                
          40 ->     len = sizeof(salocal);
                
          40 ->     if (getsockname(fd, &salocal, &len) != 0) {
          40 ->         WARN("getsockname");
          40 ->         close(fd);
          40 ->         return;
                    }
                
          40 ->     conn = new_request();
          40 ->     if (!conn) {
          40 ->         close(fd);
          40 ->         return;
                    }
          40 ->     conn->fd = fd;
          40 ->     conn->status = READ_HEADER;
          40 ->     conn->header_line = conn->client_stream;
          40 ->     conn->time_last = current_time;
          40 ->     conn->kacount = ka_max;
                
          40 ->     ascii_sockaddr(&salocal, conn->local_ip_addr, NI_MAXHOST);
                
                    /* nonblocking socket */
          40 ->     if (set_nonblock_fd(conn->fd) == -1)
          40 ->         WARN("fcntl: unable to set new socket to non-block");
                
                    /* set close on exec to true */
          40 ->     if (fcntl(conn->fd, F_SETFD, 1) == -1)
          40 ->         WARN("fctnl: unable to set close-on-exec for new socket");
                
                    /* 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.
                     */
          40 ->     if (system_bufsize == 0) {
          40 ->         len = sizeof (system_bufsize);
          40 ->         if (getsockopt
                            (conn->fd, SOL_SOCKET, SO_SNDBUF, &system_bufsize, &len) == 0
                            && len == sizeof (system_bufsize)) {
                            /*
                               fprintf(stderr, "%sgetsockopt reports SNDBUF %d\n",
                               get_commonlog_time(), system_bufsize);
                             */
                            ;
                        } else {
          40 ->             WARN("getsockopt(SNDBUF)");
          40 ->             system_bufsize = 1;
                        }
                    }
          40 ->     if (system_bufsize < sockbufsize) {
          40 ->         if (setsockopt
                            (conn->fd, SOL_SOCKET, SO_SNDBUF, (void *) &sockbufsize,
                             sizeof (sockbufsize)) == -1) {
          40 ->             WARN("setsockopt: unable to set socket buffer size");
                #ifdef DIE_ON_ERROR_TUNING_SNDBUF
                            exit(errno);
                #endif
                        }
                    }
                
                    /* for log file and possible use by CGI programs */
          40 ->     ascii_sockaddr(&remote_addr, conn->remote_ip_addr, NI_MAXHOST);
                
                    /* for possible use by CGI programs */
          40 ->     conn->remote_port = net_port(&remote_addr);
                
          40 ->     status.requests++;
                
                #ifdef USE_TCPNODELAY
                    /* Thanks to Jef Poskanzer <jef@acme.com> 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
                
                #ifndef NO_RATE_LIMIT
          40 ->     if (conn->fd > max_connections) {
          40 ->         send_r_service_unavailable(conn);
          40 ->         conn->status = DONE;
          40 ->         pending_requests = 0;
                    }
                #endif                          /* NO_RATE_LIMIT */
                
          40 ->     total_connections++;
          40 ->     enqueue(&request_ready, conn);
                }
                
                
                /*
                 * Name: free_request
                 *
                 * Description: Deallocates memory for a finished request and closes
                 * down socket.
                 */
                
         280 -> static void free_request(request ** list_head_addr, request *`H req)
                {
                    int i;
                    /* free_request should *never* get called by anything but
                       process_requests */
                
         280 ->     if (req->buffer_end && req->status != DEAD) {
         280 ->         req->status = DONE;
         280 ->         return;
                    }
                    /* put request on the free list */
         280 ->     dequeue(list_head_addr, req); /* dequeue from ready or block list */
                
         280 ->     if (req->logline)           /* access log */
         280 ->         log_access(req);
                
         280 ->     if (req->mmap_entry_var)
         280 ->         release_mmap(req->mmap_entry_var);
         280 ->     else if (req->data_mem)
         280 ->         munmap(req->data_mem, req->filesize);
                
         280 ->     if (req->data_fd)
         280 ->         close(req->data_fd);
                
         280 ->     if (req->post_data_fd)
         280 ->         close(req->post_data_fd);
                
         280 ->     if (req->response_status >= 400)
         280 ->         status.errors++;
                
         280 ->     for (i = COMMON_CGI_COUNT; i < req->cgi_env_index; ++i) {
         280 ->         if (req->cgi_env[i]) {
         280 ->             free(req->cgi_env[i]);
                        } else {
         280 ->             log_error_time();
         280 ->             fprintf(stderr, "Warning: CGI Environment contains NULL value" \
                                    "(index %d of %d).\n", i, req->cgi_env_index);
                        }
                    }
                
         280 ->     if (req->pathname)
         280 ->         free(req->pathname);
         280 ->     if (req->path_info)
         280 ->         free(req->path_info);
         280 ->     if (req->path_translated)
         280 ->         free(req->path_translated);
         280 ->     if (req->script_name)
         280 ->         free(req->script_name);
                
         280 ->     if ((req->keepalive == KA_ACTIVE) &&
                        (req->response_status < 500) && req->kacount > 0) {
                        int bytes_to_move;
                
         280 ->         request *conn = new_request();
         280 ->         if (!conn) {
                            /* errors already reported */
         280 ->             enqueue(&request_free, req);
         280 ->             close(req->fd);
         280 ->             total_connections--;
         280 ->             return;
                        }
         280 ->         conn->fd = req->fd;
         280 ->         conn->status = READ_HEADER;
         280 ->         conn->header_line = conn->client_stream;
         280 ->         conn->kacount = req->kacount - 1;
                
                        /* close enough and we avoid a call to time(NULL) */
         280 ->         conn->time_last = req->time_last;
                
                        /* for log file and possible use by CGI programs */
         280 ->         memcpy(conn->remote_ip_addr, req->remote_ip_addr, numelts((char ?@nozeroterm)req->remote_ip_addr));
         280 ->         memcpy(conn->local_ip_addr, req->local_ip_addr, numelts((char ?@nozeroterm)req->local_ip_addr));
                
                        /* for possible use by CGI programs */
         280 ->         conn->remote_port = req->remote_port;
                
         280 ->         status.requests++;
                
                        /* we haven't parsed beyond req->parse_pos, so... */
         280 ->         bytes_to_move = req->client_stream_pos - req->parse_pos;
                
         280 ->         if (bytes_to_move) {
         280 ->             memcpy(conn->client_stream,
                                   req->client_stream + req->parse_pos, bytes_to_move);
         280 ->             conn->client_stream_pos = bytes_to_move;
                        }
         280 ->         enqueue(&request_block, conn);
         280 ->         BOA_FD_SET(conn->fd, &block_read_fdset);
                
         280 ->         enqueue(&request_free, req);
         280 ->         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 compatable is
                     just plain wrong
                     */
                
         280 ->     if (req->method == M_POST) {
                        char buf[32768];
         280 ->         read(req->fd, buf, 32768);
                    }
         280 ->     close(req->fd);
         280 ->     total_connections--;
                
         280 ->     enqueue(&request_free, req);
                
         280 ->     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 procesing.
                 */
                
        2141 -> void process_requests(int server_s)
                {
        2141 ->     int retval = 0;
                    request *current, *trailer;
                
        2141 ->     if (pending_requests) {
        2141 ->         get_request(server_s);
                #ifdef ORIGINAL_BEHAVIOR
                        pending_requests = 0;
                #endif
                    }
                
        2141 ->     current = request_ready;
                
        2141 ->     while (current) {
        2141 ->         time(&current_time);
        2141 ->         if (current->buffer_end && /* there is data in the buffer */
                            current->status != DEAD && current->status != DONE) {
        2141 ->             retval = req_flush(current);
                            /*
                             * retval can be -2=error, -1=blocked, or bytes left
                             */
        2141 ->             if (retval == -2) { /* error */
        2141 ->                 current->status = DEAD;
        2141 ->                 retval = 0;
        2141 ->             } 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 */
                
        2141 ->                 retval = 1;
                            }
                        } else {
        2141 ->             switch (current->status) {
                            case READ_HEADER:
                            case ONE_CR:
                            case ONE_LF:
                            case TWO_CR:
        2141 ->                 retval = read_header(current);
        2141 ->                 break;
                            case BODY_READ:
        2141 ->                 retval = read_body(current);
        2141 ->                 break;
                            case BODY_WRITE:
        2141 ->                 retval = write_body(current);
        2141 ->                 break;
                            case WRITE:
        2141 ->                 retval = process_get(current);
        2141 ->                 break;
                            case PIPE_READ:
        2141 ->                 retval = read_from_pipe(current);
        2141 ->                 break;
                            case PIPE_WRITE:
        2141 ->                 retval = write_from_pipe(current);
        2141 ->                 break;
                            case DONE:
                                /* a non-status that will terminate the request */
        2141 ->                 retval = req_flush(current);
                                /*
                                 * retval can be -2=error, -1=blocked, or bytes left
                                 */
        2141 ->                 if (retval == -2) { /* error */
        2141 ->                     current->status = DEAD;
        2141 ->                     retval = 0;
        2141 ->                 } else if (retval > 0) {
        2141 ->                     retval = 1;
                                }
        2141 ->                 break;
                            case DEAD:
        2141 ->                 retval = 0;
        2141 ->                 current->buffer_end = 0;
        2141 ->                 SQUASH_KA(current);
        2141 ->                 break;
                            default:
        2141 ->                 retval = 0;
        2141 ->                 fprintf(stderr, "Unknown status (%d), "
                                        "closing!\n", current->status);
        2141 ->                 current->status = DEAD;
                                break;
                            }
                
                        }
                
        2141 ->         if (sigterm_flag)
        2141 ->             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!
                         */
        2141 ->         if (pending_requests)
        2141 ->             get_request(server_s);
                
        2141 ->         switch (retval) {
                        case -1:               /* request blocked */
        2141 ->             trailer = current;
        2141 ->             current = current->next;
        2141 ->             block_request(trailer);
        2141 ->             break;
                        case 0:                /* request complete */
        2141 ->             current->time_last = current_time;
        2141 ->             trailer = current;
        2141 ->             current = current->next;
        2141 ->             free_request(&request_ready, trailer);
        2141 ->             break;
                        case 1:                /* more to do */
        2141 ->             current->time_last = current_time;
        2141 ->             current = current->next;
        2141 ->             break;
                        default:
        2141 ->             log_error_time();
        2141 ->             fprintf(stderr, "Unknown retval in process.c - "
                                    "Status: %d, retval: %d\n", current->status, retval);
        2141 ->             current = current->next;
        2141 ->             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.
                 */
                
         270 -> int process_logline(request *`H req)
                {
                    char *stop, *stop2;
                    static char SIMPLE_HTTP_VERSION[]@zeroterm = "HTTP/0.9";
                
         270 ->     req->logline = req->client_stream;
         270 ->     if (!memcmp(req->logline, "GET ", 4))
         270 ->         req->method = M_GET;
         270 ->     else if (!memcmp(req->logline, "HEAD ", 5))
                        /* head is just get w/no body */
         270 ->         req->method = M_HEAD;
         270 ->     else if (!memcmp(req->logline, "POST ", 5))
         270 ->         req->method = M_POST;
                    else {
         270 ->         log_error_time();
         270 ->         fprintf(stderr, "malformed request: \"%s\"\n", req->logline);
         270 ->         send_r_not_implemented(req);
         270 ->         return 0;
                    }
                
         270 ->     req->http_version = SIMPLE_HTTP_VERSION;
         270 ->     req->simple = 1;
                
                    /* Guaranteed to find ' ' since we matched a method above */
         270 ->     stop = req->logline + 3;
         270 ->     if (*stop != ' ')
         270 ->         ++stop;
                
                    /* scan to start of non-whitespace */
         270 ->     while (*(++stop) == ' ');
                
         270 ->     stop2 = stop;
                
                    /* scan to end of non-whitespace */
         270 ->     while (*stop2 != '\0' && *stop2 != ' ')
         270 ->         ++stop2;
                
         270 ->     if (stop2 - stop > MAX_HEADER_LENGTH) {
         270 ->         log_error_time();
         270 ->         fprintf(stderr, "URI too long %d: \"%s\"\n", MAX_HEADER_LENGTH,
                                req->logline);
         270 ->         send_r_bad_request(req);
         270 ->         return 0;
                    }
         270 ->     memcpy(req->request_uri, stop, stop2 - stop);
         270 ->     req->request_uri[stop2 - stop] = '\0';
                
         270 ->     if (*stop2 == ' ') {
                        /* if found, we should get an HTTP/x.x */
                        unsigned int p1, p2;
                
                        /* scan to end of whitespace */
         270 ->         ++stop2;
         270 ->         while (*stop2 == ' ' && *stop2 != '\0')
         270 ->             ++stop2;
                
                        /* scan in HTTP/major.minor */
         270 ->         if (sscanf(stop2, "HTTP/%u.%u", &p1, &p2) == 2) {
                            /* HTTP/{0.9,1.0,1.1} */
         270 ->             if (p1 == 1 && (p2 == 0 || p2 == 1)) {
         270 ->                 req->http_version = stop2;
         270 ->                 req->simple = 0;
         270 ->             } else if (p1 > 1 || (p1 != 0 && p2 > 1)) {
                                goto BAD_VERSION;
                            }
                        } else {
                            goto BAD_VERSION;
                        }
                    }
                
         270 ->     if (req->method == M_HEAD && req->simple) {
         270 ->         send_r_bad_request(req);
         270 ->         return 0;
                    }
         270 ->     req->cgi_env_index = COMMON_CGI_COUNT;
                
         270 ->     return 1;
                
                BAD_VERSION:
         270 ->     log_error_time();
         270 ->     fprintf(stderr, "bogus HTTP version: \"%s\"\n", stop2);
         270 ->     send_r_bad_request(req);
         270 ->     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
                 */
                
         270 -> int process_header_end(request *`H req)
                {
         270 ->     if (!req->logline) {
         270 ->         send_r_error(req);
         270 ->         return 0;
                    }
                
                    /* Percent-decode request */
         270 ->     if (unescape_uri(req->request_uri, &(req->query_string)) == 0) {
         270 ->         log_error_doc(req);
         270 ->         fputs("Problem unescaping uri\n", stderr);
         270 ->         send_r_bad_request(req);
         270 ->         return 0;
                    }
                
                    /* clean pathname */
         270 ->     clean_pathname(req->request_uri);
                
         270 ->     if (req->request_uri[0] != '/') {
         270 ->         send_r_bad_request(req);
         270 ->         return 0;
                    }
                
         270 ->     if (translate_uri(req) == 0) { /* unescape, parse uri */
         270 ->         SQUASH_KA(req);
         270 ->         return 0;               /* failure, close down */
                    }
                
         270 ->     if (req->method == M_POST) {
         270 ->         req->post_data_fd = create_temporary_file(1, NULL, 0);
         270 ->         if (req->post_data_fd == 0)
         270 ->             return(0);
         270 ->         return(1); /* success */
                    }
                
         270 ->     if (req->is_cgi) {
         270 ->         return init_cgi(req);
                    }
                
         270 ->     req->status = WRITE;
         270 ->     return init_get(req);       /* get and head */
                }
                
                /*
                 * Name: process_option_line
                 *
                 * Description: Parses the contents of req->header_line and takes
                 * appropriate action.
                 */
                
        1330 -> int process_option_line(request * req)
                {
        1330 ->     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
                
        1330 ->     value = mstrchr(line, ':');
        1330 ->     if (value == NULL)
        1330 ->         return 0;
        1330 ->     *value++ = '\0';            /* overwrite the : */
        1330 ->     to_upper(line);             /* header types are case-insensitive */
        1330 ->     while ((c = *value) && (c == ' ' || c == '\t'))
        1330 ->         value++;
                
        1330 ->     if (!my_memcmp(line, "IF_MODIFIED_SINCE", 18) && !req->if_modified_since)
        1330 ->         req->if_modified_since = value;
                
        1330 ->     else if (!my_memcmp(line, "CONTENT_TYPE", 13) && !req->content_type)
        1330 ->         req->content_type = value;
                
        1330 ->     else if (!my_memcmp(line, "CONTENT_LENGTH", 15) && !req->content_length)
        1330 ->         req->content_length = value;
                
        1330 ->     else if (!my_memcmp(line, "CONNECTION", 11) &&
                             ka_max && req->keepalive != KA_STOPPED) {
        1330 ->         req->keepalive = (!strncasecmp(value, "Keep-Alive", 10) ?
                                          KA_ACTIVE : KA_STOPPED);
                    }
                    /* #ifdef ACCEPT_ON */
        1330 ->     else if (!my_memcmp(line, "ACCEPT", 7))
        1330 ->         add_accept_header(req, value);
                    /* #endif */
                
                    /* Need agent and referer for logs */
        1330 ->     else if (!my_memcmp(line, "REFERER", 8)) {
        1330 ->         req->header_referer = value;
        1330 ->         if (!add_cgi_env(req, "REFERER", value, 1))
        1330 ->             return 0;
        1330 ->     } else if (!my_memcmp(line, "USER_AGENT", 11)) {
        1330 ->         req->header_user_agent = value;
        1330 ->         if (!add_cgi_env(req, "USER_AGENT", value, 1))
        1330 ->             return 0;
                    } else {
        1330 ->         if (!add_cgi_env(req, line, value, 1))
        1330 ->             return 0;
                    }
        1330 ->     return 1;
                }
                
                /*
                 * 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
                 */
                
         270 -> void add_accept_header(request * req, char *mime_type)
                {
                #ifdef ACCEPT_ON
                    int l = strlen(req->accept);
                    int l2 = strlen(mime_type);
                
                    if ((l + l2 + 2) >= MAX_HEADER_LENGTH)
                        return;
                
                    if (req->accept[0] == '\0')
                        strcpy(req->accept, mime_type);
                    else {
                        req->accept[l] = ',';
                        req->accept[l + 1] = ' ';
                        memcpy(req->accept + l + 2, mime_type, l2 + 1);
                        /* the +1 is for the '\0' */
                        /*
                           sprintf(req->accept + l, ", %s", mime_type);
                         */
                    }
                #endif
         270 -> }
                
       ##### -> void free_requests(void)
                {
                    request *ptr, *next;
                
       ##### ->     ptr = request_free;
       ##### ->     while (ptr != NULL) {
       ##### ->         next = ptr->next;
       ##### ->         free(ptr);
       ##### ->         ptr = next;
                    }
       ##### ->     request_free = NULL;
                }


Top 10 Lines:

     Line      Count

      422       2141
      695       1330
       44        280
      275        280
      552        270
      645        270
      756        270
      113         40

Execution Summary:

      332   Executable lines in this file
      332   Lines executed
   100.00   Percent of the file executed

     4881   Total number of line executions
    14.70   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/hash.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1997 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                #include "parse.h"
                
                /*
                 * 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];
                
                #ifdef WANT_ICKY_HASH
                static unsigned four_char_hash(char *buf);
                #define boa_hash four_char_hash
                #else
                #ifdef WANT_SDBM_HASH
                static unsigned sdbm_hash(char *str);
                #define boa_hash sdbm_hash
                #else
                static unsigned djb2_hash(char *str);
                #define boa_hash djb2_hash
                #endif
                #endif
                
                #ifdef WANT_ICKY_HASH
                static unsigned four_char_hash(char *buf)
                {
                    unsigned int hash = (buf[0] +
                                     (buf[1] ? buf[1] : 241 +
                                     (buf[2] ? buf[2] : 251 +
                                      (buf[3] ? buf[3] : 257))));
                #ifdef DEBUG_HASH
                    log_error_time();
                    fprintf(stderr, "four_char_hash(%s) = %u\n", buf, hash);
                #endif
                    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
                #define MAX_HASH_LENGTH 4
                #ifdef WANT_SDBM_HASH
                static unsigned sdbm_hash(char *str)
                {
                    unsigned hash = 0;
                    int c;
                    short count = MAX_HASH_LENGTH;
                
                #ifdef DEBUG_HASH
                    log_error_time();
                    fprintf(stderr, "sdbm_hash(%s) = ", str);
                #endif
                
                    while ((c = *str++) && count--)
                        hash = c + (hash << 6) + (hash << 16) - hash;
                
                #ifdef DEBUG_HASH
                    fprintf(stderr, "%u\n", hash);
                #endif
                    return hash;
                }
                #else
                
         702 -> static unsigned djb2_hash(char *str)
                {
         702 ->     unsigned hash = 5381;
                    int c;
         702 ->     short count = MAX_HASH_LENGTH;
                
                #ifdef DEBUG_HASH
                    log_error_time();
                    fprintf(stderr, "djb2_hash(%s) = ", str);
                #endif
         702 ->     char ?str2 = str;
         702 ->     while ((c = *(str2++)) && count--)
         702 ->         hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
                
                #ifdef DEBUG_HASH
                    fprintf(stderr, "%u\n", hash);
                #endif
         702 ->     return hash;
                }
                #endif
                #endif
                
                /*
                 * Name: add_mime_type
                 * Description: Adds a key/value pair to the mime_hashtable
                 */
                
         172 -> void add_mime_type(char *extension, char *type)
                {
                    unsigned int hash;
                    hash_struct *current, *next;
                
         172 ->     if (!extension)
         172 ->         return;
                
         172 ->     hash = get_mime_hash_value(extension);
                
         172 ->     current = mime_hashtable[hash];
                
         172 ->     while (current) {
         172 ->         if (!strcmp(current->key, extension))
         172 ->             return;         /* don't add extension twice */
         172 ->         if (current->next)
         172 ->             current = current->next;
                        else
                            break;
                    }
                
                    /* if here, we need to add a new one */
         172 ->     next = (hash_struct *) malloc(sizeof (hash_struct));
         172 ->     if (!next) {
         172 ->         DIE("malloc of hash_struct failed!");
                    }
         172 ->     next->key = strdup(extension);
         172 ->     if (!next->key)
         172 ->         DIE("malloc of hash_struct->key failed!");
         172 ->     next->value = strdup(type);
         172 ->     if (!next->value)
         172 ->         DIE("malloc of hash_struct->value failed!");
         172 ->     next->next = NULL;
                
         172 ->     if (!current) {
         172 ->         mime_hashtable[hash] = next;
                    } else {
         172 ->         current->next = next;
                    }
                }
                
                /*
                 * 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
                 */
                
         702 -> unsigned get_mime_hash_value(char *extension)
                {
         702 ->     unsigned int hash = 0;
                
         702 ->     if (extension == NULL || extension[0] == '\0') {
                        /* FIXME */
         702 ->         log_error_time();
         702 ->         fprintf(stderr, "Attempt to hash NULL or empty string!\n");
         702 ->         return 0;
                    }
                
         702 ->     hash = boa_hash(extension);
         702 ->     hash %= MIME_HASHTABLE_SIZE;
                
         702 ->     return hash;
                }
                
                /*
                 * Name: get_mime_type
                 *
                 * Description: Returns the mime type for a supplied filename.
                 * Returns default type if not found.
                 */
                
         530 -> char *get_mime_type(char *filename)
                {
                    char ?extension;
                    hash_struct *current;
                
                    unsigned int hash;
                
         530 ->     extension = mstrrchr(filename, '.');
                
         530 ->     if (!extension || *extension++ == '\0')
         530 ->         return default_type;
                
         530 ->     hash = get_mime_hash_value(extension);
         530 ->     current = mime_hashtable[hash];
                
         530 ->     while (current) {
         530 ->         if (!strcmp(current->key, extension)) /* hit */
         530 ->             return current->value;
         530 ->         current = current->next;
                    }
                
         530 ->     return 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
                 */
                
       ##### -> unsigned get_homedir_hash_value(char *name)
                {
       ##### ->     unsigned int hash = 0;
                
       ##### ->     if (name == NULL || name[0] == '\0') {
                        /* FIXME */
       ##### ->         log_error_time();
       ##### ->         fprintf(stderr, "Attempt to hash NULL or empty string!\n");
       ##### ->         return 0;
                    }
                
       ##### ->     hash = boa_hash(name);
       ##### ->     hash %= PASSWD_HASHTABLE_SIZE;
                
       ##### ->     return hash;
                }
                
                
                /*
                 * 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(char *name)
                {
                    struct passwd *passwdbuf;
                
                    hash_struct *current, *next;
                    unsigned int hash;
                
                    /* first check hash table -- if username is less than four characters,
                       just hash to zero (this should be very rare) */
                
       ##### ->     hash = get_homedir_hash_value(name);
                
       ##### ->     for(current = passwd_hashtable[hash];current;current = current->next) {
       ##### ->         if (!strcmp(current->key, name)) /* hit */
       ##### ->             return current->value;
       ##### ->         if (!current->next)
       ##### ->             break;
                    }
                
                    /* if here, we have to add a new one */
                
       ##### ->     passwdbuf = getpwnam(name);
                
       ##### ->     if (!passwdbuf)         /* does not exist */
       ##### ->         return NULL;
                
       ##### ->     next = (hash_struct *) calloc(1, sizeof (hash_struct));
       ##### ->     if (!next) {
       ##### ->         WARN("malloc of hash_struct for passwd_hashtable failed!");
       ##### ->         return NULL;
                    }
                
       ##### ->     next->key = strdup(name);
       ##### ->     if (!next->key) {
       ##### ->         WARN("malloc of passwd_hashtable[hash]->key failed!");
       ##### ->         free(next);
       ##### ->         return NULL;
                    }
       ##### ->     next->value = strdup(passwdbuf->pw_dir);
       ##### ->     if (!next->value) {
       ##### ->         WARN("malloc of passwd_hashtable[hash]->value failed!");
       ##### ->         free(next->key);
       ##### ->         free(next);
       ##### ->         return NULL;
                    }
       ##### ->     next->next = NULL;
                
       ##### ->     if (!current) {
       ##### ->         passwd_hashtable[hash] = next;
                    } else {
       ##### ->         current->next = next;
                    }
       ##### ->     return next->value;
                }
                
       ##### -> void dump_mime(void)
                {
                    int i;
                    hash_struct *temp;
       ##### ->     for (i = 0; i < MIME_HASHTABLE_SIZE; ++i) { /* these limits OK? */
       ##### ->         temp = mime_hashtable[i];
       ##### ->         while (temp) {
                            hash_struct *temp_next;
                
       ##### ->             temp_next = temp->next;
       ##### ->             free(temp->key);
       ##### ->             free(temp->value);
       ##### ->             free(temp);
                
       ##### ->             temp = temp_next;
                        }
       ##### ->         mime_hashtable[i] = NULL;
                    }
                }
                
       ##### -> void dump_passwd(void)
                {
                    int i;
                    hash_struct *temp;
       ##### ->     for (i = 0; i < PASSWD_HASHTABLE_SIZE; ++i) { /* these limits OK? */
       ##### ->         temp = passwd_hashtable[i];
       ##### ->         while (temp) {
                            hash_struct *temp_next;
                
       ##### ->             temp_next = temp->next;
       ##### ->             free(temp->key);
       ##### ->             free(temp->value);
       ##### ->             free(temp);
                
       ##### ->             temp = temp_next;
                        }
       ##### ->         passwd_hashtable[i] = NULL;
                    }
                }
                
       ##### -> void show_hash_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);
                
                }


Top 10 Lines:

     Line      Count

      111        702
      186        702
      210        530
      138        172

Execution Summary:

      132   Executable lines in this file
      132   Lines executed
   100.00   Percent of the file executed

     2106   Total number of line executions
    15.95   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/config.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1999 Larry Doolittle <ldoolitt@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                #include "y.tab.h"
                #include "parse.h"
                
                int yyparse(void);              /* Better match the output of lex */
                
                #ifdef DEBUG
                #define DBG(x) x
                #else
                #define DBG(x)
                #endif
                
                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;
                long int max_connections;
                
                char *document_root;
                char *user_dir;
                char *directory_index;
                char *default_type;
                char *dirmaker;
                char *cachedir;
                
                char *tempdir;
                
                char *cgi_path = NULL;
                int single_post_limit = SINGLE_POST_LIMIT_DEFAULT;
                
                int ka_timeout;
                int ka_max;
                
                /* These came from log.c */
                char *error_log_name;
                char *access_log_name;
                char *cgi_log_name;
                
                int use_localtime;
                
                /* These are new */
                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, char **t);
                static void c_set_int(char *v1, char *v2, int *t);
                static void c_set_unity(char *v1, char *v2, int *t);
                static void c_add_type(char *v1, char *v2, void *t);
                static void c_add_alias(char *v1, char *v2, int *t);
                
                /* Fakery to keep the value passed to action() a void *,
                   see usage in table and c_add_alias() below */
                static int script_number = SCRIPTALIAS;
                static int redirect_number = REDIRECT;
                static int alias_number = ALIAS;
                static uid_t current_uid=0;
                
                /* Help keep the table below compact */
                #define S0A STMT_NO_ARGS
                #define S1A STMT_ONE_ARG
                #define S2A STMT_TWO_ARGS
                
                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},
                    {"ErrorLog", S1A, c_set_string, &error_log_name},
                    {"AccessLog", S1A, c_set_string, &access_log_name},
                    {"UseLocaltime", S0A, c_set_unity, &use_localtime},
                    {"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},
                    {"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},
                    {"KeepAliveMax", S1A, c_set_int, &ka_max},
                    {"KeepAliveTimeout", S1A, c_set_int, &ka_timeout},
                    {"MimeTypes", S1A, c_set_string, &mime_types},
                    {"DefaultType", S1A, c_set_string, &default_type},
                    {"AddType", S2A, c_add_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},
                    {"MaxConnections", S1A, c_set_int, &max_connections},
                };
                
           1 -> static void c_set_user(char *v1, char *v2, void *t)
                {
                    struct passwd *passwdbuf;
           1 ->     char @endptr = v1;
                    int i;
                
                    DBG(printf("User %s = ", v1);
                        )
           1 ->         i = strtol(v1, &endptr, 0);
           1 ->     if (*v1 != '\0' && *endptr == '\0') {
           1 ->         server_uid = i;
                    } else {
           1 ->         passwdbuf = getpwnam(v1);
           1 ->         if (!passwdbuf) {
           1 ->             if (current_uid)
           1 ->                 return;
           1 ->             fprintf(stderr, "No such user: %s\n", v1);
           1 ->             exit(1);
                        }
           1 ->         server_uid = passwdbuf->pw_uid;
                    }
                    DBG(printf("%d\n", server_uid);
                        )
                }
                
           1 -> static void c_set_group(char *v1, char *v2, void *t)
                {
                    struct group *groupbuf;
           1 ->     char @endptr = v1;
                    int i;
                    DBG(printf("Group %s = ", v1);
                        )
           1 ->         i = strtol(v1, &endptr, 0);
           1 ->     if (*v1 != '\0' && *endptr == '\0') {
           1 ->         server_gid = i;
                    } else {
           1 ->         groupbuf = getgrnam(v1);
           1 ->         if (!groupbuf) {
           1 ->             if (current_uid)
           1 ->                 return;
           1 ->             fprintf(stderr, "No such group: %s\n", v1);
           1 ->             exit(1);
                        }
           1 ->         server_gid = groupbuf->gr_gid;
                    }
                    DBG(printf("%d\n", server_gid);
                        )
                }
                
           6 -> static void c_set_string(char *v1, char *v2, char **t)
                {
                    char *s;
                    DBG(printf("Setting pointer %p to string %s ..", t, v1);
                        )
           6 ->         if (t) {
           6 ->         s = *(char **) t;
           6 ->         if (s)
           6 ->             free(s);
           6 ->         *(char **) t = strdup(v1);
           6 ->         if (!*(char **) t) {
           6 ->             DIE("Unable to strdup in c_set_string");
                        }
                        DBG(printf("done.\n");
                            )
                    } else {
                        DBG(printf("skipped.\n");
                            )
                    }
                }
                
           3 -> static void c_set_int(char *v1, char *v2, int *t)
                {
           3 ->     char @endptr = v1;
                    int i;
                    DBG(printf("Setting pointer %p to integer string %s ..", t, v1);
                        )
           3 ->         if (t) {
           3 ->         i = strtol(v1, &endptr, 0); /* Automatic base 10/16/8 switching */
           3 ->         if (*v1 != '\0' && *endptr == '\0') {
           3 ->             *(int *) t = i;
                            DBG(printf(" Integer converted as %d, done\n", i);
                                )
                        } else {
                            /* XXX should tell line number to user */
           3 ->             fprintf(stderr, "Error: %s found where integer expected\n",
                                    v1);
                        }
                    } else {
                        DBG(printf("skipped.\n");
                            )
                    }
                }
                
       ##### -> static void c_set_unity(char *v1, char *v2, int *t)
                {
                    DBG(printf("Setting pointer %p to unity\n", t);
                        )
       ##### ->         if (t)
       ##### ->         *(int *) t = 1;
                }
                
       ##### -> static void c_add_type(char *v1, char *v2, void *t)
                {
       ##### ->     add_mime_type(v1, v2);
                }
                
       ##### -> static void c_add_alias(char *v1, char *v2, int *t)
                {
       ##### ->     add_alias(v2, v1, *(int *) t);
                }
                
          22 -> struct ccommand *lookup_keyword(char *c)
                {
                    struct ccommand ?p;
                    DBG(printf("Checking string '%s' against keyword list\n", c);
                        )
          22 ->         for (p = clist;
          22 ->              p < clist + (sizeof (clist) / sizeof (struct ccommand)); p++) {
          22 ->         if (strcmp(c, p->name) == 0)
          22 ->             return p;
                    }
          22 ->     return NULL;
                }
                
                /*
                 * Name: read_config_files
                 *
                 * Description: Reads config files via yyparse, then makes sure that
                 * all required variables were set properly.
                 */
           1 -> void read_config_files(void)
                {
                    char *temp;
           1 ->     current_uid = getuid();
           1 ->     yyin = fopen("boa.conf", "r");
                
           1 ->     if (!yyin) {
           1 ->         fputs("Could not open boa.conf for reading.\n", stderr);
           1 ->         exit(1);
                    }
           1 ->     if (yyparse()) {
           1 ->         fputs("Error parsing config files, exiting\n", stderr);
           1 ->         exit(1);
                    }
                
           1 ->     if (!server_name) {
                        struct hostent *he;
                        char temp_name[100 + 1] @zeroterm;
                
           1 ->         if (gethostname(temp_name, 100) == -1) {
           1 ->             perror("gethostname:");
           1 ->             exit(1);
                        }
                
           1 ->         he = gethostbyname(temp_name);
           1 ->         if (he == NULL) {
           1 ->             perror("gethostbyname:");
           1 ->             exit(1);
                        }
                
           1 ->         server_name = strdup(he->h_name);
           1 ->         if (server_name == NULL) {
           1 ->             perror("strdup:");
           1 ->             exit(1);
                        }
                    }
           1 ->     tempdir = getenv("TMP");
           1 ->     if (tempdir == NULL)
           1 ->         tempdir = strdup("/tmp");
                
           1 ->     if (single_post_limit < 0) {
           1 ->         fprintf(stderr, "Invalid value for single_post_limit: %d\n",
                                single_post_limit);
           1 ->         exit(1);
                    }
                
           1 ->     if (document_root) {
           1 ->         temp = normalize_path(document_root);
           1 ->         free(document_root);
           1 ->         document_root = temp;
                    }
                
           1 ->     if (error_log_name) {
           1 ->         temp = normalize_path(error_log_name);
           1 ->         free(error_log_name);
           1 ->         error_log_name = temp;
                    }
                
           1 ->     if (access_log_name) {
           1 ->         temp = normalize_path(access_log_name);
           1 ->         free(access_log_name);
           1 ->         access_log_name = temp;
                    }
                
           1 ->     if (cgi_log_name) {
           1 ->         temp = normalize_path(cgi_log_name);
           1 ->         free(cgi_log_name);
           1 ->         cgi_log_name = temp;
                    }
                
           1 ->     if (dirmaker) {
           1 ->         temp = normalize_path(dirmaker);
           1 ->         free(dirmaker);
           1 ->         dirmaker = temp;
                    }
                
                #if 0
                    if (mime_types) {
                        temp = normalize_path(mime_types);
                        free(mime_types);
                        mime_types = temp;
                    }
                #endif
                }


Top 10 Lines:

     Line      Count

      232         22
      170          6
      191          3
      121          1
      146          1
      251          1

Execution Summary:

       99   Executable lines in this file
       99   Lines executed
   100.00   Percent of the file executed

       34   Total number of line executions
     0.34   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/cgi.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996,97 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996 Charles F. Randall <crandall@goldsys.com>
                 *  Some changes Copyright (C) 1997-2002 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $ */
                
                #include "boa.h"
                
                static char ?env_gen_extra(const char *key, const char *value, int extra);
                
                int verbose_cgi_logs = 0;
                /* The +1 is for the the NULL in complete_env */
                static char *common_cgi_env[COMMON_CGI_COUNT + 1];
                
                /*
                 * Name: create_common_env
                 *
                 * Description: Set up the environment variables that are common to
                 * all CGI scripts
                 */
                
           1 -> void create_common_env()
                {   static char default_path[]@zeroterm = DEFAULT_PATH;
           1 ->     int index = 0, i;
                
                
                    /* 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."
                     */
           1 ->     common_cgi_env[index++] = env_gen_extra("PATH",
                                                            ((cgi_path != NULL) ? cgi_path : default_path), 0);
           1 ->     common_cgi_env[index++] = env_gen_extra("SERVER_SOFTWARE", SERVER_VERSION, 0);
           1 ->     common_cgi_env[index++] = env_gen_extra("SERVER_NAME", server_name, 0);
           1 ->     common_cgi_env[index++] = env_gen_extra("GATEWAY_INTERFACE", CGI_VERSION, 0);
                
           1 ->     common_cgi_env[index++] =
                        env_gen_extra("SERVER_PORT", simple_itoa(server_port), 0);
                
                    /* NCSA and APACHE added -- not in CGI spec */
                    /* common_cgi_env[index++] = env_gen_extra("DOCUMENT_ROOT", document_root); */
                
                    /* NCSA added */
                    /* common_cgi_env[index++] = env_gen_extra("SERVER_ROOT", server_root); */
                
                    /* APACHE added */
           1 ->     common_cgi_env[index++] = env_gen_extra("SERVER_ADMIN", server_admin, 0);
           1 ->     common_cgi_env[index] = NULL;
                
                    /* Sanity checking -- make *sure* the memory got allocated */
           1 ->     if (index > COMMON_CGI_COUNT) {
           1 ->         log_error_time();
           1 ->         fprintf(stderr, "COMMON_CGI_COUNT not high enough.\n");
           1 ->         exit(1);
                    }
                
           1 ->     for(i = 0;i < index;++i) {
           1 ->         if (common_cgi_env[i] == NULL) {
           1 ->             log_error_time();
           1 ->             fprintf(stderr, "Unable to allocate a component of common_cgi_env - out of memory.\n");
           1 ->             exit(1);
                        }
                    }
                }
                
       ##### -> 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
                 */
         796 -> static char ?env_gen_extra(const char *key, const char *value, int extra)
                {
                    char ?result;
                    int key_len, value_len;
                
         796 ->     if (value == NULL)          /* ServerAdmin may not be defined, eg */
         796 ->         value = "";
         796 ->     key_len = strlen(key);
         796 ->     value_len = strlen(value);
                    /* leave room for '=' sign and null terminator */
         796 ->     result = malloc(extra + key_len + value_len + 2);
         796 ->     if (result) {
         796 ->         memcpy(result + extra, key, key_len);
         796 ->         *(result + extra + key_len) = '=';
         796 ->         if (value_len != 0) memcpy(result + extra + key_len + 1, value, value_len);
         796 ->         *(result + extra + key_len + value_len + 1) = '\0';
                    } else {
         796 ->         log_error_time();
         796 ->         perror("malloc");
         796 ->         log_error_time();
         796 ->         fprintf(stderr,
                                "tried to allocate (key=value) extra=%d: %s=%s\n",
                                extra, key, value);
                    }
         796 ->     return result;
                }
                
                /*
                 * Name: add_cgi_env
                 *
                 * Description: adds a variable to CGI's environment
                 * Used for HTTP_ headers
                 */
                
         790 -> int add_cgi_env(request * req, const char *key, const char *value, int http_prefix)
                {
                    char ?p;
                    int prefix_len;
                
         790 ->     if (http_prefix) {
         790 ->         prefix_len = 5;
                    } else {
         790 ->         prefix_len = 0;
                    }
                
         790 ->     if (req->cgi_env_index < CGI_ENV_MAX) {
         790 ->         p = env_gen_extra(key, value, prefix_len);
         790 ->         if (!p) {
         790 ->             log_error_time();
         790 ->             fprintf(stderr, "Unable to generate additional CGI Environment"
                                    "variable -- ran out of memory!\n");
                        }
         790 ->         if (prefix_len)
         790 ->             memcpy(p, "HTTP_", 5);
         790 ->         req->cgi_env[req->cgi_env_index++] = p;
         790 ->         return 1;
                    } else {
         790 ->         log_error_time();
         790 ->         fprintf(stderr, "Unable to generate additional CGI Environment"
                                "variable -- not enough space!\n");
                    }
         790 ->     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
                 */
                
       ##### -> 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);
                    }
                
       ##### ->     my_add_cgi_env(req, "SERVER_ADDR", req->local_ip_addr);
       ##### ->     my_add_cgi_env(req, "SERVER_PROTOCOL", 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_time();
       ##### ->     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
                 *
                 */
                
       ##### -> 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) {
       ##### ->             WARN("unable to strdup 'q' in create_argv!");
                        }
       ##### ->         for (aargc = 1; q && (aargc < CGI_ARGC_MAX);) {
       ##### ->             r = q;
                            /* for an index-style CGI, + is used to seperate arguments
                             * an escaped '+' is of no concern to us
                             */
       ##### ->             if ((p = mstrchr(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 *`H req)
                {
                    int child_pid;
                    int pipes[2];
       ##### ->     int use_pipes = 0;
                
       ##### ->     SQUASH_KA(req);
                
       ##### ->     if (req->is_cgi) {
       ##### ->         if (complete_env(req) == 0) {
       ##### ->             return 0;
                        }
                    }
                #ifdef FASCIST_LOGGING
                    {
                        int i;
                        for (i = 0; i < req->cgi_env_index; ++i)
                            fprintf(stderr, "%s - environment variable for cgi: \"%s\"\n",
                                    __FILE__, req->cgi_env[i]);
                    }
                #endif
                
                    if (req->is_cgi == CGI || 1) {
       ##### ->         use_pipes = 1;
       ##### ->         if (pipe(pipes) == -1) {
       ##### ->             log_error_time();
       ##### ->             perror("pipe");
       ##### ->             return 0;
                        }
                
                        /* set the read end of the socket to non-blocking */
       ##### ->         if (set_nonblock_fd(pipes[0]) == -1) {
       ##### ->             log_error_time();
       ##### ->             perror("cgi-fcntl");
       ##### ->             close(pipes[0]);
       ##### ->             close(pipes[1]);
       ##### ->             return 0;
                        }
                    }
                
       ##### ->     child_pid = fork();
       ##### ->     switch(child_pid) {
                    case -1:
                        /* fork unsuccessful */
       ##### ->         log_error_time();
       ##### ->         perror("fork");
                
       ##### ->         if (use_pipes) {
       ##### ->             close(pipes[0]);
       ##### ->             close(pipes[1]);
                        }
       ##### ->         send_r_error(req);
                        /* FIXME: There is aproblem here. send_r_error would work
                           for NPH and CGI, but not for GUNZIP.  Fix that. */
                        /* i'd like to send_r_error, but.... */
       ##### ->         return 0;
                        break;
                    case 0:
                        /* child */
       ##### ->         if (req->is_cgi == CGI || req->is_cgi == NPH) {
       ##### ->             char *foo = strdup(req->pathname);
                            char *c;
                
       ##### ->             if (!foo) {
       ##### ->                 WARN("unable to strdup pathname for req->pathname");
       ##### ->                 _exit(1);
                            }
       ##### ->             c = mstrrchr(foo, '/');
       ##### ->             if (c) {
       ##### ->                 ++c;
       ##### ->                 *c = '\0';
                            } else {
                                /* we have a serious problem */
       ##### ->                 log_error_time();
       ##### ->                 perror("chdir");
       ##### ->                 if (use_pipes)
       ##### ->                     close(pipes[1]);
       ##### ->                 _exit(1);
                            }
       ##### ->             if (chdir(foo) != 0) {
       ##### ->                 log_error_time();
       ##### ->                 perror("chdir");
       ##### ->                 if (use_pipes)
       ##### ->                     close(pipes[1]);
       ##### ->                 _exit(1);
                            }
                        }
       ##### ->         if (use_pipes) {
       ##### ->             close(pipes[0]);
                            /* tie cgi's STDOUT to it's write end of pipe */
       ##### ->             if (dup2(pipes[1], STDOUT_FILENO) == -1) {
       ##### ->                 log_error_time();
       ##### ->                 perror("dup2 - pipes");
       ##### ->                 close(pipes[1]);
       ##### ->                 _exit(1);
                            }
       ##### ->             close(pipes[1]);
       ##### ->             if (set_block_fd(STDOUT_FILENO) == -1) {
       ##### ->                 log_error_time();
       ##### ->                 perror("cgi-fcntl");
       ##### ->                 _exit(1);
                            }
                        } else {
                            /* tie stdout to socket */
       ##### ->             if (dup2(req->fd, STDOUT_FILENO) == -1) {
       ##### ->                 log_error_time();
       ##### ->                 perror("dup2 - fd");
       ##### ->                 _exit(1);
                            }
                            /* Switch socket flags back to blocking */
       ##### ->             if (set_block_fd(req->fd) == -1) {
       ##### ->                 log_error_time();
       ##### ->                 perror("cgi-fcntl");
       ##### ->                 _exit(1);
                            }
                        }
                        /* 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);
                        }
                        /* Close access log, so CGI program can't scribble
                         * where it shouldn't
                         */
       ##### ->         close_access_log();
                
                        /*
                         * tie STDERR to cgi_log_fd
                         * cgi_log_fd will automatically close, close-on-exec rocks!
                         * if we don't tied STDERR (current log_error) to cgi_log_fd,
                         *  then we ought to close it.
                         */
       ##### ->         if (!cgi_log_fd)
       ##### ->             dup2(devnullfd, STDERR_FILENO);
                        else
       ##### ->             dup2(cgi_log_fd, STDERR_FILENO);
                
       ##### ->         if (req->is_cgi) {
                            char *aargv[CGI_ARGC_MAX + 1] @zeroterm = {for i < CGI_ARGC_MAX : NULL};
       ##### ->             create_argv(req, aargv);
       ##### ->             execve(req->pathname, aargv, req->cgi_env);
                        } else {
       ##### ->             if (req->pathname[strlen(req->pathname) - 1] == '/')
       ##### ->                 execlp(dirmaker, dirmaker, req->pathname, req->request_uri,
                                      NULL);
                #ifdef GUNZIP
                            else
       ##### ->                 execlp(GUNZIP, GUNZIP, "--stdout", "--decompress",
                                      req->pathname, NULL);
                #endif
                        }
                        /* execve failed */
       ##### ->         WARN(req->pathname);
       ##### ->         _exit(1);
       ##### ->         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->is_cgi == 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;
                }


Top 10 Lines:

     Line      Count

      112        796
      146        790
       41          1

Execution Summary:

      210   Executable lines in this file
      210   Lines executed
   100.00   Percent of the file executed

     1587   Total number of line executions
     7.56   Average executions per line


*** File /fs/junkfood/mujtaba/cmsc631/project/boa-0.94.13/cyc-unique/src/boa.cyc:
                /*
                 *  Boa, an http server
                 *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
                 *  Some changes Copyright (C) 1996 Charles F. Randall <crandall@goldsys.com>
                 *  Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
                 *  Some changes Copyright (C) 1996-2002 Jon Nelson <jnelson@boa.org>
                 *
                 *  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: gprof.txt,v 1.1 2004/04/19 17:07:16 mujtaba Exp $*/
                
                #include "boa.h"
                #include <sys/resource.h>
                
                /* globals */
                int backlog = SO_MAXCONN;
                time_t start_time;
                
                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 max_fd = 0;
                int pending_requests = 0;
                
                /* static to boa.c */
                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 devnullfd = -1;
                
           1 -> int main(int argc, char ?`H?argv)
                {
                    int c;                      /* command line arg */
                    int server_s;                   /* boa socket */
                
                    /* set umask to u+rw, u-x, go-rwx */
           1 ->     c = umask(~0600);
           1 ->     if (c == -1) {
           1 ->         perror("umask");
           1 ->         exit(1);
                    }
                
           1 ->     devnullfd = open("/dev/null", 0);
                
                    /* make STDIN and STDOUT point to /dev/null */
           1 ->     if (devnullfd == -1) {
           1 ->         DIE("can't open /dev/null");
                    }
                
           1 ->     if (dup2(devnullfd, STDIN_FILENO) == -1) {
           1 ->         DIE("can't dup2 /dev/null to STDIN_FILENO");
                    }
                
           1 ->     if (dup2(devnullfd, STDOUT_FILENO) == -1) {
           1 ->         DIE("can't dup2 /dev/null to STDOUT_FILENO");
                    }
                
                    /* but first, update timestamp, because log_error_time uses it */
           1 ->     (void) time(&current_time);
                
           1 ->     while ((c = getopt(argc, argv, "c:r:d")) != -1) {
           1 ->         switch (c) {
                        case 'c':
           1 ->             if (server_root)
           1 ->                 free(server_root);
           1 ->             server_root = strdup(optarg);
           1 ->             if (!server_root) {
           1 ->                 perror("strdup (for server_root)");
           1 ->                 exit(1);
                            }
                            break;
                        case 'r':
           1 ->             if (chdir(optarg) == -1) {
           1 ->                 log_error_time();
           1 ->                 perror("chdir (to chroot)");
           1 ->                 exit(1);
                            }
           1 ->             if (chroot(optarg) == -1) {
           1 ->                 log_error_time();
           1 ->                 perror("chroot");
           1 ->                 exit(1);
                            }
           1 ->             if (chdir("/") == -1) {
           1 ->                 log_error_time();
           1 ->                 perror("chdir (after chroot)");
           1 ->                 exit(1);
                            }
                            break;
                        case 'd':
           1 ->             do_fork = 0;
           1 ->             break;
                        default:
           1 ->             fprintf(stderr, "Usage: %s [-c serverroot] [-r chroot] [-d]\n", argv[0]);
           1 ->             exit(1);
                        }
                    }
                
           1 ->     fixup_server_root();
           1 ->     read_config_files();
           1 ->     open_logs();
           1 ->     server_s = create_server_socket();
           1 ->     init_signals();
           1 ->     drop_privs();
           1 ->     create_common_env();
           1 ->     build_needs_escape();
                
           1 ->     if (max_connections < 1) {
                        struct rlimit rl;
                
                        /* has not been set explicitly */
           1 ->         c = getrlimit(RLIMIT_NOFILE, &rl);
           1 ->         if (c < 0) {
           1 ->             perror("getrlimit");
           1 ->             exit(1);
                        }
           1 ->         max_connections = rl.rlim_cur;
                    }
                
                    /* background ourself */
           1 ->     if (do_fork) {
           1 ->         switch(fork()) {
                        case -1:
                            /* error */
           1 ->             perror("fork");
           1 ->             exit(1);
                            break;
                        case 0:
                            /* child, success */
                            break;
                        default:
                            /* parent, success */
           1 ->             exit(0);
                            break;
                        }
                    }
                
                    /* main loop */
           1 ->     timestamp();
                
           1 ->     status.requests = 0;
           1 ->     status.errors = 0;
                
           1 ->     start_time = current_time;
           1 ->     select_loop(server_s);
           1 ->     return 0;
                }
                
           1 -> static int create_server_socket(void)
                {
                    int server_s;
                
           1 ->     server_s = socket(SERVER_AF, SOCK_STREAM, IPPROTO_TCP);
           1 ->     if (server_s == -1) {
           1 ->         DIE("unable to create socket");
                    }
                
                    /* server socket is nonblocking */
           1 ->     if (set_nonblock_fd(server_s) == -1) {
           1 ->         DIE("fcntl: unable to set server socket to nonblocking");
                    }
                
                    /* close server socket on exec so cgi's can't write to it */
           1 ->     if (fcntl(server_s, F_SETFD, 1) == -1) {
           1 ->         DIE("can't set close-on-exec on server socket!");
                    }
                
                    /* reuse socket addr */
           1 ->     if ((setsockopt(server_s, SOL_SOCKET, SO_REUSEADDR, &sock_opt,
                                    sizeof (sock_opt))) == -1) {
           1 ->         DIE("setsockopt");
                    }
                
                    /* internet family-specific code encapsulated in bind_server()  */
           1 ->     if (bind_server(server_s, server_ip) == -1) {
           1 ->         DIE("unable to bind");
                    }
                
                    /* listen: large number just in case your kernel is nicely tweaked */
           1 ->     if (listen(server_s, backlog) == -1) {
           1 ->         DIE("unable to listen");
                    }
           1 ->     return server_s;
                }
                
           1 -> static void drop_privs(void)
                {
                    /* give away our privs if we can */
           1 ->     if (getuid() == 0) {
                        struct passwd *passwdbuf;
           1 ->         passwdbuf = getpwuid(server_uid);
           1 ->         if (passwdbuf == NULL) {
           1 ->             DIE("getpwuid");
                        }
           1 ->         if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) {
           1 ->             DIE("initgroups");
                        }
           1 ->         if (setgid(server_gid) == -1) {
           1 ->             DIE("setgid");
                        }
           1 ->         if (setuid(server_uid) == -1) {
           1 ->             DIE("setuid");
                        }
                        /* test for failed-but-return-was-successful setuid
                         * http://www.securityportal.com/list-archive/bugtraq/2000/Jun/0101.html
                         */
           1 ->         if (setuid(0) != -1) {
           1 ->             DIE("icky Linux kernel bug!");
                        }
                    } else {
           1 ->         if (server_gid || server_uid) {
           1 ->             log_error_time();
           1 ->             fprintf(stderr, "Warning: "
                                    "Not running as root: no attempt to change"
                                    " to uid %d gid %d\n", server_uid, server_gid);
                        }
           1 ->         server_gid = getgid();
           1 ->         server_uid = getuid();
                    }
                }
                
                /*
                 * Name: fixup_server_root
                 *
                 * Description: Makes sure the server root is valid.
                 *
                 */
                
           1 -> static void fixup_server_root()
                {
                    char *dirbuf;
                
           1 ->     if (!server_root) {
                #ifdef SERVER_ROOT
           1 ->         server_root = strdup(SERVER_ROOT);
           1 ->         if (!server_root) {
           1 ->             perror("strdup (SERVER_ROOT)");
           1 ->             exit(1);
                        }
                #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(1);
                #endif
                    }
                
           1 ->     if (chdir(server_root) == -1) {
           1 ->         fprintf(stderr, "Could not chdir to \"%s\": aborting\n",
                                server_root);
           1 ->         exit(1);
                    }
                
           1 ->     dirbuf = normalize_path(server_root);
           1 ->     free(server_root);
           1 ->     server_root = dirbuf;
                }
                


Top 10 Lines:

     Line      Count

       50          1
      167          1
      204          1
      247          1

Execution Summary:

      107   Executable lines in this file
      107   Lines executed
   100.00   Percent of the file executed

        4   Total number of line executions
     0.04   Average executions per line
