Implementation of sieve "redirect" action. Kept apart from other actions due to …
…the lack of API support.
Showing
1 changed file
with
93 additions
and
0 deletions
guimb/scm/redirect.scm
0 → 100644
1 | ;;;; GNU mailutils - a suite of utilities for electronic mail | ||
2 | ;;;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||
3 | ;;;; | ||
4 | ;;;; This program is free software; you can redistribute it and/or modify | ||
5 | ;;;; it under the terms of the GNU General Public License as published by | ||
6 | ;;;; the Free Software Foundation; either version 2, or (at your option) | ||
7 | ;;;; any later version. | ||
8 | ;;;; | ||
9 | ;;;; This program is distributed in the hope that it will be useful, | ||
10 | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | ;;;; GNU General Public License for more details. | ||
13 | ;;;; | ||
14 | ;;;; You should have received a copy of the GNU General Public License | ||
15 | ;;;; along with this program; if not, write to the Free Software | ||
16 | ;;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | |||
18 | ;;;; This module provides sieve's "redirect" action. | ||
19 | |||
20 | (use-modules (ice-9 popen)) | ||
21 | |||
22 | (define PATH-SENDMAIL "/usr/lib/sendmail") | ||
23 | (define sieve-my-email "") | ||
24 | |||
25 | ;;; Bounce a message. | ||
26 | ;;; Current mailutils API does not provide a way to send a message | ||
27 | ;;; specifying its recipients (like "sendmail -t foo@bar.org" does), | ||
28 | ;;; hence the need for this function. | ||
29 | (define (sieve-message-bounce message addr-list) | ||
30 | (catch #t | ||
31 | (lambda () | ||
32 | (let ((port (open-output-pipe | ||
33 | (apply string-append | ||
34 | (append | ||
35 | (list | ||
36 | PATH-SENDMAIL | ||
37 | " -oi -t ") | ||
38 | (map | ||
39 | (lambda (addr) | ||
40 | (string-append addr " ")) | ||
41 | addr-list)))))) | ||
42 | ;; Write headers | ||
43 | (for-each | ||
44 | (lambda (hdr) | ||
45 | (display (string-append (car hdr) ": " (cdr hdr)) port) | ||
46 | (newline port)) | ||
47 | (mu-message-get-header-fields message)) | ||
48 | (newline port) | ||
49 | ;; Write body | ||
50 | (let ((body (mu-message-get-body message))) | ||
51 | (do ((line (mu-body-read-line body) (mu-body-read-line body))) | ||
52 | ((eof-object? line) #f) | ||
53 | (display line port))) | ||
54 | (close-output-port port))) | ||
55 | (lambda args | ||
56 | (runtime-error LOG_ERR "redirect: Can't send message") | ||
57 | (write args)))) | ||
58 | |||
59 | ;;; rfc3028 says: | ||
60 | ;;; "Implementations SHOULD take measures to implement loop control," | ||
61 | ;;; We do this by appending an "X-Sender" header to each message | ||
62 | ;;; being redirected. If one of the "X-Sender" headers of the message | ||
63 | ;;; contains our email address, we assume it is a loop and bail out. | ||
64 | |||
65 | (define (sent-from-me? msg) | ||
66 | (call-with-current-continuation | ||
67 | (lambda (x) | ||
68 | (for-each | ||
69 | (lambda (hdr) | ||
70 | (if (and (string=? (car hdr) "X-Sender") | ||
71 | (string=? (mu-address-get-email (cdr hdr)) | ||
72 | sieve-my-email)) | ||
73 | (x #t))) | ||
74 | (mu-message-get-header-fields sieve-current-message)) | ||
75 | #f))) | ||
76 | |||
77 | ;;; redirect action | ||
78 | (define (action-redirect address) | ||
79 | (if sieve-my-email | ||
80 | (cond | ||
81 | ((sent-from-me? sieve-current-message) | ||
82 | (runtime-error LOG_ERR "redirect: Loop detected")) | ||
83 | (else | ||
84 | (let ((out-msg (mu-message-copy sieve-current-message))) | ||
85 | (mu-message-set-header out-msg "X-Sender" sieve-my-email) | ||
86 | (sieve-message-bounce out-msg (list address))))) | ||
87 | (sieve-message-bounce out-msg (list address)))) | ||
88 | |||
89 | ;;; Register action | ||
90 | (if sieve-parser | ||
91 | (sieve-register-action "redirect" action-redirect 'string)) | ||
92 | |||
93 |
-
Please register or sign in to post a comment