aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2006-12-05 01:26:08 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2006-12-05 01:26:08 +0000
commit2780858dde77ff62015006b01c17f06abc8bfed7 (patch)
tree03900727f7e51a9ad2a47da288e0df418f5da08b /apps
parent45bbfd2bece9136655f4f3e9e2a2e1171e01a50a (diff)
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: http://svn.digium.com/svn/asterisk/branches/1.2@48251 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rw-r--r--apps/app_voicemail.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index a1b46d318..a8477724c 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -77,6 +77,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define COMMAND_TIMEOUT 5000
#define VOICEMAIL_DIR_MODE 0700
#define VOICEMAIL_FILE_MODE 0600
+#define CHUNKSIZE 65536
#define VOICEMAIL_CONFIG "voicemail.conf"
#define ASTERISK_USERNAME "asterisk"
@@ -925,6 +926,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, &colsize);
fdlen = colsize;
if (fd > -1) {
@@ -935,22 +937,25 @@ 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 < colsize; offset += CHUNKSIZE) {
+ /* +1 because SQLGetData likes null-terminating binary data */
+ if ((fdm = mmap(NULL, CHUNKSIZE + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == -1) {
ast_log(LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
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, &colsize);
- 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);
- goto yuck;
- }
+ truncate(full_fn, fdlen);
}
} else {
res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
@@ -969,8 +974,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;