createenv(const struct rule *rule, const struct passwd *mypw,
    const struct passwd *targpw)
{
	struct env *env;
	u_int i;

	env = malloc(sizeof(*env));
	if (!env)
		err(1, NULL);
	RB_INIT(&env->root);
	env->count = 0;

	addnode(env, "DOAS_USER", mypw->pw_name);

	if (rule->options & KEEPENV) {
		extern char **environ;

		for (i = 0; environ[i] != NULL; i++) {
			struct envnode *node;
			const char *e, *eq;
			size_t len;
			char keybuf[1024];

			e = environ[i];

			/* ignore invalid or overlong names */
			if ((eq = strchr(e, '=')) == NULL || eq == e)
				continue;
			len = eq - e;
			if (len > sizeof(keybuf) - 1)
				continue;
			memcpy(keybuf, e, len);
			keybuf[len] = '\0';

			node = createnode(keybuf, eq + 1);
			if (RB_INSERT(envtree, &env->root, node)) {
				/* ignore any later duplicates */
				freenode(node);
			} else {
				env->count++;
			}
		}
	} else {
		static const char *copyset[] = {
			"DISPLAY", "TERM",
			NULL
		};

		addnode(env, "HOME", targpw->pw_dir);
		addnode(env, "LOGNAME", targpw->pw_name);
		addnode(env, "PATH", getenv("PATH"));
		addnode(env, "SHELL", targpw->pw_shell);
		addnode(env, "USER", targpw->pw_name);

		fillenv(env, copyset);
	}

	return env;
}
createenv(const struct rule *rule, const struct passwd *mypw,
    const struct passwd *targpw)
{
	struct env *env;
	u_int i;

	env = malloc(sizeof(*env));
	if (!env)
		err(1, NULL);
	RB_INIT(&env->root);
	env->count = 0;

	addnode(env, "DOAS_USER", mypw->pw_name);

	if (rule->options & KEEPENV) {
		extern char **environ;

		for (i = 0; environ[i] != NULL; i++) {
			struct envnode *node;
			const char *e, *eq;
			size_t len;
			char keybuf[1024];

			e = environ[i];

			 
			if ((eq = strchr(e, '=')) == NULL || eq == e)
				continue;
			len = eq - e;
			if (len > sizeof(keybuf) - 1)
				continue;
			memcpy(keybuf, e, len);
			keybuf[len] = '\0';

			node = createnode(keybuf, eq + 1);
			if (RB_INSERT(envtree, &env->root, node)) {
				 
				freenode(node);
			} else {
				env->count++;
			}
		}
	} else {
		static const char *copyset[] = {
			"DISPLAY", "TERM",
			NULL
		};

		addnode(env, "HOME", targpw->pw_dir);
		addnode(env, "LOGNAME", targpw->pw_name);
		addnode(env, "PATH", getenv("PATH"));
		addnode(env, "SHELL", targpw->pw_shell);
		addnode(env, "USER", targpw->pw_name);

		fillenv(env, copyset);
	}

	return env;
}