|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
File: __acl_to_any_text.c
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
Copyright (C) 1999, 2000
|
|
rpm-build |
0a0c83 |
Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is free software; you can redistribute it and/or
|
|
rpm-build |
0a0c83 |
modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License as published by the Free Software Foundation; either
|
|
rpm-build |
0a0c83 |
version 2.1 of the License, or (at your option) any later version.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is distributed in the hope that it will be useful,
|
|
rpm-build |
0a0c83 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0a0c83 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0a0c83 |
Lesser General Public License for more details.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License along with this library; if not, write to the Free Software
|
|
rpm-build |
0a0c83 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#include "config.h"
|
|
rpm-build |
0a0c83 |
#include <stdio.h>
|
|
rpm-build |
0a0c83 |
#include <errno.h>
|
|
rpm-build |
0a0c83 |
#include <string.h>
|
|
rpm-build |
0a0c83 |
#include <pwd.h>
|
|
rpm-build |
0a0c83 |
#include <grp.h>
|
|
rpm-build |
0a0c83 |
#include "libacl.h"
|
|
rpm-build |
0a0c83 |
#include "misc.h"
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static ssize_t acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p,
|
|
rpm-build |
0a0c83 |
ssize_t size, const acl_entry_t mask_d,
|
|
rpm-build |
0a0c83 |
const char *prefix, int options);
|
|
rpm-build |
0a0c83 |
static ssize_t snprint_uint(char *text_p, ssize_t size, unsigned int i);
|
|
rpm-build |
0a0c83 |
static const char *user_name(uid_t uid);
|
|
rpm-build |
0a0c83 |
static const char *group_name(gid_t uid);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
char *
|
|
rpm-build |
0a0c83 |
__acl_to_any_text(acl_t acl, ssize_t *len_p, const char *prefix,
|
|
rpm-build |
0a0c83 |
char separator, const char *suffix, int options)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
acl_obj *acl_obj_p = ext2int(acl, acl);
|
|
rpm-build |
0a0c83 |
ssize_t size, len = 0, entry_len = 0,
|
|
rpm-build |
0a0c83 |
suffix_len = suffix ? strlen(suffix) : 0;
|
|
rpm-build |
0a0c83 |
string_obj *string_obj_p, *tmp;
|
|
rpm-build |
0a0c83 |
acl_entry_obj *entry_obj_p, *mask_obj_p = NULL;
|
|
rpm-build |
0a0c83 |
if (!acl_obj_p)
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
size = acl->a_used * 15 + 1;
|
|
rpm-build |
0a0c83 |
string_obj_p = new_var_obj_p(string, size);
|
|
rpm-build |
0a0c83 |
if (!string_obj_p)
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (options & (TEXT_SOME_EFFECTIVE|TEXT_ALL_EFFECTIVE)) {
|
|
rpm-build |
0a0c83 |
/* fetch the ACL_MASK entry */
|
|
rpm-build |
0a0c83 |
FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
|
|
rpm-build |
0a0c83 |
if (entry_obj_p->etag == ACL_MASK) {
|
|
rpm-build |
0a0c83 |
mask_obj_p = entry_obj_p;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) {
|
|
rpm-build |
0a0c83 |
repeat:
|
|
rpm-build |
0a0c83 |
entry_len = acl_entry_to_any_str(int2ext(entry_obj_p),
|
|
rpm-build |
0a0c83 |
string_obj_p->sstr + len,
|
|
rpm-build |
0a0c83 |
size-len,
|
|
rpm-build |
0a0c83 |
int2ext(mask_obj_p),
|
|
rpm-build |
0a0c83 |
prefix,
|
|
rpm-build |
0a0c83 |
options);
|
|
rpm-build |
0a0c83 |
if (entry_len < 0)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
else if (len + entry_len + suffix_len + 1 > size) {
|
|
rpm-build |
0a0c83 |
while (len + entry_len + suffix_len + 1 > size)
|
|
rpm-build |
0a0c83 |
size <<= 1;
|
|
rpm-build |
0a0c83 |
tmp = realloc_var_obj_p(string, string_obj_p, size);
|
|
rpm-build |
0a0c83 |
if (tmp == NULL)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
string_obj_p = tmp;
|
|
rpm-build |
0a0c83 |
goto repeat;
|
|
rpm-build |
0a0c83 |
} else
|
|
rpm-build |
0a0c83 |
len += entry_len;
|
|
rpm-build |
0a0c83 |
string_obj_p->sstr[len] = separator;
|
|
rpm-build |
0a0c83 |
len++;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (len)
|
|
rpm-build |
0a0c83 |
len--;
|
|
rpm-build |
0a0c83 |
if (len && suffix) {
|
|
rpm-build |
0a0c83 |
strcpy(string_obj_p->sstr + len, suffix);
|
|
rpm-build |
0a0c83 |
len += suffix_len;
|
|
rpm-build |
0a0c83 |
} else
|
|
rpm-build |
0a0c83 |
string_obj_p->sstr[len] = '\0';
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (len_p)
|
|
rpm-build |
0a0c83 |
*len_p = len;
|
|
rpm-build |
0a0c83 |
return (char *)int2ext(string_obj_p);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
free_obj_p(string_obj_p);
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define ADVANCE(x) \
|
|
rpm-build |
0a0c83 |
text_p += (x); \
|
|
rpm-build |
0a0c83 |
size -= (x); \
|
|
rpm-build |
0a0c83 |
if (size < 0) \
|
|
rpm-build |
0a0c83 |
size = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define ABBREV(s, str_len) \
|
|
rpm-build |
0a0c83 |
if (options & TEXT_ABBREVIATE) { \
|
|
rpm-build |
0a0c83 |
if (size > 0) \
|
|
rpm-build |
0a0c83 |
text_p[0] = *(s); \
|
|
rpm-build |
0a0c83 |
if (size > 1) \
|
|
rpm-build |
0a0c83 |
text_p[1] = ':'; \
|
|
rpm-build |
0a0c83 |
ADVANCE(2); \
|
|
rpm-build |
0a0c83 |
} else { \
|
|
rpm-build |
0a0c83 |
strncpy(text_p, (s), size); \
|
|
rpm-build |
0a0c83 |
ADVANCE(str_len); \
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define EFFECTIVE_STR "#effective:"
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static ssize_t
|
|
rpm-build |
0a0c83 |
acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p, ssize_t size,
|
|
rpm-build |
0a0c83 |
const acl_entry_t mask_d, const char *prefix, int options)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
#define TABS 4
|
|
rpm-build |
0a0c83 |
static const char *tabs = "\t\t\t\t";
|
|
rpm-build |
0a0c83 |
acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d);
|
|
rpm-build |
0a0c83 |
acl_entry_obj *mask_obj_p = NULL;
|
|
rpm-build |
0a0c83 |
permset_t effective;
|
|
rpm-build |
0a0c83 |
acl_tag_t type;
|
|
rpm-build |
0a0c83 |
ssize_t x;
|
|
rpm-build |
0a0c83 |
const char *orig_text_p = text_p, *str;
|
|
rpm-build |
0a0c83 |
if (!entry_obj_p)
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
if (mask_d) {
|
|
rpm-build |
0a0c83 |
mask_obj_p = ext2int(acl_entry, mask_d);
|
|
rpm-build |
0a0c83 |
if (!mask_obj_p)
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (text_p == NULL)
|
|
rpm-build |
0a0c83 |
size = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (prefix) {
|
|
rpm-build |
0a0c83 |
strncpy(text_p, prefix, size);
|
|
rpm-build |
0a0c83 |
ADVANCE(strlen(prefix));
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
type = entry_obj_p->etag;
|
|
rpm-build |
0a0c83 |
switch (type) {
|
|
rpm-build |
0a0c83 |
case ACL_USER_OBJ: /* owner */
|
|
rpm-build |
0a0c83 |
mask_obj_p = NULL;
|
|
rpm-build |
0a0c83 |
/* fall through */
|
|
rpm-build |
0a0c83 |
case ACL_USER: /* additional user */
|
|
rpm-build |
0a0c83 |
ABBREV("user:", 5);
|
|
rpm-build |
0a0c83 |
if (type == ACL_USER) {
|
|
rpm-build |
0a0c83 |
if (options & TEXT_NUMERIC_IDS)
|
|
rpm-build |
0a0c83 |
str = NULL;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
str = __acl_quote(user_name(
|
|
rpm-build |
0a0c83 |
entry_obj_p->eid.qid), ":, \t\n\r");
|
|
rpm-build |
0a0c83 |
if (str != NULL) {
|
|
rpm-build |
0a0c83 |
strncpy(text_p, str, size);
|
|
rpm-build |
0a0c83 |
ADVANCE(strlen(str));
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
x = snprint_uint(text_p, size,
|
|
rpm-build |
0a0c83 |
entry_obj_p->eid.qid);
|
|
rpm-build |
0a0c83 |
ADVANCE(x);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (size > 0)
|
|
rpm-build |
0a0c83 |
*text_p = ':';
|
|
rpm-build |
0a0c83 |
ADVANCE(1);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case ACL_GROUP_OBJ: /* owning group */
|
|
rpm-build |
0a0c83 |
case ACL_GROUP: /* additional group */
|
|
rpm-build |
0a0c83 |
ABBREV("group:", 6);
|
|
rpm-build |
0a0c83 |
if (type == ACL_GROUP) {
|
|
rpm-build |
0a0c83 |
if (options & TEXT_NUMERIC_IDS)
|
|
rpm-build |
0a0c83 |
str = NULL;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
str = __acl_quote(group_name(
|
|
rpm-build |
0a0c83 |
entry_obj_p->eid.qid), ":, \t\n\r");
|
|
rpm-build |
0a0c83 |
if (str != NULL) {
|
|
rpm-build |
0a0c83 |
strncpy(text_p, str, size);
|
|
rpm-build |
0a0c83 |
ADVANCE(strlen(str));
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
x = snprint_uint(text_p, size,
|
|
rpm-build |
0a0c83 |
entry_obj_p->eid.qid);
|
|
rpm-build |
0a0c83 |
ADVANCE(x);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (size > 0)
|
|
rpm-build |
0a0c83 |
*text_p = ':';
|
|
rpm-build |
0a0c83 |
ADVANCE(1);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case ACL_MASK: /* acl mask */
|
|
rpm-build |
0a0c83 |
mask_obj_p = NULL;
|
|
rpm-build |
0a0c83 |
ABBREV("mask:", 5);
|
|
rpm-build |
0a0c83 |
if (size > 0)
|
|
rpm-build |
0a0c83 |
*text_p = ':';
|
|
rpm-build |
0a0c83 |
ADVANCE(1);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case ACL_OTHER: /* other users */
|
|
rpm-build |
0a0c83 |
mask_obj_p = NULL;
|
|
rpm-build |
0a0c83 |
/* fall through */
|
|
rpm-build |
0a0c83 |
ABBREV("other:", 6);
|
|
rpm-build |
0a0c83 |
if (size > 0)
|
|
rpm-build |
0a0c83 |
*text_p = ':';
|
|
rpm-build |
0a0c83 |
ADVANCE(1);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
default:
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
switch ((size >= 3) ? 3 : size) {
|
|
rpm-build |
0a0c83 |
case 3:
|
|
rpm-build |
0a0c83 |
text_p[2] = (entry_obj_p->eperm.sperm &
|
|
rpm-build |
0a0c83 |
ACL_EXECUTE) ? 'x' : '-';
|
|
rpm-build |
0a0c83 |
/* fall through */
|
|
rpm-build |
0a0c83 |
case 2:
|
|
rpm-build |
0a0c83 |
text_p[1] = (entry_obj_p->eperm.sperm &
|
|
rpm-build |
0a0c83 |
ACL_WRITE) ? 'w' : '-';
|
|
rpm-build |
0a0c83 |
/* fall through */
|
|
rpm-build |
0a0c83 |
case 1:
|
|
rpm-build |
0a0c83 |
text_p[0] = (entry_obj_p->eperm.sperm &
|
|
rpm-build |
0a0c83 |
ACL_READ) ? 'r' : '-';
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
ADVANCE(3);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (mask_obj_p &&
|
|
rpm-build |
0a0c83 |
(options & (TEXT_SOME_EFFECTIVE|TEXT_ALL_EFFECTIVE))) {
|
|
rpm-build |
0a0c83 |
mask_obj_p = ext2int(acl_entry, mask_d);
|
|
rpm-build |
0a0c83 |
if (!mask_obj_p)
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
effective = entry_obj_p->eperm.sperm &
|
|
rpm-build |
0a0c83 |
mask_obj_p->eperm.sperm;
|
|
rpm-build |
0a0c83 |
if (effective != entry_obj_p->eperm.sperm ||
|
|
rpm-build |
0a0c83 |
options & TEXT_ALL_EFFECTIVE) {
|
|
rpm-build |
0a0c83 |
x = (options & TEXT_SMART_INDENT) ?
|
|
rpm-build |
0a0c83 |
((text_p - orig_text_p)/8) : TABS-1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* use at least one tab for indentation */
|
|
rpm-build |
0a0c83 |
if (x > (TABS-1))
|
|
rpm-build |
0a0c83 |
x = (TABS-1);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
strncpy(text_p, tabs+x, size);
|
|
rpm-build |
0a0c83 |
ADVANCE(TABS-x);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
strncpy(text_p, EFFECTIVE_STR, size);
|
|
rpm-build |
0a0c83 |
ADVANCE(sizeof(EFFECTIVE_STR)-1);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
switch ((size >= 3) ? 3 : size) {
|
|
rpm-build |
0a0c83 |
case 3:
|
|
rpm-build |
0a0c83 |
text_p[2] = (effective &
|
|
rpm-build |
0a0c83 |
ACL_EXECUTE) ? 'x' : '-';
|
|
rpm-build |
0a0c83 |
/* fall through */
|
|
rpm-build |
0a0c83 |
case 2:
|
|
rpm-build |
0a0c83 |
text_p[1] = (effective &
|
|
rpm-build |
0a0c83 |
ACL_WRITE) ? 'w' : '-';
|
|
rpm-build |
0a0c83 |
/* fall through */
|
|
rpm-build |
0a0c83 |
case 1:
|
|
rpm-build |
0a0c83 |
text_p[0] = (effective &
|
|
rpm-build |
0a0c83 |
ACL_READ) ? 'r' : '-';
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
ADVANCE(3);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* zero-terminate string (but don't count '\0' character) */
|
|
rpm-build |
0a0c83 |
if (size > 0)
|
|
rpm-build |
0a0c83 |
*text_p = '\0';
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
return (text_p - orig_text_p); /* total size required, excluding
|
|
rpm-build |
0a0c83 |
final NULL character. */
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#undef ADVANCE
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
This function is equivalent to the proposed changes to snprintf:
|
|
rpm-build |
0a0c83 |
snprintf(text_p, size, "%u", i)
|
|
rpm-build |
0a0c83 |
(The current snprintf returns -1 if the buffer is too small; the proposal
|
|
rpm-build |
0a0c83 |
is to return the number of characters that would be required. See the
|
|
rpm-build |
0a0c83 |
snprintf manual page.)
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static ssize_t
|
|
rpm-build |
0a0c83 |
snprint_uint(char *text_p, ssize_t size, unsigned int i)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
unsigned int tmp = i;
|
|
rpm-build |
0a0c83 |
int digits = 1;
|
|
rpm-build |
0a0c83 |
unsigned int factor = 1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
while ((tmp /= 10) != 0) {
|
|
rpm-build |
0a0c83 |
digits++;
|
|
rpm-build |
0a0c83 |
factor *= 10;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (size && (i == 0)) {
|
|
rpm-build |
0a0c83 |
*text_p++ = '0';
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
while (size > 0 && factor > 0) {
|
|
rpm-build |
0a0c83 |
*text_p++ = '0' + (i / factor);
|
|
rpm-build |
0a0c83 |
size--;
|
|
rpm-build |
0a0c83 |
i %= factor;
|
|
rpm-build |
0a0c83 |
factor /= 10;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (size)
|
|
rpm-build |
0a0c83 |
*text_p = '\0';
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
return digits;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static const char *
|
|
rpm-build |
0a0c83 |
user_name(uid_t uid)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
struct passwd *passwd = getpwuid(uid);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (passwd != NULL)
|
|
rpm-build |
0a0c83 |
return passwd->pw_name;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static const char *
|
|
rpm-build |
0a0c83 |
group_name(gid_t gid)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
struct group *group = getgrgid(gid);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (group != NULL)
|
|
rpm-build |
0a0c83 |
return group->gr_name;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|