/* * smb_vop_stream_lookup() * * The name returned in od_name is the on-disk name of the stream with the * SMB_STREAM_PREFIX stripped off. od_name should be allocated to MAXNAMELEN * by the caller. */ int smb_vop_stream_lookup( vnode_t *fvp, char *stream_name, vnode_t **vpp, char *od_name, vnode_t **xattrdirvpp, int flags, vnode_t *rootvp, cred_t *cr) { char *solaris_stream_name; char *name; int error, tmpflgs; if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp, LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0) return (error); /* * Prepend SMB_STREAM_PREFIX to stream name */ solaris_stream_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); (void) sprintf(solaris_stream_name, "%s%s", SMB_STREAM_PREFIX, stream_name); /* * "name" will hold the on-disk name returned from smb_vop_lookup * for the stream, including the SMB_STREAM_PREFIX. */ name = kmem_zalloc(MAXNAMELEN, KM_SLEEP); if ((error = smb_vop_lookup(*xattrdirvpp, solaris_stream_name, vpp, name, flags, &tmpflgs, rootvp, cr)) != 0) { VN_RELE(*xattrdirvpp); } else { (void) strlcpy(od_name, &(name[SMB_STREAM_PREFIX_LEN]), MAXNAMELEN); } kmem_free(solaris_stream_name, MAXNAMELEN); kmem_free(name, MAXNAMELEN); return (error); }
/* * smb_odir_single_fileinfo * * Lookup the file identified by od->d_pattern. * * If the looked up file is a link, we attempt to lookup the link target * to use its attributes in place of those of the files's. * If we fail to lookup the target of the link we use the original * file's attributes. * Check if the attributes match the search attributes. * * Returns: 0 - success * ENOENT - no match * errno - error */ static int smb_odir_single_fileinfo(smb_request_t *sr, smb_odir_t *od, smb_fileinfo_t *fileinfo) { int rc; smb_node_t *fnode, *tgt_node; smb_attr_t attr; ino64_t fid; char *name; boolean_t case_conflict = B_FALSE; int lookup_flags, flags = 0; vnode_t *vp; ASSERT(sr); ASSERT(sr->sr_magic == SMB_REQ_MAGIC); ASSERT(od); ASSERT(od->d_magic == SMB_ODIR_MAGIC); ASSERT(MUTEX_HELD(&od->d_mutex)); bzero(fileinfo, sizeof (smb_fileinfo_t)); rc = smb_fsop_lookup(sr, od->d_cred, 0, od->d_tree->t_snode, od->d_dnode, od->d_pattern, &fnode); if (rc != 0) return (rc); /* * If case sensitive, do a case insensitive smb_vop_lookup to * check for case conflict */ if (od->d_flags & SMB_ODIR_FLAG_IGNORE_CASE) { lookup_flags = SMB_IGNORE_CASE; if (od->d_flags & SMB_ODIR_FLAG_CATIA) lookup_flags |= SMB_CATIA; rc = smb_vop_lookup(od->d_dnode->vp, fnode->od_name, &vp, NULL, lookup_flags, &flags, od->d_tree->t_snode->vp, NULL, od->d_cred); if (rc != 0) return (rc); VN_RELE(vp); if (flags & ED_CASE_CONFLICT) case_conflict = B_TRUE; } bzero(&attr, sizeof (attr)); attr.sa_mask = SMB_AT_ALL; rc = smb_node_getattr(sr, fnode, zone_kcred(), NULL, &attr); if (rc != 0) { smb_node_release(fnode); return (rc); } /* follow link to get target node & attr */ if (smb_node_is_symlink(fnode) && smb_odir_lookup_link(sr, od, fnode->od_name, &tgt_node)) { smb_node_release(fnode); fnode = tgt_node; attr.sa_mask = SMB_AT_ALL; rc = smb_node_getattr(sr, fnode, zone_kcred(), NULL, &attr); if (rc != 0) { smb_node_release(fnode); return (rc); } } /* check search attributes */ if (!smb_sattr_check(attr.sa_dosattr, od->d_sattr)) { smb_node_release(fnode); return (ENOENT); } name = fnode->od_name; if (od->d_flags & SMB_ODIR_FLAG_SHORTNAMES) { fid = attr.sa_vattr.va_nodeid; if (case_conflict || smb_needs_mangled(name)) { smb_mangle(name, fid, fileinfo->fi_shortname, SMB_SHORTNAMELEN); } if (case_conflict) name = fileinfo->fi_shortname; } (void) strlcpy(fileinfo->fi_name, name, sizeof (fileinfo->fi_name)); fileinfo->fi_dosattr = attr.sa_dosattr; fileinfo->fi_nodeid = attr.sa_vattr.va_nodeid; fileinfo->fi_size = attr.sa_vattr.va_size; fileinfo->fi_alloc_size = attr.sa_allocsz; fileinfo->fi_atime = attr.sa_vattr.va_atime; fileinfo->fi_mtime = attr.sa_vattr.va_mtime; fileinfo->fi_ctime = attr.sa_vattr.va_ctime; if (attr.sa_crtime.tv_sec) fileinfo->fi_crtime = attr.sa_crtime; else fileinfo->fi_crtime = attr.sa_vattr.va_mtime; smb_node_release(fnode); return (0); }