[Asterisk-code-review] app_voicemail: Refactor email generation functions (asterisk[master])
N A
asteriskteam at digium.com
Mon Nov 1 10:42:33 CDT 2021
N A has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/16665 )
Change subject: app_voicemail: Refactor email generation functions
......................................................................
app_voicemail: Refactor email generation functions
Refactors generic functions used for email generation
into a separate file that can be included by multiple
modules, including app_voicemail, to avoid code
duplication.
ASTERISK-29715 #close
Change-Id: I1de0ed3483623e9599711129edc817c45ad237ee
---
M apps/app_voicemail.c
A include/asterisk/mail.h
A main/mail.c
3 files changed, 236 insertions(+), 150 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/65/16665/1
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index cb70ed6..57dd575 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -100,6 +100,7 @@
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
#include "asterisk/format_cache.h"
+#include "asterisk/mail.h"
#ifdef ODBC_STORAGE
#include "asterisk/res_odbc.h"
@@ -539,8 +540,6 @@
#define MINPASSWORD 0 /*!< Default minimum mailbox password length */
-#define BASELINELEN 72
-#define BASEMAXINLINE 256
#ifdef IMAP_STORAGE
#define ENDL "\r\n"
#else
@@ -1928,22 +1927,6 @@
return snprintf(dest, len, "%s/msg%04d", dir, num);
}
-/* same as mkstemp, but return a FILE * */
-static FILE *vm_mkftemp(char *template)
-{
- FILE *p = NULL;
- int pfd = mkstemp(template);
- chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
- if (pfd > -1) {
- p = fdopen(pfd, "w+");
- if (!p) {
- close(pfd);
- pfd = -1;
- }
- }
- return p;
-}
-
/*! \brief basically mkdir -p $dest/$context/$ext/$folder
* \param dest String. base directory.
* \param len Length of dest.
@@ -2697,7 +2680,7 @@
/* Make a temporary file instead of piping directly to sendmail, in case the mail
command hangs. */
- if (!(p = vm_mkftemp(tmp))) {
+ if (!(p = ast_file_mkftemp(tmp))) {
ast_log(AST_LOG_WARNING, "Unable to store '%s' (can't create temporary file)\n", fn);
if (tempcopy) {
ast_free(vmu->email);
@@ -4771,134 +4754,6 @@
return ast_filedelete(file, NULL);
}
-/*!
- * \brief utility used by inchar(), for base_encode()
- */
-static int inbuf(struct baseio *bio, FILE *fi)
-{
- int l;
-
- if (bio->ateof)
- return 0;
-
- if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) != BASEMAXINLINE) {
- bio->ateof = 1;
- if (l == 0) {
- /* Assume EOF */
- return 0;
- }
- }
-
- bio->iolen = l;
- bio->iocp = 0;
-
- return 1;
-}
-
-/*!
- * \brief utility used by base_encode()
- */
-static int inchar(struct baseio *bio, FILE *fi)
-{
- if (bio->iocp>=bio->iolen) {
- if (!inbuf(bio, fi))
- return EOF;
- }
-
- return bio->iobuf[bio->iocp++];
-}
-
-/*!
- * \brief utility used by base_encode()
- */
-static int ochar(struct baseio *bio, int c, FILE *so)
-{
- if (bio->linelength >= BASELINELEN) {
- if (fputs(ENDL, so) == EOF) {
- return -1;
- }
-
- bio->linelength = 0;
- }
-
- if (putc(((unsigned char) c), so) == EOF) {
- return -1;
- }
-
- bio->linelength++;
-
- return 1;
-}
-
-/*!
- * \brief Performs a base 64 encode algorithm on the contents of a File
- * \param filename The path to the file to be encoded. Must be readable, file is opened in read mode.
- * \param so A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename.
- *
- * TODO: shouldn't this (and the above 3 support functions) be put into some kind of external utility location, such as funcs/func_base64.c ?
- *
- * \return zero on success, -1 on error.
- */
-static int base_encode(char *filename, FILE *so)
-{
- static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
- 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
- '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
- int i, hiteof = 0;
- FILE *fi;
- struct baseio bio;
-
- memset(&bio, 0, sizeof(bio));
- bio.iocp = BASEMAXINLINE;
-
- if (!(fi = fopen(filename, "rb"))) {
- ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
- return -1;
- }
-
- while (!hiteof){
- unsigned char igroup[3], ogroup[4];
- int c, n;
-
- memset(igroup, 0, sizeof(igroup));
-
- for (n = 0; n < 3; n++) {
- if ((c = inchar(&bio, fi)) == EOF) {
- hiteof = 1;
- break;
- }
-
- igroup[n] = (unsigned char) c;
- }
-
- if (n > 0) {
- ogroup[0]= dtable[igroup[0] >> 2];
- ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
- ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
- ogroup[3]= dtable[igroup[2] & 0x3F];
-
- if (n < 3) {
- ogroup[3] = '=';
-
- if (n < 2)
- ogroup[2] = '=';
- }
-
- for (i = 0; i < 4; i++)
- ochar(&bio, ogroup[i], so);
- }
- }
-
- fclose(fi);
-
- if (fputs(ENDL, so) == EOF) {
- return 0;
- }
-
- return 1;
-}
-
static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag)
{
char callerid[256];
@@ -5509,7 +5364,7 @@
fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename);
else
fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format);
- base_encode(fname, p);
+ ast_base_encode(fname, p);
if (last)
fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound);
@@ -5562,7 +5417,7 @@
ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %u\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
/* Make a temporary file instead of piping directly to sendmail, in case the mail
command hangs */
- if ((p = vm_mkftemp(tmp)) == NULL) {
+ if ((p = ast_file_mkftemp(tmp)) == NULL) {
ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
return -1;
} else {
@@ -5601,7 +5456,7 @@
strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname));
}
- if ((p = vm_mkftemp(tmp)) == NULL) {
+ if ((p = ast_file_mkftemp(tmp)) == NULL) {
ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
ast_free(str1);
ast_free(str2);
diff --git a/include/asterisk/mail.h b/include/asterisk/mail.h
new file mode 100644
index 0000000..52e4007
--- /dev/null
+++ b/include/asterisk/mail.h
@@ -0,0 +1,44 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2021, Naveen Albert
+ *
+ * Naveen Albert <asterisk at phreaknet.org>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!\file
+ * \brief Email generation functions
+ */
+
+#define VOICEMAIL_FILE_MODE 0666
+#define BASELINELEN 72
+#define BASEMAXINLINE 256
+#define SENDMAIL "/usr/sbin/sendmail -t"
+#define ENDL "\n"
+
+/*!
+ * \brief Performs a base 64 encode algorithm on the contents of a File
+ * \param filename The path to the file to be encoded. Must be readable, file is opened in read mode.
+ * \param so A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename.
+ *
+ * \return zero on success, -1 on error.
+ */
+int ast_base_encode(char *filename, FILE *so);
+
+/*!
+ * \brief same as mkstemp, but return a FILE
+ * \param template The template for the unique file name to generate
+ *
+ * \return FILE handle to the temporary file on success or NULL if creation failed
+ */
+FILE *ast_file_mkftemp(char *template);
diff --git a/main/mail.c b/main/mail.c
new file mode 100644
index 0000000..739c9f6
--- /dev/null
+++ b/main/mail.c
@@ -0,0 +1,187 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2021, Naveen Albert
+ *
+ * Naveen Albert <asterisk at phreaknet.org>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Email generation functions
+ *
+ * \author Naveen Albert <asterisk at phreaknet.org>
+ */
+
+/*** MODULEINFO
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <sys/stat.h>
+
+#include "asterisk/logger.h"
+#include "asterisk/mail.h"
+
+static int my_umask;
+
+struct baseio {
+ int iocp;
+ int iolen;
+ int linelength;
+ int ateof;
+ unsigned char iobuf[BASEMAXINLINE];
+};
+
+/*!
+ * \brief utility used by inchar(), for base_encode()
+ */
+static int inbuf(struct baseio *bio, FILE *fi)
+{
+ int l;
+
+ if (bio->ateof)
+ return 0;
+
+ if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) != BASEMAXINLINE) {
+ bio->ateof = 1;
+ if (l == 0) {
+ /* Assume EOF */
+ return 0;
+ }
+ }
+
+ bio->iolen = l;
+ bio->iocp = 0;
+
+ return 1;
+}
+
+/*!
+ * \brief utility used by base_encode()
+ */
+static int inchar(struct baseio *bio, FILE *fi)
+{
+ if (bio->iocp>=bio->iolen) {
+ if (!inbuf(bio, fi))
+ return EOF;
+ }
+
+ return bio->iobuf[bio->iocp++];
+}
+
+/*!
+ * \brief utility used by base_encode()
+ */
+static int ochar(struct baseio *bio, int c, FILE *so)
+{
+ if (bio->linelength >= BASELINELEN) {
+ if (fputs(ENDL, so) == EOF) {
+ return -1;
+ }
+
+ bio->linelength = 0;
+ }
+
+ if (putc(((unsigned char) c), so) == EOF) {
+ return -1;
+ }
+
+ bio->linelength++;
+
+ return 1;
+}
+
+/*!
+ * \brief Performs a base 64 encode algorithm on the contents of a File
+ * \param filename The path to the file to be encoded. Must be readable, file is opened in read mode.
+ * \param so A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename.
+ *
+ * \return zero on success, -1 on error.
+ */
+int ast_base_encode(char *filename, FILE *so)
+{
+ static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
+ 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
+ int i, hiteof = 0;
+ FILE *fi;
+ struct baseio bio;
+
+ memset(&bio, 0, sizeof(bio));
+ bio.iocp = BASEMAXINLINE;
+
+ if (!(fi = fopen(filename, "rb"))) {
+ ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ while (!hiteof){
+ unsigned char igroup[3], ogroup[4];
+ int c, n;
+
+ memset(igroup, 0, sizeof(igroup));
+
+ for (n = 0; n < 3; n++) {
+ if ((c = inchar(&bio, fi)) == EOF) {
+ hiteof = 1;
+ break;
+ }
+
+ igroup[n] = (unsigned char) c;
+ }
+
+ if (n > 0) {
+ ogroup[0]= dtable[igroup[0] >> 2];
+ ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
+ ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
+ ogroup[3]= dtable[igroup[2] & 0x3F];
+
+ if (n < 3) {
+ ogroup[3] = '=';
+
+ if (n < 2)
+ ogroup[2] = '=';
+ }
+
+ for (i = 0; i < 4; i++)
+ ochar(&bio, ogroup[i], so);
+ }
+ }
+
+ fclose(fi);
+
+ if (fputs(ENDL, so) == EOF) {
+ return 0;
+ }
+
+ return 1;
+}
+
+/* same as mkstemp, but return a FILE * */
+FILE *ast_file_mkftemp(char *template)
+{
+ FILE *p = NULL;
+ int pfd = mkstemp(template);
+ chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
+ if (pfd > -1) {
+ p = fdopen(pfd, "w+");
+ if (!p) {
+ close(pfd);
+ pfd = -1;
+ }
+ }
+ return p;
+}
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/16665
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: I1de0ed3483623e9599711129edc817c45ad237ee
Gerrit-Change-Number: 16665
Gerrit-PatchSet: 1
Gerrit-Owner: N A <mail at interlinked.x10host.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20211101/0c1ccb0d/attachment-0001.html>
More information about the asterisk-code-review
mailing list