mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-08 14:17:02 +00:00
fix up lock breakage from bug #4245
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6125 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
24
app.c
24
app.c
@@ -1095,36 +1095,42 @@ int ast_separate_app_args(char *buf, char delim, char **array, int arraylen)
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_lock_path(const char *path)
|
enum AST_LOCK_RESULT ast_lock_path(const char *path)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
char *fs;
|
char *fs;
|
||||||
int res;
|
int res;
|
||||||
int fd;
|
int fd;
|
||||||
time_t start;
|
time_t start;
|
||||||
|
|
||||||
s = alloca(strlen(path) + 10);
|
s = alloca(strlen(path) + 10);
|
||||||
fs = alloca(strlen(path) + 20);
|
fs = alloca(strlen(path) + 20);
|
||||||
|
|
||||||
if (!fs || !s) {
|
if (!fs || !s) {
|
||||||
ast_log(LOG_WARNING, "Out of memory!\n");
|
ast_log(LOG_WARNING, "Out of memory!\n");
|
||||||
return -1;
|
return AST_LOCK_FAILURE;
|
||||||
}
|
}
|
||||||
snprintf(fs, strlen(path) + 19, "%s/%s-%08x", path, ".lock", rand());
|
|
||||||
|
snprintf(fs, strlen(path) + 19, "%s/.lock-%08x", path, rand());
|
||||||
fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "Unable to create lock file: %s\n", strerror(errno));
|
fprintf(stderr, "Unable to create lock file '%s': %s\n", path, strerror(errno));
|
||||||
return -1;
|
return AST_LOCK_PATH_NOT_FOUND;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock");
|
|
||||||
|
snprintf(s, strlen(path) + 9, "%s/.lock", path);
|
||||||
time(&start);
|
time(&start);
|
||||||
while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5))
|
while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5))
|
||||||
usleep(1);
|
usleep(1);
|
||||||
if (res < 0) {
|
if (res) {
|
||||||
ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
|
ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
|
||||||
}
|
return AST_LOCK_TIMEOUT;
|
||||||
|
} else {
|
||||||
unlink(fs);
|
unlink(fs);
|
||||||
ast_log(LOG_DEBUG, "Locked path '%s'\n", path);
|
ast_log(LOG_DEBUG, "Locked path '%s'\n", path);
|
||||||
return res;
|
return AST_LOCK_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_unlock_path(const char *path)
|
int ast_unlock_path(const char *path)
|
||||||
|
@@ -692,6 +692,19 @@ static int make_file(char *dest, int len, char *dir, int num)
|
|||||||
return snprintf(dest, len, "%s/msg%04d", dir, num);
|
return snprintf(dest, len, "%s/msg%04d", dir, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* only return failure if ast_lock_path returns 'timeout',
|
||||||
|
not if the path does not exist or any other reason
|
||||||
|
*/
|
||||||
|
static int vm_lock_path(const char *path)
|
||||||
|
{
|
||||||
|
switch (ast_lock_path(path)) {
|
||||||
|
case AST_LOCK_TIMEOUT:
|
||||||
|
return -1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_ODBC_STORAGE
|
#ifdef USE_ODBC_STORAGE
|
||||||
static int retrieve_file(char *dir, int msgnum)
|
static int retrieve_file(char *dir, int msgnum)
|
||||||
@@ -982,9 +995,9 @@ yuck:
|
|||||||
*/
|
*/
|
||||||
static int count_messages(struct ast_vm_user *vmu, char *dir)
|
static int count_messages(struct ast_vm_user *vmu, char *dir)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res;
|
||||||
|
|
||||||
res = last_message_index(vmu, dir) + 1;
|
res = last_message_index(vmu, dir);
|
||||||
return res >= 0 ? res + 1 : res;
|
return res >= 0 ? res + 1 : res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1259,23 +1272,19 @@ static int count_messages(struct ast_vm_user *vmu, char *dir)
|
|||||||
DIR *vmdir = NULL;
|
DIR *vmdir = NULL;
|
||||||
struct dirent *vment = NULL;
|
struct dirent *vment = NULL;
|
||||||
|
|
||||||
if (!ast_lock_path(dir)) {
|
if (vm_lock_path(dir))
|
||||||
|
return ERROR_LOCK_PATH;
|
||||||
|
|
||||||
if ((vmdir = opendir(dir))) {
|
if ((vmdir = opendir(dir))) {
|
||||||
while ((vment = readdir(vmdir)))
|
while ((vment = readdir(vmdir))) {
|
||||||
{
|
|
||||||
if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4))
|
if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4))
|
||||||
{
|
|
||||||
vmcount++;
|
vmcount++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
closedir(vmdir);
|
closedir(vmdir);
|
||||||
}
|
}
|
||||||
ast_unlock_path(dir);
|
ast_unlock_path(dir);
|
||||||
|
|
||||||
return vmcount;
|
return vmcount;
|
||||||
} else {
|
|
||||||
return ERROR_LOCK_PATH;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rename_file(char *sfn, char *dfn)
|
static void rename_file(char *sfn, char *dfn)
|
||||||
@@ -1354,17 +1363,18 @@ static int last_message_index(struct ast_vm_user *vmu, char *dir)
|
|||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
char fn[256];
|
char fn[256];
|
||||||
if (!ast_lock_path(dir)) {
|
|
||||||
|
if (vm_lock_path(dir))
|
||||||
|
return ERROR_LOCK_PATH;
|
||||||
|
|
||||||
for (x = 0; x < vmu->maxmsg; x++) {
|
for (x = 0; x < vmu->maxmsg; x++) {
|
||||||
make_file(fn, sizeof(fn), dir, x);
|
make_file(fn, sizeof(fn), dir, x);
|
||||||
if (ast_fileexists(fn, NULL, NULL) < 1)
|
if (ast_fileexists(fn, NULL, NULL) < 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ast_unlock_path(dir);
|
ast_unlock_path(dir);
|
||||||
|
|
||||||
return x - 1;
|
return x - 1;
|
||||||
} else {
|
|
||||||
return ERROR_LOCK_PATH;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vm_delete(char *file)
|
static int vm_delete(char *file)
|
||||||
@@ -1997,7 +2007,10 @@ static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int i
|
|||||||
|
|
||||||
make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
|
make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
|
||||||
make_file(frompath, sizeof(frompath), fromdir, msgnum);
|
make_file(frompath, sizeof(frompath), fromdir, msgnum);
|
||||||
if (!ast_lock_path(topath)) {
|
|
||||||
|
if (vm_lock_path(topath))
|
||||||
|
return ERROR_LOCK_PATH;
|
||||||
|
|
||||||
recipmsgnum = 0;
|
recipmsgnum = 0;
|
||||||
do {
|
do {
|
||||||
make_file(topath, sizeof(topath), todir, recipmsgnum);
|
make_file(topath, sizeof(topath), todir, recipmsgnum);
|
||||||
@@ -2012,9 +2025,6 @@ static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int i
|
|||||||
}
|
}
|
||||||
ast_unlock_path(topath);
|
ast_unlock_path(topath);
|
||||||
notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
|
notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
|
||||||
} else {
|
|
||||||
return ERROR_LOCK_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2208,7 +2218,12 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
|
|||||||
ast_copy_string(fmt, vmfmts, sizeof(fmt));
|
ast_copy_string(fmt, vmfmts, sizeof(fmt));
|
||||||
if (!ast_strlen_zero(fmt)) {
|
if (!ast_strlen_zero(fmt)) {
|
||||||
msgnum = 0;
|
msgnum = 0;
|
||||||
if (!ast_lock_path(dir)) {
|
|
||||||
|
if (vm_lock_path(dir)) {
|
||||||
|
free_user(vmu);
|
||||||
|
return ERROR_LOCK_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
/* Unless we're *really* silent, try to send the beep */
|
/* Unless we're *really* silent, try to send the beep */
|
||||||
res = ast_streamfile(chan, "beep", chan->language);
|
res = ast_streamfile(chan, "beep", chan->language);
|
||||||
@@ -2222,7 +2237,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
|
|||||||
msgnum++;
|
msgnum++;
|
||||||
} while (msgnum < vmu->maxmsg);
|
} while (msgnum < vmu->maxmsg);
|
||||||
if (msgnum < vmu->maxmsg) {
|
if (msgnum < vmu->maxmsg) {
|
||||||
|
|
||||||
/* assign a variable with the name of the voicemail file */
|
/* assign a variable with the name of the voicemail file */
|
||||||
pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
|
pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
|
||||||
|
|
||||||
@@ -2305,10 +2319,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
|
|||||||
res = ast_waitstream(chan, "");
|
res = ast_waitstream(chan, "");
|
||||||
ast_log(LOG_WARNING, "No more messages possible\n");
|
ast_log(LOG_WARNING, "No more messages possible\n");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
free_user(vmu);
|
|
||||||
return ERROR_LOCK_PATH;
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
ast_log(LOG_WARNING, "No format for saving voicemail?\n");
|
ast_log(LOG_WARNING, "No format for saving voicemail?\n");
|
||||||
leave_vm_out:
|
leave_vm_out:
|
||||||
@@ -2316,8 +2326,7 @@ leave_vm_out:
|
|||||||
} else {
|
} else {
|
||||||
ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
|
ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
|
||||||
/*Send the call to n+101 priority, where n is the current priority*/
|
/*Send the call to n+101 priority, where n is the current priority*/
|
||||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->cid.cid_num))
|
ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
|
||||||
chan->priority+=100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -2332,7 +2341,9 @@ static int resequence_mailbox(struct ast_vm_user *vmu, char *dir)
|
|||||||
char sfn[256];
|
char sfn[256];
|
||||||
char dfn[256];
|
char dfn[256];
|
||||||
|
|
||||||
if (!ast_lock_path(dir)) {
|
if (vm_lock_path(dir))
|
||||||
|
return ERROR_LOCK_PATH;
|
||||||
|
|
||||||
for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
|
for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
|
||||||
make_file(sfn, sizeof(sfn), dir, x);
|
make_file(sfn, sizeof(sfn), dir, x);
|
||||||
if (EXISTS(dir, x, sfn, NULL)) {
|
if (EXISTS(dir, x, sfn, NULL)) {
|
||||||
@@ -2346,9 +2357,6 @@ static int resequence_mailbox(struct ast_vm_user *vmu, char *dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast_unlock_path(dir);
|
ast_unlock_path(dir);
|
||||||
} else {
|
|
||||||
return ERROR_LOCK_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2371,7 +2379,10 @@ static int save_to_folder(struct ast_vm_user *vmu, char *dir, int msg, char *con
|
|||||||
make_file(sfn, sizeof(sfn), dir, msg);
|
make_file(sfn, sizeof(sfn), dir, msg);
|
||||||
make_dir(ddir, sizeof(ddir), context, username, dbox);
|
make_dir(ddir, sizeof(ddir), context, username, dbox);
|
||||||
mkdir(ddir, 0700);
|
mkdir(ddir, 0700);
|
||||||
if (!ast_lock_path(ddir)) {
|
|
||||||
|
if (vm_lock_path(ddir))
|
||||||
|
return ERROR_LOCK_PATH;
|
||||||
|
|
||||||
for (x = 0; x < vmu->maxmsg; x++) {
|
for (x = 0; x < vmu->maxmsg; x++) {
|
||||||
make_file(dfn, sizeof(dfn), ddir, x);
|
make_file(dfn, sizeof(dfn), ddir, x);
|
||||||
if (!EXISTS(ddir, x, dfn, NULL))
|
if (!EXISTS(ddir, x, dfn, NULL))
|
||||||
@@ -2385,9 +2396,6 @@ static int save_to_folder(struct ast_vm_user *vmu, char *dir, int msg, char *con
|
|||||||
COPY(dir, msg, ddir, x, sfn, dfn);
|
COPY(dir, msg, ddir, x, sfn, dfn);
|
||||||
}
|
}
|
||||||
ast_unlock_path(ddir);
|
ast_unlock_path(ddir);
|
||||||
} else {
|
|
||||||
return ERROR_LOCK_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3526,9 +3534,14 @@ static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
|
|||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
if (vms->lastmsg > -1) {
|
|
||||||
|
if (vms->lastmsg <= -1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* Get the deleted messages fixed */
|
/* Get the deleted messages fixed */
|
||||||
if (!ast_lock_path(vms->curdir)) {
|
if (vm_lock_path(vms->curdir))
|
||||||
|
return ERROR_LOCK_PATH;
|
||||||
|
|
||||||
vms->curmsg = -1;
|
vms->curmsg = -1;
|
||||||
for (x=0;x < vmu->maxmsg;x++) {
|
for (x=0;x < vmu->maxmsg;x++) {
|
||||||
if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) {
|
if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) {
|
||||||
@@ -3559,12 +3572,11 @@ static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
|
|||||||
DELETE(vms->curdir, x, vms->fn);
|
DELETE(vms->curdir, x, vms->fn);
|
||||||
}
|
}
|
||||||
ast_unlock_path(vms->curdir);
|
ast_unlock_path(vms->curdir);
|
||||||
} else {
|
|
||||||
return ERROR_LOCK_PATH;
|
done:
|
||||||
}
|
|
||||||
}
|
|
||||||
memset(vms->deleted, 0, sizeof(vms->deleted));
|
memset(vms->deleted, 0, sizeof(vms->deleted));
|
||||||
memset(vms->heard, 0, sizeof(vms->heard));
|
memset(vms->heard, 0, sizeof(vms->heard));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -139,8 +139,19 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
|
|||||||
/* permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. */
|
/* 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);
|
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 */
|
enum AST_LOCK_RESULT {
|
||||||
int ast_lock_path(const char *path);
|
AST_LOCK_SUCCESS = 0,
|
||||||
|
AST_LOCK_TIMEOUT = -1,
|
||||||
|
AST_LOCK_PATH_NOT_FOUND = -2,
|
||||||
|
AST_LOCK_FAILURE = -3,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \brief Lock a filesystem path.
|
||||||
|
* \param path the path to be locked
|
||||||
|
* \return one of AST_LOCK_RESULT values
|
||||||
|
*/
|
||||||
|
enum AST_LOCK_RESULT ast_lock_path(const char *path);
|
||||||
|
|
||||||
/* Unlock a path */
|
/* Unlock a path */
|
||||||
int ast_unlock_path(const char *path);
|
int ast_unlock_path(const char *path);
|
||||||
|
Reference in New Issue
Block a user