(root)/
acl-2.3.1/
test/
test_group.c
       1  #include "config.h"
       2  #include <sys/types.h>
       3  #include <stdio.h>
       4  #include <string.h>
       5  #include <stdlib.h>
       6  #include <errno.h>
       7  #include <libgen.h>
       8  #include <limits.h>
       9  #include <grp.h>
      10  
      11  #define TEST_GROUP "test/test.group"
      12  static char grfile[PATH_MAX];
      13  static void setup_grfile() __attribute__((constructor));
      14  
      15  static void setup_grfile() {
      16  	snprintf(grfile, sizeof(grfile), "%s/%s", BASEDIR, TEST_GROUP);
      17  }
      18  
      19  #define ALIGN_MASK(x, mask)    (((x) + (mask)) & ~(mask))
      20  #define ALIGN(x, a)            ALIGN_MASK(x, (typeof(x))(a) - 1)
      21  
      22  static int test_getgrent_r(FILE *file, struct group *grp, char *buf,
      23  			   size_t buflen, struct group **result)
      24  {
      25  	char *line, *str, *remain;
      26  	int count, index = 0;
      27  	int gr_mem_cnt = 0;
      28  
      29  	*result = NULL;
      30  
      31  	line = fgets(buf, buflen, file);
      32  	if (!line)
      33  		return 0;
      34  
      35  	/* We'll stuff the gr_mem array in the remaining space in the buffer */
      36  	remain = buf + ALIGN(line + strlen(line) - buf, sizeof(char *));
      37  	grp->gr_mem = (char **)remain;
      38  	count = (buf + buflen - remain) / sizeof (char *);
      39  	if (!count) {
      40  		errno = ERANGE;
      41  		return -1;
      42  	}
      43  
      44  	grp->gr_mem[--count] = NULL;
      45  
      46  	while ((str = strtok(line, ":"))) {
      47  		char *ptr;
      48  		switch (index++) {
      49  		case 0:
      50  			grp->gr_name = str;
      51  			break;
      52  		case 1:
      53  			grp->gr_passwd = str;
      54  			break;
      55  		case 2:
      56  			errno = 0;
      57  			grp->gr_gid = strtol(str, NULL, 10);
      58  			if (errno)
      59  				return -1;
      60  			break;
      61  		case 3:
      62  			while ((str = strtok_r(str, ",", &ptr))) {
      63  				if (count-- <= 0) {
      64  					errno = ERANGE;
      65  					return -1;
      66  				}
      67  				grp->gr_mem[gr_mem_cnt++] = str;
      68  				str = NULL;
      69  			}
      70  		}
      71  		line = NULL;
      72  	}
      73  
      74  	*result = grp;
      75  
      76  	return 0;
      77  }
      78  
      79  static int test_getgr_match(struct group *grp, char *buf, size_t buflen,
      80  			    struct group **result,
      81  			    int (*match)(const struct group *, const void *),
      82  			    const void *data)
      83  {
      84  	FILE *file;
      85  	struct group *_result;
      86  
      87  	*result = NULL;
      88  
      89  	file = fopen(grfile, "r");
      90  	if (!file) {
      91  		errno = EBADF;
      92  		return -1;
      93  	}
      94  
      95  	errno = 0;
      96  	while (!test_getgrent_r(file, grp, buf, buflen, &_result)) {
      97  		if (!_result)
      98  			break;
      99  		else if (match(grp, data)) {
     100  			*result = grp;
     101  			break;
     102  		}
     103  	}
     104  
     105  	fclose(file);
     106  	if (!errno && !*result)
     107  		errno = ENOENT;
     108  	if (errno)
     109  		return -1;
     110  	return 0;
     111  }
     112  
     113  static int match_name(const struct group *grp, const void *data)
     114  {
     115  	const char *name = data;
     116  	return !strcmp(grp->gr_name, name);
     117  }
     118  
     119  EXPORT
     120  int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen,
     121  	       struct group **result)
     122  {
     123  	return test_getgr_match(grp, buf, buflen, result, match_name, name);
     124  }
     125  
     126  EXPORT
     127  struct group *getgrnam(const char *name)
     128  {
     129  	static char buf[16384];
     130  	static struct group grp;
     131  	struct group *result;
     132  
     133  	(void) getgrnam_r(name, &grp, buf, sizeof(buf), &result);
     134  	return result;
     135  }
     136  
     137  static int match_gid(const struct group *grp, const void *data)
     138  {
     139  	gid_t gid = *(gid_t *)data;
     140  	return grp->gr_gid == gid;
     141  }
     142  
     143  EXPORT
     144  int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen,
     145  	       struct group **result)
     146  {
     147  	return test_getgr_match(grp, buf, buflen, result, match_gid, &gid);
     148  }
     149  
     150  EXPORT
     151  struct group *getgrgid(gid_t gid)
     152  {
     153  	static char buf[16384];
     154  	static struct group grp;
     155  	struct group *result;
     156  
     157  	(void) getgrgid_r(gid, &grp, buf, sizeof(buf), &result);
     158  	return result;
     159  }