예제 #1
0
static void
NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)
{
	int rlen;

	debug("%s\n", __func__);

	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 = NfsDownloadState;
		}
		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 {
			debug("Symlink --> %s\n", nfs_path);
			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, NfsTimeout);
		if (rlen > 0) {
			nfs_offset += rlen;
			NfsSend ();
		}
		else if ((rlen == -NFSERR_ISDIR)||(rlen == -NFSERR_INVAL)) {
			/* symbolic link */
			NfsState = STATE_READLINK_REQ;
			NfsSend ();
		} else {
			if ( ! rlen ) NfsDownloadState = NETLOOP_SUCCESS;
			NfsState = STATE_UMOUNT_REQ;
			NfsSend ();
		}
		break;
	}
}
예제 #2
0
파일: nfs.c 프로젝트: AubrCool/barebox
static void nfs_handler(void *ctx, char *packet, unsigned len)
{
	char *pkt = net_eth_to_udp_payload(packet);
	int ret;

	debug("%s\n", __func__);

	switch (nfs_state) {
	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
		ret = rpc_lookup_reply(PROG_MOUNT, pkt, len);
		if (ret)
			goto err_out;
		nfs_state = STATE_PRCLOOKUP_PROG_NFS_REQ;
		break;

	case STATE_PRCLOOKUP_PROG_NFS_REQ:
		ret = rpc_lookup_reply(PROG_NFS, pkt, len);
		if (ret)
			goto err_out;
		nfs_state = STATE_MOUNT_REQ;
		break;

	case STATE_MOUNT_REQ:
		ret = nfs_mount_reply(pkt, len);
		if (ret)
			goto err_out;

		nfs_state = STATE_LOOKUP_REQ;
		break;

	case STATE_UMOUNT_REQ:
		ret = nfs_umountall_reply(pkt, len);
		if (ret)
			nfs_err = ret;
		nfs_state = STATE_DONE;
		return;

	case STATE_LOOKUP_REQ:
		ret = nfs_lookup_reply(pkt, len);
		if (ret)
			goto err_umount;

		nfs_state = STATE_READ_REQ;
		nfs_offset = 0;
		break;

	case STATE_READLINK_REQ:
		ret = nfs_readlink_reply(pkt, len);
		if (ret)
			goto err_umount;

		debug("Symlink --> %s\n", nfs_path);

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

		nfs_state = STATE_MOUNT_REQ;
		break;

	case STATE_READ_REQ:
		ret = nfs_read_reply(pkt, len);
		nfs_timer_start = get_time_ns();
		if (ret > 0)
			nfs_offset += ret;
		else if (ret == -EISDIR || ret == -EINVAL)
			/* symbolic link */
			nfs_state = STATE_READLINK_REQ;
		else
			goto err_umount;
		show_progress(nfs_offset);
		break;
	}

	nfs_send();

	return;

err_umount:
	nfs_state = STATE_UMOUNT_REQ;
	nfs_err = ret;
	nfs_send();
	return;

err_out:
	nfs_state = STATE_DONE;
	nfs_err = ret;
}