⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htndir.c

📁 www工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	HTNewsDir_setWidth**	------------------**	The module automatically ajusts the width of the directory listing as**	a function of the file name. The width can flows dynamically between**	an upper and a lower limit.*/PUBLIC BOOL HTNewsDir_setWidth (int max_width){    MaxLineW = (max_width > 0) ? max_width : DEFAULT_MAXW;    return YES;}/*	HTNewsDir_new**	----------**    	Creates a structured stream object and sets up the initial HTML stuff**	Returns the newsdir object if OK, else NULL*/PUBLIC HTNewsDir * HTNewsDir_new (HTRequest * request, const char * title,				  HTNewsDirKey key, BOOL cache){    HTNewsDir *dir;    if (!request) return NULL;    /* Create object */    if ((dir = (HTNewsDir *) HT_CALLOC(1, sizeof (HTNewsDir))) == NULL)        HT_OUTOFMEM("HTNewsDir_new");    dir->target = HTMLGenerator(request, NULL, WWW_HTML,				HTRequest_outputFormat(request),				HTRequest_outputStream(request));    HTAnchor_setFormat(HTRequest_anchor(request), WWW_HTML);    dir->request = request;    dir->key = key;    dir->lastLevel = -1;  /* Added by MP. */    /*  Get the newsgroup(s) name; added by MP. */    {        char* url = HTAnchor_physical(HTRequest_anchor(request));        char* p = url+strlen(url);        while (p > url && p[-1] != ':' && p[-1] != '/' && p[-1] != '\\')            p--;        StrAllocCopy (dir->name, p);    }    if (key != HT_NDK_NONE) {			       /* Thread is unsorted */	int total = HTNews_maxArticles();	dir->array = HTArray_new(total > 0 ? total : 128);    }    /* If we are asked to prepare a cache entry then create the cache array */    if (cache) {	int total = HTNews_maxArticles();	dir->cache = HTArray_new(total > 0 ? total : 128);    }    /* Start the HTML stuff */    {	HTStructured *target = dir->target;	const char *msg = title ? title : "News Listing";	START(HTML_HTML);	START(HTML_HEAD);	START(HTML_TITLE);	PUTS(msg);	END(HTML_TITLE);	END(HTML_HEAD);	START(HTML_BODY);	START(HTML_H1);	PUTS(msg);	END(HTML_H1);    }    return dir;}/*	HTNewsDir_addElement**	--------------------**    	This function accepts a news line. Everything except dir and name can**	can be 0 or NULL.**	Returns new node pointer if OK, else NULL**	Changed by MP: reference list added.**	Note: Unlike other parameters, refNames is not copied, but assigned, so**	it has to contain copies of message names, not the originals.*/PUBLIC HTNewsNode* HTNewsDir_addElement (HTNewsDir * dir, int index, 					 char * subject, char * from,					 time_t date, char * name,					 int refs, HTList * refNames){    if (dir && name) {	HTNewsNode * node = HTNewsNode_new(index, subject, from,					   date, name, refs, refNames);	if (dir->key == HT_NDK_NONE) {	    HTNewsNode_print(dir, node);	    HTNewsNode_delete(node, (dir->cache!=NULL));	} else	    HTArray_addObject(dir->array, (void *) node);	return node;    }    return NULL;}/* Helper function - added by MP. */PRIVATE HTNewsNode* HTNewsDir_addFakeElement (HTNewsDir * dir, 					      char * subject, char * name){    HTNewsNode * node =	HTNewsDir_addElement(dir, 0, subject, NULL, 0, name, 0, NULL);    if (node) {	node->show = NO;	node->fake = YES;    }    return node;}/* Helper function - added by MP. */PUBLIC HTNewsNode * HTNewsDir_addGroupElement (HTNewsDir * dir, char * group,					       BOOL tmplate){    HTNewsNode * node = NULL;    if (dir && group) {	if (HTNewsDir_belongsToSet(dir, group))	    node=HTNewsDir_addElement (dir, 0, group, NULL, 0, group, 0, NULL);	/* If we are building a cache object then add the entry */	if (dir->cache && !tmplate) {	    char * name = node ? node->name : NULL;	    if (!name) StrAllocCopy(name, group);	    HTArray_addObject(dir->cache, name);	}    }    return node;}/* Added by MP. */PUBLIC BOOL HTNewsDir_belongsToSet (HTNewsDir* dir, char* group){    char* p;    if (!dir->name || !*(dir->name))        return YES;    p = strrchr(dir->name, '*');    if (!p)        return strcasecomp(group, dir->name) == 0;    else    {        int len = p - dir->name;        return strncasecomp(group, dir->name, len) == 0;    }}/* Added by MP. */PRIVATE void HTNewsDir_addLevelTags (HTNewsDir* dir, int level){    HTStructured *target = dir->target;    int i = level;    while (i > dir->lastLevel)    {        START(HTML_UL);        i--;    }    while (i < dir->lastLevel)    {        END(HTML_UL);        i++;    }    dir->lastLevel = level;}/* Added by MP. */PRIVATE HTNewsNode* HTNewsDir_findNodeNamed (HTNewsDir* dir, char* name){    int i;    for (i = 0; i < HTArray_size(dir->array); i++)    {        HTNewsNode* node = (HTNewsNode*)(HTArray_data(dir->array)[i]);        if (node->name && strcasecomp(node->name, name) == 0)            return node;    }    return NULL;}/* Added by MP. */PRIVATE HTNewsNode* HTNewsDir_findNodeWithSubject (HTNewsDir* dir,     char* subject, int which, HTNewsNode* avoidNode){    int i;    int whichDate = (which & FNWS_MIN ? -1 : (which & FNWS_MAX ? 1 : 0));    HTNewsNode* foundNode = NULL;    for (i = 0; i < HTArray_size(dir->array); i++)    {        HTNewsNode* node = (HTNewsNode*)(HTArray_data(dir->array)[i]);        if (!(which & FNWS_ONLYFAKE && !node->fake) &&             !(which & FNWS_NOTFAKE && node->fake) &&            !(which & FNWS_NOTORPHAN && !node->fake && !node->refNames) &&            node != avoidNode && node->subject &&             strcasecomp(node->subject, subject) == 0)        {            if (which == FNWS_ANY)                return node;            else if (!foundNode || (node->date != 0 &&                 (node->date - foundNode->date) * (long)whichDate > 0))                foundNode = node;        }                      }    return foundNode;}/* Added by MP. */PRIVATE void HTNewsDir_setRefInfo (HTNewsDir* dir){    /* Array grows when fake elements are added.  */    /* We don't want to set reference info for fake elements. */    int size = HTArray_size(dir->array);    int i;    for (i = 0; i < size; i++)        HTNewsNode_setRefInfo_pass1 (dir, (HTNewsNode*)(HTArray_data(dir->array)[i]));    for (i = 0; i < size; i++)        HTNewsNode_setRefInfo_pass2 (dir, (HTNewsNode*)(HTArray_data(dir->array)[i]));    for (i = 0; i < size; i++)        HTNewsNode_setRefInfo_pass3 (dir, (HTNewsNode*)(HTArray_data(dir->array)[i]));}PRIVATE void make_template (HTNewsDir * dir, HTNewsNode * node){    HT_FREE(dir->tmplate);    if ((dir->tmplate = (char *) HT_MALLOC(strlen(node->name) + 3)) == NULL)	HT_OUTOFMEM("HTNewsNode_setGroupInfo");    {	char * p1 = dir->name;	char * p2 = dir->tmplate;	strcpy(p2, node->name);	while (*p1 && *p2 && *p1 == *p2)  p1++, p2++;	while (*p2 && *p2 != '.') p2++;	if (*p2) {	    strcpy(p2, ".*");	    dir->tmplate_node=HTNewsDir_addGroupElement(dir, dir->tmplate,YES);	    dir->tmplate_node->is_tmplate = YES;	} else {	    HT_FREE(dir->tmplate);	    dir->tmplate_node = node;	}	dir->tmplate_node->show = YES;    }}/***	Runs through a sorted list of news groups and identifies the group**	hierarchy. Template groups are added to the list, for example as**	"alt.*"*/PRIVATE void HTNewsDir_setGroupInfo (HTNewsDir * dir){    HTArray * array = dir->array;    HTNewsNode * node;    int cur_size = HTArray_size(array);    int cnt;    /*    ** If we don't have a template to test against then create one    ** A template can be something like "alt.*" for example    */    for (cnt=0; cnt<cur_size; cnt++) {	node = (HTNewsNode *) HTArray_data(array)[cnt];	/*	** Make a template if we don't have any	*/	if (!dir->tmplate) make_template(dir, node);    	/*	** Now, if we do have a template then test the node name against	** it to see if we have this group already or it is a new group	** at this level in the hierarchy	*/	if (dir->tmplate) {	    if (HTStrCaseMatch(dir->tmplate, node->name) == NULL) {		make_template(dir, node);	    } else {		HTNewsNode * tmp_node = dir->tmplate_node;				/* Should we show this element in the list? */		if (tmp_node->lastChild) {		    tmp_node->lastChild->show = NO;		    node->show = NO;		}	    }	    HTNewsNode_linkRef(dir->tmplate_node, node);	}    }}PRIVATE int NDirIndexSort (const void *a, const void *b){    int aa = (*((HTNewsNode **)a))->index;    int bb = (*((HTNewsNode **)b))->index;    return aa-bb;}PRIVATE int NDirSubjectSort (const void *a, const void *b){    char *aa = (*((HTNewsNode **)a))->subject;    char *bb = (*((HTNewsNode **)b))->subject;    return strcasecomp(aa?aa:"", bb?bb:"");}PRIVATE int NDirFromSort (const void *a, const void *b){    char *aa = (*((HTNewsNode **)a))->from;    char *bb = (*((HTNewsNode **)b))->from;    return strcasecomp(aa?aa:"", bb?bb:"");}PRIVATE int NDirDateSort (const void *a, const void *b){    time_t aa = (*((HTNewsNode **)a))->date;    time_t bb = (*((HTNewsNode **)b))->date;    return bb-aa;}PRIVATE int NDirGroupSort (const void *a, const void *b){    char *aa = (*((HTNewsNode **)a))->name;    char *bb = (*((HTNewsNode **)b))->name;    while (*aa && *bb && TOLOWER(*aa)==TOLOWER(*bb)) aa++, bb++;    return (*aa=='.' && *bb) ? -1 : (*aa && *bb=='.') ?	1 : TOLOWER(*aa)-TOLOWER(*bb);}/* Added by MP. */PRIVATE int NDirRefThreadSort (const void* a, const void* b){    HTNewsNode* aa = *((HTNewsNode**)a);    HTNewsNode* bb = *((HTNewsNode**)b);    return HTNewsNode_compareRefThread(aa,bb);}/*	HTNewsDir_free**	--------------**    	If we are sorting then do the sorting and put out the list,**	else just append the end of the list.*/PUBLIC BOOL HTNewsDir_free (HTNewsDir * dir){    if (!dir) return NO;    if (dir->key != HT_NDK_NONE) {    	HTArray * array = dir->array;	HTArray * cache = NULL;    	HTComparer * comp = NULL;	/*	** Find a suitable sort key for this listing. The sort function	** depends on the type of new listing we have received.	*/    	if (dir->key == HT_NDK_INDEX)	           /* Sort by Message Number */    	    comp = NDirIndexSort;    	else if (dir->key == HT_NDK_DATE)	             /* Sort by Date */    	    comp = NDirDateSort;    	else if (dir->key == HT_NDK_SUBJECT)           /* Sort after Subject */    	    comp = NDirSubjectSort;             	else if (dir->key == HT_NDK_FROM)		  /* Sort after From */    	    comp = NDirFromSort;    	else if (dir->key == HT_NDK_GROUP) {	  /* Sort as group hierarchi */	    comp = NDirGroupSort;        } else if (dir->key == HT_NDK_REFTHREAD) {    /* Added by MP. */            HTNewsDir_setRefInfo (dir);            comp = NDirRefThreadSort;        } else {    	    HTTRACE(STREAM_TRACE, "NewsListing. Invalid sortkey\n");    	    return NO;    	}	/*	** Now sort the array of news items that we have read with the sort	** function defined by the sort key above.	*/    	HTArray_sort(array, comp);	/*	** If we are showing a group listing then run through the list and	** identify group hierarchy. We have to sort the thing again in order	** to get the new template groups included	*/	if (dir->key == HT_NDK_GROUP) {	    HTNewsDir_setGroupInfo(dir);	    HTArray_sort(array, comp);	}		/*	** After we have sorted the listing, we can write out the result and	** free the array.	*/    	{    	    void ** data;    	    HTNewsNode *node = (HTNewsNode *) HTArray_firstObject(array, data);    	    while (node) {		HTNewsNode_print(dir, node);		/*		** Create a special array for the cache containing the group		** names only and no templates		*/		if (dir->key == HT_NDK_GROUP && !node->is_tmplate)		    HTArray_addObject(cache, node->name);		HTNewsNode_delete(node, (dir->cache!=NULL));		node = (HTNewsNode *) HTArray_nextObject(array, data);    	    }	    HTArray_delete(array);		}	/* Update the cache */	if (dir->cache) HTNewsCache_after(dir->request, NULL, dir->cache, 0);    }    /* Put out the end of the HTML stuff */    {	HTStructured *target = dir->target;	/* END(HTML_UL); */        HTNewsDir_addLevelTags (dir, -1);	START(HTML_HR);	END(HTML_BODY);	END(HTML_HTML);	FREE_TARGET;    }    /* Clean up the dir object */    HT_FREE(dir->name);    HT_FREE(dir->tmplate);    HT_FREE(dir);    return YES;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -