/* * app_rss.c -- A module to navigate RSS feeds. * * Copyright (c) 2004-2007 Anthony Minessale II * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include static char *tdesc = "Play an RSS feed as an IVR"; static char *app = "RSS"; static char *synopsis = "Play an RSS feed as an IVR"; static char *desc = "" " RSS()\n" "Will make a navigatable menu from the rss dump made by rss2ivr.pl\n" "The dump dir will reside in /var/lib/asterisk/rss by default\n\n" ""; STANDARD_LOCAL_USER; LOCAL_USER_DECL; static int rss_exec(struct ast_channel *chan, void *data) { struct localuser *u; int res = 0, pos = 0, digit = 0, x = 0; struct stat buf; char dst[256], *dir, in[3] = {}, *ext; struct ast_frame *f, dtmf_frame = {AST_FRAME_DTMF, '0'}; if (!data) { ast_log(LOG_WARNING, "rss requires an argument\n"); return -1; } LOCAL_USER_ADD(u); dir = ast_strdupa(data); snprintf(dst, sizeof(dst), "%s/rss/%s", ast_config_AST_VAR_DIR, dir); if (chdir(dst)) { ast_log(LOG_WARNING, "Cannot find %s\n", dst); return -1; } while (chan && ! ast_check_hangup(chan)) { ast_queue_frame(chan, &dtmf_frame); ast_queue_frame(chan, &dtmf_frame); while ((ast_waitfor(chan, -1)) > -1 && (f = ast_read(chan))) { if ((f->frametype == AST_FRAME_DTMF)) { if (f->subclass == '#') { ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT); } else { if (pos < sizeof(in)-1) { in[pos++] = f->subclass; } else { for(x=0; x < (pos - 1); x++) { in[x] = in[x+1]; } in[x++] = f->subclass; in[x++] = '\0'; } snprintf(dst, sizeof(dst), "%s/rss/%s/%s@raw", ast_config_AST_VAR_DIR, dir, in); if ((ext = strchr(dst, '@'))) { *ext = '.'; } if (ext && !stat(dst, &buf)) { *ext = '\0'; snprintf(dst, sizeof(dst), "%s/rss/%s/%s", ast_config_AST_VAR_DIR, dir, in); dtmf_frame.subclass = '0'; pos = 0; memset(in, 0, sizeof(in)); ast_stopstream(chan); if (ast_streamfile(chan, dst, chan->language)) { break; } digit = ast_waitstream(chan, AST_DIGIT_ANY); if ((digit <= 0)) { break; } else if (digit) { dtmf_frame.subclass = digit; ast_queue_frame(chan, &dtmf_frame); digit = 0; } } } ast_frfree(f); } } } LOCAL_USER_REMOVE(u); return res; } int unload_module(void) { STANDARD_HANGUP_LOCALUSERS; return ast_unregister_application(app); } int load_module(void) { return ast_register_application(app, rss_exec, synopsis, desc); } char *description(void) { return tdesc; } int usecount(void) { int res; STANDARD_USECOUNT(res); return res; } char *key() { return ASTERISK_GPL_KEY; }