--- asterisk-1.6.1.6/funcs/func_env.c.ori 2009-11-06 15:39:08.000000000 +0100 +++ asterisk-1.6.1.6/funcs/func_env.c 2009-12-17 15:26:31.000000000 +0100 @@ -32,6 +32,7 @@ #include "asterisk/pbx.h" #include "asterisk/utils.h" #include "asterisk/app.h" +#include "asterisk/file.h" static int env_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) @@ -168,6 +169,259 @@ 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", .synopsis = "Gets or sets the environment variable specified", @@ -209,6 +463,111 @@ ", if specified, will limit the length of the data read to that size.\n", }; +static struct ast_custom_function file_count_line_function = { + .name = "FILE_COUNT_LINE", + .synopsis = "Obtains the number of lines of a text file", + .syntax = "FILE_COUNT_LINE([,])", + .read = file_count_line, + .desc = +"FILE_COUNT_LINE([,]) : count the number of lines in a text file\n" +" name of text file\n" +", if specified gives the newline format :\n" +"'u' - Unix newline format (default)\n" +"'d' - Dos newline format\n" +"'m' - Mac newline format\n\n" +"Return value :\n" +"Return the number of line or -1 on error.\n", +}; + +static struct ast_custom_function file_read_line_function = { + .name = "FILE_READ_LINE", + .synopsis = "Read one line of a text file", + .syntax = "FILE_READ_LINE([,[,]])", + .read = file_read_line, + .desc = +"FILE_READ_LINE([,[,]]) : Read one line of a text file\n" +" name of text file\n" +", if specified, the line to be read, default first.\n" +", if specified gives the newline format :\n" +"'u' - Unix newline format (default)\n" +"'d' - Dos newline format\n" +"'m' - Mac newline format\n\n" +"Return value :\n" +"Return the content of line or -1 on error.\n", +}; + +static struct ast_custom_function file_write_function = { + .name = "FILE_WRITE", + .synopsis = "Write string on file", + .syntax = "FILE_WRITE(,)", + .read = file_write, + .desc = +" name of text file\n" +" the string to write.\n\n" +"Return value :\n" +"Return the len of string or -1 on error.\n", +}; + +static struct ast_custom_function file_write_line_function = { + .name = "FILE_WRITE_LINE", + .synopsis = "Write string on file and append a newline", + .syntax = "FILE_WRITE_LINE(,[,])", + .read = file_write_line, + .desc = +" name of text file\n" +" the string to write.\n" +", if specified gives the newline format :\n" +"'u' - Unix newline format (default)\n" +"'d' - Dos newline format\n" +"'m' - Mac newline format\n\n" +"Return value :\n" +"Return the len of string or -1 on error.\n", +}; + +static struct ast_custom_function file_append_function = { + .name = "FILE_APPEND", + .synopsis = "Append string on file", + .syntax = "FILE_APPEND(,)", + .read = file_append, + .desc = +" name of text file\n" +" the string to write at the end of file.\n\n" +"Return value :\n" +"Return the len of string or -1 on error.\n", +}; + +static struct ast_custom_function file_append_line_function = { + .name = "FILE_APPEND_LINE", + .synopsis = "Append string on file with newline", + .syntax = "FILE_APPEND_LINE(,[,])", + .read = file_append_line, + .desc = +" name of text file\n" +" the string to write at the end of file.\n" +", if specified gives the newline format :\n" +"'u' - Unix newline format (default)\n" +"'d' - Dos newline format\n" +"'m' - Mac newline format\n\n" +"Return value :\n" +"Return the len of string or -1 on error.\n", +}; + +static struct ast_custom_function file_format_function = { + .name = "FILE_FORMAT", + .synopsis = "gives the format of a text file", + .syntax = "FILE_FORMAT()", + .read = file_format, + .desc = +"FILE_FORMAT() : gives the format of a text file\n" +" name of text file\n" +"Return value :\n" +"Return the format of new line or -1 on error.\n", +"format will be one of the following :\n" +"'u' - Unix newline format\n" +"'d' - Dos newline format\n" +"'m' - Mac newline format\n\n" +}; + static int unload_module(void) { int res = 0; @@ -216,6 +575,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; } @@ -227,6 +593,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; }