PUBLIC int HTTimer_next (ms_t * pSoonest) { HTList * cur = Timers; HTList * last = Timers; HTTimer * pres; ms_t now = HTGetTimeInMillis(); int ret = HT_OK; /* ** Dispatch all timers that have expired */ while (Timers && (pres = (HTTimer *) HTList_nextObject(cur))) { if (pres->expires <= now) { if ((ret = Timer_dispatch(cur, last)) != HT_OK) break; cur = last = Timers; } else { last = cur; } } if (pSoonest) { /* ** First element in Timers is the next to expire. */ HTList * cur = Timers; /* for now */ pres = (HTTimer *) HTList_nextObject(cur); *pSoonest = pres ? pres->expires - now : 0; } return ret; }
PUBLIC BOOL HTHashtable_walk (HTHashtable *me, int (*walkFunc)(HTHashtable *,char *, void *)) { if(me) { int i, j; for(i = 0; i< me->size; i++) { HTList *l = (HTList *)me->table[i]; if(l) { HTList *cur = l; keynode *kn, *nextkn; for(kn = (keynode *)HTList_nextObject(cur); kn; kn = nextkn) { j = walkFunc(me, kn->key, kn->object); if(j == 0) return YES; nextkn = (keynode *)HTList_nextObject(cur); if (j < 0) { HTList_removeObject(l, kn); me->count--; } } } } return YES; } return NO; }
PRIVATE void print_item ARGS1(Item *, item) { if (!item) fprintf(tfp, "\tNULL-ITEM\n"); else { UserDefList *cur1 = item->user_def_list; AddressDefList *cur2 = item->address_def_list; Ref *user_ref = (Ref*)HTList_nextObject(cur1); Ref *addr_ref = (Ref*)HTList_nextObject(cur2); if (user_ref) { fprintf(tfp, "\t[%s%s", user_ref->name, (user_ref->translation ? "*REF*" : "")); while (NULL != (user_ref = (Ref*)HTList_nextObject(cur1))) fprintf(tfp, "; %s%s", user_ref->name, (user_ref->translation ? "*REF*" : "")); fprintf(tfp, "] "); } else fprintf(tfp, "\tANYBODY "); if (addr_ref) { fprintf(tfp, "@ [%s", addr_ref->name); while (NULL != (addr_ref = (Ref*)HTList_nextObject(cur2))) fprintf(tfp, "; %s", addr_ref->name); fprintf(tfp, "]\n"); } else fprintf(tfp, "@ ANYADDRESS\n"); } }
/* JK: used by Amaya */ PUBLIC BOOL HTTimer_expireAll (void) { HTList * cur; HTTimer * timer; if (Timers) { /* ** first delete all plattform specific timers to ** avoid having a concurrent callback */ cur = Timers; while ((timer = (HTTimer *) HTList_nextObject(cur))) { if (DeletePlatformTimer) DeletePlatformTimer(timer); } /* ** simulate a timer timeout thru timer_dispatch ** to kill its context */ cur = Timers; while ((timer = (HTTimer *) HTList_nextObject(cur))) { /* avoid having it being refreshed */ timer->repetitive = NO; HTTimer_dispatch (timer); /* as the timer is erased, we start again from the top of the list */ cur = Timers; } return YES; } return NO; }
/* Determine a suitable suffix ** --------------------------- ** Use the set of bindings to find a suitable suffix (or index) ** for a certain combination of language, media type and encoding ** given in the anchor. ** ** Returns a pointer to a suitable suffix string that must be freed ** by the caller. If more than one suffix is found they are all ** concatenated using the first delimiter in HTDelimiters. ** If no suffix is found, NULL is returned. */ PUBLIC char * HTBind_getSuffix (HTParentAnchor * anchor) { int cnt; HTList * cur; HTChunk * suffix = HTChunk_new(48); char delimiter = *HTDelimiters; char * ct=NULL, * ce=NULL, * cl=NULL; HTFormat format = HTAnchor_format(anchor); HTList * encoding = HTAnchor_encoding(anchor); HTList * language = HTAnchor_language(anchor); if (!HTBindings) HTBind_init(); if (anchor) { for (cnt=0; cnt<HT_L_HASH_SIZE; cnt++) { if ((cur = HTBindings[cnt])) { HTBind *pres; while ((pres = (HTBind *) HTList_nextObject(cur))) { if (!ct && (pres->type && pres->type == format)){ ct = pres->suffix; } else if (!ce && pres->encoding && encoding) { HTList * cur_enc = encoding; HTEncoding pres_enc; while ((pres_enc = (HTEncoding) HTList_nextObject(cur_enc))) { if (pres_enc == pres->encoding) { ce = pres->suffix; break; } } } else if (!cl && pres->language && language) { HTList * cur_lang = language; HTLanguage pres_lang; while ((pres_lang = (HTLanguage) HTList_nextObject(cur_lang))) { if (pres_lang == pres->language) { cl = pres->suffix; break; } } } } } } /* Put the found suffixes together */ if (ct) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, ct); } if (ce) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, ce); } if (cl) { HTChunk_putc(suffix, delimiter); HTChunk_puts(suffix, cl); } } return HTChunk_toCString(suffix); }
/* Added by MP. */ PRIVATE void HTNewsNode_setRefInfo_pass2 (HTNewsDir* dir, HTNewsNode* node) { HTNewsNode* maxParent = NULL; HTList* ptr = node->refObjects; HTNewsNode* parent = NULL; if (node->fake) return; if (ptr != NULL) parent = (HTNewsNode*) HTList_nextObject(ptr); while (ptr != NULL) { if (!maxParent || maxParent->date < parent->date) maxParent = parent; parent = (HTNewsNode*) HTList_nextObject(ptr); } if (maxParent) { if (!HTNewsNode_isAncestor(node, maxParent)) /* better be careful */ HTNewsNode_linkRef (maxParent, node); } else { char* refSubject; BOOL re; /* Here is the only place we REALLY have to check for circular */ /* references. It is normally possible that a node refers to */ /* orphan node and both have the same subject. In this situation */ /* we can't make the orphan to refer to it's child. Without checking */ /* for circular references this is likely to happen here. */ refSubject = UnReSubject(node->subject); re = (strcasecomp(refSubject, node->subject) != 0); if (re) parent = HTNewsDir_findNodeWithSubject(dir, refSubject, FNWS_MIN | FNWS_NOTFAKE, node); if (!parent || HTNewsNode_isAncestor(node, parent)) parent = HTNewsDir_findNodeWithSubject(dir, refSubject, FNWS_MIN | FNWS_ONLYFAKE, node); if (!parent && re) { parent = HTNewsDir_findNodeWithSubject(dir, node->subject, FNWS_MIN | FNWS_ONLYFAKE, node); } if (!parent) parent = HTNewsDir_addFakeElement (dir, refSubject, NULL); if (parent) { HTNewsNode_linkRef (parent, node); if (parent->refChildren > 1) /* Multi-children fake node visible */ parent->show = YES; } } }
/* ** Unregister all sockets ** N.B. we just remove them for our internal data structures: it is up to the ** application to actually close the socket. */ PUBLIC int HTEventList_unregisterAll (void) { int i; HTTRACE(THD_TRACE, "Unregister.. all sockets\n"); for (i = 0 ; i < HT_M_HASH_SIZE; i++) { HTList * cur = HashTable[i]; SockEvents * pres; while ((pres = (SockEvents *) HTList_nextObject(cur))) { #ifdef WWW_WIN_ASYNC WSAAsyncSelect(pres->s, HTSocketWin, HTwinMsg, 0); #endif /* WWW_WIN_ASYNC */ HT_FREE(pres); } HTList_delete(HashTable[i]); HashTable[i] = NULL; } #ifndef WWW_WIN_ASYNC MaxSock = 0 ; HTTRACE(THD_TRACE, "Event....... New value for MaxSock is %d\n" _ MaxSock); FD_ZERO(FdArray+HTEvent_INDEX(HTEvent_READ)); FD_ZERO(FdArray+HTEvent_INDEX(HTEvent_WRITE)); FD_ZERO(FdArray+HTEvent_INDEX(HTEvent_OOB)); #endif /* !WWW_WIN_ASYNC */ EventOrder_deleteAll(); return 0; }
char *Reference_List (Robot *mr) { HTList *copy = mr->urilist; char *output = NULL; char *number = malloc(sizeof("9999 :")); char *index = malloc(1000); int i = 1; int refs = HText_sourceAnchors(mr->htext); if (refs <= 0) { return("\n\nThere are no references from this document.\n\n"); } else { StrAllocCat(output, "List of references: \n"); sprintf(number, "%d total references\n", mr->count); while ((index = (char *) HTList_nextObject(copy))) { sprintf(number, "[%d] : ", i++); StrAllocCat(output, number); StrAllocCat(output, index); StrAllocCat(output, "\n"); HT_FREE(index); } HTList_delete(copy); return(output); } }
/* Delete a Command Line Object ** ---------------------------- */ PRIVATE BOOL Robot_delete (Robot * me) { if (me) { if (me->urilist) { HTList *cur = me->urilist; char *temp; while ((temp = (char *) HTList_nextObject(cur))) { HT_FREE(temp); } HTList_delete(cur); } if (me->htext) { HText_free(me->htext); } if (me->output && me->output != STDOUT) fclose(me->output); HT_FREE(me->cwd); HT_FREE(me->tv); /* Delete the profile */ #if 0 HTProfile_delete(); #endif HT_FREE(me); return YES; } return NO; }
/* ** Removes link information from one anchor to another. ** Returns YES if OK, else NO */ PUBLIC BOOL HTLink_remove (HTAnchor * source, HTAnchor * destination) { if (!source || !destination) return NO; HTTRACE(ANCH_TRACE, "Link delete. from anchor %p to anchor %p\n" _ (void *) source _ (void *) destination); /* Remove if dest is the main link */ if (source->mainLink.dest == destination) { source->mainLink.dest = NULL; source->mainLink.type = NULL; source->mainLink.method = METHOD_INVALID; source->mainLink.result = HT_LINK_INVALID; return YES; } /* Remove link information for other links */ if (source->links) { HTList *cur = source->links; HTLink *pres; while ((pres = (HTLink *) HTList_nextObject(cur))) { if (pres->dest == destination) { HTList_removeObject(source->links, pres); HT_FREE(pres); return YES; } } } return NO; }
/* FLATTEN ALL ANCHORS ** ------------------- ** Flattens the anchor web structure into an array. ** This is useful for calculating statistics, sorting ** the parent anchors etc. ** ** The caller can indicate the size of the array (total ** number of anchors if known - otherwise 0). ** ** Return an array that must be freed by the caller or ** NULL if no anchors. */ PUBLIC HTArray * HTAnchor_getArray (int growby) { int cnt; HTArray * array = NULL; HTList * cur = NULL; if (!adult_table) return NULL; /* Allocate an array for the anchors */ if (growby <= 0) growby = PARENT_HASH_SIZE; array = HTArray_new(growby); /* Traverse anchor structure */ for (cnt=0; cnt<PARENT_HASH_SIZE; cnt++) { if ((cur = adult_table[cnt])) { HTParentAnchor * pres = NULL; while ((pres = (HTParentAnchor *) HTList_nextObject(cur)) != NULL) { if (HTArray_addObject(array, pres) == NO) { HTTRACE(ANCH_TRACE, "Anchor...... Can't add object %p to array %p\n" _ pres _ array); break; } } } } return array; }
/* Deletes all the memory allocated in a parent anchor and returns any ** hyperdoc object hanging of this anchor */ PRIVATE void * delete_parent (HTParentAnchor * me) { void * doc = me->document; /* Remove link and address information */ if (me->links) { HTList *cur = me->links; HTLink *pres; while ((pres = (HTLink *) HTList_nextObject(cur))) HTLink_delete(pres); HTList_delete(me->links); } /* Remove children */ if (me->children) { int cnt = 0; for (; cnt<CHILD_HASH_SIZE; cnt++) { if (me->children[cnt]) HTList_delete(me->children[cnt]); } HT_FREE(me->children); } HTList_delete (me->sources); HTList_delete (me->variants); HT_FREE(me->physical); HT_FREE(me->address); /* Then remove entity header information (metainformation) */ HTAnchor_clearHeader(me); HT_FREE(me); return doc; }
/* Find the cost of a filter stack ** ------------------------------- ** ** Must return the cost of the same stack which StreamStack would set up. ** ** On entry, ** length The size of the data to be converted */ PUBLIC double HTStackValue (HTList * theseConversions, HTFormat rep_in, HTFormat rep_out, double initial_value, long int length) { int which_list; HTList* conversion[2]; HTTRACE(CORE_TRACE, "StackValue.. Evaluating stream stack for %s worth %.3f to %s\n" _ HTAtom_name(rep_in) _ initial_value _ HTAtom_name(rep_out)); if (rep_out == WWW_SOURCE || rep_out == rep_in) return 0.0; conversion[0] = theseConversions; conversion[1] = HTConversions; for(which_list = 0; which_list<2; which_list++) if (conversion[which_list]) { HTList * cur = conversion[which_list]; HTPresentation * pres; while ((pres = (HTPresentation*)HTList_nextObject(cur))) { if (pres->rep == rep_in && (pres->rep_out == rep_out || HTMIMEMatch(pres->rep_out, rep_out))) { double value = initial_value * pres->quality; if (HTMaxSecs != 0.0) value = value - (length*pres->secs_per_byte + pres->secs) /HTMaxSecs; return value; } } } return NO_VALUE_FOUND; /* Really bad */ }
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; }
/* HTGetIcon() ** returns the icon corresponding to content_type or content_encoding. */ PUBLIC HTIconNode * HTGetIcon ARGS3(mode_t, mode, HTFormat, content_type, HTFormat, content_encoding) { if (!icon_unknown) icon_unknown = icon_blank; if ((mode & S_IFMT) == S_IFREG) { char * ct = content_type ? HTAtom_name(content_type) : NULL; char * ce = content_encoding ? HTAtom_name(content_encoding) : NULL; HTList * cur = icons; HTIconNode * node; while ((node = (HTIconNode*)HTList_nextObject(cur))) { char * slash = strchr(node->type_templ,'/'); if ((ct && slash && match(node->type_templ,ct)) || (ce && !slash && HTAA_templateMatch(node->type_templ,ce))) { return node; } } } else if ((mode & S_IFMT) == S_IFDIR) { return icon_dir ? icon_dir : icon_unknown; } else if ((mode & S_IFMT) == S_IFLNK) { return icon_dir ? icon_dir : icon_unknown; /* @@ */ } return icon_unknown; }
/* ** Returns the icon corresponding to content_type or content_encoding. ** If no match is found then use "unknown icon" */ PUBLIC HTIconNode * HTIcon_find (HTFileMode mode, HTFormat content_type, HTEncoding content_encoding) { if (!icon_unknown) icon_unknown = icon_blank; if (mode == HT_IS_FILE) { const char * ct = content_type ? HTAtom_name(content_type) : NULL; const char * ce = content_encoding ? HTAtom_name(content_encoding) : NULL; HTList * cur = icons; HTIconNode * node; while ((node = (HTIconNode*)HTList_nextObject(cur))) { char * slash = strchr(node->type_templ,'/'); if ((ct && slash && match(node->type_templ,ct)) || (ce && !slash && HTStrMatch(node->type_templ,ce))) { return node; } } } else if (mode == HT_IS_DIR) { return icon_dir ? icon_dir : icon_unknown; } else if (mode == HT_IS_BLANK) { return icon_blank ? icon_blank : icon_unknown; } else if (mode == HT_IS_PARENT) { return icon_parent ? icon_parent : icon_unknown; } return icon_unknown; }
/* * Returns a description string (that must not be HT_FREEd!) * for a file with name name in directory dirname. * Description file contents is in descriptions list. */ PUBLIC char * HTGetDescription (HTList * descriptions, char * dirname, char * filename, HTFormat format) { HTList * cur = descriptions; char * t; if (!dirname || !filename) return NULL; /* * descriptions may well be NULL in which case we may still * want to peek the titles. */ while ((t = (char*)HTList_nextObject(cur))) { char * d = strchr(t,' '); if (!d) continue; *d = 0; #if 0 if (HTAA_templateMatch(t,filename)) { #else if (HTStrMatch(t, filename)) { #endif *d = ' '; return d+1; } *d = ' '; } if (HTPeekTitles && format == WWW_HTML) return HTPeekTitle(dirname, filename); else return NULL; }
/* ** Moves all link information from one anchor to another. ** This is used in redirection etc. ** Returns YES if OK, else NO */ PUBLIC BOOL HTLink_moveAll (HTAnchor * src, HTAnchor * dest) { if (!src || !dest) return NO; HTTRACE(ANCH_TRACE, "Link move... all from anchor %p to anchor %p\n" _ (void *) src _ (void *) dest); /* Move main link information */ dest->mainLink.dest = src->mainLink.dest; dest->mainLink.type = src->mainLink.type; dest->mainLink.method = src->mainLink.method; dest->mainLink.result = src->mainLink.result; src->mainLink.dest = NULL; src->mainLink.type = NULL; src->mainLink.method = METHOD_INVALID; src->mainLink.result = HT_LINK_INVALID; /* Move link information for other links */ if (dest->links) { HTList *cur = dest->links; HTLink *pres; while ((pres = (HTLink *) HTList_nextObject(cur))) HT_FREE(pres); HTList_delete(dest->links); } dest->links = src->links; src->links = NULL; return YES; }
/* Delete a parent anchor and all its children. If a hyperdoc object ** is found hanging off the parent anchor then this is returned */ PRIVATE void * delete_family (HTAnchor * me) { HTParentAnchor * parent = NULL; if (!me) { HTTRACE(ANCH_TRACE, "AnchorDelete No anchor found\n"); return NULL; } parent = me->parent; HTTRACE(ANCH_TRACE, "AnchorDelete Remove parent %p and children\n" _ parent); /* Delete children */ if (parent->children) { int cnt = 0; for (; cnt<CHILD_HASH_SIZE; cnt++) { HTList * kids = parent->children[cnt]; if (kids) { HTChildAnchor * child; while ((child=(HTChildAnchor*)HTList_removeLastObject(kids))) { HT_FREE(child->tag); if (child->links) { HTList * cur = child->links; HTLink * pres; while ((pres = (HTLink *) HTList_nextObject(cur))) HTLink_delete(pres); HTList_delete(child->links); } HT_FREE(child); } HTList_delete(kids); parent->children[cnt] = NULL; } } } return delete_parent(parent); }
/* ServerCleanup ** ------------- ** This function cleans up after the request ** Returns YES on OK, else NO */ PRIVATE int ServerCleanup (HTRequest * req, HTNet * net, int status) { https_info * http = (https_info *) HTNet_context(net); HTStream * input = HTRequest_inputStream(req); HTChannel * channel = HTNet_channel(net); /* Free stream with data TO network */ if (input) { if (status == HT_INTERRUPTED) (*input->isa->abort)(input, NULL); else (*input->isa->_free)(input); HTRequest_setInputStream(req, NULL); } /* Kill all remaining requests */ if (http->clients) { HTList * cur = http->clients; HTRequest * pres; while ((pres = HTList_nextObject(cur)) != NULL) HTRequest_kill(pres); HTList_delete(http->clients); } /* ** Remove the net object and our own context structure for http. ** Also unregister all pending requests and close the connection */ HTChannel_setSemaphore(channel, 0); HTNet_delete(net, HT_IGNORE); HT_FREE(http); return YES; }
/* HTErrorIgnore ** ** Turns on the `ignore' flag for the error with the current handle in ** the error list. If the list is empty, nothing is done. */ PUBLIC void HTErrorIgnore ARGS2(HTRequest *, request, int, handle) { BOOL found = NO; HTList *cur; HTErrorInfo *pres; if (!request) { if (TRACE) fprintf(stderr, "HTErrorIgnore Bad argument!\n"); return; } cur = request->error_stack; while ((pres = (HTErrorInfo *) HTList_nextObject(cur))) { if (pres->handle == handle) { pres->ignore = YES; found = YES; break; } } if (TRACE) { if (found) { fprintf(stderr, "Error Ignore Handle: %d\tCode: %3d\tMessage: `%s\tSeverity: %d\tParameter: `%s\'\tWhere: `%s\'\n", pres->handle, error_info[pres->element].code, error_info[pres->element].msg, pres->severity, pres->par ? (char *) pres->par : "Unspecified", pres->where ? pres->where : "Unspecified"); } else { fprintf(stderr, "Error Ignore Bad handle\n"); } } return; }
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; }
/* ** A simple debug function that dumps all the socket arrays ** as trace messages */ PRIVATE void EventList_dump (void) { int v = 0; HTList* cur; SockEvents * pres; HTTRACE(ALL_TRACE, "Event....... Dumping socket events\n"); HTTRACE(ALL_TRACE, "soc "); Event_traceHead(); HTTRACE(ALL_TRACE, " "); Timer_traceHead(); HTTRACE(ALL_TRACE, "\n"); for (v = 0; v < HT_M_HASH_SIZE; v++) { cur = HashTable[v]; while ((pres = (SockEvents *) HTList_nextObject(cur))) { int i; HTTRACE(ALL_TRACE, "%3d \n" _ pres->s); for (i = 0; i < HTEvent_TYPES; i++) if (pres->events[i]) { static char * names[HTEvent_TYPES] = {"read", "writ", "xcpt"}; HTTRACE(ALL_TRACE, "%s " _ names[i]); Event_trace(pres->events[i]); HTTRACE(ALL_TRACE, " "); Timer_trace(pres->timeouts[i]); HTTRACE(ALL_TRACE, " "); } HTTRACE(ALL_TRACE, "\n"); } } }
PRIVATE void print_group_def_list ARGS1(GroupDefList *, group_list) { GroupDefList *cur = group_list; GroupDef *group_def; while (NULL != (group_def = (GroupDef*)HTList_nextObject(cur))) HTAA_printGroupDef(group_def); }
PRIVATE void CheckTimers(void) { HTList * cur = Timers; HTTimer * pres; while ((pres = (HTTimer *) HTList_nextObject(cur))) { CheckSockEvent(pres, pres->cbf, pres->param); } }
PUBLIC void HTAA_resolveGroupReferences ARGS2(GroupDef *, group_def, GroupDefList *, group_def_list) { if (group_def && group_def->item_list && group_def_list) { ItemList *cur1 = group_def->item_list; Item *item; while (NULL != (item = (Item*)HTList_nextObject(cur1))) { UserDefList *cur2 = item->user_def_list; Ref *ref; while (NULL != (ref = (Ref*)HTList_nextObject(cur2))) ref->translation = find_group_def(group_def_list, ref->name); /* Does NOT translate address_def_list */ } } }
/* ** Existing entries are replaced with new ones */ PRIVATE BOOL add_object (HTList * list, const char * access, const char * url, BOOL regex, int regex_flags) { HTProxy *me; if (!list || !access || !url || !*url) return NO; if ((me = (HTProxy *) HT_CALLOC(1, sizeof(HTProxy))) == NULL) HT_OUTOFMEM("add_object"); StrAllocCopy(me->access, access); /* Access method */ #ifdef HT_POSIX_REGEX /* ** If we support regular expressions then compile one up for ** this regular expression. Otherwise use is as a normal ** access scheme. */ if (regex) { me->regex = get_regex_t(access, regex_flags < 0 ? W3C_DEFAULT_REGEX_FLAGS : regex_flags); } else #endif { char *ptr = me->access; while ((*ptr = TOLOWER(*ptr))) ptr++; } me->url = HTParse(url, "", PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION); if (*(me->url+strlen(me->url)-1) != '/') StrAllocCat(me->url, "/"); me->url = HTSimplify(&me->url); /* See if we already have this one */ { HTList *cur = list; HTProxy *pres; while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) { if (!strcmp(pres->access, me->access)) break; /* We already have it */ } if (pres) { HTTRACE(PROT_TRACE, "HTProxy..... replacing for `%s\' access %s\n" _ me->url _ me->access); HT_FREE(pres->access); HT_FREE(pres->url); #ifdef HT_POSIX_REGEX if (pres->regex) regfree(pres->regex); #endif HTList_removeObject(list, (void *) pres); HT_FREE(pres); } HTTRACE(PROT_TRACE, "HTProxy..... adding for `%s\' access %s\n" _ me->url _ me->access); HTList_addObject(list, (void *) me); } return YES; }
PRIVATE void print_item_list ARGS1(ItemList *, item_list) { ItemList *cur = item_list; Item *item; if (!item_list) fprintf(tfp, "EMPTY"); else while (NULL != (item = (Item*)HTList_nextObject(cur))) print_item(item); }
PUBLIC char * CSUserList_findURL(char * username) { HTList * cur = UserList; UserListStruct_t * pUser; while ((pUser = (UserListStruct_t *) HTList_nextObject(cur))) { if (!strcasecomp(username, pUser->name)) return pUser->url; } return 0; }
PUBLIC void HTCoding_deleteAll (HTList * list) { if (list) { HTList * cur = list; HTCoding * pres; while ((pres = (HTCoding *) HTList_nextObject(cur))) HT_FREE(pres); HTList_delete(list); } }