return code;
}
+
+/*
+ * VIOC_GETUNIXMODE internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlGetUnixMode(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
+{
+ afs_int32 code = 0;
+ char *cp;
+
+ lock_ObtainWrite(&scp->rw);
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0)
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ReleaseWrite(&scp->rw);
+
+ if (code == 0) {
+ /* Copy all this junk into msg->im_data, keeping track of the lengths. */
+ cp = ioctlp->outDatap;
+ memcpy(cp, (char *)&scp->unixModeBits, sizeof(afs_uint32));
+ cp += sizeof(afs_uint32);
+
+ /* return new size */
+ ioctlp->outDatap = cp;
+ }
+ return code;
+}
+
+
+/*
+ * VIOC_SETUNIXMODE internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped
+ * and that cm_ioctlQueryOptions_t have been parsed and skipped.
+ *
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlSetUnixMode(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
+{
+ afs_int32 code = 0;
+ char *cp;
+
+ lock_ObtainWrite(&scp->rw);
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0)
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ReleaseWrite(&scp->rw);
+
+ if (code == 0) {
+ afs_uint32 unixModeBits;
+ cm_attr_t attr;
+
+ memset(&attr, 0, sizeof(attr));
+
+ cp = ioctlp->inDatap;
+ memcpy((char *)&unixModeBits, cp, sizeof(afs_uint32));
+
+ attr.mask = CM_ATTRMASK_UNIXMODEBITS;
+ attr.unixModeBits = unixModeBits;
+
+ code = cm_SetAttr(scp, &attr, userp, reqp);
+ }
+ return code;
+}
extern void TranslateExtendedChars(char *str);
+extern afs_int32 cm_IoctlGetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
+
+extern afs_int32 cm_IoctlSetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
+
#endif /* __CM_IOCTL_INTERFACES_ONLY__ */
#endif /* __CM_IOCTL_H_ENV__ */
#define VIOC_SETGROUP 0x35
#define VIOC_FS_CMD 0x36
#define VIOCNEWCELL2 0x37
+#define VIOC_GETUNIXMODE 0x38
+#define VIOC_SETUNIXMODE 0x39
#define VIOC_VOLSTAT_TEST 0x3F
smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
+ smb_ioctlProcsp[VIOC_SETUNIXMODE] = smb_IoctlSetUnixMode;
+ smb_ioctlProcsp[VIOC_GETUNIXMODE] = smb_IoctlSetUnixMode;
}
/* called to make a fid structure into an IOCTL fid structure */
}
+afs_int32
+smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlGetUnixMode(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+
+/*
+ * VIOC_SETUNIXMODE
+ *
+ * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
+ */
+afs_int32
+smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp) {
+ if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
+ }
+
+ code = cm_IoctlSetUnixMode(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
extern afs_int32 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
+extern afs_int32 smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
+
+extern afs_int32 smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
+
#endif /* __SMB_IOCTL_H_ENV__ */