Пример #1
0
/*	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;
}
Пример #2
0
/*	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;
}
Пример #3
0
PUBLIC HTArray * HTHashtable_keys (HTHashtable *me)
{
    if(me) {
	HTArray *keys = HTArray_new(me->count);
	int i;
    
	for(i = 0; i< me->size; i++) {
	    HTList * l = (HTList *)me->table[i];
	    if (l) {
		HTList *cur = l;
		keynode *kn;
		while ((kn = (keynode *) HTList_nextObject(cur))) {
		    char * nkey = NULL;
		    StrAllocCopy(nkey,kn->key);
		    HTArray_addObject(keys,nkey);
		}
	    }
	}
	return keys;
    }
    return NULL;
}
Пример #4
0
/* PRIVATE						multi_match()
**
**	Check if actual filename (split in parts) fulfills
**	the requirements.
*/
PRIVATE BOOL multi_match (char ** required, int m, char ** actual, int n)
{
    int c;
    int i,j;

#ifdef VMS
    for(c=0;  c<m && c<n && !strcasecomp(required[c], actual[c]);  c++);
#else /* not VMS */
    for(c=0;  c<m && c<n && !strcmp(required[c], actual[c]);  c++);
#endif /* not VMS */

    if (!c) return NO;		/* Names differ rigth from start */

    for(i=c; i<m; i++) {
	BOOL found = NO;
	for(j=c; j<n; j++) {
#ifdef VMS
	    if (!strcasecomp(required[i], actual[j])) {
#else /* not VMS */
	    if (!strcmp(required[i], actual[j])) {
#endif /* not VMS */
		found = YES;
		break;
	    }
	}
	if (!found) return NO;
    }
    return YES;
}


/*
**	Get multi-match possibilities for a given file
**	----------------------------------------------
** On entry:
**	path	absolute path to one file in a directory,
**		may end in .multi.
** On exit:
**	returns	a list of ContentDesription structures
**		describing the mathing files.
**
*/
PRIVATE HTArray * dir_matches (char * path)
{
    static char * required[MAX_SUFF+1];
    static char * actual[MAX_SUFF+1];
    int m,n;
    char * dirname = NULL;
    char * basename = NULL;
    int baselen;
    char * multi = NULL;
    DIR * dp;
    struct dirent * dirbuf;
    HTArray * matches = NULL;
#ifdef HT_REENTRANT
    struct dirent result;				         /* For readdir_r */
#endif

    if (!path) return NULL;

    StrAllocCopy(dirname, path);
    basename = (strrchr(dirname, '/'));
    if (!basename)
	goto dir_match_failed;
    *basename++ = 0;

    multi = strrchr(basename, MULTI_SUFFIX[0]);
    if (multi && !strcasecomp(multi, MULTI_SUFFIX))
	*multi = 0;
    baselen = strlen(basename);

    m = HTSplitFilename(basename, required);

    dp = opendir(dirname);
    if (!dp) {
	HTTRACE(PROT_TRACE, "Warning..... Can't open directory %s\n" _ dirname);
	goto dir_match_failed;
    }

    matches = HTArray_new(VARIANTS);
#ifdef HAVE_READDIR_R_2
	while ((dirbuf = (struct dirent *) readdir_r(dp, &result))) {
#elif defined(HAVE_READDIR_R_3)
        while (readdir_r(dp, &result, &dirbuf) == 0) {
#else
	while ((dirbuf = readdir(dp))) {
#endif /* HAVE_READDIR_R_2 */
	if (!dirbuf->d_ino) continue;	/* Not in use */
	if (!strcmp(dirbuf->d_name,".") ||
	    !strcmp(dirbuf->d_name,"..") ||
	    !strcmp(dirbuf->d_name, DEFAULT_DIR_FILE))
	    continue;

	/* Use of direct->namlen is only valid in BSD'ish system */
	/* Thanks to [email protected] (Chip Rosenthal) */
	/* if ((int)(dirbuf->d_namlen) >= baselen) { */
	if ((int) strlen(dirbuf->d_name) >= baselen) {
	    n = HTSplitFilename(dirbuf->d_name, actual);
	    if (multi_match(required, m, actual, n)) {
		HTContentDescription * cd;
		if ((cd = (HTContentDescription  *)
		     HT_CALLOC(1, sizeof(HTContentDescription))) == NULL)
		    HT_OUTOFMEM("dir_matches");
		if (HTBind_getFormat(dirbuf->d_name,
				     &cd->content_type,
				     &cd->content_encoding,
				     &cd->content_transfer,
				     &cd->content_language,
				     &cd->quality)) {
		    if (cd->content_type) {
			if ((cd->filename = (char *) HT_MALLOC(strlen(dirname) + 2 + strlen(dirbuf->d_name))) == NULL)
			    HT_OUTOFMEM("dir_matches");
			sprintf(cd->filename, "%s/%s", dirname, dirbuf->d_name);
			HTArray_addObject(matches, (void *) cd);
		    } else {
			HT_FREE(cd);
		    }
		} else {
		    HT_FREE(cd);
		}
	    }
	}
    }
    closedir(dp);

  dir_match_failed:
    HT_FREE(dirname);
    return matches;
}


/*
**	Get the best match for a given file
**	-----------------------------------
** On entry:
**	req->conversions  accepted content-types
**	req->encodings	  accepted content-transfer-encodings
**	req->languages	  accepted content-languages
**	path		  absolute pathname of the filename for
**			  which the match is desired.
** On exit:
**	returns	a newly allocated absolute filepath.
*/
PRIVATE char * HTGetBest (HTRequest * req, char * path)
{
    HTArray * variants = NULL;
    char * representation = NULL;

    if (!path || !*path) return NULL;

    if ((variants = dir_matches(path)) == NULL) {
	HTTRACE(PROT_TRACE, "No matches.. for \"%s\"\n" _ path);
	return NULL;
    }

#ifdef HTDEBUG
    if (PROT_TRACE) {
	void ** data;
	HTContentDescription * cd = HTArray_firstObject(variants, data);
	HTTRACE(PROT_TRACE, "Multi....... Possibilities for \"%s\"\n" _ path);
	HTTRACE(PROT_TRACE, "     QUALITY CONTENT-TYPE         LANGUAGE ENCODING  FILE\n");
	while (cd) {
	    HTTRACE(PROT_TRACE, "     %.4f  %-20.20s %-8.8s %-10.10s %s\n" _
		    cd->quality _
		    cd->content_type    ?HTAtom_name(cd->content_type)  :"-\t" _
		    cd->content_language?HTAtom_name(cd->content_language):"-" _
		    cd->content_encoding?HTAtom_name(cd->content_encoding):"-" _
		    cd->filename        ?cd->filename                    :"-");
	    cd = (HTContentDescription *) HTArray_nextObject(variants, data);
	}
    }
#endif /* HTDEBUG */

    /*
    ** Finally get the best variant which is readable
    */
    if (HTRank(req, variants)) {
	void ** data;
	HTContentDescription * cd = HTArray_firstObject(variants, data);
	while (cd) {
	    if (cd->filename) {
		if (access(cd->filename, R_OK) != -1)
		    StrAllocCopy(representation, cd->filename);
		else HTTRACE(PROT_TRACE, "Multi....... `%s\' is not readable\n" _ 
			    cd->filename);
	    }
	    HT_FREE(cd->filename);
	    HT_FREE(cd);
	    cd = (HTContentDescription *) HTArray_nextObject(variants, data);
	}
    }
    HTArray_delete(variants);
    return representation;
}



PRIVATE int welcome_value (char * name)
{
    HTList * cur = welcome_names;
    char * welcome;
    int v = 0;

    while ((welcome = (char*)HTList_nextObject(cur))) {
	v++;
	if (!strcmp(welcome,name)) return v;
    }
    return 0;
}



PRIVATE char * get_best_welcome (char * path)
{
    char * best_welcome = NULL;
    int best_value = 0;
    DIR * dp;
    struct dirent * dirbuf;
    char * last = strrchr(path, '/');

    if (!welcome_names) {
	HTAddWelcome("Welcome.html");
	HTAddWelcome("welcome.html");
#if 0
	HTAddWelcome("Index.html");
#endif
	HTAddWelcome("index.html");
    }

    if (last && last!=path) *last = 0;
    dp = opendir(path);
    if (last && last!=path) *last='/';
    if (!dp) {
	HTTRACE(PROT_TRACE, "Warning..... Can't open directory %s\n" _ path);
	return NULL;
    }
    while ((dirbuf = readdir(dp))) {
	if (!dirbuf->d_ino ||
	    !strcmp(dirbuf->d_name,".") ||
	    !strcmp(dirbuf->d_name,"..") ||
	    !strcmp(dirbuf->d_name, DEFAULT_DIR_FILE))
	    continue;
	else {
	    int v = welcome_value(dirbuf->d_name);
	    if (v > best_value) {
		best_value = v;
		StrAllocCopy(best_welcome, dirbuf->d_name);
	    }
	}
    }
    closedir(dp);

    if (best_welcome) {
	char * welcome;
	if ((welcome = (char *) HT_MALLOC(strlen(path) + strlen(best_welcome)+2)) == NULL)
	    HT_OUTOFMEM("get_best_welcome");
	sprintf(welcome, "%s%s%s", path, last ? "" : "/", best_welcome);
	HT_FREE(best_welcome);
	HTTRACE(PROT_TRACE, "Welcome..... \"%s\"\n" _ welcome);
	return welcome;
    }
    return NULL;
}
Пример #5
0
/*	HTDir_new
**	---------
**    	Creates a structured stream object and sets up the initial HTML stuff
**	Returns the dir object if OK, else NULL
*/
PUBLIC HTDir * HTDir_new (HTRequest * request, HTDirShow show, HTDirKey key)
{    
    HTDir *dir;
    char *title = NULL;
    if (!request) return NULL;

    /* Create object */
    if ((dir = (HTDir *) HT_CALLOC(1, sizeof (HTDir))) == NULL ||
	(dir->fnbuf = (char *) HT_MALLOC(MaxFileW+HT_DLEN_SPACE)) == NULL)
	HT_OUTOFMEM("HTDir_new");
    dir->target = HTMLGenerator(request, NULL, WWW_HTML,
			       HTRequest_outputFormat(request),
			       HTRequest_outputStream(request));
    HTRequest_setOutputConnected(request, YES);
    HTAnchor_setFormat(HTRequest_anchor(request), WWW_HTML);
    dir->request = request;
    dir->show = show;
    dir->key = key;
    if (key==HT_DK_NONE)
	dir->curfw = MaxFileW;
    else {
	dir->curfw = MinFileW;
	dir->array = HTArray_new(256);
    }

    /* We're all OK */
    HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0, "HTDir_new");

    /* Find the length of the fields */
    {
	int len = HT_DLEN_SPACE+1;
	if (show & HT_DS_SIZE) len += (HT_DLEN_SIZE+HT_DLEN_SPACE);
	if (show & HT_DS_DATE) len += (HT_DLEN_DATE+HT_DLEN_SPACE);
	if (show & HT_DS_DES) len += HT_DLEN_DES;
	if ((dir->lnbuf = (char *) HT_MALLOC(len)) == NULL)
	    HT_OUTOFMEM("HTDir_new");
    }

    /* Find the title and the base URL */
    {
	char *addr = HTAnchor_address((HTAnchor *) HTRequest_anchor(request));
	char *path = HTParse(addr, "", PARSE_PATH+PARSE_PUNCTUATION);
	char *ptr;
	if ((ptr = strchr(path, ';')) || (ptr = strchr(path, '?')))
	    *ptr = '\0';
	StrAllocCopy(title, path);
	HTUnEscape(title);				 	    /* Title */
	if((ptr=strrchr(path, '/')) && (ptr<path+strlen(path)-1 || ptr==path)){
	    StrAllocCopy(dir->base, ++ptr);
	    StrAllocCat(dir->base, "/");
	}
	HTTRACE(PROT_TRACE, "HTDir_new... base is `%s\'\n" _ dir->base ? dir->base : "");
	HT_FREE(addr);
	HT_FREE(path);
    }

    /* Start the HTML stuff */
    {
	HTStructured *target = dir->target;
	START(HTML_HTML);
	START(HTML_HEAD);
	START(HTML_TITLE);
	PUTS("Current index is ");
	PUTS(title);
	END(HTML_TITLE);
	END(HTML_HEAD);
	START(HTML_BODY);
	START(HTML_H1);
	PUTS("Index of ");
	PUTS(title);
	END(HTML_H1);
    }
    HT_FREE(title);
    return dir;
}