--- 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;
}