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

📄 nfs.c

📁 SMSC LAN device linux Uboot code
💻 C
📖 第 1 页 / 共 2 页
字号:

static int
rpc_lookup_reply (int prog, uchar *pkt, unsigned len)
{
	struct rpc_t rpc_pkt;

	memcpy ((unsigned char *)&rpc_pkt, pkt, len);

#ifdef NFS_DEBUG
	printf ("%s\n", __FUNCTION__);
#endif

	if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
		return -1;

	if (rpc_pkt.u.reply.rstatus  ||
	    rpc_pkt.u.reply.verifier ||
	    rpc_pkt.u.reply.astatus  ||
	    rpc_pkt.u.reply.astatus) {
		return -1;
	}

	switch (prog) {
	case PROG_MOUNT:
		NfsSrvMountPort = ntohl(rpc_pkt.u.reply.data[0]);
		break;
	case PROG_NFS:
		NfsSrvNfsPort = ntohl(rpc_pkt.u.reply.data[0]);
		break;
	}

	return 0;
}

static int
nfs_mount_reply (uchar *pkt, unsigned len)
{
	struct rpc_t rpc_pkt;

#ifdef NFS_DEBUG
	printf ("%s\n", __FUNCTION__);
#endif

	memcpy ((unsigned char *)&rpc_pkt, pkt, len);

	if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
		return -1;

	if (rpc_pkt.u.reply.rstatus  ||
	    rpc_pkt.u.reply.verifier ||
	    rpc_pkt.u.reply.astatus  ||
	    rpc_pkt.u.reply.data[0]) {
		return -1;
	}

	fs_mounted = 1;
	memcpy (dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);

	return 0;
}

static int
nfs_umountall_reply (uchar *pkt, unsigned len)
{
	struct rpc_t rpc_pkt;

#ifdef NFS_DEBUG
	printf ("%s\n", __FUNCTION__);
#endif

	memcpy ((unsigned char *)&rpc_pkt, pkt, len);

	if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
		return -1;

	if (rpc_pkt.u.reply.rstatus  ||
	    rpc_pkt.u.reply.verifier ||
	    rpc_pkt.u.reply.astatus) {
		return -1;
	}

	fs_mounted = 0;
	memset (dirfh, 0, sizeof(dirfh));

	return 0;
}

static int
nfs_lookup_reply (uchar *pkt, unsigned len)
{
	struct rpc_t rpc_pkt;

#ifdef NFS_DEBUG
	printf ("%s\n", __FUNCTION__);
#endif

	memcpy ((unsigned char *)&rpc_pkt, pkt, len);

	if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
		return -1;

	if (rpc_pkt.u.reply.rstatus  ||
	    rpc_pkt.u.reply.verifier ||
	    rpc_pkt.u.reply.astatus  ||
	    rpc_pkt.u.reply.data[0]) {
		return -1;
	}

	memcpy (filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);

	return 0;
}

