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; } }
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; }