<p>George Joseph <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16407">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve
George Joseph: Looks good to me, approved; Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">func_env: Add DIRNAME and BASENAME functions<br><br>Adds the DIRNAME and BASENAME functions, which are<br>wrappers around the corresponding C library functions.<br>These can be used to safely and conveniently work with<br>file paths and names in the dialplan.<br><br>ASTERISK-29628 #close<br><br>Change-Id: Id3aeb907f65c0ff96b6e57751ff0cb49d61db7f3<br>---<br>A doc/CHANGES-staging/func_env.txt<br>M funcs/func_env.c<br>2 files changed, 92 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/func_env.txt b/doc/CHANGES-staging/func_env.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..af03d5f</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/func_env.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: func_env.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Two new functions, DIRNAME and BASENAME, are now</span><br><span style="color: hsl(120, 100%, 40%);">+included which allow users to obtain the directory</span><br><span style="color: hsl(120, 100%, 40%);">+or the base filename of any file.</span><br><span>diff --git a/funcs/func_env.c b/funcs/func_env.c</span><br><span>index e625853..e5e3e70 100644</span><br><span>--- a/funcs/func_env.c</span><br><span>+++ b/funcs/func_env.c</span><br><span>@@ -28,6 +28,7 @@</span><br><span> #include "asterisk.h"</span><br><span> </span><br><span> #include <sys/stat.h> /* stat(2) */</span><br><span style="color: hsl(120, 100%, 40%);">+#include <libgen.h> /* dirname and basename */</span><br><span> </span><br><span> #include "asterisk/module.h"</span><br><span> #include "asterisk/channel.h"</span><br><span>@@ -240,6 +241,42 @@</span><br><span> <ref type="function">FILE_COUNT_LINE</ref></span><br><span> </see-also></span><br><span> </function></span><br><span style="color: hsl(120, 100%, 40%);">+ <function name="BASENAME" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ Return the name of a file.</span><br><span style="color: hsl(120, 100%, 40%);">+ </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="filename" required="true" /></span><br><span style="color: hsl(120, 100%, 40%);">+ </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <description></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Return the base file name, given a full file path.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <example title="Directory name"></span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Set(basename=${BASENAME(/etc/asterisk/extensions.conf)})</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,NoOp(${basename}) ; outputs extensions.conf</span><br><span style="color: hsl(120, 100%, 40%);">+ </example></span><br><span style="color: hsl(120, 100%, 40%);">+ </description></span><br><span style="color: hsl(120, 100%, 40%);">+ <see-also></span><br><span style="color: hsl(120, 100%, 40%);">+ <ref type="function">DIRNAME</ref></span><br><span style="color: hsl(120, 100%, 40%);">+ </see-also></span><br><span style="color: hsl(120, 100%, 40%);">+ </function></span><br><span style="color: hsl(120, 100%, 40%);">+ <function name="DIRNAME" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ Return the directory of a file.</span><br><span style="color: hsl(120, 100%, 40%);">+ </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="filename" required="true" /></span><br><span style="color: hsl(120, 100%, 40%);">+ </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <description></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Return the directory of a file, given a full file path.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <example title="Directory name"></span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Set(dirname=${DIRNAME(/etc/asterisk/extensions.conf)})</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,NoOp(${dirname}) ; outputs /etc/asterisk</span><br><span style="color: hsl(120, 100%, 40%);">+ </example></span><br><span style="color: hsl(120, 100%, 40%);">+ </description></span><br><span style="color: hsl(120, 100%, 40%);">+ <see-also></span><br><span style="color: hsl(120, 100%, 40%);">+ <ref type="function">BASENAME</ref></span><br><span style="color: hsl(120, 100%, 40%);">+ </see-also></span><br><span style="color: hsl(120, 100%, 40%);">+ </function></span><br><span> ***/</span><br><span> </span><br><span> static int env_read(struct ast_channel *chan, const char *cmd, char *data,</span><br><span>@@ -483,6 +520,40 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int file_dirname(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *ret = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ *buf = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = dirname(data);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_copy_string(buf, ret, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int file_basename(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *ret = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ *buf = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = basename(data);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_copy_string(buf, ret, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int file_read(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)</span><br><span> {</span><br><span> FILE *ff;</span><br><span>@@ -1260,6 +1331,18 @@</span><br><span> .read_max = 2,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function file_dirname_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "DIRNAME",</span><br><span style="color: hsl(120, 100%, 40%);">+ .read = file_dirname,</span><br><span style="color: hsl(120, 100%, 40%);">+ .read_max = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function file_basename_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "BASENAME",</span><br><span style="color: hsl(120, 100%, 40%);">+ .read = file_basename,</span><br><span style="color: hsl(120, 100%, 40%);">+ .read_max = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int unload_module(void)</span><br><span> {</span><br><span> int res = 0;</span><br><span>@@ -1269,6 +1352,8 @@</span><br><span> res |= ast_custom_function_unregister(&file_function);</span><br><span> res |= ast_custom_function_unregister(&file_count_line_function);</span><br><span> res |= ast_custom_function_unregister(&file_format_function);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= ast_custom_function_unregister(&file_dirname_function);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= ast_custom_function_unregister(&file_basename_function);</span><br><span> </span><br><span> return res;</span><br><span> }</span><br><span>@@ -1282,6 +1367,8 @@</span><br><span> res |= ast_custom_function_register_escalating(&file_function, AST_CFE_BOTH);</span><br><span> res |= ast_custom_function_register_escalating(&file_count_line_function, AST_CFE_READ);</span><br><span> res |= ast_custom_function_register_escalating(&file_format_function, AST_CFE_READ);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= ast_custom_function_register(&file_dirname_function);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= ast_custom_function_register(&file_basename_function);</span><br><span> </span><br><span> return res;</span><br><span> }</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16407">change 16407</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/16407"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Id3aeb907f65c0ff96b6e57751ff0cb49d61db7f3 </div>
<div style="display:none"> Gerrit-Change-Number: 16407 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>