mirror of
https://git.openafs.org/openafs.git
synced 2025-01-19 15:30:14 +00:00
Windows: fs chmod and display mode in fs examine
Make use of the new pioctl VIOC_GETUNIXMODE and VIOC_SETUNIXMODE operations to display the current mode in fs examine and permit setting the mode with "fs chmod". The mode string parsing makes use of Vincent Archer's code from Minix. The required copyright statement and license is attached to parsemode(). afsconfig-windows.h gains definitions for various mode symbols that are not defined by Visual Studio runtime headers. Change-Id: I624f73154b7f177f93289e2641da5d9478ea931c Reviewed-on: http://gerrit.openafs.org/3546 Reviewed-by: Jeffrey Altman <jaltman@openafs.org> Tested-by: Jeffrey Altman <jaltman@openafs.org>
This commit is contained in:
parent
bb4c0234b2
commit
afef1712f2
@ -16,6 +16,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <strsafe.h>
|
||||
@ -23,7 +24,7 @@
|
||||
#include <time.h>
|
||||
#include <winsock2.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <afs/afs_assert.h>
|
||||
#include <rx/rx_globals.h>
|
||||
|
||||
#include <osi.h>
|
||||
@ -1769,6 +1770,7 @@ ExamineCmd(struct cmd_syndesc *as, void *arock)
|
||||
cm_fid_t fid;
|
||||
afs_uint32 filetype;
|
||||
afs_int32 owner[2];
|
||||
afs_uint32 unixModeBits;
|
||||
char cell[CELL_MAXNAMELEN];
|
||||
|
||||
/* once per file */
|
||||
@ -1831,6 +1833,13 @@ ExamineCmd(struct cmd_syndesc *as, void *arock)
|
||||
printf("Owner %s (%d) Group %s (%d)\n", oname, owner[0], gname, owner[1]);
|
||||
}
|
||||
|
||||
blob.out_size = sizeof(afs_uint32);
|
||||
blob.out = (char *) &unixModeBits;
|
||||
if (0 == pioctl_utf8(ti->data, VIOC_GETUNIXMODE, &blob, 1) &&
|
||||
blob.out_size == sizeof(afs_uint32)) {
|
||||
printf("UNIX mode 0%o\n", unixModeBits);
|
||||
}
|
||||
|
||||
blob.out = space;
|
||||
blob.out_size = AFS_PIOCTL_MAXSIZE;
|
||||
code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
|
||||
@ -5543,6 +5552,236 @@ ChGrpCmd(struct cmd_syndesc *as, void *arock)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#define USR_MODES (S_ISUID|S_IRWXU)
|
||||
#define GRP_MODES (S_ISGID|S_IRWXG)
|
||||
#define EXE_MODES (S_IXUSR|S_IXGRP|S_IXOTH)
|
||||
#ifdef S_ISVTX
|
||||
#define ALL_MODES (USR_MODES|GRP_MODES|S_IRWXO|S_ISVTX)
|
||||
#else
|
||||
#define ALL_MODES (USR_MODES|GRP_MODES|S_IRWXO)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* parsemode() is Copyright 1991 by Vincent Archer.
|
||||
* You may freely redistribute this software, in source or binary
|
||||
* form, provided that you do not alter this copyright mention in any
|
||||
* way.
|
||||
*/
|
||||
static afs_uint32
|
||||
parsemode(char *symbolic, afs_uint32 oldmode)
|
||||
{
|
||||
afs_uint32 who, mask, u_mask = 022, newmode, tmpmask;
|
||||
char action;
|
||||
|
||||
newmode = oldmode & ALL_MODES;
|
||||
while (*symbolic) {
|
||||
who = 0;
|
||||
for (; *symbolic; symbolic++) {
|
||||
if (*symbolic == 'a') {
|
||||
who |= ALL_MODES;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 'u') {
|
||||
who |= USR_MODES;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 'g') {
|
||||
who |= GRP_MODES;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 'o') {
|
||||
who |= S_IRWXO;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!*symbolic || *symbolic == ',') {
|
||||
Die(EINVAL, "invalid mode");
|
||||
exit(1);
|
||||
}
|
||||
while (*symbolic) {
|
||||
if (*symbolic == ',')
|
||||
break;
|
||||
switch (*symbolic) {
|
||||
default:
|
||||
Die(EINVAL, "invalid mode");
|
||||
exit(1);
|
||||
case '+':
|
||||
case '-':
|
||||
case '=':
|
||||
action = *symbolic++;
|
||||
}
|
||||
mask = 0;
|
||||
for (; *symbolic; symbolic++) {
|
||||
if (*symbolic == 'u') {
|
||||
tmpmask = newmode & S_IRWXU;
|
||||
mask |= tmpmask | (tmpmask << 3) | (tmpmask << 6);
|
||||
symbolic++;
|
||||
break;
|
||||
}
|
||||
if (*symbolic == 'g') {
|
||||
tmpmask = newmode & S_IRWXG;
|
||||
mask |= tmpmask | (tmpmask >> 3) | (tmpmask << 3);
|
||||
symbolic++;
|
||||
break;
|
||||
}
|
||||
if (*symbolic == 'o') {
|
||||
tmpmask = newmode & S_IRWXO;
|
||||
mask |= tmpmask | (tmpmask >> 3) | (tmpmask >> 6);
|
||||
symbolic++;
|
||||
break;
|
||||
}
|
||||
if (*symbolic == 'r') {
|
||||
mask |= S_IRUSR | S_IRGRP | S_IROTH;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 'w') {
|
||||
mask |= S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 'x') {
|
||||
mask |= EXE_MODES;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 's') {
|
||||
mask |= S_ISUID | S_ISGID;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 'X') {
|
||||
if (S_ISDIR(oldmode) || (oldmode & EXE_MODES))
|
||||
mask |= EXE_MODES;
|
||||
continue;
|
||||
}
|
||||
if (*symbolic == 't') {
|
||||
mask |= S_ISVTX;
|
||||
who |= S_ISVTX;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (action) {
|
||||
case '=':
|
||||
if (who)
|
||||
newmode &= ~who;
|
||||
else
|
||||
newmode = 0;
|
||||
case '+':
|
||||
if (who)
|
||||
newmode |= who & mask;
|
||||
else
|
||||
newmode |= mask & (~u_mask);
|
||||
break;
|
||||
case '-':
|
||||
if (who)
|
||||
newmode &= ~(who & mask);
|
||||
else
|
||||
newmode &= ~mask | u_mask;
|
||||
}
|
||||
}
|
||||
if (*symbolic)
|
||||
symbolic++;
|
||||
}
|
||||
return(newmode);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ChModCmd(struct cmd_syndesc *as, void *arock)
|
||||
{
|
||||
afs_int32 code;
|
||||
struct ViceIoctl blob;
|
||||
struct cmd_item *ti;
|
||||
int error = 0;
|
||||
int literal = 0;
|
||||
struct {
|
||||
cm_ioctlQueryOptions_t options;
|
||||
afs_uint32 unixModeBits;
|
||||
} inData;
|
||||
afs_uint32 unixModeBits;
|
||||
afs_int32 absolute = 0;
|
||||
char * unixModeStr;
|
||||
char confDir[257];
|
||||
|
||||
cm_GetConfigDir(confDir, sizeof(confDir));
|
||||
|
||||
if (as->parms[2].items)
|
||||
literal = 1;
|
||||
|
||||
unixModeStr = as->parms[0].items->data;
|
||||
if (*unixModeStr >= '0' && *unixModeStr <= '7') {
|
||||
unixModeBits = 0;
|
||||
absolute = 1;
|
||||
while (*unixModeStr >= '0' && *unixModeStr <= '7')
|
||||
unixModeBits = (unixModeBits << 3) | (*unixModeStr++ & 07);
|
||||
if (*unixModeStr) {
|
||||
Die(EINVAL, "invalid mode");
|
||||
return(1);
|
||||
}
|
||||
unixModeBits &= ALL_MODES;
|
||||
}
|
||||
|
||||
SetDotDefault(&as->parms[1].items);
|
||||
for(ti=as->parms[1].items; ti; ti=ti->next) {
|
||||
cm_fid_t fid;
|
||||
afs_uint32 filetype;
|
||||
char cell[CELL_MAXNAMELEN];
|
||||
|
||||
/* once per file */
|
||||
memset(&fid, 0, sizeof(fid));
|
||||
memset(&inData, 0, sizeof(inData));
|
||||
filetype = 0;
|
||||
inData.options.size = sizeof(inData.options);
|
||||
inData.options.field_flags |= CM_IOCTL_QOPTS_FIELD_LITERAL;
|
||||
inData.options.literal = literal;
|
||||
blob.in_size = inData.options.size; /* no variable length data */
|
||||
blob.in = &inData;
|
||||
|
||||
blob.out_size = sizeof(cm_fid_t);
|
||||
blob.out = (char *) &fid;
|
||||
if (0 == pioctl_utf8(ti->data, VIOCGETFID, &blob, 1) &&
|
||||
blob.out_size == sizeof(cm_fid_t)) {
|
||||
inData.options.field_flags |= CM_IOCTL_QOPTS_FIELD_FID;
|
||||
inData.options.fid = fid;
|
||||
} else {
|
||||
Die(errno, ti->data);
|
||||
error = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the mode was specified as an absolute numeric,
|
||||
* value we can simply apply it to all of the listed
|
||||
* file paths. Otherwise, we must obtain the old mode
|
||||
* value in order to compute the new value from the
|
||||
* symbolic representation.
|
||||
*/
|
||||
if (!absolute) {
|
||||
blob.in_size = 0;
|
||||
blob.out_size = sizeof(afs_uint32);
|
||||
blob.out = (char *)&unixModeBits;
|
||||
if (pioctl_utf8(ti->data, VIOC_GETUNIXMODE, &blob, 1) != 0)
|
||||
{
|
||||
Die(errno, ti->data);
|
||||
error = 1;
|
||||
continue;
|
||||
}
|
||||
inData.unixModeBits = parsemode(unixModeStr, unixModeBits);
|
||||
} else {
|
||||
inData.unixModeBits = unixModeBits;
|
||||
}
|
||||
|
||||
blob.in_size = sizeof(inData);
|
||||
blob.out = NULL;
|
||||
blob.out_size = 0;
|
||||
code = pioctl_utf8(ti->data, VIOC_SETUNIXMODE, &blob, 1);
|
||||
if (code) {
|
||||
Die(errno, ti->data);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#include "AFS_component_version_number.c"
|
||||
#endif
|
||||
@ -5914,6 +6153,11 @@ int wmain(int argc, wchar_t **wargv)
|
||||
cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
|
||||
cmd_AddParm(ts, "-literal", CMD_FLAG, CMD_OPTIONAL, "literal evaluation of mountpoints and symlinks");
|
||||
|
||||
ts = cmd_CreateSyntax("chmod", ChModCmd, NULL, "set UNIX mode for object(s) in afs");
|
||||
cmd_AddParm(ts, "-mode", CMD_SINGLE, 0, "UNIX mode bits");
|
||||
cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
|
||||
cmd_AddParm(ts, "-literal", CMD_FLAG, CMD_OPTIONAL, "literal evaluation of mountpoints and symlinks");
|
||||
|
||||
code = cmd_Dispatch(argc, argv);
|
||||
|
||||
if (rxInitDone)
|
||||
|
@ -203,10 +203,35 @@
|
||||
typedef int errno_t;
|
||||
#endif
|
||||
|
||||
/* Windows only supports BSD variants */
|
||||
#define S_IRUSR _S_IREAD
|
||||
#define S_IWUSR _S_IWRITE
|
||||
/*
|
||||
* UNIX mode symbol definitions
|
||||
*/
|
||||
#ifndef S_IRWXU
|
||||
#define S_IRWXU 00700
|
||||
#define S_IRUSR 00400
|
||||
#define S_IWUSR 00200
|
||||
#define S_IXUSR 00100
|
||||
#endif
|
||||
|
||||
#ifndef S_IRWXG
|
||||
#define S_IRWXG 00070
|
||||
#define S_IRGRP 00040
|
||||
#define S_IWGRP 00020
|
||||
#define S_IXGRP 00010
|
||||
#endif
|
||||
|
||||
#ifndef S_IRWXO
|
||||
#define S_IRWXO 00007
|
||||
#define S_IROTH 00004
|
||||
#define S_IWOTH 00002
|
||||
#define S_IXOTH 00001
|
||||
#endif
|
||||
|
||||
#ifndef S_ISUID
|
||||
#define S_ISUID 0004000
|
||||
#define S_ISGID 0002000
|
||||
#define S_ISVTX 0001000
|
||||
#endif
|
||||
|
||||
#define HAVE_CONIO_H 1
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user