summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2006-12-05 01:39:53 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2006-12-05 01:39:53 +0000
commit1256ac0519350b0899e26611ae3237f789f53598 (patch)
tree947545522699346b2ad98b93fcc1810617985f5b
parent05261e30e9e000ba4a0af844defc2ab2f0af596b (diff)
Merged revisions 48252 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ................ r48252 | tilghman | 2006-12-04 19:34:34 -0600 (Mon, 04 Dec 2006) | 14 lines Merged revisions 48251 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r48251 | tilghman | 2006-12-04 19:26:08 -0600 (Mon, 04 Dec 2006) | 6 lines If the recording in the database is too large, it will fail to retrieve with an mmap error. Not too sure why this doesn't happen when we put it in the database, also, but since that doesn't seem to be broken, I'm not going to fix it (at least until someone reports it). Solution is to ask for the file in smaller chunks. (Bug 8385) ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@48253 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--apps/app_voicemail.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 2eb30bc32..bd39abae1 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -142,6 +142,7 @@ static struct vmstate *vmstates = NULL;
/* Don't modify these here; set your umask at runtime instead */
#define VOICEMAIL_DIR_MODE 0777
#define VOICEMAIL_FILE_MODE 0666
+#define CHUNKSIZE 65536
#define VOICEMAIL_CONFIG "voicemail.conf"
#define ASTERISK_USERNAME "asterisk"
@@ -1099,6 +1100,7 @@ static int retrieve_file(char *dir, int msgnum)
goto yuck;
}
if (!strcasecmp(coltitle, "recording")) {
+ off_t offset;
res = SQLGetData(stmt, x + 1, SQL_BINARY, NULL, 0, &colsize2);
fdlen = colsize2;
if (fd > -1) {
@@ -1109,24 +1111,26 @@ static int retrieve_file(char *dir, int msgnum)
fd = -1;
continue;
}
- if (fd > -1) {
- if ((fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == -1) {
+ /* Read out in small chunks */
+ for (offset = 0; offset < colsize2; offset += CHUNKSIZE) {
+ /* +1 because SQLGetData likes null-terminating binary data */
+ if ((fdm = mmap(NULL, CHUNKSIZE + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == (void *)-1) {
ast_log(LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
goto yuck;
+ } else {
+ res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE + 1, NULL);
+ munmap(fdm, 0);
+ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+ ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
+ unlink(full_fn);
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+ goto yuck;
+ }
}
}
- }
- if (fdm) {
- memset(fdm, 0, fdlen);
- res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, fdlen, &colsize2);
- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
- SQLFreeHandle (SQL_HANDLE_STMT, stmt);
- ast_odbc_release_obj(obj);
- goto yuck;
- }
+ truncate(full_fn, fdlen);
}
} else {
res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
@@ -1147,8 +1151,6 @@ static int retrieve_file(char *dir, int msgnum)
yuck:
if (f)
fclose(f);
- if (fdm)
- munmap(fdm, fdlen);
if (fd > -1)
close(fd);
return x - 1;