about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2022-02-25 20:25:13 +0000
committerLaurent Bercot <ska@appnovation.com>2022-02-25 20:25:13 +0000
commitbaa4044ea53d50271af375dbe97ce6226b865781 (patch)
tree49610483871c3d1d388ef46b8dc20759c864a774
parent336d9fedb35e577ce3aef12e633fcdeae04fe96d (diff)
downloadskalibs-baa4044ea53d50271af375dbe97ce6226b865781.tar.gz
skalibs-baa4044ea53d50271af375dbe97ce6226b865781.tar.xz
skalibs-baa4044ea53d50271af375dbe97ce6226b865781.zip
Bloat envdir with a noclamp option
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--package/deps.mak5
-rw-r--r--src/include/skalibs/env.h2
-rw-r--r--src/libenvexec/envdir-internal.h11
-rw-r--r--src/libenvexec/envdir.c82
-rw-r--r--src/libenvexec/envdir_clamp.c85
-rw-r--r--src/libenvexec/envdir_noclamp.c103
6 files changed, 210 insertions, 78 deletions
diff --git a/package/deps.mak b/package/deps.mak
index cdaf79f..739a594 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -57,6 +57,7 @@ src/include/skalibs/unixmessage.h: src/include/skalibs/buffer.h src/include/skal
 src/include/skalibs/unixonacid.h: src/include/skalibs/ancil.h src/include/skalibs/kolbak.h src/include/skalibs/skaclient.h src/include/skalibs/textclient.h src/include/skalibs/textmessage.h src/include/skalibs/unix-timed.h src/include/skalibs/unix-transactional.h src/include/skalibs/unixconnection.h src/include/skalibs/unixmessage.h
 src/libdatastruct/avlnode-internal.h: src/include/skalibs/avlnode.h
 src/libdatastruct/genqdyn-internal.h: src/include/skalibs/genqdyn.h
+src/libenvexec/envdir-internal.h: src/include/skalibs/stralloc.h
 src/librandom/random-internal.h: src/include/skalibs/surf.h
 src/libstdcrypto/sha1-internal.h: src/include/skalibs/sha1.h
 src/libstdcrypto/sha256-internal.h: src/include/skalibs/sha256.h
@@ -127,7 +128,9 @@ src/libenvexec/envalloc_0.o src/libenvexec/envalloc_0.lo: src/libenvexec/envallo
 src/libenvexec/envalloc_make.o src/libenvexec/envalloc_make.lo: src/libenvexec/envalloc_make.c src/include/skalibs/env.h src/include/skalibs/envalloc.h src/include/skalibs/genalloc.h
 src/libenvexec/envalloc_merge.o src/libenvexec/envalloc_merge.lo: src/libenvexec/envalloc_merge.c src/include/skalibs/bytestr.h src/include/skalibs/env.h src/include/skalibs/envalloc.h src/include/skalibs/genalloc.h
 src/libenvexec/envalloc_uniq.o src/libenvexec/envalloc_uniq.lo: src/libenvexec/envalloc_uniq.c src/include/skalibs/bytestr.h src/include/skalibs/envalloc.h src/include/skalibs/genalloc.h
-src/libenvexec/envdir.o src/libenvexec/envdir.lo: src/libenvexec/envdir.c src/include/skalibs/bytestr.h src/include/skalibs/direntry.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/stralloc.h
+src/libenvexec/envdir.o src/libenvexec/envdir.lo: src/libenvexec/envdir.c src/include/skalibs/env.h src/libenvexec/envdir-internal.h
+src/libenvexec/envdir_clamp.o src/libenvexec/envdir_clamp.lo: src/libenvexec/envdir_clamp.c src/include/skalibs/bytestr.h src/include/skalibs/direntry.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/libenvexec/envdir-internal.h src/include/skalibs/stralloc.h
+src/libenvexec/envdir_noclamp.o src/libenvexec/envdir_noclamp.lo: src/libenvexec/envdir_noclamp.c src/include/skalibs/buffer.h src/include/skalibs/bytestr.h src/include/skalibs/direntry.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/libenvexec/envdir-internal.h src/include/skalibs/skamisc.h src/include/skalibs/stralloc.h
 src/libenvexec/exec0_ae.o src/libenvexec/exec0_ae.lo: src/libenvexec/exec0_ae.c src/include/skalibs/exec.h
 src/libenvexec/exec_ae.o src/libenvexec/exec_ae.lo: src/libenvexec/exec_ae.c src/include/skalibs/config.h src/include/skalibs/exec.h src/include/skalibs/posixplz.h
 src/libenvexec/mexec0_af.o src/libenvexec/mexec0_af.lo: src/libenvexec/mexec0_af.c src/include/skalibs/exec.h
