int net_mountroot(void) { int error; #ifdef DEBUG printf("net_mountroot\n"); #endif /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP way. (RFC951, RFC1048) */ /* Historically, we've used BOOTPARAMS, so try that first */ error = net_mountroot_bootparams(); if (error != 0) /* Next, try BOOTP */ error = net_mountroot_bootp(); if (error != 0) return (error); printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); /* Get the NFS file handle (mount). */ if (nfs_mount(netdev_sock, rootip, rootpath) != 0) return (errno); return (0); }
int main(int argc, char *argv[]) { struct nfs_context *nfs; struct nfs_url *url; uint64_t length; struct nfs_stat_64 st; if (argc != 5) { usage(); } length = strtol(argv[4], NULL, 10); nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); exit(1); } url = nfs_parse_url_full(nfs, argv[1]); if (url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(nfs)); exit(1); } if (nfs_mount(nfs, url->server, url->path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); exit(1); } if (nfs_chdir(nfs, argv[2]) != 0) { fprintf(stderr, "Failed to chdir to \"%s\" : %s\n", argv[2], nfs_get_error(nfs)); exit(1); } if (nfs_truncate(nfs, argv[3], length)) { fprintf(stderr, "Failed to truncate file : %s\n", nfs_get_error(nfs)); exit(1); } if (nfs_stat64(nfs, argv[3], &st)) { fprintf(stderr, "Failed to stat file : %s\n", nfs_get_error(nfs)); exit(1); } if (st.nfs_size != length) { fprintf(stderr, "Unexpected file size. Expected %d got %d\n", (int)length, (int)st.nfs_size); exit(1); } nfs_destroy_url(url); nfs_destroy_context(nfs); return 0; }
static struct file_context * open_file(const char *url, int flags) { struct file_context *file_context; file_context = malloc(sizeof(struct file_context)); if (file_context == NULL) { fprintf(stderr, "Failed to malloc file_context\n"); return NULL; } file_context->fd = -1; file_context->nfs = NULL; file_context->nfsfh = NULL; file_context->url = NULL; file_context->nfs = nfs_init_context(); if (file_context->nfs == NULL) { fprintf(stderr, "failed to init context\n"); free_file_context(file_context); return NULL; } file_context->url = nfs_parse_url_full(file_context->nfs, url); if (file_context->url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } if (nfs_mount(file_context->nfs, file_context->url->server, file_context->url->path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } if (flags == O_RDONLY) { if (nfs_open(file_context->nfs, file_context->url->file, flags, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to open file %s: %s\n", file_context->url->file, nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } } else { if (nfs_creat(file_context->nfs, file_context->url->file, 0660, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to creat file %s: %s\n", file_context->url->file, nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } } return file_context; }
int net_mountroot(void) { #ifdef DEBUG printf("net_mountroot\n"); #endif /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP way. (RFC951, RFC1048) */ #ifdef SUN_BOOTPARAMS /* Get boot info using RARP and Sun bootparams. */ /* Get our IP address. (rarp.c) */ if (rarp_getipaddress(netdev_sock) == -1) return errno; printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ if (bp_whoami(netdev_sock)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ if (bp_getfile(netdev_sock, "root", &rootip, rootpath)) return (errno); #else /* Get boot info using BOOTP way. (RFC951, RFC1048) */ bootp(netdev_sock); printf("Using IP address: %s\n", inet_ntoa(myip)); printf("myip: %s (%s)", hostname, inet_ntoa(myip)); if (gateip) printf(", gateip: %s", inet_ntoa(gateip)); if (netmask) printf(", netmask: %s", intoa(netmask)); printf("\n"); #endif printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); /* Get the NFS file handle (mount). */ if (nfs_mount(netdev_sock, rootip, rootpath) != 0) return (errno); return 0; }
/* * NFS mount the kernel directory, and perform a lookup on the * kernel file. * * Places the directory filehandle in global "dirfh" * Places the kernel filehandle in global filefh * * returns 0 on success, nonzero on failure */ int fileinit(struct in_addr ip, char *dirname, char *filename) { int mount_port; char *readahead_option; int err; readahead_option = getenv("readahead"); if (readahead_option) kimg_readahead = atoi(readahead_option); if (kimg_readahead < 0) dprintf("NFS using whole-file readahead\n"); else if (kimg_readahead > 0) dprintf("NFS using %dkb readahead\n", kimg_readahead); rpc_init(); /* * Lookup NFS/MOUNTD ports for ROOT using PORTMAP. */ nfs_port = rpc_lookup(ip, PROG_NFS, 2); mount_port = rpc_lookup(ip, PROG_MOUNT, 1); if (nfs_port == -1 || mount_port == -1) { printf("Can't get root NFS/MOUNT ports.\n"); return 1; } dprintf("fileinit: NFS port = %d, MOUNT port = %d\n", nfs_port, mount_port); /* * NFS mount the directory. */ dprintf("Mounting %s ... ", dirname); err = nfs_mount(ip, mount_port, dirname, dirfh); if (err) { printf("Can't mount filesystem: %s.\n", nfs_strerror(err)); return 1; } dprintf("done\n"); /* * Lookup the file. */ dprintf("Looking up %s ... ", filename); err = nfs_lookup(ip, nfs_port, dirfh, filename, filefh); if (err) { printf("Can't lookup %s: %s.\n", filename, nfs_strerror(err)); return 1; } dprintf("done\n"); /* Stash ipaddr for subsequent calls */ ipaddr.s_addr = ip.s_addr; return 0; }
/* * Called by devopen after it sets f->f_dev to our devsw entry. * This opens the low-level device and sets f->f_devdata. * This is declared with variable arguments... */ int net_open(struct open_file *f, ...) { va_list ap; char *devname; /* Device part of file name (or NULL). */ int error = 0; va_start(ap, f); devname = va_arg(ap, char*); va_end(ap); #ifdef NETIF_DEBUG if (debug) printf("net_open: %s\n", devname); #endif /* On first open, do netif open, mount, etc. */ if (netdev_opens == 0) { /* Find network interface. */ if (netdev_sock < 0) { netdev_sock = netif_open(devname); if (netdev_sock < 0) { printf("net_open: netif_open() failed\n"); return (ENXIO); } if (debug) printf("net_open: netif_open() succeeded\n"); } if (rootip.s_addr == 0) { /* Get root IP address, and path, etc. */ error = net_getparams(netdev_sock); if (error) { /* getparams makes its own noise */ goto fail; } /* Get the NFS file handle (mountd). */ error = nfs_mount(netdev_sock, rootip, rootpath); if (error) { error = errno; printf("net_open: NFS mount error=%d\n", error); rootip.s_addr = 0; fail: netif_close(netdev_sock); netdev_sock = -1; return (error); } if (debug) printf("net_open: NFS mount succeeded\n"); } } netdev_opens++; f->f_devdata = nfs_root_node; return (error); }
int main(int argc, char *argv[]) { struct nfs_context *nfs = NULL; struct nfs_url *url = NULL; int ret = 0; int mode; if (argc != 5) { usage(); } mode = strtol(argv[4], NULL, 8); nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); exit(1); } url = nfs_parse_url_full(nfs, argv[1]); if (url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(nfs)); exit(1); } if (nfs_mount(nfs, url->server, url->path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); ret = 1; goto finished; } if (nfs_chdir(nfs, argv[2]) != 0) { fprintf(stderr, "Failed to chdir to \"%s\" : %s\n", argv[2], nfs_get_error(nfs)); ret = 1; goto finished; } if (nfs_lchmod(nfs, argv[3], mode)) { fprintf(stderr, "Failed to lchmod(): %s\n", nfs_get_error(nfs)); ret = 1; goto finished; } finished: nfs_destroy_url(url); nfs_destroy_context(nfs); return ret; }
bool CNFSConnection::Connect(VFSURL* url, std::string& relativePath) { PLATFORM::CLockObject lock(*this); bool ret = false; int nfsRet = 0; std::string exportPath; resolveHost(url->hostname); ret = splitUrlIntoExportAndPath(url->hostname, url->filename, exportPath, relativePath); if( (ret && (exportPath != m_exportPath || m_hostName != url->hostname)) || (PLATFORM::GetTimeMs() - m_lastAccessedTime) > CONTEXT_TIMEOUT ) { int contextRet = getContextForExport(std::string(url->hostname) + exportPath); if(contextRet == CONTEXT_INVALID)//we need a new context because sharename or hostname has changed { return false; } if(contextRet == CONTEXT_NEW) //new context was created - we need to mount it { //we connect to the directory of the path. This will be the "root" path of this connection then. //So all fileoperations are relative to this mountpoint... nfsRet = nfs_mount(m_pNfsContext, m_resolvedHostName.c_str(), exportPath.c_str()); if(nfsRet != 0) { XBMC->Log(ADDON::LOG_ERROR,"NFS: Failed to mount nfs share: %s %s (%s)\n", m_resolvedHostName.c_str(), exportPath.c_str(), nfs_get_error(m_pNfsContext)); destroyContext(std::string(url->hostname) + exportPath); return false; } XBMC->Log(ADDON::LOG_DEBUG,"NFS: Connected to server %s and export %s\n", url->hostname, exportPath.c_str()); } m_exportPath = exportPath; m_hostName = url->hostname; //read chunksize only works after mount m_readChunkSize = nfs_get_readmax(m_pNfsContext); m_writeChunkSize =nfs_get_writemax(m_pNfsContext); if(contextRet == CONTEXT_NEW) { XBMC->Log(ADDON::LOG_DEBUG,"NFS: chunks: r/w %i/%i\n", (int)m_readChunkSize,(int)m_writeChunkSize); } } return ret; }
/* * Get a file handle from the server for the directory which is to be * mounted. */ static int __init root_nfs_get_handle(void) { struct sockaddr_in sin; unsigned int auth_flav_len = 0; struct nfs_mount_request request = { .sap = (struct sockaddr *)&sin, .salen = sizeof(sin), .dirpath = nfs_export_path, .version = (nfs_data.flags & NFS_MOUNT_VER3) ? NFS_MNT3_VERSION : NFS_MNT_VERSION, .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ? XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP, .auth_flav_len = &auth_flav_len, }; int status = -ENOMEM; request.fh = nfs_alloc_fhandle(); if (!request.fh) goto out; set_sockaddr(&sin, servaddr, htons(mount_port)); status = nfs_mount(&request); if (status < 0) printk(KERN_ERR "Root-NFS: Server returned error %d " "while mounting %s\n", status, nfs_export_path); else { nfs_data.root.size = request.fh->size; memcpy(&nfs_data.root.data, request.fh->data, request.fh->size); } nfs_free_fhandle(request.fh); out: return status; } /* * Get the NFS port numbers and file handle, and return the prepared 'data' * argument for mount() if everything went OK. Return NULL otherwise. */ void * __init nfs_root_data(void) { if (root_nfs_init() < 0 || root_nfs_ports() < 0 || root_nfs_get_handle() < 0) return NULL; set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, htons(nfs_port)); return (void*)&nfs_data; }
int net_mountroot() { #ifdef DEBUG printf("net_mountroot\n"); #endif /* * Get info for NFS boot: our IP address, out hostname, * server IP address, and our root path on the server. * We use BOOTP (RFC951, RFC1532) exclusively as mandated * by PowerPC Reference Platform Specification I.4.2 */ bootp(netdev_sock); if (myip.s_addr == 0) return ETIMEDOUT; printf("Using IP address: %s\n", inet_ntoa(myip)); #ifdef DEBUG printf("myip: %s (%s)", hostname, inet_ntoa(myip)); if (gateip.s_addr) printf(", gateip: %s", inet_ntoa(gateip)); if (netmask) printf(", netmask: %s", intoa(netmask)); printf("\n"); #endif printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); /* * Get the NFS file handle (mount). */ if (nfs_mount(netdev_sock, rootip, rootpath) < 0) return errno; return 0; }
err_t http_cache_init(struct ip_addr server, const char *path, void (*callback)(void)) { struct timer *cache_timer; /* timer for triggering cache timeouts */ init_callback = callback; /* FIXME: Start the trace */ #if ENABLE_WEB_TRACING printf("Starting tracing\n"); errval_t err = trace_control(TRACE_EVENT(TRACE_SUBSYS_NET, TRACE_EVENT_NET_START, 0), TRACE_EVENT(TRACE_SUBSYS_NET, TRACE_EVENT_NET_STOP, 0), 0); if(err_is_fail(err)) { USER_PANIC_ERR(err, "trace_control failed"); } trace_event(TRACE_SUBSYS_NET, TRACE_EVENT_NET_START, 0); #else // ENABLE_WEB_TRACING printf("Tracing not enabled\n"); #endif // ENABLE_WEB_TRACING my_nfs_client = nfs_mount(server, path, mount_callback, NULL); assert(my_nfs_client != NULL); /* creating the empty cache */ cache_table = NULL; create_404_page_cache(); cache_timer = timer_create(MAX_STALENESS, true, cache_timeout_event, cache_table); assert (cache_timer != NULL); if (cache_timer == NULL) { printf ("http_cache_init failed in timer_create\n"); return ERR_MEM; } timer_start(cache_timer); DEBUGPRINT ("http_cache_init done\n"); return ERR_OK; } /* end function: http_cache_init */
/* * Get a file handle from the server for the directory which is to be * mounted. */ static int __init root_nfs_get_handle(void) { struct nfs_fh fh; struct sockaddr_in sin; int status; int protocol = (nfs_data.flags & NFS_MOUNT_TCP) ? XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP; int version = (nfs_data.flags & NFS_MOUNT_VER3) ? NFS_MNT3_VERSION : NFS_MNT_VERSION; set_sockaddr(&sin, servaddr, htons(mount_port)); status = nfs_mount((struct sockaddr *) &sin, sizeof(sin), NULL, nfs_path, version, protocol, &fh, nfs_data.mount_prog); if (status < 0) printk(KERN_ERR "Root-NFS: Server returned error %d " "while mounting %s\n", status, nfs_path); else { nfs_data.root.size = fh.size; memcpy(nfs_data.root.data, fh.data, fh.size); } return status; }
int CNFSConnection::stat(VFSURL* url, struct stat *statbuff) { PLATFORM::CLockObject lock(*this); int nfsRet = 0; std::string exportPath; std::string relativePath; struct nfs_context *pTmpContext = NULL; resolveHost(url->hostname); if(splitUrlIntoExportAndPath(url->hostname, url->filename, exportPath, relativePath)) { pTmpContext = nfs_init_context(); if(pTmpContext) { //we connect to the directory of the path. This will be the "root" path of this connection then. //So all fileoperations are relative to this mountpoint... nfsRet = nfs_mount(pTmpContext, m_resolvedHostName.c_str(), exportPath.c_str()); if(nfsRet == 0) { nfsRet = nfs_stat(pTmpContext, relativePath.c_str(), statbuff); } else { XBMC->Log(ADDON::LOG_ERROR,"NFS: Failed to mount nfs share: %s (%s)\n", exportPath.c_str(), nfs_get_error(m_pNfsContext)); } nfs_destroy_context(pTmpContext); XBMC->Log(ADDON::LOG_DEBUG,"NFS: Connected to server %s and export %s in tmpContext\n", url->hostname, exportPath.c_str()); } } return nfsRet; }
static struct file_context * open_file(const char *url, int flags) { struct file_context *file_context; char *server = NULL, *path = NULL, *file = NULL, *strp; file_context = malloc(sizeof(struct file_context)); if (file_context == NULL) { fprintf(stderr, "Failed to malloc file_context\n"); return NULL; } file_context->is_nfs = 0; file_context->fd = -1; file_context->nfs = NULL; file_context->nfsfh = NULL; if (strncmp(url, "nfs://", 6)) { file_context->is_nfs = 0; file_context->fd = open(url, flags, 0660); if (file_context->fd == -1) { fprintf(stderr, "Failed to open %s\n", url); free_file_context(file_context); return NULL; } return file_context; } file_context->is_nfs = 1; file_context->nfs = nfs_init_context(); if (file_context->nfs == NULL) { fprintf(stderr, "failed to init context\n"); free_file_context(file_context); return NULL; } server = strdup(url + 6); if (server == NULL) { fprintf(stderr, "Failed to strdup server string\n"); free_file_context(file_context); return NULL; } if (server[0] == '/' || server[0] == '\0') { fprintf(stderr, "Invalid server string.\n"); free(server); free_file_context(file_context); return NULL; } strp = strchr(server, '/'); path = strdup(strp); *strp = 0; if (path == NULL) { fprintf(stderr, "Invalid URL specified.\n"); free(server); free_file_context(file_context); return NULL; } strp = strrchr(path, '/'); if (strp == NULL) { fprintf(stderr, "Invalid URL specified.\n"); free(path); free(server); free_file_context(file_context); return NULL; } file = strdup(strp); *strp = 0; if (nfs_mount(file_context->nfs, server, path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(file_context->nfs)); free(file); free(path); free(server); free_file_context(file_context); return NULL; } if (flags == O_RDONLY) { if (nfs_open(file_context->nfs, file, flags, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to open file : %s\n", nfs_get_error(file_context->nfs)); free(file); free(path); free(server); free_file_context(file_context); return NULL; } } else { if (nfs_creat(file_context->nfs, file, 0660, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to creat file %s %s\n", file, nfs_get_error(file_context->nfs)); free(file); free(path); free(server); free_file_context(file_context); return NULL; } } free(file); free(path); free(server); return file_context; }
int dup2(int oldfd, int newfd) { close(newfd); if (nfs_fd_list[oldfd].is_nfs == 1) { struct nfs_context *nfs; struct nfs_url *url; struct nfsfh *fh = NULL; int ret, fd; LD_NFS_DPRINTF(9, "dup2(%s:%d, %d)", nfs_fd_list[oldfd].path, oldfd, newfd); nfs = nfs_init_context(); if (nfs == NULL) { LD_NFS_DPRINTF(1, "Failed to create context"); errno = ENOMEM; return -1; } url = nfs_parse_url_full(nfs, nfs_fd_list[oldfd].path); if (url == NULL) { LD_NFS_DPRINTF(1, "Failed to parse URL: %s\n", nfs_get_error(nfs)); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if (nfs_mount(nfs, url->server, url->path) != 0) { LD_NFS_DPRINTF(1, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if ((ret = nfs_open(nfs, url->file, nfs_fd_list[oldfd].mode, &fh)) != 0) { LD_NFS_DPRINTF(1, "Failed to open nfs file : %s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = -ret; return -1; } /* We could actually end on the right descriptor by chance */ if (nfs_get_fd(nfs) != newfd) { if (real_dup2(nfs_get_fd(nfs), newfd) < 0) { LD_NFS_DPRINTF(1, "Failed to dup2 file : %d", errno); return -1; } close(rpc_get_fd(nfs_get_rpc_context(nfs))); rpc_set_fd(nfs_get_rpc_context(nfs), newfd); } fd = nfs_get_fd(nfs); if (fd >= NFS_MAX_FD) { LD_NFS_DPRINTF(1, "Too many files open"); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = ENFILE; return -1; } nfs_fd_list[fd].is_nfs = 1; nfs_fd_list[fd].nfs = nfs; nfs_fd_list[fd].fh = fh; nfs_fd_list[fd].path = strdup(nfs_fd_list[oldfd].path); nfs_fd_list[fd].flags = nfs_fd_list[oldfd].flags; nfs_fd_list[fd].mode = nfs_fd_list[oldfd].mode; nfs_destroy_url(url); LD_NFS_DPRINTF(9, "dup2(%s) successful", nfs_fd_list[oldfd].path); return fd; } return real_dup2(oldfd, newfd); }
int netmountroot(struct open_file *f, char *devname) { int error; struct iodesc *d; #ifdef DEBUG printf("netmountroot: %s\n", devname); #endif if (netio_ask) { get_my_ip: printf("My IP address? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((myip.s_addr = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid IP address: %s\n", input_line); goto get_my_ip; } get_my_netmask: printf("My netmask? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((netmask = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid netmask: %s\n", input_line); goto get_my_netmask; } get_my_gateway: printf("My gateway? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((gateip.s_addr = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid IP address: %s\n", input_line); goto get_my_gateway; } get_server_ip: printf("Server IP address? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((rootip.s_addr = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid IP address: %s\n", input_line); goto get_server_ip; } get_server_path: printf("Server path? "); bzero(rootpath, sizeof(rootpath)); gets(rootpath); if (rootpath[0] == '\0' || rootpath[0] == '\n') goto get_server_path; if ((d = socktodesc(netdev_sock)) == NULL) return (EMFILE); d->myip = myip; goto do_nfs_mount; } /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP way. (RFC951, RFC1048) */ #ifdef SUN_BOOTPARAMS /* Get boot info using RARP and Sun bootparams. */ /* Get our IP address. (rarp.c) */ if (rarp_getipaddress(netdev_sock) == -1) return (errno); printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ if (bp_whoami(netdev_sock)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ if (bp_getfile(netdev_sock, "root", &rootip, rootpath)) return (errno); #else /* Get boot info using BOOTP way. (RFC951, RFC1048) */ bootp(netdev_sock); printf("Using IP address: %s\n", inet_ntoa(myip)); printf("myip: %s (%s)", hostname, inet_ntoa(myip)); if (gateip) printf(", gateip: %s", inet_ntoa(gateip)); if (mask) printf(", mask: %s", intoa(netmask)); printf("\n"); #endif /* SUN_BOOTPARAMS */ printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); do_nfs_mount: /* Get the NFS file handle (mount). */ error = nfs_mount(netdev_sock, rootip, rootpath); return (error); }
int open(const char *path, int flags, mode_t mode) { if (!strncmp(path, "nfs:", 4)) { struct nfs_context *nfs; struct nfs_url *url; struct nfsfh *fh = NULL; int ret, fd; LD_NFS_DPRINTF(9, "open(%s, %x, %o)", path, flags, mode); nfs = nfs_init_context(); if (nfs == NULL) { LD_NFS_DPRINTF(1, "Failed to create context"); errno = ENOMEM; return -1; } url = nfs_parse_url_full(nfs, path); if (url == NULL) { LD_NFS_DPRINTF(1, "Failed to parse URL: %s\n", nfs_get_error(nfs)); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if (nfs_mount(nfs, url->server, url->path) != 0) { LD_NFS_DPRINTF(1, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if (flags & O_CREAT) { if ((ret = nfs_creat(nfs, url->file, mode, &fh)) != 0) { LD_NFS_DPRINTF(1, "Failed to creat nfs file : " "%s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = -ret; return -1; } } else { if ((ret = nfs_open(nfs, url->file, flags, &fh)) != 0) { LD_NFS_DPRINTF(1, "Failed to open nfs file : " "%s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = -ret; return -1; } } fd = nfs_get_fd(nfs); if (fd >= NFS_MAX_FD) { LD_NFS_DPRINTF(1, "Too many files open"); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = ENFILE; return -1; } nfs_fd_list[fd].is_nfs = 1; nfs_fd_list[fd].nfs = nfs; nfs_fd_list[fd].fh = fh; nfs_fd_list[fd].path = strdup(path); nfs_fd_list[fd].flags = flags; nfs_fd_list[fd].mode = mode; nfs_destroy_url(url); LD_NFS_DPRINTF(9, "open(%s) == %d", path, fd); return fd; } return real_open(path, flags, mode); }
int net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr) { static struct netif best_if; struct iodesc *s; int r; if (inited) return 0; /* find a free socket */ s = &desc; memset(s, 0, sizeof(*s)); best_if.nif_driver = drv; s->io_netif = &best_if; memcpy(s->myea, eaddr, 6); /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP way. (RFC951, RFC1048) */ #ifdef SUPPORT_BOOTP /* Get boot info using BOOTP way. (RFC951, RFC1048) */ printf("Trying BOOTP\n"); bootp(0); if (myip.s_addr) { printf("Using IP address: %s\n", inet_ntoa(myip)); printf("myip: %s (%s)\n", hostname, inet_ntoa(myip)); } else #endif /* SUPPORT_BOOTP */ { #ifdef SUPPORT_BOOTPARAMS /* Get boot info using RARP and Sun bootparams. */ printf("Trying BOOTPARAMS\n"); /* Get our IP address. (rarp.c) */ if (rarp_getipaddress(0) == -1) return (errno); printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ if (bp_whoami(0)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ if (bp_getfile(0, "root", &rootip, rootpath)) return (errno); #endif } printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); f->f_devdata = s; /* Get the NFS file handle (mount). */ r = nfs_mount(0, rootip, rootpath); if (r) return r; inited = 1; return 0; }
/************************************************************************** LOAD - Try to get booted **************************************************************************/ load() { char *p,*q; char cfg[64]; int root_mount_port; int swap_nfs_port; int swap_mount_port; char cmd_line[80]; int err, read_size, i; long addr, broadcast; int swsize; unsigned long pad; config_buffer[0]='\0'; /* clear; bootp might fill this up */ /* Initialize this early on */ nfsdiskless.root_args.rsize = 8192; nfsdiskless.root_args.wsize = 8192; nfsdiskless.swap_args.rsize = 8192; nfsdiskless.swap_args.wsize = 8192; nfsdiskless.root_args.sotype = SOCK_DGRAM; nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE | NFSMNT_RESVPORT); nfsdiskless.swap_args.sotype = SOCK_DGRAM; nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE | NFSMNT_RESVPORT); /* Find a server to get BOOTP reply from */ if (!arptable[ARP_CLIENT].ipaddr || !arptable[ARP_SERVER].ipaddr) { printf("\nSearching for server...\n"); if (!bootp()) { printf("No Server found.\n"); longjmp(jmp_bootmenu,1); } } printf("My IP %I, Server IP %I, GW IP %I\n", arptable[ARP_CLIENT].ipaddr, arptable[ARP_SERVER].ipaddr, arptable[ARP_GATEWAY].ipaddr); #ifdef MDEBUG printf("\n=>>"); getchar(); #endif /*** check if have got info from bootp ***/ if (config_buffer[0]) goto cfg_done; #ifndef NO_TFTP /* Now use TFTP to load configuration file */ sprintf(cfg,"/tftpboot/freebsd.%I",arptable[ARP_CLIENT].ipaddr); if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; cfg[17]='\0'; if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; sprintf(cfg,"/tftpboot/cfg.%I",arptable[ARP_CLIENT].ipaddr); if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; #endif /* not found; using default values... */ sprintf(config_buffer,"rootfs %I:/usr/diskless_root", arptable[ARP_SERVER].ipaddr); printf("Unable to load config file, guessing:\n\t%s\n", config_buffer); cfg_done: #ifdef MDEBUG printf("\n=>>"); getchar(); #endif p = config_buffer; while(*p) { q = cmd_line; while ((*p != '\n') && (*p)) *(q++) = *(p++); *q = 0; printf("%s\n",cmd_line); execute(cmd_line); if (*p) p++; } #ifdef MDEBUG printf("\n=>>"); getchar(); #endif /* Check to make sure we've got a rootfs */ if (!arptable[ARP_ROOTSERVER].ipaddr) { printf("No ROOT filesystem server!\n"); longjmp(jmp_bootmenu,1); } /* Fill in nfsdiskless.myif */ sprintf(&nfsdiskless.myif.ifra_name,eth_driver); nfsdiskless.myif.ifra_addr.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_addr.sa_family = AF_INET; addr = htonl(arptable[ARP_CLIENT].ipaddr); bcopy(&addr, &nfsdiskless.myif.ifra_addr.sa_data[2], 4); broadcast = (addr & netmask) | ~netmask; nfsdiskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_broadaddr.sa_family = AF_INET; bcopy(&broadcast, &nfsdiskless.myif.ifra_broadaddr.sa_data[2], 4); addr = htonl(arptable[ARP_GATEWAY].ipaddr); if (addr) { nfsdiskless.mygateway.sin_len = sizeof(struct sockaddr); nfsdiskless.mygateway.sin_family = AF_INET; bcopy(&addr, &nfsdiskless.mygateway.sin_addr, 4); } else { nfsdiskless.mygateway.sin_len = 0; } nfsdiskless.myif.ifra_mask.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_mask.sa_family = AF_UNSPEC; bcopy(&netmask, &nfsdiskless.myif.ifra_mask.sa_data[2], 4); rpc_id = currticks(); /* Lookup NFS/MOUNTD ports for SWAP using PORTMAP */ if (arptable[ARP_SWAPSERVER].ipaddr) { char swapfs_fh[32], swapfile[32]; swap_nfs_port = rpclookup(ARP_SWAPSERVER, PROG_NFS, 2); swap_mount_port = rpclookup(ARP_SWAPSERVER, PROG_MOUNT, 1); if ((swap_nfs_port == -1) || (swap_mount_port == -1)) { printf("Unable to get SWAP NFS/MOUNT ports\n"); longjmp(jmp_bootmenu,1); } if (err = nfs_mount(ARP_SWAPSERVER, swap_mount_port, nfsdiskless.swap_hostnam, &swapfs_fh)) { printf("Unable to mount SWAP filesystem: "); nfs_err(err); longjmp(jmp_bootmenu,1); } sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr); if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port, &swapfs_fh, swapfile, &nfsdiskless.swap_fh, &swsize)) { printf("Unable to open %s: ",swapfile); nfs_err(err); longjmp(jmp_bootmenu,1); } if (!nfsdiskless.swap_nblks) { nfsdiskless.swap_nblks = swsize / 1024; printf("Swap size is: %d blocks\n",nfsdiskless.swap_nblks); } nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in); nfsdiskless.swap_saddr.sin_family = AF_INET; nfsdiskless.swap_saddr.sin_port = htons(swap_nfs_port); nfsdiskless.swap_saddr.sin_addr.s_addr = htonl(arptable[ARP_SWAPSERVER].ipaddr); nfsdiskless.swap_args.timeo = 10; nfsdiskless.swap_args.retrans = 100; } /* Lookup NFS/MOUNTD ports for ROOT using PORTMAP */ root_nfs_port = rpclookup(ARP_ROOTSERVER, PROG_NFS, 2); root_mount_port = rpclookup(ARP_ROOTSERVER, PROG_MOUNT, 1); if ((root_nfs_port == -1) || (root_mount_port == -1)) { printf("Unable to get ROOT NFS/MOUNT ports\n"); longjmp(jmp_bootmenu,1); } if (err = nfs_mount(ARP_ROOTSERVER, root_mount_port, nfsdiskless.root_hostnam, &nfsdiskless.root_fh)) { printf("Unable to mount ROOT filesystem: "); nfs_err(err); longjmp(jmp_bootmenu,1); } nfsdiskless.root_saddr.sin_len = sizeof(struct sockaddr_in); nfsdiskless.root_saddr.sin_family = AF_INET; nfsdiskless.root_saddr.sin_port = htons(root_nfs_port); nfsdiskless.root_saddr.sin_addr.s_addr = htonl(arptable[ARP_ROOTSERVER].ipaddr); nfsdiskless.root_args.timeo = 10; nfsdiskless.root_args.retrans = 100; nfsdiskless.root_time = 0; if (err = nfs_lookup(ARP_ROOTSERVER, root_nfs_port, &nfsdiskless.root_fh, *kernel == '/' ? kernel+1 : kernel, &kernel_handle, NULL)) { printf("Unable to open %s: ",kernel); nfs_err(err); longjmp(jmp_bootmenu,1); } /* Load the kernel using NFS */ printf("Loading %s...\n",kernel); if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, &kernel_handle, 0, sizeof(struct exec), &head)) < 0) { printf("Unable to read %s: ",kernel); nfs_err(err); longjmp(jmp_bootmenu,1); } if (N_BADMAG(head)) { printf("Bad executable format!\n"); longjmp(jmp_bootmenu, 1); } loadpoint = (char *)(head.a_entry & 0x00FFFFFF); offset = N_TXTOFF(head); printf("text=0x%X, ",head.a_text); #ifdef PC98 set_twiddle_max(8); #endif nfsload(head.a_text); while (((int)loadpoint) & PAGE_MASK) *(loadpoint++) = 0; printf("data=0x%X, ",head.a_data); nfsload(head.a_data); printf("bss=0x%X, ",head.a_bss); while(head.a_bss--) *(loadpoint++) = 0; while (((int)loadpoint) & PAGE_MASK) *(loadpoint++) = 0; bootinfo.bi_symtab = (int) loadpoint; p = (char*)&head.a_syms; for (i=0;i<sizeof(head.a_syms);i++) *loadpoint++ = *p++; printf("symbols=[+0x%x+0x%x", sizeof(head.a_syms), head.a_syms); nfsload(head.a_syms); i = sizeof(int); p = loadpoint; nfsload(i); i = *(int*)p; printf("+0x%x]\n", i); i -= sizeof(int); nfsload(i); bootinfo.bi_esymtab = (int) loadpoint; printf("entry=0x%X.\n",head.a_entry); /* Jump to kernel */ bootinfo.bi_version = BOOTINFO_VERSION; bootinfo.bi_kernelname = kernel; bootinfo.bi_nfs_diskless = &nfsdiskless; bootinfo.bi_size = sizeof bootinfo; kernelentry = (void *)(head.a_entry & 0x00FFFFFF); (*kernelentry)(howto|RB_BOOTINFO,NODEV,0,0,0,&bootinfo,0,0,0); printf("*** %s execute failure ***\n",kernel); }
int main(int argc, char *argv[]) { int ret = 1; struct nfs_context *nfs = NULL; struct nfsfh *nfsfh = NULL; struct nfs_url *url = NULL; #ifdef WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { printf("Failed to start Winsock2\n"); exit(10); } #endif #ifdef AROS aros_init_socket(); #endif if (argc < 3) { fprintf(stderr, "No URL specified.\n"); goto finished; } nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); goto finished; } url = nfs_parse_url_full(nfs, argv[argc - 1]); if (url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(nfs)); goto finished; } if (nfs_mount(nfs, url->server, url->path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); goto finished; } if (!strncmp(argv[1], "creat", 5)) { ret = nfs_creat(nfs, url->file, 0600, &nfsfh); } else if (!strncmp(argv[1], "unlink", 6)) { ret = nfs_unlink(nfs, url->file); } else if (!strncmp(argv[1], "mkdir", 5)) { ret = nfs_mkdir(nfs, url->file); } else if (!strncmp(argv[1], "rmdir", 5)) { ret = nfs_rmdir(nfs, url->file); } else if (!strncmp(argv[1], "stat", 4)) { struct nfs_stat_64 st; ret = nfs_stat64(nfs, url->file, &st); if (!ret) { switch (st.nfs_mode & S_IFMT) { #ifndef WIN32 case S_IFLNK: printf("l"); break; #endif case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFCHR: printf("c"); break; case S_IFBLK: printf("b"); break; } printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IRUSR)], "-w"[!!(st.nfs_mode & S_IWUSR)], "-x"[!!(st.nfs_mode & S_IXUSR)] ); printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IRGRP)], "-w"[!!(st.nfs_mode & S_IWGRP)], "-x"[!!(st.nfs_mode & S_IXGRP)] ); printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IROTH)], "-w"[!!(st.nfs_mode & S_IWOTH)], "-x"[!!(st.nfs_mode & S_IXOTH)] ); printf(" %2d", (int)st.nfs_nlink); printf(" %5d", (int)st.nfs_uid); printf(" %5d", (int)st.nfs_gid); printf(" %12" PRId64, st.nfs_size); printf("\n"); } } else { goto finished; } if (ret) { fprintf(stderr, "ERROR: %s\n", nfs_get_error(nfs)); } finished: if (ret > 0) { print_usage(); } nfs_destroy_url(url); if (nfs != NULL) { if (nfsfh) { nfs_close(nfs, nfsfh); } nfs_destroy_context(nfs); } return !!ret; }
/************************************************************************** NFS - Download extended BOOTP data, or kernel image from NFS server **************************************************************************/ int nfs(const char *name, int (*fnc)(unsigned char *, unsigned int, unsigned int, int)) { static int recursion = 0; int sport; int err, namelen = strlen(name); char dirname[300], *fname; char dirfh[NFS_FHSIZE]; /* file handle of directory */ char filefh[NFS_FHSIZE]; /* file handle of kernel image */ unsigned int block; int rlen, size, offs, len; struct rpc_t *rpc; rx_qdrain(); sport = oport++; if (oport > START_OPORT+OPORT_SWEEP) { oport = START_OPORT; } if ( name != dirname ) { memcpy(dirname, name, namelen + 1); } recursion = 0; nfssymlink: if ( recursion > NFS_MAXLINKDEPTH ) { printf ( "\nRecursion: More than %d symlinks followed. Abort.\n", NFS_MAXLINKDEPTH ); return 0; } recursion++; fname = dirname + (namelen - 1); while (fname >= dirname) { if (*fname == '/') { *fname = '\0'; fname++; break; } fname--; } if (fname < dirname) { printf("can't parse file name %s\n", name); return 0; } if (mount_port == -1) { mount_port = rpc_lookup(ARP_SERVER, PROG_MOUNT, 1, sport); } if (nfs_port == -1) { nfs_port = rpc_lookup(ARP_SERVER, PROG_NFS, 2, sport); } if (nfs_port == -1 || mount_port == -1) { printf("can't get nfs/mount ports from portmapper\n"); return 0; } err = nfs_mount(ARP_SERVER, mount_port, dirname, dirfh, sport); if (err) { printf("mounting %s: ", dirname); nfs_printerror(err); /* just to be sure... */ nfs_umountall(ARP_SERVER); return 0; } err = nfs_lookup(ARP_SERVER, nfs_port, dirfh, fname, filefh, sport); if (err) { printf("looking up %s: ", fname); nfs_printerror(err); nfs_umountall(ARP_SERVER); return 0; } offs = 0; block = 1; /* blocks are numbered starting from 1 */ size = -1; /* will be set properly with the first reply */ len = NFS_READ_SIZE; /* first request is always full size */ do { err = nfs_read(ARP_SERVER, nfs_port, filefh, offs, len, sport); if ((err <= -NFSERR_ISDIR)&&(err >= -NFSERR_INVAL) && (offs == 0)) { // An error occured. NFS servers tend to sending // errors 21 / 22 when symlink instead of real file // is requested. So check if it's a symlink! block = nfs_readlink(ARP_SERVER, nfs_port, dirfh, dirname, filefh, sport); if ( 0 == block ) { printf("\nLoading symlink:%s ..",dirname); goto nfssymlink; } nfs_printerror(err); nfs_umountall(ARP_SERVER); return 0; } if (err) { printf("reading at offset %d: ", offs); nfs_printerror(err); nfs_umountall(ARP_SERVER); return 0; } rpc = (struct rpc_t *)&nic.packet[ETH_HLEN]; /* size must be found out early to allow EOF detection */ if (size == -1) { size = ntohl(rpc->u.reply.data[6]); } rlen = ntohl(rpc->u.reply.data[18]); if (rlen > len) { rlen = len; /* shouldn't happen... */ } err = fnc((char *)&rpc->u.reply.data[19], block, rlen, (offs+rlen == size)); if (err <= 0) { nfs_umountall(ARP_SERVER); return err; } block++; offs += rlen; /* last request is done with matching requested read size */ if (size-offs < NFS_READ_SIZE) { len = size-offs; } } while (len != 0); /* len == 0 means that all the file has been read */ return 1; }