--- 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-05-25 11:17:32.000000000 +0200 @@ -32,6 +32,7 @@ #include "asterisk/pbx.h" #include "asterisk/utils.h" #include "asterisk/app.h" +#include "asterisk/file.h" /*** DOCUMENTATION @@ -85,6 +86,126 @@ + + + Obtains the number of lines of a text file. + + + + + Format may be one of the following: + u - Unix newline format (default). + d - Dos newline format. + m - Mac newline format + + + + Returns the number of lines, or -1 on error. + + + + + Read one line of a text file. + + + + + specifies the line to read, by default the first. + + + Format may be one of the following: + u - Unix newline format (default). + d - Dos newline format. + m - Mac newline format + + + + Return the content of line, or -1 on error. + + + + + Writes the string in the file. Erases the entire contents of the file before writing. + + + + + the string to write. + + + + Return the len of the string, or -1 on error. + + + + + Writes the string in the file and append a newline. Erases the entire contents of the file before writing. + + + + + the string to write. + + + Format may be one of the following: + u - Unix newline format (default). + d - Dos newline format. + m - Mac newline format + + + + Return the len of the string, or -1 on error. + + + + + Append the string at the end of the file. + + + + + the string to write. + + + + Return the len of the string, or -1 on error. + + + + + Append the string at the end of the file and add a newline. + + + + + the string to write. + + + Format may be one of the following: + u - Unix newline format (default). + d - Dos newline format. + m - Mac newline format + + + + Return the len of the string, or -1 on error. + + + + + Return the format of a text file. + + + + + + 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 + + ***/ static int env_read(struct ast_channel *chan, const char *cmd, char *data, @@ -222,6 +343,311 @@ return res; } +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, i = 0; + char *contents, newline_format = 'u'; + + 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 (!(contents = ast_read_textfile(args.filename))) { + ast_copy_string(buf, "-1", len); + return 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++; + } + } + } + snprintf(buf, len, "%d", (int) j); + ast_free(contents); + return 0; +} + +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(linenumber); + AST_APP_ARG(format); + ); + int j = 0, i = 0, k = 0, linenumber = 1; + char *contents, newline_format = 'u'; + + AST_STANDARD_APP_ARGS(args, data); + if (args.argc > 1) linenumber = atoi(args.linenumber); + if (args.argc > 2) { + 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 (linenumber<1) { + ast_log(LOG_WARNING, "The line number cannot be less than 1\n"); + ast_copy_string(buf, "", len); + return 0; + } + if (!(contents = ast_read_textfile(args.filename))) { + ast_debug(1, "File %s is empty\n", args.filename); + ast_copy_string(buf, "", len); + return 0; + } + 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 == linenumber) { + break; + } + 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 != linenumber) { + ast_debug(1, "Line %d not found\n", linenumber); + ast_copy_string(buf, "", len); + } else { + j = i-k+1; + if (newline_format == 'd') { + j--; + } + ast_debug(1, "Line %d found, begin : %d, len %d\n", linenumber, k, j); + ast_copy_string(buf, &contents[k], j); + } + ast_free(contents); + return 0; +} + +static int file_write(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(write_string); + ); + int fd, i = 0; + + AST_STANDARD_APP_ARGS(args, data); + if (args.argc < 2 || strlen(args.write_string) == 0) { + ast_log(LOG_WARNING, "The string is empty, nothing has been written\n"); + snprintf(buf, len, "%d", 0); + return 0; + } + if ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_TRUNC) ) < 0) { + ast_log(LOG_WARNING, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + snprintf(buf, len, "%d", -1); + return 0; + } + i = write(fd, args.write_string, strlen(args.write_string)); + close(fd); + snprintf(buf, len, "%d", (int) i); + return 0; +} + +static int file_write_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(write_string); + AST_APP_ARG(format); + ); + int fd, i = 0; + char newline_format = 'u'; + + AST_STANDARD_APP_ARGS(args, data); + if (args.argc < 2 || strlen(args.write_string) == 0) { + ast_log(LOG_WARNING, "The string is empty, nothing has been written\n"); + snprintf(buf, len, "%d", 0); + return 0; + } + if (args.argc > 2) { + 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 ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_TRUNC) ) < 0) { + ast_log(LOG_WARNING, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + snprintf(buf, len, "%d", -1); + return 0; + } + i = write(fd, args.write_string, strlen(args.write_string)); + if (newline_format == 'u') { + write(fd, "\n", strlen("\n")); + } else { + write(fd, "\r", strlen("\r")); + if (newline_format == 'd') { + write(fd, "\n", strlen("\n")); + } + } + close(fd); + snprintf(buf, len, "%d", (int) i); + return 0; +} + +static int file_append(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(write_string); + ); + int fd, i = 0; + + AST_STANDARD_APP_ARGS(args, data); + if (args.argc < 2 || strlen(args.write_string) == 0) { + ast_log(LOG_WARNING, "The string is empty, nothing has been written\n"); + snprintf(buf, len, "%d", 0); + return 0; + } + + if ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_APPEND) ) < 0) { + ast_log(LOG_WARNING, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + snprintf(buf, len, "%d", -1); + return 0; + } + i = write(fd, args.write_string, strlen(args.write_string)); + close(fd); + snprintf(buf, len, "%d", (int) i); + return 0; +} + +static int file_append_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(write_string); + AST_APP_ARG(format); + ); + int fd, i = 0; + char newline_format = 'u'; + + AST_STANDARD_APP_ARGS(args, data); + if (args.argc < 2 || strlen(args.write_string) == 0) { + ast_log(LOG_WARNING, "The string is empty, nothing has been written\n"); + snprintf(buf, len, "%d", 0); + return 0; + } + if (args.argc > 2) { + 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 ( (fd = open(args.filename, O_CREAT | O_WRONLY | O_APPEND) ) < 0) { + ast_log(LOG_WARNING, "Cannot open file '%s' for writing: %s\n",args.filename, strerror(errno)); + snprintf(buf, len, "%d", -1); + return 0; + } + i = write(fd, args.write_string, strlen(args.write_string)); + if (newline_format == 'u') { + write(fd, "\n", strlen("\n")); + } else { + write(fd, "\r", strlen("\r")); + if (newline_format == 'd') { + write(fd, "\n", strlen("\n")); + } + } + close(fd); + snprintf(buf, len, "%d", (int) i); + 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); + ); + int i = 0; + 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; + } + strcpy(newline_format,"u"); + for (i = 0; i < strlen(contents); i++) { + if (contents[i] == 13) { + if (i < (strlen(contents)-1) && contents[i+1] == 10) { + strcpy(newline_format,"d"); + } else { + strcpy(newline_format,"m"); + } + break; + } + if (contents[i] == 10) { + break; + } + } + ast_copy_string(buf, newline_format, len); + ast_free(contents); + return 0; +} + static struct ast_custom_function env_function = { .name = "ENV", .read = env_read, @@ -243,6 +669,41 @@ */ }; +static struct ast_custom_function file_count_line_function = { + .name = "FILE_COUNT_LINE", + .read = file_count_line +}; + +static struct ast_custom_function file_read_line_function = { + .name = "FILE_READ_LINE", + .read = file_read_line +}; + +static struct ast_custom_function file_write_function = { + .name = "FILE_WRITE", + .read = file_write +}; + +static struct ast_custom_function file_write_line_function = { + .name = "FILE_WRITE_LINE", + .read = file_write_line +}; + +static struct ast_custom_function file_append_function = { + .name = "FILE_APPEND", + .read = file_append +}; + +static struct ast_custom_function file_append_line_function = { + .name = "FILE_APPEND_LINE", + .read = file_append_line +}; + +static struct ast_custom_function file_format_function = { + .name = "FILE_FORMAT", + .read = file_format +}; + static int unload_module(void) { int res = 0; @@ -250,6 +711,13 @@ 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_read_line_function); + res |= ast_custom_function_unregister(&file_write_function); + res |= ast_custom_function_unregister(&file_write_line_function); + res |= ast_custom_function_unregister(&file_append_function); + res |= ast_custom_function_unregister(&file_append_line_function); + res |= ast_custom_function_unregister(&file_format_function); return res; } @@ -261,6 +729,13 @@ 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_read_line_function); + res |= ast_custom_function_register(&file_write_function); + res |= ast_custom_function_register(&file_write_line_function); + res |= ast_custom_function_register(&file_append_function); + res |= ast_custom_function_register(&file_append_line_function); + res |= ast_custom_function_register(&file_format_function); return res; }