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 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; }
File::File(Mount& mnt, const fs::path& p, yt::FDMode fdmode, CreateIfNecessary create_if_necessary) : ctx_(mnt.ctx_) { /* mode is not the same for both nfs_creat and nfs_open. For nfs_open * mode has the same meaning as flags but for nfs_creat is the mode used * for file creation. The newer version of libnfs makes this difference * obvious by introducing a second field 'flags' along with mode. We should * consider upgrading to the latest libnfs then and drop the workaround * introduced below. */ const int mode = create_if_necessary == CreateIfNecessary::T ? translate_create_mode(fdmode) : translate_mode(fdmode); LOG_TRACE(mnt.share_name() << ", " << p << ", mode " << mode << ", create: " << create_if_necessary); nfsfh* fh; int ret; if (create_if_necessary == CreateIfNecessary::T) { ret = nfs_creat(ctx_.get(), p.string().c_str(), mode, &fh); } else { ret = nfs_open(ctx_.get(), p.string().c_str(), mode, &fh); } if (ret < 0) { const char* err = nfs_get_error(ctx_.get()); std::stringstream ss; ss << "Failed to open " << p << ": " << err; LOG_ERROR(ss.str()); throw Exception(ss.str().c_str()); } else { fh_ = std::shared_ptr<nfsfh>(fh, FhDeleter(ctx_)); } }
static int NfsInit(access_t *p_access, const char *psz_url_decoded) { access_sys_t *p_sys = p_access->p_sys; p_sys->p_nfs = nfs_init_context(); if (p_sys->p_nfs == NULL) { msg_Err(p_access, "nfs_init_context failed"); return -1; } p_sys->p_nfs_url = nfs_parse_url_incomplete(p_sys->p_nfs, psz_url_decoded); if (p_sys->p_nfs_url == NULL || p_sys->p_nfs_url->server == NULL) { msg_Err(p_access, "nfs_parse_url_incomplete failed: '%s'", nfs_get_error(p_sys->p_nfs)); return -1; } return 0; }
int File::convert_errors_(const char* desc, int (*nfs_fun)(nfs_context*, nfsfh*, A...), A... args) { LOG_TRACE(desc); int ret = (*nfs_fun)(ctx_.get(), fh_.get(), args...); if (ret < 0) { const char* err = nfs_get_error(ctx_.get()); std::stringstream ss; ss << desc << " failed: " << err; throw Exception(ss.str().c_str()); } else { return ret; } }
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; }
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; }
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; }
static void workspace_nfs_readlink(fuse_req_t req, struct entry_struct *entry, struct call_info_struct *call_info) { struct resource_struct *resource=call_info->object->resource; struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data; struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data; char *path=call_info->pathinfo.path + call_info->relpath; int result=0; int len=512; char buffer[len]; if (strlen(path)==0) path=(char *) rootpath; logoutput("workspace_nfs_readlink, path %s", path); /* TODO: make this buffer variable, only how to correct that? what error gives nfs_readlink back when buffer is too small? */ pthread_mutex_lock(&nfs_export->mutex); result=nfs_readlink(nfs_ctx, path, buffer, len); pthread_mutex_unlock(&nfs_export->mutex); if (result<0) { logoutput("workspace_nfs_readlink, error reading readlink of %s, error %i:%s", path, abs(result), nfs_get_error(nfs_ctx)); fuse_reply_err(req, abs(result)); } else { fuse_reply_readlink(req, buffer); } free_path_pathinfo(&call_info->pathinfo); }
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 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); }
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; }