--- 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-20 15:02:46.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,258 @@ 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 +616,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 +658,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 +676,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; }