--- asterisk-1.6.2.6/funcs/func_env.c.ori 2009-03-16 18:33:38.000000000 +0100 +++ asterisk-1.6.2.6/funcs/func_env.c 2010-06-17 12:02:55.000000000 +0200 @@ -32,6 +32,7 @@ #include "asterisk/pbx.h" #include "asterisk/utils.h" #include "asterisk/app.h" +#include "asterisk/file.h" /*** DOCUMENTATION @@ -69,21 +70,153 @@ - Obtains the contents of a file. + Read or write text file. - - + + + The file where you want to read or write + + + Maybe specified as any number. If negative, offset specifies the number of bytes back from the end of the file. + If number is prefixed by 'L', offset is to be interpreted as a line number - + If specified, will limit the length of the data read to that size. If negative, trims length bytes from the end of the file. + If number is prefixed by 'L', length is to be interpreted as a number of lines + + + The Format parameter is used only for reading and may be one of the following : + + + + + + the default format is 'd' for Cygwin, 'm' for MAC and 'u' for all other + + + + Read and write text file in charactere and line mode. + + + Examples : + Read mode (char) : + ;reads the the entire content of the file. + Set(foo=${FILE(/tmp/test.txt)}) + ;reads the 10th to end of file. + Set(foo=${FILE(/tmp/test.txt,10)}) + ;reads the 10th to 19th character in the file. + Set(foo=${FILE(/tmp/test.txt,10,20)}) + + + Read mode (line) : + ; reads the 3th line of the file. + Set(foo=${FILE(/tmp/test.txt,L3,L1)}) + ; reads the 3th and 4th line of the file. + Set(foo=${FILE(/tmp/test.txt,L3,L2)}) + ; reads all lines of the file from the third. + Set(foo=${FILE(/tmp/test.txt,L3)}) + ; reads the last three lines of the file. + Set(foo=${FILE(/tmp/test.txt,L-3)}) + ; reads the 3th line of a DOS formated file. + Set(foo=${FILE(/tmp/test.txt,L3,L1,d)}) + + + Write mode (char) : + ; create empty file + Set(FILE(/tmp/test.txt)=) + ; truncate the file and write "bar" + Set(FILE(/tmp/test.txt)=bar) + ; Append "bar" + Set(FILE(/tmp/test.txt,-1)=bar) + ; Replace the first char with "bar" + Set(FILE(/tmp/test.txt,1,1)=bar) + ; Replace 10 chars begining at the 19th of the file with "bar" + Set(FILE(/tmp/test.txt,19,10)=bar) + ; Replace all chars from the 19th with "bar" + Set(FILE(/tmp/test.txt,19,-1)=bar) + ; Insert "bar" after the 4th character + Set(FILE(/tmp/test.txt,4,0)=bar) + + + Write mode (line) : + ; Replace the first line of the file with "bar" + Set(FILE(/tmp/foo.txt,L1,L1)=bar) + ; Replace the last line of the file with "bar" + Set(FILE(/tmp/foo.txt,L-1,L1)=bar) + ; Append "bar" to the file with a newline + Set(FILE(/tmp/foo.txt,L-1)=bar) + + + FILE_COUNT_LINE + FILE_FORMAT + + + + + Obtains the number of lines of a text file. + + + + + The file you want to get the number of lines + + + + Format may be one of the following : + + + + + + the default format is 'd' for Cygwin, 'm' for MAC and 'u' for all other + + + + Returns the number of lines, or -1 on error. + + + FILE + FILE_FORMAT + + + + + Return the newline format of a text file. + + + + + The file you want to get the format of lines + + Return the format of new line, or the string -1 on error. + The Format is one of the following : + 'u' - for Unix newline format. + 'd' - for Dos newline format. + 'm' - for Mac newline format. + + FILE + FILE_COUNT_LINE + ***/ @@ -160,66 +293,735 @@ return 0; } -static int file_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +static char get_file_format(char *contents) +{ + int i = 0; +#ifdef __CYGWIN__ + char newline_format = 'd'; +#else +#ifdef __APPLE__ + char newline_format = 'm'; +#else + char newline_format = 'u'; +#endif +#endif + for (i = 0; i < strlen(contents); i++) { + if (contents[i] == 13) { + if (i < (strlen(contents)-1) && contents[i+1] == 10) { + newline_format = 'd'; + } else { + newline_format = 'm'; + } + break; + } + if (contents[i] == 10) { + newline_format = 'u'; + break; + } + } + return newline_format; +} + +static int get_file_line_count(char *contents, char newline_format) +{ + int j = 0, i = 0; + + for (j = 0,i = 0; i < strlen(contents); i++) { + if (contents[i] == 10 || contents[i] == 13) { + if (contents[i] == 10 && newline_format != 'm') { + if (newline_format == 'd' && contents[i-1] != 13) { + continue; + } + j++; + } + if (contents[i] == 13 && newline_format == 'm') { + j++; + continue; + } + } + } + if (i > 1) { + if( newline_format != 'm') { + if (newline_format == 'u') { + if (contents[i-1] != 10) { + j++; + } + } else { + if (contents[i-1]!=10 || contents[i-2]!=13) { + j++; + } + } + } else { + if(contents[i-1]!=13) { + j++; + } + } + } + return j; +} + +static int file_read_char(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) { AST_DECLARE_APP_ARGS(args, AST_APP_ARG(filename); AST_APP_ARG(offset); AST_APP_ARG(length); + AST_APP_ARG(format); ); int offset = 0, length, res = 0; char *contents; - size_t contents_len; + int contents_len; AST_STANDARD_APP_ARGS(args, data); + if (args.argc > 3) { + ast_log(LOG_WARNING, "format specified in character reading mode, ignored\n"); + } + if (!(contents = ast_read_textfile(args.filename))) { + return -1; + } + contents_len = strlen(contents); + if (args.argc > 1) { offset = atoi(args.offset); + if (offset > 0) { + offset = offset - 1; + } + if (offset > contents_len) { + ast_log(LOG_WARNING, "Offset (%d) is larger than the file size (%d).\n", offset, contents_len); + ast_copy_string(buf, "", len); + ast_free(contents); + return 0; + } } if (args.argc > 2) { - /* The +1/-1 in this code section is to accomodate for the terminating NULL. */ - if ((length = atoi(args.length) + 1) > len) { + if (strlen(args.length) == 0) { + length = contents_len; + } else { + length = atoi(args.length); + } + ast_debug(1, "length = %d (%s)\n", length, args.length); + if (length < 0) { + length = length * (-1); + offset = offset - length; + if (offset < 0) { + offset = 0; + } + } else { + if (offset < 0) { + offset = contents_len + offset - length; + } + } + if (length > len) { ast_log(LOG_WARNING, "Length %d is greater than the max (%d). Truncating output.\n", length - 1, (int)len - 1); length = len; } } else { - length = len; + length = contents_len - offset; } + if (offset < 0) { + offset = 0; + } + ast_debug(1, "args = %d, Read File : %s from %d length %d\n", args.argc, args.filename, offset, length); + ast_copy_string(buf, &contents[offset], length + 1); + + ast_free(contents); + + return res; +} + +static int file_read_line(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(filename); + AST_APP_ARG(offset); + AST_APP_ARG(length); + AST_APP_ARG(format); + ); + int j = 0, i = 0, k = 0, line_start = 1, line_end = 0; + int contents_lines; + char *contents; +#ifdef __CYGWIN__ + char newline_format = 'd'; +#else +#ifdef __APPLE__ + char newline_format = 'm'; +#else + char newline_format = 'u'; +#endif +#endif + AST_STANDARD_APP_ARGS(args, data); if (!(contents = ast_read_textfile(args.filename))) { + ast_debug(1, "File %s is empty\n", args.filename); + ast_copy_string(buf, "", len); + return 0; + } + ast_debug(1, "args = %d, Read File : %s\n", args.argc, args.filename); + + if (args.argc > 3) { + if (args.format[0] == 'u' || args.format[0] == 'U') { + newline_format = 'u'; + } + if (args.format[0] == 'd' || args.format[0] == 'D') { + newline_format = 'd'; + } + if (args.format[0] == 'm' || args.format[0] == 'M') { + newline_format = 'm'; + } + } else { + newline_format=get_file_format(contents); + } + + contents_lines=get_file_line_count(contents, newline_format); + if (args.argc > 1) { + if (strlen(args.offset) == 0) { + line_start = 0; + } + line_start = atoi(args.offset+1); + } + if (line_start < 0) { + line_start = contents_lines + line_start; + } else { + if (line_start > 0) { + line_start = line_start - 1; + } + } + + if (args.argc > 2) { + if (strlen(args.length) == 0) { + line_end = contents_lines; + } else { + line_end = atoi(args.length+1); + if (line_end < 0) { + ast_log(LOG_WARNING, "The number of line to read cannot be less than 1\n"); + ast_copy_string(buf, "", len); + ast_free(contents); + return 0; + } + if (atoi(args.offset+1) < 0) { + line_start = line_start - line_end + 1; + } + line_end = line_end + line_start; + } + } else { + line_end = contents_lines; + } + if (line_end < 1) { + ast_log(LOG_WARNING, "The number of line to read cannot be less than 1\n"); + ast_copy_string(buf, "", len); + ast_free(contents); + return 0; + } + if (line_start > (contents_lines - 1)) { + ast_log(LOG_WARNING, "line_start (%d) is larger than the file lines number (%d).\n", line_start + 1, contents_lines); + ast_copy_string(buf, "", len); + ast_free(contents); + return 0; + } + + ast_debug(1, "args = %d, Read File : %s from %d to %d\n", args.argc, args.filename, line_start, line_end); + + for (k = 0,j = 0,i = 0; i < strlen(contents); i++) { + if (contents[i] == 10 || contents[i] == 13) { + if (contents[i] == 10 && newline_format != 'm') { + if(newline_format == 'd' && contents[i-1] != 13) { + continue; + } + j++; + } + if (contents[i] == 13 && newline_format == 'm') { + j++; + } + if (contents[i] == 13 && newline_format != 'm') { + continue; + } + if (j == line_end) { + break; + } + if (j == line_start) { + k = i+1; + } + } + } + if (i == strlen(contents)) { + if (contents[i] != 10 && newline_format != 'm') { + j++; + } + if (contents[i] != 13 && newline_format == 'm') { + j++; + } + } + if (j < line_start) { + ast_log(LOG_WARNING, "Line %d not found\n", line_start); + ast_copy_string(buf, "", len); + } else { + j = i-k+1; + if (newline_format == 'd') { + j--; + } + ast_debug(1, "Line found, begin : %d, len %d\n", k, j); + ast_copy_string(buf, &contents[k], j); + } + + ast_free(contents); + + return 0; +} + +static int file_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(filename); + AST_APP_ARG(offset); + AST_APP_ARG(length); + AST_APP_ARG(format); + ); + char *data2; + + ast_debug(1, "function file_read(), data = %s\n", data); + data2=ast_strdup(data); + AST_STANDARD_APP_ARGS(args, data); + if (args.argc == 0) { + ast_log(LOG_ERROR, "No filename specified.\n"); return -1; } + if (args.argc == 1) { + ast_debug(1, "No offset, use function : file_read_char()\n"); + return file_read_char(chan, cmd, data2, buf, len); + } + + if (args.argc > 2) { + if (toupper(args.offset[0]) == 'L' && strlen(args.length) > 0 && toupper(args.length[0]) != 'L') { + ast_log(LOG_ERROR, "Offset (%s) begin with 'L' but not Length (%s).\n", args.offset, args.length); + return -1; + } + if (toupper(args.offset[0]) != 'L' && toupper(args.length[0]) == 'L') { + ast_log(LOG_ERROR, "Length begin with 'L' but not Offset.\n"); + return -1; + } + } + if (toupper(args.offset[0]) != 'L') { + ast_debug(1, "use function : file_read_char(), args = %d, data = %s\n", args.argc, data2); + return file_read_char(chan, cmd, data2, buf, len); + } + ast_debug(1, "use function : file_read_line()\n"); + return file_read_line(chan, cmd, data2, buf, len); +} + +static int file_write_char(struct ast_channel *chan, const char *cmd, char *data, const char *value) +{ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(filename); + AST_APP_ARG(offset); + AST_APP_ARG(length); + AST_APP_ARG(format); + ); + int offset = 0, length = 0; + int fd; + char *contents; + size_t contents_len; + + AST_STANDARD_APP_ARGS(args, data); + + if (args.argc > 3) { + ast_log(LOG_WARNING, "format specified in character writing mode, ignored\n"); + } + if (args.argc > 1 && strlen(args.offset) > 0) { + offset = atoi(args.offset); + if (offset > 0) { + offset = offset - 1; + } + } else { + offset = 0; + } + if (args.argc == 1 || strlen(args.offset) < 1 || strlen(value) == 0) { + ast_debug(1, "write mode\n"); + if ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_TRUNC) ) < 0) { + ast_log(LOG_ERROR, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + return 0; + } + if (strlen(value) > 0) { + write(fd, value, strlen(value)); + } + close(fd); + return 0; + } + + if (offset == -1) { + ast_debug(1, "append mode\n"); + if ( (fd = open(args.filename, O_CREAT | O_APPEND | O_WRONLY,0600) ) < 0) { + ast_log(LOG_ERROR, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + return 0; + } + write(fd, value, strlen(value)); + close(fd); + return 0; + } + if (!(contents = ast_read_textfile(args.filename))) { + ast_debug(1, "File %s not fount or empty\n", args.filename); + contents_len = 0; + } else { + contents_len = strlen(contents); + } + if (args.argc > 2) { + length = atoi(args.length); + } else { + length = contents_len; + } + if (length == -1) { + length = contents_len; + } + + ast_debug(1, "insert/replace mode : args = %d, File : %s from %d to %d\n", args.argc, args.filename, offset, length); + if ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_TRUNC) ) < 0) { + ast_log(LOG_ERROR, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + ast_free(contents); + return 0; + } + if (offset != 0) { + write(fd, &contents[0], offset); + } + write(fd, value, strlen(value)); + if ( (offset + length) < contents_len) { + write(fd, &contents[offset + length], contents_len - length - offset); + } + close(fd); + + ast_free(contents); + + return 0; +} + +static int file_write_line(struct ast_channel *chan, const char *cmd, char *data, const char *value) +{ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(filename); + AST_APP_ARG(offset); + AST_APP_ARG(length); + AST_APP_ARG(format); + ); + int length = 0; + int fd; + int j = 0, i = 0, k = 0; + int line_start = 1, line_end = 0; + char *contents; + size_t contents_len; + int contents_lines; + +#ifdef __CYGWIN__ + char newline_format = 'd'; +#else +#ifdef __APPLE__ + char newline_format = 'm'; +#else + char newline_format = 'u'; +#endif +#endif + + AST_STANDARD_APP_ARGS(args, data); + + if (strlen(value) == 0) { + ast_log(LOG_WARNING, "The string is empty, nothing has been written\n"); + return 0; + } + + if (args.argc > 3) { + if (args.format[0] == 'u' || args.format[0] == 'U') { + newline_format = 'u'; + } + if (args.format[0] == 'd' || args.format[0] == 'D') { + newline_format = 'd'; + } + if (args.format[0] == 'm' || args.format[0] == 'M') { + newline_format = 'm'; + } + } else { + newline_format='x'; + } - do { + if (!(contents = ast_read_textfile(args.filename))) { + ast_debug(1, "File %s not fount or empty\n", args.filename); + contents_len = 0; + contents_lines=0; + } else { contents_len = strlen(contents); - if (offset > contents_len) { - res = -1; - break; + if (newline_format == 'x') { + newline_format=get_file_format(contents); } + contents_lines=get_file_line_count(contents, newline_format); + } - if (offset >= 0) { - if (length < 0) { - if (contents_len - offset + length < 0) { - /* Nothing left after trimming */ - res = -1; - break; - } - ast_copy_string(buf, &contents[offset], contents_len + length); - } else { - ast_copy_string(buf, &contents[offset], length); + if (newline_format == 'x') { + if (contents_len > 0) { + newline_format=get_file_format(contents); + } else { +#ifdef __CYGWIN__ + newline_format = 'd'; +#else +#ifdef __APPLE__ + newline_format = 'm'; +#else + newline_format = 'u'; +#endif +#endif + } + } + + if (strlen(args.offset) > 0) { + line_start = atoi(args.offset + 1); + } else { + line_start = 0; + } + if (contents_len == 0) { + line_start = -1; + } + if (line_start > 0) { + line_start = line_start - 1; + } + + if (line_start == -1 && (contents_len == 0 || args.argc < 3 || strlen(args.length) == 0 || atoi(args.length+1) == 0)) { + ast_debug(1, "append mode\n"); + if ( (fd = open(args.filename, O_CREAT | O_APPEND | O_WRONLY,0600) ) < 0) { + ast_log(LOG_ERROR, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + return 0; + } + write(fd, value, strlen(value)); + if (newline_format == 'd') { + write(fd, "\r\n", 2); + } + if (newline_format == 'm') { + write(fd, "\r", 1); + } + if (newline_format == 'u') { + write(fd, "\n", 1); + } + close(fd); + return 0; + } + + ast_debug(1, "args = %d, Write File : %s start %d content %d\n", args.argc, args.filename, line_start, contents_len); + if (args.argc > 2) { + if (strlen(args.length) > 0) { + line_end = atoi(args.length+1); + if (line_start > 0) { + line_end = line_end + line_start; } } else { - if (offset * -1 > contents_len) { - ast_log(LOG_WARNING, "Offset is larger than the file size.\n"); - offset = contents_len * -1; + line_end = contents_lines; + } + } else { + line_end = contents_lines; + } + + if (line_end == contents_lines && line_start < 1) { + ast_debug(1, "write mode\n"); + if ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_TRUNC) ) < 0) { + ast_log(LOG_ERROR, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + return 0; + } + write(fd, value, strlen(value)); + if (newline_format == 'd') { + write(fd, "\r\n", 2); + } + if (newline_format == 'm') { + write(fd, "\r", 1); + } + if (newline_format == 'u') { + write(fd, "\n", 1); + } + close(fd); + return 0; + } + + + ast_debug(1, "insert/replace mode\n"); + + if (line_start < 0) { + if (contents_len == 0) { + line_start = 0; + } else { + if (line_start == -1) { + line_start = contents_lines - line_end; + line_end = contents_lines; + } else { + line_start = contents_lines + line_start; + line_end = line_start + line_end; + } + } + } + + if (line_end < line_start) { + ast_log(LOG_WARNING, "The end line number cannot be less than start\n"); + ast_free(contents); + return 0; + } + + for (k = 0,j = 0,i = 0; i < contents_len; i++) { + if (contents[i] == 10 || contents[i] == 13) { + if (contents[i] == 10 && newline_format != 'm') { + if(newline_format == 'd' && contents[i-1] != 13) { + continue; + } + j++; + } + if (contents[i] == 13 && newline_format == 'm') { + j++; + } + if (contents[i] == 13 && newline_format != 'm') { + continue; } - ast_copy_string(buf, &contents[contents_len + offset], length); + if (j == line_start) { + k = i+1; + } + if (j == line_end) { + length = i + 1; + break; + } + } + } + if (i == contents_len) { + length = i; + if (contents[i] != 10 && newline_format !='m') { + j++; + } + if (contents[i] != 13 && newline_format =='m') { + j++; } - } while (0); + } + ast_debug(1, "args = %d, Write File : %s from %d to %d\n", args.argc, args.filename, k, length); + + if (j < line_start) { + ast_log(LOG_WARNING, "Line %d not found\n", line_start + 1); + ast_free(contents); + return 0; + } + + if ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_TRUNC) ) < 0) { + ast_log(LOG_ERROR, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + ast_free(contents); + return 0; + } + if (k != 0) { + write(fd, &contents[0], k); + } + write(fd, value, strlen(value)); + + if (newline_format == 'd') { + write(fd, "\r\n", 2); + } + if (newline_format == 'm') { + write(fd, "\r", 1); + } + if (newline_format == 'u') { + write(fd, "\n", 1); + } + + if ( length < contents_len) { + write(fd, &contents[length], contents_len - length); + } + close(fd); ast_free(contents); - return res; + return 0; +} + +static int file_write(struct ast_channel *chan, const char *cmd, char *data, const char *value) +{ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(filename); + AST_APP_ARG(offset); + AST_APP_ARG(length); + AST_APP_ARG(format); + ); + char *data2; + + ast_debug(1, "function file_write(), data = %s\n", data); + data2=ast_strdup(data); + AST_STANDARD_APP_ARGS(args, data); + if (args.argc == 0) { + ast_log(LOG_ERROR, "No filename specified.\n"); + return -1; + } + if (args.argc == 1) { + ast_debug(1, "No offset, use function : file_write_char()\n"); + return file_write_char(chan, cmd, data2, value); + } + + if (args.argc > 2) { + if (toupper(args.offset[0]) == 'L' && strlen(args.length) > 0 && toupper(args.length[0]) != 'L') { + ast_log(LOG_ERROR, "Offset (%s) begin with 'L' but not Length (%s).\n", args.offset, args.length); + return -1; + } + if (toupper(args.offset[0]) != 'L' && toupper(args.length[0]) == 'L') { + ast_log(LOG_ERROR, "Length begin with 'L' but not Offset.\n"); + return -1; + } + } + if (toupper(args.offset[0]) != 'L') { + ast_debug(1, "use function : file_write_char(), args = %d, data = %s\n", args.argc, data2); + return file_write_char(chan, cmd, data2, value); + } + ast_debug(1, "use function : file_write_line()\n"); + return file_write_line(chan, cmd, data2, value); +} + +static int file_count_line(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(filename); + AST_APP_ARG(format); + ); + int j = 0; + char *contents, newline_format = 'x'; + + AST_STANDARD_APP_ARGS(args, data); + if (args.argc > 1) { + if (args.format[0] == 'd' || args.format[0] == 'D') { + newline_format = 'd'; + } + if (args.format[0] == 'm' || args.format[0] == 'M') { + newline_format = 'm'; + } + if (args.format[0] == 'u' || args.format[0] == 'U') { + newline_format = 'u'; + } + } + + if (!(contents = ast_read_textfile(args.filename))) { + ast_copy_string(buf, "-1", len); + return 0; + } + if (newline_format == 'x') { + newline_format=get_file_format(contents); + } + j = get_file_line_count(contents, newline_format); + snprintf(buf, len, "%d", (int) j); + ast_free(contents); + return 0; +} + +static int file_format(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(filename); + ); + char *contents, newline_format[2]; + + AST_STANDARD_APP_ARGS(args, data); + + if (!(contents = ast_read_textfile(args.filename))) { + ast_copy_string(buf, "-1", len); + return 0; + } + + sprintf(newline_format, "%c", get_file_format(contents)); + + ast_copy_string(buf, newline_format, len); + ast_free(contents); + + return 0; } static struct ast_custom_function env_function = { @@ -235,12 +1037,18 @@ static struct ast_custom_function file_function = { .name = "FILE", - .read = file_read - /* - * Some enterprising programmer could probably add write functionality - * to FILE(), although I'm not sure how useful it would be. Hence why - * it's called FILE and not READFILE (like the app was). - */ + .read = file_read, + .write = file_write +}; + +static struct ast_custom_function file_count_line_function = { + .name = "FILE_COUNT_LINE", + .read = file_count_line +}; + +static struct ast_custom_function file_format_function = { + .name = "FILE_FORMAT", + .read = file_format }; static int unload_module(void) @@ -250,6 +1058,8 @@ res |= ast_custom_function_unregister(&env_function); res |= ast_custom_function_unregister(&stat_function); res |= ast_custom_function_unregister(&file_function); + res |= ast_custom_function_unregister(&file_count_line_function); + res |= ast_custom_function_unregister(&file_format_function); return res; } @@ -261,6 +1071,8 @@ res |= ast_custom_function_register(&env_function); res |= ast_custom_function_register(&stat_function); res |= ast_custom_function_register(&file_function); + res |= ast_custom_function_register(&file_count_line_function); + res |= ast_custom_function_register(&file_format_function); return res; }