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

📄 htfile.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
📖 第 1 页 / 共 2 页
字号:
/*								       HTFile.c**	FILE ACCESS****	(c) COPYRIGHT MIT 1995.**	Please first read the full copyright statement in the file COPYRIGH.**	@(#) $Id: HTFile.c,v 1.158 2000/08/10 16:05:39 kahan Exp $****	This is unix-specific code in general, with some VMS bits.**	These are routines for file access used by browsers.**** History:**	   Feb 91	Written Tim Berners-Lee CERN/CN**	   Apr 91	vms-vms access included using DECnet syntax**	26 Jun 92 (JFG) When running over DECnet, suppressed FTP.**			Fixed access bug for relative names on VMS.**	   Sep 93 (MD)  Access to VMS files allows sharing.**	15 Nov 93 (MD)	Moved HTVMSname to HTVMSUTILS.C**	22 Feb 94 (MD)  Excluded two routines if we are not READING directories**	18 May 94 (HF)	Directory stuff removed and stream handling updated,**			error messages introduced etc.**		  HFN	Separated transport**** Bugs:**	FTP: Cannot access VMS files from a unix machine.**      How can we know that the**	target machine runs VMS?*//* Library Includes */#include "wwwsys.h"#include "WWWUtil.h"#include "WWWCore.h"#include "WWWDir.h"#include "WWWTrans.h"#include "HTReqMan.h"#include "HTBind.h"#include "HTMulti.h"#include "HTFile.h"		/* Implemented here *//* Final states have negative value */typedef enum _FileState {    FS_RETRY		= -4,    FS_ERROR		= -3,    FS_NO_DATA		= -2,    FS_GOT_DATA		= -1,    FS_BEGIN		= 0,    FS_PENDING,    FS_DO_CN,    FS_NEED_OPEN_FILE,    FS_NEED_BODY,    FS_PARSE_DIR,    FS_TRY_FTP} FileState;/* This is the context structure for the this module */typedef struct _file_info {    FileState		state;		  /* Current state of the connection */    char *		local;		/* Local representation of file name */    struct stat		stat_info;	      /* Contains actual file chosen */    HTNet *		net;    HTTimer *		timer;} file_info;struct _HTStream {    const HTStreamClass *	isa;};struct _HTInputStream {    const HTInputStreamClass *	isa;};PRIVATE HTDirReadme	dir_readme = HT_DIR_README_TOP;PRIVATE HTDirAccess	dir_access = HT_DIR_OK;PRIVATE HTDirShow	dir_show = HT_DS_SIZE+HT_DS_DATE+HT_DS_DES+HT_DS_ICON;PRIVATE HTDirKey	dir_key = HT_DK_CINS;PRIVATE BOOL		file_suffix_binding = YES;/* ------------------------------------------------------------------------- *//*	Directory Access**	----------------*/PUBLIC BOOL HTFile_setDirAccess (HTDirAccess mode){    dir_access = mode;    return YES;}PUBLIC HTDirAccess HTFile_dirAccess (void){    return dir_access;}/*	Directory Readme**	----------------*/PUBLIC BOOL HTFile_setDirReadme (HTDirReadme mode){    dir_readme = mode;    return YES;}PUBLIC HTDirReadme HTFile_dirReadme (void){    return dir_readme;}/***  Should we find the bindings between file suffixes and media types**  here or not?*/PUBLIC BOOL HTFile_doFileSuffixBinding (BOOL mode){    file_suffix_binding = mode;    return YES;}PUBLIC BOOL HTFile_fileSuffixBinding (void){    return file_suffix_binding;}/*	HTFile_readDir**	--------------**	Reads the directory "path"**	Returns:**		HT_ERROR	Error**		HT_FORBIDDEN	Directory reading not allowed**		HT_LOADED	Successfully read the directory*/PRIVATE int HTFile_readDir (HTRequest * request, file_info *file){#ifdef HAVE_READDIR    DIR * dp;    struct stat file_info;    HTParentAnchor * anchor = HTRequest_anchor(request);    char *url = HTAnchor_physical(anchor);    char fullname[HT_MAX_PATH+1];    char *name;    HTTRACE(PROT_TRACE, "Reading..... directory\n");    if (dir_access == HT_DIR_FORBID) {	HTRequest_addError(request, ERR_FATAL, NO, HTERR_FORBIDDEN,		   NULL, 0, "HTFile_readDir");	return HT_FORBIDDEN;    }        /* Initialize path name for stat() */    if (*(name = (url+strlen(url)-1)) != '/') {	char *newurl = NULL;	StrAllocCopy(newurl, url);	StrAllocCat(newurl, "/");	HT_FREE(file->local);	file->local = HTWWWToLocal(newurl, "", HTRequest_userProfile(request));	HT_FREE(newurl);    }    strcpy(fullname, file->local);    name = fullname+strlen(fullname);		 /* Point to end of fullname */    /* Check if access is enabled */    if (dir_access == HT_DIR_SELECTIVE) {	strcpy(name, DEFAULT_DIR_FILE);	if (HT_STAT(fullname, &file_info)) {	    HTTRACE(PROT_TRACE, "Read dir.... `%s\' not found\n" _ DEFAULT_DIR_FILE);	    HTRequest_addError(request, ERR_FATAL, NO, HTERR_FORBIDDEN,		       NULL, 0, "HTFile_readDir");	    return HT_FORBIDDEN;	}    }    if ((dp = opendir(file->local))) {	struct dirent * dirbuf;	HTDir *dir = HTDir_new(request, dir_show, dir_key);	char datestr[20];	char sizestr[10];	HTFileMode mode;#ifdef HT_REENTRANT	struct dirent result;				    /* For readdir_r */#endif#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 */	{	    /* Current and parent directories are never shown in list */#ifdef HAVE_DIRENT_INO	    if (!dirbuf->d_ino ||		!strcmp(dirbuf->d_name, ".") || !strcmp(dirbuf->d_name, ".."))#else	    if (!strcmp(dirbuf->d_name, ".") || !strcmp(dirbuf->d_name, ".."))#endif		continue;	    /* Make a lstat on the file */	    strcpy(name, dirbuf->d_name);	    if (HT_LSTAT(fullname, &file_info)) {		HTTRACE(PROT_TRACE, "Read dir.... lstat failed: %s\n" _ fullname);		continue;	    }	    /* Convert stat info to fit our setup */	    if (((mode_t) file_info.st_mode & S_IFMT) == S_IFDIR) {#ifdef VMS		char *dot = strstr(name, ".DIR");      /* strip .DIR part... */		if (dot) *dot = '\0';#endif /* VMS */		mode = HT_IS_DIR;		if (dir_show & HT_DS_SIZE) strcpy(sizestr, "-");	    } else {		mode = HT_IS_FILE;		if (dir_show & HT_DS_SIZE)		    HTNumToStr(file_info.st_size, sizestr, 10);	    }	    if (dir_show & HT_DS_DATE)		HTDateDirStr(&file_info.st_mtime, datestr, 20);	    /* Add to the list */	    if (HTDir_addElement(dir, name, datestr, sizestr, mode) != YES)		break;	}	closedir(dp);	HTDir_free(dir);	return HT_LOADED;    } else {	HTRequest_addSystemError(request,  ERR_FATAL, errno, NO, "opendir");	return HT_ERROR;    }#else    return HT_ERROR;	/* needed for WWW_MSWINDOWS */#endif /* HAVE_READDIR */}/*	Determine write access to a file**	--------------------------------**	If stat_info is NULL then the function calls stat() on it's own,**	otherwise it uses the information found in stat_info** On exit,**	return value	YES if file can be accessed and can be written to.**** Bugs:**	1.	No code for non-unix systems.**	2.	Isn't there a quicker way?*/PRIVATE BOOL HTEditable (const char * filename, struct stat * stat_info){#ifdef GETGROUPS_T    int i;    uid_t myUid;    int	ngroups;			/* The number of groups  */    struct stat	fileStatus;    struct stat *fileptr = stat_info ? stat_info : &fileStatus;    GETGROUPS_T groups[NGROUPS];    if (!stat_info) {	if (HT_STAT(filename, &fileStatus))	    return NO;				  /* Can't even access file! */    }    ngroups = getgroups(NGROUPS, groups);	/* Groups to which I belong  */    myUid = geteuid();				/* Get my user identifier */#ifdef HTDEBUG    if (PROT_TRACE) {        int i;	HTTRACE(PROT_TRACE,		"File mode is 0%o, uid=%d, gid=%d. My uid=%d, %d groups (" _		(unsigned int) fileptr->st_mode _		(int) fileptr->st_uid _ (int) fileptr->st_gid _		(int) myUid _ ngroups);	for (i=0; i<ngroups; i++) HTTRACE(PROT_TRACE, " %d" _ (int) groups[i]);	HTTRACE(PROT_TRACE, ")\n");    }#endif /* HTDEBUG */        if (fileptr->st_mode & 0002)		/* I can write anyway? */    	return YES;	    if ((fileptr->st_mode & 0200)		/* I can write my own file? */     && (fileptr->st_uid == myUid))    	return YES;    if (fileptr->st_mode & 0020)		/* Group I am in can write? */    {   	for (i=0; i<ngroups; i++) {            if (groups[i] == fileptr->st_gid)	        return YES;	}    }    HTTRACE(PROT_TRACE, "\tFile is not editable.\n");    return NO;					/* If no excuse, can't do */#else    /*    ** We don't know and can't find out. Can we be sure that when opening    ** a file in mode "a" that the file is not modified?    */    return NO;#endif /* GETGROUPS_T */}/*	FileCleanup**	-----------**      This function closes the connection and frees memory.**      Returns YES on OK, else NO*/PRIVATE int FileCleanup (HTRequest *req, int status){    HTNet * net = HTRequest_net(req);    file_info * file = (file_info *) HTNet_context(net);    HTStream * input = HTRequest_inputStream(req);    /* Free stream with data TO Local file system */    if (input) {        if (status == HT_INTERRUPTED)            (*input->isa->abort)(input, NULL);        else            (*input->isa->_free)(input);        HTRequest_setInputStream(req, NULL);    }    /*    **  Remove if we have registered a timer function as a callback    */    if (file->timer) {	HTTimer_delete(file->timer);	file->timer = NULL;    }    if (file) {	HT_FREE(file->local);	HT_FREE(file);    }    HTNet_delete(net, status);    return YES;}/*	Load a document**	---------------**** On entry,

⌨️ 快捷键说明

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