summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2019-02-12 15:10:40 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2019-02-12 15:10:40 +0000
commit3d9f4c786ee1bce0ded8871f405b11e7eb62df13 (patch)
treecd14d8f88b78024485f5037b84c19b992faf0455
parent2672d89224931b8c3b9b7bf9c67fcfd962d74cbd (diff)
downloadexecline-3d9f4c786ee1bce0ded8871f405b11e7eb62df13.tar.gz
execline-3d9f4c786ee1bce0ded8871f405b11e7eb62df13.tar.xz
execline-3d9f4c786ee1bce0ded8871f405b11e7eb62df13.zip
Add envfile; prepare for 2.5.1.0
-rw-r--r--COPYING2
-rw-r--r--INSTALL2
-rw-r--r--NEWS7
-rw-r--r--doc/envfile.html95
-rw-r--r--doc/index.html5
-rw-r--r--doc/upgrade.html7
-rw-r--r--package/deps.mak3
-rw-r--r--package/info2
-rw-r--r--package/modes1
-rw-r--r--package/targets.mak1
-rw-r--r--src/execline/deps-exe/envfile1
-rw-r--r--src/execline/envfile.c93
12 files changed, 214 insertions, 5 deletions
diff --git a/COPYING b/COPYING
index 1629e84..f019bc7 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2018 Laurent Bercot <ska-skaware@skarnet.org>
+Copyright (c) 2011-2019 Laurent Bercot <ska-skaware@skarnet.org>
 
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
diff --git a/INSTALL b/INSTALL
index 206a376..f2d9caa 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,7 +6,7 @@ Build Instructions
 
   - A POSIX-compliant C development environment
   - GNU make version 3.81 or later
-  - skalibs version 2.7.0.0 or later: http://skarnet.org/software/skalibs/
+  - skalibs version 2.8.0.0 or later: http://skarnet.org/software/skalibs/
 
  This software will run on any operating system that implements
 POSIX.1-2008, available at:
diff --git a/NEWS b/NEWS
index 42c8dff..17647c5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
 Changelog for execline.
 
+In 2.5.1.0
+----------
+
+ - Bugfixes.
+ - New command: envfile.
+
+
 In 2.5.0.1
 ----------
 
