216 lines
5.9 KiB
C
216 lines
5.9 KiB
C
/*****************************************************************************\
|
|
** **
|
|
** PBX4Linux **
|
|
** **
|
|
**---------------------------------------------------------------------------**
|
|
** Copyright: Andreas Eversberg **
|
|
** **
|
|
** use mailer to send mail about message **
|
|
** **
|
|
\*****************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <sys/resource.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
//#include <poll.h>
|
|
#include "main.h"
|
|
|
|
static char *months[] = {
|
|
"January", "February", "March", "April", "Mai", "June", "July",
|
|
"August", "September", "October", "November", "December"
|
|
};
|
|
|
|
|
|
/*
|
|
* create mail with or without sample
|
|
* the process creates forks to keep pbx running
|
|
*/
|
|
struct mail_args {
|
|
char email[128];
|
|
char filename[256];
|
|
int year;
|
|
int mon;
|
|
int mday;
|
|
int hour;
|
|
int min;
|
|
char callerid[64];
|
|
char callerintern[32];
|
|
char callername[64];
|
|
char terminal[32];
|
|
};
|
|
|
|
static void *mail_child(void *arg)
|
|
{
|
|
struct mail_args *args = (struct mail_args *)arg;
|
|
char *email = args->email;
|
|
char *filename = args->filename;
|
|
int year = args->year;
|
|
int mon = args->mon;
|
|
int mday = args->mday;
|
|
int hour = args->hour;
|
|
int min = args->min;
|
|
char *callerid = args->callerid;
|
|
char *callerintern = args->callerintern;
|
|
char *callername = args->callername;
|
|
char *terminal = args->terminal;
|
|
|
|
char command[128];
|
|
char buffer[256];
|
|
char rbuf[54];
|
|
FILE *ph;
|
|
int fh;
|
|
unsigned char e1, e2, e3;
|
|
int i, n, cnt;
|
|
unsigned char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
struct sched_param schedp;
|
|
int ret;
|
|
|
|
PDEBUG(DEBUG_EPOINT, "child process started for sending a mail\n");
|
|
|
|
/* lower priority to keep pbx running fluently */
|
|
if (options.schedule > 0)
|
|
{
|
|
memset(&schedp, 0, sizeof(schedp));
|
|
schedp.sched_priority = 0;
|
|
ret = sched_setscheduler(0, SCHED_OTHER, &schedp);
|
|
if (ret < 0)
|
|
{
|
|
PERROR("Scheduling to normal priority failed (errno = %d).\nExitting child process...\n", errno);
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
/* open process */
|
|
SPRINT(command, "%s -f%s %s", SENDMAIL, options.email, email);
|
|
if ((ph = popen(command, "w")) < 0)
|
|
{
|
|
PERROR("Cannot send mail using command '%s'\n", command);
|
|
goto done;
|
|
}
|
|
|
|
/* send header */
|
|
fprintf(ph, "MIME-Version: 1.0\n");
|
|
fprintf(ph, "Content-Type: multipart/mixed;\n\tboundary=\"next_part\"\n");
|
|
fprintf(ph, "From: %s <%s>\n", NAME, options.email);
|
|
fprintf(ph, "To: %s\n", email);
|
|
fprintf(ph, "Subject: Message from '%s' recorded.\n\n", callerid);
|
|
|
|
/* send message */
|
|
fprintf(ph, "This is a MIME-encapsulated message\n--next_part\n");
|
|
fprintf(ph, "Content-Type: text/plain; charset=us-ascii\nContent-Transfer-Encoding: 7bit\n\n");
|
|
fprintf(ph, "\nThe voice box of %s has recorded a message:\n\n * extension: %s\n * from: %s", NAME, terminal, callerid);
|
|
if (callerintern[0])
|
|
fprintf(ph, " (intern %s)", callerintern);
|
|
if (callername[0])
|
|
fprintf(ph, " %s", callername);
|
|
fprintf(ph, "\n * date: %s %d %d %d:%02d\n\n", months[mon], mday, year+1900, hour, min);
|
|
|
|
/* attach audio file */
|
|
if (filename[0])
|
|
if ((fh = open(filename, O_RDONLY)))
|
|
{
|
|
while(strchr(filename, '/'))
|
|
filename = strchr(filename, '/')+1;
|
|
fprintf(ph, "--next_part\n");
|
|
if (strlen(filename) >= 4)
|
|
if (!strcasecmp(filename+strlen(filename)-4, ".wav"))
|
|
fprintf(ph, "Content-Type: audio/x-wav;\n\tname=\"%s\"\n", filename);
|
|
fprintf(ph, "Content-Transfer-Encoding: base64\nContent-Disposition: inline;\n\tfilename=\"%s\"\n\n", filename);
|
|
|
|
/* stream from disk and encode */
|
|
while(42)
|
|
{
|
|
/* read exactly one line */
|
|
cnt = read(fh, rbuf, 54);
|
|
if (cnt <= 0)
|
|
break;
|
|
/* encode */
|
|
n = cnt;
|
|
while (n%3)
|
|
{
|
|
rbuf[n] = 0;
|
|
n++;
|
|
}
|
|
n = n/3;
|
|
i = 0;
|
|
while(i<n)
|
|
{
|
|
e1 = rbuf[i+i+i];
|
|
e2 = rbuf[i+i+i+1];
|
|
e3 = rbuf[i+i+i+2];
|
|
buffer[(i<<2)+3] = base64[e3 & 0x3f];
|
|
buffer[(i<<2)+2] = base64[((e3>>6)+(e2<<2)) & 0x3f];
|
|
buffer[(i<<2)+1] = base64[((e2>>4)+(e1<<4)) & 0x3f];
|
|
buffer[i<<2] = base64[e1 >> 2];
|
|
i++;
|
|
}
|
|
if ((cnt%3) > 0)
|
|
buffer[(i<<2)-1] = '=';
|
|
if ((cnt%3) == 1)
|
|
buffer[(i<<2)-2] = '=';
|
|
buffer[(i<<2)] = '\n';
|
|
buffer[(i<<2)+1] = '\0';
|
|
/* write */
|
|
fprintf(ph, "%s", buffer);
|
|
}
|
|
|
|
fprintf(ph, "\n\n");
|
|
close(fh);
|
|
} else
|
|
{
|
|
SPRINT(buffer, "-Error- Failed to read audio file: '%s'.\n\n", filename);
|
|
fprintf(ph, "%s", buffer);
|
|
PERROR("%s", buffer);
|
|
}
|
|
|
|
/* finish mail */
|
|
fprintf(ph, ".\n");
|
|
|
|
/* wait for mail to be sent and close process */
|
|
pclose(ph);
|
|
|
|
done:
|
|
PDEBUG(DEBUG_EPOINT, "child process done for sending a mail\n");
|
|
|
|
/* exit process */
|
|
FREE(args, sizeof(struct mail_args));
|
|
amemuse--;
|
|
return(NULL);
|
|
}
|
|
|
|
void send_mail(char *filename, char *callerid, char *callerintern, char *callername, char *vbox_email, int vbox_year, int vbox_mon, int vbox_mday, int vbox_hour, int vbox_min, char *terminal)
|
|
{
|
|
struct mail_args *arg;
|
|
pthread_t tid;
|
|
|
|
arg = (struct mail_args *)MALLOC(sizeof(struct mail_args));
|
|
amemuse++;
|
|
|
|
SCPY(arg->email, vbox_email);
|
|
SCPY(arg->filename, filename);
|
|
arg->year = vbox_year;
|
|
arg->mon = vbox_mon;
|
|
arg->mday = vbox_mday;
|
|
arg->hour = vbox_hour;
|
|
arg->min = vbox_min;
|
|
SCPY(arg->callerid, callerid);
|
|
SCPY(arg->callerintern, callerintern);
|
|
SCPY(arg->callername, callername);
|
|
SCPY(arg->terminal, terminal);
|
|
|
|
if ((pthread_create(&tid, NULL, mail_child, arg)<0))
|
|
{
|
|
PERROR("failed to create mail-thread.\n");
|
|
return;
|
|
}
|
|
|
|
PDEBUG(DEBUG_EPOINT, "EPOINT '%s' send mail: child process created for sending a mail\n", terminal);
|
|
}
|
|
|