/* open a file */ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io) { struct cvfs_private *p = ntvfs->private_data; struct smbcli_request *c_req; struct ntvfs_handle *h; struct cvfs_file *f; NTSTATUS status; SETUP_PID; if (io->generic.level != RAW_OPEN_GENERIC && p->map_generic) { return ntvfs_map_open(ntvfs, req, io); } status = ntvfs_handle_new(ntvfs, req, &h); NT_STATUS_NOT_OK_RETURN(status); f = talloc_zero(h, struct cvfs_file); NT_STATUS_HAVE_NO_MEMORY(f); f->h = h; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { union smb_handle *file; status = smb_raw_open(p->tree, req, io); NT_STATUS_NOT_OK_RETURN(status); SMB_OPEN_OUT_FILE(io, file); f->fnum = file->fnum; file->ntvfs = NULL; status = ntvfs_handle_set_backend_data(f->h, p->ntvfs, f); NT_STATUS_NOT_OK_RETURN(status); file->ntvfs = f->h; DLIST_ADD(p->files, f); return NT_STATUS_OK; } c_req = smb_raw_open_send(p->tree, io); ASYNC_RECV_TAIL_F(io, async_open, f); }
/* open a file */ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io) { struct svfs_private *p = ntvfs->private_data; char *unix_path; struct stat st; int fd, flags; struct svfs_file *f; int create_flags, rdwr_flags; bool readonly; NTSTATUS status; struct ntvfs_handle *handle; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(ntvfs, req, io); } readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, SHARE_READONLY_DEFAULT); if (readonly) { create_flags = 0; rdwr_flags = O_RDONLY; } else { create_flags = O_CREAT; rdwr_flags = O_RDWR; } unix_path = svfs_unix_path(ntvfs, req, io->ntcreatex.in.fname); switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: case NTCREATEX_DISP_OVERWRITE_IF: flags = create_flags | O_TRUNC; break; case NTCREATEX_DISP_OPEN: case NTCREATEX_DISP_OVERWRITE: flags = 0; break; case NTCREATEX_DISP_CREATE: flags = create_flags | O_EXCL; break; case NTCREATEX_DISP_OPEN_IF: flags = create_flags; break; default: flags = 0; break; } flags |= rdwr_flags; if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { flags = O_RDONLY | O_DIRECTORY; if (readonly) { goto do_open; } switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_CREATE: if (mkdir(unix_path, 0755) == -1) { DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); return map_nt_error_from_unix(errno); } break; case NTCREATEX_DISP_OPEN_IF: if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); return map_nt_error_from_unix(errno); } break; } } do_open: fd = open(unix_path, flags, 0644); if (fd == -1) { return map_nt_error_from_unix(errno); } if (fstat(fd, &st) == -1) { DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); close(fd); return map_nt_error_from_unix(errno); } status = ntvfs_handle_new(ntvfs, req, &handle); NT_STATUS_NOT_OK_RETURN(status); f = talloc(handle, struct svfs_file); NT_STATUS_HAVE_NO_MEMORY(f); f->fd = fd; f->name = talloc_strdup(f, unix_path); NT_STATUS_HAVE_NO_MEMORY(f->name); DLIST_ADD(p->open_files, f); status = ntvfs_handle_set_backend_data(handle, ntvfs, f); NT_STATUS_NOT_OK_RETURN(status); ZERO_STRUCT(io->generic.out); unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); unix_to_nt_time(&io->generic.out.access_time, st.st_atime); unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); io->generic.out.file.ntvfs = handle; io->generic.out.alloc_size = st.st_size; io->generic.out.size = st.st_size; io->generic.out.attrib = svfs_unix_to_dos_attrib(st.st_mode); io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; return NT_STATUS_OK; }