static int
nfs_readlink_reply (uchar *pkt, unsigned len)
{
	struct rpc_t rpc_pkt;
	int rlen;

#ifdef NFS_DEBUG
	printf ("%s\n", __FUNCTION__);
#endif

	memcpy ((unsigned char *)&rpc_pkt, pkt, len);

	if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
		return -1;

	if (rpc_pkt.u.reply.rstatus  ||
	    rpc_pkt.u.reply.verifier ||
	    rpc_pkt.u.reply.astatus  ||
	    rpc_pkt.u.reply.data[0]) {
		return -1;
	}

	rlen = ntohl (rpc_pkt.u.reply.data[1]); /* new path length */

	if (*((char *)&(rpc_pkt.u.reply.data[2])) != '/') {
		int pathlen;
		strcat (nfs_path, "/");
		pathlen = strlen(nfs_path);
		memcpy (nfs_path+pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
		nfs_path[pathlen+rlen+1] = 0;
	} else {
		memcpy (nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
		nfs_path[rlen] = 0;
	}
	return 0;
}

static int
nfs_read_reply (uchar *pkt, unsigned len)
{
	struct rpc_t rpc_pkt;
	int rlen;

#ifdef NFS_DEBUG_nop
	printf ("%s\n", __FUNCTION__);
#endif

	memcpy ((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));

	if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
		return -1;

	if (rpc_pkt.u.reply.rstatus  ||
	    rpc_pkt.u.reply.verifier ||
	    rpc_pkt.u.reply.astatus  ||
	    rpc_pkt.u.reply.data[0]) {
		if (rpc_pkt.u.reply.rstatus) {
			return -9999;
		}
		if (rpc_pkt.u.reply.astatus) {
			return -9999;
		}
		return -ntohl(rpc_pkt.u.reply.data[0]);;
	}

	if ((nfs_offset!=0) && !((nfs_offset) % (NFS_READ_SIZE/2*10*HASHES_PER_LINE))) {
		puts ("\n\t ");
	}
	if (!(nfs_offset % ((NFS_READ_SIZE/2)*10))) {
		putc ('#');
	}

	rlen = ntohl(rpc_pkt.u.reply.data[18]);
	store_block ((uchar *)pkt+sizeof(rpc_pkt.u.reply), nfs_offset, rlen);

	return rlen;
}

/**************************************************************************
Interfaces of U-BOOT
**************************************************************************/

static void
NfsTimeout (void)
{
	puts ("Timeout\n");
	NetState = NETLOOP_FAIL;
	return;
}

static void
NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)
{
	int rlen;

#ifdef NFS_DEBUG
	printf ("%s\n", __FUNCTION__);
#endif

	if (dest != NfsOurPort) return;

	switch (NfsState) {
	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
		rpc_lookup_reply (PROG_MOUNT, pkt, len);
		NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;
		NfsSend ();
		break;

	case STATE_PRCLOOKUP_PROG_NFS_REQ:
		rpc_lookup_reply (PROG_NFS, pkt, len);
		NfsState = STATE_MOUNT_REQ;
		NfsSend ();
		break;

	case STATE_MOUNT_REQ:
		if (nfs_mount_reply(pkt, len)) {
			puts ("*** ERROR: Cannot mount\n");
			/* just to be sure... */
			NfsState = STATE_UMOUNT_REQ;
			NfsSend ();
		} else {
			NfsState = STATE_LOOKUP_REQ;
			NfsSend ();
		}
		break;

	case STATE_UMOUNT_REQ:
		if (nfs_umountall_reply(pkt, len)) {
			puts ("*** ERROR: Cannot umount\n");
			NetState = NETLOOP_FAIL;
		} else {
			puts ("\ndone\n");
			NetState = NETLOOP_SUCCESS;
		}
		break;

	case STATE_LOOKUP_REQ:
		if (nfs_lookup_reply(pkt, len)) {
			puts ("*** ERROR: File lookup fail\n");
			NfsState = STATE_UMOUNT_REQ;
			NfsSend ();
		} else {
			NfsState = STATE_READ_REQ;
			nfs_offset = 0;
			nfs_len = NFS_READ_SIZE;
			NfsSend ();
		}
		break;

	case STATE_READLINK_REQ:
		if (nfs_readlink_reply(pkt, len)) {
			puts ("*** ERROR: Symlink fail\n");
			NfsState = STATE_UMOUNT_REQ;
			NfsSend ();
		} else {
#ifdef NFS_DEBUG
			printf ("Symlink --> %s\n", nfs_path);
#endif
			nfs_filename = basename (nfs_path);
			nfs_path     = dirname (nfs_path);

			NfsState = STATE_MOUNT_REQ;
			NfsSend ();
		}
		break;

	case STATE_READ_REQ:
		rlen = nfs_read_reply (pkt, len);
		NetSetTimeout (NFS_TIMEOUT * CFG_HZ, NfsTimeout);
		if (rlen > 0) {
			nfs_offset += rlen;
			NfsSend ();
		}
		else if ((rlen == -NFSERR_ISDIR)||(rlen == -NFSERR_INVAL)) {
			/* symbolic link */
			NfsState = STATE_READLINK_REQ;
			NfsSend ();
		} else {
			NfsState = STATE_UMOUNT_REQ;
			NfsSend ();
		}
		break;
	}
}


void
NfsStart (void)
{
#ifdef NFS_DEBUG
	printf ("%s\n", __FUNCTION__);
#endif

	NfsServerIP = NetServerIP;
	nfs_path = (char *)nfs_path_buff;

	if (nfs_path == NULL) {
		NetState = NETLOOP_FAIL;
		puts ("*** ERROR: Fail allocate memory\n");
		return;
	}

	if (BootFile[0] == '\0') {
		IPaddr_t OurIP = ntohl (NetOurIP);

		sprintf (default_filename, "/nfsroot/%02lX%02lX%02lX%02lX.img",
			OurIP & 0xFF,
			(OurIP >>  8) & 0xFF,
			(OurIP >> 16) & 0xFF,
			(OurIP >> 24) & 0xFF	);
		strcpy (nfs_path, default_filename);

		printf ("*** Warning: no boot file name; using '%s'\n",
			nfs_path);
	} else {
		char *p=BootFile;

		p = strchr (p, ':');

		if (p != NULL) {
			NfsServerIP = string_to_ip (BootFile);
			++p;
			strcpy (nfs_path, p);
		} else {
			strcpy (nfs_path, BootFile);
		}
	}

	nfs_filename = basename (nfs_path);
	nfs_path     = dirname (nfs_path);

#if defined(CONFIG_NET_MULTI)
	printf ("Using %s device\n", eth_get_name());
#endif

	puts ("File transfer via NFS from server "); print_IPaddr (NfsServerIP);
	puts ("; our IP address is ");		    print_IPaddr (NetOurIP);

	/* Check if we need to send across this subnet */
	if (NetOurGatewayIP && NetOurSubnetMask) {
		IPaddr_t OurNet	    = NetOurIP	  & NetOurSubnetMask;
		IPaddr_t ServerNet  = NetServerIP & NetOurSubnetMask;

		if (OurNet != ServerNet) {
			puts ("; sending through gateway ");
			print_IPaddr (NetOurGatewayIP) ;
		}
	}
	printf ("\nFilename '%s/%s'.", nfs_path, nfs_filename);

	if (NetBootFileSize) {
		printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9);
		print_size (NetBootFileSize<<9, "");
	}
	printf ("\nLoad address: 0x%lx\n"
		"Loading: *\b", load_addr);

	NetSetTimeout (NFS_TIMEOUT * CFG_HZ, NfsTimeout);
	NetSetHandler (NfsHandler);

	NfsTimeoutCount = 0;
	NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ;

	/*NfsOurPort = 4096 + (get_ticks() % 3072);*/
	/*FIX ME !!!*/
	NfsOurPort = 1000;

	/* zero out server ether in case the server ip has changed */
	memset (NetServerEther, 0, 6);

	NfsSend ();
}

#endif /* CONFIG_COMMANDS & CFG_CMD_NFS */

⌨️ 快捷键说明

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