diff options
Diffstat (limited to 'funcs')
-rw-r--r-- | funcs/func_env.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/funcs/func_env.c b/funcs/func_env.c index c56c50d71..707e96a12 100644 --- a/funcs/func_env.c +++ b/funcs/func_env.c @@ -74,11 +74,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") <syntax> <parameter name="filename" required="true" /> <parameter name="offset" required="true"> - <para>Maybe specified as any number. if negative <replaceable>offset</replaceable> specifies the number + <para>Maybe specified as any number. If negative, <replaceable>offset</replaceable> specifies the number of bytes back from the end of the file.</para> </parameter> <parameter name="length" required="true"> - <para>If specified, will limit the length of the data read to that size.</para> + <para>If specified, will limit the length of the data read to that size. If negative, + trims <replaceable>length</replaceable> bytes from the end of the file.</para> </parameter> </syntax> <description> @@ -166,40 +167,59 @@ static int file_read(struct ast_channel *chan, const char *cmd, char *data, char AST_APP_ARG(offset); AST_APP_ARG(length); ); - int offset = 0, length; + int offset = 0, length, res = 0; char *contents; + size_t contents_len; AST_STANDARD_APP_ARGS(args, data); - if (args.argc > 1) + if (args.argc > 1) { offset = atoi(args.offset); + } if (args.argc > 2) { - if ((length = atoi(args.length)) < 1) { - ast_log(LOG_WARNING, "Invalid length '%s'. Returning the max (%d)\n", args.length, (int)len); - length = len; - } else if (length > len) { - ast_log(LOG_WARNING, "Length %d is greater than the max (%d). Truncating output.\n", length, (int)len); + /* The +1/-1 in this code section is to accomodate for the terminating NULL. */ + if ((length = atoi(args.length) + 1) > len) { + ast_log(LOG_WARNING, "Length %d is greater than the max (%d). Truncating output.\n", length - 1, (int)len - 1); length = len; } - } else + } else { length = len; + } - if (!(contents = ast_read_textfile(args.filename))) + if (!(contents = ast_read_textfile(args.filename))) { return -1; + } - if (offset >= 0) - ast_copy_string(buf, &contents[offset], length); - else { - size_t tmp = strlen(contents); - if (offset * -1 > tmp) { - ast_log(LOG_WARNING, "Offset is larger than the file size.\n"); - offset = tmp * -1; + do { + contents_len = strlen(contents); + if (offset > contents_len) { + res = -1; + break; } - ast_copy_string(buf, &contents[tmp + offset], length); - } + + 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); + } + } else { + if (offset * -1 > contents_len) { + ast_log(LOG_WARNING, "Offset is larger than the file size.\n"); + offset = contents_len * -1; + } + ast_copy_string(buf, &contents[contents_len + offset], length); + } + } while (0); + ast_free(contents); - return 0; + return res; } static struct ast_custom_function env_function = { |