getgrent_a.c raw

   1  #include "pwf.h"
   2  #include <pthread.h>
   3  
   4  static unsigned atou(char **s)
   5  {
   6  	unsigned x;
   7  	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
   8  	return x;
   9  }
  10  
  11  int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res)
  12  {
  13  	ssize_t l;
  14  	char *s, *mems;
  15  	size_t i;
  16  	int rv = 0;
  17  	int cs;
  18  	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  19  	for (;;) {
  20  		if ((l=getline(line, size, f)) < 0) {
  21  			rv = ferror(f) ? errno : 0;
  22  			free(*line);
  23  			*line = 0;
  24  			gr = 0;
  25  			goto end;
  26  		}
  27  		line[0][l-1] = 0;
  28  
  29  		s = line[0];
  30  		gr->gr_name = s++;
  31  		if (!(s = strchr(s, ':'))) continue;
  32  
  33  		*s++ = 0; gr->gr_passwd = s;
  34  		if (!(s = strchr(s, ':'))) continue;
  35  
  36  		*s++ = 0; gr->gr_gid = atou(&s);
  37  		if (*s != ':') continue;
  38  
  39  		*s++ = 0; mems = s;
  40  		break;
  41  	}
  42  
  43  	for (*nmem=!!*s; *s; s++)
  44  		if (*s==',') ++*nmem;
  45  	free(*mem);
  46  	*mem = calloc(sizeof(char *), *nmem+1);
  47  	if (!*mem) {
  48  		rv = errno;
  49  		free(*line);
  50  		*line = 0;
  51  		gr = 0;
  52  		goto end;
  53  	}
  54  	if (*mems) {
  55  		mem[0][0] = mems;
  56  		for (s=mems, i=0; *s; s++)
  57  			if (*s==',') *s++ = 0, mem[0][++i] = s;
  58  		mem[0][++i] = 0;
  59  	} else {
  60  		mem[0][0] = 0;
  61  	}
  62  	gr->gr_mem = *mem;
  63  end:
  64  	pthread_setcancelstate(cs, 0);
  65  	*res = gr;
  66  	if(rv) errno = rv;
  67  	return rv;
  68  }
  69