? .txt ? DDR.MOV ? a.out ? config-mark.c ? markdiff.txt ? mydiff.txt ? resume-ken-long.pdf ? root.xwd ? stereo-1.0 ? test.call ? test1.call ? test2.call ? tmp1.gsm ? tmp2.gsm ? tmp3.gsm ? tmp4.gsm ? apps/app_read_broken.c ? astman/.depend ? astman/astman Index: app.c =================================================================== RCS file: /usr/cvsroot/asterisk/app.c,v retrieving revision 1.44 diff -u -r1.44 app.c --- app.c 21 Jan 2005 07:06:24 -0000 1.44 +++ app.c 23 Jan 2005 09:01:21 -0000 @@ -497,7 +497,7 @@ static int global_silence_threshold = 128; static int global_maxsilence = 0; -int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence) +int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path) { char d, *fmts; char comment[256]; @@ -507,7 +507,7 @@ char *sfmt[MAX_OTHER_FORMATS]; char *stringp=NULL; time_t start, end; - struct ast_dsp *sildet; /* silence detector dsp */ + struct ast_dsp *sildet=NULL; /* silence detector dsp */ int totalsilence = 0; int dspsilence = 0; int gotsilence = 0; /* did we timeout for silence? */ @@ -564,18 +564,23 @@ } } - sildet = ast_dsp_new(); /* Create the silence detector */ - if (!sildet) { - ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); - return -1; - } - ast_dsp_set_threshold(sildet, silencethreshold); + if (path) + ast_unlock_path(path); + + if (maxsilence > 0) { + sildet = ast_dsp_new(); /* Create the silence detector */ + if (!sildet) { + ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); + return -1; + } + ast_dsp_set_threshold(sildet, silencethreshold); rfmt = chan->readformat; res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); if (res < 0) { ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); + ast_dsp_free(sildet); return -1; } } @@ -619,13 +624,13 @@ totalsilence = 0; if (totalsilence > maxsilence) { - /* Ended happily with silence */ - if (option_verbose > 2) - ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); - ast_frfree(f); - gotsilence = 1; - outmsg=2; - break; + /* Ended happily with silence */ + if (option_verbose > 2) + ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); + ast_frfree(f); + gotsilence = 1; + outmsg=2; + break; } } /* Exit on any error */ @@ -704,6 +709,8 @@ if(!ast_streamfile(chan, "auth-thankyou", chan->language)) ast_waitstream(chan, ""); } + if (sildet) + ast_dsp_free(sildet); return res; } @@ -1061,7 +1068,50 @@ return x; } -int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration) +int ast_lock_path(const char *path) +{ + char *s; + char *fs; + int res; + int fd; + time_t start; + s = alloca(strlen(path) + 10); + fs = alloca(strlen(path) + 20); + if (!fs || !s) { + ast_log(LOG_WARNING, "Out of memory!\n"); + return -1; + } + snprintf(fs, strlen(path) + 19, "%s/%s-%08x", path, ".lock", rand()); + fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600); + if (fd < 0) { + fprintf(stderr, "Unable to create lock file: %s\n", strerror(errno)); + return -1; + } + close(fd); + snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock"); + time(&start); + while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5)) + usleep(1); + if (res < 0) { + ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno)); + } + unlink(fs); + ast_log(LOG_DEBUG, "Locked path '%s'\n", path); + return res; +} + +int ast_unlock_path(const char *path) +{ + char *s; + s = alloca(strlen(path) + 10); + if (!s) + return -1; + snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock"); + ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path); + return unlink(s); +} + +int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) { int silencethreshold = 128; int maxsilence=0; @@ -1108,7 +1158,7 @@ else ast_verbose(VERBOSE_PREFIX_3 "Recording\n"); recorded = 1; - cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence); + cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path); if (cmd == -1) { /* User has hung up, no options to give */ return cmd; Index: apps/app_meetme.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_meetme.c,v retrieving revision 1.72 diff -u -r1.72 app_meetme.c --- apps/app_meetme.c 22 Jan 2005 04:51:30 -0000 1.72 +++ apps/app_meetme.c 23 Jan 2005 09:01:22 -0000 @@ -626,7 +626,7 @@ snprintf(user->namerecloc,sizeof(user->namerecloc),"%s/meetme-username-%s-%d",AST_SPOOL_DIR,conf->confno,user->user_no); if (!(confflags & CONFFLAG_QUIET) && (confflags & CONFFLAG_INTROUSER)) - ast_record_review(chan,"vm-rec-name",user->namerecloc, 10,"sln", &duration); + ast_record_review(chan,"vm-rec-name",user->namerecloc, 10,"sln", &duration, NULL); while((confflags & CONFFLAG_WAITMARKED) && (conf->markedusers == 0)) { confflags &= ~CONFFLAG_QUIET; Index: apps/app_voicemail.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_voicemail.c,v retrieving revision 1.196 diff -u -r1.196 app_voicemail.c --- apps/app_voicemail.c 21 Jan 2005 07:06:24 -0000 1.196 +++ apps/app_voicemail.c 23 Jan 2005 09:01:27 -0000 @@ -185,7 +185,7 @@ }; static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option); static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context); -static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration); +static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir); static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc); static int vm_play_folder_name(struct ast_channel *chan, char *mbox); @@ -1299,11 +1299,13 @@ { int x; char fn[256]; + ast_lock_path(dir); for (x=0;xcontext, vmu->mailbox, frombox); make_file(frompath, sizeof(frompath), fromdir, msgnum); + ast_lock_path(topath); recipmsgnum = 0; do { make_file(topath, sizeof(topath), todir, recipmsgnum); @@ -1946,7 +1949,7 @@ } else { ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); } - + ast_unlock_path(topath); notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name); } @@ -2132,18 +2135,19 @@ strncpy(fmt, vmfmts, sizeof(fmt) - 1); if (!ast_strlen_zero(fmt)) { msgnum = 0; - do { - make_file(fn, sizeof(fn), dir, msgnum); - if (!EXISTS(dir,msgnum,fn,chan->language)) - break; - msgnum++; - } while (msgnum < MAXMSG); if (res >= 0) { /* Unless we're *really* silent, try to send the beep */ res = ast_streamfile(chan, "beep", chan->language); if (!res) res = ast_waitstream(chan, ""); } + ast_lock_path(dir); + do { + make_file(fn, sizeof(fn), dir, msgnum); + if (!EXISTS(dir,msgnum,fn,chan->language)) + break; + msgnum++; + } while (msgnum < MAXMSG); if (msgnum < MAXMSG) { /* Store information */ snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); @@ -2177,7 +2181,7 @@ fclose(txt); } else ast_log(LOG_WARNING, "Error opening text file for output\n"); - res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration); + res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration, dir); if (res == '0') goto transfer; if (res > 0) @@ -2220,6 +2224,7 @@ DISPOSE(dir, msgnum); } } else { + ast_unlock_path(dir); res = ast_streamfile(chan, "vm-mailboxfull", chan->language); if (!res) res = ast_waitstream(chan, ""); @@ -2248,6 +2253,7 @@ char sfn[256]; char dfn[256]; + ast_lock_path(dir); for (x=0,dest=0;x= MAXMSG) + if (x >= MAXMSG) { + ast_unlock_path(ddir); return -1; + } if (strcmp(sfn, dfn)) { COPY(dir, msg, ddir, x, sfn, dfn); } + ast_unlock_path(ddir); return 0; } @@ -3403,6 +3414,7 @@ int x; if (vms->lastmsg > -1) { /* Get the deleted messages fixed */ + ast_lock_path(vms->curdir); vms->curmsg = -1; for (x=0;x < MAXMSG;x++) { if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { @@ -3426,6 +3438,7 @@ break; DELETE(vms->curdir, x, vms->fn); } + ast_unlock_path(vms->curdir); } memset(vms->deleted, 0, sizeof(vms->deleted)); memset(vms->heard, 0, sizeof(vms->heard)); @@ -4067,7 +4080,7 @@ /* If forcename is set, have the user record their name */ if (ast_test_flag(vmu, VM_FORCENAME)) { snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); - cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration); + cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); if (cmd < 0 || cmd == 't' || cmd == '#') return cmd; } @@ -4075,11 +4088,11 @@ /* If forcegreetings is set, have the user record their greetings */ if (ast_test_flag(vmu, VM_FORCEGREET)) { snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); - cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration); + cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); if (cmd < 0 || cmd == 't' || cmd == '#') return cmd; snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); - cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration); + cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); if (cmd < 0 || cmd == 't' || cmd == '#') return cmd; } @@ -4113,15 +4126,15 @@ switch (cmd) { case '1': snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); - cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration); + cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); break; case '2': snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); - cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration); + cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); break; case '3': snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); - cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration); + cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); break; case '4': cmd = vm_tempgreeting(chan, vmu, vms, fmtc); @@ -4209,7 +4222,7 @@ if (ast_fileexists(prefile, NULL, NULL) > 0) { switch (cmd) { case '1': - cmd = play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration); + cmd = play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); break; case '2': ast_filedelete(prefile, NULL); @@ -4233,7 +4246,7 @@ } } } else { - play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration); + play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL); cmd = 't'; } } @@ -4908,7 +4921,8 @@ return 0; } -static int vm_box_exists(struct ast_channel *chan, void *data) { +static int vm_box_exists(struct ast_channel *chan, void *data) +{ struct localuser *u; struct ast_vm_user svm; char *context, *box; @@ -5738,7 +5752,7 @@ -static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration) +static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir) { /* Record message & let caller review or re-record it, or set options if applicable */ int res = 0; @@ -5793,7 +5807,7 @@ } recorded = 1; /* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */ - cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence); + cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir); if (cmd == -1) { /* User has hung up, no options to give */ return cmd; Index: include/asterisk/app.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/app.h,v retrieving revision 1.26 diff -u -r1.26 app.h --- include/asterisk/app.h 21 Jan 2005 07:06:25 -0000 1.26 +++ include/asterisk/app.h 23 Jan 2005 09:01:27 -0000 @@ -66,13 +66,20 @@ int ast_play_and_wait(struct ast_channel *chan, const char *fn); /*! Record a file for a max amount of time (in seconds), in a given list of formats separated by '|', outputting the duration of the recording, and with a maximum */ -/* permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. */ -int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms); +/* permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. + calls ast_unlock_path() on 'path' if passed */ +int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path); /*! Record a message and prepend the message to the given record file after playing the optional playfile (or a beep), storing the duration in 'duration' and with a maximum */ /* permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. */ int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence_ms); +/* Lock a path */ +int ast_lock_path(const char *path); + +/* Unlock a path */ +int ast_unlock_path(const char *path); + #define GROUP_CATEGORY_PREFIX "GROUP" /*! Split a group string into group and category, returning a default category if none is provided. */ @@ -94,7 +101,7 @@ int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout); /*! Allow to record message and have a review option */ -int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration); +int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path); #if defined(__cplusplus) || defined(c_plusplus) }