1#include "pwf.h"
2
3#define FIX(x) (gr->gr_##x = gr->gr_##x - line + buf)
4
5static int getgr_r(const char* name, gid_t gid, struct group* gr, char* buf, size_t size,
6                   struct group** res) {
7    char* line = 0;
8    size_t len = 0;
9    char** mem = 0;
10    size_t nmem = 0;
11    int rv = 0;
12    size_t i;
13
14    rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
15    if (*res && size < len + (nmem + 1) * sizeof(char*) + 32) {
16        *res = 0;
17        rv = ERANGE;
18    }
19    if (*res) {
20        buf += (16 - (uintptr_t)buf) % 16;
21        gr->gr_mem = (void*)buf;
22        buf += (nmem + 1) * sizeof(char*);
23        memcpy(buf, line, len);
24        FIX(name);
25        FIX(passwd);
26        for (i = 0; mem[i]; i++)
27            gr->gr_mem[i] = mem[i] - line + buf;
28        gr->gr_mem[i] = 0;
29    }
30    free(mem);
31    free(line);
32    return rv;
33}
34
35int getgrnam_r(const char* name, struct group* gr, char* buf, size_t size, struct group** res) {
36    return getgr_r(name, 0, gr, buf, size, res);
37}
38
39int getgrgid_r(gid_t gid, struct group* gr, char* buf, size_t size, struct group** res) {
40    return getgr_r(0, gid, gr, buf, size, res);
41}
42