diff --git a/src/include/skalibs/env.h b/src/include/skalibs/env.h
index 73398c2..5e17dfa 100644
--- a/src/include/skalibs/env.h
+++ b/src/include/skalibs/env.h
@@ -24,6 +24,8 @@ extern size_t env_merg (char const **, size_t, char const *const *, char const *
 
 #define SKALIBS_ENVDIR_VERBATIM 0x01
 #define SKALIBS_ENVDIR_NOCHOMP 0x02
+#define SKALIBS_ENVDIR_NOCLAMP 0x04
+
 extern int envdir_internal (char const *, stralloc *, unsigned int, char) ;
 #define envdir(path, sa) envdir_internal(path, (sa), 0, '\n')
 #define envdir_chomp(path, sa) envdir_internal(path, (sa), SKALIBS_ENVDIR_NOCHOMP, '\n')
diff --git a/src/libenvexec/envdir-internal.h b/src/libenvexec/envdir-internal.h
new file mode 100644
index 0000000..7b86b1c
--- /dev/null
+++ b/src/libenvexec/envdir-internal.h
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#ifndef ENVDIR_INTERNAL_H
+#define ENVDIR_INTERNAL_H
+
+#include <skalibs/stralloc.h>
+
+extern int envdir_internal_clamp (char const *, stralloc *, unsigned int, char) ;
+extern int envdir_internal_noclamp (char const *, stralloc *, unsigned int, char) ;
+
+#endif
diff --git a/src/libenvexec/envdir.c b/src/libenvexec/envdir.c
index 6992654..be8867a 100644
--- a/src/libenvexec/envdir.c
+++ b/src/libenvexec/envdir.c
@@ -1,85 +1,13 @@
 /* ISC license. */
 
-#include <unistd.h>
-#include <string.h>
 #include <errno.h>
-#include <skalibs/bytestr.h>
-#include <skalibs/env.h>
-#include <skalibs/direntry.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
 
-#define MAXVARSIZE 4095
+#include <skalibs/env.h>
+#include "envdir-internal.h"
 
 int envdir_internal (char const *path, stralloc *modifs, unsigned int options, char nullis)
 {
-  char buf[MAXVARSIZE + 1] ;
-  unsigned int n = 0 ;
-  size_t pathlen = strlen(path) ;
-  size_t modifbase = modifs->len ;
-  int wasnull = !modifs->s ;
-  DIR *dir ;
-  if (!nullis) return (errno = EINVAL, -1) ;
-  dir = opendir(path) ;
-  if (!dir) return -1 ;
-  for (;;)
-  {
-    direntry *d ;
-    size_t len ;
-    ssize_t r ;
-    errno = 0 ;
-    d = readdir(dir) ;
-    if (!d) break ;
-    if (d->d_name[0] == '.') continue ;
-    len = strlen(d->d_name) ;
-    if (str_chr(d->d_name, '=') < len) continue ;
-    {
-      char tmp[pathlen + len + 2] ;
-      memcpy(tmp, path, pathlen) ;
-      tmp[pathlen] = '/' ;
-      memcpy(tmp + pathlen + 1, d->d_name, len + 1) ;
-      r = openreadnclose(tmp, buf, MAXVARSIZE) ;
-    }
-    if (r < 0)
-    {
-      if (errno == ENOENT) errno = EIDRM ;
-      goto err ;
-    }
-    else if (r > 0)
-    {
-      if (options & SKALIBS_ENVDIR_VERBATIM)
-      {
-        if (!(options & SKALIBS_ENVDIR_NOCHOMP) && (buf[r-1] == '\n')) r-- ;
-      }
-      else
-      {
-        r = byte_chr(buf, r, '\n') ;
-        if (!(options & SKALIBS_ENVDIR_NOCHOMP))
-        {
-          while (r--) if ((buf[r] != ' ') && (buf[r] != '\t') && (buf[r] != '\r')) break ;
-          r++ ;
-        }
-      }
-      {
-        size_t i = 0 ;
-        for (; i < (size_t)r ; i++) if (!buf[i]) buf[i] = nullis ;
-      }
-      buf[r++] = 0 ;
-      if (!env_addmodif(modifs, d->d_name, buf)) goto err ;
-    }
-    else if (!env_addmodif(modifs, d->d_name, 0)) goto err ;
-    n++ ;
-  }
-  if (errno) goto err ;
-  dir_close(dir) ;
-  return n ;
-
- err:
-  {
-    int e = errno ;
-    dir_close(dir) ;
-    if (wasnull) stralloc_free(modifs) ; else modifs->len = modifbase ;
-    errno = e ;
-    return -1 ;
-  }
+  return nullis ? options & SKALIBS_ENVDIR_NOCLAMP ?
+    envdir_internal_noclamp(path, modifs, options & ~SKALIBS_ENVDIR_NOCLAMP, nullis) :
+    envdir_internal_clamp(path, modifs, options, nullis) : (errno = EINVAL, -1) ;
 }
diff --git a/src/libenvexec/envdir_clamp.c b/src/libenvexec/envdir_clamp.c
new file mode 100644
index 0000000..b63ed97
--- /dev/null
+++ b/src/libenvexec/envdir_clamp.c
@@ -0,0 +1,85 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <skalibs/bytestr.h>
+#include <skalibs/env.h>
+#include <skalibs/direntry.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+#include "envdir-internal.h"
+
+#define MAXVARSIZE 4095
+
+int envdir_internal_clamp (char const *path, stralloc *modifs, unsigned int options, char nullis)
+{
+  char buf[MAXVARSIZE + 1] ;
+  unsigned int n = 0 ;
+  size_t pathlen = strlen(path) ;
+  size_t modifbase = modifs->len ;
+  int wasnull = !modifs->s ;
+  DIR *dir = opendir(path) ;
+  if (!dir) return -1 ;
+  for (;;)
+  {
+    direntry *d ;
+    size_t len ;
+    ssize_t r ;
+    errno = 0 ;
+    d = readdir(dir) ;
+    if (!d) break ;
+    if (d->d_name[0] == '.') continue ;
+    len = strlen(d->d_name) ;
+    if (str_chr(d->d_name, '=') < len) continue ;
+    {
+      char tmp[pathlen + len + 2] ;
+      memcpy(tmp, path, pathlen) ;
+      tmp[pathlen] = '/' ;
+      memcpy(tmp + pathlen + 1, d->d_name, len + 1) ;
+      r = openreadnclose(tmp, buf, MAXVARSIZE) ;
+    }
+    if (r < 0)
+    {
+      if (errno == ENOENT) errno = EIDRM ;
+      goto err ;
+    }
+    else if (r > 0)
+    {
+      if (options & SKALIBS_ENVDIR_VERBATIM)
+      {
+        if (!(options & SKALIBS_ENVDIR_NOCHOMP) && (buf[r-1] == '\n')) r-- ;
+      }
+      else
+      {
+        r = byte_chr(buf, r, '\n') ;
+        if (!(options & SKALIBS_ENVDIR_NOCHOMP))
+        {
+          while (r--) if ((buf[r] != ' ') && (buf[r] != '\t') && (buf[r] != '\r')) break ;
+          r++ ;
+        }
+      }
+      {
+        size_t i = 0 ;
+        for (; i < (size_t)r ; i++) if (!buf[i]) buf[i] = nullis ;
+      }
+      buf[r++] = 0 ;
+      if (!env_addmodif(modifs, d->d_name, buf)) goto err ;
+    }
+    else if (!env_addmodif(modifs, d->d_name, 0)) goto err ;
+    n++ ;
+  }
+  if (errno) goto err ;
+  dir_close(dir) ;
+  return n ;
+
+ err:
+  {
+    int e = errno ;
+    dir_close(dir) ;
+    if (wasnull) stralloc_free(modifs) ; else modifs->len = modifbase ;
+    errno = e ;
+    return -1 ;
+  }
+}
diff --git a/src/libenvexec/envdir_noclamp.c b/src/libenvexec/envdir_noclamp.c
new file mode 100644
index 0000000..b87291a
--- /dev/null
+++ b/src/libenvexec/envdir_noclamp.c
@@ -0,0 +1,103 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <skalibs/bytestr.h>
+#include <skalibs/buffer.h>
+#include <skalibs/env.h>
+#include <skalibs/direntry.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/skamisc.h>
+#include "envdir-internal.h"
+
+#define N 4096
+
+int envdir_internal_noclamp (char const *path, stralloc *modifs, unsigned int options, char nullis)
+{
+  unsigned int n = 0 ;
+  size_t pathlen = strlen(path) ;
+  size_t modifbase = modifs->len ;
+  int wasnull = !modifs->s ;
+  int fd ;
+  DIR *dir = opendir(path) ;
+  if (!dir) return -1 ;
+  for (;;)
+  {
+    direntry *d ;
+    size_t len, pos ;
+    errno = 0 ;
+    d = readdir(dir) ;
+    if (!d) break ;
+    if (d->d_name[0] == '.') continue ;
+    len = strlen(d->d_name) ;
+    if (str_chr(d->d_name, '=') < len) continue ;
+    {
+      char tmp[pathlen + len + 2] ;
+      memcpy(tmp, path, pathlen) ;
+      tmp[pathlen] = '/' ;
+      memcpy(tmp + pathlen + 1, d->d_name, len + 1) ;
+      fd = openc_readb(tmp) ;
+    }
+    if (fd < 0)
+    {
+      if (errno == ENOENT) errno = EIDRM ;
+      goto err ;
+    }
+    if (!stralloc_catb(modifs, d->d_name, len) || !stralloc_catb(modifs, "=", 1)) goto errfd ;
+    pos = modifs->len ;
+    if (options & SKALIBS_ENVDIR_VERBATIM)
+    {
+      if (!slurp(modifs, fd)) goto errfd ;
+      if (modifs->len == pos) modifs->len = pos - 1 ;
+      if (!(options & SKALIBS_ENVDIR_NOCHOMP) && (modifs->s[modifs->len - 1] == '\n')) modifs->len-- ;
+    }
+    else
+    {
+      int r ;
+      char buf[N] ;
+      buffer b = BUFFER_INIT(&buffer_read, fd, buf, N) ;
+      r = skagetln(&b, modifs, '\n') ;
+      if (r == -1)
+      {
+        if (errno != EPIPE) goto errfd ;
+        if (!(options & SKALIBS_ENVDIR_NOCHOMP)) modifs->len = pos ;
+        if (!stralloc_catb(modifs, "\n", 1)) goto errfd ;
+      }
+      if (!r) modifs->len = pos - 1 ;
+      else
+      {
+        size_t i = pos ;
+        if (!(options & SKALIBS_ENVDIR_NOCHOMP))
+        {
+          while (modifs->len-- > pos)
+          {
+            char c = modifs->s[modifs->len] ;
+            if ((c != ' ') && (c != '\t') && (c != '\r')) break ;
+          }
+          modifs->len++ ;
+          for (; i < modifs->len ; i++) if (!modifs->s[i]) modifs->s[i] = nullis ;
+        }
+      }
+    }
+    fd_close(fd) ;
+    if (!stralloc_0(modifs)) goto err ;
+    n++ ;
+  }
+  if (errno) goto err ;
+  dir_close(dir) ;
+  return n ;
+
+ errfd:
+  fd_close(fd) ;
+ err:
+  {
+    int e = errno ;
+    dir_close(dir) ;
+    if (wasnull) stralloc_free(modifs) ; else modifs->len = modifbase ;
+    errno = e ;
+    return -1 ;
+  }
+}