Exemplo n.º 1
0
PUBLIC BOOL HTBind_getResponseBindings (HTResponse * response, const char * url)
{
    BOOL status = NO;
    double quality = 1.0;
    if (response) {
	char * path = HTParse(url, "", PARSE_PATH + PARSE_PUNCTUATION);
	char * file;
	char * end;
	if ((end = strchr(path, ';')) || (end = strchr(path, '?')) ||
	    (end = strchr(path, '#')))
	    *end = '\0';
	if ((file = strrchr(path, '/'))) {
	    HTFormat format = NULL;
	    HTEncoding encoding = NULL;
	    HTEncoding transfer = NULL;
	    HTLanguage language = NULL;
 	    HTTRACE(BIND_TRACE, "Response.... Get Bindings for `%s\'\n" _ path);
	    status = HTBind_getFormat(file, &format, &encoding, &transfer,
				      &language, &quality);
	    if (status) {
		HTResponse_setFormat(response, format);
		HTResponse_setContentTransferEncoding(response, transfer);
		HTResponse_addEncoding(response, encoding);
#if 0
		HTResponse_addLanguage(response, language);
#endif
	    }
	}
	HT_FREE(path);
    }
    return status;
}
Exemplo n.º 2
0
/*
**  Use the set of bindings to find the combination of language,
**  media type and encoding of a given object. This information can either be
**  stored in the anchor obejct or in the response object depending on which
**  function is called.
**
**  We comprise here as bindings only can have one language and one encoding.
**  If more than one suffix is found they are all searched. The last suffix
**  has highest priority, the first one lowest. See also HTBind_getFormat()
*/
PUBLIC BOOL HTBind_getAnchorBindings (HTParentAnchor * anchor)
{
    BOOL status = NO;
    double quality=1.0;		  /* @@@ Should we add this into the anchor? */
    if (anchor) {
	char *addr = HTAnchor_address((HTAnchor *) anchor);
	char *path = HTParse(addr, "", PARSE_PATH+PARSE_PUNCTUATION);
	char *file;
	char *end;
	if ((end = strchr(path, ';')) || (end = strchr(path, '?')) ||
	    (end = strchr(path, '#')))
	    *end = '\0';
	if ((file = strrchr(path, '/'))) {
	    HTFormat format = NULL;
	    HTEncoding encoding = NULL;
	    HTEncoding transfer = NULL;
	    HTLanguage language = NULL;
 	    HTTRACE(BIND_TRACE, "Anchor...... Get bindings for `%s\'\n" _ path);
	    status = HTBind_getFormat(file, &format, &encoding, &transfer,
				      &language, &quality);
	    if (status) {
		HTAnchor_setFormat(anchor, format);
		HTAnchor_setContentTransferEncoding(anchor, transfer);

                HTAnchor_deleteEncodingAll(anchor);
                HTAnchor_addEncoding(anchor, encoding);

                HTAnchor_deleteLanguageAll(anchor);
                HTAnchor_addLanguage(anchor, language);
	    }
	}
        HT_FREE(addr);
        HT_FREE(path);
    }
    return status;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/*
**	Output an element in HTML
**	Returns YES if OK, else NO
*/
PRIVATE BOOL HTDirNode_print (HTDir *dir, HTDirNode *node)
{
    char *tp = NULL;
    HTStructured *target = dir->target;
    if (dir->show & HT_DS_ICON) {
	HTFormat format = NULL;
	HTEncoding encoding = NULL;
	double q=1.0;
	HTIconNode * icon;
	if (node->mode == HT_IS_FILE)
	    HTBind_getFormat(node->fname, &format, &encoding, NULL, NULL, &q);
	icon = HTIcon_find(node->mode, format, encoding);

	/* Are we having a hot or a cold icon? */
	if (!(dir->show & HT_DS_HOTI)) {
	    if (icon) {
		char * alt = HTIcon_alternative(icon, YES);
		HTMLPutImg(target, HTIcon_url(icon), alt, NULL);
		HT_FREE(alt);
		PUTC(' ');
	    }
	}

	/* Start the anchor element */
	if (dir->base) {
	    char *escaped = expand_name(node->fname, node->mode);
	    char *full;
	    if ((full = (char *) HT_MALLOC(strlen(escaped)+strlen(dir->base)+1)) == NULL)
		HT_OUTOFMEM("HTDirNode_print");
	    strcpy(full, dir->base);
	    strcat(full, escaped);
	    HTStartAnchor(target, NULL, full);
	    HT_FREE(escaped);
	    HT_FREE(full);
	} else {
	    char *escaped = expand_name(node->fname, node->mode);
	    HTStartAnchor(target, NULL, escaped);
	    HT_FREE(escaped);
	}

	if (dir->show & HT_DS_HOTI) {
	    char * alt = HTIcon_alternative(icon, YES);
	    HTMLPutImg(target, HTIcon_url(icon), alt, NULL);
	    PUTC(' ');
	}
    } else {
	if (dir->base) {
	    char *escaped = expand_name(node->fname, node->mode);
	    char *full;
	    if ((full = (char *) HT_MALLOC(strlen(escaped)+strlen(dir->base)+1)) == NULL)
		HT_OUTOFMEM("HTDirNode_print");
	    strcpy(full, dir->base);
	    strcat(full, escaped);
	    HTStartAnchor(target, NULL, escaped);
	    HT_FREE(escaped);
	    HT_FREE(full);
	} else {
	    char *escaped = HTEscape(node->fname, URL_XPALPHAS);
	    HTStartAnchor(target, NULL, escaped);
	    HT_FREE(escaped);
	}
    }
    
    /* Insert the anchor text and end anchor */
    {
	char *in = node->fname;
	char *out = dir->fnbuf;
	int l = dir->curfw;
	while (l-- > 0 && *in && (*out++ = *in++));
	if (*in)
	    *(out-1) = '>';
	else if (node->mode == HT_IS_DIR) {
	    *out++ = '/';
	    l--;
	}
	*out = '\0';
	PUTS(dir->fnbuf);
	END(HTML_A);
	out = dir->fnbuf;
	while (l-- >= 0) *out++ = ' ';
	LeftStr(&out, " ", HT_DLEN_SPACE);
	*out = '\0';
	PUTS(dir->fnbuf);
    }

    /* Print the rest of it */
    tp = dir->lnbuf;
    if (node->date) {
	RightStr(&tp, node->date, HT_DLEN_DATE);
	LeftStr(&tp, " ", HT_DLEN_SPACE);
    }
    if (node->size) {
	RightStr(&tp, node->size, HT_DLEN_SIZE);
	LeftStr(&tp, " ", HT_DLEN_SPACE);
    }
    if (node->note) {
	LeftStr(&tp, node->note, HT_DLEN_DES);
	LeftStr(&tp, " ", HT_DLEN_SPACE);
    }
    *tp = '\0';
    PUTS(dir->lnbuf);
    PUTC('\n');
    return YES;
}