diff options
| author | Sam Varshavchik | 2017-07-23 23:16:48 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2017-07-23 23:16:48 -0400 | 
| commit | 4238d38f75d45793521a3b49ba421413d2b53a21 (patch) | |
| tree | 241d230890014f5e69ae4738cdf0f520dafc1992 | |
| parent | de2a130974e1a76daa1893e18442154c7fc90321 (diff) | |
| download | courier-libs-4238d38f75d45793521a3b49ba421413d2b53a21.tar.bz2 | |
maildrop: add the "system" command.
| -rw-r--r-- | maildrop/filter.C | 63 | ||||
| -rw-r--r-- | maildrop/funcs.h | 1 | ||||
| -rw-r--r-- | maildrop/lexer.C | 3 | ||||
| -rw-r--r-- | maildrop/maildrop.sgml | 13 | ||||
| -rw-r--r-- | maildrop/maildropfilter.sgml | 26 | ||||
| -rw-r--r-- | maildrop/recipenode.C | 13 | ||||
| -rw-r--r-- | maildrop/recipenode.h | 1 | ||||
| -rw-r--r-- | maildrop/recipeparse.C | 8 | ||||
| -rw-r--r-- | maildrop/token.C | 1 | ||||
| -rw-r--r-- | maildrop/token.h | 1 | 
10 files changed, 125 insertions, 5 deletions
| diff --git a/maildrop/filter.C b/maildrop/filter.C index d59e2ec..abc3872 100644 --- a/maildrop/filter.C +++ b/maildrop/filter.C @@ -100,7 +100,7 @@ pid_t	pid=fork();  		{  			if (write(2, p, strlen(p)) < 0 ||  			    write(2, "\n", 1) < 0) -				; /* ignore */  +				; /* ignore */  			_exit(100);  		}  #if NEED_NONCONST_EXCEPTIONS @@ -273,3 +273,64 @@ int	wait_stat;  		return (-1);  	return (0);  } + +void executesystem(const char *cmd) +{ +	int devnull=open("/dev/null", O_RDONLY); +	pid_t	pid; + +	if (devnull < 0) +		throw "Cannot open /dev/null"; + +	pid=fork(); +	if (pid < 0) +	{ +		close(devnull); +		throw "Cannot fork."; +	} + +	if (pid == 0) +	{ +		try +		{ +			dup2(devnull, 0); +			close(devnull); +			subshell(cmd); +		} +		catch (const char *p) +		{ +			if (write(2, p, strlen(p)) < 0 || +			    write(2, "\n", 1) < 0) +				; /* ignore */ +			_exit(100); +		} +#if NEED_NONCONST_EXCEPTIONS +		catch (char *p) +		{ +			if (write(2, p, strlen(p)) < 0 || +			    write(2, "\n", 1) < 0) +				; /* ignore */ +			_exit(100); +		} +#endif +		catch (...) +		{ +			_exit(101); +		} +	} +	close(devnull); + +int	wait_stat; + +	while (wait(&wait_stat) != pid) +		; +	wait_stat= WIFEXITED(wait_stat) ? WEXITSTATUS(wait_stat):-1; + +	{ +	Buffer	name, val; + +		val.append( (unsigned long)wait_stat); +		name="RETURNCODE"; +		SetVar(name, val); +	} +} diff --git a/maildrop/funcs.h b/maildrop/funcs.h index 3ac3a5e..ad17bac 100644 --- a/maildrop/funcs.h +++ b/maildrop/funcs.h @@ -20,6 +20,7 @@ extern int verbose_level;  const char *GetDefaultMailbox(const char *);  int	delivery(const char *);  int	filter(const char *); +void	executesystem(const char *);  void	subshell(const char *);  const char *TempName();	// Return temporary filename  const char *TempName(const char *, unsigned=0);	// ... with this prefix. diff --git a/maildrop/lexer.C b/maildrop/lexer.C index 99732dd..65e019a 100644 --- a/maildrop/lexer.C +++ b/maildrop/lexer.C @@ -41,6 +41,7 @@ void	Lexer::token(Token &t)  		case Token::tokencc:  		case Token::btstring:  		case Token::tokenxfilter: +		case Token::tokensystem:  		case Token::dotlock:  		case Token::flock:  		case Token::logfile: @@ -346,6 +347,8 @@ missquote:  			t.Type(Token::echo);  		else if (pattern == "xfilter")  			t.Type(Token::tokenxfilter); +		else if (pattern == "system") +			t.Type(Token::tokensystem);  		else if (pattern == "dotlock")  			t.Type(Token::dotlock);  		else if (pattern == "flock") diff --git a/maildrop/maildrop.sgml b/maildrop/maildrop.sgml index b476d71..ca5beba 100644 --- a/maildrop/maildrop.sgml +++ b/maildrop/maildrop.sgml @@ -620,6 +620,13 @@ The <command>logfile</command> command is not allowed in embedded mode.</para>  	  </listitem>  	</varlistentry>  	<varlistentry> +	  <term><ulink url="maildropfilter.html#system">system</ulink></term> +	  <listitem> +<para> +The <command>system</command> command is not allowed in embedded mode.</para> +	  </listitem> +	</varlistentry> +	<varlistentry>  	  <term><ulink url="maildropfilter.html#to">to</ulink></term>  	  <listitem>  <para> @@ -663,8 +670,10 @@ suspended for any additional filter files that are included from        <para>  This allows the system administrator to have a controlled environment for -running external commands (via the backticks, or the -<ulink url="maildropfilter.html#xfilter">xfilter</ulink> command).</para> +running external commands (via the backticks, the +<ulink url="maildropfilter.html#system">system</ulink> +or the +<ulink url="maildropfilter.html#xfilter">xfilter</ulink> commands).</para>        <para>  The name of the file may not contain any periods (so that a creative diff --git a/maildrop/maildropfilter.sgml b/maildrop/maildropfilter.sgml index 4d91abc..c97aeec 100644 --- a/maildrop/maildropfilter.sgml +++ b/maildrop/maildropfilter.sgml @@ -511,7 +511,9 @@ MAILBOX="${HOME-WORD}/Mailbox"  	</para></listitem></varlistentry>  	<varlistentry><term><varname>RETURNCODE</varname></term><listitem><para>This variable is set when <command>maildrop</command> -	      runs the <ulink url="#xfilter">xfilter</ulink> command, or a command that's +	      runs the +	      <ulink url="#system">system</ulink> command, +	      <ulink url="#xfilter">xfilter</ulink> command, or a command that's  	      specified within a pair of backtick characters ( command substitution ).  	      The <varname>RETURNCODE</varname> variable will be set to the exit code of the  	      command, after it completes. @@ -1485,6 +1487,28 @@ log <replaceable>expression</replaceable>        </refsect3>        <refsect3> +	<title>system - execute a system command</title> +	<anchor id="system"/> + +	<blockquote> +	  <informalexample> +	    <programlisting> +system <replaceable>expression</replaceable> +	    </programlisting> +	  </informalexample> +	</blockquote> + +	<para> +	  <replaceable>expression</replaceable> specifies an external program +	  that +	  <command>maildrop</command> runs as a subprocess. +	  The subprocess's standard input gets connected to +	  <filename>/dev/null</filename>, and the subprocess inherits +	  the standard output and error from +	   <command>maildrop</command>.</para> +      </refsect3> + +      <refsect3>  	<title>to - deliver message to a mailbox</title>  	<anchor id="to"/>  	<blockquote> diff --git a/maildrop/recipenode.C b/maildrop/recipenode.C index c69c017..031eec0 100644 --- a/maildrop/recipenode.C +++ b/maildrop/recipenode.C @@ -496,7 +496,7 @@ RecipeNode	*c;  				debug += '\0';  				r.errmsg(*this, debug);  			} -	 +  		long l=bb.Length();  			if (n < 0 || n > l)	n=l; @@ -622,6 +622,17 @@ RecipeNode	*c;  			throw "Unable to filter message.";  		b = "0";  		break; +	case system: +		if (!firstChild) +			throw "Internal error in system statement."; +		firstChild->Evaluate(r,b); +		b += '\0'; +		if (VerboseLevel() > 0) +			merr << "maildrop: Executing system command " << +				(const char *)b << "\n"; +		executesystem(b); +		b = "0"; +		break;  	case exception:  		if (!firstChild)  			throw "Internal error in delivery statement."; diff --git a/maildrop/recipenode.h b/maildrop/recipenode.h index cff0a7a..4a76a42 100644 --- a/maildrop/recipenode.h +++ b/maildrop/recipenode.h @@ -97,6 +97,7 @@ public:  		exception,  		echo,  		xfilter, +		system,  		dotlock,  		flock,  		logfile, diff --git a/maildrop/recipeparse.C b/maildrop/recipeparse.C index f43cc1b..6a83042 100644 --- a/maildrop/recipeparse.C +++ b/maildrop/recipeparse.C @@ -173,6 +173,14 @@ RecipeNode *n, *o;  			throw "Syntax error.";  		lex->token(cur_tok);  		return (n); +	case Token::tokensystem: +		lex->token(cur_tok); +		n=alloc(RecipeNode::system); +		n->AppendSibling( ParseExpr()); +		if (cur_tok.Type() != Token::semicolon) +			throw "Syntax error."; +		lex->token(cur_tok); +		return (n);  	case Token::dotlock:  		lex->token(cur_tok);  		n=alloc(RecipeNode::dotlock); diff --git a/maildrop/token.C b/maildrop/token.C index c6ab42d..59ca3e0 100644 --- a/maildrop/token.C +++ b/maildrop/token.C @@ -50,6 +50,7 @@ static const char *names[]={  		"exception",  		"echo",  		"xfilter", +		"system",  		"dotlock",  		"flock",  		"logfile", diff --git a/maildrop/token.h b/maildrop/token.h index 0a97471..f2829b1 100644 --- a/maildrop/token.h +++ b/maildrop/token.h @@ -65,6 +65,7 @@ public:  		exception,  		echo,  		tokenxfilter, +		tokensystem,  		dotlock,  		flock,  		logfile, | 
