list macro conversion (issue #6328, with bugfix)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@10020 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Kevin P. Fleming 20 years ago
parent 918cab0e08
commit c6ddfef02d

@ -240,7 +240,7 @@ struct ast_vm_user {
unsigned int flags; /*!< VM_ flags */ unsigned int flags; /*!< VM_ flags */
int saydurationm; int saydurationm;
int maxmsg; /*!< Maximum number of msgs per folder for this mailbox */ int maxmsg; /*!< Maximum number of msgs per folder for this mailbox */
struct ast_vm_user *next; AST_LIST_ENTRY(ast_vm_user) list;
}; };
struct vm_zone { struct vm_zone {
@ -386,9 +386,7 @@ static char *app2 = "VoiceMailMain";
static char *app3 = "MailboxExists"; static char *app3 = "MailboxExists";
static char *app4 = "VMAuthenticate"; static char *app4 = "VMAuthenticate";
AST_MUTEX_DEFINE_STATIC(vmlock); static AST_LIST_HEAD_STATIC(users, ast_vm_user);
struct ast_vm_user *users;
struct ast_vm_user *usersl;
struct vm_zone *zones = NULL; struct vm_zone *zones = NULL;
struct vm_zone *zonesl = NULL; struct vm_zone *zonesl = NULL;
static int maxsilence; static int maxsilence;
@ -586,29 +584,27 @@ static struct ast_vm_user *find_user(struct ast_vm_user *ivm, const char *contex
{ {
/* This function could be made to generate one from a database, too */ /* This function could be made to generate one from a database, too */
struct ast_vm_user *vmu=NULL, *cur; struct ast_vm_user *vmu=NULL, *cur;
ast_mutex_lock(&vmlock); AST_LIST_LOCK(&users);
cur = users;
if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
context = "default"; context = "default";
while (cur) { AST_LIST_TRAVERSE(&users, cur, list) {
if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
break; break;
if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
break; break;
cur=cur->next;
} }
if (cur) { if (cur) {
/* Make a copy, so that on a reload, we have no race */ /* Make a copy, so that on a reload, we have no race */
if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
memcpy(vmu, cur, sizeof(*vmu)); memcpy(vmu, cur, sizeof(*vmu));
ast_set2_flag(vmu, !ivm, VM_ALLOCED); ast_set2_flag(vmu, !ivm, VM_ALLOCED);
vmu->next = NULL; AST_LIST_NEXT(vmu, list) = NULL;
} }
} else } else
vmu = find_user_realtime(ivm, context, mailbox); vmu = find_user_realtime(ivm, context, mailbox);
ast_mutex_unlock(&vmlock); AST_LIST_UNLOCK(&users);
return vmu; return vmu;
} }
@ -617,19 +613,17 @@ static int reset_user_pw(const char *context, const char *mailbox, const char *n
/* This function could be made to generate one from a database, too */ /* This function could be made to generate one from a database, too */
struct ast_vm_user *cur; struct ast_vm_user *cur;
int res = -1; int res = -1;
ast_mutex_lock(&vmlock); AST_LIST_LOCK(&users);
cur = users; AST_LIST_TRAVERSE(&users, cur, list) {
while (cur) {
if ((!context || !strcasecmp(context, cur->context)) && if ((!context || !strcasecmp(context, cur->context)) &&
(!strcasecmp(mailbox, cur->mailbox))) (!strcasecmp(mailbox, cur->mailbox)))
break; break;
cur=cur->next;
} }
if (cur) { if (cur) {
ast_copy_string(cur->password, newpass, sizeof(cur->password)); ast_copy_string(cur->password, newpass, sizeof(cur->password));
res = 0; res = 0;
} }
ast_mutex_unlock(&vmlock); AST_LIST_UNLOCK(&users);
return res; return res;
} }
@ -3363,7 +3357,8 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
char callerid[512]; char callerid[512];
char ext_context[256]=""; char ext_context[256]="";
int res = 0, cmd = 0; int res = 0, cmd = 0;
struct ast_vm_user *receiver = NULL, *extensions = NULL, *vmtmp = NULL, *vmfree; struct ast_vm_user *receiver, *vmtmp;
AST_LIST_HEAD_NOLOCK(extension, ast_vm_user) extensions;
char tmp[256]; char tmp[256];
char *stringp, *s; char *stringp, *s;
int saved_messages = 0, found = 0; int saved_messages = 0, found = 0;
@ -3459,12 +3454,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
while (s) { while (s) {
/* find_user is going to ast_malloc since we have a NULL as first argument */ /* find_user is going to ast_malloc since we have a NULL as first argument */
if ((receiver = find_user(NULL, context, s))) { if ((receiver = find_user(NULL, context, s))) {
if (!extensions) AST_LIST_INSERT_HEAD(&extensions, receiver, list);
vmtmp = extensions = receiver;
else {
vmtmp->next = receiver;
vmtmp = receiver;
}
found++; found++;
} else { } else {
valid_extensions = 0; valid_extensions = 0;
@ -3479,9 +3469,8 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
res = ast_play_and_wait(chan, "pbx-invalid"); res = ast_play_and_wait(chan, "pbx-invalid");
} }
/* check if we're clear to proceed */ /* check if we're clear to proceed */
if (!extensions || !valid_extensions) if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
return res; return res;
vmtmp = extensions;
if (flag==1) { if (flag==1) {
struct leave_vm_options leave_options; struct leave_vm_options leave_options;
@ -3495,7 +3484,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
RETRIEVE(dir, curmsg); RETRIEVE(dir, curmsg);
cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain); cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain);
if (!cmd) { if (!cmd) {
while (!res && vmtmp) { AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
/* if (ast_play_and_wait(chan, "vm-savedto")) /* if (ast_play_and_wait(chan, "vm-savedto"))
break; break;
*/ */
@ -3567,10 +3556,12 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
run_externnotify(vmtmp->context, vmtmp->mailbox); run_externnotify(vmtmp->context, vmtmp->mailbox);
saved_messages++; saved_messages++;
vmfree = vmtmp; AST_LIST_REMOVE_CURRENT(&extensions, list);
vmtmp = vmtmp->next; free_user(vmtmp);
free_user(vmfree); if (res)
break;
} }
AST_LIST_TRAVERSE_SAFE_END;
if (saved_messages > 0) { if (saved_messages > 0) {
/* give confirmation that the message was saved */ /* give confirmation that the message was saved */
/* commented out since we can't forward batches yet /* commented out since we can't forward batches yet
@ -5645,12 +5636,7 @@ static int append_mailbox(char *context, char *mbox, char *data)
if (stringp && (s = strsep(&stringp, ","))) if (stringp && (s = strsep(&stringp, ",")))
apply_options(vmu, s); apply_options(vmu, s);
vmu->next = NULL; AST_LIST_INSERT_TAIL(&users, vmu, list);
if (usersl)
usersl->next = vmu;
else
users = vmu;
usersl = vmu;
} }
return 0; return 0;
} }
@ -5752,31 +5738,31 @@ static char show_voicemail_zones_help[] =
static int handle_show_voicemail_users(int fd, int argc, char *argv[]) static int handle_show_voicemail_users(int fd, int argc, char *argv[])
{ {
struct ast_vm_user *vmu = users; struct ast_vm_user *vmu;
char *output_format = "%-10s %-5s %-25s %-10s %6s\n"; char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE; if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE; else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
if (vmu) { AST_LIST_LOCK(&users);
if (!AST_LIST_EMPTY(&users)) {
if (argc == 3) if (argc == 3)
ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg"); ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
else { else {
int count = 0; int count = 0;
while (vmu) { AST_LIST_TRAVERSE(&users, vmu, list) {
if (!strcmp(argv[4],vmu->context)) if (!strcmp(argv[4],vmu->context))
count++; count++;
vmu = vmu->next;
} }
if (count) { if (count) {
vmu = users;
ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg"); ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
} else { } else {
ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]); ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
AST_LIST_UNLOCK(&users);
return RESULT_FAILURE; return RESULT_FAILURE;
} }
} }
while (vmu) { AST_LIST_TRAVERSE(&users, vmu, list) {
char dirname[256]; char dirname[256];
DIR *vmdir; DIR *vmdir;
struct dirent *vment; struct dirent *vment;
@ -5795,12 +5781,13 @@ static int handle_show_voicemail_users(int fd, int argc, char *argv[])
snprintf(count,sizeof(count),"%d",vmcount); snprintf(count,sizeof(count),"%d",vmcount);
ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
} }
vmu = vmu->next;
} }
} else { } else {
ast_cli(fd, "There are no voicemail users currently defined\n"); ast_cli(fd, "There are no voicemail users currently defined\n");
AST_LIST_UNLOCK(&users);
return RESULT_FAILURE; return RESULT_FAILURE;
} }
AST_LIST_UNLOCK(&users);
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
@ -5841,7 +5828,7 @@ static char *complete_show_voicemail_users(const char *line, const char *word, i
return NULL; return NULL;
} }
wordlen = strlen(word); wordlen = strlen(word);
for (vmu = users; vmu; vmu = vmu->next) { AST_LIST_TRAVERSE(&users, vmu, list) {
if (!strncasecmp(word, vmu->context, wordlen)) { if (!strncasecmp(word, vmu->context, wordlen)) {
if (context && strcmp(context, vmu->context)) { if (context && strcmp(context, vmu->context)) {
if (++which > state) { if (++which > state) {
@ -5866,7 +5853,7 @@ static struct ast_cli_entry show_voicemail_zones_cli =
static int load_config(void) static int load_config(void)
{ {
struct ast_vm_user *cur, *l; struct ast_vm_user *cur;
struct vm_zone *zcur, *zl; struct vm_zone *zcur, *zl;
struct ast_config *cfg; struct ast_config *cfg;
char *cat; char *cat;
@ -5902,14 +5889,13 @@ static int load_config(void)
int tmpadsi[4]; int tmpadsi[4];
cfg = ast_config_load(VOICEMAIL_CONFIG); cfg = ast_config_load(VOICEMAIL_CONFIG);
ast_mutex_lock(&vmlock); AST_LIST_LOCK(&users);
cur = users; AST_LIST_TRAVERSE_SAFE_BEGIN(&users, cur, list) {
while (cur) { AST_LIST_REMOVE_CURRENT(&users, list);
l = cur; ast_set_flag(cur, VM_ALLOCED);
cur = cur->next; free_user(cur);
ast_set_flag(l, VM_ALLOCED);
free_user(l);
} }
AST_LIST_TRAVERSE_SAFE_END
zcur = zones; zcur = zones;
while (zcur) { while (zcur) {
zl = zcur; zl = zcur;
@ -5918,8 +5904,7 @@ static int load_config(void)
} }
zones = NULL; zones = NULL;
zonesl = NULL; zonesl = NULL;
users = NULL; AST_LIST_HEAD_INIT(&users);
usersl = NULL;
memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
if (cfg) { if (cfg) {
@ -6310,11 +6295,11 @@ static int load_config(void)
tmpread = tmpwrite+len; tmpread = tmpwrite+len;
} }
} }
ast_mutex_unlock(&vmlock); AST_LIST_UNLOCK(&users);
ast_config_destroy(cfg); ast_config_destroy(cfg);
return 0; return 0;
} else { } else {
ast_mutex_unlock(&vmlock); AST_LIST_UNLOCK(&users);
ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n"); ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
return 0; return 0;
} }

Loading…
Cancel
Save