Commit 6fab28ed 6fab28ed5d7022c5ef248b849996e6296b113d6f by Sergey Poznyakoff

Implements "mimeheader" extension test. The test is similar to

"header" but works on multipart MIME messages also.
1 parent 9c0caf82
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 GNU extension test "mimeheader".
19
20 ;;;; Syntax: mimeheader [COMPARATOR] [MATCH-TYPE]
21 ;;;; <header-names: string-list> <key-list: string-list>
22 ;;;;
23 ;;;; The "mimeheader" test evaluates to true if in any part of the
24 ;;;; multipart MIME message a header name from <header-names> list
25 ;;;; matches any key from <key-list>. If the message is not multipart,
26 ;;;; "mimeheader" test is equivalent to "header" test.
27 ;;;;
28 ;;;; The arguments to "mimeheader" test are the same as to "header" test.
29
30 ;;;; Example:
31 ;;;;
32 ;;;; require [ "mimeheader", "reject"];
33 ;;;; if mimeheader :matches "Content-Type" "*application/msword;*" {
34 ;;;; reject "Please do not send data in a proprietary format.";
35 ;;;; }
36
37 (define (test-mimeheader header-list key-list . opt-args)
38 (if (mu-message-multipart? sieve-current-message)
39 (let ((mime-count (mu-message-get-num-parts sieve-current-message))
40 (comp (find-comp opt-args))
41 (match (find-match opt-args)))
42 (call-with-current-continuation
43 (lambda (exit)
44 (do ((n 1 (1+ n)))
45 ((> n mime-count) #f)
46 (let ((msg (mu-message-get-part sieve-current-message n)))
47 (if msg
48 (for-each
49 (lambda (key)
50 (let ((header-fields (mu-message-get-header-fields
51 msg
52 header-list))
53 (rx (if (eq? match #:matches)
54 (make-regexp (sieve-regexp-to-posix key)
55 (if (eq? comp string-ci=?)
56 regexp/icase
57 '()))
58 #f)))
59 (for-each
60 (lambda (h)
61 (let ((hdr (cdr h)))
62 (if hdr
63 (case match
64 ((#:is)
65 (if (comp hdr key)
66 (exit #t)))
67 ((#:contains)
68 (if (sieve-str-str hdr key comp)
69 (exit #t)))
70 ((#:matches)
71 (if (regexp-exec rx hdr)
72 (exit #t)))))))
73 header-fields)))
74 key-list)
75 #f))))))
76 (apply test-header header-list key-list opt-args)))
77
78 ;;; Register the test at compile time
79 (if sieve-parser
80 (sieve-register-test "mimeheader"
81 test-mimeheader
82 (append comparator match-type)
83 (list 'string-list 'string-list)))