]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
func_env: Add DIRNAME and BASENAME functions
authorNaveen Albert <asterisk@phreaknet.org>
Fri, 3 Sep 2021 00:00:50 +0000 (00:00 +0000)
committerGeorge Joseph <gjoseph@digium.com>
Fri, 10 Sep 2021 16:47:41 +0000 (11:47 -0500)
Adds the DIRNAME and BASENAME functions, which are
wrappers around the corresponding C library functions.
These can be used to safely and conveniently work with
file paths and names in the dialplan.

ASTERISK-29628 #close

Change-Id: Id3aeb907f65c0ff96b6e57751ff0cb49d61db7f3

doc/CHANGES-staging/func_env.txt [new file with mode: 0644]
funcs/func_env.c

diff --git a/doc/CHANGES-staging/func_env.txt b/doc/CHANGES-staging/func_env.txt
new file mode 100644 (file)
index 0000000..af03d5f
--- /dev/null
@@ -0,0 +1,5 @@
+Subject: func_env.c
+
+Two new functions, DIRNAME and BASENAME, are now
+included which allow users to obtain the directory
+or the base filename of any file.
index e6258531428656ac8da1fd4a9f17ad7017b5276c..e5e3e70e6addf5a37ffc40b39f10c2001250b493 100644 (file)
@@ -28,6 +28,7 @@
 #include "asterisk.h"
 
 #include <sys/stat.h>   /* stat(2) */
+#include <libgen.h>     /* dirname and basename */
 
 #include "asterisk/module.h"
 #include "asterisk/channel.h"
                        <ref type="function">FILE_COUNT_LINE</ref>
                </see-also>
        </function>
+       <function name="BASENAME" language="en_US">
+               <synopsis>
+                       Return the name of a file.
+               </synopsis>
+               <syntax>
+                       <parameter name="filename" required="true" />
+               </syntax>
+               <description>
+                       <para>Return the base file name, given a full file path.</para>
+                       <example title="Directory name">
+                       same => n,Set(basename=${BASENAME(/etc/asterisk/extensions.conf)})
+                       same => n,NoOp(${basename}) ; outputs extensions.conf
+                       </example>
+               </description>
+               <see-also>
+                       <ref type="function">DIRNAME</ref>
+               </see-also>
+       </function>
+       <function name="DIRNAME" language="en_US">
+               <synopsis>
+                       Return the directory of a file.
+               </synopsis>
+               <syntax>
+                       <parameter name="filename" required="true" />
+               </syntax>
+               <description>
+                       <para>Return the directory of a file, given a full file path.</para>
+                       <example title="Directory name">
+                       same => n,Set(dirname=${DIRNAME(/etc/asterisk/extensions.conf)})
+                       same => n,NoOp(${dirname}) ; outputs /etc/asterisk
+                       </example>
+               </description>
+               <see-also>
+                       <ref type="function">BASENAME</ref>
+               </see-also>
+       </function>
  ***/
 
 static int env_read(struct ast_channel *chan, const char *cmd, char *data,
@@ -483,6 +520,40 @@ static int file_format(struct ast_channel *chan, const char *cmd, char *data, st
        return 0;
 }
 
+static int file_dirname(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+       char *ret = NULL;
+
+       *buf = '\0';
+
+       if (data) {
+               ret = dirname(data);
+       }
+
+       if (ret) {
+               ast_copy_string(buf, ret, len);
+       }
+
+       return 0;
+}
+
+static int file_basename(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+       char *ret = NULL;
+
+       *buf = '\0';
+
+       if (data) {
+               ret = basename(data);
+       }
+
+       if (ret) {
+               ast_copy_string(buf, ret, len);
+       }
+
+       return 0;
+}
+
 static int file_read(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 {
        FILE *ff;
@@ -1260,6 +1331,18 @@ static struct ast_custom_function file_format_function = {
        .read_max = 2,
 };
 
+static struct ast_custom_function file_dirname_function = {
+       .name = "DIRNAME",
+       .read = file_dirname,
+       .read_max = 12,
+};
+
+static struct ast_custom_function file_basename_function = {
+       .name = "BASENAME",
+       .read = file_basename,
+       .read_max = 12,
+};
+
 static int unload_module(void)
 {
        int res = 0;
@@ -1269,6 +1352,8 @@ static int unload_module(void)
        res |= ast_custom_function_unregister(&file_function);
        res |= ast_custom_function_unregister(&file_count_line_function);
        res |= ast_custom_function_unregister(&file_format_function);
+       res |= ast_custom_function_unregister(&file_dirname_function);
+       res |= ast_custom_function_unregister(&file_basename_function);
 
        return res;
 }
@@ -1282,6 +1367,8 @@ static int load_module(void)
        res |= ast_custom_function_register_escalating(&file_function, AST_CFE_BOTH);
        res |= ast_custom_function_register_escalating(&file_count_line_function, AST_CFE_READ);
        res |= ast_custom_function_register_escalating(&file_format_function, AST_CFE_READ);
+       res |= ast_custom_function_register(&file_dirname_function);
+       res |= ast_custom_function_register(&file_basename_function);
 
        return res;
 }