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

📄 htmulti.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
📖 第 1 页 / 共 2 页
字号:
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 chip@chinacat.unicom.com (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;}#endif /* HAVE_READDIR *//***	Do multiformat handling**	-----------------------** 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.**	stat_info	  pointer to result space.**** On exit:**	returns	a newly allocated absolute filepath of the best**		match, or NULL if no match.**	stat_info	  will contain inode information as**			  returned by stat().*/PUBLIC char * HTMulti (HTRequest *	req,		       char *		path,		       struct stat *	stat_info){    char * new_path = NULL;    int stat_status = -1;    if (!req || !path || !*path || !stat_info)	return NULL;#ifdef HAVE_READDIR    if (*(path+strlen(path)-1) == '/') {	/* Find welcome page */	new_path = get_best_welcome(path);	if (new_path) path = new_path;    } else{	char * multi = strrchr(path, MULTI_SUFFIX[0]);	if (multi && !strcasecomp(multi, MULTI_SUFFIX)) {	    HTTRACE(PROT_TRACE, "Multi....... by %s suffix\n" _ MULTI_SUFFIX);	    if (!(new_path = HTGetBest(req, path))) {		HTTRACE(PROT_TRACE, "Multi....... failed -- giving up\n");		return NULL;	    }	    path = new_path;	} else {	    stat_status = HT_STAT(path, stat_info);	    if (stat_status == -1) {		HTTRACE(PROT_TRACE, "AutoMulti... can't stat \"%s\"(errno %d)\n" _ 			    path _ errno);		if (!(new_path = HTGetBest(req, path))) {		    HTTRACE(PROT_TRACE, "AutoMulti... failed -- giving up\n");		    return NULL;		}		path = new_path;	    }	}    }#endif /* HAVE_READDIR */    if (stat_status == -1)	stat_status = HT_STAT(path, stat_info);    if (stat_status == -1) {	HTTRACE(PROT_TRACE, "Stat fails.. on \"%s\" -- giving up (errno %d)\n" _ 		    path _ errno);	return NULL;    } else {	if (!new_path) {	    StrAllocCopy(new_path, path);	    return new_path;	}	else return path;    }}

⌨️ 快捷键说明

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