diff --git a/doc/envfile.html b/doc/envfile.html
new file mode 100644
index 0000000..49b88f9
--- /dev/null
+++ b/doc/envfile.html
@@ -0,0 +1,95 @@
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the envfile program</title>
+    <meta name="Description" content="execline: the envfile program" />
+    <meta name="Keywords" content="execline command envfile environment file shell envdir s6-envdir env" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">execline</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>envfile</tt> program </h1>
+
+<p>
+<tt>envfile</tt> reads a file containing variable assignments,
+adds the variables to the environment, then executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     envfile <em>file</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>envfile</tt> reads <em>file</em> and adds the key-value pairs
+defined in <em>file</em> to the environment. Then it
+execs into <em>prog...</em>, i.e. the rest of its command line,
+with the modified environment.
+</p>
+
+<h2> Exit codes </h2>
+
+<ul>
+ <li> 1:&nbsp;syntax error in <em>file</em> </li>
+ <li> 100:&nbsp;wrong usage </li>
+ <li> 111:&nbsp;system call failed </li>
+ <li> 126:&nbsp;execve() on <em>prog</em> failed (unknown reason) </li>
+ <li> 127:&nbsp;execve() on <em>prog</em> failed (<em>prog</em> could not be found) </li>
+</ul>
+
+<p>
+ 0 is not listed because on success, <tt>envfile</tt> does not exit:
+it execs into <em>prog</em>.
+</p>
+
+<h2> File syntax </h2>
+
+<p>
+ <em>file</em> is a text file containing lines of the form <tt>key = value</tt>.
+Whitespace is permitted before and after <em>key</em>, and before or after <em>value</em>,
+but <em>key</em> or <em>value</em> can never contain whitespace. No quoting
+is possible.
+</p>
+
+<p>
+ Empty lines, or lines containing only whitespace, are ignored.
+Lines beginning with <tt>#</tt> (possibly after some whitespace)
+are ignored (and typically used for comments).
+Comments are also possible at the end of lines:
+<tt>key = value # comment</tt> is a valid line. Note that there
+<em>must</em> be whitespace between <em>value</em> and <tt>#</tt>
+in this case (else <tt>#</tt> is just read as a part of <em>value</em>).
+</p>
+
+<p>
+ If <em>value</em> is empty, <em>key</em> is <strong>still</strong>
+added to the environment, with an empty value. If you do not want
+<em>key</em> to be added to the environment at all, comment out the line.
+<tt>envfile</tt> does not offer a way to <em>remove</em> variables from
+the environment.
+</p>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> If <em>file</em> is <tt>-</tt> then <tt>envfile</tt> reads
+and parses its standard input instead. To read a file literally named
+<tt>-</tt>, you can use <tt>./-</tt> for instance. </li>
+ <li> <tt>The variables and values that can be defined with <tt>envfile</tt>
+are purposefully restricted in order to keep the parsing extremely simple.
+If you need fancy values, for instance values that contain whitespace or
+a newline, you should use an envdir instead: see
+<a href="//skarnet.org/software/s6/s6-envdir.html">s6-envdir</a>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/index.html b/doc/index.html
index 9a68d5f..3efad3a 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -51,7 +51,7 @@ shell's syntax, and has no security issues.
  <li> A POSIX-compliant system with a standard C development environment </li>
  <li> GNU make, version 3.81 or later. </li>
  <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> version
-2.7.0.0 or later. It's a build-time requirement. It's also a run-time
+2.8.0.0 or later. It's a build-time requirement. It's also a run-time
 requirement if you link against the shared version of the skalibs
 library. </li>
 </ul>
@@ -66,7 +66,7 @@ library. </li>
 <h3> Download </h3>
 
 <ul>
- <li> The current released version of execline is <a href="execline-2.5.0.1.tar.gz">2.5.0.1</a>. </li>
+ <li> The current released version of execline is <a href="execline-2.5.1.0.tar.gz">2.5.1.0</a>. </li>
  <li> Alternatively, you can checkout a copy of the
 <a href="//git.skarnet.org/cgi-bin/cgit.cgi/execline/">execline
 git repository</a>:
@@ -128,6 +128,7 @@ to your installation: the shebang lines for your system might be something like
 <li><a href="cd.html">The <tt>cd</tt> program</a></li>
 <li><a href="umask.html">The <tt>umask</tt> program</a></li>
 <li><a href="emptyenv.html">The <tt>emptyenv</tt> program</a></li>
+<li><a href="envfile.html">The <tt>envfile</tt> program</a></li>
 <li><a href="export.html">The <tt>export</tt> program</a></li>
 <li><a href="unexport.html">The <tt>unexport</tt> program</a></li>
 <li><a href="fdclose.html">The <tt>fdclose</tt> program</a></li>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 5eed0d8..80c5dea 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,6 +18,13 @@
 
 <h1> What has changed in execline </h1>
 
+<h2> in 2.5.1.0 </h2>
+
+<ul>
+ <li> skalibs dependency bumped to 2.8.0.0 </li>
+ <li> New command: <a href="envfile.html">envfile</a>. </li>
+</ul>
+
 <h2> in 2.5.0.1 </h2>
 
 <ul>
diff --git a/package/deps.mak b/package/deps.mak
index db14ec6..e058e9f 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -11,6 +11,7 @@ src/execline/elgetopt.o src/execline/elgetopt.lo: src/execline/elgetopt.c src/in
 src/execline/elgetpositionals.o src/execline/elgetpositionals.lo: src/execline/elgetpositionals.c src/include-local/exlsn.h
 src/execline/elglob.o src/execline/elglob.lo: src/execline/elglob.c src/include-local/exlsn.h
 src/execline/emptyenv.o src/execline/emptyenv.lo: src/execline/emptyenv.c src/include/execline/execline.h
+src/execline/envfile.o src/execline/envfile.lo: src/execline/envfile.c
 src/execline/exec.o src/execline/exec.lo: src/execline/exec.c
 src/execline/execlineb.o src/execline/execlineb.lo: src/execline/execlineb.c src/include/execline/execline.h src/include-local/exlsn.h
 src/execline/exit.o src/execline/exit.lo: src/execline/exit.c
@@ -89,6 +90,8 @@ elglob: EXTRA_LIBS :=
 elglob: src/execline/elglob.o ${LIBEXECLINE} -lskarnet
 emptyenv: EXTRA_LIBS :=
 emptyenv: src/execline/emptyenv.o ${LIBEXECLINE} -lskarnet
+envfile: EXTRA_LIBS :=
+envfile: src/execline/envfile.o -lskarnet
 exec: EXTRA_LIBS :=
 exec: src/execline/exec.o -lskarnet
 execlineb: EXTRA_LIBS :=
diff --git a/package/info b/package/info
index 7325953..e66a0ee 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
 package=execline
-version=2.5.0.1
+version=2.5.1.0
 category=admin
 package_macro_name=EXECLINE
diff --git a/package/modes b/package/modes
index 76ae052..7852d06 100644
--- a/package/modes
+++ b/package/modes
@@ -9,6 +9,7 @@ elglob			0755
 multidefine		0755
 multisubstitute		0755
 emptyenv		0755
+envfile			0755
 exec			0755
 exit			0755
 execlineb		0755
diff --git a/package/targets.mak b/package/targets.mak
index 678393f..c076fa3 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -8,6 +8,7 @@ elgetopt \
 elgetpositionals \
 elglob \
 emptyenv \
+envfile \
 exec \
 execlineb \
 exit \
diff --git a/src/execline/deps-exe/envfile b/src/execline/deps-exe/envfile
new file mode 100644
index 0000000..e7187fe
--- /dev/null
+++ b/src/execline/deps-exe/envfile
@@ -0,0 +1 @@
+-lskarnet
diff --git a/src/execline/envfile.c b/src/execline/envfile.c
new file mode 100644
index 0000000..638b182
--- /dev/null
+++ b/src/execline/envfile.c
@@ -0,0 +1,93 @@
+/* ISC license. */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <skalibs/types.h>
+#include <skalibs/buffer.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/env.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#define USAGE "envfile file prog..."
+#define dieusage() strerr_dieusage(100, USAGE)
+#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
+
+static inline uint8_t cclass (char c)
+{
+  switch (c)
+  {
+    case 0 : return 0 ;
+    case '#' : return 1 ;
+    case '\n' : return 2 ;
+    case '=' : return 3 ;
+    case ' ' :
+    case '\t' :
+    case '\f' :
+    case '\r' : return 4 ;
+    default : return 5 ;
+  }
+}
+
+static inline char next (char const *file, buffer *b)
+{
+  char c ;
+  ssize_t r = buffer_get(b, &c, 1) ;
+  if (r < 0) strerr_diefu2sys(111, "read from ", file) ;
+  if (!r) c = 0 ;
+  return c ;
+}
+
+static inline void parse_config (char const *file, buffer *b, stralloc *modif)
+{
+  static uint8_t const table[7][6] =
+  {
+    { 0x07, 0x01, 0x80, 0x08, 0x00, 0x22 },
+    { 0x07, 0x01, 0x80, 0x01, 0x01, 0x01 },
+    { 0x08, 0x08, 0x08, 0x24, 0x03, 0x22 },
+    { 0x08, 0x08, 0x08, 0x24, 0x03, 0x08 },
+    { 0x47, 0x41, 0xc0, 0x25, 0x04, 0x25 },
+    { 0x47, 0x41, 0xc0, 0x25, 0x46, 0x25 },
+    { 0x07, 0x01, 0x80, 0x08, 0x06, 0x08 }
+  } ;
+  unsigned int line = 1 ;
+  uint8_t state = 0 ;
+  while (state < 7)
+  {
+    char c = next(file, b) ;
+    uint8_t what = table[state][cclass(c)] ;
+    state = what & 0x0f ;
+    if (what & 0x20)
+      if (!stralloc_catb(modif, &c, 1)) dienomem() ;
+    if (what & 0x40)
+      if (!stralloc_0(modif)) dienomem() ;
+    if (what & 0x80) line++ ;
+  }
+  if (state > 7)
+  {
+    char fmt[UINT_FMT] ;
+    fmt[uint_fmt(fmt, line)] = 0 ;
+    strerr_dief4x(1, "syntax error line ", fmt, " while parsing ", file) ;
+  }
+}
+
+int main (int argc, char const *const *argv, char const *const *envp)
+{
+  stralloc modif = STRALLOC_ZERO ;
+  PROG = "envfile" ;
+  if (argc < 3) dieusage() ;
+  if (!strcmp(argv[1], "-"))
+    parse_config("standard input", buffer_0, &modif) ;
+  else
+  {
+    buffer b ;
+    char buf[BUFFER_INSIZE] ;
+    int fd = open_readb(argv[1]) ;
+    if (fd == -1) strerr_diefu2sys(111, "open ", argv[1]) ;
+    buffer_init(&b, &buffer_read, fd, buf, BUFFER_INSIZE) ;
+    parse_config(argv[1], &b, &modif) ;
+    fd_close(fd) ;
+  }
+  xpathexec_r(argv + 2, envp, env_len(envp), modif.s, modif.len) ;
+}