static char *group_list_function_read(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) { struct cw_group_info *gi = NULL; char tmp1[1024] = ""; char tmp2[1024] = ""; cw_app_group_list_lock(); for (gi = cw_app_group_list_head(); gi; gi = CW_LIST_NEXT(gi, list)) { if (gi->chan != chan) continue; if (!cw_strlen_zero(tmp1)) { cw_copy_string(tmp2, tmp1, sizeof(tmp2)); if (!cw_strlen_zero(gi->category)) snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, gi->group, gi->category); else snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, gi->group); } else { if (!cw_strlen_zero(gi->category)) snprintf(tmp1, sizeof(tmp1), "%s@%s", gi->group, gi->category); else snprintf(tmp1, sizeof(tmp1), "%s", gi->group); } } cw_app_group_list_unlock(); cw_copy_string(buf, tmp1, len); return buf; }
static char *builtin_function_iftime(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) { struct cw_timing timing; char *s, *q; if (argc < 4 || argc > 6 || !(s = strchr(argv[3], '?'))) { cw_log(LOG_ERROR, "Syntax: %s\n", if_time_func_syntax); return NULL; } /* Trim trailing space from the timespec */ q = s; do { *(q--) = '\0'; } while (q >= argv[3] && isspace(*q)); pbx_extract_timing_fromargv(&timing, argc, argv); s++; // Move pointer after the '?' sign // Move pointer after ':' sign if ((q = strchr(s, ':'))) { *(q) = '\0'; q++; } if (cw_check_timing(&timing)) { /* True: we want everything between '?' and ':' */ cw_copy_string(buf, s, len); } else if (q && *(q) != '\0') { // False: we want everything after ':' (if anything) // cw_copy_string(buf, q, len); } return buf; }
int cw_osp_validate(char *provider, char *token, int *handle, unsigned int *timelimit, char *callerid, struct in_addr addr, char *extension) { char tmp[256]="", *l, *n; char iabuf[INET_ADDRSTRLEN]; char source[OSP_MAX] = ""; /* Same length as osp->source */ char *token2; int tokenlen; struct osp_provider *osp; int res = 0; unsigned int authorised, dummy; if (!provider || !strlen(provider)) provider = "default"; token2 = cw_strdupa(token); tokenlen = cw_base64decode(token2, token, strlen(token)); *handle = -1; if (!callerid) callerid = ""; cw_copy_string(tmp, callerid, sizeof(tmp)); cw_callerid_parse(tmp, &n, &l); if (!l) l = ""; else { cw_shrink_phone_number(l); if (!cw_isphonenumber(l)) l = ""; } callerid = l; cw_mutex_lock(&osplock); cw_inet_ntoa(iabuf, sizeof(iabuf), addr); osp = providers; while(osp) { if (!strcasecmp(osp->name, provider)) { if (OSPPTransactionNew(osp->handle, handle)) { cw_log(LOG_WARNING, "Unable to create OSP Transaction handle!\n"); } else { cw_copy_string(source, osp->source, sizeof(source)); res = 1; } break; } osp = osp->next; } cw_mutex_unlock(&osplock); if (res) { res = 0; dummy = 0; if (!OSPPTransactionValidateAuthorisation(*handle, iabuf, source, NULL, NULL, callerid, OSPC_E164, extension, OSPC_E164, 0, "", tokenlen, token2, &authorised, timelimit, &dummy, NULL, tokenformat)) { if (authorised) { cw_log(LOG_DEBUG, "Validated token for '%s' from '%s@%s'\n", extension, callerid, iabuf); res = 1; } } } return res; }
char *cw_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown) { if (!unknown) unknown = "<unknown>"; if (name && num) snprintf(buf, bufsiz, "\"%s\" <%s>", name, num); else if (name) cw_copy_string(buf, name, bufsiz); else if (num) cw_copy_string(buf, num, bufsiz); else cw_copy_string(buf, unknown, bufsiz); return buf; }
int cw_linear_stream(struct cw_channel *chan, const char *filename, int fd, int allowoverride) { struct linear_state *lin; char tmpf[256]; int res = -1; int autoclose = 0; if (fd < 0) { if (cw_strlen_zero(filename)) return -1; autoclose = 1; if (filename[0] == '/') cw_copy_string(tmpf, filename, sizeof(tmpf)); else snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", (char *)cw_config_CW_VAR_DIR, "sounds", filename); fd = open(tmpf, O_RDONLY); if (fd < 0){ cw_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno)); return -1; } } lin = malloc(sizeof(struct linear_state)); if (lin) { memset(lin, 0, sizeof(lin)); lin->fd = fd; lin->allowoverride = allowoverride; lin->autoclose = autoclose; res = cw_generator_activate(chan, &linearstream, lin); } return res; }
int cw_app_group_match_get_count(char *groupmatch, char *category) { regex_t regexbuf; struct cw_channel *chan; int count = 0; char *test; char cat[80]; char *s; if (cw_strlen_zero(groupmatch)) return 0; /* if regex compilation fails, return zero matches */ if (regcomp(®exbuf, groupmatch, REG_EXTENDED | REG_NOSUB)) return 0; s = (!cw_strlen_zero(category)) ? category : GROUP_CATEGORY_PREFIX; cw_copy_string(cat, s, sizeof(cat)); chan = NULL; while ((chan = cw_channel_walk_locked(chan)) != NULL) { test = pbx_builtin_getvar_helper(chan, cat); if (test && !regexec(®exbuf, test, 0, NULL, 0)) count++; cw_mutex_unlock(&chan->lock); } regfree(®exbuf); return count; }
int cw_privacy_check(char *dest, char *cid) { char tmp[256] = ""; char *trimcid = ""; char *n, *l; int res; char key[256], result[256]; if (cid) cw_copy_string(tmp, cid, sizeof(tmp)); cw_callerid_parse(tmp, &n, &l); if (l) { cw_shrink_phone_number(l); trimcid = l; } snprintf(key, sizeof(key), "%s/%s", dest, trimcid); res = cw_db_get("privacy", key, result, sizeof(result)); if (!res) { if (!strcasecmp(result, "allow")) return CW_PRIVACY_ALLOW; if (!strcasecmp(result, "deny")) return CW_PRIVACY_DENY; if (!strcasecmp(result, "kill")) return CW_PRIVACY_KILL; if (!strcasecmp(result, "torture")) return CW_PRIVACY_TORTURE; } return CW_PRIVACY_UNKNOWN; }
int cw_privacy_set(char *dest, char *cid, int status) { char tmp[256] = ""; char *trimcid = ""; char *n, *l; int res; char key[256]; if (cid) cw_copy_string(tmp, cid, sizeof(tmp)); cw_callerid_parse(tmp, &n, &l); if (l) { cw_shrink_phone_number(l); trimcid = l; } if (cw_strlen_zero(trimcid)) { /* Don't store anything for empty Caller*ID */ return 0; } snprintf(key, sizeof(key), "%s/%s", dest, trimcid); if (status == CW_PRIVACY_UNKNOWN) res = cw_db_del("privacy", key); else if (status == CW_PRIVACY_ALLOW) res = cw_db_put("privacy", key, "allow"); else if (status == CW_PRIVACY_DENY) res = cw_db_put("privacy", key, "deny"); else if (status == CW_PRIVACY_KILL) res = cw_db_put("privacy", key, "kill"); else if (status == CW_PRIVACY_TORTURE) res = cw_db_put("privacy", key, "torture"); else res = -1; return res; }
static int get_callback(void *pArg, int argc, char **argv, char **columnNames) { struct cw_db_data *result = pArg; cw_copy_string(result->data, argv[0], result->datalen); result->rownum++; return 0; }
int cw_callerid_split(const char *buf, char *name, int namelen, char *num, int numlen) { char *tmp; char *l = NULL; char *n = NULL; tmp = cw_strdupa(buf); cw_callerid_parse(tmp, &n, &l); if (n) cw_copy_string(name, n, namelen); else name[0] = '\0'; if (l) { cw_shrink_phone_number(l); cw_copy_string(num, l, numlen); } else num[0] = '\0'; return 0; }
struct cw_var_t *cw_var_assign(const char *name, const char *value) { int i; struct cw_var_t *var; unsigned int hash = cw_hash_var_name(name); var = calloc(sizeof(struct cw_var_t) + strlen(name) + 1 + strlen(value) + 1, sizeof(char)); if (var == NULL) { cw_log(LOG_WARNING, "Out of memory\n"); return NULL; } var->hash = hash; i = strlen(name) + 1; cw_copy_string(var->name, name, i); var->value = var->name + i; cw_copy_string(var->value, value, strlen(value) + 1); return var; }
static void group_function_write(struct cw_channel *chan, int argc, char **argv, const char *value) { char grpcat[256]; if (argc > 0 && argv[0][0]) { snprintf(grpcat, sizeof(grpcat), "%s@%s", value, argv[0]); } else { cw_copy_string(grpcat, value, sizeof(grpcat)); } if (cw_app_group_set_channel(chan, grpcat)) cw_log(LOG_WARNING, "Setting a group requires an argument (group name)\n"); }
static char *builtin_function_set(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) { char *p; if (argc != 1 || !argv[0][0] || !(p = strchr(argv[0], '='))) { cw_log(LOG_ERROR, "Syntax: %s\n", set_func_syntax); return NULL; } *(p++) = '\0'; pbx_builtin_setvar_helper(chan, argv[0], p); cw_copy_string(buf, p, len); return buf; }
static int conference_set_pin(struct cw_conf_member *member, char *pin) { cw_copy_string(member->conf->pin, pin, sizeof(member->conf->pin)); cw_log( CW_CONF_DEBUG, "Conference %s: PIN Set to %s\n",member->conf->name, member->conf->pin ) ; conference_queue_number( member, member->conf->pin ); manager_event( EVENT_FLAG_CALL, APP_CONFERENCE_MANID"SetPIN", "Channel: %s\r\n" "PIN: %s\r\n", member->channel_name, member->conf->pin ) ; return 1; }
int cw_callerid_parse(char *instr, char **name, char **location) { char *ns, *ne; char *ls, *le; char tmp[256]; /* Try for "name" <location> format or name <location> format */ if ((ls = strchr(instr, '<')) && (le = strchr(ls, '>'))) { /* Found the location */ *le = '\0'; *ls = '\0'; *location = ls + 1; if ((ns = strchr(instr, '\"')) && (ne = strchr(ns + 1, '\"'))) { /* Get name out of quotes */ *ns = '\0'; *ne = '\0'; *name = ns + 1; return 0; } else { /* Just trim off any trailing spaces */ cw_trim_blanks(instr); /* And leading spaces */ *name = cw_skip_blanks(instr); return 0; } } else { cw_copy_string(tmp, instr, sizeof(tmp)); cw_shrink_phone_number(tmp); if (cw_isphonenumber(tmp)) { /* Assume it's just a location */ *name = NULL; *location = instr; } else { /* Assume it's just a name. Make sure it's not quoted though */ *name = instr; while(**name && (isspace(**name) || (**name == '\"'))) (*name)++; ne = *name + strlen(*name) - 1; while((ne > *name) && (!*ne || isspace(*ne) || (*ne == '\"'))) { *ne = '\0'; ne--; } *location = NULL; } return 0; } return -1; }
static int init_keys(int fd, int argc, char *argv[]) { struct cw_key *key; int ign; char *kn; char tmp[256] = ""; key = keys; while(key) { /* Reload keys that need pass codes now */ if (key->ktype & KEY_NEEDS_PASSCODE) { kn = key->fn + strlen(cw_config_CW_KEY_DIR) + 1; cw_copy_string(tmp, kn, sizeof(tmp)); try_load_key((char *)cw_config_CW_KEY_DIR, tmp, fd, fd, &ign); } key = key->next; } return RESULT_SUCCESS; }
int conference_queue_sound( struct cw_conf_member *member, char *soundfile ) { struct cw_conf_soundq *newsound; struct cw_conf_soundq **q; if( member == NULL ) { cw_log(LOG_WARNING, "Member is null. Cannot play\n"); return 0; } if( soundfile == NULL ) { cw_log(LOG_WARNING, "Soundfile is null. Cannot play\n"); return 0; } if ( ( member->force_remove_flag == 1 ) || ( member->remove_flag == 1 ) ) { return 0; } newsound = calloc(1,sizeof(struct cw_conf_soundq)); cw_copy_string(newsound->name, soundfile, sizeof(newsound->name)); // append sound to the end of the list. cw_mutex_lock(&member->lock); for( q = &member->soundq; *q; q = &((*q)->next) ) ;; *q = newsound; cw_mutex_unlock(&member->lock); return 0 ; }
int cw_app_group_get_count(char *group, char *category) { struct cw_channel *chan; int count = 0; char *test; char cat[80]; char *s; if (cw_strlen_zero(group)) return 0; s = (!cw_strlen_zero(category)) ? category : GROUP_CATEGORY_PREFIX; cw_copy_string(cat, s, sizeof(cat)); chan = NULL; while ((chan = cw_channel_walk_locked(chan)) != NULL) { test = pbx_builtin_getvar_helper(chan, cat); if (test && !strcasecmp(test, group)) count++; cw_mutex_unlock(&chan->lock); } return count; }
static char *group_function_read(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) { struct cw_group_info *gi = NULL; cw_app_group_list_lock(); gi = cw_app_group_list_head(); while (gi) { if (gi->chan != chan) continue; if (cw_strlen_zero(argv)) break; if (!cw_strlen_zero(gi->category) && !strcasecmp(gi->category, argv[0])) break; gi = CW_LIST_NEXT(gi, list); } if (gi) cw_copy_string(buf, gi->group, len); cw_app_group_list_unlock(); return buf; }
static int do_directory(struct cw_channel *chan, struct cw_config *cfg, char *context, char *dialcontext, char digit, int last) { /* Read in the first three digits.. "digit" is the first digit, already read */ char ext[NUMDIGITS + 1]; char name[80] = ""; struct cw_variable *v; int res; int found=0; int lastuserchoice = 0; char *start, *pos, *conv,*stringp=NULL; if (cw_strlen_zero(context)) { cw_log(LOG_WARNING, "Directory must be called with an argument " "(context in which to interpret extensions)\n"); return -1; } if (digit == '0') { if (!cw_goto_if_exists(chan, chan->context, "o", 1) || (!cw_strlen_zero(chan->proc_context) && !cw_goto_if_exists(chan, chan->proc_context, "o", 1))) { return 0; } else { cw_log(LOG_WARNING, "Can't find extension 'o' in current context. " "Not Exiting the Directory!\n"); res = 0; } } if (digit == '*') { if (!cw_goto_if_exists(chan, chan->context, "a", 1) || (!cw_strlen_zero(chan->proc_context) && !cw_goto_if_exists(chan, chan->proc_context, "a", 1))) { return 0; } else { cw_log(LOG_WARNING, "Can't find extension 'a' in current context. " "Not Exiting the Directory!\n"); res = 0; } } memset(ext, 0, sizeof(ext)); ext[0] = digit; res = 0; if (cw_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) res = -1; if (!res) { /* Search for all names which start with those digits */ v = cw_variable_browse(cfg, context); while(v && !res) { /* Find all candidate extensions */ while(v) { /* Find a candidate extension */ start = strdup(v->value); if (start && !strcasestr(start, "hidefromdir=yes")) { stringp=start; strsep(&stringp, ","); pos = strsep(&stringp, ","); if (pos) { cw_copy_string(name, pos, sizeof(name)); /* Grab the last name */ if (last && strrchr(pos,' ')) pos = strrchr(pos, ' ') + 1; conv = convert(pos); if (conv) { if (!strcmp(conv, ext)) { /* Match! */ found++; free(conv); free(start); break; } free(conv); } } free(start); } v = v->next; } if (v) { /* We have a match -- play a greeting if they have it */ res = play_mailbox_owner(chan, context, dialcontext, v->name, name); switch (res) { case -1: /* user pressed '1' but extension does not exist, or * user hungup */ lastuserchoice = 0; break; case '1': /* user pressed '1' and extensions exists; play_mailbox_owner will already have done a goto() on the channel */ lastuserchoice = res; break; case '*': /* user pressed '*' to skip something found */ lastuserchoice = res; res = 0; break; default: break; } v = v->next; } } if (lastuserchoice != '1') { if (found) res = cw_streamfile(chan, "dir-nomore", chan->language); else res = cw_streamfile(chan, "dir-nomatch", chan->language); if (!res) res = 1; return res; } return 0; } return res; }
int cw_osp_next(struct cw_osp_result *result, int cause) { int res = 0; int tokenlen; unsigned int dummy=0; unsigned int timelimit; unsigned int callidlen; char callidstr[OSPC_CALLID_MAXSIZE] = ""; char callednum[2048]=""; char callingnum[2048]=""; char destination[2048]=""; char token[2000]; OSPE_DEST_PROT prot; OSPE_DEST_OSP_ENABLED ospenabled; result->tech[0] = '\0'; result->dest[0] = '\0'; result->token[0] = '\0'; if (result->handle > -1) { dummy = 0; if (result->numresults) { tokenlen = sizeof(token); while(!res && result->numresults) { result->numresults--; callidlen = sizeof(callidstr); if (!OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) { if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) { result->token[0] = 0; } else { cw_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1); } if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) { res = 1; /* Strip leading and trailing brackets */ destination[strlen(destination) - 1] = '\0'; switch(prot) { case OSPE_DEST_PROT_H323_SETUP: cw_copy_string(result->tech, "H323", sizeof(result->tech)); snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); break; case OSPE_DEST_PROT_SIP: cw_copy_string(result->tech, "SIP", sizeof(result->tech)); snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); break; case OSPE_DEST_PROT_IAX: cw_copy_string(result->tech, "IAX", sizeof(result->tech)); snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); break; default: cw_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot); res = 0; } } else { cw_log(LOG_DEBUG, "Missing destination protocol\n"); break; } } } } if (!res) { OSPPTransactionDelete(result->handle); result->handle = -1; } } return res; }
static int osp_build(struct cw_config *cfg, char *cat) { OSPTCERT TheAuthCert[MAX_CERTS]; unsigned char Reqbuf[4096],LocalBuf[4096],AuthBuf[MAX_CERTS][4096]; struct cw_variable *v; struct osp_provider *osp; int x,length,errorcode=0; int mallocd=0,i; char *cacerts[MAX_CERTS]; const char *servicepoints[MAX_SERVICEPOINTS]; OSPTPRIVATEKEY privatekey; OSPTCERT localcert; OSPTCERT *authCerts[MAX_CERTS]; cw_mutex_lock(&osplock); osp = providers; while(osp) { if (!strcasecmp(osp->name, cat)) break; osp = osp->next; } cw_mutex_unlock(&osplock); if (!osp) { mallocd = 1; osp = malloc(sizeof(struct osp_provider)); if (!osp) { cw_log(LOG_WARNING, "Out of memory!\n"); return -1; } memset(osp, 0, sizeof(struct osp_provider)); osp->handle = -1; } cw_copy_string(osp->name, cat, sizeof(osp->name)); snprintf(osp->localpvtkey, sizeof(osp->localpvtkey) ,"%s/%s-privatekey.pem", cw_config_CW_KEY_DIR, cat); snprintf(osp->localcert, sizeof(osp->localpvtkey), "%s/%s-localcert.pem", cw_config_CW_KEY_DIR, cat); osp->maxconnections=OSP_DEFAULT_MAX_CONNECTIONS; osp->retrydelay = OSP_DEFAULT_RETRY_DELAY; osp->retrylimit = OSP_DEFAULT_RETRY_LIMIT; osp->timeout = OSP_DEFAULT_TIMEOUT; osp->source[0] = '\0'; cw_log(LOG_DEBUG, "Building OSP Provider '%s'\n", cat); v = cw_variable_browse(cfg, cat); while(v) { if (!strcasecmp(v->name, "privatekey")) { if (v->value[0] == '/') cw_copy_string(osp->localpvtkey, v->value, sizeof(osp->localpvtkey)); else snprintf(osp->localpvtkey, sizeof(osp->localpvtkey), "%s/%s", cw_config_CW_KEY_DIR , v->value); } else if (!strcasecmp(v->name, "localcert")) { if (v->value[0] == '/') cw_copy_string(osp->localcert, v->value, sizeof(osp->localcert)); else snprintf(osp->localcert, sizeof(osp->localcert), "%s/%s", cw_config_CW_KEY_DIR, v->value); } else if (!strcasecmp(v->name, "cacert")) { if (osp->cacount < MAX_CERTS) { if (v->value[0] == '/') cw_copy_string(osp->cacerts[osp->cacount], v->value, sizeof(osp->cacerts[0])); else snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s", cw_config_CW_KEY_DIR, v->value); osp->cacount++; } else cw_log(LOG_WARNING, "Too many CA Certificates at line %d\n", v->lineno); } else if (!strcasecmp(v->name, "servicepoint")) { if (osp->spcount < MAX_SERVICEPOINTS) { cw_copy_string(osp->servicepoints[osp->spcount], v->value, sizeof(osp->servicepoints[0])); osp->spcount++; } else cw_log(LOG_WARNING, "Too many Service points at line %d\n", v->lineno); } else if (!strcasecmp(v->name, "maxconnections")) { if ((sscanf(v->value, "%d", &x) == 1) && (x > 0) && (x <= 1000)) { osp->maxconnections = x; } else cw_log(LOG_WARNING, "maxconnections should be an integer from 1 to 1000, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "retrydelay")) { if ((sscanf(v->value, "%d", &x) == 1) && (x >= 0) && (x <= 10)) { osp->retrydelay = x; } else cw_log(LOG_WARNING, "retrydelay should be an integer from 0 to 10, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "retrylimit")) { if ((sscanf(v->value, "%d", &x) == 1) && (x >= 0) && (x <= 100)) { osp->retrylimit = x; } else cw_log(LOG_WARNING, "retrylimit should be an integer from 0 to 100, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "timeout")) { if ((sscanf(v->value, "%d", &x) == 1) && (x >= 200) && (x <= 10000)) { osp->timeout = x; } else cw_log(LOG_WARNING, "timeout should be an integer from 200 to 10000, not '%s' at line %d\n", v->value, v->lineno); } else if (!strcasecmp(v->name, "source")) { cw_copy_string(osp->source, v->value, sizeof(osp->source)); } v = v->next; } if (osp->cacount < 1) { snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s-cacert.pem", cw_config_CW_KEY_DIR, cat); osp->cacount++; } for (x=0;x<osp->cacount;x++) cacerts[x] = osp->cacerts[x]; for (x=0;x<osp->spcount;x++) servicepoints[x] = osp->servicepoints[x]; cw_mutex_lock(&osplock); osp->dead = 0; if (osp->handle > -1) { cw_log(LOG_DEBUG, "Deleting old handle for '%s'\n", osp->name); OSPPProviderDelete(osp->handle, 0); } length = 0; cw_log(LOG_DEBUG, "Loading private key for '%s' (%s)\n", osp->name, osp->localpvtkey); errorcode = loadPemPrivateKey(osp->localpvtkey,Reqbuf,&length); if (errorcode == 0) { privatekey.PrivateKeyData = Reqbuf; privatekey.PrivateKeyLength = length; } else { return -1; } length = 0; cw_log(LOG_DEBUG, "Loading local cert for '%s' (%s)\n", osp->name, osp->localcert); errorcode = loadPemCert(osp->localcert,LocalBuf,&length); if (errorcode == 0) { localcert.CertData = LocalBuf; localcert.CertDataLength = length; } else { return -1; } for (i=0;i<osp->cacount;i++) { length = 0; cw_log(LOG_DEBUG, "Loading CA cert %d for '%s' (%s)\n", i + 1, osp->name, osp->cacerts[i]); errorcode = loadPemCert(osp->cacerts[i],AuthBuf[i],&length); if (errorcode == 0) { TheAuthCert[i].CertData = AuthBuf[i]; TheAuthCert[i].CertDataLength = length; authCerts[i] = &(TheAuthCert[i]); } else { return -1; } } cw_log(LOG_DEBUG, "Creating provider handle for '%s'\n", osp->name); cw_log(LOG_DEBUG, "Service point '%s %d'\n", servicepoints[0], osp->spcount); if (OSPPProviderNew(osp->spcount, servicepoints, NULL, "localhost", &privatekey, &localcert, osp->cacount, (const OSPTCERT **)authCerts, 1, 300, osp->maxconnections, 1, osp->retrydelay, osp->retrylimit, osp->timeout, "", "", &osp->handle)) { cw_log(LOG_WARNING, "Unable to initialize provider '%s'\n", cat); osp->dead = 1; } if (mallocd) { osp->next = providers; providers = osp; } cw_mutex_unlock(&osplock); return 0; }
static int conf_do_originate(struct cw_conf_member *member, char *ext) { int res; pthread_t th; pthread_attr_t attr; struct fast_originate_helper *fast = malloc(sizeof(struct fast_originate_helper)); char dst[80]=""; char appdata[80]=""; char *var; if (!fast) { res = -1; } else { memset(fast, 0, sizeof(struct fast_originate_helper)); if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_TIMEOUT")) ) { fast->timeout = atoi(var) * 1000; } else fast->timeout = 30000; strcat(dst,ext); strcat(dst,"@"); if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_CONTEXT")) ) strcat(dst,var); else strcat(dst,member->chan->context); strcat(appdata,member->id); strcat(appdata,"/"); if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_PARAMS")) ) strcat(appdata,var); else { strcat(appdata,"Sdq"); #if ENABLE_VAD strcat(appdata,"V"); #endif } cw_copy_string( fast->tech, "Local", sizeof(fast->tech) ); cw_copy_string( fast->data, dst, sizeof(fast->data) ); cw_copy_string( fast->app, APP_CONFERENCE_NAME, sizeof(fast->app) ); cw_copy_string( fast->appdata, appdata, sizeof(fast->appdata) ); if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_CID_NAME")) ) cw_copy_string( fast->cid_name, var, sizeof(fast->cid_name) ); else cw_copy_string( fast->cid_name,"NavyConference",sizeof(fast->cid_name) ); if ( (var = pbx_builtin_getvar_helper(member->chan, "NCONF_OUTBOUND_CID_NUM")) ) cw_copy_string( fast->cid_num, var,sizeof(fast->cid_num) ); else cw_copy_string( fast->cid_num, member->id,sizeof(fast->cid_num) ); cw_copy_string( fast->context, "internal", sizeof(fast->context) ); cw_copy_string( fast->exten, ext, sizeof(fast->exten) ); fast->priority = 1; fast->vars=NULL; /**/ fast->frommember=member; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (cw_pthread_create(&th, &attr, fast_originate, fast)) { free(fast); res = -1; } else { res = 0; } } cw_mutex_unlock(&member->chan->lock); cw_conf_member_genactivate( member ) ; return res; }
int conference_queue_number( struct cw_conf_member *member, char *str ) { struct cw_conf_soundq *newsound; struct cw_conf_soundq **q; if( member == NULL ) { cw_log(LOG_WARNING, "Member is null. Cannot play\n"); return 0; } if( str == NULL ) { cw_log(LOG_WARNING, "STRING is null. Cannot play\n"); return 0; } if ( ( member->force_remove_flag == 1 ) || ( member->remove_flag == 1 ) ) { return 0; } const char *fn = NULL; char soundfile[255] = ""; int num = 0; int res = 0; while (str[num] && !res) { fn = NULL; switch (str[num]) { case ('*'): fn = "digits/star"; break; case ('#'): fn = "digits/pound"; break; case ('-'): fn = "digits/minus"; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': strcpy(soundfile, "digits/X"); soundfile[7] = str[num]; fn = soundfile; break; } num++; if (fn) { newsound = calloc(1,sizeof(struct cw_conf_soundq)); cw_copy_string(newsound->name, fn, sizeof(newsound->name)); // append sound to the end of the list. cw_mutex_lock(&member->lock); for( q = &member->soundq; *q; q = &((*q)->next) ) ;; *q = newsound; cw_mutex_unlock(&member->lock); } } return 0 ; }
static int record_exec(struct cw_channel *chan, int argc, char **argv) { int res = 0; int count = 0; int percentflag = 0; char *ext = NULL; int i = 0; char tmp[256]; struct cw_filestream *s = '\0'; struct localuser *u; struct cw_frame *f = NULL; struct cw_dsp *sildet = NULL; /* silence detector dsp */ int totalsilence = 0; int dspsilence = 0; int silence = 0; /* amount of silence to allow */ int gotsilence = 0; /* did we timeout for silence? */ int maxduration = 0; /* max duration of recording in milliseconds */ int gottimeout = 0; /* did we timeout for maxduration exceeded? */ int option_skip = 0; int option_noanswer = 0; int option_append = 0; int terminator = '#'; int option_quiet = 0; int rfmt = 0; int flags; if (argc < 1 || argc > 4 || !argv[0][0]) { cw_log(LOG_ERROR, "Syntax: %s\n", record_syntax); return -1; } LOCAL_USER_ADD(u); if (strstr(argv[0], "%d")) percentflag = 1; ext = strrchr(argv[0], '.'); /* to support filename with a . in the filename, not format */ if (!ext) ext = strchr(argv[0], ':'); if (ext) { *ext = '\0'; ext++; } if (!ext) { cw_log(LOG_WARNING, "No extension specified to filename!\n"); LOCAL_USER_REMOVE(u); return -1; } if (argc > 1) { silence = atoi(argv[1]); if (silence > 0) silence *= 1000; else if (silence < 0) silence = 0; } if (argc > 2) { maxduration = atoi(argv[2]); if (maxduration > 0) maxduration *= 1000; else if (maxduration < 0) maxduration = 0; } if (argc > 3) { /* Retain backwards compatibility with old style options */ if (!strcasecmp(argv[3], "skip")) option_skip = 1; else if (!strcasecmp(argv[3], "noanswer")) option_noanswer = 1; else { if (strchr(argv[3], 's')) option_skip = 1; if (strchr(argv[3], 'n')) option_noanswer = 1; if (strchr(argv[3], 'a')) option_append = 1; if (strchr(argv[3], 't')) terminator = '*'; if (strchr(argv[3], 'q')) option_quiet = 1; } } /* done parsing */ /* these are to allow the use of the %d in the config file for a wild card of sort to create a new file with the inputed name scheme */ if (percentflag) { char *piece[100]; int pieces; /* Separate each piece out by the format specifier */ pieces = cw_separate_app_args(argv[0], '%', arraysize(piece), piece); do { int tmplen; /* First piece has no leading percent, so it's copied verbatim */ cw_copy_string(tmp, piece[0], sizeof(tmp)); tmplen = strlen(tmp); for (i = 1; i < pieces; i++) { if (piece[i][0] == 'd') { /* Substitute the count */ snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%d", count); tmplen += strlen(tmp + tmplen); } else if (tmplen + 2 < sizeof(tmp)) { /* Unknown format specifier - just copy it verbatim */ tmp[tmplen++] = '%'; tmp[tmplen++] = piece[i][0]; } /* Copy the remaining portion of the piece */ cw_copy_string(tmp + tmplen, &(piece[i][1]), sizeof(tmp) - tmplen); } count++; } while ( cw_fileexists(tmp, ext, chan->language) != -1 ); pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp); } else strncpy(tmp, argv[0], sizeof(tmp)-1); /* end of routine mentioned */ if (chan->_state != CW_STATE_UP) { if (option_skip) { /* At the user's option, skip if the line is not up */ LOCAL_USER_REMOVE(u); return 0; } else if (!option_noanswer) { /* Otherwise answer unless we're supposed to record while on-hook */ res = cw_answer(chan); } } if (!res) { if (!option_quiet) { /* Some code to play a nice little beep to signify the start of the record operation */ res = cw_streamfile(chan, "beep", chan->language); if (!res) { res = cw_waitstream(chan, ""); } else { cw_log(LOG_WARNING, "cw_streamfile failed on %s\n", chan->name); } cw_stopstream(chan); } /* The end of beep code. Now the recording starts */ if (silence > 0) { rfmt = chan->readformat; res = cw_set_read_format(chan, CW_FORMAT_SLINEAR); if (res < 0) { cw_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); LOCAL_USER_REMOVE(u); return -1; } sildet = cw_dsp_new(); if (!sildet) { cw_log(LOG_WARNING, "Unable to create silence detector :(\n"); LOCAL_USER_REMOVE(u); return -1; } cw_dsp_set_threshold(sildet, 256); } flags = option_append ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY; s = cw_writefile( tmp, ext, NULL, flags , 0, 0644); if (s) { int waitres; /* Request a video update */ cw_indicate(chan, CW_CONTROL_VIDUPDATE); if (maxduration <= 0) maxduration = -1; while ((waitres = cw_waitfor(chan, maxduration)) > -1) { if (maxduration > 0) { if (waitres == 0) { gottimeout = 1; break; } maxduration = waitres; } f = cw_read(chan); if (!f) { res = -1; break; } if (f->frametype == CW_FRAME_VOICE) { res = cw_writestream(s, f); if (res) { cw_log(LOG_WARNING, "Problem writing frame\n"); cw_fr_free(f); break; } if (silence > 0) { dspsilence = 0; cw_dsp_silence(sildet, f, &dspsilence); if (dspsilence) { totalsilence = dspsilence; } else { totalsilence = 0; } if (totalsilence > silence) { /* Ended happily with silence */ cw_fr_free(f); gotsilence = 1; break; } } } if (f->frametype == CW_FRAME_VIDEO) { res = cw_writestream(s, f); if (res) { cw_log(LOG_WARNING, "Problem writing frame\n"); cw_fr_free(f); break; } } if ((f->frametype == CW_FRAME_DTMF) && (f->subclass == terminator)) { cw_fr_free(f); break; } cw_fr_free(f); } if (!f) { cw_log(LOG_DEBUG, "Got hangup\n"); res = -1; } if (gotsilence) { cw_stream_rewind(s, silence-1000); cw_truncstream(s); } else if (!gottimeout) { /* Strip off the last 1/4 second of it */ cw_stream_rewind(s, 250); cw_truncstream(s); } cw_closestream(s); } else cw_log(LOG_WARNING, "Could not create file %s\n", tmp); } else cw_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name); if ((silence > 0) && rfmt) { res = cw_set_read_format(chan, rfmt); if (res) cw_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); if (sildet) cw_dsp_free(sildet); } LOCAL_USER_REMOVE(u); return res; }
static void function_moh_write(struct cw_channel *chan, int argc, char **argv, const char *value) { cw_copy_string(chan->musicclass, value, MAX_MUSICCLASS); }
static char *function_moh_read(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) { cw_copy_string(buf, chan->musicclass, len); return buf; }
static char *builtin_function_math(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) { double fnum1; double fnum2; double ftmp = 0; char *op; int iaction=-1; int type_of_result=FLOAT_RESULT; /* dunno, big calulations :D */ char user_result[30]; char *mvalue1, *mvalue2=NULL, *mtype_of_result; if (argc != 2 || !argv[0][0] || !argv[1][0]) { cw_log(LOG_ERROR, "Syntax: %s\n", math_func_syntax); return NULL; } mvalue1 = argv[0]; if ((op = strchr(mvalue1, '+'))) { iaction = ADDFUNCTION; *op = '\0'; } else if ((op = strchr(mvalue1, '-'))) { iaction = SUBTRACTFUNCTION; *op = '\0'; } else if ((op = strchr(mvalue1, '*'))) { iaction = MULTIPLYFUNCTION; *op = '\0'; } else if ((op = strchr(mvalue1, '/'))) { iaction = DIVIDEFUNCTION; *op = '\0'; } else if ((op = strchr(mvalue1, '%'))) { iaction = MODULUSFUNCTION; *op = '\0'; } else if ((op = strchr(mvalue1, '>'))) { iaction = GTFUNCTION; *op = '\0'; if (*(op+1) == '=') { *++op = '\0'; iaction = GTEFUNCTION; } } else if ((op = strchr(mvalue1, '<'))) { iaction = LTFUNCTION; *op = '\0'; if (*(op+1) == '=') { *++op = '\0'; iaction = LTEFUNCTION; } } else if ((op = strchr(mvalue1, '='))) { iaction = GTFUNCTION; *op = '\0'; if (*(op+1) == '=') { *++op = '\0'; iaction = EQFUNCTION; } else op = NULL; } if (op) mvalue2 = op + 1; /* detect wanted type of result */ mtype_of_result = argv[1]; if (mtype_of_result) { if (!strcasecmp(mtype_of_result,"float") || !strcasecmp(mtype_of_result,"f")) type_of_result=FLOAT_RESULT; else if (!strcasecmp(mtype_of_result,"int") || !strcasecmp(mtype_of_result,"i")) type_of_result=INT_RESULT; else if (!strcasecmp(mtype_of_result,"hex") || !strcasecmp(mtype_of_result,"h")) type_of_result=HEX_RESULT; else if (!strcasecmp(mtype_of_result,"char") || !strcasecmp(mtype_of_result,"c")) type_of_result=CHAR_RESULT; else { cw_log(LOG_WARNING, "Unknown type of result requested '%s'.\n", mtype_of_result); return NULL; } } if (!mvalue1 || !mvalue2) { cw_log(LOG_WARNING, "Supply all the parameters - just this once, please\n"); return NULL; } if (sscanf(mvalue1, "%lf", &fnum1) != 1) { cw_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1); return NULL; } if (sscanf(mvalue2, "%lf", &fnum2) != 1) { cw_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2); return NULL; } switch (iaction) { case ADDFUNCTION : ftmp = fnum1 + fnum2; break; case DIVIDEFUNCTION : if (fnum2 <= 0) ftmp = 0.0L; /* can't do a divide by 0 */ else ftmp = (fnum1 / fnum2); break; case MULTIPLYFUNCTION : ftmp = (fnum1 * fnum2); break; case SUBTRACTFUNCTION : ftmp = (fnum1 - fnum2); break; case MODULUSFUNCTION : { int inum1 = fnum1; int inum2 = fnum2; ftmp = (inum1 % inum2); break; } case GTFUNCTION : cw_copy_string (user_result, (fnum1 > fnum2)?"TRUE":"FALSE", sizeof (user_result)); break; case LTFUNCTION : cw_copy_string (user_result, (fnum1 < fnum2)?"TRUE":"FALSE", sizeof (user_result)); break; case GTEFUNCTION : cw_copy_string (user_result, (fnum1 >= fnum2)?"TRUE":"FALSE", sizeof (user_result)); break; case LTEFUNCTION : cw_copy_string (user_result, (fnum1 <= fnum2)?"TRUE":"FALSE", sizeof (user_result)); break; case EQFUNCTION : cw_copy_string (user_result, (fnum1 == fnum2)?"TRUE":"FALSE", sizeof (user_result)); break; default : cw_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction); return NULL; } if (iaction < GTFUNCTION || iaction > EQFUNCTION) { if (type_of_result == FLOAT_RESULT) snprintf(user_result, sizeof(user_result), "%lf", ftmp); else if (type_of_result == INT_RESULT) snprintf(user_result, sizeof(user_result), "%i", (int) ftmp); else if (type_of_result == HEX_RESULT) snprintf(user_result, sizeof(user_result), "%x", (unsigned int) ftmp); else if (type_of_result == CHAR_RESULT) snprintf(user_result, sizeof(user_result), "%c", (unsigned char) ftmp); } cw_copy_string(buf, user_result, len); return buf; }
static struct cw_key *try_load_key (char *dir, char *fname, int ifd, int ofd, int *not2) { int ktype = 0; char *c = NULL; char ffname[256]; FILE *f; EVP_MD_CTX mdctx; unsigned char md_value[CW_MAX_BINARY_MD_SIZE]; unsigned int md_len; struct cw_key *key; static int notice = 0; int found = 0; /* Make sure its name is a public or private key */ if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) { ktype = CW_KEY_PUBLIC; } else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) { ktype = CW_KEY_PRIVATE; } else return NULL; /* Get actual filename */ snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname); cw_mutex_lock(&keylock); key = keys; while(key) { /* Look for an existing version already */ if (!strcasecmp(key->fn, ffname)) break; key = key->next; } cw_mutex_unlock(&keylock); /* Open file */ f = fopen(ffname, "r"); if (!f) { cw_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno)); return NULL; } EVP_DigestInit(&mdctx, EVP_md5()); while(!feof(f)) { /* Calculate a "whatever" quality md5sum of the key */ char buf[256]; memset(buf, 0, 256); fgets(buf, sizeof(buf), f); if (!feof(f)) { EVP_DigestUpdate(&mdctx, (unsigned char *) buf, strlen(buf)); } } EVP_DigestFinal(&mdctx, md_value, &md_len); if (key) { /* If the MD5 sum is the same, and it isn't awaiting a passcode then this is far enough */ if (!memcmp(md_value, key->md_value, md_len) && !(key->ktype & KEY_NEEDS_PASSCODE)) { fclose(f); key->delme = 0; return NULL; } else { /* Preserve keytype */ ktype = key->ktype; /* Recycle the same structure */ found++; } } /* Make fname just be the normal name now */ *c = '\0'; if (!key) { key = (struct cw_key *)malloc(sizeof(struct cw_key)); if (!key) { cw_log(LOG_WARNING, "Out of memory\n"); fclose(f); return NULL; } memset(key, 0, sizeof(struct cw_key)); } /* At this point we have a key structure (old or new). Time to fill it with what we know */ /* Gotta lock if this one already exists */ if (found) cw_mutex_lock(&keylock); /* First the filename */ cw_copy_string(key->fn, ffname, sizeof(key->fn)); /* Then the name */ cw_copy_string(key->name, fname, sizeof(key->name)); key->ktype = ktype; /* Yes, assume we're going to be deleted */ key->delme = 1; /* Keep the key type */ memcpy(key->md_value, md_value, md_len); key->md_len = md_len; /* Can I/O takes the FD we're given */ key->infd = ifd; key->outfd = ofd; /* Reset the file back to the beginning */ rewind(f); /* Now load the key with the right method */ if (ktype == CW_KEY_PUBLIC) key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key); else key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key); fclose(f); if (key->rsa) { if (RSA_size(key->rsa) == 128) { /* Key loaded okay */ key->ktype &= ~KEY_NEEDS_PASSCODE; if (option_verbose > 2) cw_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == CW_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name); if (option_debug) cw_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name); key->delme = 0; } else cw_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name); } else if (key->infd != -2) { cw_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == CW_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name); if (ofd > -1) { ERR_print_errors_fp(stderr); } else ERR_print_errors_fp(stderr); } else { cw_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name); key->ktype |= KEY_NEEDS_PASSCODE; if (!notice) { if (!option_initcrypto) cw_log(LOG_NOTICE, "Add the '-i' flag to the callweaver command line if you want to automatically initialize passcodes at launch.\n"); notice++; } /* Keep it anyway */ key->delme = 0; /* Print final notice about "init keys" when done */ *not2 = 1; } if (found) cw_mutex_unlock(&keylock); if (!found) { cw_mutex_lock(&keylock); key->next = keys; keys = key; cw_mutex_unlock(&keylock); } return key; }
int cw_play_and_prepend(struct cw_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence) { int d = 0; char *fmts; char comment[256]; int x, fmtcnt=1, res=-1,outmsg=0; struct cw_frame *f; struct cw_filestream *others[MAX_OTHER_FORMATS]; struct cw_filestream *realfiles[MAX_OTHER_FORMATS]; char *sfmt[MAX_OTHER_FORMATS]; char *stringp=NULL; time_t start, end; struct cw_dsp *sildet; /* silence detector dsp */ int totalsilence = 0; int dspsilence = 0; int gotsilence = 0; /* did we timeout for silence? */ int rfmt=0; char prependfile[80]; if (silencethreshold < 0) silencethreshold = global_silence_threshold; if (maxsilence < 0) maxsilence = global_maxsilence; /* barf if no pointer passed to store duration in */ if (duration == NULL) { cw_log(LOG_WARNING, "Error play_and_prepend called without duration pointer\n"); return -1; } cw_log(LOG_DEBUG,"play_and_prepend: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt); snprintf(comment,sizeof(comment),"Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name); if (playfile || beep) { if (!beep) d = cw_play_and_wait(chan, playfile); if (d > -1) d = cw_streamfile(chan, "beep",chan->language); if (!d) d = cw_waitstream(chan,""); if (d < 0) return -1; } cw_copy_string(prependfile, recordfile, sizeof(prependfile)); strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1); fmts = cw_strdupa(fmt); stringp=fmts; strsep(&stringp, "|,"); cw_log(LOG_DEBUG,"Recording Formats: sfmts=%s\n", fmts); sfmt[0] = cw_strdupa(fmts); while((fmt = strsep(&stringp, "|,"))) { if (fmtcnt > MAX_OTHER_FORMATS - 1) { cw_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app_voicemail.c\n"); break; } sfmt[fmtcnt++] = cw_strdupa(fmt); } time(&start); end=start; /* pre-initialize end to be same as start in case we never get into loop */ for (x=0;x<fmtcnt;x++) { others[x] = cw_writefile(prependfile, sfmt[x], comment, O_TRUNC, 0, 0700); cw_verbose( VERBOSE_PREFIX_3 "x=%d, open writing: %s format: %s, %p\n", x, prependfile, sfmt[x], others[x]); if (!others[x]) { break; } } sildet = cw_dsp_new(); /* Create the silence detector */ if (!sildet) { cw_log(LOG_WARNING, "Unable to create silence detector :(\n"); return -1; } cw_dsp_set_threshold(sildet, silencethreshold); if (maxsilence > 0) { rfmt = chan->readformat; res = cw_set_read_format(chan, CW_FORMAT_SLINEAR); if (res < 0) { cw_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); return -1; } } if (x == fmtcnt) { /* Loop forever, writing the packets we read to the writer(s), until we read a # or get a hangup */ f = NULL; for(;;) { res = cw_waitfor(chan, 2000); if (!res) { cw_log(LOG_DEBUG, "One waitfor failed, trying another\n"); /* Try one more time in case of masq */ res = cw_waitfor(chan, 2000); if (!res) { cw_log(LOG_WARNING, "No audio available on %s??\n", chan->name); res = -1; } } if (res < 0) { f = NULL; break; } f = cw_read(chan); if (!f) break; if (f->frametype == CW_FRAME_VOICE) { /* write each format */ for (x=0;x<fmtcnt;x++) { if (!others[x]) break; res = cw_writestream(others[x], f); } /* Silence Detection */ if (maxsilence > 0) { dspsilence = 0; cw_dsp_silence(sildet, f, &dspsilence); if (dspsilence) totalsilence = dspsilence; else totalsilence = 0; if (totalsilence > maxsilence) { /* Ended happily with silence */ if (option_verbose > 2) cw_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); cw_fr_free(f); gotsilence = 1; outmsg=2; break; } } /* Exit on any error */ if (res) { cw_log(LOG_WARNING, "Error writing frame\n"); cw_fr_free(f); break; } } else if (f->frametype == CW_FRAME_VIDEO) { /* Write only once */ cw_writestream(others[0], f); } else if (f->frametype == CW_FRAME_DTMF) { /* stop recording with any digit */ if (option_verbose > 2) cw_verbose( VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); res = 't'; outmsg = 2; cw_fr_free(f); break; } if (maxtime) { time(&end); if (maxtime < (end - start)) { if (option_verbose > 2) cw_verbose( VERBOSE_PREFIX_3 "Took too long, cutting it short...\n"); res = 't'; outmsg=2; cw_fr_free(f); break; } } cw_fr_free(f); } if (end == start) time(&end); if (!f) { if (option_verbose > 2) cw_verbose( VERBOSE_PREFIX_3 "User hung up\n"); res = -1; outmsg=1; #if 0 /* delete all the prepend files */ for (x=0;x<fmtcnt;x++) { if (!others[x]) break; cw_closestream(others[x]); cw_filedelete(prependfile, sfmt[x]); } #endif } } else { cw_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", prependfile, sfmt[x]); } *duration = end - start; #if 0 if (outmsg > 1) { #else if (outmsg) { #endif struct cw_frame *fr; for (x=0;x<fmtcnt;x++) { snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]); realfiles[x] = cw_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0); if (!others[x] || !realfiles[x]) break; if (totalsilence) cw_stream_rewind(others[x], totalsilence-200); else cw_stream_rewind(others[x], 200); cw_truncstream(others[x]); /* add the original file too */ while ((fr = cw_readframe(realfiles[x]))) { cw_writestream(others[x],fr); } cw_closestream(others[x]); cw_closestream(realfiles[x]); cw_filerename(prependfile, recordfile, sfmt[x]); #if 0 cw_verbose("Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x],prependfile,recordfile); #endif cw_filedelete(prependfile, sfmt[x]); } } if (rfmt) { if (cw_set_read_format(chan, rfmt)) { cw_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", cw_getformatname(rfmt), chan->name); } } if (outmsg) { if (outmsg > 1) { /* Let them know it worked */ cw_streamfile(chan, "auth-thankyou", chan->language); cw_waitstream(chan, ""); } } return res; } /* Channel group core functions */ int cw_app_group_split_group(char *data, char *group, int group_max, char *category, int category_max) { int res=0; char tmp[256]; char *grp=NULL, *cat=NULL; if (!cw_strlen_zero(data)) { cw_copy_string(tmp, data, sizeof(tmp)); grp = tmp; cat = strchr(tmp, '@'); if (cat) { *cat = '\0'; cat++; } } if (!cw_strlen_zero(grp)) cw_copy_string(group, grp, group_max); else res = -1; if (cat) snprintf(category, category_max, "%s_%s", GROUP_CATEGORY_PREFIX, cat); else cw_copy_string(category, GROUP_CATEGORY_PREFIX, category_max); return res; }