Index: apps/app_voicemail.c =================================================================== --- apps/app_voicemail.c (revision 48177) +++ apps/app_voicemail.c (working copy) @@ -77,6 +77,7 @@ #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 @@ 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,23 +937,26 @@ 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; + } } } + truncate(full_fn, fdlen); } - 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; - } - } } else { res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { @@ -969,8 +974,6 @@ yuck: if (f) fclose(f); - if (fdm) - munmap(fdm, fdlen); if (fd > -1) close(fd); return x - 1;