Subject: Re: Default 'login.conf' in new installs?
To: None <current-users@netbsd.org>
From: Christian Biere <christianbiere@gmx.de>
List: current-users
Date: 10/13/2006 21:39:20
--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Patrick Welche wrote:
> On Thu, Oct 12, 2006 at 09:20:40PM +0200, Christian Biere wrote:
> > Patrick Welche wrote:
> > > Which reminds me of something I was unable to do: set the environment
> > > variable PGDATESTYLE to "ISO,DMY" in login.conf...
> > setenv doesn't work?
> Its the fact that the value I am trying to set it to contains a comma. As
> setenv takes a comma delimited list and there seems to be no way to
> escape it, I am stuck.
Could you try the attached patch? It adds support for backslash escaping.
--
Christian
--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="login_cap.c.udif"
--- lib/libutil/login_cap.c 20 Dec 2005 21:32:20 -0000 1.23
+++ lib/libutil/login_cap.c 13 Oct 2006 19:35:00 -0000
@@ -489,53 +489,61 @@ envset(void *envp, const char *name, con
int
setuserenv(login_cap_t *lc, envfunc_t senv, void *envp)
{
- const char *stop = ", \t";
- int i, count;
- char *ptr;
- char **res;
- char *str = login_getcapstr(lc, "setenv", NULL, NULL);
+ const char *str = login_getcapstr(lc, "setenv", NULL, NULL);
+ const char *value;
+ char *buf, *q;
if (str == NULL || *str == '\0')
return 0;
-
- /* count the sub-strings */
- for (i = 1, ptr = str; *ptr; i++) {
- ptr += strcspn(ptr, stop);
- if (*ptr)
- ptr++;
- }
-
- /* allocate ptr array and string */
- count = i;
- res = malloc(count * sizeof(char *) + strlen(str) + 1);
- if (!res)
+ buf = malloc(strlen(str) + 1);
+ if (!buf)
return -1;
-
- ptr = (char *)(void *)res + count * sizeof(char *);
- strcpy(ptr, str);
-
- /* split string */
- for (i = 0; *ptr && i < count; i++) {
- res[i] = ptr;
- ptr += strcspn(ptr, stop);
- if (*ptr)
- *ptr++ = '\0';
- }
-
- res[i] = NULL;
-
- for (i = 0; i < count && res[i]; i++) {
- if (*res[i] != '\0') {
- if ((ptr = strchr(res[i], '=')) != NULL)
- *ptr++ = '\0';
- else
- ptr = NULL;
- (void)(*senv)(envp, res[i], ptr ? ptr : "", 1);
+
+ value = NULL;
+ q = buf;
+ *q = '\0';
+
+ do {
+ size_t n;
+
+ n = strcspn(str, "=\\, \t");
+ memcpy(q, str, n);
+ q += n;
+ str += n;
+
+ switch (*str) {
+ case '=':
+ if (!value) {
+ *q++ = '\0';
+ value = q;
+ } else {
+ *q++ = *str;
+ }
+ break;
+ case '\\':
+ str++;
+ if ('\0' != *str) {
+ *q++ = *str;
+ break;
+ }
+ /* FALLTHRU */
+ case ',':
+ case ' ':
+ case '\t':
+ case '\0':
+ if ('\0' != buf[0]) {
+ *q = '\0';
+ (void)(*senv)(envp, buf, value ? value : "", 1);
+ }
+ value = NULL;
+ q = buf;
+ *q = '\0';
+ break;
}
- }
-
- free(res);
+ } while ('\0' != *str++);
+
+ free(buf);
return 0;
}
@@ -623,7 +631,11 @@ setusercontext(login_cap_t *lc, struct p
}
if (flags & LOGIN_SETENV)
- setuserenv(lc, envset, NULL);
+ if (setuserenv(lc, envset, NULL) < 0) {
+ syslog(LOG_ERR, "setuserenv(): %m");
+ login_close(flc);
+ return (-1);
+ }
if (flags & LOGIN_SETPATH)
setuserpath(lc, pwd ? pwd->pw_dir : "", envset, NULL);
--fdj2RfSjLxBAspz7--