diff options
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | doc/envfile.html | 95 | ||||
-rw-r--r-- | doc/index.html | 5 | ||||
-rw-r--r-- | doc/upgrade.html | 7 | ||||
-rw-r--r-- | package/deps.mak | 3 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | package/modes | 1 | ||||
-rw-r--r-- | package/targets.mak | 1 | ||||
-rw-r--r-- | src/execline/deps-exe/envfile | 1 | ||||
-rw-r--r-- | src/execline/envfile.c | 93 |
12 files changed, 214 insertions, 5 deletions
@@ -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 @@ -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: @@ -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: syntax error in <em>file</em> </li> + <li> 100: wrong usage </li> + <li> 111: system call failed </li> + <li> 126: execve() on <em>prog</em> failed (unknown reason) </li> + <li> 127: 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) ; +} |