📄 nfs.c
字号:
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 + -