summaryrefslogtreecommitdiff
path: root/digest-mailer.in
blob: 0ac607e359edf002dff70347825e5aac06f3fc6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/bash

set +e

verwendung() {
  >&2 echo 'digest-mailer collects emails into digests before sending them.'
  >&2 echo ''
  >&2 echo 'Usage: digest-mailer [OPTIONS]'
  >&2 echo \
'#HELPTEXT#    #'
  exit 1
}

if [ "x$1" = 'x--help' ]; then
  verwendung
fi

if [ "x$1" = 'x--version' ]; then
  echo '#VERSION#'
  exit
fi

if [ $# -ne 0 ]; then
  verwendung
fi

min_delay=3600
max_delay=3600
agressivity=0
mail_cmd='sendmail -t'

if [ -r '#ETCDIR#/digest-mailer.conf' ]
then
  . '#ETCDIR#/digest-mailer.conf'
fi

message=$(
  cat
)
sender=$(
  whoami | \
    sha224sum | \
    awk '{print $1}'
)
receiver=$(
  printf '%s\n' "${message}" | \
    sed -n '
      /^$/q
      s/^To:\s*//
      T
      p
    ' | \
    sha224sum | \
    awk '{print $1}'
)
time=$(
  date +%s
)
hash=$(
  printf '%s' "${message}" | \
    sha224sum | \
    awk '{print $1}'
)
if [ -s "#LIBDIR#/digest-mailer/${sender}.${receiver}.last-sent" ]; then
  last_sent=$(
    cat "#LIBDIR#/digest-mailer/${sender}.${receiver}.last-sent"
  )
else
  last_sent='0'
fi

printf '%s' "${message}" > "#LIBDIR#/digest-mailer/${sender}.${receiver}.${time}.${hash}"

first_unsent=$(
  find '#LIBDIR#/digest-mailer' -regextype grep -maxdepth 1 -mindepth 1 \
    -regex ".*/${sender}\.${receiver}\.[0-9]\+\.[0-9a-f]\+\$" \
    -printf '%f\n' | \
    cut -d. -f3 | \
    sort -nr | \
    tail -n1
)

to_send=$(
  find '#LIBDIR#/digest-mailer' -regextype grep -maxdepth 1 -mindepth 1 \
    -regex ".*/${sender}\.${receiver}\.[0-9]\+\.[0-9a-f]\+\$" | \
    sort
)
to_send_count=$(
  printf '%s\n' "${to_send}" | \
    wc -l
)
if [ $((last_sent + min_delay)) -gt ${time} ]; then
  # last email was sent too close
  exit
fi
if [ ${to_send_count} -gt 1 ] && \
  [ $(printf 'scale=10; (%s+%s)*%s + (%s+%s)*(1-%s)\n' "${min_delay}" "${last_sent}" "${agressivity}" "${max_delay}" "${first_unsent}" "${agressivity}" | bc) -gt ${time} ] && \
  [ $((first_unsent + max_delay)) -ge ${time} ]; then
  exit
fi

printf '%s' "${time}" > "#LIBDIR#/digest-mailer/${sender}.${receiver}.last-sent"

if [ ${to_send_count} -eq 1 ]; then
  ${mail_cmd} < "${to_send}"
  rm "${to_send}"
  exit
fi

{
  sed -n '
    /^$/q
    s/^Subject:.*$/Subject: mail-digest/
  ' "$(
    printf '%s' "${to_send}" | \
      head -n1
    )"
  printf '\n'
  printf '%s\n' "${to_send}" | \
    while read -r file; do
      cat "${file}"
      printf '\n'
      rm "${file}"
    done
} | ${mail_cmd}