From 99d44f1b4892f86714a9eff18eee5267be56df7c Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Fri, 21 Jun 2019 16:51:25 +1100 Subject: [PATCH] pass to oblibs library --- doc/execl-envfile.html | 19 ++++---- src/extra-tools/execl-envfile.c | 77 +++++++++++++++++++++++++++------ 2 files changed, 75 insertions(+), 21 deletions(-) diff --git a/doc/execl-envfile.html b/doc/execl-envfile.html index bab78488..f520de6d 100644 --- a/doc/execl-envfile.html +++ b/doc/execl-envfile.html @@ -25,11 +25,11 @@ <h2> Interface </h2> <pre> - execl-envfile [ -h ] [ -f <em>file</em> ] [ -l ] <em>dir</em> <em>prog</em> + execl-envfile [ -h ] [ -l ] <em>src</em> <em>prog</em> </pre> <p> - This tool expects to find a regular file(s) in <em>dir</em> containing one or multiple <tt>key=value</tt> pair. For each files found: it will parse the file, import the <tt>key=value</tt> then execs <em>prog</em> with the modified environment. + This tool expects to find a regular file(s) or directory as <em>src</em> containing one or multiple <tt>key=value</tt> pair. For each files found: it will parse the file, import the <tt>key=value</tt> then execs <em>prog</em> with the modified environment. </p> <ul> <li>It opens and reads the file.</li> @@ -39,21 +39,22 @@ <li>It unexports the variable if requested.</li> <li>It execs <em>prog</em> with the modified environment.</li> </ul> + <p>In case as <em>src</em> is a directory, the same processus is made for each files found in <em>src</em>. <em>src</em> can be absolute or relative path. In case of relative path only <tt>'../'</tt>,<tt>'./'</tt>, <tt>'.'</tt> or <tt>'..'</tt> are accepted as valid format.</p> <h2> Options </h2> <ul> <li> <tt>-h </tt> : prints this help. </li> <li> - <tt>-f <em>file</em> </tt> : only parses the <em>file</em> found in <em>dir</em>. + <tt>-f <em>file</em> </tt> : only parses the <em>file</em> found in <em>src</em>.<strong>deprecated</strong> </li> <li> - <tt>-l </tt> : loose. does nothing and executes <em>prog</em> directly if <em>dir</em> does not contain any regular file(s) or <em>dir</em> doesn't exist. + <tt>-l </tt> : loose. does nothing and executes <em>prog</em> directly if <em>src</em> does not contain any regular file(s) or <em>src</em> doesn't exist. </li> </ul> -<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>, +<h2> <em>File</em> 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>, Quoting is also possible. In this case, the quoting field is treated as one word. </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 <strong>not</strong> possible at the end of lines: @@ -61,11 +62,13 @@ </p> <p>Empty <em>value</em> is <strong>not</strong> permitted.</p> <p>If <tt>key</tt> begin by a <tt>'!'</tt> character: <tt>!key=value</tt> the <tt>key</tt> will be removed from the environment after the substitution.</p> + <p>If the same <tt>key=value</tt> pair is found multiple time, only the first one definition is keepts.</p> + <p>It must be terminated by an <strong>empty new line</strong>.</p> <h2> Example of use </h2> <pre> #!/usr/bin/execlineb -P fdmove -c 2 1 - execl-envfile -f ntpd /etc/66/conf/ + execl-envfile /etc/66/conf/ntpd foreground { mkdir -p -m 0755 ${RUNDIR} } execl-cmdline -s { ntpd ${CMD_ARGS} } </pre> @@ -82,6 +85,6 @@ </pre> <p>where <tt>/etc/66/conf</tt> directory contains two named files <tt>RUNDIR</tt> and <tt>CMD_ARGS</tt> written with <tt>/run/openntpd</tt> and <tt>-d -s</tt> respectively.</p> <h2> limits</h2> -<p><em>dir</em> cannot exceed more than 100 files. Each file cannot contain more than 4095 bytes or more than 50 <em>key=value</em> pairs.</p> +<p><em>src</em> cannot exceed more than 100 files. Each file cannot contain more than 4095 bytes or more than 50 <em>key=value</em> pairs.</p> </body> </html> diff --git a/src/extra-tools/execl-envfile.c b/src/extra-tools/execl-envfile.c index ea6ec4a7..f9f4b499 100644 --- a/src/extra-tools/execl-envfile.c +++ b/src/extra-tools/execl-envfile.c @@ -15,10 +15,12 @@ #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> +#include <stdio.h> #include <oblibs/string.h> #include <oblibs/stralist.h> #include <oblibs/error2.h> +#include <oblibs/types.h> #include <oblibs/obgetopt.h> #include <oblibs/directory.h> #include <oblibs/files.h> @@ -37,20 +39,19 @@ #include <66/parser.h> #include <66/environ.h> -unsigned int VERBOSITY = 1 ; static stralloc SAENV = STRALLOC_ZERO ; static genalloc GAENV = GENALLOC_ZERO ; //diuint32, pos in senv -#define USAGE "execl-envfile [ -h help ] [ -f file ] [ -l ] dir prog" +#define USAGE "execl-envfile [ -h help ] [ -l ] src prog" static inline void info_help (void) { static char const *help = -"execl-envfile <options> dir prog\n" +"execl-envfile <options> src prog\n" "\n" "options :\n" " -h: print this help\n" -" -f: file to parse\n" +" -f: file to parse(deprecated)\n" " -l: loose\n" ; @@ -58,14 +59,24 @@ static inline void info_help (void) strerr_diefu1sys(111, "write to stdout") ; } +int loop_stra(stralloc *sa,char const *search) +{ + size_t i = 0, len = sa->len ; + for (;i < len; i += strlen(sa->s + i) + 1) + if (!strcmp(sa->s+i,search)) return 1 ; + + return 0 ; +} + int main (int argc, char const *const *argv, char const *const *envp) { - int r, i, one, unexport ; + int r, i, unexport ; int insist = 1 ; - + size_t pathlen ; char const *path = 0 ; char const *file = 0 ; - + char tpath[MAXENV + 1] ; + char tfile[MAXENV+1] ; stralloc src = STRALLOC_ZERO ; stralloc modifs = STRALLOC_ZERO ; stralloc dst = STRALLOC_ZERO ; @@ -73,7 +84,7 @@ int main (int argc, char const *const *argv, char const *const *envp) exlsn_t info = EXLSN_ZERO ; - r = i = one = unexport = 0 ; + r = i = unexport = 0 ; insist = 1 ; PROG = "execl-envfile" ; @@ -88,7 +99,7 @@ int main (int argc, char const *const *argv, char const *const *envp) switch (opt) { case 'h' : info_help(); return 0 ; - case 'f' : file = l.arg ; one = 1 ; break ; + case 'f' : file = l.arg ; break ; case 'l' : insist = 0 ; break ; default : exitusage(USAGE) ; } @@ -101,7 +112,44 @@ int main (int argc, char const *const *argv, char const *const *envp) path = *argv ; argv++; argc--; - if (path[0] != '/') strerr_dief3x(111,"directory: ",path," must be an absolute path") ; + + /** Mark -f as deprecated */ + if (file) + { + strerr_warnw1x("-f options is deprecated") ; + if (path[0] != '/') strerr_dief3x(111,"path of: ",path,": must be absolute") ; + } + else + { + r = scan_mode(path,S_IFREG) ; + if (!r) strerr_diefu2sys(111,"find: ",path) ; + if (r < 0) + { + r = scan_mode(path,S_IFDIR) ; + if (!r) strerr_diefu2sys(111,"find: ",path) ; + if (r < 0) strerr_dief2x(111,"invalid format of: ", path) ; + if (path[0] == '.') + { + if (!dir_beabsolute(tpath,path)) + strerr_diefu2sys(111,"find absolute path of: ",path) ; + } + else if (path[0] != '/') strerr_dief3x(111,"path of: ",path,": must be absolute") ; + else + { + pathlen = strlen(path) ; + memcpy(tpath,path,pathlen); + tpath[pathlen] = 0 ; + } + path = tpath ; + } + else + { + if (!basename(tfile,path)) strerr_diefu2x(111,"get file name of: ",path) ; + file = tfile ; + if (!dirname(tpath,path)) strerr_diefu2x(111,"get parent path of: ",path) ; + path = tpath ; + } + } r = dir_get(&toparse,path,"",S_IFREG) ; if (!r && insist) strerr_diefu2sys(111,"get file from: ",path) ; @@ -110,7 +158,7 @@ int main (int argc, char const *const *argv, char const *const *envp) xpathexec_run(argv[0],argv,envp) ; } - if (one) + if (file) { r = stra_findidx(&toparse,file) ; if (r < 0) @@ -130,10 +178,12 @@ int main (int argc, char const *const *argv, char const *const *envp) for (i = 0 ; i < genalloc_len(stralist,&toparse) ; i++) { src.len = 0 ; + size_t n = i + MAXVAR ; if (i > MAXFILE) strerr_dief2x(111,"to many file to parse in: ",path) ; if (!file_readputsa(&src,path,gaistr(&toparse,i))) strerr_diefu4sys(111,"read file: ",path,"/",gaistr(&toparse,i)) ; if (!env_parsenclean(&modifs,&src)) strerr_diefu4x(111,"parse and clean environment of: ",path,"/",gaistr(&toparse,i)) ; if (!env_split(&GAENV,&SAENV,&src)) strerr_diefu4x(111,"split environment of: ",path,"/",gaistr(&toparse,i)) ; + if (genalloc_len(stralist,&toparse) > n) strerr_dief4x(111,"to many variables in file: ",path,"/",gaistr(&toparse,i)) ; } } genalloc_deepfree(stralist,&toparse,stra_free) ; @@ -151,7 +201,6 @@ int main (int argc, char const *const *argv, char const *const *envp) for (i = 0 ; i < genalloc_len(diuint32,&GAENV) ; i++) { - if (i > MAXVAR) strerr_dief1x(111,"to many variables") ; unexport = 0 ; int key = genalloc_s(diuint32,&GAENV)[i].left ; int val = genalloc_s(diuint32,&GAENV)[i].right ; @@ -160,7 +209,9 @@ int main (int argc, char const *const *argv, char const *const *envp) key++ ; unexport = 1 ; } - if (!env_substitute(SAENV.s + key,SAENV.s + val,&info,newenv,unexport)) strerr_diefu4x(111,"substitute value of: ",SAENV.s + key," by: ",SAENV.s + val) ; + if(!loop_stra(&info.vars,SAENV.s + key)) + if (!env_substitute(SAENV.s + key,SAENV.s + val,&info,newenv,unexport)) + strerr_diefu4x(111,"substitute value of: ",SAENV.s + key," by: ",SAENV.s + val) ; } genalloc_free(diuint32,&GAENV) ; stralloc_free(&SAENV) ; -- GitLab