diff options
-rw-r--r-- | NEWS | 10 | ||||
-rw-r--r-- | mh/mh_alias.l | 34 | ||||
-rw-r--r-- | mh/tests/ali.at | 12 |
3 files changed, 48 insertions, 8 deletions
@@ -1,4 +1,4 @@ -GNU mailutils NEWS -- history of user-visible changes. 2012-11-12 +GNU mailutils NEWS -- history of user-visible changes. 2013-02-16 Copyright (C) 2002-2012 Free Software Foundation, Inc. See the end of file for copying conditions. @@ -203,6 +203,14 @@ option: "yes", the mailbox will be truncated after successful processing. If BOOL is "no", the source mailbox will not be truncated. +** MH aliases + +The "< FILE" construct has been extended to allow for building the +list of aliases on the fly. If FILE is an executable file and its +first line begins with a shell interpreter magic (#!/ or #! /), then +instead of being included, such file is run using "/bin/sh -c", its +output is collected and included in the aliases. + ** mailutils-config is deprecated. Use `mu cflags' and `mu ldflags' instead. The mailutils-config is diff --git a/mh/mh_alias.l b/mh/mh_alias.l index 53a46b985..94e5428fe 100644 --- a/mh/mh_alias.l +++ b/mh/mh_alias.l @@ -219,10 +219,12 @@ struct buffer_ctx { int line; ino_t i_node; FILE *yyin; + int exec_p; LEX_BUFFER_STATE state; }; static struct buffer_ctx *context_stack; +static int exec_p; static struct buffer_ctx * ctx_lookup (ino_t ino) @@ -242,7 +244,8 @@ push_source (const char *name, int fail) struct buffer_ctx *ctx; struct stat st; char *filename; - + int ex = 0; + filename = mh_expand_name (NULL, name, 0); if (stat (filename, &st)) { @@ -251,7 +254,7 @@ push_source (const char *name, int fail) free (filename); return 1; } - + if (ali_filename && st.st_ino == ali_source_inode) { ali_parse_error (_("recursive inclusion")); @@ -279,12 +282,35 @@ push_source (const char *name, int fail) free (filename); return 1; } + if (access (filename, X_OK) == 0) + { + char sig[4]; + + if (fread (sig, sizeof(sig), 1, fp) == 1 && + (memcmp(sig, "#!/", 3) == 0 || + memcmp(sig, "#! /", 4) == 0)) + { + ex = 1; + fclose (fp); + fp = popen (filename, "r"); + if (!fp) + { + ali_parse_error (_("can't execute `%s': %s"), + filename, strerror (errno)); + free (filename); + return 1; + } + } + else + rewind (fp); + } /* Push current context */ if (ali_filename) { ctx = mu_alloc (sizeof (*ctx)); ctx->filename = ali_filename; + ctx->exec_p = exec_p; ctx->line = ali_line_num; ctx->i_node = ali_source_inode; ctx->yyin = yyin; @@ -307,6 +333,7 @@ push_source (const char *name, int fail) ali_filename = filename; ali_line_num = 1; ali_source_inode = st.st_ino; + exec_p = ex; return 0; } @@ -316,7 +343,7 @@ pop_source () struct buffer_ctx *ctx; if (yyin) - fclose (yyin); + (exec_p ? pclose : fclose) (yyin); #ifndef FLEX_SCANNER lex_delete_buffer (current_buffer); #endif @@ -332,6 +359,7 @@ pop_source () ali_filename = context_stack->filename; ali_line_num = context_stack->line + 1; /* < line did not increment it */ ali_source_inode = context_stack->i_node; + exec_p = context_stack->exec_p; RESTORE_BUFFER_STATE (context_stack->state); ctx = context_stack->prev; free (context_stack); diff --git a/mh/tests/ali.at b/mh/tests/ali.at index 98cd4771a..ff9ee911d 100644 --- a/mh/tests/ali.at +++ b/mh/tests/ali.at @@ -108,15 +108,19 @@ ali -list -a ./mh_aliases everybody [0], [expout]) -MH_CHECK([ali: simple aliases],[ali00],[ +MH_CHECK([ali: executable file inlcusion],[ali02 ali-xinclude],[ +AT_DATA([Mail/ali.sh],[#! /bin/sh +echo "admin: gray, jeff" +]) +chmod +x Mail/ali.sh AT_DATA([mh_aliases],[ -devel: gray, polak -admin: gray, jeff +devel: gray, polak, admin +<ali.sh ]) ali -a ./mh_aliases devel ], [0], -[gray, polak +[gray, polak, gray, jeff ]) m4_popdef[MH_KEYWORDS]) |