- const char *safeset[] = {
- "DISPLAY", "HOME", "LOGNAME", "MAIL", "SHELL",
- "PATH", "TERM", "USER", "USERNAME",
- NULL,
- };
- int nsafe;
- int nextras = 0;
- char **envp;
- const char **extra;
- int ei;
- int i, j;
-
- if ((rule->options & KEEPENV) && !rule->envlist) {
- j = arraylen(oldenvp);
- envp = reallocarray(NULL, j + 1, sizeof(char *));
- if (!envp)
- err(1, "reallocarray");
- for (i = 0; i < j; i++) {
- if (!(envp[i] = strdup(oldenvp[i])))
- err(1, "strdup");
- }
- envp[i] = NULL;
- return envp;
- }
-
- nsafe = arraylen(safeset);
- if ((extra = rule->envlist)) {
- nextras = arraylen(extra);
- for (i = 0; i < nsafe; i++) {
- for (j = 0; j < nextras; j++) {
- if (strcmp(extra[j], safeset[i]) == 0) {
- extra[j--] = extra[nextras--];
- extra[nextras] = NULL;
- }
- }
- }
+ int rv;
+ char *buf;
+ static long pwsz = 0;
+ size_t buflen;
+
+ *result = NULL;
+
+ if (pwsz == 0)
+ pwsz = sysconf(_SC_GETPW_R_SIZE_MAX);
+
+ buflen = pwsz > 0 ? pwsz : 1024;
+
+ buf = malloc(buflen);
+ if (buf == NULL)
+ return errno;
+
+ while ((rv = getpwuid_r(uid, pwd, buf, buflen, result)) == ERANGE) {
+ size_t newsz;
+ newsz = buflen * 2;
+ if (newsz < buflen)
+ return rv;
+ buflen = newsz;
+ buf = realloc(buf, buflen);
+ if (buf == NULL)
+ return errno;