/* Link me Anchor to another given one ** ------------------------------------- */ PUBLIC BOOL HTLink_add (HTAnchor * source, HTAnchor * destination, HTLinkType type, HTMethod method) { if (source && destination) { HTTRACE(ANCH_TRACE, "Link create. from anchor %p to %p with type %s, method %s\n" _ (void *) source _ (void *) destination _ type ? HTAtom_name(type) : "NONE" _ method != METHOD_INVALID ? HTMethod_name(method) : "NONE"); if (!source->mainLink.dest) { source->mainLink.dest = destination; source->mainLink.type = type; source->mainLink.method = method; } else { HTLink * newLink = HTLink_new(); newLink->dest = destination; newLink->type = type; newLink->method = method; if (!source->links) source->links = HTList_new(); HTList_addObject (source->links, newLink); } if (!destination->parent->sources) destination->parent->sources = HTList_new(); HTList_addObject (destination->parent->sources, source); return YES; } else HTTRACE(ANCH_TRACE, "Link........ Bad argument\n"); return NO; }
PRIVATE BOOL HTCookieHolder_addCookie (HTRequest * request, HTCookie * cookie) { if (request && cookie) { HTList * cur = cookie_holder; HTCookieHolder * pres = NULL; /* Make sure that we have a cookie holder list */ if (!cookie_holder) cookie_holder = HTList_new(); /* See if we already have a cookie holder for this request */ while ((pres = (HTCookieHolder *) HTList_nextObject(cur))) { if (pres->request == request) break; } /* If found then use existing cookie holder, otherwise create new one */ if (!pres) { if ((pres = (HTCookieHolder *) HT_CALLOC(1, sizeof(HTCookieHolder))) == NULL) HT_OUTOFMEM("HTCookieHolder_newCookie"); pres->request = request; pres->cookies = HTList_new(); /* Add to cookie holder list */ HTList_addObject(cookie_holder, pres); } /* Now add the cookie */ HTList_addObject(pres->cookies, cookie); return YES; } return NO; }
PUBLIC HTStream * HTRules (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream) { HTAlertCallback *cbf = HTAlert_find(HT_A_CONFIRM); /* ** If the library has been compiled so that we automatically accept ** rule files then it's OK not to ask the user. */ #ifdef HT_AUTOMATIC_RULES if (!cbf || (cbf && (*cbf)(request,HT_A_CONFIRM, HT_MSG_RULES, NULL,NULL,NULL))) { #else if ((cbf && (*cbf)(request,HT_A_CONFIRM, HT_MSG_RULES, NULL,NULL,NULL))) { #endif HTStream * me; HTTRACE(APP_TRACE, "Rule file... Parser object created\n"); if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTRules"); me->isa = &HTRuleClass; me->request = request; me->buffer = HTChunk_new(512); me->EOLstate = EOL_BEGIN; if (!rules) rules = HTList_new(); return me; } else { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NO_AUTO_RULES, NULL, 0, "HTRules"); return HTErrorStream(); } } /* ** Parse a rule file - don't ask don't tell - be carefull with this one! */ PUBLIC HTStream * HTRules_parseAutomatically (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream) { if (request) { HTStream * me; HTTRACE(APP_TRACE, "Rule file... Automatic parser object created\n"); if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTRules"); me->isa = &HTRuleClass; me->request = request; me->buffer = HTChunk_new(512); me->EOLstate = EOL_BEGIN; if (!rules) rules = HTList_new(); return me; } else { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NO_AUTO_RULES, NULL, 0, "HTRules"); return HTErrorStream(); } }
int main() { HTList * converters = HTList_new(); /* List of converters */ HTList * encodings = HTList_new(); /* List of encoders */ /* Set up the application's event loop. We use the example event loop that comes with the Library. */ HTEventInit(); /* Initialize libwww core */ HTLibInit("TestApp", "1.0"); /* Turn on TRACE so we can see what is going on */ HTSetTraceMessageMask("sop"); /* Register the default set of transport protocols */ HTTransportInit(); /* Register the default set of protocol modules */ HTProtocolInit(); /* Register the default set of BEFORE and AFTER filters */ HTNetInit(); /* Register the default set of converters */ HTConverterInit(converters); HTFormat_setConversion(converters); /* Register the default set of transfer encoders and decoders */ HTTransferEncoderInit(encodings); HTFormat_setTransferCoding(encodings); /* Register the default set of file suffix bindings */ HTFileInit(); /* Register the default set of MIME header parsers */ HTMIMEInit(); /* Register the default set of Icons for directory listings */ HTIconInit(NULL); /* Register the default set of messages and dialog functions */ HTAlertInit(); /* Terminate the Library */ HTLibTerminate(); return 0; }
/* ParseGroup ** ---------- ** Extract the index number, subject etc, from a XOVER command. Expects ** the following format of the line: ** ** <index> <subject> <from> <data> <msgid> [*<thread>] ... ** ** Returns YES if OK, NO on error */ PRIVATE BOOL ParseGroup (HTRequest * request, HTNewsDir *dir, char * line) { int index; int refcnt=0; time_t t=0; char *subject = line; char *from; char *date; char *msgid; char *ptr=NULL; HTList* reflist = NULL; /* Added by MP. */ while (*subject && *subject != DELIMITER) subject++; *subject++ = '\0'; /* Index */ index = atoi(line); from = subject; while (*from && *from != DELIMITER) from++; *from++ = '\0'; /* Subject */ date = from; while (*date && *date != DELIMITER) { if (*date=='<' || *date=='(') { ptr = date+1; *date = '\0'; } if (*date=='>' || *date==')') *date = '\0'; date++; } *date++ = '\0'; if (strchr(from, ATSIGN) && ptr) from = ptr; /* From */ msgid = date; while (*msgid && *msgid != DELIMITER) msgid++; *msgid++ = '\0'; /* Date */ if (*msgid=='<') msgid++; t = HTParseTime(date, HTRequest_userProfile(request), YES); ptr = msgid; while (*ptr && *ptr != DELIMITER) { if (*ptr=='>') *ptr = '\0'; ptr++; } *ptr++ = '\0'; /* MsgId */ while (ptr && *ptr && !isdigit((int) *ptr)) { char* refstart = ptr; /* Added by MP. */ char* refcopy = NULL; char* refstop; while (*ptr && *ptr != DELIMITER && *ptr != ' ') ptr++; refstop = ptr - 1; *ptr++ = '\0'; if (strlen(refstart) > 0) /* Added by MP. */ { refcnt++; if (*refstart == '<') refstart++; if (*refstop == '>') *refstop = '\0'; if (reflist == NULL) reflist = HTList_new(); StrAllocCopy (refcopy, refstart); HTList_addObject (reflist, (void*) refcopy); } } /* Changed by MP. */ return (HTNewsDir_addElement(dir, index, subject, from, t, msgid, refcnt, reflist) != NULL); }
/* Define a presentation system command for a content-type ** ------------------------------------------------------- */ PUBLIC void HTSetPresentation ARGS5( WWW_CONST char *, representation, WWW_CONST char *, command, float, quality, float, secs, float, secs_per_byte ){ HTPresentation * pres = (HTPresentation *)malloc(sizeof(HTPresentation)); pres->rep = HTAtom_for(representation); pres->rep_out = WWW_PRESENT; /* Fixed for now ... :-) */ pres->converter = HTSaveAndExecute; /* Fixed for now ... */ pres->quality = quality; pres->secs = secs; pres->secs_per_byte = secs_per_byte; pres->rep = HTAtom_for(representation); pres->command = 0; StrAllocCopy(pres->command, command); if (!HTPresentations) HTPresentations = HTList_new(); if (strcmp(representation, "*")==0) { if (default_presentation) free(default_presentation); default_presentation = pres; } else { HTList_addObjectAtEnd(HTPresentations, pres); } }
/* ** Register a Protocol module as an active access method */ PUBLIC BOOL HTProtocol_add (const char * name, const char * transport, HTProtocolId protocolId, BOOL preemptive, HTProtCallback * client, HTProtCallback * server) { if (name && (client || server)) { HTProtocol *newProt; if ((newProt=(HTProtocol *) HT_CALLOC(1, sizeof(HTProtocol))) == NULL) HT_OUTOFMEM("HTProtocol_add"); StrAllocCopy(newProt->name, name); { char *ptr = newProt->name; while ((*ptr = TOLOWER(*ptr))) ptr++; } StrAllocCopy(newProt->transport, transport); { char *ptr = newProt->transport; while ((*ptr = TOLOWER(*ptr))) ptr++; } newProt->id = protocolId; newProt->preemptive = preemptive; newProt->client = client; newProt->server = server; if (!protocols) protocols = HTList_new(); else HTProtocol_delete(name); /* Ensure not listed twice */ HTTRACE(CORE_TRACE, "Protocol.... Adding `%s'\n" _ name); return HTList_addObject(protocols, (void *) newProt); } return NO; }
/* Define a built-in function for a content-type ** --------------------------------------------- */ PUBLIC void HTSetConversion ARGS6( WWW_CONST char *, representation_in, WWW_CONST char *, representation_out, HTConverter*, converter, float, quality, float, secs, float, secs_per_byte ){ HTPresentation * pres = (HTPresentation *)malloc(sizeof(HTPresentation)); pres->rep = HTAtom_for(representation_in); pres->rep_out = HTAtom_for(representation_out); pres->converter = converter; pres->command = NULL; /* Fixed */ pres->quality = quality; pres->secs = secs; pres->secs_per_byte = secs_per_byte; pres->command = 0; if (!HTPresentations) HTPresentations = HTList_new(); if (strcmp(representation_in, "*")==0) { if (default_presentation) free(default_presentation); default_presentation = pres; } else { HTList_addObject(HTPresentations, pres); } }
PRIVATE ItemList *parse_item_list ARGS1(FILE *, fp) { ItemList *item_list = HTList_new(); Item *item; LexItem lex_item; for(;;) { if (!(item = parse_item(fp))) { HTList_delete(item_list); /* @@@@ */ item_list = NULL; return NULL; } HTList_addObject(item_list, (void*)item); lex_item = lex(fp); if (lex_item != LEX_ITEM_SEP) { unlex(lex_item); return item_list; } /* ** Here lex_item == LEX_ITEM_SEP; after item separator it ** is ok to have one or more newlines (LEX_REC_SEP) and ** they are ignored (continuation line). */ do { lex_item = lex(fp); } while (lex_item == LEX_REC_SEP); unlex(lex_item); } }
/* Define the representation associated with a file suffix ** ------------------------------------------------------- ** ** Calling this with suffix set to "*" will set the default ** representation. ** Calling this with suffix set to "*.*" will set the default ** representation for unknown suffix files which contain a ".". */ PUBLIC void HTSetSuffix ARGS4( WWW_CONST char *, suffix, WWW_CONST char *, representation, WWW_CONST char *, encoding, float, value) { HTSuffix * suff; if (strcmp(suffix, "*")==0) suff = &no_suffix; else if (strcmp(suffix, "*.*")==0) suff = &unknown_suffix; else { suff = (HTSuffix*) calloc(1, sizeof(HTSuffix)); if (suff == NULL) outofmem(__FILE__, "HTSetSuffix"); if (!HTSuffixes) HTSuffixes = HTList_new(); HTList_addObject(HTSuffixes, suff); StrAllocCopy(suff->suffix, suffix); } suff->rep = HTAtom_for(representation); { char *enc = NULL, *p; StrAllocCopy(enc, encoding); for (p=enc; *p; p++) *p = TOLOWER(*p); suff->encoding = HTAtom_for(enc); free (enc); } suff->quality = value; }
PRIVATE Robot * Robot_new (void) { Robot * me; if ((me = (Robot *) HT_CALLOC(1, sizeof(Robot))) == NULL || (me->tv = (struct timeval*) HT_CALLOC(1, sizeof(struct timeval))) == NULL) HT_OUTOFMEM("Robot_new"); me->htext = 0; me->tv->tv_sec = DEFAULT_TIMEOUT; me->cwd = HTGetCurrentDirectoryURL(); me->output = OUTPUT; me->urilist = HTList_new(); me->count = 0; /* We keep an extra timeout request object for the timeout_handler */ me->timeout = HTRequest_new(); /* Bind the Robot object together with the Request Object */ me->request = HTRequest_new(); HTRequest_setContext (me->request, me); HTRequest_setPreemptive(me->request, YES); /* Make a new profile */ HTProfile_newPreemptiveRobot ("w3clibtcl", "1.0"); return me; }
/* HTNoProxy_add ** ------------- ** Registers a host name or a domain as a place where no proxy should ** be contacted - for example a very fast link. If `port' is '0' then ** it applies to all ports and if `access' is NULL then it applies to ** to all access methods. ** ** Examples: w3.org ** www.close.com */ PUBLIC BOOL HTNoProxy_add (const char * host, const char * access, unsigned port) { if (!noproxy) noproxy = HTList_new(); return add_hostname(noproxy, host, access, port, NO, -1); }
PUBLIC HTMuxChannel * HTMuxChannel_new (HTHost * host) { if (host) { HTMuxChannel * me = NULL; /* Create new object */ if ((me = (HTMuxChannel *) HT_CALLOC(1, sizeof(HTMuxChannel))) == NULL) HT_OUTOFMEM("HTMuxChannel_new"); me->hash = HTHost_hash(host); me->host = host; /* ** Make sure that we are in interleave mode */ HTHost_setMode(host, HT_TP_INTERLEAVE); /* ** Get a special MUX Net object that we keep to our selves. We don't ** associate a request object as the Net object lives longer. */ me->net = HTNet_new(NULL); HTNet_setReadStream(me->net, HTDemux_new(host, me)); /* Insert into hash table */ if (!muxchs) { if ((muxchs=(HTList **) HT_CALLOC(HOST_HASH_SIZE, sizeof(HTList *))) == NULL) HT_OUTOFMEM("HTMuxChannel_new"); } if (!muxchs[me->hash]) muxchs[me->hash] = HTList_new(); HTList_addObject(muxchs[me->hash], (void *) me); HTTRACE(MUX_TRACE, "Mux Channel. %p created with hash %d\n" _ me _ me->hash); return me; } return NULL; }
PRIVATE HTChildAnchor * HTAnchor_findChild ARGS2 (HTParentAnchor *,parent, CONST char *,tag) { HTChildAnchor *child; HTList *kids; if (! parent) { if (TRACE) printf ("HTAnchor_findChild called with NULL parent.\n"); return NULL; } if (kids = parent->children) { /* parent has children : search them */ if (tag && *tag) { /* TBL */ while (child = HTList_nextObject (kids)) { if (equivalent(child->tag, tag)) { /* Case sensitive 920226 */ if (TRACE) printf ( "Child anchor %p of parent %p with name `%s' already exists.\n", child, parent, tag); return child; } } } /* end if tag is void */ } else /* parent doesn't have any children yet : create family */ parent->children = HTList_new (); child = HTChildAnchor_new (); if (TRACE) fprintf(stderr, "new Anchor %p named `%s' is child of %p\n", child, (int)tag ? tag : (CONST char *)"" , parent); /* int for apollo */ HTList_addObject (parent->children, child); child->parent = parent; StrAllocCopy(child->tag, tag); return child; }
PUBLIC int HTServHTTP (SOCKET soc, HTRequest * request) { HTNet * net = HTRequest_net(request); https_info * http; /* Specific protocol information */ /* ** Initiate a new https object and bind to request object ** This is actually state HTTPS_BEGIN, but it can't be in the state ** machine as we need the object first (chicken and egg problem). */ HTTRACE(PROT_TRACE, "Serv HTTP... on socket %d\n" _ soc); if ((http = (https_info *) HT_CALLOC(1, sizeof(https_info))) == NULL) HT_OUTOFMEM("HTServHTTP"); http->server = request; http->state = HTTPS_BEGIN; http->clients = HTList_new(); HTNet_setContext(net, http); /* ** Create the stream pipe FROM the channel to the server request. */ net->readStream = HTTPReceive_new(request, http); HTRequest_setOutputConnected(request, YES); http->state = HTTPS_BEGIN; HTNet_setEventCallback(net, ServEvent); HTNet_setEventParam(net, http); /* callbacks get http* */ return ServEvent(soc, http, HTEvent_BEGIN); /* get it started - ops is ignored */ }
PUBLIC BOOL HTFormat_addTransferCoding ( char * encoding, HTCoder * encoder, HTCoder * decoder, double quality) { if (!HTTransferCoders) HTTransferCoders = HTList_new(); return HTCoding_add(HTTransferCoders, encoding, encoder, decoder, quality); }
PUBLIC BOOL HTAnchor_addLanguage (HTParentAnchor * me, HTLanguage language) { if (me && language) { if (!me->content_language) me->content_language = HTList_new(); return HTList_addObject(me->content_language, language); } return NO; }
/* Methods List ** ------------ */ PUBLIC HTList * HTAnchor_methods ARGS1( HTParentAnchor *, me) { if (!me->methods) { me->methods = HTList_new(); } return( me->methods); }
/* ** Transfer Encoding */ PUBLIC BOOL HTResponse_addTransfer (HTResponse * me, HTEncoding transfer) { if (me && transfer) { if (!me->transfer_encoding) me->transfer_encoding = HTList_new(); return HTList_addObject(me->transfer_encoding, transfer); } return NO; }
PUBLIC BOOL HTAnchor_addEncoding (HTParentAnchor * me, HTEncoding encoding) { if (me && encoding) { if (!me->content_encoding) me->content_encoding = HTList_new(); return HTList_addObject(me->content_encoding, encoding); } return NO; }
/* ** Content Encoding */ PUBLIC BOOL HTResponse_addEncoding (HTResponse * me, HTEncoding encoding) { if (me && encoding) { if (!me->content_encoding) me->content_encoding = HTList_new(); return HTList_addObject(me->content_encoding, encoding); } return NO; }
PUBLIC HTStyleSheet * HTStyleSheet_new (const char * name) { HTStyleSheet * ss; if ((ss = (HTStyleSheet *) HT_CALLOC(1, sizeof(HTStyleSheet))) == NULL) HT_OUTOFMEM("HTStyleSheet_new"); StrAllocCopy(ss->name, name ? name : "unknown"); ss->styles = HTList_new(); return ss; }
void HTHistory_record ARGS1 (HTAnchor *,destination) { if (destination) { if (! history) history = HTList_new(); HTList_addObject (history, destination); } }
PUBLIC BOOL HTAnchor_addVariant (HTParentAnchor * me, HTParentAnchor * variant) { if (me && variant) { if (!me->variants) me->variants = HTList_new(); return HTList_addObject(me->variants, variant); } return NO; }
PRIVATE GroupDefList *parse_group_file ARGS1(FILE *, fp) { GroupDefList *group_def_list = HTList_new(); GroupDef *group_def; while (NULL != (group_def = parse_group_decl(fp))) add_group_def(group_def_list, group_def); return group_def_list; }
static void remember_alloced(void *ptr) { if (!alloced) { alloced = HTList_new(); #ifdef LY_FIND_LEAKS atexit(free_alloced_lynxcgi); #endif } HTList_addObject(alloced, ptr); }
/* HTNoProxy_addRegex ** ------------------ ** Registers a regular expression where URIs matching this expression ** should go directly and not via a proxy. ** */ PUBLIC BOOL HTNoProxy_addRegex (const char * regex, int regex_flags) { if (!noproxy) noproxy = HTList_new(); #ifdef HT_POSIX_REGEX return add_hostname(noproxy, regex, NULL, 0, YES, regex_flags); #else return add_hostname(noproxy, regex, NULL, 0, NO, -1); #endif }
PUBLIC void HTFormat_addConversion (const char * input_format, const char * output_format, HTConverter * converter, double quality, double secs, double secs_per_byte) { if (!HTConversions) HTConversions = HTList_new(); HTConversion_add(HTConversions, input_format, output_format, converter, quality, secs, secs_per_byte); }
/* ** Set default file name for welcome page on each directory. */ PUBLIC void HTAddWelcome (char * name) { if (name) { char * mycopy = NULL; StrAllocCopy(mycopy,name); if (!welcome_names) welcome_names = HTList_new(); HTList_addObject(welcome_names, (void*)mycopy); } }
/* Create new or find old named anchor ** ----------------------------------- ** ** Me one is for a reference which is found in a document, and might ** not be already loaded. ** Note: You are not guaranteed a new anchor -- you might get an old one, ** like with fonts. */ PUBLIC HTAnchor * HTAnchor_findAddress (const char * address) { char *tag = HTParse (address, "", PARSE_VIEW); /* Any tags? */ /* If the address represents a sub-anchor, we recursively load its parent, then we create a child anchor within that document. */ if (*tag) { char *addr = HTParse(address, "", PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION); HTParentAnchor * parent = (HTParentAnchor*) HTAnchor_findAddress(addr); HTChildAnchor * child = HTAnchor_findChild(parent, tag); HT_FREE(addr); HT_FREE(tag); return (HTAnchor *) child; } else { /* Else check whether we have this node */ int hash; const char *p; HTList * adults; HTList *grownups; HTParentAnchor * foundAnchor; char *newaddr = NULL; StrAllocCopy(newaddr, address); /* Get our own copy */ HT_FREE(tag); newaddr = HTSimplify(&newaddr); /* Select list from hash table */ for(p=newaddr, hash=0; *p; p++) hash = (int) ((hash * 3 + (*(unsigned char*)p)) % PARENT_HASH_SIZE); if (!adult_table) { if ((adult_table = (HTList* *) HT_CALLOC(PARENT_HASH_SIZE, sizeof(HTList*))) == NULL) HT_OUTOFMEM("HTAnchor_findAddress"); } if (!adult_table[hash]) adult_table[hash] = HTList_new(); adults = adult_table[hash]; /* Search list for anchor */ grownups = adults; while ((foundAnchor = (HTParentAnchor *) HTList_nextObject(grownups))){ if (!strcmp(foundAnchor->address, newaddr)) { HTTRACE(ANCH_TRACE, "Find Parent. %p with address `%s' already exists.\n" _ (void*) foundAnchor _ newaddr); HT_FREE(newaddr); /* We already have it */ return (HTAnchor *) foundAnchor; } } /* Node not found : create new anchor. */ foundAnchor = HTParentAnchor_new(); foundAnchor->address = newaddr; /* Remember our copy */ HTList_addObject (adults, foundAnchor); HTTRACE(ANCH_TRACE, "Find Parent. %p with hash %d and address `%s' created\n" _ (void*)foundAnchor _ hash _ newaddr); return (HTAnchor *) foundAnchor; } }