FreeBSD/lib/libstand/nfs.c
/*
 * Open a file.
 * return zero or error number
 */
Open a file.
return zero or error number
Open a file . return zero or error number
int
nfs_open(const char *upath, struct open_file *f)
{
	struct iodesc *desc;
	struct nfs_iodesc *currfd;
	char buf[2 * NFS_FHSIZE + 3];
	u_char *fh;
	char *cp;
	int i;
#ifndef NFS_NOSYMLINK
	struct nfs_iodesc *newfd;
	struct nfsv2_fattrs *fa;
	char *ncp;
	int c;
	char namebuf[NFS_MAXPATHLEN + 1];
	char linkbuf[NFS_MAXPATHLEN + 1];
	int nlinks = 0;
#endif
	int error;
	char *path;
#ifdef NFS_DEBUG
 	if (debug)
 	    printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath);
#endif
	if (!rootpath[0]) {
		printf("no rootpath, no nfs\n");
		return (ENXIO);
	}
#ifndef __i386__
	if (strcmp(f->f_dev->dv_name, "net") != 0)
		return(EINVAL);
#else
	if (strcmp(f->f_dev->dv_name, "pxe") != 0)
		return(EINVAL);
#endif
	if (!(desc = socktodesc(*(int *)(f->f_devdata))))
		return(EINVAL);
	desc->myport = htons(--rpc_port);
	desc->destip = rootip;
	if ((error = nfs_getrootfh(desc, rootpath, nfs_root_node.fh)))
		return (error);
	nfs_root_node.fa.fa_type  = htonl(NFDIR);
	nfs_root_node.fa.fa_mode  = htonl(0755);
	nfs_root_node.fa.fa_nlink = htonl(2);
	nfs_root_node.iodesc = desc;
	fh = &nfs_root_node.fh[0];
	buf[0] = 'X';
	cp = &buf[1];
	for (i = 0; i < NFS_FHSIZE; i++, cp += 2)
		sprintf(cp, "%02x", fh[i]);
	sprintf(cp, "X");
	setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
	setenv("boot.nfsroot.path", rootpath, 1);
	setenv("boot.nfsroot.nfshandle", buf, 1);
	currfd = malloc(sizeof(*newfd));
	if (currfd == NULL) {
		error = ENOMEM;
		goto out;
	}
#ifndef NFS_NOSYMLINK
	bcopy(&nfs_root_node, currfd, sizeof(*currfd));
	newfd = NULL;
	cp = path = strdup(upath);
	if (path == NULL) {
	    error = ENOMEM;
	    goto out;
	}
	while (*cp) {
		while (*cp == '/')
			cp++;
		if (*cp == '\0')
			break;
		if (currfd->fa.fa_type != htonl(NFDIR)) {
			error = ENOTDIR;
			goto out;
		}
		newfd = malloc(sizeof(*newfd));
		newfd->iodesc = currfd->iodesc;
		{
			int len = 0;
			ncp = cp;
			while ((c = *cp) != '\0' && c != '/') {
				if (++len > NFS_MAXNAMLEN) {
					error = ENOENT;
					goto out;
				}
				cp++;
			}
			*cp = '\0';
		}
		error = nfs_lookupfh(currfd, ncp, newfd);
		*cp = c;
		if (error)
			goto out;
		if (newfd->fa.fa_type == htonl(NFLNK)) {
			int link_len, len;
			error = nfs_readlink(newfd, linkbuf);
			if (error)
				goto out;
			link_len = strlen(linkbuf);
			len = strlen(cp);
			if (link_len + len > MAXPATHLEN
			    || ++nlinks > MAXSYMLINKS) {
				error = ENOENT;
				goto out;
			}
			bcopy(cp, &namebuf[link_len], len + 1);
			bcopy(linkbuf, namebuf, link_len);
			cp = namebuf;
			if (*cp == '/')
				bcopy(&nfs_root_node, currfd, sizeof(*currfd));
			free(newfd);
			newfd = NULL;
			continue;
		}
		free(currfd);
		currfd = newfd;
		newfd = NULL;
	}
	error = 0;
out:
	free(newfd);
	free(path);
#else
        currfd->iodesc = desc;
        error = nfs_lookupfh(&nfs_root_node, upath, currfd);
#endif
	if (!error) {
		currfd->off = 0;
		f->f_fsdata = (void *)currfd;
		return (0);
	}
#ifdef NFS_DEBUG
	if (debug)
		printf("nfs_open: %s lookupfh failed: %s\n",
		    path, strerror(error));
