Merging SJSWS 7.0 update 4 and update 5 bug fixes
authorMeena Vyas <meena.vyas@sun.com>
Thu May 07 03:20:10 2009 -0700 (10 months ago)
changeset 4367e5999a90e
parent 3f11d28822e4e
child 556e8ed48e7eb
Merging SJSWS 7.0 update 4 and update 5 bug fixes
make/rules_COMMON.mk
schema/open-web-server_1_0.xsd
src/server/Makefile
src/server/base/servnss.cpp
src/server/base/servnss.h
src/server/base/sslconf.cpp
src/server/base/sslconf.h
src/server/base/vs.cpp
src/server/extras/Makefile
src/server/extras/binlog/Makefile
src/server/extras/binlog/binlog.cpp
src/server/frame/conf.cpp
src/server/frame/conf.h
src/server/frame/object.cpp
src/server/frame/objset.cpp
src/server/libaccess/lasip.cpp
src/server/libsi18n/makefile.step2
src/server/libsi18n/webserv_msg_de.txt
src/server/libsi18n/webserv_msg_es.txt
src/server/libsi18n/webserv_msg_fr.txt
src/server/libsi18n/webserv_msg_ja.txt
src/server/libsi18n/webserv_msg_ko.txt
src/server/libsi18n/webserv_msg_zh_cn.txt
src/server/libsi18n/webserv_msg_zh_tw.txt
src/server/plugins/fastcgi/constants.h
src/server/plugins/fastcgi/fcgirequest.cpp
src/server/plugins/fastcgi/fcgirequest.h
src/server/plugins/fastcgi/fcgirole.cpp
src/server/plugins/fastcgi/nsapifastcgi.cpp
src/server/plugins/htaccess/http_access.cpp
src/server/plugins/htaccess/util.cpp
src/server/public/nsapi.h
src/server/safs/Cgistub.c
src/server/safs/Makefile.cgistub
src/server/safs/cgi.cpp
src/server/safs/cgi.h
src/server/safs/dbtsafs.h
src/server/safs/dump.cpp
src/server/safs/flexlog.cpp
src/server/safs/flexlogcommon.h
src/support/filecache/fileio.cpp
src/support/xp/Makefile
src/support/xp/i386/atomic.S
templates/Makefile
templates/install-bin/binlog.template
       1 --- a/make/rules_COMMON.mk	Sun Jan 18 01:43:32 2009 -0800
       2 +++ b/make/rules_COMMON.mk	Thu May 07 03:20:10 2009 -0700
       3 @@ -417,7 +417,7 @@
       4  ifdef SHIP_ICU_RESOURCES
       5  ifndef BUILD64
       6  SOMETHING_EXPORTED=1
       7 -_ICU_RESOURCES=$(addprefix $(OBJDIR)/, $(addsuffix _root.res, \
       8 +_ICU_RESOURCES=$(addprefix $(OBJDIR)/, $(addsuffix .res, \
       9                 $(SHIP_ICU_RESOURCES)))
      10  SHIP_RESOURCE_FILES+=$(_ICU_RESOURCES)
      11  endif
      12 @@ -605,6 +605,9 @@
      13  ifndef NO_STD_ICU_RESOURCES_TARGET
      14  compile:: $(_ICU_RESOURCES)
      15  $(OBJDIR)/%_root.res: %.properties
      16 +	$(GENRB) -d $(OBJDIR) $<
      17 +
      18 +$(OBJDIR)/%.res: %.properties
      19  	$(GENRB) -d $(OBJDIR) $<
      20  endif # NO_STD_ICU_RESOURCES_TARGET
      21  
     1.1 --- a/schema/open-web-server_1_0.xsd	Sun Jan 18 01:43:32 2009 -0800
     1.2 +++ b/schema/open-web-server_1_0.xsd	Thu May 07 03:20:10 2009 -0700
     1.3 @@ -969,7 +969,7 @@
     1.4        <xs:simpleType>
     1.5          <xs:restriction base="xs:integer">
     1.6            <xs:minInclusive value="1"/>
     1.7 -          <xs:maxInclusive value="128"/>
     1.8 +          <xs:maxInclusive value="256"/>
     1.9          </xs:restriction>
    1.10        </xs:simpleType>
    1.11      </xs:element>
    1.12 @@ -2380,6 +2380,17 @@
    1.13        <xs:annotation>
    1.14          <xs:appinfo>
    1.15            <appinfo:implicit>default</appinfo:implicit>
    1.16 +        </xs:appinfo>
    1.17 +      </xs:annotation>
    1.18 +    </xs:element>
    1.19 +
    1.20 +    <xs:element name="mode" type="access-logModeType" default="text" minOccurs="0" maxOccurs="1">
    1.21 +      <xs:annotation>
    1.22 +        <xs:documentation>
    1.23 +            If the mode element is omitted, the mode is assumed to be text. 
    1.24 +        </xs:documentation>
    1.25 +        <xs:appinfo>
    1.26 +          <appinfo:implicit>text</appinfo:implicit>
    1.27          </xs:appinfo>
    1.28        </xs:annotation>
    1.29      </xs:element>
    1.30 @@ -3586,12 +3597,25 @@
    1.31      <xs:enumeration value="Cp285"/>
    1.32      <xs:enumeration value="Cp1123"/>
    1.33      <xs:enumeration value="Cp1124"/>
    1.34 +    <xs:enumeration value="Cp858"/>
    1.35 +    <xs:enumeration value="Cp1140"/>
    1.36 +    <xs:enumeration value="Cp1141"/>
    1.37 +    <xs:enumeration value="Cp1142"/>
    1.38 +    <xs:enumeration value="Cp1143"/>
    1.39 +    <xs:enumeration value="Cp1144"/>
    1.40 +    <xs:enumeration value="Cp1145"/>
    1.41 +    <xs:enumeration value="Cp1146"/>
    1.42 +    <xs:enumeration value="Cp1147"/>
    1.43 +    <xs:enumeration value="Cp1148"/>
    1.44 +    <xs:enumeration value="Cp1149"/>
    1.45 +    <xs:enumeration value="Cp1047"/>
    1.46      <xs:enumeration value="ISCII91"/>
    1.47      <xs:enumeration value="ISO-8859-1"/>
    1.48      <xs:enumeration value="ISO-8859-2"/>
    1.49      <xs:enumeration value="ISO-8859-3"/>
    1.50      <xs:enumeration value="ISO-8859-4"/>
    1.51      <xs:enumeration value="ISO-8859-9"/>
    1.52 +    <xs:enumeration value="ISO-8859-11"/>
    1.53      <xs:enumeration value="ISO-8859-13"/>
    1.54      <xs:enumeration value="ISO-8859-15"/>
    1.55      <xs:enumeration value="ISO8859_15"/>
    1.56 @@ -3638,6 +3662,7 @@
    1.57      <xs:enumeration value="windows-1256"/>
    1.58      <xs:enumeration value="windows-1257"/>
    1.59      <xs:enumeration value="windows-1250"/>
    1.60 +    <xs:enumeration value="windows-1251"/>
    1.61      <xs:enumeration value="windows-1253"/>
    1.62      <xs:enumeration value="windows-1255"/>
    1.63      <xs:enumeration value="windows-1252"/>
    1.64 @@ -3675,6 +3700,28 @@
    1.65      <xs:enumeration value="windows-949"/>
    1.66      <xs:enumeration value="windows-936"/>
    1.67      <xs:enumeration value="windows-950"/>
    1.68 +    <xs:enumeration value="ISO-2022-CN"/>
    1.69 +    <xs:enumeration value="ISO-2022-JP"/>
    1.70 +    <xs:enumeration value="Shift_JIS"/>
    1.71 +    <xs:enumeration value="Cp1381"/>
    1.72 +    <xs:enumeration value="Cp1383"/>
    1.73 +    <xs:enumeration value="Cp33722"/>
    1.74 +    <xs:enumeration value="Cp33722"/>
    1.75 +    <xs:enumeration value="Cp930"/>
    1.76 +    <xs:enumeration value="Cp939"/>
    1.77 +    <xs:enumeration value="Cp942"/>
    1.78 +    <xs:enumeration value="Cp942C"/>
    1.79 +    <xs:enumeration value="Cp943"/>
    1.80 +    <xs:enumeration value="Cp943C"/>
    1.81 +    <xs:enumeration value="Cp948"/>
    1.82 +    <xs:enumeration value="Cp949C"/>
    1.83 +    <xs:enumeration value="Cp964"/>
    1.84 +    <xs:enumeration value="Cp970"/>
    1.85 +    <xs:enumeration value="JISAutoDetect"/>
    1.86 +    <xs:enumeration value="Johab"/>
    1.87 +    <xs:enumeration value="EUC-JP"/>
    1.88 +    <xs:enumeration value="EUC-JP-LINUX"/>
    1.89 +    <xs:enumeration value="EUC-JP-SOLARIS"/>
    1.90    </xs:restriction>
    1.91  </xs:simpleType>
    1.92  
    1.93 @@ -4210,6 +4257,30 @@
    1.94    </xs:restriction>
    1.95  </xs:simpleType>
    1.96  
    1.97 +<xs:simpleType name="access-logModeType">
    1.98 +  <xs:annotation>
    1.99 +    <xs:documentation>
   1.100 +      The value must be a log mode. Valid log modes are text and binary.
   1.101 +    </xs:documentation>
   1.102 +  </xs:annotation>
   1.103 +  <xs:restriction base="xs:token">
   1.104 +    <xs:enumeration value="text">
   1.105 +      <xs:annotation>
   1.106 +        <xs:documentation>
   1.107 +          Use text format for access log.
   1.108 +        </xs:documentation>
   1.109 +      </xs:annotation>
   1.110 +    </xs:enumeration>
   1.111 +    <xs:enumeration value="binary">
   1.112 +      <xs:annotation>
   1.113 +        <xs:documentation>
   1.114 +          Use binary format for access log.
   1.115 +        </xs:documentation>
   1.116 +      </xs:annotation>
   1.117 +    </xs:enumeration>
   1.118 +  </xs:restriction>
   1.119 +</xs:simpleType>
   1.120 +
   1.121  <xs:simpleType name="sizeType">
   1.122    <xs:annotation>
   1.123      <xs:documentation>
     2.1 --- a/src/server/Makefile	Sun Jan 18 01:43:32 2009 -0800
     2.2 +++ b/src/server/Makefile	Thu May 07 03:20:10 2009 -0700
     2.3 @@ -34,7 +34,7 @@
     2.4  BUILD_ROOT=../..
     2.5  include $(BUILD_ROOT)/make/defines.mk
     2.6  MODULE=lib 
     2.7 -DIRS=httpdaemon base ldaputil frame libaccess libadmin safs libsi18n libcrypt libdrcache httpparser libsed libserverxml libproxy shtml
     2.8 +DIRS=httpdaemon base ldaputil frame libaccess libadmin safs libsi18n libcrypt libdrcache httpparser libsed libserverxml libproxy shtml extras
     2.9  
    2.10  ifdef FEAT_SEARCH
    2.11  DIRS+=libnscore
     3.1 --- a/src/server/base/servnss.cpp	Sun Jan 18 01:43:32 2009 -0800
     3.2 +++ b/src/server/base/servnss.cpp	Thu May 07 03:20:10 2009 -0700
     3.3 @@ -824,3 +824,73 @@
     3.4  
     3.5      return PR_FALSE;
     3.6  }
     3.7 +
     3.8 +/*
     3.9 + * Return PR_TRUE if certa is better than certb
    3.10 + */
    3.11 +static PRBool is_better(CERTCertificate *certa, CERTCertificate *certb)
    3.12 +{
    3.13 +    PRTime notBeforeA, notAfterA, notBeforeB, notAfterB;
    3.14 +
    3.15 +    SECStatus rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
    3.16 +    if (rv != SECSuccess)
    3.17 +        return PR_FALSE;
    3.18 +
    3.19 +    rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
    3.20 +    if (rv != SECSuccess)
    3.21 +        return PR_TRUE;
    3.22 +
    3.23 +    PRBool isfutureA = (notBeforeA > PR_Now()) ? PR_TRUE : PR_FALSE;
    3.24 +    PRBool isfutureB = (notBeforeB > PR_Now()) ? PR_TRUE : PR_FALSE;
    3.25 +
    3.26 +    // If one cert is newer than the other, choose that unless
    3.27 +    // the issue-date of newer cert is in the future and the
    3.28 +    // issue-date of the older cert is in the past
    3.29 +    if (LL_CMP(notBeforeA, >, notBeforeB)) {
    3.30 +        if (isfutureA && !isfutureB)
    3.31 +            return PR_FALSE;
    3.32 +        return PR_TRUE;
    3.33 +    } else {
    3.34 +        if (isfutureB && !isfutureA)
    3.35 +            return PR_TRUE;
    3.36 +        return PR_FALSE;
    3.37 +    }
    3.38 +}
    3.39 +
    3.40 +NSAPI_PUBLIC CERTCertificate *servnss_get_cert_from_nickname(const char *nickname, PK11CertListType listType)
    3.41 +{
    3.42 +    if (!nickname) { return NULL; }
    3.43 +
    3.44 +    CERTCertificate *currentCert = NULL, // Cursor in list
    3.45 +                    *savedCert = NULL;   // Last matching cert
    3.46 +
    3.47 +    CERTCertList* clist = PK11_ListCerts(listType, NULL);
    3.48 +    CERTCertListNode *cln;
    3.49 +    for (cln = CERT_LIST_HEAD(clist); !CERT_LIST_END(cln,clist);
    3.50 +            cln = CERT_LIST_NEXT(cln)) {
    3.51 +        currentCert = cln->cert;
    3.52 +        const char* cnick = (const char*) cln->appData;
    3.53 +        if (!cnick) {
    3.54 +            cnick = currentCert->nickname;
    3.55 +        }
    3.56 +        /*If nickname matches
    3.57 +         *    Case 1: Previous match saved in savedCert?
    3.58 +         *            if no, save currentCert into savedCert
    3.59 +         *    Case 2: store newer cert in savedCert
    3.60 +         */
    3.61 +        if (0==strcmp(cnick, nickname))
    3.62 +        {
    3.63 +            if (savedCert == NULL || is_better(currentCert, savedCert))
    3.64 +                savedCert = currentCert;
    3.65 +        }
    3.66 +    }
    3.67 +    //We found our cert
    3.68 +    CERTCertificate *cert = NULL;
    3.69 +    if (savedCert)
    3.70 +        cert = CERT_DupCertificate(savedCert);
    3.71 +
    3.72 +    CERT_DestroyCertList(clist);
    3.73 +
    3.74 +    return cert;
    3.75 +}
    3.76 +
     4.1 --- a/src/server/base/servnss.h	Sun Jan 18 01:43:32 2009 -0800
     4.2 +++ b/src/server/base/servnss.h	Thu May 07 03:20:10 2009 -0700
     4.3 @@ -57,4 +57,6 @@
     4.4  PRBool servssl_maybe_client_hello(void *buf, int sz);
     4.5  void PR_CALLBACK servssl_handshake_callback(PRFileDesc *socket, void *arg);
     4.6  
     4.7 +NSAPI_PUBLIC CERTCertificate *servnss_get_cert_from_nickname(const char *nickname, PK11CertListType type=PK11CertListUser);
     4.8 +
     4.9  #endif /* SERVNSS_H */
     5.1 --- a/src/server/base/sslconf.cpp	Sun Jan 18 01:43:32 2009 -0800
     5.2 +++ b/src/server/base/sslconf.cpp	Thu May 07 03:20:10 2009 -0700
     5.3 @@ -153,44 +153,6 @@
     5.4      }
     5.5  }
     5.6  
     5.7 -/*
     5.8 - * Attempt to find a certificate with the given nickname. If found (non-NULL
     5.9 - * returned) the caller is responsible for eventually calling 
    5.10 - * CERT_DestroyCertificate() on it.
    5.11 - *
    5.12 - */
    5.13 -CERTCertificate* 
    5.14 -SSLSocketConfiguration :: FindServerCertFromNickname(const char* name) const
    5.15 -{
    5.16 -    if (!name) { return NULL; }
    5.17 -
    5.18 -    CERTCertList* clist;
    5.19 -    clist = PK11_ListCerts(PK11CertListUser, NULL);
    5.20 -
    5.21 -    CERTCertListNode *cln;
    5.22 -
    5.23 -    for (cln = CERT_LIST_HEAD(clist); !CERT_LIST_END(cln,clist);
    5.24 -        cln = CERT_LIST_NEXT(cln))
    5.25 -    {
    5.26 -        CERTCertificate* cert = cln->cert;
    5.27 -        const char* nickname = (const char*) cln->appData;
    5.28 -        if (!nickname)
    5.29 -        {
    5.30 -            nickname = cert->nickname;
    5.31 -        }
    5.32 -        if (0==strcmp(name, nickname))
    5.33 -        {
    5.34 -            // we found our cert
    5.35 -            CERTCertificate* rv = CERT_DupCertificate(cert);
    5.36 -            CERT_DestroyCertList(clist);
    5.37 -            return rv;
    5.38 -        }
    5.39 -    }
    5.40 -    CERT_DestroyCertList(clist);
    5.41 -    return NULL;
    5.42 -}
    5.43 -
    5.44 -
    5.45  /* 
    5.46   * This function loops through all the server cert nicknames listed in the
    5.47   * given config and attempts to locate each one along with associated info
    5.48 @@ -252,7 +214,7 @@
    5.49          ereport(LOG_VERBOSE, "Processing server cert nicknamed [%s]", 
    5.50                  servercertNickname[i]);
    5.51  
    5.52 -        servercert[i] = FindServerCertFromNickname(servercertNickname[i]);
    5.53 +        servercert[i] = servnss_get_cert_from_nickname(servercertNickname[i]);
    5.54  
    5.55          if (NULL == servercert[i])
    5.56          {
     6.1 --- a/src/server/base/sslconf.h	Sun Jan 18 01:43:32 2009 -0800
     6.2 +++ b/src/server/base/sslconf.h	Thu May 07 03:20:10 2009 -0700
     6.3 @@ -133,7 +133,6 @@
     6.4          void set_cipher(PRInt32 cipher, const char *cipherName,
     6.5                                                const ServerXMLSchema::Bool& on);
     6.6          void set_ciphers();
     6.7 -        CERTCertificate* FindServerCertFromNickname(const char* name) const;
     6.8          PRBool check_bypass() const;
     6.9  };
    6.10  
     7.1 --- a/src/server/base/vs.cpp	Sun Jan 18 01:43:32 2009 -0800
     7.2 +++ b/src/server/base/vs.cpp	Thu May 07 03:20:10 2009 -0700
     7.3 @@ -320,6 +320,8 @@
     7.4      inline PRBool isValid() { return sn && rq && objset; }
     7.5  
     7.6      HttpRequest* hrq;
     7.7 +    const VirtualServer* threadVS;
     7.8 +    HttpRequest* threadHrq;
     7.9      pool_handle_t* poolCaller;
    7.10      Session* sn;
    7.11      Request* rq;
    7.12 @@ -344,6 +346,8 @@
    7.13      hrq = HttpRequest::CurrentRequest();
    7.14      if (hrq)
    7.15          HttpRequest::SetCurrentRequest(NULL);
    7.16 +    else
    7.17 +        conf_get_thread_globals(threadHrq, threadVS);
    7.18  
    7.19      // Remember the caller's MALLOC pool
    7.20      if (keyPool == -1)
    7.21 @@ -400,6 +404,9 @@
    7.22      if (hrq) {
    7.23          HttpRequest::SetCurrentRequest(hrq);
    7.24          conf_set_thread_globals(hrq);
    7.25 +    }
    7.26 +    else {
    7.27 +        conf_set_thread_globals(threadHrq, threadVS);
    7.28      }
    7.29  }
    7.30  
     8.1 --- a/src/server/frame/conf.cpp	Sun Jan 18 01:43:32 2009 -0800
     8.2 +++ b/src/server/frame/conf.cpp	Thu May 07 03:20:10 2009 -0700
     8.3 @@ -186,6 +186,23 @@
     8.4      }
     8.5  }
     8.6  
     8.7 +/* ----------------------- conf_get_thread_globals ------------------------ */
     8.8 +
     8.9 +/* Take a backup of thread local data.
    8.10 + *
    8.11 + */
    8.12 +
    8.13 +NSAPI_PUBLIC void conf_get_thread_globals(HttpRequest *&hrq,
    8.14 +                                          const VirtualServer *&vs)
    8.15 +{
    8.16 +    ThreadGlobalsData *data = get_thread_globals_data();
    8.17 +    PR_ASSERT(data);
    8.18 +    if (data) {
    8.19 +        hrq = data->hrq; 
    8.20 +        vs = data->vs; 
    8.21 +    }
    8.22 +
    8.23 +}
    8.24  
    8.25  /* ----------------------- conf_set_thread_globals ------------------------ */
    8.26  
    8.27 @@ -204,6 +221,26 @@
    8.28          data->initialized = PR_FALSE;
    8.29      }
    8.30  }
    8.31 +
    8.32 +
    8.33 + /* ---------------------- conf_set_thread_globals ---------------------- */
    8.34 +
    8.35 +/* This is called to cover the scenario's when hrq could be null. The backup 
    8.36 + * thread local variables are set back if hrq is null.
    8.37 + */
    8.38 +
    8.39 +NSAPI_PUBLIC void conf_set_thread_globals(class HttpRequest *hrq, 
    8.40 +                                          const VirtualServer *vs)
    8.41 +{
    8.42 +    ThreadGlobalsData *data = get_thread_globals_data();
    8.43 +    PR_ASSERT(data);
    8.44 +    if (data) {
    8.45 +        data->hrq = hrq;
    8.46 +        data->vs = vs;
    8.47 +    }
    8.48 +    
    8.49 +}
    8.50 +
    8.51  
    8.52  
    8.53  /* ---------------------- conf_set_thread_vs_globals ---------------------- */
     9.1 --- a/src/server/frame/conf.h	Sun Jan 18 01:43:32 2009 -0800
     9.2 +++ b/src/server/frame/conf.h	Thu May 07 03:20:10 2009 -0700
     9.3 @@ -83,8 +83,10 @@
     9.4  
     9.5  NSAPI_PUBLIC conf_global_vars_s *conf_get_true_globals();
     9.6  NSAPI_PUBLIC void conf_set_thread_globals(class HttpRequest *hrq);
     9.7 +NSAPI_PUBLIC void conf_set_thread_globals(class HttpRequest *hrq, const VirtualServer *vs);
     9.8  NSAPI_PUBLIC void conf_set_thread_vs_globals(const VirtualServer *vs);
     9.9  NSAPI_PUBLIC void conf_reset_thread_globals();
    9.10 +NSAPI_PUBLIC void conf_get_thread_globals(HttpRequest *&hrq, const VirtualServer*& vs);
    9.11  NSAPI_PUBLIC const VirtualServer *conf_get_vs();
    9.12  NSAPI_PUBLIC PRStatus conf_parse(const char *cfn, PRBool jvm_enabled);
    9.13  NSAPI_PUBLIC void conf_add_init(pblock *initfn, conf_global_vars_s *cg);
    10.1 --- a/src/server/frame/object.cpp	Sun Jan 18 01:43:32 2009 -0800
    10.2 +++ b/src/server/frame/object.cpp	Thu May 07 03:20:10 2009 -0700
    10.3 @@ -448,7 +448,7 @@
    10.4  
    10.5              pblock *ncp = NULL;
    10.6              if (od->client.pb) {
    10.7 -                ncp = pbmap.lookup(od->param.pb);
    10.8 +                ncp = pbmap.lookup(od->client.pb);
    10.9                  if (!ncp)
   10.10                      return PR_FAILURE;
   10.11              }
    11.1 --- a/src/server/frame/objset.cpp	Sun Jan 18 01:43:32 2009 -0800
    11.2 +++ b/src/server/frame/objset.cpp	Thu May 07 03:20:10 2009 -0700
    11.3 @@ -783,34 +783,64 @@
    11.4  }
    11.5  
    11.6  
    11.7 +/* ---------------------------- open_condition ---------------------------- */
    11.8 +
    11.9 +static PRInt32 open_condition(PRFileDesc *f, const Condition *cond, const char *&condtag)
   11.10 +{
   11.11 +     PRInt32 rv = 0;
   11.12 +
   11.13 +     if (!cond->expr) {
   11.14 +         condtag = "Else";
   11.15 +     } else if (cond->follows) {
   11.16 +         condtag = "ElseIf";
   11.17 +     } else {
   11.18 +         condtag = "If";
   11.19 +     }
   11.20 +     char *s = expr_format(cond->expr);
   11.21 +     if (strchr(s, '>')) {
   11.22 +         PR_ASSERT(strcmp(condtag, "Else"));
   11.23 +         rv |= PR_fprintf(f, "<%s (%s)>\n", condtag, s);
   11.24 +     } else if (*s) {
   11.25 +         PR_ASSERT(strcmp(condtag, "Else"));
   11.26 +         rv |= PR_fprintf(f, "<%s %s>\n", condtag, s);
   11.27 +     } else {
   11.28 +         PR_ASSERT(!strcmp(condtag, "Else"));
   11.29 +         rv |= PR_fprintf(f, "<%s>\n", condtag);
   11.30 +     }
   11.31 +     FREE(s);
   11.32 +
   11.33 +     return rv;
   11.34 +}
   11.35 +
   11.36 +/* --------------------------- close_condition ---------------------------- */
   11.37 +
   11.38 +static PRInt32 close_condition(PRFileDesc *f, const char *condtag)
   11.39 +{
   11.40 +    return PR_fprintf(f, "</%s>\n", condtag);
   11.41 +}
   11.42 +
   11.43 +
   11.44  /* --------------------------- write_directives --------------------------- */
   11.45  
   11.46 -static PRStatus write_directives(PRFileDesc *f, const char *dc, dtable *dt, int& i, const Condition *cond)
   11.47 -{
   11.48 +static PRStatus write_directives(PRFileDesc *f, const char *dc, dtable *dt, int& i, Condition ** conds, int ci, int& pci){
   11.49      PRInt32 rv = 0;
   11.50  
   11.51      // Open the condition tag
   11.52      const char *condtag = NULL;
   11.53 +    const Condition *cond = NULL;
   11.54 +
   11.55 +    if (ci != -1)
   11.56 +        cond = conds[ci];
   11.57 +
   11.58      if (cond) {
   11.59 -        if (!cond->expr) {
   11.60 -            condtag = "Else";
   11.61 -        } else if (cond->follows) {
   11.62 -            condtag = "ElseIf";
   11.63 -        } else {
   11.64 -            condtag = "If";
   11.65 +        if (ci > (pci+1)) {
   11.66 +            for (int lv = pci + 1; lv < ci; lv++) {
   11.67 +                rv |= open_condition(f, conds[lv], condtag);
   11.68 +                rv |= close_condition(f, condtag);
   11.69 +            }
   11.70          }
   11.71 -        char *s = expr_format(cond->expr);
   11.72 -        if (strchr(s, '>')) {
   11.73 -            PR_ASSERT(strcmp(condtag, "Else"));
   11.74 -            rv |= PR_fprintf(f, "<%s (%s)>\n", condtag, s);
   11.75 -        } else if (*s) {
   11.76 -            PR_ASSERT(strcmp(condtag, "Else"));
   11.77 -            rv |= PR_fprintf(f, "<%s %s>\n", condtag, s);
   11.78 -        } else {
   11.79 -            PR_ASSERT(!strcmp(condtag, "Else"));
   11.80 -            rv |= PR_fprintf(f, "<%s>\n", condtag);
   11.81 -        }
   11.82 -        FREE(s);
   11.83 +        rv |= open_condition(f, cond, condtag);
   11.84 +        pci = cond->i;
   11.85      }
   11.86  
   11.87      const Condition *childcond = NULL;
   11.88 @@ -829,7 +859,7 @@
   11.89                  // Recurse for nested <ElseIf>/<Else>
   11.90                  if (childcond && dt->inst[i].cond->follows == childcond) {
   11.91                      childcond = dt->inst[i].cond;
   11.92 -                    write_directives(f, dc, dt, i, childcond);
   11.93 +                    write_directives(f, dc, dt, i, conds, childcond->i, pci);
   11.94                      continue;
   11.95                  }
   11.96  
   11.97 @@ -841,7 +871,7 @@
   11.98                      childcond = childcond->inside;
   11.99                  }
  11.100                  if (childcond) {
  11.101 -                    write_directives(f, dc, dt, i, childcond);
  11.102 +                    write_directives(f, dc, dt, i, conds, childcond->i, pci);
  11.103                      continue;
  11.104                  }
  11.105              }
  11.106 @@ -878,7 +908,7 @@
  11.107  
  11.108      // Close the condition tag
  11.109      if (cond)
  11.110 -        rv |= PR_fprintf(f, "</%s>\n", condtag);
  11.111 +        rv |= close_condition(f, condtag);
  11.112  
  11.113      return (rv < 0) ? PR_FAILURE : PR_SUCCESS;
  11.114  }
  11.115 @@ -935,7 +965,7 @@
  11.116          for (int di = 0; di < os->obj[x]->nd; di++) {
  11.117              const char *dc = directive_num2name(di);
  11.118              dtable *dt = &os->obj[x]->dt[di];
  11.119 -            for (int z = 0; z < dt->ni; rv |= write_directives(f, dc, dt, z, NULL));
  11.120 +            for (int z = 0, pci = -1; z < dt->ni; rv |= write_directives(f, dc, dt, z, os->obj[x]->cond, -1, pci));
  11.121          }
  11.122  
  11.123          rv |= PR_fprintf(f, "</Object>\n\n");
    12.1 --- a/src/server/libaccess/lasip.cpp	Sun Jan 18 01:43:32 2009 -0800
    12.2 +++ b/src/server/libaccess/lasip.cpp	Thu May 07 03:20:10 2009 -0700
    12.3 @@ -1009,18 +1009,49 @@
    12.4  
    12.5      // Assuming its 123.456.789.012 then,
    12.6      // it can be 123.* or 123.456.* or 123.456.789.*
    12.7 +    // or 123.*.*.*  or  123.456.*.* or *.*.*.*
    12.8      // we can NOT have 12* or 123.4* keeping the traditions of 6.1
    12.9 +    // Now calculate length after :: has been removed
   12.10      int len = strlen(ip);
   12.11 -    if (ip[len-1]=='*' && ip[len-2] != '.') {
   12.12 -         ereport(LOG_VERBOSE,
   12.13 -                 "ERROR Invalid IP Address %s. Can only have a * after a '.'.",
   12.14 +    int starcount = getDelimCount(ip, '*');
   12.15 +    PRBool validFormat = PR_TRUE;
   12.16 +    if (starcount > 1 && dotcount != 3)
   12.17 +        validFormat = PR_FALSE;
   12.18 +    char* ptr = strchr(ip, '*');
   12.19 +    if (ptr && validFormat) {
   12.20 +        if ((ptr != ip) && (*(ptr -1) != '.'))
   12.21 +            validFormat = PR_FALSE;
   12.22 +        else {
   12.23 +            // Now we can only expect ".*" combination after ptr
   12.24 +            ptr++;
   12.25 +            while (validFormat && *ptr) {
   12.26 +                // *ptr is not null so it is safe to read *(ptr+1)
   12.27 +                // we expect only .* from this point
   12.28 +                if (! ((*ptr == '.') && (*(ptr+1) == '*'))) {
   12.29 +                    validFormat = PR_FALSE;
   12.30 +                    break;
   12.31 +                }
   12.32 +                ptr += 2;
   12.33 +            }
   12.34 +        }
   12.35 +     }
   12.36 +     if (!validFormat) {
   12.37 +          ereport(LOG_VERBOSE,
   12.38 +                 "ERROR Invalid IP Address %s",
   12.39                   ip);
   12.40           return LAS_EVAL_INVALID;
   12.41      }
   12.42      // if dotcount == 3 need to substitute * with 0
   12.43 +    // 8*1 for 123.* or 8*2 for 123.45.* or 8*3 for 123.45.67.* 
   12.44      int wildcardPos = 8*dotcount;
   12.45 +    // 8*1 for 123.*.*.* or 8*2 for 123.456.*.*  or 8*0 for *.*.*.*
   12.46 +    if (starcount > 1)
   12.47 +        wildcardPos = 8*(4-starcount);
   12.48      if (dotcount == 3) {
   12.49 -        ip[len-1]='0';
   12.50 +        // 123.*.*.* or 123.456.*.* or 123.456.78.* or *.*.*.*
   12.51 +        for(int i=0; i<len;i++)
   12.52 +            if (ip[i] == '*')
   12.53 +                ip[i] = '0';
   12.54      } else {
   12.55         // if dotcount == 1 need to substitute * with 0.0.0(5)
   12.56         // if dotcount == 2 need to substitute * with 0.0(3)
   12.57 @@ -1118,13 +1149,6 @@
   12.58      // ip=*
   12.59      if (!strcmp(iIP,"*"))
   12.60          return (PR_AF_INET + PR_AF_INET6);
   12.61 -    else if (iIP[0] == '*' && strlen(iIP) > 1 ) {
   12.62 -        // ip=*/digits or *digits
   12.63 -        ereport(LOG_VERBOSE,
   12.64 -                "ERROR Invalid IP Address %s.",
   12.65 -                iIP);
   12.66 -        return LAS_EVAL_INVALID;
   12.67 -    }
   12.68  
   12.69      int hasdot =0;
   12.70      if (strchr(iIP, '.'))
   12.71 @@ -1145,6 +1169,13 @@
   12.72  
   12.73      int prefix_length=-1;
   12.74      if (strchr(ip, '/')) {
   12.75 +        if (strchr(ip, '*')) {
   12.76 +            // ip=*/digits
   12.77 +            ereport(LOG_VERBOSE,
   12.78 +                    "ERROR Invalid IP Address %s. Can not have * and / both",
   12.79 +                    iIP);
   12.80 +            return LAS_EVAL_INVALID;
   12.81 +        }
   12.82          prefix_length = separateIpAndNetmaskPrefixLength(ip, hasdot?32:128);
   12.83          if (prefix_length == LAS_EVAL_INVALID) {
   12.84              return LAS_EVAL_INVALID;
    13.1 --- a/src/server/libsi18n/makefile.step2	Sun Jan 18 01:43:32 2009 -0800
    13.2 +++ b/src/server/libsi18n/makefile.step2	Thu May 07 03:20:10 2009 -0700
    13.3 @@ -56,9 +56,9 @@
    13.4  EXE1_OBJS=makstrdb
    13.5  EXE1_LIBS=libdbm
    13.6  
    13.7 +DB_LIST=$(wildcard $(PRODUCT_I18N_DB)_*.txt)
    13.8  DB_FILES=$(OBJDIR)/$(PRODUCT_I18N_DB).db \
    13.9 -         $(addprefix $(OBJDIR)/$(PRODUCT_I18N_DB)_, $(addsuffix .db, \
   13.10 -                     en))
   13.11 +         $(addprefix $(OBJDIR)/, $(DB_LIST:.txt=.db))
   13.12  
   13.13  local_pre_publish::$(DB_FILES)
   13.14  SHIP_RESOURCE_FILES=$(DB_FILES)
    14.1 --- a/src/server/plugins/fastcgi/constants.h	Sun Jan 18 01:43:32 2009 -0800
    14.2 +++ b/src/server/plugins/fastcgi/constants.h	Thu May 07 03:20:10 2009 -0700
    14.3 @@ -47,10 +47,9 @@
    14.4  #include "errortypes.h"
    14.5  
    14.6  #define CGI_VERSION "CGI/1.1"
    14.7 -#define MAX_CGI_SPECIFIC_VARS    8
    14.8  #define MAX_CGI_SSI_VARS         7
    14.9  #define MAX_CGI_CLIENT_AUTH_VARS 64
   14.10 -#define MAX_EXTRA_FCGI_VARS 6
   14.11 +#define MAX_EXTRA_FCGI_VARS 8
   14.12  
   14.13  #define SERVER_PROTOCOL "HTTP/1.0"
   14.14  #define IOBUFSIZE 10240
    15.1 --- a/src/server/plugins/fastcgi/fcgirequest.cpp	Sun Jan 18 01:43:32 2009 -0800
    15.2 +++ b/src/server/plugins/fastcgi/fcgirequest.cpp	Thu May 07 03:20:10 2009 -0700
    15.3 @@ -52,7 +52,7 @@
    15.4  
    15.5  //constructor
    15.6  FcgiRequest::FcgiRequest(const FcgiServerConfig *config, Session *sn, Request *rq, PRUint8 role)
    15.7 -: _config(config), _sn(sn), _rq(rq), fcgiRole(role) {
    15.8 +: _config(config), _sn(sn), _rq(rq), fcgiRole(role), filterApp(NULL) {
    15.9      _headers = pblock_dup(_rq->headers);
   15.10      _hasContentLength = (pblock_find("content-length", _headers) != NULL);
   15.11      _hasBody = _hasContentLength || pblock_find("transfer-encoding", _headers);
   15.12 @@ -73,6 +73,7 @@
   15.13  
   15.14  FcgiRequest::~FcgiRequest() {
   15.15      pblock_free(_headers);
   15.16 +    FREE(filterApp);
   15.17  }
   15.18  
   15.19  void FcgiRequest::log(int degree, const char *fmt, ...) {
   15.20 @@ -97,7 +98,7 @@
   15.21      // Setup the environment for the FCGI program
   15.22      env = http_hdrs2env(_rq->headers);
   15.23      env = cgi_common_vars(_sn, _rq, env);
   15.24 -    env = cgi_specific_vars(args, env);
   15.25 +    env = cgi_specific_vars(_sn, _rq, args, env, (fcgiRole != FCGI_AUTHORIZER));
   15.26      env = cgi_ssi_vars(args, env);
   15.27      env = fcgiSpecificVars(env);
   15.28  
   15.29 @@ -129,88 +130,6 @@
   15.30      return env;
   15.31  }
   15.32  
   15.33 -char** FcgiRequest::cgi_specific_vars(char *args, char** env) {
   15.34 -    int y;
   15.35 -    register pblock *pb;
   15.36 -    char c, *t, *u;
   15.37 -
   15.38 -    pb = _rq->reqpb;
   15.39 -
   15.40 -    int x;
   15.41 -    env = util_env_create(env, MAX_CGI_SPECIFIC_VARS, &x);
   15.42 -    env[x++] = util_env_str(const_cast<char *> ("GATEWAY_INTERFACE"),
   15.43 -                             const_cast<char *> (CGI_VERSION));
   15.44 -
   15.45 -    // Added error check for missing request information.
   15.46 -    t = pblock_findval("protocol", pb);
   15.47 -    if(t == NULL) {
   15.48 -       log(LOG_FAILURE, "send-request", "invalid protocol variable");
   15.49 -       return NULL;
   15.50 -    }
   15.51 -    env[x++] = util_env_str(const_cast<char *> ("SERVER_PROTOCOL"), t);
   15.52 -
   15.53 -    t = pblock_findval("method", pb);
   15.54 -    if(t == NULL) {
   15.55 -       log(LOG_FAILURE, "send-request", "invalid request method variable");
   15.56 -       return NULL;
   15.57 -    }
   15.58 -    env[x++] = util_env_str(const_cast<char *> ("REQUEST_METHOD"), t);
   15.59 -
   15.60 -    t = pblock_findval("uri", pb);
   15.61 -
   15.62 -    /* Simulate CGI URIs by truncating path info */
   15.63 -
   15.64 -
   15.65 -    if( (u = pblock_findval("path-info", _rq->vars)) ) {
   15.66 -        y = strlen(t) - strlen(u);
   15.67 -        if (y >= 0) {
   15.68 -            c = t[y];
   15.69 -            t[y] = '\0';
   15.70 -        }
   15.71 -
   15.72 -    if(fcgiRole != FCGI_AUTHORIZER)
   15.73 -            env[x++] = util_env_str(const_cast<char *> ("SCRIPT_NAME"), t);
   15.74 -
   15.75 -        if (y >= 0) {
   15.76 -            t[y] = c;
   15.77 -        }
   15.78 -
   15.79 -    if(fcgiRole != FCGI_AUTHORIZER) {
   15.80 -            env[x++] = util_env_str(const_cast<char *> ("PATH_INFO"), u);
   15.81 -
   15.82 -            if((t = INTservact_translate_uri2(u, _sn, _rq))) {
   15.83 -                    env[x++] = util_env_str(const_cast<char *>("PATH_TRANSLATED"), t);
   15.84 -                    filterApp = STRDUP(t);
   15.85 -                    FREE(t);
   15.86 -            }
   15.87 -       }
   15.88 -
   15.89 -    } else if(fcgiRole != FCGI_AUTHORIZER) {
   15.90 -        env[x++] = util_env_str(const_cast<char *> ("SCRIPT_NAME"), t);
   15.91 -
   15.92 -        if(u = pblock_findval("path", _rq->vars)) {
   15.93 -            env[x++] = util_env_str(const_cast<char *> ("PATH_TRANSLATED"), u);
   15.94 -            filterApp = u;
   15.95 -        }
   15.96 -    }
   15.97 -
   15.98 -    if(args)
   15.99 -        env[x++] = util_env_str(const_cast<char *> ("QUERY_STRING"), args);
  15.100 -
  15.101 -    t = pblock_findval("content-length", _rq->srvhdrs);
  15.102 -
  15.103 -    if(t) {
  15.104 -    int cl = atoi(t);
  15.105 -
  15.106 -    if((cl > 0) && (fcgiRole != FCGI_AUTHORIZER))
  15.107 -            env[x++] = util_env_str(const_cast<char *> ("CONTENT_LENGTH"), t);
  15.108 -    }
  15.109 -
  15.110 -    env[x] = NULL;
  15.111 -
  15.112 -    return env;
  15.113 -}
  15.114 -
  15.115  char** FcgiRequest::cgi_ssi_vars(char *args, char** env) {
  15.116      pblock *param = ((NSAPIRequest *) _rq)->param;
  15.117  
  15.118 @@ -239,9 +158,29 @@
  15.119  
  15.120  char **FcgiRequest::fcgiSpecificVars(char **env) {
  15.121      int x;
  15.122 -    char *auth;
  15.123 -    
  15.124 +    char *path, *auth;
  15.125 +
  15.126      env = util_env_create(env, MAX_EXTRA_FCGI_VARS, &x);
  15.127 +
  15.128 +    if (fcgiRole != FCGI_AUTHORIZER) {
  15.129 +        // set PATH_TRANSLATED if not set by cgi_specific_vars
  15.130 +        if (!(path = pblock_findval("path-translated", _rq->vars)) &&
  15.131 +             (path = pblock_findval("path", _rq->vars))) {
  15.132 +            env[x++] = util_env_str(const_cast<char *> ("PATH_TRANSLATED"),
  15.133 +                                    path);
  15.134 +        }
  15.135 +        // set the CONTENT_LENGTH 
  15.136 +        // We are setting content-length here since it is not supposed to
  15.137 +        // be set in the cgi_specific_vars
  15.138 +        char *t = pblock_findval("content-length", _rq->srvhdrs);
  15.139 +        if (t) {
  15.140 +           int cl = atoi(t);
  15.141 +           if (cl > 0)
  15.142 +               env[x++] = util_env_str(const_cast<char *> ("CONTENT_LENGTH"), t);
  15.143 +        }
  15.144 +    }
  15.145 +
  15.146 +    // set other fastcgi specific variables
  15.147      env[x++] = util_env_str(const_cast<char *>("SERVER_HOSTNAME"), conf_getglobals()->Vserver_hostname);
  15.148      env[x++] = util_env_str(const_cast<char *>("SERVER_ADDR"), conf_getglobals()->Vaddr);
  15.149  
  15.150 @@ -250,11 +189,13 @@
  15.151          env[x++] = util_env_str((char *)"HTTP_AUTHORIZATION", auth);
  15.152      }
  15.153  
  15.154 -    if(fcgiRole == FCGI_FILTER) {
  15.155 +    if (fcgiRole == FCGI_FILTER) {
  15.156 +        filterApp = STRDUP(path);
  15.157 +        // set the filter file
  15.158          PRStatus status = PR_GetFileInfo(filterApp, &filterFileInfo);
  15.159          if(filterFileInfo.type != PR_FILE_FILE)
  15.160              log(LOG_FAILURE, "send-request", "Filter application is not a file (%s)",
  15.161 -                                    filterApp);
  15.162 +                                    path);
  15.163          else {
  15.164              PRTime lastMod = filterFileInfo.modifyTime;
  15.165              PRUint32 dataSize = filterFileInfo.size;
  15.166 @@ -277,4 +218,3 @@
  15.167  
  15.168      return env;
  15.169  }
  15.170 -
    16.1 --- a/src/server/plugins/fastcgi/fcgirequest.h	Sun Jan 18 01:43:32 2009 -0800
    16.2 +++ b/src/server/plugins/fastcgi/fcgirequest.h	Thu May 07 03:20:10 2009 -0700
    16.3 @@ -64,7 +64,6 @@
    16.4      PRUint64 contentLength;
    16.5  
    16.6  private:
    16.7 -    char **cgi_specific_vars(char *args, char** env);
    16.8      char **cgi_ssi_vars(char *args, char** env);
    16.9      char **fcgiSpecificVars(char **env);
   16.10      char **getRemoteAppEnv(char **env);
    17.1 --- a/src/server/plugins/fastcgi/fcgirole.cpp	Sun Jan 18 01:43:32 2009 -0800
    17.2 +++ b/src/server/plugins/fastcgi/fcgirole.cpp	Thu May 07 03:20:10 2009 -0700
    17.3 @@ -276,9 +276,6 @@
    17.4      if (filterFd) {
    17.5          system_fclose(filterFd);
    17.6          filterFd = NULL;
    17.7 -    }
    17.8 -    if (filterApp) {
    17.9 -        FREE(filterApp);
   17.10      }
   17.11  }
   17.12  
    18.1 --- a/src/server/plugins/fastcgi/nsapifastcgi.cpp	Sun Jan 18 01:43:32 2009 -0800
    18.2 +++ b/src/server/plugins/fastcgi/nsapifastcgi.cpp	Thu May 07 03:20:10 2009 -0700
    18.3 @@ -296,17 +296,6 @@
    18.4      // Log build info
    18.5      ereport(LOG_INFORM, GetString(DBT_build_info), PRODUCT_ID" "PRODUCT_FULL_VERSION_ID" "PLUGIN_FULL_NAME" B"BUILD_NUM);
    18.6  
    18.7 -    // We need iWS 6.0 or higher
    18.8 -    char *version = system_version();
    18.9 -    char *major = strchr(version, '/');
   18.10 -    if ((!strstr(version, COMPANY_SHORT_NAME) && !strstr(version, "iPlanet")) || !major || atoi(major + 1) < 6) {
   18.11 -        if (strstr(version, "App"))
   18.12 -            pblock_nvinsert("error", PRODUCT_BRAND_NAME" 6.0 or higher is required", pb);
   18.13 -        else
   18.14 -            pblock_nvinsert("error", COMPANY_SHORT_NAME"/iPlanet Web Server 6.0 or higher is required", pb);
   18.15 -        return REQ_ABORTED;
   18.16 -    }
   18.17 -
   18.18      if(systemTmpDir)
   18.19          ereport(LOG_VERBOSE, "FastCGI plugin's temp directory is %s", systemTmpDir);
   18.20  
    19.1 --- a/src/server/plugins/htaccess/http_access.cpp	Sun Jan 18 01:43:32 2009 -0800
    19.2 +++ b/src/server/plugins/htaccess/http_access.cpp	Thu May 07 03:20:10 2009 -0700
    19.3 @@ -258,13 +258,26 @@
    19.4                      pblock *pb, Session *sn, Request *rq)
    19.5  {
    19.6      int will_allow, need_auth, num_dirs;
    19.7 -    char path[MAX_STRING_LEN], d[MAX_STRING_LEN];
    19.8      register int x;
    19.9 +    char *path,*root_dir,*full_filename;
   19.10      int start=0; /* start looking for .htaccess files at ntrans-base */
   19.11      int init=0; /* htaccess context allocation flag */
   19.12      char *base = pblock_findval("ntrans-base", rq->vars);
   19.13      htaccess_context_s * ctxt;
   19.14      int rv = ACCESS_OK;
   19.15 +    int len=0;
   19.16 +
   19.17 +    len = strlen(p);
   19.18 +
   19.19 +    if ((path = (char *)MALLOC(len + 1)) == NULL) {
   19.20 +        log_error(LOG_FAILURE,"htaccess_evaluate_access", sn, rq, "out of memory");
   19.21 +        return REQ_ABORTED;
   19.22 +    }
   19.23 +    if ((root_dir = (char *)MALLOC(len + 1)) == NULL) {
   19.24 +        log_error(LOG_FAILURE,"htaccess_evaluate_access", sn, rq, "out of memory");
   19.25 +        FREE(path);
   19.26 +        return REQ_ABORTED;
   19.27 +    }
   19.28  
   19.29      if(isdir) htaccess_strcpy_dir(path,p);
   19.30      else htaccess_lim_strcpy(path,p, MAX_STRING_LEN);
   19.31 @@ -275,30 +288,38 @@
   19.32      will_allow = 1; 
   19.33      need_auth = -1;
   19.34  
   19.35 +    char *access_name = pblock_findval("filename", pb);
   19.36 +    if (!access_name)
   19.37 +        access_name = DEFAULT_ACCESS_FNAME;
   19.38 +
   19.39 +    /* Allocate space to store "/" and null apart from htaccess file name */
   19.40 +    if ((full_filename = (char *)MALLOC(len + strlen(access_name) + 2)) == NULL) {
   19.41 +        log_error(LOG_FAILURE,"htaccess_evaluate_access", sn, rq, "out of memory");
   19.42 +        FREE(path);
   19.43 +        FREE(root_dir);
   19.44 +        return REQ_ABORTED;
   19.45 +    }
   19.46 +
   19.47      /* traverse the request path looking for .htaccess files */
   19.48      for(x=0;x<num_dirs;x++) {
   19.49 -        char *access_name = pblock_findval("filename", pb);
   19.50 -        if (!access_name)
   19.51 -            access_name = DEFAULT_ACCESS_FNAME;
   19.52  
   19.53 -        htaccess_make_dirstr(path,x+1,d);
   19.54 +        htaccess_make_dirstr(path,x+1,root_dir);
   19.55  
   19.56          /* start checking for files at ntrans-base */
   19.57 -        if ((strcmp(d, base)) == 0) start=1;
   19.58 +        if ((strcmp(root_dir, base)) == 0) start=1;
   19.59  
   19.60          if (start) {
   19.61 -            char t[MAX_STRING_LEN];
   19.62              filebuffer *f;
   19.63  
   19.64 -            htaccess_make_full_path(d, access_name, t);
   19.65 +            htaccess_make_full_path(root_dir, access_name, full_filename);
   19.66  
   19.67              /* don't create a context unless there is a file to parse */
   19.68 -            if ((f=htaccess_cfg_open(t))) {
   19.69 +            if ((f=htaccess_cfg_open(full_filename))) {
   19.70  		if (!init) {
   19.71                      ctxt = _htaccess_newctxt(pb, sn, rq);
   19.72                      init=1;
   19.73                  }
   19.74 -                htaccess_parse_access_dir(f,-1,0,d,t,ctxt);
   19.75 +                htaccess_parse_access_dir(f,-1,0,root_dir,full_filename,ctxt);
   19.76                  htaccess_cfg_close(f);
   19.77              }
   19.78          }
   19.79 @@ -322,6 +343,9 @@
   19.80  
   19.81          _htaccess_freectxt(ctxt);
   19.82      }
   19.83 +    FREE(path);
   19.84 +    FREE(root_dir);
   19.85 +    FREE(full_filename);
   19.86      return rv;
   19.87  }
   19.88  
    20.1 --- a/src/server/plugins/htaccess/util.cpp	Sun Jan 18 01:43:32 2009 -0800
    20.2 +++ b/src/server/plugins/htaccess/util.cpp	Thu May 07 03:20:10 2009 -0700
    20.3 @@ -212,6 +212,8 @@
    20.4          dst[x++] = '/';
    20.5  
    20.6      for(y=0; (dst[x] = src2[y]); x++,y++);
    20.7 +    dst[x] = '\0';
    20.8 +
    20.9  }
   20.10  
   20.11  
    21.1 --- a/src/server/public/nsapi.h	Sun Jan 18 01:43:32 2009 -0800
    21.2 +++ b/src/server/public/nsapi.h	Thu May 07 03:20:10 2009 -0700
    21.3 @@ -1486,6 +1486,7 @@
    21.4  
    21.5  #if NSAPI_VERSION >= 303
    21.6  typedef struct nsapi303_dispatch_s nsapi303_dispatch_t;
    21.7 +struct hostent;
    21.8  struct nsapi303_dispatch_s {
    21.9      int (*f_dns_set_hostent)(struct hostent *he, Session *sn, Request *rq);
   21.10  };
    22.1 --- a/src/server/safs/Cgistub.c	Sun Jan 18 01:43:32 2009 -0800
    22.2 +++ b/src/server/safs/Cgistub.c	Thu May 07 03:20:10 2009 -0700
    22.3 @@ -56,6 +56,9 @@
    22.4  #include <sys/types.h>
    22.5  #include <sys/socket.h>
    22.6  #include <sys/stat.h>
    22.7 +#if defined(SOLARIS)
    22.8 +#include <dlfcn.h> /* dlopen */
    22.9 +#endif
   22.10  #if !defined(LINUX)
   22.11  #include <sys/stropts.h>
   22.12  #endif
   22.13 @@ -1494,9 +1497,25 @@
   22.14  void
   22.15  cleanup_environment(void)
   22.16  {
   22.17 +    int closed = 0;
   22.18 +
   22.19 +#if defined(SOLARIS)
   22.20 +    void *handle = dlopen("libc.so", RTLD_LAZY);
   22.21 +    void (*closefromptr)(int) = NULL;
   22.22 +    if (handle) {
   22.23 +        closefromptr = (void (*)(int))dlsym(handle,"closefrom");
   22.24 +        if (closefromptr) {
   22.25 +            (*closefromptr)(STDERR_FILENO+1);
   22.26 +            closed = 1;
   22.27 +        }
   22.28 +        dlclose(handle);
   22.29 +        handle= NULL;
   22.30 +    }
   22.31 +#endif
   22.32 +
   22.33 +  if (!closed) {
   22.34      int     fd;
   22.35      int     fdlimit;
   22.36 -    struct  sigaction sa;
   22.37  
   22.38      /*
   22.39       *  first, close all our potentially nasty inherited fds
   22.40 @@ -1507,6 +1526,7 @@
   22.41          close( fd );
   22.42      }
   22.43    
   22.44 +  }
   22.45      SetupCgiStubSignalDisposition();    
   22.46  }
   22.47  
    23.1 --- a/src/server/safs/Makefile.cgistub	Sun Jan 18 01:43:32 2009 -0800
    23.2 +++ b/src/server/safs/Makefile.cgistub	Thu May 07 03:20:10 2009 -0700
    23.3 @@ -40,7 +40,8 @@
    23.4  endif
    23.5  
    23.6  ifeq ($(OS_ARCH),SunOS)
    23.7 -LD_LIBS += -lsocket -lnsl
    23.8 +C_FLAGS += -DSOLARIS
    23.9 +LD_LIBS += -lsocket -lnsl -ldl
   23.10  LD_FLAGS += -norunpath 
   23.11  ifeq ($(BUILD_ARCH),AMD64)
   23.12  C_FLAGS += -xarch=amd64
    24.1 --- a/src/server/safs/cgi.cpp	Sun Jan 18 01:43:32 2009 -0800
    24.2 +++ b/src/server/safs/cgi.cpp	Thu May 07 03:20:10 2009 -0700
    24.3 @@ -200,12 +200,53 @@
    24.4      return argv;
    24.5  }
    24.6  
    24.7 +//----------------------------------------------------------------------------
    24.8 +// get_request_uri
    24.9 +//----------------------------------------------------------------------------
   24.10 +
   24.11 +char* get_request_uri(Request *req)
   24.12 +{
   24.13 +    // Extract the encoded URI from the request line if possible
   24.14 +    char *clf_request = pblock_findkeyval(pb_key_clf_request, req->reqpb);
   24.15 +    if (clf_request) {
   24.16 +        // Find the beginning of the method
   24.17 +        char *method = clf_request;
   24.18 +        while (*method && isspace(*method))
   24.19 +            method++;
   24.20 +
   24.21 +        // Skip over the method
   24.22 +        char *uri = method;
   24.23 +        while (*uri && !isspace(*uri))
   24.24 +            uri++;
   24.25 +
   24.26 +        // Find the beginning of the URI
   24.27 +        while (*uri && isspace(*uri))
   24.28 +            uri++;
   24.29 +
   24.30 +        // Find the end of the URI
   24.31 +        char *end = uri;
   24.32 +        while (*end && !isspace(*end)) 
   24.33 +            end++;
   24.34 +
   24.35 +        // Make a copy of the uri
   24.36 +        int len = end - uri;
   24.37 +        char* request_uri = (char*) MALLOC(len+1);
   24.38 +        memcpy(request_uri, uri, len);
   24.39 +        request_uri[len] = '\0';
   24.40 +
   24.41 +        return request_uri;
   24.42 +    }
   24.43 +
   24.44 +    // No request line.
   24.45 +    return NULL;
   24.46 +}
   24.47 +
   24.48  //-----------------------------------------------------------------------------
   24.49  // cgi_specific_vars
   24.50  //-----------------------------------------------------------------------------
   24.51  
   24.52 -static char** cgi_specific_vars(Session *sn, Request *rq, const char *args,
   24.53 -                                char** env)
   24.54 +char** cgi_specific_vars(Session *sn, Request *rq, const char *args,
   24.55 +                         char** env, int scriptVars)
   24.56  {
   24.57      int y;
   24.58      register pblock *pb;
   24.59 @@ -219,7 +260,7 @@
   24.60  
   24.61      // Added error check for missing request information.
   24.62      t = pblock_findval("protocol", pb);
   24.63 -    if(t == NULL) {
   24.64 +    if (t == NULL) {
   24.65         log_error(LOG_FAILURE, "cgi_specific_vars", sn, rq, 
   24.66                   XP_GetAdminStr(DBT_cgiError21), "protocol");
   24.67         return NULL;
   24.68 @@ -227,41 +268,59 @@
   24.69      env[x++] = util_env_str("SERVER_PROTOCOL", t);
   24.70  
   24.71      t = pblock_findval("method", pb);
   24.72 -    if(t == NULL) {
   24.73 +    if (t == NULL) {
   24.74         log_error(LOG_FAILURE, "cgi_specific_vars", sn, rq, 
   24.75                   XP_GetAdminStr(DBT_cgiError21), "request method");
   24.76         return NULL;
   24.77      }
   24.78      env[x++] = util_env_str("REQUEST_METHOD", t);
   24.79  
   24.80 -    t = pblock_findval("uri", pb);
   24.81 +    if (args)
   24.82 +        env[x++] = util_env_str("QUERY_STRING", args);
   24.83  
   24.84 -    /* Simulate CGI URIs by truncating path info */
   24.85 -    if( (u = pblock_findval("path-info", rq->vars)) ) {
   24.86 -        y = strlen(t) - strlen(u);
   24.87 -        if (y >= 0) {
   24.88 -            c = t[y];
   24.89 -            t[y] = '\0';
   24.90 -        }
   24.91 -        env[x++] = util_env_str("SCRIPT_NAME", t);
   24.92 -        if (y >= 0) {
   24.93 -            t[y] = c;
   24.94 +    // set REQUEST_URI
   24.95 +    if (rq->orig_rq) {
   24.96 +        t = get_request_uri(rq->orig_rq);
   24.97 +    } else {
   24.98 +        t = get_request_uri(rq);
   24.99 +    }
  24.100 +    if (t) {
  24.101 +        env[x++] = util_env_str("REQUEST_URI", t);
  24.102 +        FREE(t);
  24.103 +    }
  24.104 +
  24.105 +    if (scriptVars) {
  24.106 +        t = pblock_findval("uri", pb);
  24.107 +
  24.108 +        /* Simulate CGI URIs by truncating path info */
  24.109 +        if ((u = pblock_findval("path-info", rq->vars))) {
  24.110 +            y = strlen(t) - strlen(u);
  24.111 +            if (y >= 0) {
  24.112 +                c = t[y];
  24.113 +                t[y] = '\0';
  24.114 +            }
  24.115 +            env[x++] = util_env_str("SCRIPT_NAME", t);
  24.116 +            if (y >= 0) {
  24.117 +                t[y] = c;
  24.118 +            }
  24.119 +
  24.120 +            env[x++] = util_env_str("PATH_INFO", u);
  24.121 +            if((t = INTservact_translate_uri2(u, sn, rq))) {
  24.122 +                env[x++] = util_env_str("PATH_TRANSLATED", t);
  24.123 +                // keep path-translated in rq->vars since we may need it
  24.124 +                // during fastcgi processing
  24.125 +                pblock_nvinsert("path-translated", t, rq->vars);
  24.126 +                FREE(t);
  24.127 +            }
  24.128 +        } else {
  24.129 +            env[x++] = util_env_str("SCRIPT_NAME", t);
  24.130          }
  24.131  
  24.132 -        env[x++] = util_env_str("PATH_INFO", u);
  24.133 -        if((t = INTservact_translate_uri2(u, sn, rq))) {
  24.134 -            env[x++] = util_env_str("PATH_TRANSLATED", t);
  24.135 -            FREE(t);
  24.136 -        }
  24.137 +        if (t = pblock_findval("path", rq->vars))
  24.138 +            env[x++] = util_env_str("SCRIPT_FILENAME", t);
  24.139      }
  24.140 -    else
  24.141 -        env[x++] = util_env_str("SCRIPT_NAME", t);
  24.142 -
  24.143 -    if(args)
  24.144 -        env[x++] = util_env_str("QUERY_STRING", args);
  24.145  
  24.146      env[x] = NULL;
  24.147 -
  24.148      return env;
  24.149  }
  24.150  
  24.151 @@ -1190,7 +1249,7 @@
  24.152      char **env;
  24.153      env = http_hdrs2env(rq->headers);
  24.154      env = cgi_common_vars(sn, rq, env);
  24.155 -    env = cgi_specific_vars(sn, rq, args, env);
  24.156 +    env = cgi_specific_vars(sn, rq, args, env, 1); // 1 implies add all variables
  24.157      if(env == NULL) {
  24.158          log_error(LOG_FAILURE, "send-cgi", sn, rq, 
  24.159                    XP_GetAdminStr(DBT_cgiError21), "cgi specific variables");
  24.160 @@ -1422,3 +1481,4 @@
  24.161  {
  24.162      return _initenv;
  24.163  }
  24.164 +
    25.1 --- a/src/server/safs/cgi.h	Sun Jan 18 01:43:32 2009 -0800
    25.2 +++ b/src/server/safs/cgi.h	Thu May 07 03:20:10 2009 -0700
    25.3 @@ -42,6 +42,7 @@
    25.4  // cgi
    25.5  const pblock* GetCgiInitEnv();
    25.6  NSAPI_PUBLIC char** cgi_common_vars(Session *sn, Request *rq, char **env);
    25.7 +NSAPI_PUBLIC char** cgi_specific_vars(Session *sn, Request *rq, const char *args, char **env, int scriptVars);
    25.8  void cgi_add_var(const char *name, const char *value);
    25.9  void cgi_set_timeout(PRIntervalTime timeout);
   25.10  void cgi_set_idle_timeout(PRIntervalTime timeout);
    26.1 --- a/src/server/safs/dbtsafs.h	Sun Jan 18 01:43:32 2009 -0800
    26.2 +++ b/src/server/safs/dbtsafs.h	Thu May 07 03:20:10 2009 -0700
    26.3 @@ -324,4 +324,6 @@
    26.4      ResDef(DBT_MalformedPathX, 393, "CORE4393: malformed path: %s")
    26.5      ResDef(DBT_pcheckError15, 394, "HTTP4394: missing parameter (need bong-file)")
    26.6      ResDef(DBT_nsfcsafEreport23, 395, "HTTP4395: Failed to set the max open descriptor in file cache")
    26.7 +    ResDef(DBT_flexLogError4, 396, "HTTP4396: Log file %s should be removed before changing its format (ASCII <--> Binary)")
    26.8 +    ResDef(DBT_flexLogError5, 397, "HTTP4397: Binary log file version mismatch error. Please remove the log file and restart the server" )
    26.9  END_STR(safs)
    27.1 --- a/src/server/safs/dump.cpp	Sun Jan 18 01:43:32 2009 -0800
    27.2 +++ b/src/server/safs/dump.cpp	Thu May 07 03:20:10 2009 -0700
    27.3 @@ -655,7 +655,8 @@
    27.4                  thread->lock();
    27.5  
    27.6                  PRUint32 mode = thread->threadStats.mode;
    27.7 -                if (mode != STATS_THREAD_EMPTY && mode != STATS_THREAD_IDLE) {
    27.8 +                if (mode != STATS_THREAD_EMPTY && mode != STATS_THREAD_IDLE &&
    27.9 +                    mode != STATS_THREAD_KEEPALIVE) {
   27.10                      rows[y].columns[SESSION_COLUMN_PROCESS].printf("%u", process->procStats.pid);
   27.11                      rows[y].columns[SESSION_COLUMN_STATUS] = StatsManager::getMode(&thread->threadStats);
   27.12  
    28.1 --- a/src/server/safs/flexlog.cpp	Sun Jan 18 01:43:32 2009 -0800
    28.2 +++ b/src/server/safs/flexlog.cpp	Thu May 07 03:20:10 2009 -0700
    28.3 @@ -37,78 +37,24 @@
    28.4   * Don Eastman, imported by Mike McCool 
    28.5   */
    28.6  
    28.7 -#include "netsite.h"
    28.8 -#include "support/NSString.h"
    28.9 -#include "time/nstime.h"
   28.10 -#include "base/util.h"
   28.11 -#include "base/date.h"
   28.12  #include "base/ereport.h"
   28.13  #include "base/vs.h"
   28.14  #include "frame/accel.h"
   28.15  #include "frame/conf.h"
   28.16 -#include "frame/log.h"
   28.17 -#include "frame/object.h"
   28.18 -#include "safs/flexlog.h"
   28.19  #include "safs/dbtsafs.h"
   28.20  #include "httpdaemon/vsconf.h"
   28.21  #include "httpdaemon/connqueue.h"
   28.22  #include "httpdaemon/httpheader.h"
   28.23  #include "httpdaemon/logmanager.h"
   28.24 +#include "generated/ServerXMLSchema/AccessLogMode.h"
   28.25 +#include "flexlogcommon.h"
   28.26  
   28.27 +/* Check binlog.cpp for binary mode file format */
   28.28  
   28.29  /*
   28.30   * DEFAULT_LOG_NAME is the log name used when none is explicitly specified.
   28.31   */
   28.32  #define DEFAULT_LOG_NAME "default"
   28.33 -
   28.34 -/*
   28.35 - * FORMAT_PREFIX is the prefix for the format line in a log file.  The format
   28.36 - * line records the log format in use in that log file.
   28.37 - */
   28.38 -#define FORMAT_PREFIX "format="
   28.39 -
   28.40 -/*
   28.41 - * FORMAT_PREFIX_LEN is the number of characters in FORMAT_PREFIX (not
   28.42 - * including any trailing '\0).
   28.43 - */
   28.44 -#define FORMAT_PREFIX_LEN (sizeof(FORMAT_PREFIX) - 1)
   28.45 -
   28.46 -/*
   28.47 - * FORMAT_LEN is the maximum length of the format string in a log file's
   28.48 - * format line, not including the "format=" prefix or trailing EOL.
   28.49 - */
   28.50 -#define FORMAT_LEN (FORMAT_LINE_LEN - FORMAT_PREFIX_LEN - ENDLINE_LEN)
   28.51 -
   28.52 -/*
   28.53 - * FORMAT_LINE_LEN is the maximum length of the format line in a log file,
   28.54 - * including the "format=" prefix and trailing EOL.
   28.55 - */
   28.56 -#define FORMAT_LINE_LEN 2048
   28.57 -
   28.58 -/*
   28.59 - * TIME_PREFIX is the prefix for the optional time line in a log file.  The
   28.60 - * time line records the base time from which %RELATIVETIME% values are
   28.61 - * computed.
   28.62 - */
   28.63 -#define TIME_PREFIX "time="
   28.64 -
   28.65 -/*
   28.66 - * TIME_PREFIX_LEN is the number of characters in TIME_PREFIX (not including
   28.67 - * any trailing '\0).
   28.68 - */
   28.69 -#define TIME_PREFIX_LEN (sizeof(TIME_PREFIX) - 1)
   28.70 -
   28.71 -/*
   28.72 - * TIME_LINE_LEN is the maximum length of the time line in a log file,
   28.73 - * including the "time=" prefix and trailing EOL.
   28.74 - */
   28.75 -#define TIME_LINE_LEN (TIME_PREFIX_LEN + UTIL_I64TOA_SIZE + ENDLINE_LEN)
   28.76 -
   28.77 -/*
   28.78 - * ENDLINE_LEN is the number of characters in an EOL (not including any
   28.79 - * trailing '\0').
   28.80 - */
   28.81 -#define ENDLINE_LEN (sizeof(ENDLINE) - 1)
   28.82  
   28.83  /*
   28.84   * DOT_DOT_DOT_LEN is the length of the "..." suffix we attach to truncated
   28.85 @@ -125,110 +71,6 @@
   28.86   * TOKENS_ARRAY_INCSIZE is the allocation quantum for the tokens[] array.
   28.87   */
   28.88  #define TOKENS_ARRAY_INCSIZE 8
   28.89 -
   28.90 -/*
   28.91 - * flex_scan_percent_token groks the following tokens.
   28.92 - */
   28.93 -#define SYSDATE                                "SYSDATE"
   28.94 -#define LOCALEDATE                             "LOCALEDATE"
   28.95 -#define TIME                                   "TIME"
   28.96 -#define RELATIVETIME                           "RELATIVETIME"
   28.97 -#define SES_CLIENT_IP                          "Ses->client.ip"
   28.98 -#define REQ_METHOD_NUM                         "Req->method_num"
   28.99 -#define REQ_PROTV_NUM                          "Req->protv_num"
  28.100 -#define REQ_REQPB_CLF_REQUEST                  "Req->reqpb.clf-request"
  28.101 -#define REQ_REQPB_CLF_REQUEST_METHOD           "Req->reqpb.clf-request.method"
  28.102 -#define REQ_REQPB_CLF_REQUEST_URI              "Req->reqpb.clf-request.uri"
  28.103 -#define REQ_REQPB_CLF_REQUEST_URI_ABS_PATH     "Req->reqpb.clf-request.uri.abs_path"
  28.104 -#define REQ_REQPB_CLF_REQUEST_URI_QUERY        "Req->reqpb.clf-request.uri.query"
  28.105 -#define REQ_REQPB_CLF_REQUEST_PROTOCOL         "Req->reqpb.clf-request.protocol"
  28.106 -#define REQ_REQPB_CLF_REQUEST_PROTOCOL_NAME    "Req->reqpb.clf-request.protocol.name"
  28.107 -#define REQ_REQPB_CLF_REQUEST_PROTOCOL_VERSION "Req->reqpb.clf-request.protocol.version"
  28.108 -#define REQ_REQPB_METHOD                       "Req->reqpb.method"
  28.109 -#define REQ_SRVHDRS_CLF_STATUS                 "Req->srvhdrs.clf-status"
  28.110 -#define REQ_SRVHDRS_STATUS_CODE                "Req->srvhdrs.status.code"
  28.111 -#define REQ_SRVHDRS_STATUS_REASON              "Req->srvhdrs.status.reason"
  28.112 -#define REQ_SRVHDRS_CONTENT_LENGTH             "Req->srvhdrs.content-length"
  28.113 -#define REQ_HEADERS_REFERER                    "Req->headers.referer"
  28.114 -#define REQ_HEADERS_USER_AGENT                 "Req->headers.user-agent"
  28.115 -#define REQ_VARS_AUTH_USER                     "Req->vars.auth-user"
  28.116 -#define VSID                                   "vsid"
  28.117 -#define DURATION                               "duration"
  28.118 -#define SUBSYSTEM                              "subsystem"
  28.119 -#define REQ_HEADERS_COOKIE_PREFIX              "Req->headers.cookie."
  28.120 -#define REQ_HEADERS_COOKIE_PREFIX_LEN          (sizeof(REQ_HEADERS_COOKIE_PREFIX) - 1)
  28.121 -
  28.122 -/*
  28.123 - * FlexTokenType identifies the type of token that was parsed from a flex-log
  28.124 - * format string.
  28.125 - */
  28.126 -enum FlexTokenType {
  28.127 -    TOKEN_TEXT_OFFSET,
  28.128 -    TOKEN_TEXT_POINTER,
  28.129 -    TOKEN_MODEL,
  28.130 -    TOKEN_SYSDATE,
  28.131 -    TOKEN_LOCALEDATE,
  28.132 -    TOKEN_TIME,
  28.133 -    TOKEN_RELATIVETIME,
  28.134 -    TOKEN_IP,
  28.135 -    TOKEN_DNS,
  28.136 -    TOKEN_METHOD_NUM,
  28.137 -    TOKEN_PROTV_NUM,
  28.138 -    TOKEN_REQUEST_LINE,
  28.139 -    TOKEN_REQUEST_LINE_URI,
  28.140 -    TOKEN_REQUEST_LINE_URI_ABS_PATH,
  28.141 -    TOKEN_REQUEST_LINE_URI_QUERY,
  28.142 -    TOKEN_REQUEST_LINE_PROTOCOL,
  28.143 -    TOKEN_REQUEST_LINE_PROTOCOL_NAME,
  28.144 -    TOKEN_REQUEST_LINE_PROTOCOL_VERSION,
  28.145 -    TOKEN_METHOD,
  28.146 -    TOKEN_STATUS_CODE,
  28.147 -    TOKEN_STATUS_REASON,
  28.148 -    TOKEN_CONTENT_LENGTH,
  28.149 -    TOKEN_REFERER,
  28.150 -    TOKEN_USER_AGENT,
  28.151 -    TOKEN_AUTH_USER,
  28.152 -    TOKEN_VSID,
  28.153 -    TOKEN_DURATION,
  28.154 -    TOKEN_SUBSYSTEM,
  28.155 -    TOKEN_COOKIE,
  28.156 -    TOKEN_PB_KEY,
  28.157 -    TOKEN_PB_NAME,
  28.158 -    TOKEN_SN_CLIENT_KEY,
  28.159 -    TOKEN_SN_CLIENT_NAME,
  28.160 -    TOKEN_RQ_VARS_KEY,
  28.161 -    TOKEN_RQ_VARS_NAME,
  28.162 -    TOKEN_RQ_REQPB_KEY,
  28.163 -    TOKEN_RQ_REQPB_NAME,
  28.164 -    TOKEN_RQ_HEADERS_KEY,
  28.165 -    TOKEN_RQ_HEADERS_NAME,
  28.166 -    TOKEN_RQ_SRVHDRS_KEY,
  28.167 -    TOKEN_RQ_SRVHDRS_NAME
  28.168 -};
  28.169 -
  28.170 -/*
  28.171 - * FlexToken describes a token that was parsed from a flex-log format string.
  28.172 - */
  28.173 -struct FlexToken {
  28.174 -    FlexTokenType type;
  28.175 -    char *p;
  28.176 -    int offset;
  28.177 -    int len;
  28.178 -    ModelString *model;
  28.179 -    const pb_key *key;
  28.180 -};
  28.181 -
  28.182 -/*
  28.183 - * FlexFormat defines the format of a log file.
  28.184 - */
  28.185 -struct FlexFormat {
  28.186 -    FlexFormat *next;  // next FlexFormat in flex_format_list
  28.187 -    char *format;      // flex-log format string
  28.188 -    FlexToken *tokens; // parsed tokens
  28.189 -    int ntokens;       // number of elements in tokens[]
  28.190 -    PRBool accel;      // set if tokens can be retrieved from the accelerator
  28.191 -    int refcount;      // number of references (excluding flex_format_list's)
  28.192 -};
  28.193  
  28.194  /*
  28.195   * FlexTemplate is a log file template defined by the flex-init SAF.
  28.196 @@ -258,6 +100,7 @@
  28.197  struct FlexFormatted {
  28.198      const char *p;
  28.199      int len;
  28.200 +    PRBool appendNull;
  28.201  };
  28.202  
  28.203  /*
  28.204 @@ -350,6 +193,7 @@
  28.205      case TOKEN_AUTH_USER:
  28.206      case TOKEN_VSID:
  28.207      case TOKEN_SUBSYSTEM:
  28.208 +    case TOKEN_RECORD_SIZE:
  28.209          return PR_TRUE;
  28.210  
  28.211      default:
  28.212 @@ -453,7 +297,8 @@
  28.213  
  28.214  /* ----------------------- flex_scan_percent_token ------------------------ */
  28.215  
  28.216 -static const char *flex_scan_percent_token(FlexFormat *f, const char *p)
  28.217 +extern "C" NSAPI_PUBLIC
  28.218 +const char *flex_scan_percent_token(FlexFormat *f, const char *p)
  28.219  {
  28.220      PR_ASSERT(*p == '%');
  28.221  
  28.222 @@ -541,7 +386,8 @@
  28.223  
  28.224  /* ------------------------ flex_scan_dollar_token ------------------------ */
  28.225  
  28.226 -static const char *flex_scan_dollar_token(FlexFormat *f, const char *p)
  28.227 +extern "C" NSAPI_PUBLIC
  28.228 +const char *flex_scan_dollar_token(FlexFormat *f, const char *p)
  28.229  {
  28.230      PR_ASSERT(*p == '$');
  28.231  
  28.232 @@ -568,7 +414,8 @@
  28.233  
  28.234  /* ------------------------- flex_scan_text_token ------------------------- */
  28.235  
  28.236 -static const char *flex_scan_text_token(FlexFormat *f, const char *p)
  28.237 +extern "C" NSAPI_PUBLIC
  28.238 +const char *flex_scan_text_token(FlexFormat *f, const char *p)
  28.239  {
  28.240      NSString text;
  28.241  
  28.242 @@ -590,7 +437,8 @@
  28.243  
  28.244  /* ------------------------- flex_acquire_format -------------------------- */
  28.245  
  28.246 -static FlexFormat *flex_acquire_format(const char *format)
  28.247 +static FlexFormat *flex_acquire_format(const char *format,
  28.248 +                                       PRBool binary = PR_FALSE)
  28.249  {
  28.250      PR_Lock(flex_format_lock);
  28.251  
  28.252 @@ -613,6 +461,10 @@
  28.253              f->ntokens = 0;
  28.254              f->accel = PR_TRUE;
  28.255              f->refcount = 1; // reference for caller
  28.256 +
  28.257 +            // In binary log first write record length and then the line
  28.258 +            if (binary)
  28.259 +                flex_add_token(f, TOKEN_RECORD_SIZE);
  28.260  
  28.261              // Parse the format string into tokens
  28.262              const char *p = f->format;
  28.263 @@ -791,6 +643,20 @@
  28.264      return protocol;
  28.265  }
  28.266  
  28.267 +/* -------------------------- flex_format_binary -------------------------- */
  28.268 +/* T can be anything like short or PRInt64 */
  28.269 +template <class T>
  28.270 +static inline int flex_format_binary(pool_handle_t *pool, T i, const char **p)
  28.271 +{
  28.272 +    int len = sizeof(T);
  28.273 +    char *buf = (char *)pool_malloc(pool, len);
  28.274 +    if (!buf)
  28.275 +        return -1;
  28.276 +
  28.277 +    memcpy((void *)buf, &i, len);
  28.278 +    *p = buf;
  28.279 +    return len;
  28.280 +}
  28.281  
  28.282  /* --------------------------- flex_format_date --------------------------- */
  28.283  
  28.284 @@ -810,10 +676,42 @@
  28.285      return -1;
  28.286  }
  28.287  
  28.288 +/* --------------------------- flex_format_time --------------------------- */
  28.289 +
  28.290 +extern "C" NSAPI_PUBLIC
  28.291 +int flex_format_time(pool_handle_t *pool, time_t tim, int type, const char **p)
  28.292 +{
  28.293 +    const int size = 64; // big enough for CLF or any "reasonable" locale
  28.294 +    char *buf = (char *) pool_malloc(pool, size);
  28.295 +    if (!buf)
  28.296 +        return -1;
  28.297 +
  28.298 +    int len = 0;
  28.299 +    switch(type) {
  28.300 +        case TOKEN_SYSDATE :
  28.301 +            len = date_format_time(tim, date_format_clf, buf, size);
  28.302 +            break;
  28.303 +        case TOKEN_LOCALEDATE :
  28.304 +            len = date_format_time(tim, date_format_locale, buf, size);
  28.305 +            break;
  28.306 +        default :
  28.307 +            break;
  28.308 +    }
  28.309 +
  28.310 +    if (len <= 0) {
  28.311 +        pool_free(pool, (void *)buf);
  28.312 +        buf = NULL;
  28.313 +    }
  28.314 +
  28.315 +    *p = buf;
  28.316 +    return len;
  28.317 +}
  28.318 +
  28.319  
  28.320  /* ---------------------------- flex_format_64 ---------------------------- */
  28.321  
  28.322 -static inline int flex_format_64(pool_handle_t *pool, PRInt64 v, const char **p)
  28.323 +extern "C" NSAPI_PUBLIC
  28.324 +int flex_format_64(pool_handle_t *pool, PRInt64 v, const char **p)
  28.325  {
  28.326      char *buf = (char *) pool_malloc(pool, UTIL_I64TOA_SIZE);
  28.327      if (!buf)
  28.328 @@ -922,13 +820,14 @@
  28.329  
  28.330  /* ------------------------- flex_format_duration ------------------------- */
  28.331  
  28.332 -static inline int flex_format_duration(Session *sn, Request *rq, const char **p)
  28.333 +static inline int flex_format_duration(Session *sn, Request *rq,
  28.334 +                                       const char **p, PRBool binary)
  28.335  {
  28.336      PRIntervalTime start_ticks;
  28.337      if (request_get_start_interval(rq, &start_ticks) != PR_SUCCESS)
  28.338          return -1;
  28.339  
  28.340 -    const int size = 15; // big enough for a year
  28.341 +    const int size = binary ? sizeof(PRUint64) : 15; // big enough for a year
  28.342      char *buf = (char *) pool_malloc(sn->pool, size);
  28.343      if (!buf)
  28.344          return -1;
  28.345 @@ -939,6 +838,11 @@
  28.346          int elapsed_s = ft_time() - rq->req_start;
  28.347          if (elapsed_s > flex_max_seconds / 2) {
  28.348              // Format duration as s*1000000 to avoid PRIntervalTime overflow
  28.349 +            if (binary) {
  28.350 +                PRUint64 t = elapsed_s*1000000;
  28.351 +                memcpy(buf, &t, size);
  28.352 +                return size;
  28.353 +            }
  28.354              return PR_snprintf(buf, size, "%d000000", elapsed_s);
  28.355          }
  28.356      }
  28.357 @@ -946,6 +850,10 @@
  28.358      PRUint64 elapsed_ticks = PR_IntervalNow() - start_ticks;
  28.359      PRUint64 elapsed_us = elapsed_ticks * flex_us_per_tick;
  28.360  
  28.361 +    if (binary) {
  28.362 +        memcpy(buf, &elapsed_us, size);
  28.363 +        return size;
  28.364 +    }
  28.365      return PR_snprintf(buf, size, "%llu", elapsed_us);
  28.366  }
  28.367  
  28.368 @@ -992,6 +900,7 @@
  28.369  {
  28.370      const FlexFormat *f = log->format;
  28.371      int pos = 0;
  28.372 +    int nullCount = 0;
  28.373  
  28.374      // Format tokens for a request served by NSAPI
  28.375      for (int ti = 0; ti < f->ntokens; ti++) {
  28.376 @@ -999,11 +908,17 @@
  28.377  
  28.378          const char *p = NULL;
  28.379          int len = -1;
  28.380 +        formatted[ti].appendNull = PR_FALSE;
  28.381  
  28.382          switch (t->type) {
  28.383          case TOKEN_TEXT_OFFSET:
  28.384              p = f->format + t->offset;
  28.385 -            len = t->len;
  28.386 +            // not writing beautification stuff in binary log
  28.387 +            if (f->binary) {
  28.388 +                len = 0;
  28.389 +            } else {
  28.390 +                len = t->len;
  28.391 +            }
  28.392              break;
  28.393  
  28.394          case TOKEN_TEXT_POINTER:
  28.395 @@ -1014,22 +929,43 @@
  28.396          case TOKEN_MODEL:
  28.397              if (model_str_interpolate(t->model, sn, rq, &p, &len))
  28.398                  log_error(LOG_VERBOSE, "flex-log", sn, rq, "error interpolating format (%s)", system_errmsg());
  28.399 +            else if (f->binary && p && (len > 0)) {  // for '\0'
  28.400 +                formatted[ti].appendNull = PR_TRUE;
  28.401 +                nullCount++;
  28.402 +            }
  28.403              break;
  28.404  
  28.405          case TOKEN_SYSDATE:
  28.406 -            len = flex_format_date(sn->pool, date_format_clf, &p);
  28.407 +            if (f->binary)
  28.408 +                len = flex_format_binary <PRInt64> (sn->pool, (PRInt64)
  28.409 +                                                    ft_time(), &p);
  28.410 +            else
  28.411 +                len = flex_format_date(sn->pool, date_format_clf, &p);
  28.412              break;
  28.413  
  28.414          case TOKEN_LOCALEDATE:
  28.415 -            len = flex_format_date(sn->pool, date_format_locale, &p);
  28.416 +            if (f->binary)
  28.417 +                len = flex_format_binary <PRInt64> (sn->pool, (PRInt64)
  28.418 +                                                    ft_time(), &p);
  28.419 +            else
  28.420 +                len = flex_format_date(sn->pool, date_format_locale, &p);
  28.421              break;
  28.422  
  28.423          case TOKEN_TIME:
  28.424 -            len = flex_format_64(sn->pool, ft_time(), &p);
  28.425 +            if (f->binary)
  28.426 +                len = flex_format_binary <PRInt64> (sn->pool, (PRInt64)
  28.427 +                                                    ft_time(), &p);
  28.428 +            else
  28.429 +                len = flex_format_64(sn->pool, ft_time(), &p);
  28.430              break;
  28.431  
  28.432          case TOKEN_RELATIVETIME:
  28.433 -            len = flex_format_64(sn->pool, (PRInt64) ft_time() - log->epoch, &p);
  28.434 +            if (f->binary)
  28.435 +                len = flex_format_binary <PRInt64> (sn->pool, (PRInt64) 
  28.436 +                                            (ft_time() - log->epoch), &p);
  28.437 +            else
  28.438 +                len = flex_format_64(sn->pool, (PRInt64) ft_time()
  28.439 +                                     - log->epoch, &p);
  28.440              break;
  28.441  
  28.442          case TOKEN_IP:
  28.443 @@ -1044,11 +980,19 @@
  28.444              break;
  28.445  
  28.446          case TOKEN_METHOD_NUM:
  28.447 -            len = flex_format_method_num(sn->pool, rq->method_num, &p);
  28.448 +            if (f->binary)
  28.449 +                len = flex_format_binary <short> (sn->pool, (short)
  28.450 +                                                  rq->method_num, &p);
  28.451 +            else
  28.452 +                len = flex_format_method_num(sn->pool, rq->method_num, &p);
  28.453              break;
  28.454  
  28.455          case TOKEN_PROTV_NUM:
  28.456 -            len = flex_format_protv_num(sn->pool, rq->protv_num, &p);
  28.457 +            if (f->binary)
  28.458 +                len = flex_format_binary <short>(sn->pool, (short)
  28.459 +                                                 rq->protv_num, &p);
  28.460 +            else
  28.461 +                len = flex_format_protv_num(sn->pool, rq->protv_num, &p);
  28.462              break;
  28.463  
  28.464          case TOKEN_REQUEST_LINE:
  28.465 @@ -1060,6 +1004,10 @@
  28.466              p = flex_skip_method(p);
  28.467              if (p)
  28.468                  for (len = 0; p[len] && !isspace(p[len]); len++);
  28.469 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.470 +                formatted[ti].appendNull = PR_TRUE;
  28.471 +                nullCount++;
  28.472 +            }
  28.473              break;
  28.474  
  28.475          case TOKEN_REQUEST_LINE_URI_ABS_PATH:
  28.476 @@ -1067,6 +1015,10 @@
  28.477              p = flex_skip_method(p);
  28.478              if (p)
  28.479                  for (len = 0; p[len] && p[len] != '?' && !isspace(p[len]); len++);
  28.480 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.481 +                formatted[ti].appendNull = PR_TRUE;
  28.482 +                nullCount++;
  28.483 +            }
  28.484              break;
  28.485  
  28.486          case TOKEN_REQUEST_LINE_URI_QUERY:
  28.487 @@ -1074,6 +1026,10 @@
  28.488              p = flex_skip_prefix(p, '?');
  28.489              if (p)
  28.490                  for (len = 0; p[len] && !isspace(p[len]); len++);
  28.491 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.492 +                formatted[ti].appendNull = PR_TRUE;
  28.493 +                nullCount++;
  28.494 +            }
  28.495              break;
  28.496  
  28.497          case TOKEN_REQUEST_LINE_PROTOCOL:
  28.498 @@ -1084,6 +1040,10 @@
  28.499              p = flex_get_request_line_protocol(rq);
  28.500              if (p)
  28.501                  for (len = 0; p[len] && p[len] != '/'; len++);
  28.502 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.503 +                formatted[ti].appendNull = PR_TRUE;
  28.504 +                nullCount++;
  28.505 +            }
  28.506              break;
  28.507  
  28.508          case TOKEN_REQUEST_LINE_PROTOCOL_VERSION:
  28.509 @@ -1097,8 +1057,14 @@
  28.510  
  28.511          case TOKEN_STATUS_CODE:
  28.512              p = pblock_findkeyval(pb_key_status, rq->srvhdrs);
  28.513 -            if (p && p[0] && p[1] && p[2])
  28.514 -                len = 3;
  28.515 +            if (p && p[0] && p[1] && p[2]) {
  28.516 +                if (f->binary) {
  28.517 +                    short s = atoi(p);
  28.518 +                    len = flex_format_binary <short> (sn->pool, s, &p);
  28.519 +                } else {
  28.520 +                    len = 3;
  28.521 +                }
  28.522 +            }
  28.523              break;
  28.524  
  28.525          case TOKEN_STATUS_REASON:
  28.526 @@ -1112,6 +1078,10 @@
  28.527  
  28.528          case TOKEN_CONTENT_LENGTH:
  28.529              p = pblock_findkeyval(pb_key_content_length, rq->srvhdrs);
  28.530 +            if (f->binary && p) {
  28.531 +                PRInt64 cl = util_atoi64(p);
  28.532 +                len = flex_format_binary <PRInt64> (sn->pool, cl, &p);
  28.533 +            }
  28.534              break;
  28.535  
  28.536          case TOKEN_REFERER:
  28.537 @@ -1131,16 +1101,24 @@
  28.538              break;
  28.539  
  28.540          case TOKEN_DURATION:
  28.541 -            len = flex_format_duration(sn, rq, &p);
  28.542 +            len = flex_format_duration(sn, rq, &p, f->binary);
  28.543              break;
  28.544  
  28.545          case TOKEN_SUBSYSTEM:
  28.546              p = "NSAPI";
  28.547              len = 5;
  28.548 +            if (f->binary) { // for '\0'
  28.549 +                formatted[ti].appendNull = PR_TRUE;
  28.550 +                nullCount++;
  28.551 +            }
  28.552              break;
  28.553  
  28.554          case TOKEN_COOKIE:
  28.555              len = flex_format_cookie(sn, rq, t->p, &p);
  28.556 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.557 +                formatted[ti].appendNull = PR_TRUE;
  28.558 +                nullCount++;
  28.559 +            }
  28.560              break;
  28.561  
  28.562          case TOKEN_PB_KEY:
  28.563 @@ -1190,6 +1168,11 @@
  28.564          case TOKEN_RQ_SRVHDRS_NAME:
  28.565              p = pblock_findval(t->p, rq->srvhdrs);
  28.566              break;
  28.567 +        case TOKEN_RECORD_SIZE:
  28.568 +            // Field to add buffer length
  28.569 +            len = sizeof(PRInt32);
  28.570 +            p = (char *)pool_malloc(sn->pool, len);
  28.571 +            break;
  28.572  
  28.573          default:
  28.574              PR_ASSERT(0);
  28.575 @@ -1197,11 +1180,22 @@
  28.576          }
  28.577  
  28.578          if (p) {
  28.579 -            if (len == -1)
  28.580 +            if (len == -1) {
  28.581                  len = strlen(p);
  28.582 +                if (f->binary) { // for '\0'
  28.583 +                    formatted[ti].appendNull = PR_TRUE;
  28.584 +                    nullCount++;
  28.585 +                }
  28.586 +            }
  28.587          } else {
  28.588 -            p = "-";
  28.589 -            len = 1;
  28.590 +            if (f->binary) { // for '\0'
  28.591 +                len = 0;
  28.592 +                formatted[ti].appendNull = PR_TRUE;
  28.593 +                nullCount++;
  28.594 +            } else {
  28.595 +                p = "-";
  28.596 +                len = 1;
  28.597 +            }
  28.598          }
  28.599  
  28.600          formatted[ti].p = p;
  28.601 @@ -1210,6 +1204,11 @@
  28.602          pos += len;
  28.603      }
  28.604  
  28.605 +    pos += nullCount;
  28.606 +    // We now have buffer length we add copy it in the first field
  28.607 +    if (f->binary)
  28.608 +        memcpy((void *)(formatted[0].p), (void *)&pos, sizeof(PRInt32));
  28.609 +
  28.610      return pos;
  28.611  }
  28.612  
  28.613 @@ -1220,6 +1219,7 @@
  28.614  {
  28.615      const FlexFormat *f = log->format;
  28.616      int pos = 0;
  28.617 +    int nullCount = 0;
  28.618  
  28.619      // Format tokens for a request served from the accelerator cache
  28.620      for (int ti = 0; ti < f->ntokens; ti++) {
  28.621 @@ -1229,11 +1229,17 @@
  28.622                
  28.623          const char *p = NULL;
  28.624          int len = -1;
  28.625 +        formatted[ti].appendNull = PR_FALSE;
  28.626  
  28.627          switch (t->type) {
  28.628          case TOKEN_TEXT_OFFSET:
  28.629              p = f->format + t->offset;
  28.630 -            len = t->len;
  28.631 +            // not writing beautification stuff in binary log
  28.632 +            if (f->binary) {
  28.633 +                len = 0;
  28.634 +            } else {
  28.635 +                len = t->len;
  28.636 +            }
  28.637              break;
  28.638  
  28.639          case TOKEN_TEXT_POINTER:
  28.640 @@ -1242,49 +1248,91 @@
  28.641              break;
  28.642  
  28.643          case TOKEN_SYSDATE:
  28.644 -            len = flex_format_date(pool, date_format_clf, &p);
  28.645 +            if (f->binary)
  28.646 +                len = flex_format_binary <PRInt64> (pool, (PRInt64)
  28.647 +                                                    ft_time(), &p);
  28.648 +            else
  28.649 +                len = flex_format_date(pool, date_format_clf, &p);
  28.650              break;
  28.651  
  28.652          case TOKEN_LOCALEDATE:
  28.653 -            len = flex_format_date(pool, date_format_locale, &p);
  28.654 +            if (f->binary)
  28.655 +                len = flex_format_binary <PRInt64> (pool, (PRInt64)
  28.656 +                                                    ft_time(), &p);
  28.657 +            else
  28.658 +                len = flex_format_date(pool, date_format_locale, &p);
  28.659              break;
  28.660  
  28.661          case TOKEN_TIME:
  28.662 -            len = flex_format_64(pool, ft_time(), &p);
  28.663 +            if (f->binary)
  28.664 +                len = flex_format_binary <PRInt64> (pool, (PRInt64)
  28.665 +                                                    ft_time(), &p);
  28.666 +            else
  28.667 +                len = flex_format_64(pool, ft_time(), &p);
  28.668              break;
  28.669  
  28.670          case TOKEN_RELATIVETIME:
  28.671 -            len = flex_format_64(pool, (PRInt64) ft_time() - log->epoch, &p);
  28.672 +            if (f->binary)
  28.673 +                len = flex_format_binary <PRInt64> (pool, (PRInt64) (ft_time()
  28.674 +                                                    - log->epoch), &p);
  28.675 +            else
  28.676 +                len = flex_format_64(pool, (PRInt64) ft_time() - log->epoch,
  28.677 +                                     &p);
  28.678              break;
  28.679  
  28.680          case TOKEN_IP:
  28.681              p = connection->remoteIP.buf;
  28.682              len = connection->remoteIP.len;
  28.683 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.684 +                formatted[ti].appendNull = PR_TRUE;
  28.685 +                nullCount++;
  28.686 +            }
  28.687              break;
  28.688  
  28.689          case TOKEN_METHOD_NUM:
  28.690              PR_ASSERT(METHOD_GET == 1);
  28.691 -            p = "1";
  28.692 -            len = 1;
  28.693 +            if (f->binary)
  28.694 +                len = flex_format_binary <short> (pool, (short)1, &p);
  28.695 +            else {
  28.696 +                p = "1";
  28.697 +                len = 1;
  28.698 +            }
  28.699              break;
  28.700  
  28.701          case TOKEN_PROTV_NUM:
  28.702 -            len = flex_format_protv_num(pool, connection->httpHeader.GetNegotiatedProtocolVersion(), &p);
  28.703 +            if (f->binary)
  28.704 +                len = flex_format_binary <short> (pool, (short)
  28.705 +                    connection->httpHeader.GetNegotiatedProtocolVersion(), &p);
  28.706 +            else
  28.707 +                len = flex_format_protv_num(pool, 
  28.708 +                    connection->httpHeader.GetNegotiatedProtocolVersion(), &p);
  28.709              break;
  28.710  
  28.711          case TOKEN_REQUEST_LINE:
  28.712              p = connection->httpHeader.GetRequestLine().ptr;
  28.713              len = connection->httpHeader.GetRequestLine().len;
  28.714 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.715 +                formatted[ti].appendNull = PR_TRUE;
  28.716 +                nullCount++;
  28.717 +            }
  28.718              break;
  28.719  
  28.720          case TOKEN_REQUEST_LINE_URI:
  28.721              p = connection->httpHeader.GetRequestAbsPath().ptr;
  28.722              len = connection->httpHeader.GetRequestAbsPath().len;
  28.723 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.724 +                formatted[ti].appendNull = PR_TRUE;
  28.725 +                nullCount++;
  28.726 +            }
  28.727              break;
  28.728  
  28.729          case TOKEN_REQUEST_LINE_URI_ABS_PATH:
  28.730              p = connection->httpHeader.GetRequestAbsPath().ptr;
  28.731              len = connection->httpHeader.GetRequestAbsPath().len;
  28.732 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.733 +                formatted[ti].appendNull = PR_TRUE;
  28.734 +                nullCount++;
  28.735 +            }
  28.736              break;
  28.737  
  28.738          case TOKEN_REQUEST_LINE_URI_QUERY:
  28.739 @@ -1292,37 +1340,71 @@
  28.740  
  28.741          case TOKEN_REQUEST_LINE_PROTOCOL:
  28.742              len = flex_format_protocol(pool, connection->httpHeader.GetClientProtocolVersion(), &p);
  28.743 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.744 +                formatted[ti].appendNull = PR_TRUE;
  28.745 +                nullCount++;
  28.746 +            }
  28.747              break;
  28.748  
  28.749          case TOKEN_REQUEST_LINE_PROTOCOL_NAME:
  28.750              p = "HTTP";
  28.751              len = 4;
  28.752 +            if (f->binary) { // for '\0'
  28.753 +                formatted[ti].appendNull = PR_TRUE;
  28.754 +                nullCount++;
  28.755 +            }
  28.756              break;
  28.757  
  28.758          case TOKEN_REQUEST_LINE_PROTOCOL_VERSION:
  28.759              len = flex_format_version(pool, connection->httpHeader.GetClientProtocolVersion(), &p);
  28.760 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.761 +                formatted[ti].appendNull = PR_TRUE;
  28.762 +                nullCount++;
  28.763 +            }
  28.764              break;
  28.765  
  28.766          case TOKEN_METHOD:
  28.767              p = "GET";
  28.768              len = 3;
  28.769 +            if (f->binary) { // for '\0'
  28.770 +                formatted[ti].appendNull = PR_TRUE;
  28.771 +                nullCount++;
  28.772 +            }
  28.773              break;
  28.774  
  28.775          case TOKEN_STATUS_CODE:
  28.776 -            p = status;
  28.777 -            len = status_len;
  28.778 +            if (f->binary) {
  28.779 +                if (status) {
  28.780 +                    short s = atoi(status);
  28.781 +                    len = flex_format_binary <short>(pool, s, &p);
  28.782 +                }
  28.783 +            } else {
  28.784 +                p = status;
  28.785 +                len = status_len;
  28.786 +            }
  28.787              break;
  28.788  
  28.789          case TOKEN_CONTENT_LENGTH:
  28.790 -            len = flex_format_64(pool, cl, &p);
  28.791 +            if (f->binary)
  28.792 +                len = flex_format_binary <PRInt64> (pool, cl, &p);
  28.793 +            else
  28.794 +                len = flex_format_64(pool, cl, &p);
  28.795              break;
  28.796  
  28.797          case TOKEN_REFERER:
  28.798              len = flex_format_hhstring(connection->httpHeader.GetReferer(), &p);
  28.799 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.800 +                formatted[ti].appendNull = PR_TRUE;
  28.801 +                nullCount++;
  28.802 +            }
  28.803              break;
  28.804  
  28.805          case TOKEN_USER_AGENT:
  28.806              len = flex_format_hhstring(connection->httpHeader.GetUserAgent(), &p);
  28.807 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.808 +                formatted[ti].appendNull = PR_TRUE;
  28.809 +                nullCount++;
  28.810 +            }
  28.811              break;
  28.812  
  28.813          case TOKEN_AUTH_USER:
  28.814 @@ -1331,12 +1413,26 @@
  28.815          case TOKEN_VSID:
  28.816              p = vsid;
  28.817              len = vsid_len;
  28.818 +            if (f->binary && p && (len > 0)) { // for '\0'
  28.819 +                formatted[ti].appendNull = PR_TRUE;
  28.820 +                nullCount++;
  28.821 +            }
  28.822              break;
  28.823  
  28.824          case TOKEN_SUBSYSTEM:
  28.825              // XXX elving differentiate between sync and async in log
  28.826              p = "cache";
  28.827              len = 5;
  28.828 +            if (f->binary) { // for '\0'
  28.829 +                formatted[ti].appendNull = PR_TRUE;
  28.830 +                nullCount++;
  28.831 +            }
  28.832 +            break;
  28.833 +
  28.834 +        case TOKEN_RECORD_SIZE:
  28.835 +            // Field for buffer length
  28.836 +            len = sizeof(PRInt32);
  28.837 +            p = (char *)pool_malloc(pool, len);
  28.838              break;
  28.839  
  28.840          default:
  28.841 @@ -1346,11 +1442,22 @@
  28.842          }
  28.843  
  28.844          if (p) {
  28.845 -            if (len == -1)
  28.846 +            if (len == -1) {
  28.847                  len = strlen(p);
  28.848 +                if (f->binary) { // for '\0'
  28.849 +                    formatted[ti].appendNull = PR_TRUE;
  28.850 +                    nullCount++;
  28.851 +                }
  28.852 +            }
  28.853          } else {
  28.854 -            p = "-";
  28.855 -            len = 1;
  28.856 +            if (f->binary) { // for '\0'
  28.857 +                len = 0;
  28.858 +                formatted[ti].appendNull = PR_TRUE;
  28.859 +                nullCount++;
  28.860 +            } else {
  28.861 +                p = "-";
  28.862 +                len = 1;
  28.863 +            }
  28.864          }
  28.865  
  28.866          formatted[ti].p = p;
  28.867 @@ -1359,13 +1466,19 @@
  28.868          pos += len;
  28.869      }
  28.870  
  28.871 +    pos += nullCount;
  28.872 +    // We now have buffer length we add copy it in the first field
  28.873 +    if (f->binary)
  28.874 +        memcpy((void *)(formatted[0].p), (void *)&pos, sizeof(PRInt32));
  28.875 +
  28.876      return pos;
  28.877  }
  28.878  
  28.879  
  28.880  /* ----------------------------- flex_memcpy ------------------------------ */
  28.881  
  28.882 -static inline void flex_memcpy(char *buf, int& pos, const char *p, int len)
  28.883 +static inline void flex_memcpy(char *buf, int& pos, const char *p, int len,
  28.884 +                               PRBool appendNull)
  28.885  {
  28.886      // Access log format strings tend to contain a number of extremely short
  28.887      // strings, so skip the memcpy call when it makes sense
  28.888 @@ -1380,6 +1493,8 @@
  28.889          pos += len;
  28.890          break;
  28.891      }
  28.892 +    if (appendNull)
  28.893 +        buf[pos++] = '\0';
  28.894  }
  28.895  
  28.896  
  28.897 @@ -1407,9 +1522,10 @@
  28.898  
  28.899  /* --------------------------- flex_read_header --------------------------- */
  28.900  
  28.901 -static int flex_read_header(const char *filename, NSString& format, NSString& time)
  28.902 +static int flex_read_header(const char *filename, NSString& format,
  28.903 +                            NSString& time, NSString& version) 
  28.904  {
  28.905 -    char buf[FORMAT_LINE_LEN + TIME_LINE_LEN + 1];
  28.906 +    char buf[FORMAT_LINE_LEN + TIME_LINE_LEN + BIN_LOG_VERSION_LINE_LEN + 1];
  28.907  
  28.908      // Open the log file
  28.909      SYS_FILE fd = system_fopenRO(filename);
  28.910 @@ -1427,6 +1543,8 @@
  28.911      const char *p = buf;
  28.912      p = flex_parse_header_line(p, FORMAT_PREFIX, FORMAT_PREFIX_LEN, format);
  28.913      p = flex_parse_header_line(p, TIME_PREFIX, TIME_PREFIX_LEN, time);
  28.914 +    p = flex_parse_header_line(p, BIN_LOG_VERSION_PREFIX, 
  28.915 +                               BIN_LOG_VERSION_PREFIX_LEN, version);
  28.916  
  28.917      return len;
  28.918  }
  28.919 @@ -1434,7 +1552,9 @@
  28.920  
  28.921  /* --------------------------- flex_create_log ---------------------------- */
  28.922  
  28.923 -static FlexLog *flex_create_log(const VirtualServer *vs, const char *name, const char *filename, const char *format, PRBool enabled)
  28.924 +static FlexLog *flex_create_log(const VirtualServer *vs, const char *name,
  28.925 +                                const char *filename, const char *format,
  28.926 +                                PRBool enabled, PRBool binary = PR_FALSE)
  28.927  {
  28.928      PR_ASSERT(vs);
  28.929      PR_ASSERT(name);
  28.930 @@ -1452,11 +1572,37 @@
  28.931              // Compare the old header with the new header
  28.932              NSString old_format;
  28.933              NSString old_time;
  28.934 -            int rv = flex_read_header(filename, old_format, old_time);
  28.935 +            NSString old_binversion;
  28.936 +            int rv = flex_read_header(filename, old_format, old_time,
  28.937 +                                      old_binversion);
  28.938              if (rv > 0) {
  28.939                  if (strncmp(format, old_format, FORMAT_LEN))
  28.940                      ereport(LOG_MISCONFIG, XP_GetAdminStr(DBT_flexLogError3), filename);
  28.941                  epoch = util_atoi64(old_time);
  28.942 +
  28.943 +                if (binary) {
  28.944 +                    // older log was not binary but this one is
  28.945 +                    if (old_binversion.length() <= 0) {
  28.946 +                        ereport(LOG_MISCONFIG,
  28.947 +                                XP_GetAdminStr(DBT_flexLogError4), filename);
  28.948 +                        // Do not start the server
  28.949 +                        return NULL;
  28.950 +                    } else if (strncmp(BIN_LOG_VERSION, old_binversion.data(),
  28.951 +                             strlen(BIN_LOG_VERSION))) {
  28.952 +                        // both are binary but their versions didnt match
  28.953 +                        ereport(LOG_MISCONFIG,
  28.954 +                                XP_GetAdminStr(DBT_flexLogError5));
  28.955 +                        // Do not start the server
  28.956 +                        return NULL;
  28.957 +                    } // else if both the versions are same - ok
  28.958 +                } else if (old_binversion.length() > 0) {
  28.959 +                        // If this log is NOT binary and older log is binary
  28.960 +                        ereport(LOG_MISCONFIG,
  28.961 +                                XP_GetAdminStr(DBT_flexLogError4), filename);
  28.962 +                        // Do not start the server
  28.963 +                        return NULL;
  28.964 +                }
  28.965 +                    // else both are non-binary access logs - ok 
  28.966              }
  28.967          }
  28.968      }
  28.969 @@ -1469,7 +1615,8 @@
  28.970      // Initialize the FlexLog
  28.971      log->next = NULL;
  28.972      log->name = PERM_STRDUP(name);
  28.973 -    log->format = flex_acquire_format(format);
  28.974 +    log->format = flex_acquire_format(format, binary);
  28.975 +    log->format->binary = binary;
  28.976      log->epoch = epoch;
  28.977      log->enabled = enabled;
  28.978      log->file = LogManager::getFile(filename);
  28.979 @@ -1484,6 +1631,9 @@
  28.980              break;
  28.981          }
  28.982      }
  28.983 +    if (binary)
  28.984 +        header.printf("%s%s%s", BIN_LOG_VERSION_PREFIX, BIN_LOG_VERSION,
  28.985 +                      ENDLINE);
  28.986              
  28.987      // Open the log file
  28.988      LogManager::setHeader(log->file, header);
  28.989 @@ -1504,7 +1654,9 @@
  28.990      for (i = 0; i < vs->getAccessLogCount(); i++) {
  28.991          const ServerXMLSchema::AccessLog *al = vs->getAccessLog(i);
  28.992          if (!strcmp(al->name, name))
  28.993 -            return flex_create_log(vs, name, al->file, al->format, al->enabled);
  28.994 +            return flex_create_log(vs, name, al->file, al->format, al->enabled,
  28.995 +                          al->mode.getEnumValue() == 
  28.996 +                          ServerXMLSchema::AccessLogMode::ACCESSLOGMODE_BINARY);
  28.997      }
  28.998  
  28.999      // Look for a <server> <access-log>
 28.1000 @@ -1512,7 +1664,9 @@
 28.1001      for (i = 0; i < configuration->getAccessLogCount(); i++) {
 28.1002          const ServerXMLSchema::AccessLog *al = configuration->getAccessLog(i);
 28.1003          if (!strcmp(al->name, name))
 28.1004 -            return flex_create_log(vs, name, al->file, al->format, al->enabled);
 28.1005 +            return flex_create_log(vs, name, al->file, al->format, al->enabled,
 28.1006 +                          al->mode.getEnumValue() == 
 28.1007 +                          ServerXMLSchema::AccessLogMode::ACCESSLOGMODE_BINARY);
 28.1008      }
 28.1009  
 28.1010      // Look for a magnus.conf flex-init log template
 28.1011 @@ -1641,18 +1795,21 @@
 28.1012  
 28.1013  /* ------------------------------ flex_write ------------------------------ */
 28.1014  
 28.1015 -static int flex_write(pool_handle_t *pool, FlexLog *log, FlexFormatted *formatted, int desired, LogBuffer* incomingHandle)
 28.1016 +static int flex_write(pool_handle_t *pool, FlexLog *log,
 28.1017 +                      FlexFormatted *formatted, int desired,
 28.1018 +                      LogBuffer* incomingHandle, PRBool binary)
 28.1019  {
 28.1020      const FlexFormat *f = log->format;
 28.1021  
 28.1022      // If the formatted tokens will fit in a buffer...
 28.1023 -    int available = LogManager::sizeMaxLogLine - ENDLINE_LEN;
 28.1024 +    int available = LogManager::sizeMaxLogLine - ((binary) ? 0 : ENDLINE_LEN);
 28.1025      char* buf = NULL;
 28.1026      if (desired <= available) {
 28.1027          // Acquire a log buffer
 28.1028          LogBuffer *handle = NULL;
 28.1029          if (incomingHandle == NULL) {
 28.1030 -            buf = LogManager::lockBuffer(log->file, handle, desired + ENDLINE_LEN);
 28.1031 +            buf = LogManager::lockBuffer(log->file, handle, desired +
 28.1032 +                                         ((binary) ? 0 : ENDLINE_LEN));
 28.1033              if (!buf)
 28.1034                  return -1;
 28.1035          }
 28.1036 @@ -1663,9 +1820,11 @@
 28.1037  
 28.1038          // Copy the formatted tokens into the buffer
 28.1039          for (int ti = 0; ti < f->ntokens; ti++)
 28.1040 -            flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len);
 28.1041 +            flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len,
 28.1042 +                        formatted[ti].appendNull);
 28.1043  
 28.1044          // Append EOL
 28.1045 +        if (!binary)
 28.1046          for (int i = 0; i < ENDLINE_LEN; i++)
 28.1047              buf[pos++] = ENDLINE[i];
 28.1048  
 28.1049 @@ -1693,10 +1852,13 @@
 28.1050      int greedy_desired = 0;
 28.1051      int ungreedy_desired = 0;
 28.1052      for (ti = 0; ti < f->ntokens; ti++) {
 28.1053 -        if (formatted[ti].len > avg_available) {
 28.1054 -            greedy_desired += formatted[ti].len;
 28.1055 +        if ((formatted[ti].len + (int)formatted[ti].appendNull)
 28.1056 +            > avg_available) {
 28.1057 +            greedy_desired += (formatted[ti].len +
 28.1058 +                               (int)formatted[ti].appendNull);
 28.1059          } else {
 28.1060 -            ungreedy_desired += formatted[ti].len;
 28.1061 +            ungreedy_desired += (formatted[ti].len +
 28.1062 +                                 (int)formatted[ti].appendNull);
 28.1063          }
 28.1064      }
 28.1065  
 28.1066 @@ -1715,11 +1877,13 @@
 28.1067      int greedy_allowed = 0;
 28.1068      int ungreedy_allowed = 0;
 28.1069      for (ti = 0; ti < f->ntokens; ti++) {
 28.1070 -        if (formatted[ti].len > avg_available) {
 28.1071 -            allowed[ti] = formatted[ti].len * 1024 / greedy_scale;
 28.1072 +        if ((formatted[ti].len + (int)formatted[ti].appendNull)
 28.1073 +            > avg_available) {
 28.1074 +            allowed[ti] = (formatted[ti].len + (int)formatted[ti].appendNull)
 28.1075 +                           * 1024 / greedy_scale;
 28.1076              greedy_allowed += allowed[ti];
 28.1077          } else {
 28.1078 -            allowed[ti] = formatted[ti].len;
 28.1079 +            allowed[ti] = formatted[ti].len + (int)formatted[ti].appendNull;
 28.1080              ungreedy_allowed += allowed[ti];
 28.1081          }
 28.1082      }
 28.1083 @@ -1730,7 +1894,8 @@
 28.1084          for (ti = 0; ti < f->ntokens; ti++) {
 28.1085              if (leftover == 0)
 28.1086                  break;
 28.1087 -            if (formatted[ti].len > allowed[ti]) {
 28.1088 +            if ((formatted[ti].len + (int)formatted[ti].appendNull)
 28.1089 +                > allowed[ti]) {
 28.1090                  allowed[ti]++;
 28.1091                  leftover--;
 28.1092              }
 28.1093 @@ -1741,7 +1906,8 @@
 28.1094      LogBuffer *handle = NULL;
 28.1095      buf = NULL;
 28.1096      if (incomingHandle == NULL) {
 28.1097 -        buf = LogManager::lockBuffer(log->file, handle, available + ENDLINE_LEN);
 28.1098 +        buf = LogManager::lockBuffer(log->file, handle, available +
 28.1099 +                                     ((binary) ? 0 : ENDLINE_LEN));
 28.1100          if (!buf)
 28.1101              return -1;
 28.1102      } else {
 28.1103 @@ -1752,17 +1918,31 @@
 28.1104  
 28.1105      // Copy the formatted tokens into the buffer, truncating tokens as needed
 28.1106      for (ti = 0; ti < f->ntokens; ti++) {
 28.1107 -        if (formatted[ti].len > allowed[ti]) {
 28.1108 -            flex_memcpy(buf, pos, formatted[ti].p, allowed[ti] - DOT_DOT_DOT_LEN);
 28.1109 +        if ((formatted[ti].len + (int)formatted[ti].appendNull)
 28.1110 +            > allowed[ti]) {
 28.1111 +            flex_memcpy(buf, pos, formatted[ti].p, allowed[ti]
 28.1112 +                        - DOT_DOT_DOT_LEN - (int)formatted[ti].appendNull, 0);
 28.1113              buf[pos++] = '.';
 28.1114              buf[pos++] = '.';
 28.1115              buf[pos++] = '.';
 28.1116 +            if (formatted[ti].appendNull)
 28.1117 +                buf[pos++] = '\0';
 28.1118 +            // size of actual record written is going to vary
 28.1119 +            if ((&f->tokens[0])->type == TOKEN_RECORD_SIZE) {
 28.1120 +                PRInt32 i;
 28.1121 +                memcpy(&i, buf, sizeof(PRInt32));
 28.1122 +                i = i + allowed[ti] - formatted[ti].len 
 28.1123 +                    - (int)formatted[ti].appendNull;
 28.1124 +                memcpy(buf, &i, sizeof(PRInt32));
 28.1125 +            }
 28.1126          } else {
 28.1127 -            flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len);
 28.1128 +            flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len,
 28.1129 +                        formatted[ti].appendNull);
 28.1130          }
 28.1131      }    
 28.1132  
 28.1133      // Append EOL
 28.1134 +    if (!binary)
 28.1135      for (int i = 0; i < ENDLINE_LEN; i++)
 28.1136          buf[pos++] = ENDLINE[i];
 28.1137  
 28.1138 @@ -1821,7 +2001,7 @@
 28.1139      int len = flex_format_nsapi(pb, sn, rq, log, formatted);
 28.1140  
 28.1141      // Write the entry to the log file
 28.1142 -    int rv = flex_write(sn->pool, log, formatted, len, NULL);
 28.1143 +    int rv = flex_write(sn->pool, log, formatted, len, NULL, f->binary);
 28.1144      if (rv == -1)
 28.1145          return REQ_ABORTED;
 28.1146      if (rv < len)
 28.1147 @@ -1849,7 +2029,7 @@
 28.1148      int len = flex_format_accel(log, pool, connection, status, status_len, vsid, vsid_len, cl, formatted);
 28.1149  
 28.1150      // Write the entry to the log file
 28.1151 -    flex_write(pool, log, formatted, len, NULL);
 28.1152 +    flex_write(pool, log, formatted, len, NULL, f->binary);
 28.1153  
 28.1154  }
 28.1155  
 28.1156 @@ -1876,7 +2056,7 @@
 28.1157  
 28.1158      // Format the tokens
 28.1159      int len = flex_format_accel(log, pool, connection, status, status_len, vsid, vsid_len, cl, formatted);
 28.1160 -    int desired = len + ENDLINE_LEN;
 28.1161 +    int desired = len + ((f->binary)?0:ENDLINE_LEN);
 28.1162      PRBool spaceAvailable = PR_FALSE;
 28.1163  
 28.1164      int available = LogManager::sizeMaxLogLine;
 28.1165 @@ -1902,5 +2082,5 @@
 28.1166      }
 28.1167  
 28.1168      // Write the entry to the log file
 28.1169 -    flex_write(pool, log, formatted, len, *handle);
 28.1170 +    flex_write(pool, log, formatted, len, *handle, f->binary);
 28.1171  }
    29.1 --- a/src/support/filecache/fileio.cpp	Sun Jan 18 01:43:32 2009 -0800
    29.2 +++ b/src/support/filecache/fileio.cpp	Thu May 07 03:20:10 2009 -0700
    29.3 @@ -667,6 +667,14 @@
    29.4                  rv = PR_SendFile(socket, &sfd, PR_TRANSMITFILE_KEEP_OPEN, 
    29.5                                   timeout);
    29.6              }
    29.7 +
    29.8 +            // If there were no errors, set the rv value to the total size
    29.9 +            // written instead of the last chunk written. The caller may
   29.10 +            // do sanity check on number of bytes written based on returned
   29.11 +            // value
   29.12 +            if (rv >= 0) 
   29.13 +                rv = hdrlen + finfo->pr.size + tlrlen;
   29.14 +
   29.15          } 
   29.16      }
   29.17  
    30.1 --- a/src/support/xp/Makefile	Sun Jan 18 01:43:32 2009 -0800
    30.2 +++ b/src/support/xp/Makefile	Thu May 07 03:20:10 2009 -0700
    30.3 @@ -45,6 +45,10 @@
    30.4  DLL_OBJS=xpatomic \
    30.5           xpunit
    30.6  
    30.7 +ifeq ($(UNAME_OS_RELEASE),5.11)
    30.8 +LOCAL_DEF+= -DNO_INC_ATOMIC_ASM_WEAK
    30.9 +endif
   30.10 +
   30.11  ifeq ($(OS_ARCH),SunOS)
   30.12  DLL_OBJS+=atomic
   30.13  endif
    31.1 --- a/src/support/xp/i386/atomic.S	Sun Jan 18 01:43:32 2009 -0800
    31.2 +++ b/src/support/xp/i386/atomic.S	Thu May 07 03:20:10 2009 -0700
    31.3 @@ -74,7 +74,7 @@
    31.4  	/*
    31.5  	 * Include the definitions for the libc weak aliases.
    31.6  	 */
    31.7 -#ifdef NON_OPENSOLARIS // XXX TODO FIX THIS
    31.8 +#ifndef NO_INC_ATOMIC_ASM_WEAK
    31.9  #include "../atomic_asm_weak.h"
   31.10  #endif
   31.11  #endif
    32.1 --- a/templates/Makefile	Sun Jan 18 01:43:32 2009 -0800
    32.2 +++ b/templates/Makefile	Thu May 07 03:20:10 2009 -0700
    32.3 @@ -84,6 +84,8 @@
    32.4  
    32.5  bin::
    32.6  	$(MKDIR_DASH_P) $(WS_INSTALL_ROOT)/bin
    32.7 +	$(PERL) replace_vars.pl $(WS_VARS) INPUT_DIR=$(BUILD_ROOT)/templates/install-bin/ OUTPUT_DIR=$(WS_INSTALL_ROOT)/bin/
    32.8 +	$(CHMOD) +x $(WS_INSTALL_ROOT)/bin/binlog
    32.9  	#$(CP) TBD/flexanlg ./bin/flexanlg
   32.10  	#$(CP) TBD ./bin/htpasswd
   32.11  
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/src/server/extras/Makefile	Thu May 07 03:20:10 2009 -0700
    33.3 @@ -0,0 +1,39 @@
    33.4 +#
    33.5 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    33.6 +#
    33.7 +# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
    33.8 +#
    33.9 +# THE BSD LICENSE
   33.10 +#
   33.11 +# Redistribution and use in source and binary forms, with or without
   33.12 +# modification, are permitted provided that the following conditions are met:
   33.13 +#
   33.14 +# Redistributions of source code must retain the above copyright notice, this
   33.15 +# list of conditions and the following disclaimer.
   33.16 +# Redistributions in binary form must reproduce the above copyright notice,
   33.17 +# this list of conditions and the following disclaimer in the documentation
   33.18 +# and/or other materials provided with the distribution.
   33.19 +#
   33.20 +# Neither the name of the  nor the names of its contributors may be
   33.21 +# used to endorse or promote products derived from this software without
   33.22 +# specific prior written permission.
   33.23 +#
   33.24 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   33.25 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   33.26 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   33.27 +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   33.28 +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   33.29 +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   33.30 +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   33.31 +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   33.32 +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   33.33 +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   33.34 +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33.35 +#
   33.36 +
   33.37 +BUILD_ROOT=../../..
   33.38 +include $(BUILD_ROOT)/make/defines.mk
   33.39 +
   33.40 +DIRS=binlog
   33.41 +
   33.42 +include $(BUILD_ROOT)/make/rules.mk
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/src/server/extras/binlog/Makefile	Thu May 07 03:20:10 2009 -0700
    34.3 @@ -0,0 +1,73 @@
    34.4 +#
    34.5 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    34.6 +#
    34.7 +# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
    34.8 +#
    34.9 +# THE BSD LICENSE
   34.10 +#
   34.11 +# Redistribution and use in source and binary forms, with or without
   34.12 +# modification, are permitted provided that the following conditions are met:
   34.13 +#
   34.14 +# Redistributions of source code must retain the above copyright notice, this
   34.15 +# list of conditions and the following disclaimer.
   34.16 +# Redistributions in binary form must reproduce the above copyright notice,
   34.17 +# this list of conditions and the following disclaimer in the documentation
   34.18 +# and/or other materials provided with the distribution.
   34.19 +#
   34.20 +# Neither the name of the  nor the names of its contributors may be
   34.21 +# used to endorse or promote products derived from this software without
   34.22 +# specific prior written permission.
   34.23 +#
   34.24 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   34.25 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   34.26 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   34.27 +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   34.28 +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   34.29 +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   34.30 +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   34.31 +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   34.32 +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   34.33 +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   34.34 +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   34.35 +#
   34.36 +
   34.37 +BUILD_ROOT=../../../..
   34.38 +USE_NSPR=1
   34.39 +MODULE=binlog
   34.40 +include $(BUILD_ROOT)/make/defines.mk
   34.41 +
   34.42 +all::
   34.43 +
   34.44 +# object list is here
   34.45 +LOCAL_SRC=binlog
   34.46 +CCSRCS=$(LOCAL_SRC:=.cpp)
   34.47 +
   34.48 +LOCAL_INC=-I../../
   34.49 +LOCAL_INC+=-I../../../support
   34.50 +
   34.51 +LOCAL_LIB+=ns-httpd40 support
   34.52 +LOCAL_LIB+= nsfc nsprwrap nstime nstp xp ares3 xsd2cpp libdbm libsi18n
   34.53 +LOCAL_LIB+= ssldap60 ldap60 prldap60
   34.54 +LOCAL_LIB+= softokn3
   34.55 +LOCAL_LIBDIRS+=../../webservd/$(OBJDIR)/
   34.56 +LOCAL_LIBDIRS+=../../../support/support/$(OBJDIR)/
   34.57 +LOCAL_LIBDIRS+=../../../support/filecache/$(OBJDIR)/
   34.58 +LOCAL_LIBDIRS+=../../../support/NsprWrap/$(OBJDIR)/
   34.59 +LOCAL_LIBDIRS+=../../../support/time/$(OBJDIR)/
   34.60 +LOCAL_LIBDIRS+=../../../support/threadpool/$(OBJDIR)/
   34.61 +LOCAL_LIBDIRS+=../../../support/xp/$(OBJDIR)/
   34.62 +LOCAL_LIBDIRS+=../../../support/ares/$(OBJDIR)/
   34.63 +LOCAL_LIBDIRS+=../../../support/libxsd2cpp/$(OBJDIR)/
   34.64 +LOCAL_LIBDIRS+=../../../support/libdbm/$(OBJDIR)/
   34.65 +LOCAL_LIBDIRS+=../../libsi18n/$(OBJDIR)/
   34.66 +LOCAL_LIBDIRS+=$(LDAPSDK_LIBDIR)
   34.67 +LOCAL_LIBDIRS+=$(NSS_LIBDIR)
   34.68 +
   34.69 +EXE_TARGET=binlog
   34.70 +EXE_OBJS=binlog
   34.71 +EXE_LIBS+=ns-httpd40 support
   34.72 +
   34.73 +SHIP_PRIVATE_BINARIES=binlog
   34.74 +
   34.75 +# this should always be last!
   34.76 +include $(BUILD_ROOT)/make/rules.mk
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/src/server/extras/binlog/binlog.cpp	Thu May 07 03:20:10 2009 -0700
    35.3 @@ -0,0 +1,610 @@
    35.4 +/*
    35.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    35.6 + *
    35.7 + * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
    35.8 + *
    35.9 + * THE BSD LICENSE
   35.10 + *
   35.11 + * Redistribution and use in source and binary forms, with or without
   35.12 + * modification, are permitted provided that the following conditions are met:
   35.13 + *
   35.14 + * Redistributions of source code must retain the above copyright notice, this
   35.15 + * list of conditions and the following disclaimer.
   35.16 + * Redistributions in binary form must reproduce the above copyright notice,
   35.17 + * this list of conditions and the following disclaimer in the documentation
   35.18 + * and/or other materials provided with the distribution.
   35.19 + *
   35.20 + * Neither the name of the  nor the names of its contributors may be
   35.21 + * used to endorse or promote products derived from this software without
   35.22 + * specific prior written permission.
   35.23 + *
   35.24 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   35.25 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   35.26 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   35.27 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   35.28 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   35.29 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   35.30 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   35.31 + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   35.32 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   35.33 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   35.34 + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35.35 + *
   35.36 + */
   35.37 +/* 
   35.38 + * Binary access log format
   35.39 + *
   35.40 + * The default format is the CLF (common log file) format which is
   35.41 + * "%Ses->client.ip% - %Req->vars.auth-user% [%SYSDATE%] \"%Req->reqpb.clf-request%\" %Req->srvhdrs.clf-status% 
   35.42 + * %Req->srvhdrs.content-length%"
   35.43 + *
   35.44 + * A binary format file consists of a new ASCII header "binlog-version=1.0".
   35.45 + * In later releases, this version may get changed.
   35.46 + *
   35.47 + * The records have the following structure:
   35.48 + * RECORD_LEN : PRInt32 4 bytes followed by the RECORD itself.
   35.49 + * For CLF a typical binary record will be :
   35.50 + * 
   35.51 + * TOKEN                   DATA TYPE   WHAT IT CONTAINS
   35.52 + * ----------------------------------------------------
   35.53 + * TOKEN_RECORD_SIZE       PRInt32     record length
   35.54 + * TOKEN_IP                String\0    Ses->client "ip"
   35.55 + * TOKEN_AUTH_USER         String\0    rq->vars    "auth-user"
   35.56 + * TOKEN_SYSDATE           PRInt64     time when log entry was created
   35.57 + * TOKEN_REQUEST_LINE      String\0    rq->reqpb   "clf-request"
   35.58 + * TOKEN_STATUS_CODE       short       rq->srvhdrs "clf-status"
   35.59 + * TOKEN_CONTENT_LENGTH    PRInt64     rq->srvhdrs "content-length"
   35.60 + * 
   35.61 + * Cosmetic stuff in format (of type TEXT_TOKEN_OFFSET) like spaces, quotes,
   35.62 + * brackets, endline, etc. will not be written in binary log. They will be 
   35.63 + * added by the binlog reader.
   35.64 + *
   35.65 + * What other formats do
   35.66 + *
   35.67 + * TOKEN                               DATA TYPE   WHAT IT CONTAINS
   35.68 + * -----------------------------------------------------------------
   35.69 + * TOKEN_TEXT_OFFSET                   None        Nothing
   35.70 + * TOKEN_METHOD_NUM                    short       rq->method_num
   35.71 + * TOKEN_PROTV_NUM                     short       rq->protv_num
   35.72 + * TOKEN_TEXT_POINTER                  String      ??
   35.73 + * TOKEN_MODEL                         String\0    model
   35.74 + * TOKEN_REFERER                       String\0    rq->headers "referer"
   35.75 + * TOKEN_USER_AGENT                    String\0    rq->headers "user-agent"
   35.76 + * TOKEN_VSID                          String\0    virtual server id
   35.77 + * TOKEN_DNS                           String\0    DNS of the client
   35.78 + * TOKEN_REQUEST_LINE_URI              String\0    Uri part from rq line
   35.79 + *                                                 (includes query string)
   35.80 + * TOKEN_REQUEST_LINE_URI_ABS_PATH     String\0    Path part from rq line
   35.81 + *                                                 (excludes query string)
   35.82 + * TOKEN_REQUEST_LINE_URI_QUERY        String\0    Query string from rq line
   35.83 + * TOKEN_REQUEST_LINE_PROTOCOL         String\0    Rq line protocol 
   35.84 + *                                                 For example "HTTP/1.0\0"
   35.85 + * TOKEN_REQUEST_LINE_PROTOCOL_NAME    String\0    Rq line protocol name 
   35.86 + *                                                 For example "HTTP\0"
   35.87 + * TOKEN_REQUEST_LINE_PROTOCOL_VERSION String\0    Rq line protocol number
   35.88 + *                                                 For example "1.0\0"
   35.89 + * TOKEN_METHOD                        String\0    rq->reqpb "method"
   35.90 + * TOKEN_STATUS_REASON                 String\0    Reason in rq->srvhdrs "status"
   35.91 + * TOKEN_SUBSYSTEM                     String\0    "NSAPI\0"
   35.92 + * TOKEN_COOKIE                        String\0    rq->headers "cookie"
   35.93 + * TOKEN_PB_KEY                        String\0    pb key
   35.94 + * TOKEN_PB_NAME                       String\0    pb value
   35.95 + * TOKEN_SN_CLIENT_NAME                String\0    sn->client
   35.96 + * TOKEN_SN_CLIENT_KEY                 String\0    sn->client key
   35.97 + * TOKEN_RQ_VARS_KEY                   String\0    rq->vars for key
   35.98 + * TOKEN_RQ_VARS_NAME                  String\0    rq->vars value
   35.99 + * TOKEN_RQ_REQPB_KEY                  String\0    rq->reqpb key
  35.100 + * TOKEN_RQ_REQPB_NAME                 String\0    rq->reqpb value
  35.101 + * TOKEN_RQ_HEADERS_KEY                String\0    rq->headers key
  35.102 + * TOKEN_RQ_HEADERS_NAME               String\0    rq->headers value
  35.103 + * TOKEN_RQ_SRVHDRS_KEY                String\0    rq->srvhdrs key
  35.104 + * TOKEN_RQ_SRVHDRS_NAME               String\0    rq->srvhdrs value
  35.105 + * TOKEN_DURATION                      PRUint64    duration
  35.106 + * TOKEN_LOCALEDATE                    PRInt64     current time 
  35.107 + * TOKEN_TIME                          PRInt64     current time
  35.108 + * TOKEN_RELATIVETIME                  PRInt64     current time minus time from
  35.109 + *                                                 "time= ..." header line
  35.110 + */
  35.111 +#include <stdio.h>
  35.112 +#include "netsite.h"
  35.113 +#include "support/NSString.h"
  35.114 +#include "time/nstime.h"
  35.115 +#include "base/util.h"
  35.116 +#include "base/date.h"
  35.117 +#include "frame/log.h"
  35.118 +#include "frame/object.h"
  35.119 +#include "safs/flexlog.h"
  35.120 +#include "safs/flexlogcommon.h"
  35.121 +#include "base/pool.h"
  35.122 +#ifdef XP_WIN32
  35.123 +#include "wingetopt.h"
  35.124 +#endif
  35.125 +
  35.126 +// T could be short, PRInt64 or PRUint64
  35.127 +template <class T>
  35.128 +inline PRInt32 convert(char *p, T& i)
  35.129 +{
  35.130 +    PRInt32 l =  sizeof(i);
  35.131 +    memcpy(&i, p, l);
  35.132 +    return l;
  35.133 +}
  35.134 +
  35.135 +class BinLog
  35.136 +{
  35.137 +public :
  35.138 +    BinLog();
  35.139 +   ~BinLog();
  35.140 +   PRInt32 readLog(const char *filename);
  35.141 +private :
  35.142 +    SYS_FILE _fd;
  35.143 +
  35.144 +    char *_recordBuf;
  35.145 +    PRInt32 _currRecordBufSize;
  35.146 +
  35.147 +    NSString _line;
  35.148 +
  35.149 +    char _headerBuf[FORMAT_LINE_LEN + 1];
  35.150 +    PRInt32 _headerBufSize;
  35.151 +
  35.152 +    NSString _time;
  35.153 +    NSString _version;
  35.154 +    NSString _format;
  35.155 +
  35.156 +    FlexFormat *_f;
  35.157 +
  35.158 +    PRInt32 openFile(const char *filename);
  35.159 +    PRInt32 parseLogFileHeaders(void);
  35.160 +    PRInt32 parseRecord(void);
  35.161 +    PRInt32 readNextRecord(void);
  35.162 +    PRInt32 readTillENDLINE(const char *prefix, NSString &val);
  35.163 +};
  35.164 +
  35.165 +BinLog::BinLog(void)
  35.166 +{
  35.167 +    _currRecordBufSize = 0;
  35.168 +
  35.169 +    // use the same size working buffer for format, data, version
  35.170 +    // format line is the biggest line
  35.171 +    _headerBufSize = FORMAT_LINE_LEN + 1;
  35.172 +    PR_ASSERT(FORMAT_LINE_LEN > TIME_LINE_LEN);
  35.173 +    PR_ASSERT(FORMAT_LINE_LEN > BIN_LOG_VERSION_LINE_LEN);
  35.174 +
  35.175 +    _recordBuf = NULL;
  35.176 +    _f = NULL;
  35.177 +    _fd = SYS_ERROR_FD;
  35.178 +}
  35.179 +
  35.180 +BinLog::~BinLog(void)
  35.181 +{
  35.182 +    if (_recordBuf)
  35.183 +        PERM_FREE(_recordBuf);
  35.184 +
  35.185 +    // Destroy the FlexFormat
  35.186 +    for (int ti = 0; ti < _f->ntokens; ti++) {
  35.187 +         if (_f->tokens[ti].p)
  35.188 +             PERM_FREE(_f->tokens[ti].p);
  35.189 +         model_str_free(_f->tokens[ti].model);
  35.190 +    }
  35.191 +    if (_f->tokens)
  35.192 +        PERM_FREE(_f->tokens);
  35.193 +    if (_f->format)
  35.194 +        PERM_FREE(_f->format);
  35.195 +    PERM_FREE(_f);
  35.196 +    _f = NULL;
  35.197 +
  35.198 +    if (_fd)
  35.199 +        PR_Close(_fd);
  35.200 +
  35.201 +}
  35.202 +
  35.203 +
  35.204 +PRInt32 BinLog::parseRecord(void)
  35.205 +{
  35.206 +    // note we already have read sizeof(PRInt32) record length
  35.207 +    char *p = _recordBuf;
  35.208 +
  35.209 +    for (int ti = 0; ti < _f->ntokens; ti++) {
  35.210 +        const FlexToken *t = &_f->tokens[ti];
  35.211 +
  35.212 +        PRInt32 len;
  35.213 +        short s;
  35.214 +        const char *arr = NULL;
  35.215 +        PRInt64 i;
  35.216 +        PRUint64 u;
  35.217 +        time_t tim;
  35.218 +
  35.219 +        switch (t->type) {
  35.220 +        case TOKEN_TEXT_OFFSET:
  35.221 +                _line.append(_f->format + t->offset, t->len);
  35.222 +            break;
  35.223 +        case TOKEN_TEXT_POINTER:
  35.224 +                len = t->len;
  35.225 +                _line.append(p, len);
  35.226 +                p += len;
  35.227 +             break;
  35.228 +        case TOKEN_SYSDATE:
  35.229 +        case TOKEN_LOCALEDATE:
  35.230 +                p += convert(p, i);
  35.231 +
  35.232 +                tim = (time_t)i;
  35.233 +
  35.234 +                if (flex_format_time(NULL, tim, t->type, &arr) == -1) {
  35.235 +                     fprintf(stderr, "Error converting time %lld to string\n",
  35.236 +                             i);
  35.237 +                     return -1;
  35.238 +                }
  35.239 +                _line.append(arr);
  35.240 +                pool_free(NULL, (void *)arr);
  35.241 +            break;
  35.242 +        // time_t
  35.243 +        case TOKEN_TIME:
  35.244 +        case TOKEN_RELATIVETIME:
  35.245 +                p += convert(p, i);
  35.246 +
  35.247 +                tim = (time_t)i;
  35.248 +
  35.249 +                if (flex_format_64(NULL,(PRInt64) tim, &arr) == -1) {
  35.250 +                    fprintf(stderr, "Error converting time %lld to string\n",
  35.251 +                            i);
  35.252 +                    return -1;
  35.253 +                }
  35.254 +                _line.append(arr);
  35.255 +                pool_free(NULL, (void *)arr);
  35.256 +            break;
  35.257 +
  35.258 +        // strings
  35.259 +        case TOKEN_MODEL:
  35.260 +        case TOKEN_IP:
  35.261 +        case TOKEN_AUTH_USER:
  35.262 +        case TOKEN_DNS:
  35.263 +        case TOKEN_REQUEST_LINE:
  35.264 +        case TOKEN_REQUEST_LINE_URI:
  35.265 +        case TOKEN_REQUEST_LINE_URI_ABS_PATH:
  35.266 +        case TOKEN_REQUEST_LINE_URI_QUERY:
  35.267 +        case TOKEN_REQUEST_LINE_PROTOCOL:
  35.268 +        case TOKEN_REQUEST_LINE_PROTOCOL_NAME:
  35.269 +        case TOKEN_REQUEST_LINE_PROTOCOL_VERSION:
  35.270 +        case TOKEN_METHOD:
  35.271 +        case TOKEN_STATUS_REASON:
  35.272 +        case TOKEN_REFERER:
  35.273 +        case TOKEN_USER_AGENT:
  35.274 +        case TOKEN_VSID:
  35.275 +        case TOKEN_SUBSYSTEM:
  35.276 +        case TOKEN_COOKIE:
  35.277 +        case TOKEN_PB_KEY:
  35.278 +        case TOKEN_PB_NAME:
  35.279 +        case TOKEN_SN_CLIENT_KEY:
  35.280 +        case TOKEN_SN_CLIENT_NAME:
  35.281 +        case TOKEN_RQ_VARS_KEY:
  35.282 +        case TOKEN_RQ_VARS_NAME:
  35.283 +        case TOKEN_RQ_REQPB_KEY:
  35.284 +        case TOKEN_RQ_REQPB_NAME:
  35.285 +        case TOKEN_RQ_HEADERS_KEY:
  35.286 +        case TOKEN_RQ_HEADERS_NAME:
  35.287 +        case TOKEN_RQ_SRVHDRS_KEY:
  35.288 +        case TOKEN_RQ_SRVHDRS_NAME:
  35.289 +            if (p && p[0] != '\0') {
  35.290 +                _line.append(p);
  35.291 +                len = strlen(p) + 1;
  35.292 +                p += len;
  35.293 +            } else {
  35.294 +                _line.append("-");
  35.295 +                p++;
  35.296 +            }
  35.297 +            break;
  35.298 +        // short
  35.299 +        case TOKEN_METHOD_NUM:
  35.300 +        case TOKEN_PROTV_NUM:
  35.301 +        case TOKEN_STATUS_CODE:
  35.302 +                p += convert(p, s);
  35.303 +                _line.printf("%d", s);
  35.304 +            break;
  35.305 +
  35.306 +        // PRInt64
  35.307 +        case TOKEN_CONTENT_LENGTH:
  35.308 +                p += convert(p, i);
  35.309 +
  35.310 +                // convert PRInt64 to string
  35.311 +                if (flex_format_64(NULL, i, &arr) == -1) {
  35.312 +                    fprintf(stderr, 
  35.313 +                            "Error converting content length %lld to string\n",
  35.314 +                            i);
  35.315 +                    return -1;
  35.316 +                }
  35.317 +                _line.append(arr);
  35.318 +                pool_free(NULL, (void *)arr);
  35.319 +            break;
  35.320 +
  35.321 +        // PRUint64
  35.322 +        case TOKEN_DURATION:
  35.323 +                p += convert(p, u);
  35.324 +
  35.325 +                // convert PRUint64 to string
  35.326 +                char arr1[30];
  35.327 +                memset(arr1, '\0', sizeof(arr1));
  35.328 +                if (PR_snprintf(arr1, sizeof(arr1), "%llu", u) != -1)
  35.329 +                    _line.append(arr1);
  35.330 +            break;
  35.331 +
  35.332 +        case TOKEN_RECORD_SIZE:
  35.333 +            // Field to add buffer length do nothing as it is already read
  35.334 +            break;
  35.335 +        default:
  35.336 +            PR_ASSERT(0);
  35.337 +            break;
  35.338 +        }
  35.339 +    }
  35.340 +    return 0;
  35.341 +}
  35.342 +
  35.343 +PRInt32 BinLog::readTillENDLINE(const char *prefix, NSString &val)
  35.344 +{
  35.345 +
  35.346 +    memset(_headerBuf, '\0', _headerBufSize);
  35.347 +
  35.348 +    // read ...=.... (till endline)
  35.349 +    char c = 'a';
  35.350 +    char *p = _headerBuf;
  35.351 +    PRInt32 totalBytesRead = 0;
  35.352 +    PRInt32 bytes = 0;
  35.353 +    do {
  35.354 +        bytes = PR_Read(_fd, (void *)&c, sizeof(char));
  35.355 +        if (bytes == 0)
  35.356 +            break;
  35.357 +        if (bytes != sizeof(char)) {
  35.358 +            fprintf(stderr, "Error reading %s... line. %d bytes read.\n",
  35.359 +                    prefix, bytes);
  35.360 +            return -1;
  35.361 +        }
  35.362 +        *p = c;
  35.363 +        p++;
  35.364 +        totalBytesRead++;
  35.365 +    } while ((c != ENDLINE[0]) && (totalBytesRead < _headerBufSize));
  35.366 +
  35.367 +    // If no bytes are read error
  35.368 +    if (totalBytesRead <= 0) {
  35.369 +        fprintf(stderr, "Error reading %s... line.\n", prefix);
  35.370 +        return -1;
  35.371 +    }
  35.372 +
  35.373 +    // read ENDLINE
  35.374 +    // ENDLINE is '\r\n' (windows) and is '\n' on Unix
  35.375 +    if (c == ENDLINE[0] && ENDLINE_LEN > 1) {
  35.376 +        for (int j = 0; j < ENDLINE_LEN - 1; j++) {
  35.377 +            bytes = PR_Read(_fd, (void *)p, sizeof(char));
  35.378 +            if (bytes != sizeof(char)) {
  35.379 +                fprintf(stderr, "Error reading end of line.\n");
  35.380 +                return -1;
  35.381 +            }
  35.382 +            p++;
  35.383 +        }
  35.384 +    }
  35.385 +
  35.386 +    // if it doesn't contain ENDLINE return error
  35.387 +    const char *eol = strstr(_headerBuf, ENDLINE);
  35.388 +    if (eol == NULL) {
  35.389 +        fprintf(stderr,
  35.390 +                "Error reading %s... line. It should end with ENDLINE\n",
  35.391 +                prefix);
  35.392 +        return -1;
  35.393 +    }
  35.394 +
  35.395 +    // If _headerBuf doesn't start with ...= return error
  35.396 +    if (strncmp(_headerBuf, prefix, strlen(prefix)) != 0) {
  35.397 +        fprintf(stderr, "Error reading %s line.\n", prefix);
  35.398 +        return -1;
  35.399 +    }
  35.400 +
  35.401 +    // value should contain the actual format minus format prefix
  35.402 +    const char *suffix = _headerBuf + strlen(prefix);
  35.403 +    PRInt32 suffix_len =  eol - suffix;
  35.404 +    val.append(suffix, suffix_len);
  35.405 +
  35.406 +    printf("%s", _headerBuf);
  35.407 +    return 0;
  35.408 +}
  35.409 +
  35.410 +PRInt32 BinLog::parseLogFileHeaders(void)