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

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I1de0ed3483623e9599711129edc817c45ad237ee </div>
<div style="display:none"> Gerrit-Change-Number: 16665 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>