int getPass(struct ast_channel *chan, struct userkeyin dtmfinput, struct roomdetails *dtmfmatch) { char *prompt; /* char *invalid; */ int res = 0, retry=0; prompt = "agent-pass"; if(ast_app_getdata(chan, prompt, dtmfinput.inpass, sizeof(dtmfinput.inpass) - 2, 0) < 0) return -1; res = ast_waitstream(chan,""); res = passQuery(dtmfinput, dtmfmatch); while (retry++ < 2 && res !=1){ prompt = "auth-incorrect"; if(ast_app_getdata(chan, prompt, dtmfinput.inpass, sizeof(dtmfinput.inpass) - 2, 0) < 0) return -1; res = ast_waitstream(chan,""); res = passQuery(dtmfinput, dtmfmatch); if(res==1) break; } if(retry>1 && res != 1){ prompt = "vm-goodbye"; if (!ast_streamfile(chan, prompt, chan->language)){ res = ast_waitstream(chan,""); ast_stopstream(chan); } res = -1; } return res; }
int getConf(struct ast_channel *chan, struct userkeyin dtmfinput, struct roomdetails *dtmfmatch) { char *prompt; /* char *invalid;*/ int res=0, retry=0, skip=0; if (ast_strlen_zero(dtmfinput.inroom)){ strcpy(dtmfinput.inroom, ""); } else { skip = 1; retry = 2; } while (retry++ < 3){ if(!skip){ prompt = "conf-getconfno"; if(ast_app_getdata(chan, prompt, dtmfinput.inroom, sizeof(dtmfinput.inroom) - 2, 0) < 0) return -1; res = ast_waitstream(chan,""); } res = roomQuery(dtmfinput, dtmfmatch); if(res==1 || res==2) break; if(res == -2){ prompt = "conf-has-not-started"; if (!ast_streamfile(chan, prompt, chan->language)){ res = ast_waitstream(chan,""); ast_stopstream(chan); } res = -1; break; } prompt = "conf-invalid"; if (!ast_streamfile(chan, prompt, chan->language)){ res = ast_waitstream(chan,""); ast_stopstream(chan); } } if(retry>=2 && (res < 1 && !skip)){ prompt = "vm-goodbye"; if (!ast_streamfile(chan, prompt, chan->language)){ res = ast_waitstream(chan,""); ast_stopstream(chan); } res = -1; } return res; }
static int exec(struct ast_channel *chan, void *data, int dahdimode) { int res=-1; struct ast_module_user *u; int retrycnt = 0; int confflags = 0; int confno = 0; char confstr[80] = ""; u = ast_module_user_add(chan); if (!ast_strlen_zero(data)) { if (dahdimode) { if ((sscanf(data, "DAHDI/%30d", &confno) != 1) && (sscanf(data, "%30d", &confno) != 1)) { ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data); ast_module_user_remove(u); return 0; } } else { if ((sscanf(data, "Zap/%30d", &confno) != 1) && (sscanf(data, "%30d", &confno) != 1)) { ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data); ast_module_user_remove(u); return 0; } } } if (chan->_state != AST_STATE_UP) ast_answer(chan); while(!confno && (++retrycnt < 4)) { /* Prompt user for conference number */ confstr[0] = '\0'; res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0); if (res <0) goto out; if (sscanf(confstr, "%30d", &confno) != 1) confno = 0; } if (confno) { /* XXX Should prompt user for pin if pin is required XXX */ /* Run the conference */ res = conf_run(chan, confno, confflags); } out: /* Do the conference */ ast_module_user_remove(u); return res; }
static int testserver_exec(struct ast_channel *chan, const char *data) { int res = 0; char testid[80]=""; char fn[80]; FILE *f; if (ast_channel_state(chan) != AST_STATE_UP) res = ast_answer(chan); /* Read version */ ast_debug(1, "Read client version\n"); if (!res) res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0); if (res > 0) res = 0; ast_debug(1, "client version: %s\n", testid); ast_debug(1, "Transmit server version\n"); res = ast_safe_sleep(chan, 1000); if (!res) res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0); if (res > 0) res = 0; if (!res) res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0); ast_debug(1, "read test identifier: %s\n", testid); /* Check for sneakyness */ if (strchr(testid, '/')) res = -1; if ((res >=0) && (!ast_strlen_zero(testid))) { /* Got a Test ID! Whoo hoo! */ /* Make the directory to hold the test results in case it's not there */ snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR); ast_mkdir(fn, 0777); snprintf(fn, sizeof(fn), "%s/testresults/%s-server.txt", ast_config_AST_LOG_DIR, testid); if ((f = fopen(fn, "w+"))) { setlinebuf(f); fprintf(f, "SERVERCHAN: %s\n", ast_channel_name(chan)); fprintf(f, "SERVERTEST ID: %s\n", testid); fprintf(f, "ANSWER: PASS\n"); ast_debug(1, "Processing Test ID '%s'\n", testid); res = ast_safe_sleep(chan, 1000); if (!res) { /* Step 1: Send "1" */ ast_debug(1, "TestServer: 1. Send DTMF 1\n"); res = ast_dtmf_stream(chan, NULL, "1", 0,0 ); fprintf(f, "SEND DTMF 1: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 2: Wait for "2" */ ast_debug(1, "TestServer: 2. Wait DTMF 2\n"); res = ast_waitfordigit(chan, 3000); fprintf(f, "WAIT DTMF 2: %s\n", (res != '2') ? "FAIL" : "PASS"); if (res == '2') res = 0; else res = -1; } if (!res) { /* Step 3: Measure noise */ ast_debug(1, "TestServer: 3. Measure noise\n"); res = measurenoise(chan, 6000, "TestServer"); fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res); if (res > 0) res = 0; } if (!res) { /* Step 4: Send "4" */ ast_debug(1, "TestServer: 4. Send DTMF 4\n"); res = ast_dtmf_stream(chan, NULL, "4", 0, 0); fprintf(f, "SEND DTMF 4: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 5: Wait one second */ ast_debug(1, "TestServer: 5. Wait one second\n"); res = ast_safe_sleep(chan, 1000); fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 6: Measure noise */ ast_debug(1, "TestServer: 6. Measure tone\n"); res = measurenoise(chan, 4000, "TestServer"); fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res); if (res > 0) res = 0; } if (!res) { /* Step 7: Send "5" */ ast_debug(1, "TestServer: 7. Send DTMF 5\n"); res = ast_dtmf_stream(chan, NULL, "5", 0, 0); fprintf(f, "SEND DTMF 5: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 8: Transmit tone noise */ ast_debug(1, "TestServer: 8. Transmit tone\n"); res = sendnoise(chan, 6000); fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS"); } if (!res || (res == '7')) { /* Step 9: Wait for "7" */ ast_debug(1, "TestServer: 9. Wait DTMF 7\n"); if (!res) res = ast_waitfordigit(chan, 3000); fprintf(f, "WAIT DTMF 7: %s\n", (res != '7') ? "FAIL" : "PASS"); if (res == '7') res = 0; else res = -1; } if (!res) { res = ast_safe_sleep(chan, 1000); } if (!res) { /* Step 10: Send "8" */ ast_debug(1, "TestServer: 10. Send DTMF 8\n"); res = ast_dtmf_stream(chan, NULL, "8", 0, 0); fprintf(f, "SEND DTMF 8: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 11: Wait for hangup to arrive! */ ast_debug(1, "TestServer: 11. Waiting for hangup\n"); res = ast_safe_sleep(chan, 10000); fprintf(f, "WAIT HANGUP: %s\n", (res < 0) ? "PASS" : "FAIL"); } ast_log(LOG_NOTICE, "-- TEST COMPLETE--\n"); fprintf(f, "-- END TEST--\n"); fclose(f); res = -1; } else res = -1; } else { ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", ast_channel_name(chan)); res = -1; } return res; }
static int testclient_exec(struct ast_channel *chan, const char *data) { int res = 0; const char *testid=data; char fn[80]; char serverver[80]; FILE *f; /* Check for test id */ if (ast_strlen_zero(testid)) { ast_log(LOG_WARNING, "TestClient requires an argument - the test id\n"); return -1; } if (ast_channel_state(chan) != AST_STATE_UP) res = ast_answer(chan); /* Wait a few just to be sure things get started */ res = ast_safe_sleep(chan, 3000); /* Transmit client version */ if (!res) res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0); ast_debug(1, "Transmit client version\n"); /* Read server version */ ast_debug(1, "Read server version\n"); if (!res) res = ast_app_getdata(chan, NULL, serverver, sizeof(serverver) - 1, 0); if (res > 0) res = 0; ast_debug(1, "server version: %s\n", serverver); if (res > 0) res = 0; if (!res) res = ast_safe_sleep(chan, 1000); /* Send test id */ if (!res) res = ast_dtmf_stream(chan, NULL, testid, 0, 0); if (!res) res = ast_dtmf_stream(chan, NULL, "#", 0, 0); ast_debug(1, "send test identifier: %s\n", testid); if ((res >=0) && (!ast_strlen_zero(testid))) { /* Make the directory to hold the test results in case it's not there */ snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR); ast_mkdir(fn, 0777); snprintf(fn, sizeof(fn), "%s/testresults/%s-client.txt", ast_config_AST_LOG_DIR, testid); if ((f = fopen(fn, "w+"))) { setlinebuf(f); fprintf(f, "CLIENTCHAN: %s\n", ast_channel_name(chan)); fprintf(f, "CLIENTTEST ID: %s\n", testid); fprintf(f, "ANSWER: PASS\n"); res = 0; if (!res) { /* Step 1: Wait for "1" */ ast_debug(1, "TestClient: 2. Wait DTMF 1\n"); res = ast_waitfordigit(chan, 3000); fprintf(f, "WAIT DTMF 1: %s\n", (res != '1') ? "FAIL" : "PASS"); if (res == '1') res = 0; else res = -1; } if (!res) { res = ast_safe_sleep(chan, 1000); } if (!res) { /* Step 2: Send "2" */ ast_debug(1, "TestClient: 2. Send DTMF 2\n"); res = ast_dtmf_stream(chan, NULL, "2", 0, 0); fprintf(f, "SEND DTMF 2: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 3: Wait one second */ ast_debug(1, "TestClient: 3. Wait one second\n"); res = ast_safe_sleep(chan, 1000); fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 4: Measure noise */ ast_debug(1, "TestClient: 4. Measure noise\n"); res = measurenoise(chan, 5000, "TestClient"); fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res); if (res > 0) res = 0; } if (!res) { /* Step 5: Wait for "4" */ ast_debug(1, "TestClient: 5. Wait DTMF 4\n"); res = ast_waitfordigit(chan, 3000); fprintf(f, "WAIT DTMF 4: %s\n", (res != '4') ? "FAIL" : "PASS"); if (res == '4') res = 0; else res = -1; } if (!res) { /* Step 6: Transmit tone noise */ ast_debug(1, "TestClient: 6. Transmit tone\n"); res = sendnoise(chan, 6000); fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS"); } if (!res || (res == '5')) { /* Step 7: Wait for "5" */ ast_debug(1, "TestClient: 7. Wait DTMF 5\n"); if (!res) res = ast_waitfordigit(chan, 3000); fprintf(f, "WAIT DTMF 5: %s\n", (res != '5') ? "FAIL" : "PASS"); if (res == '5') res = 0; else res = -1; } if (!res) { /* Step 8: Wait one second */ ast_debug(1, "TestClient: 8. Wait one second\n"); res = ast_safe_sleep(chan, 1000); fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res = 0; } if (!res) { /* Step 9: Measure noise */ ast_debug(1, "TestClient: 9. Measure tone\n"); res = measurenoise(chan, 4000, "TestClient"); fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res); if (res > 0) res = 0; } if (!res) { /* Step 10: Send "7" */ ast_debug(1, "TestClient: 10. Send DTMF 7\n"); res = ast_dtmf_stream(chan, NULL, "7", 0, 0); fprintf(f, "SEND DTMF 7: %s\n", (res < 0) ? "FAIL" : "PASS"); if (res > 0) res =0; } if (!res) { /* Step 11: Wait for "8" */ ast_debug(1, "TestClient: 11. Wait DTMF 8\n"); res = ast_waitfordigit(chan, 3000); fprintf(f, "WAIT DTMF 8: %s\n", (res != '8') ? "FAIL" : "PASS"); if (res == '8') res = 0; else res = -1; } if (!res) { res = ast_safe_sleep(chan, 1000); } if (!res) { /* Step 12: Hangup! */ ast_debug(1, "TestClient: 12. Hangup\n"); } ast_debug(1, "-- TEST COMPLETE--\n"); fprintf(f, "-- END TEST--\n"); fclose(f); res = -1; } else res = -1; } else { ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", ast_channel_name(chan)); res = -1; } return res; }
/*--- conf_exec: The meetme() application */ static int conf_exec(struct ast_channel *chan, void *data) { int res=-1; struct localuser *u; char confno[AST_MAX_EXTENSION] = ""; int allowretry = 0; int retrycnt = 0; struct ast_conference *cnf; int confflags = 0; int dynamic = 0; int empty = 0, empty_no_pin = 0; char *notdata, *info, *inflags = NULL, *inpin = NULL, the_pin[AST_MAX_EXTENSION] = ""; if (!data || ast_strlen_zero(data)) { allowretry = 1; notdata = ""; } else { notdata = data; } LOCAL_USER_ADD(u); if (chan->_state != AST_STATE_UP) ast_answer(chan); info = ast_strdupa((char *)notdata); if (info) { char *tmp = strsep(&info, "|"); strncpy(confno, tmp, sizeof(confno) - 1); if (ast_strlen_zero(confno)) { allowretry = 1; } } if (info) inflags = strsep(&info, "|"); if (info) inpin = strsep(&info, "|"); if (inpin) strncpy(the_pin, inpin, sizeof(the_pin) - 1); if (inflags) { if (strchr(inflags, 'a')) confflags |= CONFFLAG_ADMIN; if (strchr(inflags, 'm')) confflags |= CONFFLAG_MONITOR; if (strchr(inflags, 'p')) confflags |= CONFFLAG_POUNDEXIT; if (strchr(inflags, 's')) confflags |= CONFFLAG_STARMENU; if (strchr(inflags, 't')) confflags |= CONFFLAG_TALKER; if (strchr(inflags, 'q')) confflags |= CONFFLAG_QUIET; if (strchr(inflags, 'M')) confflags |= CONFFLAG_MOH; if (strchr(inflags, 'x')) confflags |= CONFFLAG_MARKEDEXIT; if (strchr(inflags, 'X')) confflags |= CONFFLAG_EXIT_CONTEXT; if (strchr(inflags, 'A')) confflags |= CONFFLAG_MARKEDUSER; if (strchr(inflags, 'b')) confflags |= CONFFLAG_AGI; if (strchr(inflags, 'w')) confflags |= CONFFLAG_WAITMARKED; if (strchr(inflags, 'd')) dynamic = 1; if (strchr(inflags, 'D')) { dynamic = 1; if (! inpin) { strncpy(the_pin, "q", sizeof(the_pin) - 1); } } if (strchr(inflags, 'e')) empty = 1; if (strchr(inflags, 'E')) { empty = 1; empty_no_pin = 1; } } do { if (retrycnt > 3) allowretry = 0; if (empty) { int i, map[1024]; struct ast_config *cfg; struct ast_variable *var; int confno_int; memset(map, 0, sizeof(map)); ast_mutex_lock(&conflock); cnf = confs; while (cnf) { if (sscanf(cnf->confno, "%d", &confno_int) == 1) { /* Disqualify in use conference */ if (confno_int >= 0 && confno_int < 1024) map[confno_int]++; } cnf = cnf->next; } ast_mutex_unlock(&conflock); /* We only need to load the config file for static and empty_no_pin (otherwise we don't care) */ if ((empty_no_pin) || (!dynamic)) { cfg = ast_load("meetme.conf"); if (cfg) { var = ast_variable_browse(cfg, "rooms"); while(var) { if (!strcasecmp(var->name, "conf")) { char *stringp = ast_strdupa(var->value); if (stringp) { char *confno_tmp = strsep(&stringp, "|,"); int found = 0; if (sscanf(confno_tmp, "%d", &confno_int) == 1) { if ((confno_int >= 0) && (confno_int < 1024)) { if (stringp && empty_no_pin) { map[confno_int]++; } } } if (! dynamic) { /* For static: run through the list and see if this conference is empty */ ast_mutex_lock(&conflock); cnf = confs; while (cnf) { if (!strcmp(confno_tmp, cnf->confno)) { /* The conference exists, therefore it's not empty */ found = 1; break; } cnf = cnf->next; } ast_mutex_unlock(&conflock); if (!found) { /* At this point, we have a confno_tmp (static conference) that is empty */ if ((empty_no_pin && ((!stringp) || (stringp && (stringp[0] == '\0')))) || (!empty_no_pin)) { /* Case 1: empty_no_pin and pin is nonexistant (NULL) * Case 2: empty_no_pin and pin is blank (but not NULL) * Case 3: not empty_no_pin */ strncpy(confno, confno_tmp, sizeof(confno) - 1); break; /* XXX the map is not complete (but we do have a confno) */ } } } } else { ast_log(LOG_ERROR, "Out of memory\n"); } } var = var->next; } ast_destroy(cfg); } } /* Select first conference number not in use */ if (ast_strlen_zero(confno) && dynamic) { for (i=0;i<1024;i++) { if (!map[i]) { snprintf(confno, sizeof(confno), "%d", i); break; } } } /* Not found? */ if (ast_strlen_zero(confno)) { res = ast_streamfile(chan, "conf-noempty", chan->language); if (!res) ast_waitstream(chan, ""); } else { if (sscanf(confno, "%d", &confno_int) == 1) { res = ast_streamfile(chan, "conf-enteringno", chan->language); if (!res) { ast_waitstream(chan, ""); res = ast_say_digits(chan, confno_int, "", chan->language); } } else { ast_log(LOG_ERROR, "Could not scan confno '%s'\n", confno); } } } while (allowretry && (ast_strlen_zero(confno)) && (++retrycnt < 4)) { /* Prompt user for conference number */ res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0); if (res < 0) { /* Don't try to validate when we catch an error */ confno[0] = '\0'; allowretry = 0; break; } } if (!ast_strlen_zero(confno)) { /* Check the validity of the conference */ cnf = find_conf(chan, confno, 1, dynamic, the_pin); if (!cnf) { res = ast_streamfile(chan, "conf-invalid", chan->language); if (!res) ast_waitstream(chan, ""); res = -1; if (allowretry) confno[0] = '\0'; } else { if (!ast_strlen_zero(cnf->pin)) { char pin[AST_MAX_EXTENSION]=""; int j; /* Allow the pin to be retried up to 3 times */ for (j=0; j<3; j++) { if (*the_pin) { strncpy(pin, the_pin, sizeof(pin) - 1); res = 0; } else { /* Prompt user for pin if pin is required */ res = ast_app_getdata(chan, "conf-getpin", pin + strlen(pin), sizeof(pin) - 1 - strlen(pin), 0); } if (res >= 0) { if (!strcasecmp(pin, cnf->pin)) { /* Pin correct */ allowretry = 0; /* Run the conference */ res = conf_run(chan, cnf, confflags); break; } else { /* Pin invalid */ res = ast_streamfile(chan, "conf-invalidpin", chan->language); if (!res) ast_waitstream(chan, AST_DIGIT_ANY); if (res < 0) break; pin[0] = res; pin[1] = '\0'; res = -1; if (allowretry) confno[0] = '\0'; } } else { res = -1; allowretry = 0; break; } /* Don't retry pin with a static pin */ if (*the_pin) { break; } } } else { /* No pin required */ allowretry = 0; /* Run the conference */ res = conf_run(chan, cnf, confflags); } } } } while (allowretry); /* Do the conference */ LOCAL_USER_REMOVE(u); return res; }
static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin) { struct ast_config *cfg; struct ast_variable *var; struct ast_conference *cnf; /* Check first in the conference list */ ast_mutex_lock(&conflock); cnf = confs; while (cnf) { if (!strcmp(confno, cnf->confno)) break; cnf = cnf->next; } ast_mutex_unlock(&conflock); if (!cnf) { if (dynamic) { /* No need to parse meetme.conf */ ast_log(LOG_DEBUG, "Building dynamic conference '%s'\n", confno); if (dynamic_pin) { if (dynamic_pin[0] == 'q') { /* Query the user to enter a PIN */ ast_app_getdata(chan, "conf-getpin", dynamic_pin, AST_MAX_EXTENSION - 1, 0); } cnf = build_conf(confno, dynamic_pin, make, dynamic); } else { cnf = build_conf(confno, "", make, dynamic); } } else { /* Check the config */ cfg = ast_load("meetme.conf"); if (!cfg) { ast_log(LOG_WARNING, "No meetme.conf file :(\n"); return NULL; } var = ast_variable_browse(cfg, "rooms"); while(var) { if (!strcasecmp(var->name, "conf")) { /* Separate the PIN */ char *pin, *conf; if ((pin = ast_strdupa(var->value))) { conf = strsep(&pin, "|,"); if (!strcasecmp(conf, confno)) { /* Bingo it's a valid conference */ if (pin) cnf = build_conf(confno, pin, make, dynamic); else cnf = build_conf(confno, "", make, dynamic); break; } } } var = var->next; } if (!var) { ast_log(LOG_DEBUG, "%s isn't a valid conference\n", confno); } ast_destroy(cfg); } } else if (dynamic_pin) { /* Correct for the user selecting 'D' instead of 'd' to have someone join into a conference that has already been created with a pin. */ if (dynamic_pin[0] == 'q') dynamic_pin[0] = '\0'; } return cnf; }
static int read_exec(struct ast_channel *chan, void *data) { int res = 0; struct localuser *u; char tmp[256]; char *timeout = NULL; char *varname = NULL; char *filename = NULL; char *loops; char *maxdigitstr=NULL; char *options=NULL; int option_skip = 0; int option_noanswer = 0; int maxdigits=255; int tries = 1; int to = 0; int x = 0; char *argcopy = NULL; char *args[8]; if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "Read requires an argument (variable)\n"); return -1; } LOCAL_USER_ADD(u); argcopy = ast_strdupa(data); if (!argcopy) { ast_log(LOG_ERROR, "Out of memory\n"); LOCAL_USER_REMOVE(u); return -1; } if (ast_app_separate_args(argcopy, '|', args, sizeof(args) / sizeof(args[0])) < 1) { ast_log(LOG_WARNING, "Cannot Parse Arguments.\n"); LOCAL_USER_REMOVE(u); return -1; } varname = args[x++]; filename = args[x++]; maxdigitstr = args[x++]; options = args[x++]; loops = args[x++]; timeout = args[x++]; if (options) { if (!strcasecmp(options, "skip")) option_skip = 1; else if (!strcasecmp(options, "noanswer")) option_noanswer = 1; else { if (strchr(options, 's')) option_skip = 1; if (strchr(options, 'n')) option_noanswer = 1; } } if(loops) { tries = atoi(loops); if(tries <= 0) tries = 1; } if(timeout) { to = atoi(timeout); if (to <= 0) to = 0; else to *= 1000; } if (ast_strlen_zero(filename)) filename = NULL; if (maxdigitstr) { maxdigits = atoi(maxdigitstr); if ((maxdigits<1) || (maxdigits>255)) { maxdigits = 255; } else if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %d digits.\n", maxdigits); } if (ast_strlen_zero(varname)) { ast_log(LOG_WARNING, "Invalid! Usage: Read(variable[|filename][|maxdigits][|option][|attempts][|timeout])\n\n"); LOCAL_USER_REMOVE(u); return -1; } if (chan->_state != AST_STATE_UP) { if (option_skip) { /* At the user's option, skip if the line is not up */ pbx_builtin_setvar_helper(chan, varname, "\0"); LOCAL_USER_REMOVE(u); return 0; } else if (!option_noanswer) { /* Otherwise answer unless we're supposed to read while on-hook */ res = ast_answer(chan); } } if (!res) { while(tries && !res) { ast_stopstream(chan); res = ast_app_getdata(chan, filename, tmp, maxdigits, to); if (res > -1) { pbx_builtin_setvar_helper(chan, varname, tmp); if (!ast_strlen_zero(tmp)) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp); tries = 0; } else { tries--; if (option_verbose > 2) { if (tries) ast_verbose(VERBOSE_PREFIX_3 "User entered nothing, %d chance%s left\n", tries, (tries != 1) ? "s" : ""); else ast_verbose(VERBOSE_PREFIX_3 "User entered nothing.\n"); } } res = 0; } else { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n"); } } } LOCAL_USER_REMOVE(u); return res; }
static int auth_exec(struct ast_channel *chan, void *data) { int res=0; int retries; struct localuser *u; char password[256]=""; char passwd[256]; char *opts; char *prompt; if (!data || ast_strlen_zero(data)) { ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n"); return -1; } LOCAL_USER_ADD(u); if (chan->_state != AST_STATE_UP) { res = ast_answer(chan); if (res) { LOCAL_USER_REMOVE(u); return -1; } } strncpy(password, data, sizeof(password) - 1); opts=strchr(password, '|'); if (opts) { *opts = 0; opts++; } else opts = ""; /* Start asking for password */ prompt = "agent-pass"; for (retries = 0; retries < 3; retries++) { res = ast_app_getdata(chan, prompt, passwd, sizeof(passwd) - 2, 0); if (res < 0) break; res = 0; if (password[0] == '/') { if (strchr(opts, 'd')) { char tmp[256]; /* Compare against a database key */ if (!ast_db_get(password + 1, passwd, tmp, sizeof(tmp))) { /* It's a good password */ if (strchr(opts, 'r')) { ast_db_del(password + 1, passwd); } break; } } else { /* Compare against a file */ FILE *f; f = fopen(password, "r"); if (f) { char buf[256] = ""; while(!feof(f)) { fgets(buf, sizeof(buf), f); if (!feof(f) && !ast_strlen_zero(buf)) { buf[strlen(buf) - 1] = '\0'; if (!ast_strlen_zero(buf) && !strcmp(passwd, buf)) break; } } fclose(f); if (!ast_strlen_zero(buf) && !strcmp(passwd, buf)) break; } else ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", password, strerror(errno)); } } else { /* Compare against a fixed password */ if (!strcmp(passwd, password)) break; } prompt="auth-incorrect"; } if ((retries < 3) && !res) { if (strchr(opts, 'a')) ast_cdr_setaccount(chan, passwd); res = ast_streamfile(chan, "auth-thankyou", chan->language); if (!res) res = ast_waitstream(chan, ""); } else { if (!res) res = ast_streamfile(chan, "vm-goodbye", chan->language); if (!res) res = ast_waitstream(chan, ""); res = -1; } LOCAL_USER_REMOVE(u); return res; }