NET_InitRDFCookieResources (void) {
NET_InitRDFCookieResources (void)
NET_InitRDFCookieResources (void) {{}/* reads HTTP cookies from disk * * on entry pass in the name of the file to read * * returns 0 on success -1 on failure. * * */#define LINE_BUFFER_SIZE 4096PUBLIC intNET_ReadCookies(char * filename){    XP_List * list_ptr;    net_CookieStruct *new_cookie, *tmp_cookie_ptr;	size_t new_len;    XP_File fp;	char buffer[LINE_BUFFER_SIZE];	char *host, *is_domain, *path, *xxx, *expires, *name, *cookie;	Bool added_to_list;#if defined(CookieManagement)    net_ReadCookiePermissions(NULL);#endif    if(!(fp = XP_FileOpen(filename, xpHTTPCookie, XP_FILE_READ)))        return(-1);	net_lock_cookie_list();	list_ptr = net_cookie_list;    /* format is:     *     * host \t is_domain \t path \t xxx \t expires \t name \t cookie     *     * if this format isn't respected we move onto the next line in the file.     * is_domain is TRUE or FALSE	-- defaulting to FALSE     * xxx is TRUE or FALSE   -- should default to TRUE     * expires is a time_t integer     * cookie can have tabs     */    while(XP_FileReadLine(buffer, LINE_BUFFER_SIZE, fp))      {		added_to_list = FALSE;		if (*buffer == '#' || *buffer == CR || *buffer == LF || *buffer == 0)		  continue;		host = buffer;				if( !(is_domain = PL_strchr(host, '\t')) )			continue;		*is_domain++ = '\0';		if(*is_domain == CR || *is_domain == LF || *is_domain == 0)			continue;				if( !(path = PL_strchr(is_domain, '\t')) )			continue;		*path++ = '\0';		if(*path == CR || *path == LF || *path == 0)			continue;		if( !(xxx = PL_strchr(path, '\t')) )			continue;		*xxx++ = '\0';		if(*xxx == CR || *xxx == LF || *xxx == 0)			continue;		if( !(expires = PL_strchr(xxx, '\t')) )			continue;		*expires++ = '\0';		if(*expires == CR || *expires == LF || *expires == 0)			continue;        if( !(name = PL_strchr(expires, '\t')) )			continue;		*name++ = '\0';		if(*name == CR || *name == LF || *name == 0)			continue;        if( !(cookie = PL_strchr(name, '\t')) )			continue;		*cookie++ = '\0';		if(*cookie == CR || *cookie == LF || *cookie == 0)			continue;		/* remove the '\n' from the end of the cookie */		XP_StripLine(cookie);        /* construct a new cookie_struct         */        new_cookie = PR_NEW(net_CookieStruct);        if(!new_cookie)          {			net_unlock_cookie_list();            return(-1);          }		memset(new_cookie, 0, sizeof(net_CookieStruct));            /* copy         */        StrAllocCopy(new_cookie->cookie, cookie);        StrAllocCopy(new_cookie->name, name);        StrAllocCopy(new_cookie->path, path);        StrAllocCopy(new_cookie->host, host);        new_cookie->expires = atol(expires);		HG87365        if(!PL_strcmp(is_domain, "TRUE"))        	new_cookie->is_domain = TRUE;        else        	new_cookie->is_domain = FALSE;		if(!net_cookie_list)		  {			net_cookie_list = XP_ListNew();		    if(!net_cookie_list)			  {				net_unlock_cookie_list();				return(-1);			  }		  }				/* add it to the list so that it is before any strings of		 * smaller length		 */		new_len = PL_strlen(new_cookie->path);		while((tmp_cookie_ptr = (net_CookieStruct *) XP_ListNextObject(list_ptr)) != NULL)		  { 			if(new_len > PL_strlen(tmp_cookie_ptr->path))			  {				XP_ListInsertObject(net_cookie_list, tmp_cookie_ptr, new_cookie);				added_to_list = TRUE;				break;			  }		  }		/* no shorter strings found in list */			if(!added_to_list)		    XP_ListAddObjectToEnd(net_cookie_list, new_cookie);	  }    XP_FileClose(fp);	net_unlock_cookie_list();	cookies_changed = FALSE;    return(0);}/* --- New stuff: General auth utils (currently used only by proxy auth) --- *//* * Figure out the authentication scheme used; currently supported: * *		* Basic * */ HG73632PRIVATE net_AuthTypenet_auth_type(char *name){	if (name) {		while (*name && NET_IS_SPACE(*name))			name++;		if (!PL_strncasecmp(name, "basic", 5))			return AUTH_BASIC;#ifdef SIMPLE_MD5		HG29383#endif		/*FORTEZZA checks*/		else if (!PL_strncasecmp(name, "fortezzaproxy", 13))			return AUTH_FORTEZZA;	}	return AUTH_INVALID;}/* * Figure out better of two {WWW,Proxy}-Authenticate headers; * SimpleMD5 is better than Basic.  Uses the order of AuthType * enum values. * */MODULE_PRIVATE PRBoolnet_IsBetterAuth(char *new_auth, char *old_auth){	if (!old_auth || net_auth_type(new_auth) >= net_auth_type(old_auth))		return PR_TRUE;	else		return PR_FALSE;}/* * Turns binary data of given lenght into a newly-allocated HEX string. * * */PRIVATE char *bin2hex(unsigned char *data, int len){    char *buf = (char *)PR_Malloc(2 * len + 1);    char *p = buf;	if(!buf)		return NULL;    while (len-- > 0) {		sprintf(p, "%02x", *data);		p += 2;		data++;    }    *p = '\0';    return buf;}/* * Parse {WWW,Proxy}-Authenticate header parameters into a net_AuthStruct * structure. * */#define SKIP_WS(p) while((*(p)) && NET_IS_SPACE(*(p))) p++PRIVATE PRBoolnext_params(char **pp, char **name, char **value){    char *q, *p = *pp;    SKIP_WS(p);    if (!p || !(*p) || !(q = strchr(p, '=')))		return FALSE;    *name = p;    *q++ = '\0';    if (*q == '"') {		*value = q + 1;		q = strchr(*value, '"');		if (q)		  *q++ = '\0';    }    else {		*value = q;		while (*q && !NET_IS_SPACE(*q)) q++;		if (*q)		  *q++ = '\0';    }    *pp = q;    return TRUE;}PRIVATE net_AuthStruct *net_parse_authenticate_line(char *auth, net_AuthStruct *ret){    char *name, *value, *p = auth;	if (!auth || !*auth)		return NULL;	if (!ret)		ret = PR_NEWZAP(net_AuthStruct);	if(!ret)		return NULL;    SKIP_WS(p);	ret->auth_type = net_auth_type(p);    while (*p && !NET_IS_SPACE(*p)) p++;    while (next_params(&p, &name, &value)) {		if (!PL_strcasecmp(name, "realm"))		  {			  StrAllocCopy(ret->realm, value);		  }#ifdef SIMPLE_MD5		else if (!PL_strcasecmp(name, "domain"))		  {			  StrAllocCopy(ret->domain, value);		  }		else if (!PL_strcasecmp(name, "nonce"))		  {			  StrAllocCopy(ret->nonce, value);		  }		else if (!PL_strcasecmp(name, "opaque"))		  {			  StrAllocCopy(ret->opaque, value);		  }		else if (!PL_strcasecmp(name, "oldnonce"))		  {			  ret->oldNonce = (!PL_strcasecmp(value, "TRUE")) ? TRUE : FALSE;		  }#endif /* SIMPLE_MD5 */		/* Some FORTEZZA checks */		else if (!PL_strcasecmp(name, "challenge"))		  {			  StrAllocCopy(ret->challenge, value);		  }		else if (!PL_strcasecmp(name, "oldchallenge"))		  {			  ret->oldChallenge = (!PL_strcasecmp(value, "TRUE")) ? TRUE : FALSE;		  }		/* End FORTEZZA checks  */    }#ifdef SIMPLE_MD5	if (!ret->oldNonce)		ret->oldNonce_retries = 0;#endif /* SIMPLE_MD5 */	/*Another FORTEZZA addition*/	if (!ret->oldChallenge)		ret->oldChallenge_retries = 0;	/*End FORTEZZA  addition   */    return ret;}#ifdef SIMPLE_MD5/* ---------- New stuff: SimpleMD5 Authentication for proxies -------------- */PRIVATE void do_md5(unsigned char *stuff, unsigned char digest[16]){	MD5Context *cx = MD5_NewContext();	unsigned int len;	if (!cx)		return;	MD5_Begin(cx);	MD5_Update(cx, stuff, strlen((char*)stuff));	MD5_End(cx, digest, &len, 16);	/* len had better be 16 when returned! */	MD5_DestroyContext(cx, (DSBool)TRUE);}/* * Generate a response for a SimpleMD5 challenge. * *	HEX( MD5("challenge password method url")) * */char *net_generate_md5_challenge_response(char *challenge,										  char *password,										  int   method,										  char *url){    unsigned char digest[16];    unsigned char *cookie =	  (unsigned char *)PR_Malloc(strlen(challenge) + strlen(password) +								strlen(url) + 10);	if(!cookie)		return NULL;    sprintf((char *)cookie, "%s %s %s %s", challenge, password,			(method==URL_POST_METHOD ? "POST" :			 method==URL_HEAD_METHOD ? "HEAD" : "GET"),			url);    do_md5(cookie, digest);    return bin2hex(digest, 16);}#define SIMPLEMD5_AUTHORIZATION_FMT "SimpleMD5\ username=\"%s\",\ realm=\"%s\",\ nonce=\"%s\",\ response=\"%s\",\ opaque=\"%s\""#endif /* SIMPLE_MD5 */PRIVATEchar *net_generate_auth_string(URL_Struct *url_s,							   net_AuthStruct *auth_s){	if (!auth_s)		return NULL;	switch (auth_s->auth_type) {	  case AUTH_INVALID:		break;	  case AUTH_BASIC:		if (!auth_s->auth_string) {			int len;			char *u_pass_string = NULL;			StrAllocCopy(u_pass_string, auth_s->username);			StrAllocCat (u_pass_string, ":");			StrAllocCat (u_pass_string, auth_s->password);			len = PL_strlen(u_pass_string);			if (!(auth_s->auth_string = (char*) PR_Malloc((((len+1)*4)/3)+20)))			  {				  return NULL;			  }			PL_strcpy(auth_s->auth_string, "Basic ");			NET_UUEncode((unsigned char *)u_pass_string,						 (unsigned char *)&auth_s->auth_string[6],						 len);			PR_Free(u_pass_string);		}		break;#ifdef SIMPLE_MD5	  case AUTH_SIMPLEMD5:	    if (auth_s->username && auth_s->password &&			auth_s->nonce    && auth_s->opaque   &&			url_s            && url_s->address)		  {			  char *resp;			  PR_FREEIF(auth_s->auth_string);			  auth_s->auth_string = NULL;			  if ((resp = net_generate_md5_challenge_response(auth_s->nonce,															  auth_s->password,															  url_s->method,															  url_s->address)))				{					if ((auth_s->auth_string =						 (char *)PR_Malloc(PL_strlen(auth_s->username) +										  PL_strlen(auth_s->realm)    +										  PL_strlen(auth_s->nonce)    +										  PL_strlen(resp)             +										  PL_strlen(auth_s->opaque)   +										  100)))					  {						  sprintf(auth_s->auth_string,								  SIMPLEMD5_AUTHORIZATION_FMT,								  auth_s->username,								  auth_s->realm,								  auth_s->nonce,								  resp,								  auth_s->opaque);					  }					PR_Free(resp);				}		  }		break;#endif /* SIMPLE_MD5 */		/* Handle the FORTEZZA case        */	        case AUTH_FORTEZZA:	       		HG26251		  break;		/* Done Handling the FORTEZZA case */    }	return auth_s->auth_string;}/* --------------- New stuff: client-proxy authentication --------------- */PRIVATE net_AuthStruct *net_CheckForProxyAuth(char * proxy_addr){	XP_List * lp = net_proxy_auth_list;	net_AuthStruct * s;	while ((s = (net_AuthStruct *)XP_ListNextObject(lp)) != NULL)      {		  if (!PL_strcasecmp(s->proxy_addr, proxy_addr))			  return s;	  }    return NULL;}/* * returns a proxy authorization string if one is required, otherwise * returns NULL */PUBLIC char *NET_BuildProxyAuthString(MWContext * context,						 URL_Struct * url_s,						 char * proxy_addr){	net_AuthStruct * auth_s = net_CheckForProxyAuth(proxy_addr);	return auth_s ? net_generate_auth_string(url_s, auth_s) : NULL;}/* * Returns FALSE if the user wishes to cancel proxy authorization * and TRUE if the user wants to continue with a new authorization * string. */#define INVALID_AUTH_HEADER XP_GetString( XP_PROXY_REQUIRES_UNSUPPORTED_AUTH_SCHEME )#define LOOPING_OLD_NONCES XP_GetString( XP_LOOPING_OLD_NONCES )PUBLIC PRBoolNET_AskForProxyAuth(MWContext * context,					char *   proxy_addr,					char *   pauth_params,					PRBool  already_sent_auth){	net_AuthStruct * prev;	PRBool new_entry = FALSE;	char * username = NULL;	char * password = NULL;	char * buf;	int32  len=0;	TRACEMSG(("Entering NET_AskForProxyAuth"));	if (!proxy_addr || !*proxy_addr || !pauth_params || !*pauth_params)		return FALSE;	prev = net_CheckForProxyAuth(proxy_addr);    if (prev) {		new_entry = FALSE;		net_parse_authenticate_line(pauth_params, prev);	}	else {		new_entry = TRUE;		if (!(prev = net_parse_authenticate_line(pauth_params, NULL)))		  {			  FE_Alert(context, INVALID_AUTH_HEADER);			  return FALSE;		  }		StrAllocCopy(prev->proxy_addr, proxy_addr);	}	if (!prev->realm || !*prev->realm)		StrAllocCopy(prev->realm, XP_GetString( XP_UNIDENTIFIED_PROXY_SERVER ) );    if (!new_entry) {		if (!already_sent_auth)		  {			  /* somehow the mapping changed since the time we sent			   * the authorization.			   * This happens sometimes because of the parrallel			   * nature of the requests.			   * In this case we want to just retry the connection			   * since it will probably succeed now.			   */			  return TRUE;		  }#ifdef SIMPLE_MD5		else if (prev->oldNonce && prev->oldNonce_retries++ < 3)		  {			  /*			   * We already sent the authorization string and the			   * nonce was expired -- auto-retry.			   */			  if (!FE_Confirm(context, LOOPING_OLD_NONCES))				  return FALSE;		  }#endif /* SIMPLE_MD5 */		/* Do the good old FORTEZZA  stuff */		else if (prev->oldChallenge && (prev->oldChallenge_retries++ > 3)) 		  {			  /*			   * We already sent the authorization string and the			   * nonce was expired -- auto-retry.			   */			  if (!FE_Confirm(context, XP_GetString(XP_CONFIRM_PROXYAUTHOR_FAIL)))				  return FALSE;		  }		else if (prev->auth_type != AUTH_FORTEZZA)		  {			  /*			   * We already sent the authorization string and it failed.			   */			  if (!FE_Confirm(context, XP_GetString(XP_CONFIRM_PROXYAUTHOR_FAIL)))				  return FALSE;		  }	}        if (prev->auth_type == AUTH_FORTEZZA) {		SECStatus rv;		rv = HG26252		if ( rv != SECSuccess ) {			return(FALSE);		}    } else    {	username = prev->username;	password = prev->password;	len = PL_strlen(prev->realm) + PL_strlen(proxy_addr) + 50;	buf = (char*)PR_Malloc(len*sizeof(char));		if(buf)	  {		PR_snprintf(buf, len*sizeof(char), XP_GetString( XP_PROXY_AUTH_REQUIRED_FOR ), prev->realm, proxy_addr);		NET_Progress(context, XP_GetString( XP_CONNECT_PLEASE_ENTER_PASSWORD_FOR_PROXY ) );#if defined(SingleSignon)		/* prefill prompt with previous username/passwords if any */		len = SI_PromptUsernameAndPassword		    (context, buf, &username, &password, proxy_addr);#else		len = FE_PromptUsernameAndPassword		    (context, buf, &username, &password);#endif		PR_Free(buf);	  }	else	  {		len = 0;	  }	if (!len)	  {		  TRACEMSG(("User canceled login!!!"));		  return FALSE;	  }	else if (!username || !password)	  {		  return FALSE;	  }	PR_FREEIF(prev->auth_string);	prev->auth_string = NULL;		/* Generate a new one */	PR_FREEIF(prev->username);	prev->username = username;	PR_FREEIF(prev->password);	prev->password = password;    }	if (new_entry)	  {		  if (!net_proxy_auth_list)			{				net_proxy_auth_list = XP_ListNew();				if (!net_proxy_auth_list)				  {					  return TRUE;				  }			}		  XP_ListAddObjectToEnd(net_proxy_auth_list, prev);	  }	return TRUE;}#if defined(CookieManagement)#include "htmldlgs.h"extern int XP_CERT_PAGE_STRINGS;extern int SA_REMOVE_BUTTON_LABEL;#define BUFLEN 5000#define FLUSH_BUFFER			\    if (buffer) {			\	StrAllocCat(buffer2, buffer);	\	g = 0;				\        buffer[0] = '\0';               \    }/* return TRUE if "number" is in sequence of comma-separated numbers */Bool net_InSequence(char* sequence, int number) {    char* ptr;    char* endptr;    char* undo = NULL;    Bool retval = FALSE;    int i;    /* not necessary -- routine will work even with null sequence */    if (!*sequence) {	return FALSE;    }    for (ptr = sequence ; ptr ; ptr = endptr) {	/* get to next comma */        endptr = PL_strchr(ptr, ',');        /* if comma found, process it */        if (endptr) {            /* restore last comma-to-null back to comma */            if (undo) {                *undo = ',';            }            /* set the comma to a null */            undo = endptr;            *endptr++ = '\0';            /* compare the number before the comma with "number" */            if (*ptr) {                i = atoi(ptr);                if (i == number) {                    /* "number" was in the sequence so return TRUE */                    retval = TRUE;                    break;                }            }        }    }    /* restore last comma-to-null back to comma */    if (undo) {        *undo = ',';    }    return retval;}PR_STATIC_CALLBACK(PRBool)net_AboutCookiesDialogDone(XPDialogState* state, char** argv, int argc,						unsigned int button){    XP_List *list;    net_CookieStruct *cookie;    net_CookiePermissionStruct *cookiePermission;    char *buttonName;    int cookieNumber;    net_CookieStruct *cookieToDelete = 0;    net_CookiePermissionStruct *cookiePermissionToDelete = 0;    char* gone;    buttonName = XP_FindValueInArgs("button", argv, argc);    if (button != XP_DIALOG_OK_BUTTON) {	/* OK button not pressed (must be cancel button that was pressed) */	return PR_FALSE;    }    /* OK was pressed, do the deletions */    /* get the comma-separated sequence of cookies to be deleted */    gone = XP_FindValueInArgs("goneC", argv, argc);    PR_ASSERT(gone);    if (!gone) {	return PR_FALSE;    }    /*     * walk through the cookie list, deleting the designated cookies     * Note: we can't delete cookie while "list" is pointing to it because     * that would destroy "list".  So we do a lazy deletion     */    net_lock_cookie_list();    list = net_cookie_list;    cookieNumber = 0;    while ( (cookie=(net_CookieStruct *) XP_ListNextObject(list)) ) {	if (net_InSequence(gone, cookieNumber)) {	    if (cookieToDelete) {		net_FreeCookie(cookieToDelete);	    }	    cookieToDelete = cookie;	}	cookieNumber++;    }    if (cookieToDelete) {	net_FreeCookie(cookieToDelete);	cookies_changed = TRUE;	NET_SaveCookies(NULL);    }    net_unlock_cookie_list();    /* get the comma-separated sequence of permissions to be deleted */    gone = XP_FindValueInArgs("goneP", argv, argc);    PR_ASSERT(gone);    if (!gone) {	return PR_FALSE;    }    /*     * walk through the cookie permission list, deleting the designated permissions     * Note: we can't delete permissions while "list" is pointing to it because     * that would destroy "list".  So we do a lazy deletion     */    net_lock_cookie_permission_list();    list = net_cookie_permission_list;    cookieNumber = 0;    while ( (cookiePermission=(net_CookiePermissionStruct *) XP_ListNextObject(list)) ) {	if (net_InSequence(gone, cookieNumber)) {	    if (cookiePermissionToDelete) {		net_FreeCookiePermission(cookiePermissionToDelete, TRUE);	    }	    cookiePermissionToDelete = cookiePermission;	}	cookieNumber++;    }    if (cookiePermissionToDelete) {	net_FreeCookiePermission(cookiePermissionToDelete, TRUE);	cookie_permissions_changed = TRUE;	net_SaveCookiePermissions(NULL);    }    net_unlock_cookie_permission_list();    return PR_FALSE;}PRIVATE BoolCookieCompare (net_CookieStruct * cookie1, net_CookieStruct * cookie2) {    char * host1 = cookie1->host;    char * host2 = cookie2->host;    /* get rid of leading period on host name, if any */    if (*host1 == '.') {	host1++;    }    if (*host2 == '.') {	host2++;    }    /* make decision based on host name if they are unequal */    if (PL_strcmp (host1, host2) < 0) {	return -1;    }    if (PL_strcmp (host1, host2) > 0) {	return 1;    }    /* if host names are equal, make decision based on cookie name */    return (PL_strcmp (cookie1->name, cookie2->name));}/* * find the next cookie that is alphabetically after the specified cookie *    ordering is based on hostname and the cookie name *    if specified cookie is NULL, find the first cookie alphabetically */PRIVATE net_CookieStruct *NextCookieAfter(net_CookieStruct * cookie, int * cookieNum) {    XP_List *cookie_list=net_cookie_list;    net_CookieStruct *cookie_ptr;    net_CookieStruct *lowestCookie = NULL;    int localCookieNum = 0;    int lowestCookieNum;    while ( (cookie_ptr=(net_CookieStruct *) XP_ListNextObject(cookie_list)) ) {	if (!cookie || (CookieCompare(cookie_ptr, cookie) > 0)) {	    if (!lowestCookie ||		    (CookieCompare(cookie_ptr, lowestCookie) < 0)) {		lowestCookie = cookie_ptr;		lowestCookieNum = localCookieNum;	    }	}	localCookieNum++;    }    *cookieNum = lowestCookieNum;    return lowestCookie;}typedef struct _CookieViewerDialog CookieViewerDialog;struct _CookieViewerDialog {    void *window;    void *parent_window;    PRBool dialogUp;    XPDialogState *state;};#ifdef TRUST_LABELS/* Purpose: given a cookie name look in the list containing the cookperm.txt * file and locate a matching trust label.  If a matching trust label * is found then format a simple text string that describes the trust label * information in a user friendly manner. * * If a matching label is not found return a string with a single space. * The caller must free the string. */char *GetTrustLabelString(char *CookieName){    XP_List * list_ptr, *Tptr;    TrustEntry *TEntry;    net_CookiePermissionStruct *cookperm;    char *szTemp = NULL;    char *szPurpose = NULL;    char *szRecipient = NULL;    char *szBy = NULL;    int i, j;/* * here's how we would like to write the code but it doesn't compile on the mac  * *   int PurposeIds[] = {MK_ACCESS_TL_PPH0, MK_ACCESS_TL_PPH1, *                       MK_ACCESS_TL_PPH2, MK_ACCESS_TL_PPH3, *                       MK_ACCESS_TL_PPH4, MK_ACCESS_TL_PPH5}; *   int RecpIds[] = { 0, MK_ACCESS_TL_RPH1,  *                     MK_ACCESS_TL_RPH2, MK_ACCESS_TL_RPH3};*/#define NumPurposeBits 6 /* number of bits in the recipient value */    /* array of msg Ids for the purpose values */    int PurposeIds[NumPurposeBits];#define NumRecpBits 4 /* number of bits in the recipient value */    /* the list of msg Ids for the recipient value. */    int RecpIds[NumRecpBits];#if NumPurposeBits > NumRecpBits#define NumStrs  NumPurposeBits#else#define NumStrs  NumRecpBits#endif    /* this array holds strings used in formatting the message */    char *szTempStrs[ NumStrs ];    PurposeIds[0] = MK_ACCESS_TL_PPH0;    PurposeIds[1] = MK_ACCESS_TL_PPH1;    PurposeIds[2] = MK_ACCESS_TL_PPH2;    PurposeIds[3] = MK_ACCESS_TL_PPH3;    PurposeIds[4] = MK_ACCESS_TL_PPH4;    PurposeIds[5] = MK_ACCESS_TL_PPH5;    RecpIds[0] = 0;    RecpIds[1] = MK_ACCESS_TL_RPH1;    RecpIds[2] = MK_ACCESS_TL_RPH2;    RecpIds[3] = MK_ACCESS_TL_RPH3;    if( CookieName ) {        /* look thru the cookie permission list for a matching trust label */        net_lock_cookie_permission_list();        list_ptr = net_cookie_permission_list;        while( szTemp == NULL &&                (cookperm = (net_CookiePermissionStruct *) XP_ListNextObject(list_ptr))!=0) {            /* look thru the trust list for this cookie */            if (cookperm->TrustList ) {                Tptr = cookperm->TrustList;                while( (TEntry = (TrustEntry *)XP_ListNextObject(Tptr))) {                    if( TEntry->CookieName                            && !PL_strcmp(CookieName, TEntry->CookieName)) {                        /* this permission entry matches the given cookie */                        szTemp = (char*)PR_Malloc(BUFLEN);                        break;                    }                }            }        }        net_unlock_cookie_permission_list();        /* was a match found?? */        if (szTemp) {            /* yes convert the ratings info into user strings */            for( j=0; j<NumStrs; j++) {                szTempStrs[j] = NULL;            }            /*             * count the number of purpose bits set AND             *  make a list of the phrases to use             */            for (j=0,i=0; i<NumPurposeBits; i++) {               if ((TEntry->purpose>>i) & 1) {                    /* this bit is set get the associated phrase */                    szTempStrs[j++] = PL_strdup( XP_GetString( PurposeIds[i] ) );                }            }            /*             * build the purpose string              * For translation purposes I am using strings              * of the form "This information is used for %1$s, %2$s and %3$s."             * and inserting the additional phrases in the formating.*/            switch ( j ) {                case 1:                    PR_snprintf(szTemp, BUFLEN,                        XP_GetString( MK_ACCESS_TL_PUR1 ),                        szTempStrs[0]                    );                    break;                case 2:                    PR_snprintf(szTemp, BUFLEN,                        XP_GetString( MK_ACCESS_TL_PUR2 ),                        szTempStrs[0],                        szTempStrs[1]                    );                    break;                case 3:                    PR_snprintf(szTemp, BUFLEN,                        XP_GetString( MK_ACCESS_TL_PUR3 ),                        szTempStrs[0],                        szTempStrs[1],                        szTempStrs[2]                    );                    break;                case 4:                    PR_snprintf(szTemp, BUFLEN,                        XP_GetString( MK_ACCESS_TL_PUR4 ),                        szTempStrs[0],                        szTempStrs[1],                        szTempStrs[2],                        szTempStrs[3]                    );                    break;                case 5:                    PR_snprintf(szTemp, BUFLEN,                        XP_GetString( MK_ACCESS_TL_PUR5 ),                        szTempStrs[0],                        szTempStrs[1],                        szTempStrs[2],                        szTempStrs[3],                        szTempStrs[4]                    );                    break;                case 6:                    PR_snprintf(szTemp, BUFLEN,                        XP_GetString( MK_ACCESS_TL_PUR6 ),                        szTempStrs[0],                        szTempStrs[1],                        szTempStrs[2],                        szTempStrs[3],                        szTempStrs[4],                        szTempStrs[5]                    );                    break;            } /* switch ( j ) */            /* I did things this way to avoid buffer overflow problems */            szPurpose = PL_strdup( szTemp );            /* free the temporary strings */            for( j=0; j<NumStrs; j++) {                PR_FREEIF(szTempStrs[j]);                szTempStrs[j] = NULL;            }            /* second build the recipient phrase list */            if ( TEntry->recipient == 1 ) {                szTempStrs[0] = PL_strdup( XP_GetString( MK_ACCESS_TL_RPH0 ) );                PR_snprintf(szTemp, BUFLEN,                    XP_GetString( MK_ACCESS_TL_RECP1 ),                    szTempStrs[0]                );            } else {                /*                 * if bits other than bit 0 are set then dont                  * output the "used only by this site" text                 *                 * count the number of purpose bits set AND                 *  make a list of the phrases to use                 */                for (j=0,i=1; i<NumRecpBits; i++) {                    if ((TEntry->recipient>>i) & 1) {                        /* this bit is set get the associated phrase */                        szTempStrs[j++] = PL_strdup( XP_GetString( RecpIds[i] ) );                    }                }                /*                 * format the recipient string according to the                  * number of bits set                 */                switch ( j ) {                    case 1:                        PR_snprintf(szTemp, BUFLEN,                            XP_GetString( MK_ACCESS_TL_RECP1 ),                            szTempStrs[0]                        );                        break;                    case 2:                        PR_snprintf(szTemp, BUFLEN,                            XP_GetString( MK_ACCESS_TL_RECP2 ),                            szTempStrs[0],                            szTempStrs[1]                        );                        break;                    case 3:                        PR_snprintf(szTemp, BUFLEN,                            XP_GetString( MK_ACCESS_TL_RECP3 ),                            szTempStrs[0],                            szTempStrs[1],                            szTempStrs[2]                        );                        break;                } /* switch ( j ) */            }            /* I did things this way to avoid buffer overflow problems */            szRecipient = PL_strdup( szTemp );            /* free the temporary strings */            for( j=0; j<NumStrs; j++) {                PR_FREEIF(szTempStrs[j]);                szTempStrs[j] = NULL;            }            /* construct the by string */            if (TEntry->by) {                PR_snprintf(szTemp, BUFLEN, XP_GetString(MK_ACCESS_TL_BY), TEntry->by);                szBy = PL_strdup( szTemp );            } else {                szBy = PL_strdup( " " );            }            /*             * construct the entire trust label statement.             * WATCHOUT: you can only execute four XP_GetString calls             * in this format string.             */            PR_snprintf(szTemp, BUFLEN,                "%s " /* identifiable text */                "%s " /* purpose string */                "%s " /* receipent */                "%s",  /* by string */                (TEntry->bIdentifiable                    ? XP_GetString(MK_ACCESS_TL_ID1)                    : XP_GetString(MK_ACCESS_TL_ID0)),                szPurpose, szRecipient, szBy);        }    }    PR_FREEIF(szPurpose);    PR_FREEIF(szRecipient);    PR_FREEIF(szBy);    return szTemp;}#define STR_TRUST_LABEL "(TrustLabel"/* these structures describe the layout of the trust label information in  *  the cookperm.txt.  The structures are used for both reading and writing the  *  file. */enum {TYPE_QUOTED_STRING, TYPE_INT};typedef struct {    char *szMatchStr; /* the string to look for coming in */    int ValueType; /* what kind of thing the value is */    int DataOffset; /* where in the TrustEntry struct to store the value */                    } ParseItem;static ParseItem ParseData[] = {    {"cookie", TYPE_QUOTED_STRING, offsetof(TrustEntry, CookieName)},    {"purpose", TYPE_INT, offsetof(TrustEntry, purpose)},    {"id", TYPE_INT, offsetof(TrustEntry, bIdentifiable)},    {"recipient", TYPE_INT, offsetof(TrustEntry, recipient)},    {"by", TYPE_QUOTED_STRING, offsetof(TrustEntry, by)},    /* the timestamp is the date and time when the cookie was set.        * It is in the form "14 Apr 89 03:20 GMT".   Use PR_ParseTimeString     * to parse it into a PR_Exploded time.     */    {"timestamp", TYPE_QUOTED_STRING, offsetof(TrustEntry, CookieSet)}};#define NUM_ITEMS  sizeof(ParseData) / sizeof( ParseItem)/****************************************************** * Purpose:  parse all the trust label string from a line in * cookperm.txt and store the result in a net_CookiePermissionStruct. * * This is a simple table driven parser.   ******************************************************/PRIVATEvoid ParseTrustLabelInfo    (char *Buf, net_CookiePermissionStruct * cookie_permission){    char *pToken, *p, *pEnd, *pSub;    int i, k, len;    Bool Status = FALSE;    char *pChar, *szTemp;    char *pCopy = NULL;    TrustEntry *TEntry;    /*     * Look for the trust label information which is in the form     *   "(TrustLabel" - must be the first token     *     "cookie:"<cookie name>     *     "purpose:"<purpose value>     *     "id:"<"0"|"1">     *     "recipient:"<recipient value>     *     "by:"<by value>     *     "timestamp:"<timestamp>     *    ")"								- must be the last token     * purpose value == a hex value corresponding to the purpose value to set     * recipient value == a hex value corresponding to the recipient value to set     * by value == a text string enclosed in double quotes     * timestamp == time when the cookie was set: format is quoted string in any of the      * formats that PR_Time will accept.     * cookie name == the name of the cookie enclosed in quotes     *     * The middle tokens can be in any order.     */    /*     * Do I have a well formed trust label string ??     * - can I find a beginning and an end??     */    p = Buf;    while ((p=strcasestr(p, (char *)STR_TRUST_LABEL)) && (pEnd=strchr(p,')'))) {        p += PL_strlen(STR_TRUST_LABEL);        /* Allocate a new trust Entry */        TEntry = PR_NEW(TrustEntry);        if (TEntry) {            /* init the elements */            TEntry->CookieName = NULL;            TEntry->purpose = 0;            TEntry->recipient = 0;            TEntry->bIdentifiable = FALSE;            TEntry->by = NULL;            TEntry->CookieSet = NULL;            /*             * isolate this trust label string for parsing, I must make a copy             * of the incoming string because the tokenizer will add nulls to it.             * Also allocate one more byte than I really need so that the tokenizer             * can write an extra Null at the end.             */            len = pEnd-p+1;            pCopy = XP_ALLOC(len + 1);            if (!pCopy) return;            XP_MEMCPY(pCopy, p, len-1);            pCopy[len] = '\0';            /* get the first token from the copy */            pToken = XP_STRTOK_R(pCopy, " :", &pSub);            while (pToken) {                if (pToken != ")") {                    for ( i=0; i<NUM_ITEMS; i++ ) {                        /* Is this token one that we are interested in ?? */                        if (PL_strcasecmp(pToken, ParseData[i].szMatchStr) == 0) {                            /* yes - extract its associated value and store it */                            switch(ParseData[i].ValueType) {                                case TYPE_QUOTED_STRING:                                    /*                                     * since I allow white space INSIDE the                                     * quoted string, AND I want the next token                                     * to contain all the stuff inside the                                     * quoted string; I need to eat all the                                     * whitespace between the : and the                                     * next "                                     */                                    while(*pSub == ' ' || *pSub == '\t') {                                        pSub++;                                    }                                    /* get next token which should be " */                                    pToken = XP_STRTOK_R(nil, "\"", &pSub );                                    if (pToken) {                                        pChar = (char *)((void *)(TEntry))                                            + ParseData[i].DataOffset;                                        szTemp = PL_strdup(pToken);                                        XP_MEMCPY((void *)pChar,                                            (void *)&szTemp,                                            sizeof(char *) );                                    }                                    break;                                case TYPE_INT:                                    /*                                     * get the next token which should be some                                     * number                                     */                                    pToken = XP_STRTOK_R(nil, " ", &pSub );                                    if (pToken) {                                        pChar = (char *)((void *)(TEntry))                                            + ParseData[i].DataOffset;                                        k = XP_ATOI( pToken );                                        XP_MEMCPY((void *)pChar,                                            (void *)&k, sizeof(int));                                    }                                    break;                            }                            break;           /* break out of the for loop */                        }                    }                } else {                    /* all done */                    break;                }                pToken = XP_STRTOK_R(nil, " :", &pSub );     /* get the next token */            } /* end while */            PR_FREEIF( pCopy );            /* Does the trust list exist in this entry, if not create it */            if(!cookie_permission->TrustList) {                cookie_permission->TrustList = XP_ListNew();                if(!cookie_permission->TrustList) {                    return;                }            }            /* add the entry to the list in the permission entry */            XP_ListAddObjectToEnd( cookie_permission->TrustList, TEntry );        } /* end if (TEntry) */        /* set up for the next entry */        p = ++pEnd;    } /* end while ((p=strcasestr( */    return;}/***************************************************************** Purpose: Write the trust label information from the permission*		   list to cookperm.txt** History:*  Paul Chek - initial creation****************************************************************/PRIVATEvoid SaveTrustLabelData	( net_CookiePermissionStruct * cookie_permission, XP_File fp ){    XP_List *Tptr;    TrustEntry *TEntry;    char *szTemp;    char *szTemp2;    char **pChar;    int *pInt;    int T2Size = 50;    int len, i;    /*     * do an initial allocation for szTemp2.  Whenever a quoted string      * is processed the size of szTemp2 is tested to make sure it is big enough,     * if it is not it is resized.     */    szTemp2 = XP_ALLOC( T2Size );    if ( fp && cookie_permission && cookie_permission->TrustList && szTemp2 ) {        /* there is trust label information, write it */        Tptr = cookie_permission->TrustList;        while( (TEntry = (TrustEntry *)XP_ListNextObject(Tptr))) {            /* build the string up one piece at a time, its slower but safer */            szTemp = NULL;            StrAllocCopy( szTemp, "  "STR_TRUST_LABEL);            /* march thru the Parsing table and output the TrustLabel information */            for ( i=0; i<NUM_ITEMS; i++ ) {                switch(ParseData[i].ValueType) {                    case TYPE_QUOTED_STRING:                        pChar = (char **)(((char *)TEntry)+ ParseData[i].DataOffset);                        if ( PL_strlen( *pChar ) ) {                            /* make sure szTemp2 is big enough. */                            len = PL_strlen( ParseData[i].szMatchStr ) + PL_strlen(*pChar) + 3;                            if ( T2Size <= len ) {                                T2Size = len +50;                                szTemp2 = XP_REALLOC( szTemp2, T2Size );                            }                            if ( szTemp2 ) {                                PR_snprintf( szTemp2, T2Size, " %s:\"%s\"",                                ParseData[i].szMatchStr, *pChar );                                StrAllocCat( szTemp, szTemp2 );                             } else {                               /* error reallocating szTemp2, blast out */                               PR_FREEIF( szTemp );                               return;                            }                        }                        break;                    case TYPE_INT:                        pInt = (int *)(((char *)TEntry)+ ParseData[i].DataOffset);                        PR_snprintf( szTemp2, T2Size, " %s:%d",                            ParseData[i].szMatchStr, *pInt );                        StrAllocCat( szTemp, szTemp2 );                         break;                }            } /* end for */            StrAllocCat( szTemp, " )" ); /* add the termination paren */            /* write a single trust label string */            XP_FileWrite(szTemp, -1, fp);            PR_FREEIF( szTemp );        } /* end while( (TEntry =  */         PR_FREEIF( szTemp2 );    }}/***************************************************************** Purpose:  search for a TrustEntry in the trust list of a cookie * permission entry.** History:*  Paul Chek - initial creation****************************************************************/PRIVATEBool FindTrustEntry( char *CookieName, XP_List *TList, TrustEntry **TheEntry ){    TrustEntry *TEntry;    XP_List *TPtr;    Bool Status = FALSE;    if ( TList && !XP_ListIsEmpty( TList ) ) {        TPtr = TList;        while( (TEntry = (TrustEntry *)XP_ListNextObject(TPtr))) {            if (PL_strcasecmp(CookieName, TEntry->CookieName) == 0) {                /* the entry was found */                *TheEntry = TEntry;                Status = TRUE;                break;            }        }    }    return Status;}/***************************************************************** Purpose: given a TrustLabel struct sat up the corresponding TrustEntry** History:*  Paul Chek - initial creation****************************************************************/PRIVATEvoid CopyTrustEntry( char *CookieName, TrustEntry *TEntry, TrustLabel *trustlabel ){    PRExplodedTime now;    char line[100];    if ( TEntry && trustlabel ) {        PR_FREEIF(TEntry->CookieName);        PR_FREEIF(TEntry->by);        PR_FREEIF(TEntry->CookieSet);        TEntry->CookieName  = PL_strdup( CookieName );        TEntry->purpose = trustlabel->purpose;        TEntry->recipient = trustlabel->recipients;        TEntry->bIdentifiable = trustlabel->ID;        TEntry->by = PL_strdup( trustlabel->szBy );        /*         * format an ASCII timestamp for when the cookie was set.  Use a          *format that PR_ParseTimeString supports. "22-AUG-1993 10:59 PM"         */         PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);        PR_FormatTimeUSEnglish(line, 400, "%d-%b-%Y %I:%M %p", &now);        TEntry->CookieSet  = PL_strdup( line );	}}/***************************************************************** Purpose: look in the permissions list to see if there is * trust label information for the cookie.  If so delete it.** History:*  Paul Chek - initial creation****************************************************************/PRIVATEvoid DeleteCookieFromPermissions( char *CookieHost, char *CookieName ){    XP_List *Tptr, *TmpList;    TrustEntry *TEntry;    net_CookiePermissionStruct * cookie_permission;    /* lock the permission list */    TmpList=net_cookie_permission_list;    net_lock_cookie_permission_list();    while ( (cookie_permission=(net_CookiePermissionStruct *)XP_ListNextObject(TmpList)) ) {        /* is this the corect host for the cookie */        if (PL_strcasecmp(CookieHost, cookie_permission->host) == 0) {            /* yes - see if there is a trust label entry for the cookie */            if ( FindTrustEntry( CookieName, cookie_permission->TrustList, &TEntry ) ) {                /* yes there is - delete it */                Tptr = Tptr->prev; /* before removing the current entry get the ptr to the next one */                XP_ListRemoveObject( cookie_permission->TrustList, TEntry);                /* free the strings in the entry */                PR_FREEIF(TEntry->CookieName);                PR_FREEIF(TEntry->by);                PR_FREEIF(TEntry->CookieSet);            }            /* dont need to look in the list anymore cause there is only one entry per host */            break;			        }    }    net_unlock_cookie_permission_list();}/***************************************************************** Purpose: given a TrustLabel struct containing the trust label*			info that matches a particular cookie add the trust*			label info to the cookie permission list** History:*  Paul Chek - initial creation****************************************************************/PRIVATEvoid AddTrustLabelInfo( char *CookieName, TrustLabel *trustlabel ){    XP_List *TmpList;    TrustEntry *TEntry;	net_CookiePermissionStruct * cookie_permission;	/* lock the permission list */    TmpList=net_cookie_permission_list;    net_lock_cookie_permission_list();    while ( (cookie_permission=(net_CookiePermissionStruct *)XP_ListNextObject(TmpList)) ) {		/* is this the corect host for the cookie */		if (PL_strcasecmp(trustlabel->domainName, cookie_permission->host) == 0) {			/* OK - we have found the entry for this host.  Look thru the trust list 			   to see if we have an existing entry for this cookie.  If so replace it.			   If not add a new entry			*/			if ( FindTrustEntry( CookieName, cookie_permission->TrustList, &TEntry ) ) {				/* the entry exists modify it */				CopyTrustEntry( CookieName, TEntry, trustlabel );			} else {				/* the entry does NOT exist - add a new one */				TEntry = PR_NEWZAP( TrustEntry ); 				if ( TEntry ) {					/* yes - build the entry for the cookie */					CopyTrustEntry( CookieName, TEntry, trustlabel );					/* Does the trust list exist in this entry, if not create it */					if(!cookie_permission->TrustList) {						cookie_permission->TrustList = XP_ListNew();						if(!cookie_permission->TrustList) {							return;						}					}					/* add it to the list */					XP_ListAddObjectToEnd(cookie_permission->TrustList, TEntry);					break;		  /* all done */					}			}		}	}    net_unlock_cookie_permission_list();}#endif/* * return a string that has each " of the argument sting * replaced with \" so it can be used inside a quoted string */PRIVATE char*net_FixQuoted(char* s) {    char * result;    int count = PL_strlen(s);    char *quote = s;    unsigned int i, j;    while (quote = PL_strchr(quote, '"')) {        count = count++;        quote++;    }    result = XP_ALLOC(count + 1);    for (i=0, j=0; i<PL_strlen(s); i++) {        if (s[i] == '"') {            result[i+(j++)] = '\\';        }        result[i+j] = s[i];    }    result[i+j] = '\0';    return result;}#ifdef XP_MAC/* pinkerton - if we don't do this, it won't compile because it runs out of registers */#pragma global_optimizer on#endifPRIVATE voidnet_DisplayCookieInfoAsHTML(MWContext *context, char* host){    char *buffer = (char*)PR_Malloc(BUFLEN);    char *buffer2 = 0;    int g = 0, count, cookieNum;    XP_List *cookie_list;    XP_List *cookie_permission_list;    net_CookieStruct *cookie;    net_CookiePermissionStruct *cookperm;    CookieViewerDialog *dlg;    int i;    char * view_sites = NULL;    char * view_cookies = NULL;    char * heading = NULL;#ifdef TRUST_LABELS    char * szTrustLabel = NULL;#endif    static XPDialogInfo dialogInfo = {	0,	net_AboutCookiesDialogDone,	600,	400    };    XPDialogStrings* strings;    strings = XP_GetDialogStrings(XP_CERT_PAGE_STRINGS);    if (!strings) {	return;    }    StrAllocCopy(buffer2, "");    StrAllocCopy (view_cookies, XP_GetString(MK_ACCESS_VIEW_COOKIES));    StrAllocCopy (view_sites, XP_GetString(MK_ACCESS_VIEW_SITES));    /* generate initial section of html file */    g += PR_snprintf(buffer+g, BUFLEN-g,"<HTML>\n""<HEAD>\n""  <TITLE>Cookies</TITLE>\n""  <SCRIPT>\n""    index_frame = 0;\n""    title_frame = 1;\n""    spacer1_frame = 2;\n""    list_frame = 3;\n""    spacer2_frame = 4;\n""    prop_frame = 5;\n""    spacer3_frame = 6;\n""    button_frame = 7;\n""\n""    var cookie_mode;\n""    var goneC;\n""    var goneP;\n""    deleted_cookies = new Array (0"	);    FLUSH_BUFFER    /* fill in initial 0's for deleted_cookies and deleted_sites arrays */    count = XP_ListCount(net_cookie_list);    for (i=1; i<count; i++) {	g += PR_snprintf(buffer+g, BUFLEN-g,",0"	    );	if ((i%50) == 0) {	    g += PR_snprintf(buffer+g, BUFLEN-g,"\n      "	    );	}    }    g += PR_snprintf(buffer+g, BUFLEN-g,");\n""    deleted_sites = new Array (0"	);    count = XP_ListCount(net_cookie_permission_list);    for (i=1; i<count; i++) {	g += PR_snprintf(buffer+g, BUFLEN-g,",0"	    );	if ((i%50) == 0) {	    g += PR_snprintf(buffer+g, BUFLEN-g,"\n      "	    );	}    }    FLUSH_BUFFER    g += PR_snprintf(buffer+g, BUFLEN-g,");\n""\n""    function DeleteItemSelected() {\n""      if (cookie_mode) {\n""        DeleteCookieSelected();\n""      } else {\n""        DeleteSiteSelected();\n""      }\n""    }\n""\n""    function DeleteCookieSelected() {\n""      selname = top.frames[list_frame].document.fSelectCookie.selname;\n""      goneC = top.frames[button_frame].document.buttons.goneC;\n""      var p;\n""      var i;\n""      for (i=selname.options.length; i>0; i--) {\n""        if (selname.options[i-1].selected) {\n""          selname.options[i-1].selected = 0;\n""          goneC.value = goneC.value + selname.options[i-1].value + \",\";\n""          deleted_cookies[selname.options[i-1].value] = 1;\n""          for (j=i ; j<selname.options.length ; j++) {\n""            selname.options[j-1] = selname.options[j];\n""          }\n""          selname.options[selname.options.length-1] = null;\n""        }\n""      }\n""      top.frames[prop_frame].document.open();\n""      top.frames[prop_frame].document.close();\n""    }\n""\n""    function DeleteSiteSelected() {\n""      selname = top.frames[list_frame].document.fSelectSite.selname;\n""      goneP = top.frames[button_frame].document.buttons.goneP;\n""      var p;\n""      var i;\n""      for (i=selname.options.length; i>0; i--) {\n""        if (selname.options[i-1].selected) {\n""          selname.options[i-1].selected = 0;\n""          goneP.value = goneP.value + selname.options[i-1].value + \",\";\n""          deleted_sites[selname.options[i-1].value] = 1;\n""          for (j=i; j < selname.options.length; j++) {\n""            selname.options[j-1] = selname.options[j];\n""          }\n""          selname.options[selname.options.length-1] = null;\n""        }\n""      }\n""      top.frames[prop_frame].document.open();\n""      top.frames[prop_frame].document.close();\n""    }\n""\n""    function ViewCookieSelected(selCookie) {\n""      selname = top.frames[list_frame].document.fSelectCookie.selname;\n""      top.frames[prop_frame].document.open();\n""      switch (selname.options[selCookie].value) {\n"	);    FLUSH_BUFFER    /* Get rid of any expired cookies now so user doesn't     * think/see that we're keeping cookies in memory.     */    net_lock_cookie_list();    net_remove_expired_cookies();    /* Generate the html for the cookie properties (alphabetical order) */    cookie_list=net_cookie_list;    cookie = NULL;    while (cookie = NextCookieAfter(cookie, &cookieNum)) {	char * name = NULL;	char * value = NULL;	char * domain_or_host = NULL;	char * path = NULL;	char * secure = NULL;	char * yes_or_no = NULL;	char * expires = NULL;	char * expireDate = NULL;        char *fixed_name = net_FixQuoted(cookie->name);        char *fixed_value = net_FixQuoted(cookie->cookie);	StrAllocCopy (name, XP_GetString(MK_ACCESS_NAME));	StrAllocCopy (value, XP_GetString(MK_ACCESS_VALUE));	StrAllocCopy (domain_or_host,	    cookie->is_domain		? XP_GetString(MK_ACCESS_DOMAIN)		: XP_GetString(MK_ACCESS_HOST));	StrAllocCopy (path, XP_GetString(MK_ACCESS_PATH));	StrAllocCopy (secure, XP_GetString(MK_ACCESS_SECURE));	StrAllocCopy (yes_or_no,	    HG78111		? XP_GetString(MK_ACCESS_YES)		: XP_GetString(MK_ACCESS_NO));	StrAllocCopy (expires, XP_GetString(MK_ACCESS_EXPIRES));	StrAllocCopy (expireDate,	    cookie->expires		? ctime(&(cookie->expires))		: XP_GetString(MK_ACCESS_END_OF_SESSION));	if (!expireDate) {            StrAllocCopy (expireDate, "");        } else if (expireDate[PL_strlen(expireDate)-1] == '\n') {            expireDate[PL_strlen(expireDate)-1] = ' ';	}	g += PR_snprintf(buffer+g, BUFLEN-g,"       case %d:\n""         top.frames[prop_frame].document.write(\n""            \"<NOBR><b>%s</b> %s</NOBR><BR>\" +\n""            \"<NOBR><b>%s</b> %s</NOBR><BR>\" +\n""            \"<NOBR><b>%s</b> %s</NOBR><BR>\" +\n""            \"<NOBR><b>%s</b> %s</NOBR><BR>\" +\n""            \"<NOBR><b>%s</b> %s</NOBR><BR>\" +\n""            \"<NOBR><b>%s</b> %s</NOBR><BR>\" ",	    cookieNum,	    name, fixed_name,	    value, fixed_value,	    domain_or_host, cookie->host,	    path, cookie->path,	    secure, yes_or_no,	    expires, expireDate	    );	FLUSH_BUFFER        PR_FREEIF(fixed_name);        PR_FREEIF(fixed_value);	PR_FREEIF(name);	PR_FREEIF(value);	PR_FREEIF(domain_or_host);	PR_FREEIF(path);	PR_FREEIF(secure);	PR_FREEIF(yes_or_no);	PR_FREEIF(expires);	PR_FREEIF(expireDate);	/* caveat: It would have been simpler to not allocate and free the	 * above strings but rather just use the XP_GetString(...) parameters	 * in the call to PR_snprintf.	However there are only four buffers	 * that XP_GetString uses and it keeps recycling them.	Since the	 * above would require more than four parameters which are calls to	 * XP_GetString, some of the returned buffers would be overwritten         * before they could be used.  Hence the simpler approach wouldn't work	 */#ifdef TRUST_LABELS        /* add an entry that contains the trust label information */        szTrustLabel = GetTrustLabelString( cookie->name );        if ( szTrustLabel ) {            g += PR_snprintf(buffer+g, BUFLEN-g,"+\n""            \"<HR WIDTH=100%> <FONT SIZE=2> %s </FONT>\"",                szTrustLabel);            PR_FREEIF(szTrustLabel);        }#endif        g += PR_snprintf(buffer+g, BUFLEN-g,"\n""         );\n""         break;\n"            );        FLUSH_BUFFER    }    /* generate next section of html file */    g += PR_snprintf(buffer+g, BUFLEN-g,"      }\n""      top.frames[prop_frame].document.close();\n""    }\n""\n""    function loadCookies(){\n""      cookie_mode = 1;\n"	);    FLUSH_BUFFER    /* generate index frame only if full viewer */    if (!host) {	g += PR_snprintf(buffer+g, BUFLEN-g,"      top.frames[index_frame].document.open();\n""      top.frames[index_frame].document.write(\n""        \"<BODY BGCOLOR=#C0C0C0>\" +\n""          \"<TABLE BORDER=0 WIDTH=100%>\" +\n""            \"<TR>\" +\n""              \"<TD> <SPACER TYPE=HORIZONTAL SIZE=10> </TD>\" +\n""              \"<TD ALIGN=CENTER VALIGN=MIDDLE BGCOLOR=#FFFFFF>\" +\n""                \"<FONT SIZE=2 COLOR=#666666>\" +\n""                  \"<B>%s</B>\" +\n""                \"</FONT>\" +\n""              \"</TD>\" +\n""              \"<TD>&nbsp;&nbsp;&nbsp;</TD>\" +\n""              \"<TD ALIGN=CENTER VALIGN=MIDDLE BGCOLOR=#C0C0C0>\" +\n""                \"<A HREF=javascript:top.loadSites();>\" +\n""                  \"<FONT SIZE=2>%s</FONT>\" +\n""                \"</A>\" +\n""              \"</TD>\" +\n""              \"<TD>&nbsp;&nbsp;&nbsp;</TD>\" +\n""            \"</TR>\" +\n""          \"</TABLE>\" +\n""        \"</BODY>\"\n""      );\n""      top.frames[index_frame].document.close();\n""\n",	    view_cookies, view_sites);	FLUSH_BUFFER    }    /* generate next section of html file */    if (!host) {	StrAllocCopy (heading, XP_GetString(MK_ACCESS_COOKIES_ACCEPTED));    } else {	StrAllocCopy (heading, XP_GetString(MK_ACCESS_SITE_COOKIES_ACCEPTED));    }    g += PR_snprintf(buffer+g, BUFLEN-g,"      top.frames[title_frame].document.open();\n""      top.frames[title_frame].document.write\n""        (\"&nbsp;%s\");\n""      top.frames[title_frame].document.close();\n""\n""      top.frames[list_frame].document.open();\n""      top.frames[list_frame].document.write(\n""        \"<FORM name=fSelectCookie>\" +\n""          \"<P>\" +\n""          \"<TABLE BORDER=0 WIDTH=100% HEIGHT=95%>\" +\n""            \"<TR>\" +\n""              \"<TD WIDTH=100% VALIGN=TOP>\" +\n""                \"<CENTER>\" +\n""                  \"<P>\" +\n""                  \"<SELECT NAME=selname \" +\n""                          \"SIZE=15 \" +\n""                          \"MULTIPLE \" +\n""                          \"onchange=top.ViewCookieSelected(selname.selectedIndex);>\"\n""      );\n",	heading);    FLUSH_BUFFER    PR_FREEIF(heading);    /* generate the html for the list of cookies in alphabetical order */    cookie_list=net_cookie_list;    cookie = NULL;    while (cookie = NextCookieAfter(cookie, &cookieNum)) {	if (!host || net_CookieIsFromHost(cookie, host)) {            char *fixed_name = net_FixQuoted(cookie->name);	    g += PR_snprintf(buffer+g, BUFLEN-g,"      if (!deleted_cookies[%d]) {\n""        top.frames[list_frame].document.write(\n""                    \"<OPTION value=%d>\" +\n""                      \"%s:%s\" +\n""                    \"</OPTION>\"\n""        );\n""      }\n",		cookieNum, cookieNum,		(*(cookie->host)=='.') ? (cookie->host)+1: cookie->host,		fixed_name		);	    FLUSH_BUFFER            PR_FREEIF(fixed_name);	}    }    net_unlock_cookie_list();    /* generate next section of html file */    StrAllocCopy (heading, XP_GetString(MK_ACCESS_COOKIES_PERMISSION));    g += PR_snprintf(buffer+g, BUFLEN-g,"      top.frames[list_frame].document.write(\n""                  \"</SELECT>\" +\n""                \"</CENTER>\" +\n""              \"</TD>\" +\n""            \"</TR>\" +\n""          \"</TABLE>\" +\n""        \"</FORM>\"\n""      );\n""      top.frames[list_frame].document.close();\n""\n""      top.frames[prop_frame].document.open();\n""      top.frames[prop_frame].document.close();\n""    }\n""\n""    function loadSites(){\n""      cookie_mode = 0;\n""      top.frames[index_frame].document.open();\n""      top.frames[index_frame].document.write(\n""        \"<BODY BGCOLOR=#C0C0C0>\" +\n""          \"<TABLE BORDER=0 WIDTH=100%>\" +\n""            \"<TR>\" +\n""              \"<TD> <SPACER TYPE=HORIZONTAL SIZE=10> </TD>\" +\n""              \"<TD ALIGN=CENTER VALIGN=MIDDLE BGCOLOR=#C0C0C0>\" +\n""                \"<A HREF=javascript:top.loadCookies();>\" +\n""                  \"<FONT SIZE=2>%s</FONT>\" +\n""                \"</A>\" +\n""              \"</TD>\" +\n""              \"<TD>&nbsp;&nbsp;&nbsp;</TD>\" +\n""              \"<TD ALIGN=CENTER VALIGN=MIDDLE BGCOLOR=#FFFFFF>\" +\n""                \"<FONT SIZE=2 COLOR=#666666>\" +\n""                  \"<B>%s</B>\" +\n""                \"</FONT>\" +\n""              \"</TD>\" +\n""              \"<TD>&nbsp;&nbsp;&nbsp;</TD>\" +\n""            \"</TR>\" +\n""          \"</TABLE>\" +\n""        \"</BODY>\"\n""      );\n""      top.frames[index_frame].document.close();\n""\n""      top.frames[title_frame].document.open();\n""      top.frames[title_frame].document.write\n""        (\"&nbsp;%s\");\n""      top.frames[title_frame].document.close();\n""\n""      top.frames[list_frame].document.open();\n""      top.frames[list_frame].document.write(\n""        \"<FORM name=fSelectSite>\" +\n""          \"<P>\" +\n""          \"<TABLE BORDER=0 WIDTH=100% HEIGHT=95%>\" +\n""            \"<TR>\" +\n""              \"<TD WIDTH=100% VALIGN=TOP>\" +\n""                \"<CENTER>\" +\n""                  \"<P>\" +\n""                  \"<SELECT NAME=selname SIZE=15 MULTIPLE> \"\n""      );\n",	view_cookies, view_sites, heading);    FLUSH_BUFFER    PR_FREEIF(heading);    FLUSH_BUFFER    /* generate the html for the list of cookie permissions */    cookieNum = 0;    cookie_permission_list=net_cookie_permission_list;    net_lock_cookie_permission_list();    while ( (cookperm=(net_CookiePermissionStruct *)		      XP_ListNextObject(cookie_permission_list)) ) {	g += PR_snprintf(buffer+g, BUFLEN-g,"      if (!deleted_sites[%d]) {\n""        top.frames[list_frame].document.write(\n""                    \"<OPTION value=\" +\n""                      \"%d>\" +\n""                      \"%s %s\" +\n""                    \"</OPTION>\"\n""        );\n""      }\n",	    cookieNum, cookieNum,            cookperm->permission ? "+" : "-",	    cookperm->host);	FLUSH_BUFFER	cookieNum++;    }    net_unlock_cookie_permission_list();    /* generate next section of html file */    g += PR_snprintf(buffer+g, BUFLEN-g,"      top.frames[list_frame].document.write(\n""                  \"</SELECT>\" +\n""                \"</CENTER>\" +\n""              \"</TD>\" +\n""            \"</TR>\" +\n""          \"</TABLE>\" +\n""        \"</FORM>\"\n""      );\n""      top.frames[list_frame].document.close();\n""\n""      top.frames[prop_frame].document.open();\n""      top.frames[prop_frame].document.close();\n""    }\n""\n""    function loadButtons(){\n""      top.frames[button_frame].document.open();\n""      top.frames[button_frame].document.write(\n""        \"<FORM name=buttons action=internal-dialog-handler method=post>\" +\n""          \"<BR>\" +\n""          \"&nbsp;\" +\n""          \"<INPUT type=BUTTON \" +\n""                 \"value=Remove \" +\n""                 \"onclick=top.DeleteItemSelected();>\" +\n""          \"<DIV align=right>\" +\n""            \"<INPUT type=BUTTON value=OK width=80 onclick=parent.clicker(this,window.parent)>\" +\n""            \" &nbsp;&nbsp;\" +\n""            \"<INPUT type=BUTTON value=Cancel width=80 onclick=parent.clicker(this,window.parent)>\" +\n""          \"</DIV>\" +\n""          \"<INPUT type=HIDDEN name=xxxbuttonxxx>\" +\n""          \"<INPUT type=HIDDEN name=handle value="	);    FLUSH_BUFFER    /* transfer what we have so far into strings->args[0] */    if (buffer2) {	XP_SetDialogString(strings, 0, buffer2);	buffer2 = NULL;    }    /* Note: strings->args[1] will later be filled in with value of handle */    /* generate remainder of html, it will go into strings->arg[2] */    g += PR_snprintf(buffer+g, BUFLEN-g,">\" +\n""          \"<INPUT TYPE=HIDDEN NAME=goneC SIZE=-1>\" +\n""          \"<INPUT TYPE=HIDDEN NAME=goneP SIZE=-1>\" +\n""        \"</FORM>\"\n""      );\n""      top.frames[button_frame].document.close();\n""    }\n""\n""    function loadFrames(){\n""      loadCookies();\n""      loadButtons();\n""    }\n""\n""    function clicker(but,win){\n""      top.frames[button_frame].document.buttons.xxxbuttonxxx.value = but.value;\n""      top.frames[button_frame].document.buttons.xxxbuttonxxx.name = 'button';\n""      top.frames[button_frame].document.buttons.submit();\n""    }\n""\n""  </SCRIPT>\n""</HEAD>\n""<FRAMESET ROWS = 25,25,*,75\n""         BORDER=0\n""         FRAMESPACING=0\n""         onLoad=loadFrames()>\n""  <FRAME SRC=about:blank\n""        NAME=index_frame\n""        SCROLLING=NO\n""        MARGINWIDTH=1\n""        MARGINHEIGHT=1\n""        NORESIZE>\n""  <FRAME SRC=about:blank\n""        NAME=title_frame\n""        SCROLLING=NO\n""        MARGINWIDTH=1\n""        MARGINHEIGHT=1\n""        NORESIZE>\n""  <FRAMESET COLS=5,*,10,*,5\n""           BORDER=0\n""           FRAMESPACING=0>\n""    <FRAME SRC=about:blank\n""          NAME=spacer1_frame\n""          SCROLLING=AUTO\n""          MARGINWIDTH=0\n""          MARGINHEIGHT=0\n""          NORESIZE>\n""    <FRAME SRC=about:blank\n""          NAME=list_frame\n""          SCROLLING=AUTO\n""          MARGINWIDTH=0\n""          MARGINHEIGHT=0\n""          NORESIZE>\n""    <FRAME SRC=about:blank\n""          NAME=spacer2_frame\n""          SCROLLING=AUTO\n""          MARGINWIDTH=0\n""          MARGINHEIGHT=0\n""          NORESIZE>\n""    <FRAME SRC=about:blank\n""          NAME=prop_frame\n""          SCROLLING=AUTO\n""          MARGINWIDTH=0\n""          MARGINHEIGHT=0\n""          NORESIZE>\n""    <FRAME SRC=about:blank\n""          NAME=spacer3_frame\n""          SCROLLING=AUTO\n""          MARGINWIDTH=0\n""          MARGINHEIGHT=0\n""          NORESIZE>\n""  </FRAMESET>\n""  <FRAME SRC=about:blank\n""        NAME=button_frame\n""        SCROLLING=NO\n""        MARGINWIDTH=1\n""        MARGINHEIGHT=1\n""        NORESIZE>\n""</FRAMESET>\n""\n""<NOFRAMES>\n""  <BODY> <P> </BODY>\n""</NOFRAMES>\n""</HTML>\n"	);    FLUSH_BUFFER    /* free some strings that are no longer needed */    PR_FREEIF(view_cookies);    PR_FREEIF(view_sites);    PR_FREEIF(buffer);    /* put html just generated into strings->arg[2] and invoke HTML dialog */    if (buffer2) {      XP_SetDialogString(strings, 2, buffer2);      buffer2 = NULL;    }    dlg = PORT_ZAlloc(sizeof(CookieViewerDialog));    if ( dlg == NULL ) {	return;    }    dlg->parent_window = (void *)context;    dlg->dialogUp = PR_TRUE;    dlg->state =XP_MakeRawHTMLDialog(context, &dialogInfo, MK_ACCESS_YOUR_COOKIES,		strings, 1, (void *)dlg);    return;}PUBLIC voidNET_DisplayCookieInfoOfSiteAsHTML(MWContext * context, char * URLName){    char * host;    char * colon;    /* remove protocol from URL name */    host = NET_ParseURL(URLName, GET_HOST_PART);    /* remove port number from URL name */    colon = PL_strchr(host, ':');    if(colon) {        *colon = '\0';    }    net_DisplayCookieInfoAsHTML(context, host);    /* free up allocated string and return */    if(colon) {        *colon = ':';    }    PR_Free(host);}PUBLIC voidNET_DisplayCookieInfoAsHTML(MWContext * context){    net_DisplayCookieInfoAsHTML(context, NULL);}#ifdef XP_MAC/* pinkerton - reset optimization state (see above) */#pragma global_optimizer reset#endif#elsePUBLIC voidNET_DisplayCookieInfoAsHTML(ActiveEntry * cur_entry){}#endif