mail.c
author viric@llimona
Fri, 13 Apr 2007 20:50:31 +0200
changeset 125 b60f173b1489
parent 95 d31aaee661d1
child 146 5e689cb593aa
permissions -rw-r--r--
Copyright for list.c
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
{
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    50
    FILE *f;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    51
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    52
    f = fdopen(fd, "a");
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    53
    if (f == NULL)
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    54
        error("Cannot fdopen the letter file");
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    55
73
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    56
    fprintf(f, "From: Task Spooler <taskspooler>\n");
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    57
    fprintf(f, "To: %s\n", dest);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    58
    fprintf(f, "Subject: the task %i finished with error %i. \n", jobid,
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    59
            errorlevel);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    60
    fprintf(f, "\nCommand: %s\n", command);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    61
    fprintf(f, "Output:\n");
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    62
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    63
    fflush(f);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    64
}
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    65
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    66
static void copy_output(int write_fd, const char *ofname)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    67
{
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    68
    int file_fd;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    69
    char buffer[1000];
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    70
    int read_bytes;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    71
    int res;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    72
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    73
    file_fd = open(ofname, O_RDONLY);
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    74
    if (file_fd == -1)
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    75
        error("mail: Cannot open the output file %s", ofname);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    76
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    77
    do {
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    78
        read_bytes = read(file_fd, buffer, 1000);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    79
        if (read_bytes > 0)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    80
        {
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    81
            res = write(write_fd, buffer, read_bytes);
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    82
            if (res == -1)
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    83
                warning("Cannot write to the mail pipe %i", write_fd);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    84
        }
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    85
    } while (read_bytes > 0);
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    86
    if (read_bytes == -1)
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
    87
        warning("Cannot read the output file %s from %i", ofname, file_fd);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    88
}
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
    89
73
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    90
void hook_on_finish(int jobid, int errorlevel, const char *ofname,
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    91
    const char *command)
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    92
{
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    93
    char *onfinish;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    94
    int pid;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    95
    char sjobid[20];
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    96
    char serrorlevel[20];
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    97
    int status;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    98
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
    99
    onfinish = getenv("TS_ONFINISH");
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   100
    if (onfinish == NULL)
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   101
        return;
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   102
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   103
    pid = fork();
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   104
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   105
    switch(pid)
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   106
    {
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   107
        case 0: /* Child */
95
d31aaee661d1 Protection against SIGPIPE. Block it.
viric@llimona
parents: 92
diff changeset
   108
            restore_sigmask();
73
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   109
            sprintf(sjobid, "%i", jobid);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   110
            sprintf(serrorlevel, "%i", errorlevel);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   111
            execlp(onfinish, onfinish, sjobid, serrorlevel, ofname, command,
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   112
                    NULL);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   113
        case -1:
92
05004c52ecff Better error reports on internal handled errors.
viric@llimona
parents: 78
diff changeset
   114
            error("fork on finish");
73
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   115
        default: /* Parent */
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   116
            wait(&status);
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   117
    }
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   118
}
0c03786ff927 Added TS_ONFINISH.
viric@llimona
parents: 72
diff changeset
   119
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   120
void send_mail(int jobid, int errorlevel, const char *ofname,
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   121
    const char *command)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   122
{
72
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   123
    char to[101];
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   124
    char *user;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   125
    char *env_to;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   126
    int write_fd;
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   127
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   128
    env_to = getenv("TS_MAILTO");
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   129
72
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   130
    if (env_to == NULL || strlen(env_to) > 100)
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   131
    {
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   132
        user = getenv("USER");
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   133
        if (user == NULL)
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   134
            user = "nobody";
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   135
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   136
        strcpy(to, user);
72
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   137
        /*strcat(to, "@localhost");*/
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   138
    } else
a85ae716659c Fixed a bug in the mailer.
viric@llimona
parents: 71
diff changeset
   139
        strcpy(to, env_to);
71
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   140
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   141
    write_fd = run_sendmail(to);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   142
    write_header(write_fd, to, command, jobid, errorlevel);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   143
    copy_output(write_fd, ofname);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   144
    close(write_fd);
531666e297d7 Send e-letter implemented.
viric@llimona
parents:
diff changeset
   145
}