/* this set of functions parses an incoming stream of HTML and tries to find * any PICS label within it. It doesn't do anything accept parse the pics label * and finish */ #include "xp.h" #include "plstr.h" #include "prmem.h" #include "netutils.h" #include "mkselect.h" #include "mktcp.h" #include "mkgeturl.h" #include "mkstream.h" #include "pa_parse.h" #include "xpgetstr.h" #include "layout.h" #include "pics.h" typedef enum StatesEnum { IN_CONTENT, IN_SCRIPT, ABOUT_TO_BEGIN_TAG, IN_BEGIN_TAG, IN_TAG, BEGIN_ATTRIBUTE_VALUE, IN_QUOTED_ATTRIBUTE_VALUE, IN_BROKEN_QUOTED_ATTRIBUTE_VALUE, IN_UNQUOTED_ATTRIBUTE_VALUE, IN_COMMENT, IN_AMPERSAND_THINGY } StatesEnum; #define MAXTAGLEN 15 typedef struct _DataObject { MWContext *context; URL_Struct *URL_s; StatesEnum state; char tag[MAXTAGLEN+1]; uint tag_index; int tag_type; PRBool in_broken_html; char *tag_data; /* the contents of the current tag */ } DataObject; extern int MK_CVCOLOR_SOURCE_OF; PRIVATE void net_BeginPICSLabelFinderTag (DataObject *obj) { if(obj->tag_data) *obj->tag_data = '\0'; /* empty tag_data */ if (obj->tag_type == P_SCRIPT) { obj->tag_type = P_UNKNOWN; } obj->state = ABOUT_TO_BEGIN_TAG; return ; } PRIVATE void net_EndPICSLabelFinderTag (DataObject *obj) { if(obj->in_broken_html) { obj->in_broken_html = PR_FALSE; } if (obj->tag_type == P_SCRIPT) { obj->state = IN_SCRIPT; } else { obj->state = IN_CONTENT; } /* check tag_data for a META tag */ if(obj->tag_data && !PL_strncasecmp(obj->tag_data, "META", 4)) { PA_Tag tmp_tag; char *name; tmp_tag.type = P_META; tmp_tag.data = (void*)obj->tag_data; tmp_tag.data_len = PL_strlen((char*)tmp_tag.data); name = (char *)lo_FetchParamValue(obj->context, &tmp_tag, PARAM_HTTP_EQUIV); #define PICS_HEADER "PICS-Label" if(name && !PL_strcasecmp(name, PICS_HEADER)) { char *label = (char *)lo_FetchParamValue(obj->context, &tmp_tag, PARAM_CONTENT); if(label) { PICS_RatingsStruct * rs = PICS_ParsePICSLable(label); PR_Free(label); PICS_CompareToUserSettings(rs, obj->URL_s->address); PICS_FreeRatingsStruct(rs); /* handles NULL */ } } PR_FREEIF(name); } return; } PRIVATE int net_PICSLabelFinderWrite (NET_StreamClass *stream, CONST char *s, int32 l) { int32 i; CONST char *cp; DataObject *obj = (DataObject *)stream->data_object; char tiny_buf[8]; for(i = 0, cp = s; i < l; i++, cp++) { switch(obj->state) { case IN_CONTENT: /* do nothing until you find a '<' "' */ if(!PL_strncmp(cp, "-->", 3)) { cp += 2; i += 2; obj->state = IN_CONTENT; } break; case IN_AMPERSAND_THINGY: /* do nothing until you find a ';' or space */ if(*cp == ';' || NET_IS_SPACE(*cp)) { sprintf(tiny_buf, "%c", *cp); obj->state = IN_CONTENT; } break; default: PR_ASSERT(0); break; } } return(0); } /* is the stream ready for writeing? */ PRIVATE unsigned int net_PICSLabelFinderWriteReady (NET_StreamClass *stream) { return(MAX_WRITE_READY); } PRIVATE void net_PICSLabelFinderComplete (NET_StreamClass *stream) { } PRIVATE void net_PICSLabelFinderAbort (NET_StreamClass *stream, int status) { } PUBLIC NET_StreamClass * net_PICSLabelFinderStream (int format_out, void *data_obj, URL_Struct *URL_s, MWContext *window_id) { DataObject* obj; NET_StreamClass *new_stream; PRBool is_html_stream = PR_FALSE; TRACEMSG(("Setting up PICSLabelFinder stream. Have URL: %s\n", URL_s->address)); new_stream = PR_NEWZAP(NET_StreamClass); if(!new_stream) return NULL; obj = PR_NEW(DataObject); if (obj == NULL) { PR_Free(new_stream); return(NULL); } memset(obj, 0, sizeof(DataObject)); obj->state = IN_CONTENT; obj->tag_type = P_UNKNOWN; obj->context = window_id; obj->URL_s = URL_s; new_stream->name = "PICSLabelFinder"; new_stream->complete = (MKStreamCompleteFunc) net_PICSLabelFinderComplete; new_stream->abort = (MKStreamAbortFunc) net_PICSLabelFinderAbort; new_stream->put_block = (MKStreamWriteFunc) net_PICSLabelFinderWrite; new_stream->is_write_ready = (MKStreamWriteReadyFunc) net_PICSLabelFinderWriteReady; new_stream->data_object = (void *) obj; /* document info object */ new_stream->window_id = window_id; /* don't cache this URL, since the content type is wrong */ URL_s->dont_cache = PR_TRUE; return new_stream; }