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

📄 nfsdlib.c

📁 VxWorks源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    nfsstat       authorized;	/* request is authorized if == NFS_OK*/        /* Initialize task for VxWorks RPC work */        rpcTaskInit ();    transp = svcudp_create(-1);    /* Work loop is repeated until catastrophic error encountered */        FOREVER	{	/* Get the next message */		if (msgQReceive (nfsRequestQ, (char *) &request, sizeof(request),			 WAIT_FOREVER) == ERROR)	    {	    perror ("NFS server aborted abnormally");	    return;	    }	/* Break down the incoming message */		local        = request.routine;	argument     = request.argument;	xdr_argument = request.xdrArg;  	xdr_result   = request.xdrResult;	addr         = &request.sockAddr;	xid          = request.xid;	sock         = request.socket;	/* Create a new RPC transport to reply.  Need to do this as	 * next incoming client request will alter xid field of old	 * transport, and replies won't match the correct request.	 */	transp->xp_sock = sock;	((struct svcudp_data *) transp->xp_p2)->su_xid = xid;	transp->xp_raddr = *addr;	memset (&transp->xp_verf, 0, sizeof(transp->xp_verf));	transp->xp_addrlen = sizeof (transp->xp_raddr);	/* Authenticate the request, then call the correct NFS routine */	if (nfsdAuthHook)	    {	    authorized = (*nfsdAuthHook) (NFS_PROGRAM, NFS_VERSION,					  request.procNum, request.sockAddr,					  argument);	    }	else	    authorized = NFS_OK;	if (authorized  != NFS_OK)	    {	    result = KHEAP_ALLOC(sizeof (nfsstat));	    if (NULL != result)		{		bzero ((char *)result, sizeof (nfsstat));		}	    *((nfsstat *) result) = authorized;	    }	else	    result = (char *) (*local)(argument);	/* Send the result */		if (result != NULL && !svc_sendreply(transp, xdr_result, result))	    {	    svcerr_systemerr(transp);	    }	/* Free any space used by RPC/XDR */		if (!svc_freeargs(transp, xdr_argument, argument))	    {	    perror ("unable to free arguments for NFS server");	    return;	    }	/* Free space allocated when request was queued up */		KHEAP_FREE((char *)result);	KHEAP_FREE((char *)argument);	/* Unfortunately, there's no way to tell svc_destroy() to not close	 * the socket.  So, set the socket to -1. svc_destroy() doesn't	 * check the value of the close() anyway.  If errno is set to	 * S_iosLib_INVALID_FILE_DESCRIPTOR due to the close (-1), reset it	 * to OK.  (svc_destroy() returns NULL, so there's no way to check	 * its return value.)	 */		}    transp->xp_sock = -1;    svc_destroy (transp);    if (errno == S_iosLib_INVALID_FILE_DESCRIPTOR)        errno = OK;    }/******************************************************************************** nfsd - NFS daemon process** Used as the entrypoint to a task spawned from nfsdInit().  This task* sets up the NFS RPC service, and calls svc_run(), which should never return.* nfsdRequestEnqueue() is called from the svc_run() call.** This routine is not declared LOCAL only because the symbol for its entry* point should be displayed by i().* * NOTE:  Some of this routine was generated by rpcgen.* * RETURNS:  Never returns unless an error is encountered.* * SEE ALSO: nfsdRequestEnqueue().* * NOMANUAL*/void nfsd    (    void    )    {    register SVCXPRT * transp;	/* RPC transport */    int                sock;	/* NFS socket */    struct sockaddr_in addr;	/* Address of NFS (port 2049 */    int                optVal = NFS_MAXDATA * 2 + sizeof (struct rpc_msg) * 2;                                /* XXX - too much space is wasted here */        /* Initialize the task to use VxWorks RPC code */        rpcTaskInit();    /* Create NFS socket and bind it to correct address */        sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    /* Set up the socket address */        addr.sin_family             = AF_INET;    addr.sin_addr.s_addr        = INADDR_ANY;    addr.sin_port               = htons (NFS_PORT);    bzero (addr.sin_zero, sizeof (addr.sin_zero));    if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == ERROR)	{	perror ("Could not bind to NFS port address");	return;	}    /* Unset any previous NFS services */    pmap_unset(NFS_PROGRAM, NFS_VERSION);    /* Set socket buffer large enough to accommodate max NFS message */    if ((setsockopt (sock, SOL_SOCKET, SO_SNDBUF, (char *)&optVal,		     sizeof (optVal)) == ERROR)	|| (setsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char *)&optVal,			sizeof (optVal)) == ERROR))        return;    /* Create RPC transport */    transp = svcudp_create(sock);    if (transp == NULL)	{	fprintf(stderr, "cannot create udp service.");	exit(1);	}    /* Register NFS */    if (!svc_register(transp, NFS_PROGRAM, NFS_VERSION, nfsdRequestEnqueue,		      IPPROTO_UDP))	{	perror ("unable to register (NFS_PROGRAM, NFS_VERSION, udp).\n");	return;	}    /* Start the RPC service, and never come back */    svc_run();    /* Should never get to this point */        perror ("NFS svc_run returned");    }/******************************************************************************** nfsproc_null_2 - do nothing** RETURNS: A pointer to malloced spaced that contains no information.** NOMANUAL*/void * nfsproc_null_2    (    void    )    {    nfsdServerStatus.nullCalls++;        return ((void *) KHEAP_ALLOC(0));    }/******************************************************************************** nfsproc_getattr_2 - get file attributes** If the reply status is NFS_OK, then the reply attributes contains the* attributes for the file given by the input fhandle.* * RETURNS: A pointer to an attrstat struct.** NOMANUAL*/attrstat * nfsproc_getattr_2    (    nfs_fh *   fh /* File handle to get attributes of */    )    {    attrstat * retVal = KHEAP_ALLOC(sizeof (attrstat)); /* Struct to fill in */    nfsdServerStatus.getattrCalls++;    nfsdFhNtoh ((NFS_FILE_HANDLE *) fh);        if (retVal == NULL)        return (NULL);    /* Get the attributes for the file */        if (nfsdFattrGet ((NFS_FILE_HANDLE *) fh,			 &retVal->attrstat_u.attributes) == ERROR)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    else        retVal->status = NFS_OK;        return (retVal);    }/******************************************************************************** nfsproc_setattr_2 - set the attributes for a file* * The "attr" argument contains fields which are either -1 or are* the new value for the attributes of "file".  If the reply status is* NFS_OK, then the reply attributes have the attributes of the file* after the "SETATTR" operation has completed.* * Notes:  The use of -1 to indicate an unused field in "attributes" is* changed in the next version of the protocol.** NOMANUAL*/attrstat * nfsproc_setattr_2    (    sattrargs *    attr		/* Attributes to change */    )    {    attrstat *     retVal = KHEAP_ALLOC(sizeof (attrstat));/* Return info */    char *         fileName;    /* Name of the file being changed */    int 	   fd;		/* File descriptor for file being changed */    struct utimbuf timeBuf;	/* New time settings for file */    if (retVal == NULL)        return (NULL);         if ((fileName = (char *) alloca (nfsMaxPath)) == NULL)	return (NULL);    nfsdServerStatus.setattrCalls++;    nfsdFhNtoh ((NFS_FILE_HANDLE *) &attr->file);    /* Make sure the file system is writeable */    if (nfsdFsReadOnly((NFS_FILE_HANDLE *) &attr->file))	{	retVal->status = NFSERR_ACCES;	return (retVal);	}    if (nfsdFhToName ((NFS_FILE_HANDLE *) &attr->file, fileName) == ERROR)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    if (attr->attributes.mode != -1)        /* Currently don't have any way to set the mode */        ;            if (attr->attributes.uid != -1)        /* Currently don't have any way to set the uid */        ;            if (attr->attributes.gid != -1)        /* Currently don't have any way to set the gid */        ;            if (attr->attributes.size != -1)	{	/* Set the size of the file using FIOTRUNC ioctl, as VxWorks	 * doesn't have ftruncate() */	        fd = open (fileName, O_RDWR, 0666);	if (fd != ERROR)	    {	    if (ioctl (fd, FIOTRUNC, attr->attributes.size) == ERROR)		{		retVal->status = nfsdErrToNfs (errno);		close (fd);		return (retVal);		}	    else	        close (fd);	    }	else	    {	    retVal->status = nfsdErrToNfs (errno);	    close (fd);	    return (retVal);	    }	}    /* Set file time.     *     * As there's no way to set only one of these fields, if only one     * is set, set the other one to the same value.     */        if (attr->attributes.atime.seconds != -1)	timeBuf.modtime = timeBuf.actime = attr->attributes.atime.seconds;        if (attr->attributes.mtime.seconds != -1)	{	timeBuf.modtime = attr->attributes.mtime.seconds;	if (attr->attributes.atime.seconds == -1)	    timeBuf.actime = timeBuf.modtime;	}    if ((attr->attributes.atime.seconds != -1) ||	(attr->attributes.mtime.seconds != -1))        if (utime (fileName, &timeBuf) == ERROR)	    {	    retVal->status = nfsdErrToNfs (errno);	    return (retVal);	    }        /* Get the status information for the file to return */        if (nfsdFattrGet ((NFS_FILE_HANDLE *) &attr->file,			 &retVal->attrstat_u.attributes) != OK)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    retVal->status = NFS_OK;    return (retVal);    }/******************************************************************************** nfsproc_root_2 - obsolete* * Obsolete.  This procedure is no longer used because finding the root* file handle of a filesystem requires moving pathnames between client* and server.  To do this right, we would have to define a network* standard representation of pathnames.  Instead, the function of* looking up the root file handle is done by the MNTPROC_MNT procedure.* * RETURNS:  A pointer to no information.** NOMANUAL*/void * nfsproc_root_2    (    void    )    {    nfsdServerStatus.setattrCalls++;    return ((void *) KHEAP_ALLOC(0));    }/******************************************************************************** nfsproc_lookup_2 -* * If the reply "status" is NFS_OK, then the reply "file" and reply* "attributes" are the file handle and attributes for the file "name"* in the directory given by "dir" in the argument.* * RETURNS:  A pointer to a diropres struct, or NULL.** NOMANUAL*/diropres * nfsproc_lookup_2    (    diropargs * dir		/* The direcory and file to look up */    )    {    diropres *  retVal = KHEAP_ALLOC(sizeof (diropres)); /* return status */    if (retVal == NULL)        return (NULL);        nfsdServerStatus.lookupCalls++;    nfsdFhNtoh ((NFS_FILE_HANDLE *) &dir->dir);        /* Build file handle for new file */    if (nfsdFhCreate ((NFS_FILE_HANDLE *) &dir->dir, dir->name,			 (NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file)	== ERROR)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    /* Get the attributes for the newly created file handle */    if (nfsdFattrGet ((NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file,			 &retVal->diropres_u.diropres.attributes) == ERROR)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    retVal->status = NFS_OK;    nfsdFhHton ((NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file);        return (retVal);    }/******************************************************************************** nfsproc_readlink_2 - read from a symbolic link* * VxWorks does not support symbolic links.* * RETURNS:  A pointer to an EOPNOTSUPP error.** NOMANUAL*/readlinkres * nfsproc_readlink_2    (    nfs_fh * fh			/* File handle to read */    )    {    readlinkres * retVal = KHEAP_ALLOC(sizeof (retVal->status));    if (retVal == NULL)        return (NULL);    /* Increment statistics */    nfsdServerStatus.readlinkCalls++;    /* symbolic links not supported */    retVal->status = EOPNOTSUPP;    return (retVal);    }/******************************************************************************** nfsproc_read_2 - read data from a file* * Returns up to "count" bytes of "data" from the file given by "file",* starting at "offset" bytes from the beginning of the file.  The first* byte of the file is at offset zero.  The file attributes after the* read takes place are returned in "attributes".* * Notes:  The argument "totalcount" is unused, and is removed in the* next protocol revision.** NOMANUAL*/readres * nfsproc_read_2    (    readargs * readFile		/* File, offset, and count information */    )    {    char *     fileName;        /* Name of the file being read */    readres *  retVal = KHEAP_ALLOC(sizeof (readres) + readFile->count);				/* Return information, including read data */    char *     readData;	/* Address of read data in retVal */    int        fd;		/* File descriptor for file being read */    int	       nBytes;		/* Number of bytes actually read */    if (retVal == NULL)        return (NULL);    if ((fileName = (char *) alloca (nfsMaxPath)) == NULL)	return (NULL);    /* Increment statistics */    nfsdServerStatus.readCalls++;    /* set readData to point to the correct position in the return value */    readData = (char *) retVal + sizeof (readres);        nfsdFhNtoh ((NFS_FILE_HANDLE *) &readFile->file);        if (nfsdFhToName ((NFS_FILE_HANDLE *) &readFile->file, fileName)	== ERROR)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    if (lseek (fd, readFile->offset, SEEK_SET) == ERROR)	{	retVal->status = nfsdErrToNfs (errno);	close (fd);	return (retVal);	}    if ((nBytes = read (fd, readData, readFile->count)) == ERROR)    	{	retVal->status = nfsdErrToNfs (errno);	close (fd);	return (retVal);	}    else	{        retVal->readres_u.reply.data.data_val = readData;	retVal->readres_u.reply.data.data_len = nBytes;	}    if (close (fd) == ERROR)	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    if (nfsdFattrGet ((NFS_FILE_HANDLE *) &readFile->file,			 &retVal->readres_u.reply.attributes) == ERROR)    	{	retVal->status = nfsdErrToNfs (errno);	return (retVal);	}    retVal->status = NFS_OK;    return (retVal);    }/******************************************************************************** nfsproc_writecache_2 - unused*

⌨️ 快捷键说明

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