2828#include "asterisk.h"
2929
3030#include <sys/stat.h> /* stat(2) */
31+ #include <libgen.h> /* dirname and basename */
3132
3233#include "asterisk/module.h"
3334#include "asterisk/channel.h"
240241 <ref type="function">FILE_COUNT_LINE</ref>
241242 </see-also>
242243 </function>
244+ <function name="BASENAME" language="en_US">
245+ <synopsis>
246+ Return the name of a file.
247+ </synopsis>
248+ <syntax>
249+ <parameter name="filename" required="true" />
250+ </syntax>
251+ <description>
252+ <para>Return the base file name, given a full file path.</para>
253+ <example title="Directory name">
254+ same => n,Set(basename=${BASENAME(/etc/asterisk/extensions.conf)})
255+ same => n,NoOp(${basename}) ; outputs extensions.conf
256+ </example>
257+ </description>
258+ <see-also>
259+ <ref type="function">DIRNAME</ref>
260+ </see-also>
261+ </function>
262+ <function name="DIRNAME" language="en_US">
263+ <synopsis>
264+ Return the directory of a file.
265+ </synopsis>
266+ <syntax>
267+ <parameter name="filename" required="true" />
268+ </syntax>
269+ <description>
270+ <para>Return the directory of a file, given a full file path.</para>
271+ <example title="Directory name">
272+ same => n,Set(dirname=${DIRNAME(/etc/asterisk/extensions.conf)})
273+ same => n,NoOp(${dirname}) ; outputs /etc/asterisk
274+ </example>
275+ </description>
276+ <see-also>
277+ <ref type="function">BASENAME</ref>
278+ </see-also>
279+ </function>
243280 ***/
244281
245282static 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
483520 return 0 ;
484521}
485522
523+ static int file_dirname (struct ast_channel * chan , const char * cmd , char * data , char * buf , size_t len )
524+ {
525+ char * ret = NULL ;
526+
527+ * buf = '\0' ;
528+
529+ if (data ) {
530+ ret = dirname (data );
531+ }
532+
533+ if (ret ) {
534+ ast_copy_string (buf , ret , len );
535+ }
536+
537+ return 0 ;
538+ }
539+
540+ static int file_basename (struct ast_channel * chan , const char * cmd , char * data , char * buf , size_t len )
541+ {
542+ char * ret = NULL ;
543+
544+ * buf = '\0' ;
545+
546+ if (data ) {
547+ ret = basename (data );
548+ }
549+
550+ if (ret ) {
551+ ast_copy_string (buf , ret , len );
552+ }
553+
554+ return 0 ;
555+ }
556+
486557static int file_read (struct ast_channel * chan , const char * cmd , char * data , struct ast_str * * buf , ssize_t len )
487558{
488559 FILE * ff ;
@@ -1260,6 +1331,18 @@ static struct ast_custom_function file_format_function = {
12601331 .read_max = 2 ,
12611332};
12621333
1334+ static struct ast_custom_function file_dirname_function = {
1335+ .name = "DIRNAME" ,
1336+ .read = file_dirname ,
1337+ .read_max = 12 ,
1338+ };
1339+
1340+ static struct ast_custom_function file_basename_function = {
1341+ .name = "BASENAME" ,
1342+ .read = file_basename ,
1343+ .read_max = 12 ,
1344+ };
1345+
12631346static int unload_module (void )
12641347{
12651348 int res = 0 ;
@@ -1269,6 +1352,8 @@ static int unload_module(void)
12691352 res |= ast_custom_function_unregister (& file_function );
12701353 res |= ast_custom_function_unregister (& file_count_line_function );
12711354 res |= ast_custom_function_unregister (& file_format_function );
1355+ res |= ast_custom_function_unregister (& file_dirname_function );
1356+ res |= ast_custom_function_unregister (& file_basename_function );
12721357
12731358 return res ;
12741359}
@@ -1282,6 +1367,8 @@ static int load_module(void)
12821367 res |= ast_custom_function_register_escalating (& file_function , AST_CFE_BOTH );
12831368 res |= ast_custom_function_register_escalating (& file_count_line_function , AST_CFE_READ );
12841369 res |= ast_custom_function_register_escalating (& file_format_function , AST_CFE_READ );
1370+ res |= ast_custom_function_register (& file_dirname_function );
1371+ res |= ast_custom_function_register (& file_basename_function );
12851372
12861373 return res ;
12871374}
0 commit comments