mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-09-28 15:01:21 +02:00
28638: add $usergroups parameter
This commit is contained in:
parent
aa58d139ff
commit
94225e07fc
@ -1,3 +1,9 @@
|
||||
2011-01-19 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 28638: Doc/Zsh/parameter.yo, Src/zsh.h,
|
||||
Src/Modules/parameter.c, plus NEWS added: add $usergroups hash
|
||||
mapping from user's own groups by name to GID.
|
||||
|
||||
2011-01-18 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* Mikael: 28637: Src/subst.c: ${foo:0:} caused crash.
|
||||
@ -14147,5 +14153,5 @@
|
||||
|
||||
*****************************************************
|
||||
* This is used by the shell to define $ZSH_PATCHLEVEL
|
||||
* $Revision: 1.5188 $
|
||||
* $Revision: 1.5189 $
|
||||
*****************************************************
|
||||
|
@ -164,6 +164,12 @@ item(tt(userdirs))(
|
||||
This associative array maps user names to the pathnames of their home
|
||||
directories.
|
||||
)
|
||||
vindex(usergroups)
|
||||
item(tt(usergroups))(
|
||||
This associative array maps names of system groups of which the current
|
||||
user is a member to the corresponding group identifiers. The contents
|
||||
are the same as the groups output by the tt(id) command.
|
||||
)
|
||||
vindex(funcfiletrace)
|
||||
item(tt(funcfiletrace))(
|
||||
This array contains the absolute line numbers and corresponding file
|
||||
|
8
NEWS
8
NEWS
@ -4,6 +4,14 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH
|
||||
|
||||
Note also the list of incompatibilities in the README file.
|
||||
|
||||
Changes since 4.3.11
|
||||
--------------------
|
||||
|
||||
The zsh/parameter module has a new readonly associative array
|
||||
$usergroups whose keys are the names of system groups of which the
|
||||
current user is a member and whose values are the corresponding
|
||||
group identifiers.
|
||||
|
||||
Changes between versions 4.3.10 and 4.3.11
|
||||
------------------------------------------
|
||||
|
||||
|
@ -1820,6 +1820,141 @@ scanpmdissaliases(HashTable ht, ScanFunc func, int flags)
|
||||
scanaliases(sufaliastab, ht, func, flags, ALIAS_SUFFIX|DISABLED);
|
||||
}
|
||||
|
||||
|
||||
/* Functions for the usergroups special parameter */
|
||||
|
||||
/*
|
||||
* Get GID and names for groups of which the current user is a member.
|
||||
*/
|
||||
|
||||
/**/
|
||||
static Groupset get_all_groups(void)
|
||||
{
|
||||
Groupset gs = zhalloc(sizeof(*gs));
|
||||
Groupmap gaptr;
|
||||
gid_t *list, *lptr, egid;
|
||||
int add_egid;
|
||||
struct group *grptr;
|
||||
|
||||
egid = getegid();
|
||||
add_egid = 1;
|
||||
gs->num = getgroups(0, NULL);
|
||||
if (gs->num > 0) {
|
||||
list = zhalloc(gs->num * sizeof(*list));
|
||||
if (getgroups(gs->num, list) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's unspecified whether $EGID is included in the
|
||||
* group set, so check.
|
||||
*/
|
||||
for (lptr = list; lptr < list + gs->num; lptr++) {
|
||||
if (*lptr == egid) {
|
||||
add_egid = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
gs->array = zhalloc((gs->num + add_egid) * sizeof(*gs->array));
|
||||
/* Put EGID if needed first */
|
||||
gaptr = gs->array + add_egid;
|
||||
for (lptr = list; lptr < list + gs->num; lptr++) {
|
||||
gaptr->gid = *lptr;
|
||||
gaptr++;
|
||||
}
|
||||
gs->num += add_egid;
|
||||
} else {
|
||||
/* Just use effective GID */
|
||||
gs->num = 1;
|
||||
gs->array = zhalloc(sizeof(*gs->array));
|
||||
}
|
||||
if (add_egid) {
|
||||
gs->array->gid = egid;
|
||||
}
|
||||
|
||||
/* Get group names */
|
||||
for (gaptr = gs->array; gaptr < gs->array + gs->num; gaptr++) {
|
||||
grptr = getgrgid(gaptr->gid);
|
||||
if (!grptr) {
|
||||
return NULL;
|
||||
}
|
||||
gaptr->name = dupstring(grptr->gr_name);
|
||||
}
|
||||
|
||||
return gs;
|
||||
}
|
||||
|
||||
/* Standard hash element lookup. */
|
||||
|
||||
/**/
|
||||
static HashNode
|
||||
getpmusergroups(UNUSED(HashTable ht), const char *name)
|
||||
{
|
||||
Param pm = NULL;
|
||||
Groupset gs = get_all_groups();
|
||||
Groupmap gaptr;
|
||||
|
||||
pm = (Param)hcalloc(sizeof(struct param));
|
||||
pm->node.nam = dupstring(name);
|
||||
pm->node.flags = PM_SCALAR | PM_READONLY;
|
||||
pm->gsu.s = &nullsetscalar_gsu;
|
||||
|
||||
if (!gs) {
|
||||
zerr("failed to retrieve groups for user: %e", errno);
|
||||
pm->u.str = dupstring("");
|
||||
pm->node.flags |= PM_UNSET;
|
||||
return &pm->node;
|
||||
}
|
||||
|
||||
for (gaptr = gs->array; gaptr < gs->array + gs->num; gaptr++) {
|
||||
if (!strcmp(name, gaptr->name)) {
|
||||
char buf[DIGBUFSIZE];
|
||||
|
||||
sprintf(buf, "%d", (int)gaptr->gid);
|
||||
pm->u.str = dupstring(buf);
|
||||
return &pm->node;
|
||||
}
|
||||
}
|
||||
|
||||
pm->u.str = dupstring("");
|
||||
pm->node.flags |= PM_UNSET;
|
||||
return &pm->node;
|
||||
}
|
||||
|
||||
/* Standard hash scan. */
|
||||
|
||||
/**/
|
||||
static void
|
||||
scanpmusergroups(UNUSED(HashTable ht), ScanFunc func, int flags)
|
||||
{
|
||||
struct param pm;
|
||||
Groupset gs = get_all_groups();
|
||||
Groupmap gaptr;
|
||||
|
||||
if (!gs) {
|
||||
zerr("failed to retrieve groups for user: %e", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
memset((void *)&pm, 0, sizeof(pm));
|
||||
pm.node.flags = PM_SCALAR | PM_READONLY;
|
||||
pm.gsu.s = &nullsetscalar_gsu;
|
||||
|
||||
for (gaptr = gs->array; gaptr < gs->array + gs->num; gaptr++) {
|
||||
pm.node.nam = gaptr->name;
|
||||
if (func != scancountparams &&
|
||||
((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
|
||||
!(flags & SCANPM_WANTKEYS))) {
|
||||
char buf[DIGBUFSIZE];
|
||||
|
||||
sprintf(buf, "%d", (int)gaptr->gid);
|
||||
pm.u.str = dupstring(buf);
|
||||
}
|
||||
func(&pm.node, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Table for defined parameters. */
|
||||
|
||||
struct pardef {
|
||||
@ -1926,7 +2061,9 @@ static struct paramdef partab[] = {
|
||||
SPECIALPMDEF("saliases", 0,
|
||||
&pmsaliases_gsu, getpmsalias, scanpmsaliases),
|
||||
SPECIALPMDEF("userdirs", PM_READONLY,
|
||||
NULL, getpmuserdir, scanpmuserdirs)
|
||||
NULL, getpmuserdir, scanpmuserdirs),
|
||||
SPECIALPMDEF("usergroups", PM_READONLY,
|
||||
NULL, getpmusergroups, scanpmusergroups)
|
||||
};
|
||||
|
||||
static struct features module_features = {
|
||||
|
17
Src/zsh.h
17
Src/zsh.h
@ -1731,6 +1731,23 @@ struct nameddir {
|
||||
#define ND_USERNAME (1<<1) /* nam is actually a username */
|
||||
#define ND_NOABBREV (1<<2) /* never print as abbrev (PWD or OLDPWD) */
|
||||
|
||||
/* Storage for single group/name mapping */
|
||||
typedef struct {
|
||||
/* Name of group */
|
||||
char *name;
|
||||
/* Group identifier */
|
||||
gid_t gid;
|
||||
} groupmap;
|
||||
typedef groupmap *Groupmap;
|
||||
|
||||
/* Storage for a set of group/name mappings */
|
||||
typedef struct {
|
||||
/* The set of name to gid mappings */
|
||||
Groupmap array;
|
||||
/* A count of the valid entries in groupmap. */
|
||||
int num;
|
||||
} groupset;
|
||||
typedef groupset *Groupset;
|
||||
|
||||
/* flags for controlling printing of hash table nodes */
|
||||
#define PRINT_NAMEONLY (1<<0)
|
||||
|
Loading…
Reference in New Issue
Block a user