#endif
	free(currfd);
	return (error);
}
int nfs_open ( const char * upath , struct open_file * f ) { struct iodesc * desc ; struct nfs_iodesc * currfd ; char buf [ 2 * NFS_FHSIZE + 3 ] ; u_char * fh ; char * cp ; int i ; #ifndef NFS_NOSYMLINK struct nfs_iodesc * newfd ; struct nfsv2_fattrs * fa ; char * ncp ; int c ; char namebuf [ NFS_MAXPATHLEN + 1 ] ; char linkbuf [ NFS_MAXPATHLEN + 1 ] ; int nlinks = 0 ; #endif int error ; char * path ; #ifdef NFS_DEBUG if ( debug ) printf ( " \n " , upath , rootpath ) ; #endif if ( ! rootpath [ 0 ] ) { printf ( " \n " ) ; return ( ENXIO ) ; } #ifndef __i386__ if ( strcmp ( f -> f_dev -> dv_name , " " ) != 0 ) return ( EINVAL ) ; #else if ( strcmp ( f -> f_dev -> dv_name , " " ) != 0 ) return ( EINVAL ) ; #endif if ( ! ( desc = socktodesc ( * ( int * ) ( f -> f_devdata ) ) ) ) return ( EINVAL ) ; desc -> myport = htons ( -- rpc_port ) ; desc -> destip = rootip ; if ( ( error = nfs_getrootfh ( desc , rootpath , nfs_root_node . fh ) ) ) return ( error ) ; nfs_root_node . fa . fa_type = htonl ( NFDIR ) ; nfs_root_node . fa . fa_mode = htonl ( 0755 ) ; nfs_root_node . fa . fa_nlink = htonl ( 2 ) ; nfs_root_node . iodesc = desc ; fh = & nfs_root_node . fh [ 0 ] ; buf [ 0 ] = ' ' ; cp = & buf [ 1 ] ; for ( i = 0 ; i < NFS_FHSIZE ; i ++ , cp += 2 ) sprintf ( cp , " " , fh [ i ] ) ; sprintf ( cp , " " ) ; setenv ( " " , inet_ntoa ( rootip ) , 1 ) ; setenv ( " " , rootpath , 1 ) ; setenv ( " " , buf , 1 ) ; currfd = malloc ( sizeof ( * newfd ) ) ; if ( currfd == NULL ) { error = ENOMEM ; goto out ; } #ifndef NFS_NOSYMLINK bcopy ( & nfs_root_node , currfd , sizeof ( * currfd ) ) ; newfd = NULL ; cp = path = strdup ( upath ) ; if ( path == NULL ) { error = ENOMEM ; goto out ; } while ( * cp ) { while ( * cp == ' ' ) cp ++ ; if ( * cp == ' \0 ' ) break ; if ( currfd -> fa . fa_type != htonl ( NFDIR ) ) { error = ENOTDIR ; goto out ; } newfd = malloc ( sizeof ( * newfd ) ) ; newfd -> iodesc = currfd -> iodesc ; { int len = 0 ; ncp = cp ; while ( ( c = * cp ) != ' \0 ' && c != ' ' ) { if ( ++ len > NFS_MAXNAMLEN ) { error = ENOENT ; goto out ; } cp ++ ; } * cp = ' \0 ' ; } error = nfs_lookupfh ( currfd , ncp , newfd ) ; * cp = c ; if ( error ) goto out ; if ( newfd -> fa . fa_type == htonl ( NFLNK ) ) { int link_len , len ; error = nfs_readlink ( newfd , linkbuf ) ; if ( error ) goto out ; link_len = strlen ( linkbuf ) ; len = strlen ( cp ) ; if ( link_len + len > MAXPATHLEN || ++ nlinks > MAXSYMLINKS ) { error = ENOENT ; goto out ; } bcopy ( cp , & namebuf [ link_len ] , len + 1 ) ; bcopy ( linkbuf , namebuf , link_len ) ; cp = namebuf ; if ( * cp == ' ' ) bcopy ( & nfs_root_node , currfd , sizeof ( * currfd ) ) ; free ( newfd ) ; newfd = NULL ; continue ; } free ( currfd ) ; currfd = newfd ; newfd = NULL ; } error = 0 ; out : free ( newfd ) ; free ( path ) ; #else currfd -> iodesc = desc ; error = nfs_lookupfh ( & nfs_root_node , upath , currfd ) ; #endif if ( ! error ) { currfd -> off = 0 ; f -> f_fsdata = ( void * ) currfd ; return ( 0 ) ; } #ifdef NFS_DEBUG if ( debug ) printf ( " \n " , path , strerror ( error ) ) ; #endif free ( currfd ) ; return ( error ) ; }
Open a file.
Open a file .
/*
	 * This is silly - we should look at dv_type but that value is
	 * arch dependant and we can't use it here.
	 */ /* Bind to a reserved port. */ /* Allocate file system specific data structure */ /*
		 * Remove extra separators
		 */ /*
		 * Check that current node is a directory.
		 */ /* allocate file system specific data structure */ /*
		 * Get next component of path name.
		 */ /* lookup a file handle */ /*
		 * Check for symbolic link
		 */ /*
			 * If absolute pathname, restart at root.
			 * If relative pathname, restart at parent directory.
			 */