mail.c
author viric@mandarina
Mon, 05 May 2008 23:14:22 +0200
changeset 216 b4476e12a717
parent 147 e173645f5221
child 231 558b281b88f5
permissions -rw-r--r--
Moving versions to 0.5.4.1 for debianers.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
78
e4d5907f5aaf Added manpage and make install.
viric@llimona
parents: 73
diff changeset
     1
/*
e4d5907f5aaf Added manpage and make install.
viric@llimona
parents: 73
diff changeset
     2
    Task Spooler - a task queue system for the unix user
e4d5907f5aaf Added manpage and make install.
viric@llimona
parents: 73
diff changeset
     3
    Copyright (C) 2007  LluĂ­s Batlle i Rossell
e4d5907f5aaf Added manpage and make install.
viric@llimona
parents: 73
diff changeset
     4
e4d5907f5aaf Added manpage and make install.
viric@llimona
parents: 73
diff changeset
     5
    Please find the license in the provided COPYING file.
e4d5907f5aaf Added manpage and make install.
viric@llimona
parents: 73
diff changeset
     6
*/
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
     7
#include <signal.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
     8
#include <string.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
     9
#include <sys/types.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    10
#include <sys/wait.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    11
#include <stdlib.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    12
#include <unistd.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    13
#include <stdio.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    14
#include <sys/stat.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    15
#include <fcntl.h>
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    16
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    17
#include "main.h"
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    18
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    19
/* Returns the write pipe */
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    20
static int run_sendmail(const char *dest)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    21
{
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    22
    int pid;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    23
    int p[2];
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    24
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    25
    pipe(p);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    26
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    27
    pid = fork();
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    28
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    29
    switch(pid)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    30
    {
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    31
        case 0: /* Child */
95
d31aaee661d1 Protection against SIGPIPE. Block it.
viric@llimona
parents: 92
diff changeset
    32
            restore_sigmask();
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    33
            close(0);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    34
            close(1);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    35
            close(2);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    36
            dup2(p[0], 0);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    37
            execl("/usr/sbin/sendmail", "sendmail", "-oi", dest, NULL);
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    38
            error("run sendmail");
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    39
        case -1:
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    40
            error("fork sendmail");
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    41
        default: /* Parent */
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    42
            ;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    43
    }
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    44
    return p[1];
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    45
}
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    46
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    47
static void write_header(int fd, const char *dest, const char * command,
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    48
        int jobid, int errorlevel)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    49
{
147
e173645f5221 Added environment info through TS_ENV
viric@llimona
parents: 146
diff changeset
    50
    fd_nprintf(fd, 100, "From: Task Spooler <taskspooler>\n");
e173645f5221 Added environment info through TS_ENV
viric@llimona
parents: 146
diff changeset
    51
    fd_nprintf(fd, 500, "To: %s\n", dest);
e173645f5221 Added environment info through TS_ENV
viric@llimona
parents: 146
diff changeset
    52
    fd_nprintf(fd, 500, "Subject: the task %i finished with error %i. \n", jobid,
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    53
            errorlevel);
147
e173645f5221 Added environment info through TS_ENV
viric@llimona
parents: 146
diff changeset
    54
    fd_nprintf(fd, 500, "\nCommand: %s\n", command);
e173645f5221 Added environment info through TS_ENV
viric@llimona
parents: 146
diff changeset
    55
    fd_nprintf(fd, 500, "Output:\n");
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    56
}
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    57
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    58
static void copy_output(int write_fd, const char *ofname)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    59
{
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    60
    int file_fd;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    61
    char buffer[1000];
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    62
    int read_bytes;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    63
    int res;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    64
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    65
    file_fd = open(ofname, O_RDONLY);
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    66
    if (file_fd == -1)
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    67
        error("mail: Cannot open the output file %s", ofname);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    68
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    69
    do {
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    70
        read_bytes = read(file_fd, buffer, 1000);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    71
        if (read_bytes > 0)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    72
        {
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    73
            res = write(write_fd, buffer, read_bytes);
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    74
            if (res == -1)
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    75
                warning("Cannot write to the mail pipe %i", write_fd);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    76
        }
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    77
    } while (read_bytes > 0);
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    78
    if (read_bytes == -1)
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    79
        warning("Cannot read the output file %s from %i", ofname, file_fd);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    80
}
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    81
73
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    82
void hook_on_finish(int jobid, int errorlevel, const char *ofname,
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    83
    const char *command)
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    84
{
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    85
    char *onfinish;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    86
    int pid;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    87
    char sjobid[20];
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    88
    char serrorlevel[20];
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    89
    int status;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    90
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    91
    onfinish = getenv("TS_ONFINISH");
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    92
    if (onfinish == NULL)
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    93
        return;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    94
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    95
    pid = fork();
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    96
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    97
    switch(pid)
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    98
    {
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    99
        case 0: /* Child */
95
d31aaee661d1 Protection against SIGPIPE. Block it.
viric@llimona
parents: 92
diff changeset
   100
            restore_sigmask();
73
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   101
            sprintf(sjobid, "%i", jobid);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   102
            sprintf(serrorlevel, "%i", errorlevel);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   103
            execlp(onfinish, onfinish, sjobid, serrorlevel, ofname, command,
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   104
                    NULL);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   105
        case -1:
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
   106
            error("fork on finish");
73
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   107
        default: /* Parent */
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   108
            wait(&status);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   109
    }
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   110
}
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   111
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   112
void send_mail(int jobid, int errorlevel, const char *ofname,
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   113
    const char *command)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   114
{
72
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   115
    char to[101];
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   116
    char *user;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   117
    char *env_to;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   118
    int write_fd;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   119
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   120
    env_to = getenv("TS_MAILTO");
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   121
72
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   122
    if (env_to == NULL || strlen(env_to) > 100)
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   123
    {
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   124
        user = getenv("USER");
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   125
        if (user == NULL)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   126
            user = "nobody";
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   127
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   128
        strcpy(to, user);
72
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   129
        /*strcat(to, "@localhost");*/
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   130
    } else
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   131
        strcpy(to, env_to);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   132
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   133
    write_fd = run_sendmail(to);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   134
    write_header(write_fd, to, command, jobid, errorlevel);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   135
    copy_output(write_fd, ofname);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   136
    close(write_fd);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   137
}