/* Recalculate outbound channel */
other = isoutbound ? p->owner : p->chan;
- /* Set glare detection */
- ast_set_flag(p, LOCAL_GLARE_DETECT);
- if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
- /* We had a glare on the hangup. Forget all this business,
- return and destroy p. */
- ast_mutex_unlock(&p->lock);
- p = local_pvt_destroy(p);
- return -1;
- }
if (!other) {
- ast_clear_flag(p, LOCAL_GLARE_DETECT);
return 0;
}
/* do not queue frame if generator is on both local channels */
- if (us && us->generator && other->generator)
+ if (us && us->generator && other->generator) {
return 0;
+ }
+
+ /* Set glare detection */
+ ast_set_flag(p, LOCAL_GLARE_DETECT);
/* Ensure that we have both channels locked */
while (other && ast_channel_trylock(other)) {
other = isoutbound ? p->owner : p->chan;
}
+ /* Since glare detection only occurs within this function, and because
+ * a pvt flag cannot be set without having the pvt lock, this is the only
+ * location where we could detect a cancelling of the queue. */
+ if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
+ /* We had a glare on the hangup. Forget all this business,
+ return and destroy p. */
+ ast_mutex_unlock(&p->lock);
+ p = local_pvt_destroy(p);
+ return -1;
+ }
+
if (other) {
ast_queue_frame(other, f);
ast_channel_unlock(other);
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 = {